AVFoundation播放连续的视频片段



我正在开发一款iOS应用程序,该应用程序涉及从网络服务器获取流中的视频片段,并在应用程序中连续播放。经过一番研究,我决定使用AVQueuePlayer。每次我从服务器获取MP4文件并将其存储在NSData对象中时,我都会创建一个AVPlayerItem并将其附加到队列中。此外,我会收听AVPlayerItemDidPlayToEndTimeNotification通知,在该通知中我将前进到下一个项目。我面临的问题是,每当我从一个电影片段前进到另一个片段时,都会有一个恼人的小滞后。我试着在iMovie上组合这些片段,但无法判断一个片段何时结束,另一个片段什么时候开始。如何摆脱连续片段之间的小停顿/滞后?

这是我的代码:

import UIKit
import MediaPlayer
import AVFoundation
class WatchStream: UIViewController, StreamManagerDelegate {
var subscriber : Subscriber!
//Model object responsible for fetching mp4 fragments
var streamManager = StreamManager()
var queue : AVQueuePlayer!

override func viewDidLoad() {
    super.viewDidLoad()
    //Set up the manager
    streamManager.streamID = subscriber.streamid
    streamManager.delegate = self
    //Register for notification once movie player finished
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "AVPlayerFinishedPlaying:", name:AVPlayerItemDidPlayToEndTimeNotification, object: nil)
    queue = AVQueuePlayer()
    var playerLayer = AVPlayerLayer(player: queue)
    playerLayer.frame = self.view.bounds
    self.view.layer.insertSublayer(playerLayer, below: self.navigationController!.navigationBar.layer)
}
//Delegate method notifying that a new fragment is ready to be watched
func streamManagerLoadedStream(fragment: Int, manager: StreamManager) {
    var url = streamManager.fetchFragmentToPlay()
    if url == nil {return}
    var playerItem = AVPlayerItem(URL: url!)
    queue.insertItem(playerItem, afterItem: nil)
    queue.play()
}
//Method called once name:AVPlayerItemDidPlayToEndTimeNotification fires
func AVPlayerFinishedPlaying(notification : NSNotification) {
    //We need to switch to second one
    queue.advanceToNextItem()
    if queue.status == AVPlayerStatus.ReadyToPlay {
        queue.play()
    }
}
}

同样,我的问题是在推进AVQueuePlayer时。正是它造成了这种不可能存在的滞后。电影片段很小(每个片段1-2秒),应该是连续的,因为它是一个流。我尝试使用2个AVQueuePlayers和2个AVPlayerLayers,但没有解决问题。

我还尝试使用MPMoviePlayerController,并在每次播放结束时更新其内容URL。滞后并没有消失。

有线索吗?

将AVMutableComposition与AVPlayer一起使用,而不是与AVQueuePlayer一起使用。我使用Objective-C,所以我的样本不在Swift中,但Swift代码会非常相似。

基本逻辑是:

  1. 创建AVMutableComposition

    composition=[AVMutableComposition new];

  2. 在中添加单个可变轨道

    AVMutableCompositionTrack*track=[_composition addMutableTrackWithMediaType:AVMediaTypeVideo In a preferredTrackID:kCMPersistentTrackID_Invalid];

  3. 循环:为每个视频片段创建一个AVAssetTrack

    AVURLAsset*asset=。。。;

    AVAssetTrack*assetTrack=[[asset-tracksWithMediaType:AVMediaTypeVideo]objectAtIndex:0];

    CMTimeRange时间范围=资产跟踪时间范围;

  4. 将片段添加到您的曲目中,以获得您想要的播放的确切时间

    [track insertTimeRange:track:assetTrackAtTime:时间错误:&error];

    1. 播放你的作文

    AVPlayerItem*playerItem=[AVPPlayerItem playerItemWithAsset:composition];myPlayer=[[AVPlayer alloc]initWithPlayerItem:playerItem];

最新更新