使用包装器ffmpeg记录和播放文件

时间:2014-09-03 14:35:54

标签: ffmpeg

我正在使用来自ffmpeg的ffmpeg的C#包装器 我想要记录rtsp流并播放它但我无法从文件中解码帧

使用这段代码我写了文件test.avi

 unsafe
        {
            AVFormatContext* context = FFmpegInvoke.avformat_alloc_context();
            int video_stream_index=0;

            FFmpegInvoke.av_register_all();
            FFmpegInvoke.avcodec_register_all();
            FFmpegInvoke.avformat_network_init();

            //open rtsp
            if (FFmpegInvoke.avformat_open_input(&context, "rtsp://admin:admin@192.168.0.71:554", null, null) != 0)
            {
                return ;
            }

            if (FFmpegInvoke.avformat_find_stream_info(context, null) < 0)
            {
                return ;
            }

            //search video stream
            for (int i = 0; i < context->nb_streams; i++)
            {
                if (context->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                    video_stream_index = i;
            }

            AVPacket packet;
            FFmpegInvoke.av_init_packet(&packet);

            //open output file
            AVOutputFormat* fmt = FFmpegInvoke.av_guess_format("h264", null, null);
            AVFormatContext* oc = FFmpegInvoke.avformat_alloc_context();
            oc->oformat = fmt;
            FFmpegInvoke.avio_open2(&oc->pb, "test.mkv", FFmpegInvoke.AVIO_FLAG_WRITE, null, null);

            AVStream* stream = null;
            int cnt = 0;
            //start reading packets from stream and write them to file

         ///   FFmpegInvoke.av_read_play(context);//play RTSP
            while (FFmpegInvoke.av_read_frame(context, &packet) >= 0 && cnt < 1000)
            {//read 100 frames


                if (packet.stream_index == video_stream_index)
                {//packet is video               
                    if (stream == null)
                    {//create stream in file

                        stream = FFmpegInvoke.avformat_new_stream(oc, context->streams[video_stream_index]->codec->codec);
                        FFmpegInvoke.avcodec_copy_context(stream->codec, context->streams[video_stream_index]->codec);
                        stream->sample_aspect_ratio = context->streams[video_stream_index]->codec->sample_aspect_ratio;
                        FFmpegInvoke.avformat_write_header(oc, null);
                    }
                    packet.stream_index = stream->id;
                    var p1 = new FileInfo("test.mkv").Length;
                    FFmpegInvoke.av_write_frame(oc, &packet);
                    cnt++;
                }
                FFmpegInvoke.av_free_packet(&packet);
                FFmpegInvoke.av_init_packet(&packet);
            }
            FFmpegInvoke.av_read_pause(context);
            FFmpegInvoke.av_write_trailer(oc);
            FFmpegInvoke.avio_close(oc->pb);
            FFmpegInvoke.avformat_free_context(oc);
        }

并使用此代码我想播放文件

unsafe{


            string url = "test.mkv";

            FFmpegInvoke.av_register_all();
            FFmpegInvoke.avcodec_register_all();
            FFmpegInvoke.avformat_network_init();


            AVFormatContext* pFormatContext = FFmpegInvoke.avformat_alloc_context();
            if (FFmpegInvoke.avformat_open_input(&pFormatContext, url, null, null) != 0)
                throw new Exception("Could not open file");

            if (FFmpegInvoke.avformat_find_stream_info(pFormatContext, null) != 0)
                throw new Exception("Could not find stream info");
            AVStream* pStream = null;
            for (int i = 0; i < pFormatContext->nb_streams; i++)
            {
                if (pFormatContext->streams[i]->codec->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO)
                {
                    pStream = pFormatContext->streams[i];
                    break;
                }
            }
            var packet = new AVPacket();
            AVPacket* pPacket = &packet;
            FFmpegInvoke.av_init_packet(pPacket);



            AVCodecContext codecContext = *(pStream->codec);
            int width = codecContext.width;
            int height = codecContext.height;
            AVPixelFormat sourcePixFmt = codecContext.pix_fmt;
            AVCodecID codecId = codecContext.codec_id;
            var convertToPixFmt = AVPixelFormat.PIX_FMT_BGR24;
            SwsContext* pConvertContext = FFmpegInvoke.sws_getContext(width, height, sourcePixFmt,
                                                                       width, height, convertToPixFmt,
                                                                       FFmpegInvoke.SWS_FAST_BILINEAR, null, null, null);
            if (pConvertContext == null)
                throw new Exception("Could not initialize the conversion context");

            var pConvertedFrame = (AVPicture*)FFmpegInvoke.avcodec_alloc_frame();
            int convertedFrameBufferSize = FFmpegInvoke.avpicture_get_size(convertToPixFmt, width, height);
            var pConvertedFrameBuffer = (byte*)FFmpegInvoke.av_malloc((uint)convertedFrameBufferSize);
            FFmpegInvoke.avpicture_fill(pConvertedFrame, pConvertedFrameBuffer, convertToPixFmt, width, height);

            AVCodec* pCodec = FFmpegInvoke.avcodec_find_decoder(codecId);
            if (pCodec == null)
                throw new Exception("Unsupported codec");

            // Reusing codec context from stream info, 
            // as an alternative way it could look like this: (but it works not for all kind of codecs)
            // AVCodecContext* pCodecContext = FFmpegInvoke.avcodec_alloc_context3(pCodec);
            AVCodecContext* pCodecContext = &codecContext;

            if ((pCodec->capabilities & FFmpegInvoke.CODEC_CAP_TRUNCATED) == FFmpegInvoke.CODEC_CAP_TRUNCATED)
                pCodecContext->flags |= FFmpegInvoke.CODEC_FLAG_TRUNCATED;

            AVFrame* pDecodedFrame = FFmpegInvoke.avcodec_alloc_frame();

            if (FFmpegInvoke.av_read_frame(pFormatContext, pPacket) < 0)
                throw new System.IO.EndOfStreamException();
            int gotPicture = 0;
            int size = FFmpegInvoke.avcodec_decode_video2(pCodecContext, pDecodedFrame, &gotPicture, pPacket);
            if (size < 0)
                throw new Exception(string.Format("Error while decoding frame "));

            if (gotPicture == 1)
            {

            }

size = -22。为什么?有什么问题?如何使用ffmpeg播放我的文件?

0 个答案:

没有答案