新增运营区域与飞手认证模块,并完善直播推流就绪流程

将运营区域与飞手认证从首页占位页迁移为完整模块,扩展 Live 播放与推流就绪流程,并新增飞手证书 OSS 上传。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 18:15:59 +08:00
parent fcb692b56a
commit a04168cf30
33 changed files with 3455 additions and 37 deletions

View File

@ -5,6 +5,7 @@
// Created by Codex on 2026/6/25.
//
import AVKit
import PhotosUI
import SwiftUI
import UniformTypeIdentifiers
@ -459,13 +460,17 @@ struct LiveAlbumPreviewView: View {
private struct LiveAlbumPreviewPage: View {
let file: LiveAlbumFileItem
@Environment(ToastCenter.self) private var toastCenter
@State private var playbackViewModel: LivePlaybackViewModel
init(file: LiveAlbumFileItem) {
self.file = file
_playbackViewModel = State(initialValue: LivePlaybackViewModel(urlString: file.url))
}
var body: some View {
VStack(spacing: AppMetrics.Spacing.medium) {
if file.isVideo && file.coverImg?.liveTrimmed.isEmpty != false {
Image(systemName: "play.circle.fill")
.font(.system(size: 72, weight: .semibold))
.foregroundStyle(.white)
if file.isVideo {
videoContent
} else {
RemoteImage(urlString: file.previewURL, contentMode: .fit) {
ProgressView()
@ -487,6 +492,33 @@ private struct LiveAlbumPreviewPage: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(AppMetrics.Spacing.medium)
.background(Color.black)
.onDisappear {
playbackViewModel.release()
}
}
@ViewBuilder
private var videoContent: some View {
if let player = playbackViewModel.player, playbackViewModel.playableURL != nil {
VideoPlayer(player: player)
.aspectRatio(16.0 / 9.0, contentMode: .fit)
.frame(maxWidth: .infinity)
.clipShape(RoundedRectangle(cornerRadius: AppMetrics.CornerRadius.card))
} else if file.coverImg?.liveTrimmed.isEmpty == false {
RemoteImage(urlString: file.previewURL, contentMode: .fit) {
ProgressView()
.tint(.white)
}
} else {
VStack(spacing: AppMetrics.Spacing.small) {
Image(systemName: "play.slash.fill")
.font(.system(size: 62, weight: .semibold))
.foregroundStyle(.white)
Text("当前视频地址暂不可播放")
.font(.system(size: AppMetrics.FontSize.subheadline, weight: .semibold))
.foregroundStyle(.white)
}
}
}
}