C# 利用FluorineFx-4.0 RTMP-Server 真实可用

C# RTMPServer Rtmp服务器

  • 利用FluorineFx-4.0开发RtmpServer
    • 效果展示
    • 代码展示
    • 操作流程
    • 遗留问题
    • 未来计划
    • 项目说明
    • 项目下载地址
    • 欢迎留言交流

利用FluorineFx-4.0开发RtmpServer

效果展示

Rtmp客户端使用手机导播软件可以实现Rtmp推流,我用的是芯象导播。Rtmp接收流是自己写的服务。图片如下:
C# 利用FluorineFx-4.0 RTMP-Server 真实可用_第1张图片
C# 利用FluorineFx-4.0 RTMP-Server 真实可用_第2张图片

C# 利用FluorineFx-4.0 RTMP-Server 真实可用_第3张图片

代码展示

  /// 
        /// 初始化按钮
        /// 
        /// 
        /// 
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //创建一个多路推送的地址列表
            RtmpPushTable table = new RtmpPushTable();
            table.RtmpPullKeys = new List<RtmpPushKey>();

            RtmpPushKey key = new RtmpPushKey();
            key.KeyName = "tt";
            key.Channels = new List<RtmpPushChannel>();
            RtmpPushChannel channel = new RtmpPushChannel();
            string id = "0";
            channel.ChannelId = id;
            channel.RtmpStreamKey = "aabbccdd";
            channel.Cache = 0;
            key.Channels.Add(channel);


            table.RtmpPullKeys.Add(key);
            Console.WriteLine("-------------------RtmpPush1111111111111111111");

            //开启Rtmp服务并注册回调
            FLApplication.Start(RtmpHandshakeIPPoint, table);
            FLApplication.Flapp_DisConnect -= FLApplication_Flapp_DisConnect;
            FLApplication.Flapp_DisConnect += FLApplication_Flapp_DisConnect;
            FLApplication.Flapp_BroadCast -= FLApplication_Flapp_BroadCast;
            FLApplication.Flapp_BroadCast += FLApplication_Flapp_BroadCast;
            //音频相关配置

            aCfg = AudioEncodeCfg.GetDefault();
            aCfg.frequency = param.Frequency;
            aCfg.bitrate = param.Bitrate;
            aCfg.keyFrameRate = param.KeyFrameRate;
            aCfg.SetEncoder("AAC_");

            //音视频播放器启动
            _mp.IsVideoPlay = true;
            _mp.IsAudioPlay = true;
            _mp.Start();

        }
//接收到Rtmp流的回调函数
   private void RtmpDataCallBack(byte[] data, uint dataLen, int mediaType, int isKeyFrame, uint pts)
        {
            RealStreamTime = DateTime.Now;

            if (dataLen == 0)
            {
                return;
            }
            try
            {

                if (mediaType == 0)
                {
                    var mf = new MediaFrame()
                    {
                        nWidth = 1080,
                        nHeight = 720,
                        nEx = 1,
                        nIsAudio = 0,
                        nEncoder = MediaFrame.H264Encoder,
                        nIsKeyFrame = (byte)(isKeyFrame),
                        MediaFrameVersion = 0,
                        nPPSLen = 0,
                        nSPSLen = 0,
                        Data = data,
                        nSize = data.Length,
                        nTimetick = Environment.TickCount,
                    };

                    if (mf.nIsKeyFrame == 1)
                    {
                        var sps_pps = MediaSteamConverter.GetSPS_PPS(data);
                        mf.nSPSLen = (short)sps_pps[0].Length;
                        mf.nPPSLen = (short)sps_pps[1].Length;
                    }
                    mf.MediaFrameVersion = mf.nIsKeyFrame;
				//播放音视频
                    _mp.Play(mf);
                    //packet = new MediaFramePacket(data, Nvr.Core.Adapter.MediaType.VideoES, pts, 0, Convert.ToByte(isKeyFrame), 0, 0);
                }
                else
                {



                    var mf = new MediaFrame()
                    {
                        nFrequency = param.Frequency,
                        nSamples = (short)1024 * 2,
                        nIsKeyFrame = (byte)((_audioFrameIndex++ % 50) == 0 ? 1 : 0),
                        nEncoder = aCfg.encoder,
                        MediaFrameVersion = 0,
                        nChannel = 1,
                        nAudioFormat = 2,
                        nIsAudio = 1,
                        nTimetick = Environment.TickCount,
                        nEx = 1,
                        Data = data,
                        nSize = data.Length,
                    };

                    mf.MediaFrameVersion = (byte)(mf.nIsKeyFrame == 1 ? 1 : 0);
                    mf.nEx = (byte)(mf.nIsKeyFrame == 1 ? 0 : 1);

                    //if (_isFirstKeyFrame)
                    //{
                    //    _isFirstKeyFrame = false;
                    //    var resetCodecMediaFrame = CreateResetCodecMediaFrame(mf);
                    //    if (_callBack != null)
                    //        _callBack(resetCodecMediaFrame);
                    //}

                    //if (_callBack != null)
                    //    _callBack(mf);

                    mf.MediaFrameVersion = mf.nIsKeyFrame;

                    _mp.Play(mf);
                    //   Console.WriteLine("收到声音");
                }


            }
            catch (Exception ex)
            {
                //   Main.PrintMessage("Dahua->ClientReadDataCallBack:" + ex.Message);
            }
        }

操作流程

1、启动Rtmp
2、等待Rtmp启动完成点击获取流按钮

遗留问题

项目目前对音频支持不好,音频播放我测试是卡顿的。后续会继续优化。

未来计划

1、优化音频
2、使用UDP转发音视频流包括乱序重拍、流控、丢包补偿(nack和Fec)

项目说明

未来开发的服务主要针对以下几个方向:
1、监控SDK方向
2、视频传输SDK
3、视频会议方向

项目下载地址

https://download.csdn.net/download/qq_20504373/12742048

欢迎留言交流

你可能感兴趣的:(音视频通信,C#,rtmp,rtmp,c#)