rtsp://带有AVPlayer的liveStream

时间:2015-03-31 14:42:07

标签: iphone ios8 avfoundation avplayer rtsp

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

我使用Apple guide来创建播放器。目前使用本地存储的videoFiles,这个播放器工作正常,当我尝试播放这个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://网址返回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返回错误的网址,例如:rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 --file:/// - 所以我猜错了
  3. 根据AppleDev尝试使用diff方法创建AvPlayer:如[AVPlayer playerWithPlayerItem:playerItem][AVPlayer playerWithURL:url]一样 - 没有任何改变。还尝试为AVAsset设置不同的设置 - 在initialSetupWithURL中(参见上面的方法实现)。
  4. 那么,问题是AVPlayer支持播放rtsp:// stream吗? 如果是,有人可以提供正确使用的样本吗? Nad我在代码中做错了什么? 如果AvPlayer不支持rtsp://可能存在一些替代解决方案吗?

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

你试过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()

答案 3 :(得分:0)

无法使用 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