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; }
private void DoStart() { var vss = Source; if (!_modeAudio) { vss = Tokenise(vss); } AVDictionary *options = null; if (_inputFormat == null) { ffmpeg.av_dict_set(&options, "analyzeduration", _analyzeDuration.ToString(), 0); string prefix = vss.ToLower().Substring(0, vss.IndexOf(":", StringComparison.Ordinal)); switch (prefix) { case "http": case "mmsh": case "mms": ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0); ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0); if (_cookies != "") { ffmpeg.av_dict_set(&options, "cookies", _cookies, 0); } if (_headers != "") { ffmpeg.av_dict_set(&options, "headers", _headers, 0); } if (_userAgent != "") { ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0); } break; case "tcp": case "udp": case "rtp": case "sdp": case "mmst": case "ftp": ffmpeg.av_dict_set(&options, "timeout", _timeout.ToString(), 0); break; case "rtsp": case "rtmp": ffmpeg.av_dict_set(&options, "stimeout", (_timeout * 1000).ToString(), 0); if (_userAgent != "") { ffmpeg.av_dict_set(&options, "user-agent", _userAgent, 0); } break; } ffmpeg.av_dict_set(&options, "rtsp_transport", RTSPmode, 0); } ffmpeg.av_dict_set(&options, "rtbufsize", "10000000", 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); } } } } } _stopReadingFrames = false; try { Program.FfmpegMutex.WaitOne(); var pFormatContext = ffmpeg.avformat_alloc_context(); _lastPacket = DateTime.UtcNow; _interruptCallback = InterruptCb; _interruptCallbackAddress = Marshal.GetFunctionPointerForDelegate(_interruptCallback); pFormatContext->interrupt_callback.callback = _interruptCallbackAddress; pFormatContext->interrupt_callback.opaque = null; if (ffmpeg.avformat_open_input(&pFormatContext, vss, _inputFormat, &options) != 0) { throw new ApplicationException(@"Could not open source"); } _formatContext = pFormatContext; SetupFormat(); } catch (Exception ex) { ErrorHandler?.Invoke(ex.Message); _res = ReasonToFinishPlaying.VideoSourceError; PlayingFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); AudioFinished?.Invoke(this, new PlayingFinishedEventArgs(_res)); } finally { try { Program.FfmpegMutex.ReleaseMutex(); } catch { } } _starting = false; }
private void Open(string fileName, int width, int height, AVCodecID videoCodec, int framerate, AVCodecID audioCodec) { CreatedDate = DateTime.UtcNow; 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); _formatContext->interrupt_callback.callback = _interruptCallbackAddress; _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; _recordingStartTime = DateTime.UtcNow; _opened = true; }