Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >多路RTSP转RTMP推送方案的两个选择

多路RTSP转RTMP推送方案的两个选择

原创
作者头像
音视频牛哥
发布于 2024-08-09 03:10:46
发布于 2024-08-09 03:10:46
19900
代码可运行
举报
运行总次数:0
代码可运行

​技术选型

RTSP转RTMP推送到流媒体服务器,说起来技术实现不难,简单来说,获取RTSP流后,拿到未经解码的H.264/H.265和audio数据,重新打包RTMP发送出去即可。需要注意的是,大多RTSP转RTMP模块,需要长时间运行,所以,需要有好多错误处理和自动重连机制,确保转发模块的稳定性。以下是两个可选的技术方案:

方案1:FFMPEG命令转发

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ffmpeg -i rtsp://[摄像头地址]/[流媒体地址] -c:v libx264 -preset veryfast -maxrate 3000k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://[服务器地址]/[应用名称]/[流密钥]
  • rtsp://[摄像头地址]/[流媒体地址] 是摄像头的RTSP流地址。
  • -c:v libx264 指定视频编码器为libx264。
  • -preset veryfast 设置编码速度为非常快,以牺牲一些压缩效率换取更快的编码速度。
  • -maxrate-bufsize 设置最大码率和缓冲区大小。
  • -pix_fmt yuv420p 设置像素格式为YUV420P,这是RTMP兼容的格式。
  • -g 50 设置关键帧间隔为50帧。
  • -c:a aac 指定音频编码器为AAC。
  • -b:a-ac-ar 分别设置音频比特率、声道数和采样率。
  • -f flv 指定输出格式为FLV,RTMP流通常以FLV格式封装。
  • rtmp://[服务器地址]/[应用名称]/[流密钥] 是目标RTMP服务器的推送地址。

上述命令中的参数可能需要根据实际情况进行调整。

方案2:SmartRelaySDK

大牛直播SDK发布的RTSP转RTMP推送模块(SmartRelaySDK)C#的界面如下:

技术设计:

1. 拉流:通过RTSP直播播放SDK的数据回调接口,拿到音视频数据;

2. 转推:通过RTMP直播推送SDK的编码后数据输入接口,把回调上来的数据,传给RTMP直播推送模块,实现RTSP数据流到RTMP服务器的转发;

3. 录像:如果需要录像,借助RTSP直播播放SDK,拉到音视频数据后,直接存储MP4文件即可;

4. 快照:如果需要实时快照,拉流后,解码调用播放端快照接口,生成快照,因为快照涉及到video数据解码,如无必要,可不必开启,不然会额外消耗性能。

5. 拉流预览:如需预览拉流数据,只要调用播放端的播放接口,即可实现拉流数据预览;

6. 数据转AAC后转发:考虑到好多监控设备出来的音频可能是PCMA/PCMU的,如需要更通用的音频格式,可以转AAC后,在通过RTMP推送;

7. 转推RTMP实时静音:只需要在传audio数据的地方,加个判断即可;

8. 拉流速度反馈:通过RTSP播放端的实时码率反馈event,拿到实时带宽占用即可;

9. 整体网络状态反馈:考虑到有些摄像头可能会临时或异常关闭,RTMP服务器亦是,可以通过推拉流的event回调状态,查看那整体网络情况,如此界定:是拉不到流,还是推不到RTMP服务器。

上述是C#的基础demo,如果对C++比较熟悉,也可以直接用C++的,大牛直播SDK的RTSP转RTMP推送模块,通过配置xml的形式,程序启动后,从configure.xml读取相关的参数,实现一键拉流转发。

常规的参数配置,比如推拉流的rtsp rtmp url,如果需要自采集audio,设置采集的audio类型,比如rtsp自带audio、麦克风、扬声器或麦克风扬声器混音。

