123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- using FFmpeg.AutoGen;
- using System;
- using Vinno.FIS.TRTCClient.Common.Enum;
- using Vinno.vCloud.FIS.CrossPlatform.Common;
- using Vinno.vCloud.FIS.CrossPlatform.Common.Enum;
- using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo;
- using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo.Interface;
- namespace Vinno.vCloud.FIS.CrossPlatform.Windows.LiveVideo.RTMP
- {
- public unsafe class DsRtmpPusher : IDisposable
- {
- private ICapturer _capture;
- private FFmpegEncoder _encoder;
- private DaniuPusher _pusher;
- private AVFrame* _srcFrame;
- private AVFrame* _destFrame;
- private bool _isPushing;
- private EnumLiveChannelCategory _category;
- private FormatConvertUtil _formatConvertUtil;
- public event EventHandler<ImageFrameData> ImageFrameReceived;
- public event EventHandler<EnumLiveStatus> LiveStatusChanged;
- public DsRtmpPusher(CPVideoDeviceInfo deviceInfo, string url, string micId, bool isMute, int outputWitdh, int outputHeight)
- {
- _category = deviceInfo.Category;
- _encoder = new FFmpegEncoder(outputWitdh, outputHeight, deviceInfo.FrameRate);
- _encoder.EncodedFrameReceived += OnEncodedFrameReceived;
- _capture = new Capturer(deviceInfo.Id, outputWitdh, outputHeight, 20, deviceInfo.Category, deviceInfo.Width, deviceInfo.Height);
- _capture.ImageFrameReceived += OnImageFrameReceived;
- var micIndex = CrossPlatformHelper.Instance.HardwareDetector.GetMicIndex(micId);
- _pusher = new DaniuPusher(url, outputWitdh, outputHeight, deviceInfo.FrameRate, EnumAudioMode.Mic, micIndex, isMute);
- _pusher.StatusChanged += OnStatusChanged;
- _formatConvertUtil = new FormatConvertUtil();
- _srcFrame = AvFrameOperateUtil.Create(outputWitdh, outputHeight, AVPixelFormat.AV_PIX_FMT_BGRA);
- _destFrame = AvFrameOperateUtil.Create(outputWitdh, outputHeight, _encoder.Format);
- }
- public void SetMute(bool isMute)
- {
- _pusher?.SetMute(isMute);
- }
- public void Start()
- {
- if (!_isPushing)
- {
- _capture.StartCapture();
- _pusher.StartPush();
- _isPushing = true;
- }
- }
- public void Stop()
- {
- if (_isPushing)
- {
- _pusher.StopPush();
- _capture.StopCapture();
- _capture.Dispose();
- _capture = null;
- _isPushing = false;
- }
- }
- private void OnStatusChanged(object sender, CPLiveStatusData e)
- {
- LiveStatusChanged?.Invoke(_category, e.Status);
- }
- private void OnImageFrameReceived(object sender, ImageFrameData e)
- {
- Buffer.MemoryCopy(e.Data.ToPointer(), _srcFrame->data[0], e.Size, e.Size);
- _formatConvertUtil.Convert(_srcFrame, _destFrame);
- _encoder?.Encode(_destFrame);
- ImageFrameReceived?.Invoke(_category, e);
- }
- private void OnEncodedFrameReceived(object sender, AVPacket e)
- {
- var iskeyFrame = e.flags == ffmpeg.AV_PKT_FLAG_KEY ? 1 : 0;
- _pusher?.PostEncodeData(new IntPtr(e.data), (uint)e.size, iskeyFrame, (ulong)e.dts, (ulong)e.pts);
- }
- public void Dispose()
- {
- try
- {
- Stop();
- if (_pusher != null)
- {
- _pusher.StatusChanged -= OnStatusChanged;
- _pusher.Dispose();
- _pusher = null;
- }
- if (_capture != null)
- {
- _capture.ImageFrameReceived -= OnImageFrameReceived;
- }
- if (_encoder != null)
- {
- _encoder.EncodedFrameReceived -= OnEncodedFrameReceived;
- _encoder.Dispose();
- _encoder = null;
- }
- _formatConvertUtil.Dispose();
- AvFrameOperateUtil.Destory(_srcFrame);
- AvFrameOperateUtil.Destory(_destFrame);
- }
- catch (Exception ex)
- {
- CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"DsRtmpPusher Dispose Error:{ex}");
- }
- }
- }
- }
|