You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVFragmentedAssetMinder在iPhone真机失效但模拟器正常问题求助

问题描述

我们通过WebSecureSocket(wss://)接收碎片化视频数据,将数据写入temp.mp4的同时播放已写入文件的分片内容。因此我们使用AVFragmentedAsset和AVFragmentedAssetMinder实现该逻辑,该功能在模拟器上运行符合预期,但在真机上不会更新资源时长,也不会触发.AVAssetDurationDidChange通知。暂未排查出问题原因,已经花费2天时间定位仍无进展,希望获得大家的帮助。

实现代码

WssPlayerSource类实现

public class WssPlayerSource: WebSocketDelegate {
    
    static let ASSET_MINDER = AVFragmentedAssetMinder()
    
    private let socketClient: WebSocketStreamingClient
    private var tempMovieFile:FileHandle? = nil
    private var startedPlay = false
    private var fragmentedAsset: AVFragmentedAsset? = nil
    
    let player = AVPlayer()
    
    init(withUrl url: URL) {
        socketClient = WebSocketStreamingClient(wssUrl: url)
        socketClient.delegate = self
        do {
            self.tempMovieFile = try getTemporaryMovieFileWriter()
        }catch {
            print("打开文件出错")
        }
        
        NotificationCenter.default.addObserver(self, selector: #selector(onVideoUpdate), name: .AVAssetDurationDidChange, object: nil)
        socketClient.connect()
    }
    
    // Socket代理方法
    public func didReceive(event: WebSocketEvent, client: WebSocket) {
        switch event {
        case .binary(let data):
            
            self.tempMovieFile?.write(data)
           
            if !startedPlay {
                startedPlay = true
                DispatchQueue.global().async { [weak self] in
                    self?.didReceivedInitialData()
                }
            }
            break;
        default:
            break;
        }
    }
    
    func didReceivedInitialData() {
        fragmentedAsset = AVFragmentedAsset(url: getTemporaryMovieFile()!)
        fragmentedAsset?.loadValuesAsynchronously(forKeys: ["duration", "containsFragments", "canContainFragments"], completionHandler: {
            WssPlayerSource.ASSET_MINDER.mindingInterval = 1
            WssPlayerSource.ASSET_MINDER.addFragmentedAsset(self.fragmentedAsset!)
            
            self.player.replaceCurrentItem(with: AVPlayerItem(asset: self.fragmentedAsset!))
            self.player.play()
        })
    }
    
    @objc
    func onVideoUpdate() {
        print("视频时长已更新..")
        // 真机上不会触发该方法,但模拟器上运行正常
    }
    
    func stop() {
        socketClient.forceDisconnect()
        NotificationCenter.default.removeObserver(self)
        if let asset = self.fragmentedAsset {
            WssPlayerSource.ASSET_MINDER.addFragmentedAsset(asset)
        }
    }
}

ViewController实现

class ViewController: UIViewController {
    
    @IBOutlet var playerView:PlayerView!
    
    private static let SOCKET_URL = "wss://..."
    
    private var playerSource:WssPlayerSource? = nil
    private var playerLayer:AVPlayerLayer? = nil
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.playerSource =  WssPlayerSource(withUrl: URL(string: ViewController.SOCKET_URL)!)
        self.playerLayer = AVPlayerLayer(player: self.playerSource!.player)
        self.playerLayer?.videoGravity = .resize
        self.playerView.layer.addSublayer(self.playerLayer!)
    }
}

内容的提问来源于stack exchange,提问作者Suryavel TR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 04:21:02