代码语言:xml
AI代码解释
复制
<?xml version="1.0" encoding="utf-8" ?>
<StreamRelays>
  <Relay>
    <id>0</id>
	<AudioOption>4</AudioOption>
    <PullUrl>rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream00</PushUrl>
  </Relay>
  <Relay>
    <id>1</id>
	<AudioOption>1</AudioOption>
    <PullUrl>rtsp://admin:admin123456@192.168.0.121:554/cam/realmonitor?channel=1<![CDATA[&]]>subtype=0</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream01</PushUrl>
  </Relay>
  <Relay>
    <id>2</id>
	<AudioOption>3</AudioOption>
    <PullUrl>rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream02</PushUrl>
  </Relay>
  <Relay>
    <id>3</id>
	<AudioOption>3</AudioOption>
    <PullUrl>rtsp://admin:admin123456@192.168.0.121:554/cam/realmonitor?channel=1<![CDATA[&]]>subtype=0</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream03</PushUrl>
  </Relay>
    <Relay>
    <id>4</id>
	<AudioOption>4</AudioOption>
    <PullUrl>rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream04</PushUrl>
  </Relay>
  <Relay>
    <id>5</id>
	<AudioOption>1</AudioOption>
    <PullUrl>rtsp://admin:admin123456@192.168.0.121:554/cam/realmonitor?channel=1<![CDATA[&]]>subtype=0</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream05</PushUrl>
  </Relay>
  <Relay>
    <id>6</id>
	<AudioOption>4</AudioOption>
    <PullUrl>rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream06</PushUrl>
  </Relay>
  <Relay>
    <id>7</id>
	<AudioOption>2</AudioOption>
    <PullUrl>rtsp://admin:admin123456@192.168.0.121:554/cam/realmonitor?channel=1<![CDATA[&]]>subtype=0</PullUrl>
    <PushUrl>rtmp://192.168.0.103:1935/hls/stream07</PushUrl>
  </Relay>
</StreamRelays>

封装代码如下:

代码语言:csharp
AI代码解释
复制
/*
 * nt_relay_wrapper.cs.cs
 * nt_relay_wrapper.cs
 * 
 * WebSite: https://daniusdk.com
 * WeChat: xinsheng120
 * 
 * Created by DaniuLive on 2017/11/14.
 * Copyright © 2014~2024 DaniuLive. All rights reserved.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace SmartRelayDemo
{
    class nt_relay_wrapper
    {
        int relay_index_;
        nt_player_wrapper player_wrapper_;
        nt_publisher_wrapper publisher_wrapper_;
 
        UInt32 video_option_ = (UInt32)NT.NTSmartPublisherDefine.NT_PB_E_VIDEO_OPTION.NT_PB_E_VIDEO_OPTION_ENCODED_DATA;
        UInt32 audio_option_ = (UInt32)NT.NTSmartPublisherDefine.NT_PB_E_AUDIO_OPTION.NT_PB_E_AUDIO_OPTION_ENCODED_DATA;
 
        public nt_player_wrapper GetPlayerWrapper() { return player_wrapper_; }
        public nt_publisher_wrapper GetPublisherWrapper() { return publisher_wrapper_; }
 
        public nt_relay_wrapper(int index, System.Windows.Forms.Control render_wnd, System.ComponentModel.ISynchronizeInvoke sync_invoke)
        {
            relay_index_ = index;
            player_wrapper_ = new nt_player_wrapper(index, render_wnd, sync_invoke);
            publisher_wrapper_ = new nt_publisher_wrapper(index, render_wnd, sync_invoke);
        }
 
        ~nt_relay_wrapper() { }
 
        private void OnVideoDataHandle(IntPtr handle, IntPtr user_data,
            UInt32 video_codec_id, IntPtr data, UInt32 size,
            IntPtr info, IntPtr reserve)
        {
            if (publisher_wrapper_.is_rtmp_publishing())
            {
                publisher_wrapper_.OnVideoDataHandle(handle, user_data, video_codec_id, data, size, info, reserve);
            }
        }
 
        private void OnAudioDataHandle(IntPtr handle, IntPtr user_data,
            UInt32 audio_codec_id, IntPtr data, UInt32 size,
            IntPtr info, IntPtr reserve)
        {
            if (publisher_wrapper_.is_rtmp_publishing())
            {
                publisher_wrapper_.OnAudioDataHandle(handle, user_data, audio_codec_id, data, size, info, reserve);
            }
        }
 
        public void StartPull(String url)
        {
            if (!player_wrapper_.is_pulling())
            {
                player_wrapper_.SetBuffer(0);
 
                if (!player_wrapper_.StartPull(url, false))
                    return;
 
                player_wrapper_.EventOnVideoDataHandle += new nt_player_wrapper.DelOnVideoDataHandle(OnVideoDataHandle);
 
                if (audio_option_ == (UInt32)NT.NTSmartPublisherDefine.NT_PB_E_AUDIO_OPTION.NT_PB_E_AUDIO_OPTION_ENCODED_DATA)
                {
                    player_wrapper_.EventOnAudioDataHandle += new nt_player_wrapper.DelOnAudioDataHandle(OnAudioDataHandle);
                }
            }
        }
 
        public void StopPull()
        {
            player_wrapper_.StopPull();
        }
 
        public void StartPlayer(String url, bool is_rtsp_tcp_mode, bool is_mute)
        {
            player_wrapper_.SetBuffer(0);
 
            if (!player_wrapper_.StartPlay(url, is_rtsp_tcp_mode, is_mute))
                return;
        }
 
        public void StopPlayer()
        {
            player_wrapper_.StopPlay();
        }
 
        public void PlayerDispose()
        {
            player_wrapper_.Dispose();
        }
 
        public void SetPusherOption(UInt32 video_option, UInt32 audio_option)
        {
            video_option_ = video_option;
            audio_option_ = audio_option;
        }
 
        public void StartPublisher(String url)
        {
            if (!publisher_wrapper_.OpenPublisherHandle(video_option_, audio_option_))
                return;
 
            if (url.Length < 8)
            {
                publisher_wrapper_.try_close_handle();
                return;
            }
 
            if (!publisher_wrapper_.StartPublisher(url))
            {
                return;
            }
        }
 
        public void StopPublisher()
        {
            publisher_wrapper_.StopPublisher();
        }
 
        public void PublisherDispose()
        {
            publisher_wrapper_.Dispose();
        }
    }
}

如需播放,播放端封装逻辑实现如下:

代码语言:csharp
AI代码解释
复制
/*
 * nt_player_wrapper.cs
 * nt_player_wrapper
 * 
 * WebSite: https://daniusdk.com
 * 
 * Created by DaniuLive on 2017/11/14.
 * Copyright © 2014~2024 DaniuLive. All rights reserved.
 */
 
