混合视频类型内容在iPhone上的AVQueuePlayer中排队 [英] Mixed Video Type Content queued in an AVQueuePlayer on iPhone

查看:86
本文介绍了混合视频类型内容在iPhone上的AVQueuePlayer中排队的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为这篇荒唐的文章道歉,但我尝试提供尽可能多的代码和数据供您参考.

I'd like to start of by apologizing for this ridiculously long post, but I tried to provide as much code and data as possible for you to refer to.

我正在一个视频项目中,我需要AVQueuePlayer的灵活性(最重要的是可以自由缩放和布局视频层,以及创建自定义控件的能力).问题是,我需要能够混合不同类型的视频内容(在这种情况下为渐进式下载.mp4和http流.m3u8).这是时髦的地方.

I am working on a video project where I will need the flexibility of the AVQueuePlayer (foremost the ability to scale and layout the video layer freely, as well as creating my customized controls). Problem is, I need to be able to mix video content of different types (in this case progressive download .mp4 and http streaming .m3u8). Here's where things get funky.

首先提供一些帮助您入门的代码:

First some code to get you going:

- (void)viewDidLoad {
   [super viewDidLoad];

   NSArray *assetsArray = [NSArray arrayWithObjects:
                        [AVPlayerItem playerItemWithURL: [NSURL URLWithString: kTestPrerollURL]], // .mp4-file on server
                        [AVPlayerItem playerItemWithURL: [NSURL URLWithString: kTestVideoURL]],   // .m3u8-file on server
                        [AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: @"2" ofType:@"m4v"]]], // local m4v-file
                        [AVPlayerItem playerItemWithURL: [NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource: @"3" ofType:@"m4v"]]], // local m4v-file
                        nil];

    // Add KVO observation on each player item to track when they are ready for playback
    for(id playerItem in assetsArray) {
       [playerItem addObserver: self forKeyPath:@"status" options: 0 context: NULL];
    }

    [self setPlayer: [AVQueuePlayer queuePlayerWithItems: assetsArray]];


    [self setPlayerLayer: [AVPlayerLayer playerLayerWithPlayer: [self player]]];
    [[self playerLayer] setFrame: [playerView bounds]];
    // Additional layer customization...
    [[playerView layer] addSublayer: [self playerLayer]];
    [playerView setBackgroundColor: [UIColor clearColor]];

    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(playerItemDidReachEnd:)
                                                 name: AVPlayerItemDidPlayToEndTimeNotification
                                               object: nil];
}

当AVPlayerItem更改状态时,将调用此方法:

And when the AVPlayerItem changes status, this method is invoked:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

   // A bunch of loggers...
   if([(AVPlayerItem *)object status] == AVPlayerItemStatusReadyToPlay) {
      CGSize   movieSize = [[[player currentItem] asset] naturalSize];
      CGRect   playerRect = [playerView frame];
      playerRect.size.height  = playerRect.size.width * movieSize.height/movieSize.width + 7.0;
      [playerView  setFrame: playerRect];
      [playerLayer setFrame: [playerView bounds]];

      [player play];
   }
}

如果用户选择按下下一步"按钮,则播放器将跳至下一个剪辑:

If the user chooses to press a "Next"-button, the player skips to the next clip:

- (IBAction)next:(id)sender {
   NSLog(@"------ USER SWITCHED TO NEXT ------");
   AVPlayerItem *object = (AVPlayerItem *)[player currentItem];
   [object removeObserver:self forKeyPath: @"status"];
   [player advanceToNextItem];
}

最后,当AVPlayerItem到达末尾时,将调用此方法:

Finally, when the AVPlayerItem reaches the end, this method is invoked:

- (void)playerItemDidReachEnd:(NSNotification *)notification {
   NSLog(@"------ PLAYER ITEM DID REACH END ------");
   AVPlayerItem *object = (AVPlayerItem *)[notification object];
   [object removeObserver:self forKeyPath: @"status"];
}

好吧,所以我的问题是混合不同格式(在本例中为m3u8文件)会导致一些时髦的行为.

Ok, so my problem is that mixing different formats (in this case the m3u8-file) causes some funky behavior.

