Exemplo n.º 1
0
        private void DoStart()
        {
            var vss = Source;

            if (!IsAudio)
            {
                vss = Tokenise(vss);
            }

            if (string.IsNullOrEmpty(vss))
            {
                ErrorHandler?.Invoke("Source not found");
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
                _starting = false;
                return;
            }

            AVDictionary *options = null;

            if (_inputFormat == null)
            {
                var prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal));
                ffmpeg.av_dict_set_int(&options, "rw_timeout", _timeoutMicroSeconds, 0);
                ffmpeg.av_dict_set_int(&options, "tcp_nodelay", 1, 0);
                switch (prefix)
                {
                case "https":
                case "http":
                case "mmsh":
                case "mms":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);

                    if (!string.IsNullOrEmpty(_cookies))
                    {
                        ffmpeg.av_dict_set(&options, "cookies", _cookies, 0);
                    }
                    if (!string.IsNullOrEmpty(_headers))
                    {
                        ffmpeg.av_dict_set(&options, "headers", _headers, 0);
                    }
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    break;

                case "rtsp":
                case "rtmp":
                    ffmpeg.av_dict_set_int(&options, "stimeout", _timeoutMicroSeconds, 0);
                    if (!string.IsNullOrEmpty(_userAgent))
                    {
                        ffmpeg.av_dict_set(&options, "user_agent", _userAgent, 0);
                    }
                    if (!string.IsNullOrEmpty(_modeRTSP))
                    {
                        ffmpeg.av_dict_set(&options, "rtsp_transport", _modeRTSP, 0);
                    }
                    ffmpeg.av_dict_set(&options, "rtsp_flags", "prefer_tcp", 0);
                    break;

                default:
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "tcp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;

                case "udp":
                    ffmpeg.av_dict_set_int(&options, "timeout", _timeoutMicroSeconds, 0);
                    break;
                }
                ffmpeg.av_dict_set_int(&options, "buffer_size", BUFSIZE, 0);
            }
            //ffmpeg.av_dict_set_int(&options, "rtbufsize", BUFSIZE, 0);

            var lo = _options.Split(Environment.NewLine.ToCharArray());

            foreach (var nv in lo)
            {
                if (!string.IsNullOrEmpty(nv))
                {
                    var i = nv.IndexOf('=');
                    if (i > -1)
                    {
                        var n = nv.Substring(0, i).Trim();
                        var v = nv.Substring(i + 1).Trim();
                        if (!string.IsNullOrEmpty(n) && !string.IsNullOrEmpty(v))
                        {
                            int j;
                            if (int.TryParse(v, out j))
                            {
                                ffmpeg.av_dict_set_int(&options, n, j, 0);
                            }
                            else
                            {
                                ffmpeg.av_dict_set(&options, n, v, 0);
                            }
                        }
                    }
                }
            }


            _abort = false;
            try
            {
                Program.MutexHelper.Wait();
                var pFormatContext = ffmpeg.avformat_alloc_context();
                _lastPacket = DateTime.UtcNow;


                _interruptCallback        = InterruptCb;
                _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

                _aviocb = new AVIOInterruptCB_callback_func
                {
                    Pointer = _interruptCallbackAddress
                };
                pFormatContext->interrupt_callback.callback = _aviocb;
                pFormatContext->interrupt_callback.opaque   = null;
                pFormatContext->max_analyze_duration        = 0; //0 = auto

                var t = _timeoutMicroSeconds;
                _timeoutMicroSeconds = Math.Max(_timeoutMicroSeconds, 15000000);

                Throw("OPEN_INPUT", ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options));
                _formatContext = pFormatContext;

                SetupFormat();

                _timeoutMicroSeconds = t;
            }
            catch (Exception ex)
            {
                ErrorHandler?.Invoke(ex.Message);
                _res = ReasonToFinishPlaying.VideoSourceError;
                CleanUp();
            }
            finally
            {
                try
                {
                    Program.MutexHelper.Release();
                }
                catch
                {
                }
            }

            _starting = false;
        }
Exemplo n.º 2
0
        private void Open(string fileName, int width, int height, AVCodecID videoCodec, int framerate, AVCodecID audioCodec, DateTime created)
        {
            CreatedDate  = created;
            Filename     = fileName;
            _abort       = false;
            _ignoreAudio = false;

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                IsTimelapse = framerate != 0;

                if (((width & 1) != 0) || ((height & 1) != 0))
                {
                    throw new ArgumentException("Video file resolution must be a multiple of two.");
                }
            }

            int i;

            _lastPacket = DateTime.UtcNow;
            var outputFormat = ffmpeg.av_guess_format(null, fileName, null);

            if (outputFormat == null)
            {
                switch (videoCodec)
                {
                default:
                case AVCodecID.AV_CODEC_ID_MPEG1VIDEO:
                    outputFormat = ffmpeg.av_guess_format("mpeg1video", null, null);
                    break;
                }
            }

            _formatContext = ffmpeg.avformat_alloc_context();

            if (_formatContext == null)
            {
                throw new Exception("Cannot allocate format context.");
            }

            _interruptCallback        = InterruptCb;
            _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback);

            _aviocb = new AVIOInterruptCB_callback_func
            {
                Pointer = _interruptCallbackAddress
            };
            _formatContext->interrupt_callback.callback = _aviocb;
            _formatContext->interrupt_callback.opaque   = null;


            _formatContext->oformat = outputFormat;

            AVDictionary *opts = null;

            if (audioCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                AddAudioStream(audioCodec);
                OpenAudio();
            }

            if (videoCodec != AVCodecID.AV_CODEC_ID_NONE)
            {
                _width  = width;
                _height = height;
                //_bitRate = videoBitRate;
                _framerate           = framerate;
                _isConstantFramerate = framerate > 0;

                AddVideoStream(videoCodec);
                OpenVideo();

                if (videoCodec == AVCodecID.AV_CODEC_ID_MPEG1VIDEO)
                {
                    ffmpeg.av_dict_set(&opts, "pkt_size", "1316", 0);
                    ffmpeg.av_dict_set(&opts, "buffer_size", "65535", 0);

                    //ffmpeg.av_dict_set(&opts, "crf", "30", 0);
                }
            }


            if (movflags != "")
            {
                ffmpeg.av_dict_set(&opts, "movflags", movflags, 0);
            }


            if ((outputFormat->flags & ffmpeg.AVFMT_NOFILE) != ffmpeg.AVFMT_NOFILE)
            {
                i = ffmpeg.avio_open2(&_formatContext->pb, fileName, ffmpeg.AVIO_FLAG_WRITE, null, &opts);
                if (i < 0)
                {
                    throw new Exception("Cannot create the video file. (" + i + ")");
                }
            }

            i = ffmpeg.avformat_write_header(_formatContext, null);
            if (i < 0)
            {
                throw new Exception("Cannot write header - check disk space (" + i + ")");
            }

            ffmpeg.av_dict_free(&opts);

            _frameNumber      = 0;
            _keyframeInterval = DateTime.UtcNow;
            _opened           = true;
        }