public bool is_playing() {  return is_playing_; }
 
public bool is_pulling() {  return is_pulling_; }
	
public bool is_recording() { return is_recording_; }
 
public static bool is_zero_ptr(IntPtr ptr) { return IntPtr.Zero == ptr; }
 
public bool is_empty_handle() { return is_zero_ptr(player_handle_); }
 
private bool is_running()
{
	if (is_empty_handle())
		return false;
 
	return is_playing_ || is_recording_ || is_pulling_;
}
 
public bool OpenPullHandle(String url, bool is_rtsp_tcp_mode, bool is_mute)
{
	if ( player_handle_ != IntPtr.Zero )
		return true;
 
	if ( String.IsNullOrEmpty(url) )
		return false;
 
	IntPtr pull_handle = IntPtr.Zero;
 
	if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPlayerSDK.NT_SP_Open(out pull_handle, IntPtr.Zero, 0, IntPtr.Zero))
	{
		return false;
	}
 
	if (pull_handle == IntPtr.Zero)
	{
		return false;
	}
 
	pull_event_call_back_ = new SP_SDKEventCallBack(SDKPullEventCallBack);
	NTSmartPlayerSDK.NT_SP_SetEventCallBack(pull_handle, IntPtr.Zero, pull_event_call_back_);
 
	resolution_notify_callback_ = new ResolutionNotifyCallback(PlaybackWindowResized);
 
	set_video_frame_call_back_ = new VideoFrameCallBack(SDKVideoFrameCallBack);
 
	NTSmartPlayerSDK.NT_SP_SetBuffer(pull_handle, play_buffer_);
	NTSmartPlayerSDK.NT_SP_SetFastStartup(pull_handle, 1);
	NTSmartPlayerSDK.NT_SP_SetRtspAutoSwitchTcpUdp(pull_handle, 1);
	NTSmartPlayerSDK.NT_SP_SetRTSPTcpMode(pull_handle, is_rtsp_tcp_mode ? 1 : 0);
 
	NTSmartPlayerSDK.NT_SP_SetMute(pull_handle, is_mute_ ? 1 : 0);
 
	NTSmartPlayerSDK.NT_SP_SetAudioVolume(pull_handle, cur_audio_volume_);
 
	Int32 is_report = 1;
	Int32 report_interval = 3;
	NTSmartPlayerSDK.NT_SP_SetReportDownloadSpeed(pull_handle, is_report, report_interval);
 
	//RTSP timeout设置
	Int32 rtsp_timeout = 10;
	NTSmartPlayerSDK.NT_SP_SetRtspTimeout(pull_handle, rtsp_timeout);
 
	//RTSP TCP/UDP自动切换设置
	Int32 is_auto_switch_tcp_udp = 1;
	NTSmartPlayerSDK.NT_SP_SetRtspAutoSwitchTcpUdp(pull_handle, is_auto_switch_tcp_udp);
 
	if (NTBaseCodeDefine.NT_ERC_OK != NTSmartPlayerSDK.NT_SP_SetURL(pull_handle, url))
	{
		NTSmartPlayerSDK.NT_SP_Close(pull_handle);
		pull_handle = IntPtr.Zero;
		return false;
	}
 
	player_handle_ = pull_handle;
 
	return true;
}
 