如果我首先在队列中加载m3u8文件,则它会正常播放,但是如果我AdvanceToNextItem,则该应用程序将崩溃. NSZombieEnabled报告:

If I load the m3u8-file first in the queue, it plays properly, but if I advanceToNextItem the app crashes. NSZombieEnabled reports:

*** -[Not A Type retain]: message sent to deallocated instance 0x684dfe0
[Switching to process 67957]

并且调用堆栈显示了释放的范围(MyPlayer是项目的名称):

And the call stack shows a release out of my bounds (MyPlayer is the name of the project):

po [NSThread callStackSymbols]
2011-01-05 16:12:57.151 MyPlayer[67957:6303] *** __NSAutoreleaseNoPool(): Object 0x56a0580 of class _NSCallStackArray autoreleased with no pool in place - just leaking
<_NSCallStackArray 0x56a0580>(
0   MyPlayer                            0x00002154 start + 0,
1   CoreFoundation                      0x00e72f22 _CF_forwarding_prep_0 + 50,
2   CoreFoundation                      0x00e140bc CFRetain + 92,
3   CFNetwork                           0x014c436e _ZN21XConnectionEventQueueI12XLoaderEvent18XLoaderEventParamsE10pushEventsEP20XConnectionEventInfoIS0_S1_El + 120,
4   CFNetwork                           0x014c4252 _ZN19URLConnectionLoader16pushEventsLockedEP20XConnectionEventInfoI12XLoaderEvent18XLoaderEventParamsEl + 120,
5   CFNetwork                           0x014c41c7 _ZN19URLConnectionLoader10pushEventsEP20XConnectionEventInfoI12XLoaderEvent18XLoaderEventParamsEl + 57,
6   CFNetwork                           0x015976b6 _ZN19URLConnectionClient25getRequestForTransmissionEhP14_CFURLResponsePK13_CFURLRequestPP9__CFError + 942,
7   CFNetwork                           0x014c3030 _ZN19URLConnectionClient22_clientWillSendRequestEPK13_CFURLRequestP14_CFURLResponsePNS_26ClientConnectionEventQueueE + 230,
8   CFNetwork                           0x01597789 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 141,
9   CFNetwork                           0x014c2e3c _ZN19URLConnectionClient13processEventsEv + 100,
10  CFNetwork                           0x014c2cb7 _ZN17MultiplexerSource7performEv + 251,
11  CoreFoundation                      0x00ee301f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15,
12  CoreFoundation                      0x00e4128b __CFRunLoopDoSources0 + 571,
13  CoreFoundation                      0x00e40786 __CFRunLoopRun + 470,
14  CoreFoundation                      0x00e40240 CFRunLoopRunSpecific + 208,
15  CoreFoundation                      0x00e43504 CFRunLoopRun + 84,
16  CoreMedia                           0x00cb39af FigThreadGlobalNetworkBufferingRunloop + 149,
17  CoreMedia                           0x00cb624a figThreadMain + 308,
18  libSystem.B.dylib                   0x9473885d _pthread_start + 345,
19  libSystem.B.dylib                   0x947386e2 thread_start + 34
)

如果.m3u8文件放置在队列中第一个位置之后的某个位置,则我的状态为AVPlayerItemStatusFailed,并且剪辑跳到队列中的下一个剪辑.

if the .m3u8-file is placed somewhere after the first position in the queue, I get a status AVPlayerItemStatusFailed, and the clip skips to the next clip in the queue.

我意识到这可能与某些内存管理有关,但与此同时,我开始对此表示怀疑.但是,很明显我做错了,所以每一个解决方案的建议都值得欢迎.

I realize this might be related to some memory management, but at the same time I start doubting it. However, it is quite evident I am doing something wrong, so every suggestion of a solution is more than welcome.

推荐答案

您不能执行此操作-AVPlayer可以播放HLS内容(M3U)或不播放流媒体,但不能混合播放. 详情请参见: https://devforums.apple.com/message/570406#570406

You can't do this - AVPlayer can either play HLS content (M3U) or non-streamed, but not a mix. See this for details: https://devforums.apple.com/message/570406#570406

这篇关于混合视频类型内容在iPhone上的AVQueuePlayer中排队的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