尝试从YouTube读取视频流时获取工件

时间:2011-07-21 00:49:47

标签: iphone youtube ffmpeg gdata-api rtsp

我正在尝试从YouTube获取的RTSP流中读取视频帧。以下是我的测试视频的链接:

  

RTSP://v8.cache5.c.youtube.com/CiILENy73wIaGQkJlrXMiAG8BxMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp

如果我正在从本地文件中读取帧 - 一切都很好,但是当从流中读取它们时,除了大​​量的工件之外什么都没有。我已经google了一下,发现UDP数据包可能存在问题,切换到TCP可能会有所帮助,但我真的找不到可以改变它的地方。

以下是阅读框架的功能:

bool nextFrame(AVFormatContext *pFormatCtx, AVCodecContext *pCodecCtx, int videoStream, AVFrame *pFrame) {  AVPacket packet;
    int frameFinished = 0;

    while( !frameFinished && av_read_frame(pFormatCtx, &packet) >= 0 ) {
        // Is this a packet from the video stream?
        if( packet.stream_index == videoStream ) {
            // Decode video frame
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
        }

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);    
       }    
       return frameFinished!=0;  
}

我的日志中也收到了很多错误消息:

[h263 @ 0x7804c00] warning: first frame is no keyframe
[h263 @ 0x7804c00] illegal ac vlc code at 6x1
[h263 @ 0x7804c00] Error at MB: 18
[h263 @ 0x7804c00] concealing 99 DC, 99 AC, 99 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 10 4
[h263 @ 0x7804c00] Error at MB: 58
[h263 @ 0x7804c00] concealing 99 DC, 99 AC, 99 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 6 6
[h263 @ 0x7804c00] Error at MB: 78
[h263 @ 0x7804c00] concealing 76 DC, 76 AC, 76 MV errors
[h263 @ 0x7804c00] I cbpy damaged at 5 5
[h263 @ 0x7804c00] Error at MB: 65
[h263 @ 0x7804c00] concealing 88 DC, 88 AC, 88 MV errors
[h263 @ 0x7804c00] illegal ac vlc code at 7x5
[h263 @ 0x7804c00] Error at MB: 67
[h263 @ 0x7804c00] concealing 86 DC, 86 AC, 86 MV errors

......等等

编辑:这是99.9%的UDP-TCP问题。我找到了这个链接:

  

RTSP://195.200.199.8/mpeg4/media.amp

这是在线提供的一些测试相机。它与工件流。但是如果它有参数'tcp'并且我使用了这个

  

的rtsp://195.200.199.8/mpeg4/media.amp TCP

一切都没有文物。

所以要纠正我的问题:有没有办法迫使YouTube或ffmpeg使用TCP?

3 个答案:

答案 0 :(得分:3)

传输协议是您请求的IP套接字的属性。因此,您可以在TCP和UDP传输上使用相同的url(和ip:port)。这意味着它可以由客户端打开TCP端口而不是UDP端口。

创建套接字时会选择它。

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)

sock = socket(PF_INET, SOCK_STREAM, IPPROTO_UDP)

现在,我不知道ffmpeg在哪里做到这一点,但上面肯定会给你一个如何找出答案的线索。

答案 1 :(得分:1)

AVDictionary *format_opts = NULL;
av_dict_set(&format_opts,"rtsp_transport","tcp",0); 

if(avformat_open_input(&context, url,NULL, **&format_opts**) != 0)
{ 
av_dict_free(&format_opts);
return; //error
} 

//if you want more info about RTSP session, you can use RTSPState
//(#include "libavformat\rtsp.h") :
RTSPState *pRTSPState = (RTSPState*)context->priv_data;

//.....

av_dict_free(&format_opts);

//...

答案 2 :(得分:0)

RTSP RFC(http://www.ietf.org/rfc/rfc2326.txt)似乎建议您在第12.39节中的请求期间指定您的首选项传输。我不知道这是否有帮助。