private void PlaybackWindowResized(Int32 width, Int32 height)
{
	String resolution = width + "*" + height;
	EventGetVideoSize(player_index_, resolution);
}
 
public void SP_SDKVideoSizeHandle(IntPtr handle, IntPtr userData, Int32 width, Int32 height)
{
	if (null == sync_invoke_)
		return;
 
	System.ComponentModel.ISynchronizeInvoke sync_invoke_target = sync_invoke_.Target as System.ComponentModel.ISynchronizeInvoke;
 
	if (sync_invoke_target != null)
	{
		if (sync_invoke_target.InvokeRequired)
		{
			sync_invoke_target.BeginInvoke(resolution_notify_callback_, new object[] { width, height });
		}
		else
		{
			resolution_notify_callback_(width, height);
		}
	}
 
}
 
public bool StartPlay(String url, bool is_rtsp_tcp_mode, bool is_mute)
{
	if ( is_playing_ )
		return false;
 
	if (!is_pulling() && !is_recording())
	{
		if (!OpenPullHandle(url, is_rtsp_tcp_mode, is_mute))
			return false;
	}
 
	//video resolution callback
	video_size_call_back_ = new SP_SDKVideoSizeCallBack(SP_SDKVideoSizeHandle);
	NTSmartPlayerSDK.NT_SP_SetVideoSizeCallBack(player_handle_, IntPtr.Zero, video_size_call_back_);
 
	bool is_support_d3d_render = false;
	Int32 in_support_d3d_render = 0;
 
	if (NT.NTBaseCodeDefine.NT_ERC_OK == NTSmartPlayerSDK.NT_SP_IsSupportD3DRender(player_handle_, render_wnd_.Handle, ref in_support_d3d_render))
	{
		if (1 == in_support_d3d_render)
		{
			is_support_d3d_render = true;
		}
	}
 
	// is_support_d3d_render = false;
 
	if (is_support_d3d_render)
	{
		// 支持d3d绘制的话,就用D3D绘制
		NTSmartPlayerSDK.NT_SP_SetRenderWindow(player_handle_, render_wnd_.Handle);
		NTSmartPlayerSDK.NT_SP_SetRenderScaleMode(player_handle_, 1);
	}
	else
	{
		// 不支持D3D就让播放器吐出数据来,用GDI绘制,本demo仅用来展示一对一互动使用,具体可参考播放端的demo
 
		//video frame callback (YUV/RGB)
		//format请参见 NT_SP_E_VIDEO_FRAME_FORMAT,如需回调YUV,请设置为 NT_SP_E_VIDEO_FRAME_FROMAT_I420
		video_frame_call_back_ = new SP_SDKVideoFrameCallBack(SetVideoFrameCallBack);
		NTSmartPlayerSDK.NT_SP_SetVideoFrameCallBack(player_handle_, (Int32)NT.NTSmartPlayerDefine.NT_SP_E_VIDEO_FRAME_FORMAT.NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, IntPtr.Zero, video_frame_call_back_);
	}
 
	uint ret = NTSmartPlayerSDK.NT_SP_StartPlay(player_handle_);
	if ( NTBaseCodeDefine.NT_ERC_OK != ret )
	{
		NTSmartPlayerSDK.NT_SP_Close(player_handle_);
		player_handle_ = IntPtr.Zero;
 
		return false;
	}
 
	is_playing_ = true;
 
	return true;
}
 
