公网 rtsp流源 测试地址_ffmpeg(六) FFMPEG实现RTSP中H264数据流解码 并且实时播放...

主要过程和ffmpeg实现视频播放的过程差不多 
可以参考:https://blog.csdn.net/yunge812/article/details/79342089

主要改动原始文件的读取 
播放器是播放本地文件 而我们这里需要读取的是RTSP中H264数据流

char filepath[1024] = "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov";
if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)
{
    qDebug()<<"Couldn't open input stream";
    return;
}

这里的rtsp地址是网络上用于测试的地址

之后的过程和实现播放器的过程完全一致 可以直接用来移植

效果:

a4b07e253eb192e85831f1ed3cb031a0.png

源码下载地址: 

https://download.csdn.net/download/yunge812/1031055098

更多详细解析以及源码可以参考本人csdn博客,里面有详细的解释

https://blog.csdn.net/yunge812

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在C#使用FFmpeg播放RTSP H264视频流并将其显示到窗体上,你可以使用FFmpeg.AutoGen库来实现。以下是一个简单的示例代码: 首先,你需要在项目引用FFmpeg.AutoGen库。你可以通过NuGet包管理器来安装它。 然后,你可以使用以下代码来实现播放RTSP视频流并将其显示到窗体上: ```csharp using System; using System.Drawing; using System.Windows.Forms; using FFmpeg.AutoGen; namespace RTSPPlayer { public partial class MainForm : Form { private AVFormatContext* _formatContext; private AVCodecContext* _codecContext; private AVFrame* _frame; private AVPacket _packet; private SwsContext* _swsContext; private IntPtr _videoFrameBuffer; private Bitmap _bitmap; private bool _isPlaying; public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { // 初始化FFmpeg ffmpeg.av_register_all(); ffmpeg.avformat_network_init(); // 打开RTSP流 string rtspUrl = "your_rtsp_url"; AVDictionary* options = null; ffmpeg.av_dict_set(&options, "rtsp_transport", "tcp", 0); ffmpeg.av_dict_set(&options, "stimeout", "5000000", 0); int result = ffmpeg.avformat_open_input(&_formatContext, rtspUrl, null, &options); if (result != 0) { MessageBox.Show("无法打开RTSP流"); return; } // 查找视频流信息 result = ffmpeg.avformat_find_stream_info(_formatContext, null); if (result < 0) { MessageBox.Show("无法找到视频流信息"); return; } // 查找视频流索引 int videoStreamIndex = -1; for (int i = 0; i < _formatContext->nb_streams; i++) { if (_formatContext->streams[i]->codecpar->codec_type == AVMediaType.AVMEDIA_TYPE_VIDEO) { videoStreamIndex = i; break; } } if (videoStreamIndex == -1) { MessageBox.Show("无法找到视频流"); return; } // 获取视频解码器 AVCodec* codec = ffmpeg.avcodec_find_decoder(_formatContext->streams[videoStreamIndex]->codecpar->codec_id); if (codec == null) { MessageBox.Show("无法找到视频解码器"); return; } // 创建解码器上下文 _codecContext = ffmpeg.avcodec_alloc_context3(codec); ffmpeg.avcodec_parameters_to_context(_codecContext, _formatContext->streams[videoStreamIndex]->codecpar); // 打开解码器 result = ffmpeg.avcodec_open2(_codecContext, codec, null); if (result < 0) { MessageBox.Show("无法打开视频解码器"); return; } // 创建帧对象 _frame = ffmpeg.av_frame_alloc(); // 创建包对象 ffmpeg.av_init_packet(&_packet); // 创建图像转换上下文 _swsContext = ffmpeg.sws_getContext(_codecContext->width, _codecContext->height, _codecContext->pix_fmt, _codecContext->width, _codecContext->height, AVPixelFormat.AV_PIX_FMT_BGR24, ffmpeg.SWS_BILINEAR, null, null, null); // 创建视频帧缓冲区 int bufferSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_BGR24, _codecContext->width, _codecContext->height, 1); _videoFrameBuffer = ffmpeg.av_malloc((ulong)bufferSize); ffmpeg.av_image_fill_arrays(_frame->data, _frame->linesize, (byte*)_videoFrameBuffer, AVPixelFormat.AV_PIX_FMT_BGR24, _codecContext->width, _codecContext->height, 1); // 创建位图对象 _bitmap = new Bitmap(_codecContext->width, _codecContext->height, _codecContext->width * 3, PixelFormat.Format24bppRgb, _videoFrameBuffer); // 开始播放 _isPlaying = true; Play(); } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { // 停止播放 _isPlaying = false; ffmpeg.av_packet_unref(&_packet); ffmpeg.av_frame_free(&_frame); ffmpeg.avcodec_close(_codecContext); ffmpeg.avformat_close_input(&_formatContext); ffmpeg.avformat_network_deinit(); ffmpeg.av_free(_videoFrameBuffer); ffmpeg.sws_freeContext(_swsContext); } private void Play() { while (_isPlaying) { // 读取一帧数据 int result = ffmpeg.av_read_frame(_formatContext, &_packet); if (result < 0) { // 读取失败,结束播放 _isPlaying = false; break; } if (_packet.stream_index == _formatContext->streams[0]->index) { // 解码视频帧 result = ffmpeg.avcodec_send_packet(_codecContext, &_packet); if (result < 0) { // 解码失败,跳过该帧 ffmpeg.av_packet_unref(&_packet); continue; } result = ffmpeg.avcodec_receive_frame(_codecContext, _frame); if (result < 0) { // 解码失败,跳过该帧 ffmpeg.av_packet_unref(&_packet); continue; } // 转换图像格式 ffmpeg.sws_scale(_swsContext, _frame->data, _frame->linesize, 0, _codecContext->height, _frame->data, _frame->linesize); // 刷新窗体 pictureBox.Image = _bitmap; pictureBox.Refresh(); } // 释放数据包 ffmpeg.av_packet_unref(&_packet); } } } } ``` 请注意,上述代码仅为示例,你需要根据实际情况进行适当的修改和调整。 相关问题: 1. 如何在C#使用FFmpeg播放RTSP视频流? 2. 如何在C#显示视频帧到窗体上? 3. 如何解码H264视频流? 4. 如何使用FFmpeg.AutoGen库在C#进行视频解码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值