【问题标题】:rtsp:// liveStream with AVPlayerrtsp:// liveStream 与 A​​VPlayer
【发布时间】:2015-06-04 22:55:48
【问题描述】:

我想用 AVPlayer 在 iPhoneDevice 上播放 liveStream。我还想从此流中获取CVPixelBufferRef 以供下次使用。

我使用Apple guide 来创建播放器。目前使用本地存储的视频文件,这个播放器工作得很好,当我尝试播放这个 AppleSampleStremURL - http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8 - 它的工作也是正弦的。

当我想用 rtsp:// 播放流时出现问题:rtsp://192.192.168.1:8227/TTLS/Streaming/channels/2?videoCodecType=H.264

一段代码 - 几乎都是使用 Apple 提供的 guid 完成的,但无论如何:

为播放准备资产

- (void)initialSetupWithURL:(NSURL *)url
{
    NSDictionary *assetOptions = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES,
                                    AVURLAssetReferenceRestrictionsKey : @(AVAssetReferenceRestrictionForbidNone)};
    self.urlAsset = [AVURLAsset URLAssetWithURL:url options:assetOptions];
}

准备播放器

- (void)prepareToPlay
{
    NSArray *keys = @[@"tracks"];
    __weak SPHVideoPlayer *weakSelf = self;
    [weakSelf.urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf startLoading];
        });
    }];
}

- (void)startLoading
{
    NSError *error;
    AVKeyValueStatus status = [self.urlAsset statusOfValueForKey:@"tracks" error:&error];
    if (status == AVKeyValueStatusLoaded) {
        self.assetDuration = CMTimeGetSeconds(self.urlAsset.duration);
        NSDictionary* videoOutputOptions = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange)};
        self.videoOutput = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:videoOutputOptions];
        self.playerItem = [AVPlayerItem playerItemWithAsset: self.urlAsset];

        [self.playerItem addObserver:self
                          forKeyPath:@"status"
                             options:NSKeyValueObservingOptionInitial
                             context:&ItemStatusContext];
        [self.playerItem addObserver:self
                          forKeyPath:@"loadedTimeRanges"
                             options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld
                             context:&ItemStatusContext];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(playerItemDidReachEnd:)
                                                     name:AVPlayerItemDidPlayToEndTimeNotification
                                                   object:self.playerItem];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(didFailedToPlayToEnd)
                                                     name:AVPlayerItemFailedToPlayToEndTimeNotification
                                                   object:nil];

        [self.playerItem addOutput:self.videoOutput];

        self.assetPlayer = [AVPlayer playerWithPlayerItem:self.playerItem];

        [self addPeriodicalObserver];
        NSLog(@"Player created");
    } else {
        NSLog(@"The asset's tracks were not loaded:\n%@", error.localizedDescription);
    }
}

问题出现在这里 - AVKeyValueStatus status = [self.urlAsset statusOfValueForKey:@"tracks" error:&error]; - 带有 rtsp:// 的这一行 URL 返回 AVKeyValueStatusFailed

有错误:

Printing description of error:
Error Domain=AVFoundationErrorDomain Code=-11800 
"The operation could not be completed" 
UserInfo=0x7fd1ea5a8a10 {NSLocalizedFailureReason=An unknown error occurred (-12936), 
NSLocalizedDescription=The operation could not be completed,
NSURL=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264,
NSUnderlyingError=0x7fd1ea53f830 "The operation couldn’t be completed.
(OSStatus error -12936.)"}

我也找了问题:

  1. FirstOne - 尝试使用 Apple 的这个流示例应用程序 - StitchedStreamPlayer - 但对于我想在那里播放的流,会遇到一些不同的错误
  2. SecondOne - 尝试同时使用这两个建议 - fileURLWithPath 返回不正确的 URL,例如:rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 --file:/// - 所以我猜是不正确的
  3. 根据 AppleDev 的说法,尝试使用不同的方法创建 AvPlayer:像 [AVPlayer playerWithPlayerItem:playerItem] 和像 [AVPlayer playerWithURL:url] - 没有任何改变。还可以尝试为 AVAsset 设置不同的设置 - 在 initialSetupWithURL 中(参见上面的方法实现)。

那么,问题 AVPlayer 是否支持播放 rtsp:// 流? 如果是,有人可以提供正确用法的样本吗? Nad我在代码中做错了什么? 如果 AvPlayer 不支持 rtsp:// 可能存在一些替代解决方案?

【问题讨论】:

  • 您可以参考 VLCKit :(MobileVLC) for plat RTSP stream

标签: iphone ios8 avfoundation avplayer rtsp


【解决方案1】:

使用 AVPlayer 播放 RTSP 流是不可能的。您共享的链接 http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8 是 HLS 流。所以它工作正常。

您应该在服务器中将 RTSP 流转换为 HLS,或者您需要寻找其他方式。最有效的一种是在客户端播放 HLS 流。但是,如果您没有机会获得 HLS 流,则可以使用 VLC。这种方式效率不高,但会奏效。

我有一篇旧博客文章解释了 iOS 上的 VLC。你可以参考一下。

https://medium.com/mobil-dev/lets-make-a-video-player-app-e759c165fd58

【讨论】:

    【解决方案2】:

    基本上可以将 rtsp 流分割成小的 mp4 容器,然后使用自定义的 URLAsset 将容器推送到 AVPlayer。这是一个实验,仍然需要在块之间平滑过渡的工作,但就像这里的一个想法https://github.com/MaximKomlev/RTSPAVPlayer

    【讨论】:

    • 是不是很贵。好主意,但您是否比较过使用 VLC?
    【解决方案3】:

    你试过MobileVLCKit吗? 这真的很容易而且效果很好!我写了small example here

    如果您想尝试,只需在终端中输入pod try ONVIFCamera

    这是怎么做的:

    var mediaPlayer = VLCMediaPlayer()
    
    // Associate the movieView to the VLC media player
    mediaPlayer.drawable = self.movieView
    
    let url = URL(string: "rtsp://IP_ADDRESS:PORT/params")
    let media = VLCMedia(url: url)
    mediaPlayer.media = media
    
    mediaPlayer.play()
    

    【讨论】:

      【解决方案4】:

      我没有找到如何通过 AVURLAsset 进行 rtsp 流式传输的方法,但可以在 here 找到良好的起点。也许它对某些人有用

      【讨论】:

      • 您最终找到解决方案了吗?
      • AVFoundation 仅支持 HTTP Live Streaming (HLS),但您可以查看 github.com/iMoreApps/ffmpeg-avplayer-for-ios-tvos 甚至 github.com/larrytin/vlc-ios
      • 我看到了那些,更多的是研究 Mac OS 解决方案,而不是 iO。一件事:您是否找到支持 AVFoundation 仅支持 HTTP Live Streaming 的官方资源?文档有点稀疏
      • 实际上没有,反过来也一样
      猜你喜欢
      • 2018-01-13
      • 1970-01-01
      • 2020-01-07
      • 2021-05-16
      • 2016-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多