public void StopPlay(bool is_update_ui =true)
{
	if ( !is_playing_ )
		return;
 
	NTSmartPlayerSDK.NT_SP_StopPlay(player_handle_);
 
	if (!is_pulling() && !is_recording())
	{
		NTSmartPlayerSDK.NT_SP_Close(player_handle_);
		player_handle_ = IntPtr.Zero;
	}
 
	is_playing_ = false;
 
	if (is_update_ui && render_wnd_ != null)
	{
		render_wnd_.Invalidate();
	}
}
 
public bool StartPull(String url, bool is_rtsp_tcp_mode)
{
	if (is_pulling())
		return false;
 
	if (!is_playing() && !is_recording())
	{
		if (!OpenPullHandle(url, is_rtsp_tcp_mode, is_mute_))
			return false;
	}
 
	pull_stream_video_data_call_back_ = new SP_SDKPullStreamVideoDataCallBack(OnVideoDataHandle);
	pull_stream_audio_data_call_back_ = new SP_SDKPullStreamAudioDataCallBack(OnAudioDataHandle);
 
	NTSmartPlayerSDK.NT_SP_SetPullStreamVideoDataCallBack(player_handle_, IntPtr.Zero, pull_stream_video_data_call_back_);
	NTSmartPlayerSDK.NT_SP_SetPullStreamAudioDataCallBack(player_handle_, IntPtr.Zero, pull_stream_audio_data_call_back_);
 
	int is_transcode_aac = 1;   //PCMA/PCMU/Speex格式转AAC后 再转发
	NTSmartPlayerSDK.NT_SP_SetPullStreamAudioTranscodeAAC(player_handle_, is_transcode_aac);
 
	UInt32 ret = NTSmartPlayerSDK.NT_SP_StartPullStream(player_handle_);
 
	if (NTBaseCodeDefine.NT_ERC_OK != ret)
	{
		if (!is_playing_)
		{
			NTSmartPlayerSDK.NT_SP_Close(player_handle_);
			player_handle_ = IntPtr.Zero;
		}
 
		return false;
	}
 
	is_pulling_ = true;
 
	return true;
}
 
public void StopPull()
{
	if (!is_pulling_)
		return;
 
	NTSmartPlayerSDK.NT_SP_StopPullStream(player_handle_);
 
	if (!is_playing() && !is_recording())
	{
		NTSmartPlayerSDK.NT_SP_Close(player_handle_);
		player_handle_ = IntPtr.Zero;
	}
 
	is_pulling_ = false;
}
 
private void OnVideoDataHandle(IntPtr handle, IntPtr user_data,
	UInt32 video_codec_id, IntPtr data, UInt32 size,
	IntPtr info, IntPtr reserve)
{
	EventOnVideoDataHandle(handle, user_data, video_codec_id, data, size, info, reserve);
}
 
private void OnAudioDataHandle(IntPtr handle, IntPtr user_data,
					UInt32 audio_codec_id, IntPtr data, UInt32 size,
					IntPtr info, IntPtr reserve)
{
	EventOnAudioDataHandle(handle, user_data, audio_codec_id, data, size, info, reserve);
}

总结

RTSP转RTMP模块设计,可以用ffmpeg直接命令行转发,也可以用方案二的非常成熟的转发设计,ffmpeg转发,需要有一定的代码基础,有问题的话,bug修复需要对底层逻辑非常了解才行,方案二,技术成熟,二次开发难度不大,很同意集成到自己现有系统,感兴趣的开发者,可以单独跟我沟通交流。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Windows平台C#版RTSP转RTMP直播推送定制版
前几年我们发布了C++版的多路RTMP/RTSP转RTMP转发官方定制版。在秉承低延迟、灵活稳定、低资源占用的前提下,客户无需关注开发细节,只需图形化配置转发等各类参数,实现产品快速上线目的。
音视频牛哥
2024/05/19
1980
Windows平台C#版RTSP转RTMP直播推送定制版
Unity平台如何实现RTSP转RTMP推送?
Unity平台下,RTSP、RTMP播放和RTMP推送,甚至包括轻量级RTSP服务这块都不再赘述,今天探讨的一位开发者提到的问题,如果在Unity下,实现RTSP播放的同时,随时转RTMP推送出去?
音视频牛哥
2023/07/14
2980
Unity平台如何实现RTSP转RTMP推送?
wpf下RTSP|RTMP播放器两种渲染模式实现
在这篇blog之前,我提到了wpf下播放RTMP和RTSP渲染的两种方式,一种是通过控件模式,另外一种是直接原生RTSP、RTMP播放模块,回调rgb,然后在wpf下渲染,本文就两种方式做个说明。
音视频牛哥
2024/04/14
3530
wpf下RTSP|RTMP播放器两种渲染模式实现
Windows平台基于RTMP实现一对一互动直播
基于 https://github.com/daniulive/SmarterStreaming/ 拉流端封装的代码:
音视频牛哥
2020/04/05
9490
Unity下如何实现RTMP或RTSP流播放和录制
在探讨Unity平台RTMP或RTSP直播流数据播放和录制之前,我们先简单回顾下RTSP或RTMP直播流数据在Unity平台的播放流程:
音视频牛哥
2022/12/24
2.2K0
Unity下如何实现RTMP或RTSP流播放和录制
低延迟播放超高分辨率(4K+)帧率(50帧+)RTSP|RTMP流技术探讨和实现
我们在对接RTSP、RTMP推拉流播放的时候,开发者提到这样的技术诉求,他们在用于安检等场景的时候,采集分辨率甚至需要4K+,帧率需要达到50帧以上,码率也非常高,这就对推流和播放模块,提出了更高的要求。
音视频牛哥
2024/07/15
3090
低延迟播放超高分辨率(4K+)帧率(50帧+)RTSP|RTMP流技术探讨和实现
Windows平台如何实现多路RTSP|RTMP流合成后录像或转发RTMP服务
我们在对接Windows平台RTSP|RTMP直播播放模块的时候,有开发者提出来这样的技术需求,他们做驾考、全景摄像头、多路会议录制等场景的时候,希望把多路视频流数据,合并到一路保存或者对外推送到RTMP服务。
音视频牛哥
2024/07/15
2650
Windows平台如何实现多路RTSP|RTMP流合成后录像或转发RTMP服务
Windows平台如何实现RTSP拉流添加动态水印|视频处理后转推RTMP或轻量级RTSP服务
我们在做Windows平台流数据转发的时候,除了常规的RTSP转RTMP推送外,还有个场景就是,好多开发者希望拉取的RTSP流,做二次视频分析,或者加动态水印等,处理后的数据,再二次编码推送到RTMP服务或轻量级RTSP服务。
音视频牛哥
2023/12/27
4820
Windows平台如何实现RTSP拉流添加动态水印|视频处理后转推RTMP或轻量级RTSP服务
Windows平台RTSP|RTMP播放器如何实现细粒度录像控制
好多开发者在跟我做技术交流的时候,说用大牛直播SDK模块的特点是,想到什么功能,找找头文件和demo几乎都有对应的实现,你们是何收集到这么多技术需求的?
音视频牛哥
2024/04/17
6840
Windows平台RTSP|RTMP播放器如何实现细粒度录像控制
Windows平台RTSP播放器、RTMP播放器几点设计细节讨论
我们在实现Windows平台RTSP播放器或RTMP播放器的时候,需要考虑的点很多,比如多实例设计、多绘制模式兼容、软硬解码支持、快照、RTSP下TCP-UDP自动切换等,以下就其中几个方面,做个大概的探讨:
音视频牛哥
2020/06/07
1.6K0
Windows平台如何实现RTSP|RTMP流录像?
​好多开发者使用场景,除了实现基础的低延迟RTSP、RTMP播放外,还需要实现RTSP、RTMP流数据的本地录像功能。本文以大牛直播SDK的Windows平台播放模块为例,介绍下如何实现RTSP、RTMP流录像。
音视频牛哥
2024/10/01
2450
Windows平台如何实现RTSP|RTMP流录像?
跨平台低延迟RTSP转RTMP推送技术方案探讨
实现RTSP摄像头数据转RTMP推送到服务器,可以用第三方库或者工具实现,总体设计架构如下:
音视频牛哥
2023/07/11
1.1K0
跨平台低延迟RTSP转RTMP推送技术方案探讨
wpf下如何实现超低延迟的RTMP或RTSP播放
我们在做Windows平台RTMP和RTSP播放模块对接的时候,有开发者需要在wpf下调用,如果要在wpf下使用,只需要参考C#的对接demo即可,唯一不同的是,视频流数据显示的话,要么通过控件模式,要么可以让RTMP、RTSP播放模块回调rgb数据上来,在wpf直接绘制即可。
音视频牛哥
2024/04/10
5380
wpf下如何实现超低延迟的RTMP或RTSP播放
Unity3D下Linux平台播放RTSP或RTMP流
尽管Windows平台有诸多优势,Linux平台的发展还是势不可挡,特别实在传统行业,然而Linux生态构建,总是差点意思,特别是有些常用的组件,本文基于已有的Linux平台RTSP、RTMP播放模块,构建Unity下的RTSP和RTMP直播播放。
音视频牛哥
2022/04/01
1.2K0
Windows平台如何实现RTSP流二次编码并添加动态水印后推送RTMP或轻量级RTSP服务
我们在对接RTSP播放器相关的技术诉求的时候,遇到这样的需求,客户做特种设备巡检的,需要把摄像头拍到的RTSP流拉下来,然后添加动态水印后,再生成新的RTSP URL,供平台调用。真个流程需要延迟尽可能的低,分辨率要支持到1080p,并需要把添加过动态水印的数据,保存到本地。
音视频牛哥
2023/11/22
4860
Windows平台如何实现RTSP流二次编码并添加动态水印后推送RTMP或轻量级RTSP服务
如何在Unity3d实现多路RTSP或RTMP流播放
好多开发者在做AR、VR或者教育类产品时,苦于如何在windows平台构建一个稳定且低延迟的RTSP或者RTMP播放器,如果基于Unity3d完全重新开发一个播放器,代价大、而且周期长,不适合快速出产品,我们认为当前最好的方式就是集成现有Native平台上成熟稳定播放器,回调rgb/yuv数据到上层,上层做绘制即可。
音视频牛哥
2021/03/12
2.3K0
如何在Unity3d实现多路RTSP或RTMP流播放
RTSP播放器实现回调RGB|YUV给视觉算法,然后二次编码推送到RTMP服务
在本文中,我们将介绍如何基于大牛直播SDK构建一个功能强大的RTSP|RTMP播放器,该播放器利用自定义SDK解码视频、处理RGB帧,并将其推送到RTMP流中进行直播。这个解决方案非常适合需要在实时视频流中集成视觉算法的场景,在处理后将数据推送到RTMP服务器。我们将详细探讨播放器的架构、回调处理以及图像帧的操作过程。
音视频牛哥
2025/04/24
780
RTSP播放器实现回调RGB|YUV给视觉算法,然后二次编码推送到RTMP服务
深度解析大牛直播SDK在RTSP播放器中的集成与优化实践
RTSP(Real Time Streaming Protocol)作为实时流媒体传输协议,广泛应用于安防监控、直播推流等场景。本文基于大牛直播SDK(SmartPlayer SDK),结合C# WinForm实现了一个功能完备的RTSP播放器,涵盖直播播放、录像、全屏切换、硬件加速等核心功能。我们将从技术实现、性能优化、问题排查等维度,深入探讨SDK集成过程中的关键问题与解决方案。
音视频牛哥
2025/02/22
2450
深度解析大牛直播SDK在RTSP播放器中的集成与优化实践
D3D还是GDI? Windows平台播放RTSP或RTMP渲染模式比较
好多开发者纠结播放端绘制,是D3D还是GDI,先说结论,Windows平台播放渲染这块,支持D3D的前提下,优先D3D,如果检测到不支持D3D,数据回调上来,GDI模式绘制。
音视频牛哥
2020/06/20
1.4K0
QT下实现低延迟RTSP|RTMP播放器
好多开发者在QT环境下实现RTMP或RTSP播放时,首先考虑到的是集成VLC,集成后,却发现VLC在延迟、断网重连、稳定性等各个方面不尽人意,无法满足上线环境需求。本文以调用大牛直播SDK(官方)的Windows平台播放端SDK为例,介绍下如何在QT下实现低延迟的RTMP|RTSP播放器,废话不多说,先上图:
音视频牛哥
2021/04/30
1.9K0
推荐阅读
相关推荐
Windows平台C#版RTSP转RTMP直播推送定制版
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档