利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中
既然已经可以通过 RTSP 获取h264 裸流了。那么通过 FFmpeg 将其保存到文件中怎么做呢?
一、首先RTSP获取 h264 裸流
我们上面两篇文章主要讲的是通过 rtsp://Your ip:554/stream_chn0.h265 播放H.265视频流。
PS:我刚试了一下,我的 FFmpeg 程序暂时不支持 h265 ... 之前编译的时候,只提供了 x264没有x265
如果感兴趣参看下面两篇文章添加。
参看:使用VS2015添加对ffmpeg添加h265 支持。
再结合之前讲的,FFmepg 再学习系列,应该是没问题的。不过好久没有弄了,早忘了了。
那现在没有可以播放的 H.264 视频流了啊,怎么办?
有办法之前讲过一篇文章,参看:LIVE555再学习 -- VLC搭建RTSP服务器(转) 用VLC搭建一个不就完了。
当然还可以直接用 live555,参看:LIVE555再学习 -- live555实现RTSP直播服务器 (推荐)
二、FFmpeg 将H.264 裸流保存到文件
这个也好说,之前有讲到,参看:FFmpeg再学习 -- SDL 环境搭建和视频显示
将其改改就可以了。
具体代码如下:
参看:利用ffmpeg将RTSP传输的h264原始码流保存到文件中
- #include "stdafx.h"
- #include <stdio.h>
- #define __STDC_CONSTANT_MACROS
- #ifdef _WIN32
- //Windows
- extern "C"
- {
- #include "libavcodec/avcodec.h"
- #include "libavformat/avformat.h"
- #include "libswscale/swscale.h"
- #include "SDL2/SDL.h"
- };
- #else
- //Linux...
- #ifdef __cplusplus
- extern "C"
- {
- #endif
- #include <libavcodec/avcodec.h>
- #include <libavformat/avformat.h>
- #include <libswscale/swscale.h>
- #include <SDL2/SDL.h>
- #ifdef __cplusplus
- };
- #endif
- #endif
- int main(int argc, char* argv[])
- {
- AVFormatContext *pFormatCtx;
- int i, videoindex;
- AVCodecContext *pCodecCtx;
- AVCodec *pCodec;
- AVFrame *pFrame, *pFrameYUV;
- uint8_t *out_buffer;
- AVPacket *packet;
- int ret, got_picture;
- struct SwsContext *img_convert_ctx;
- // 改成你自己的 URL
- char filepath[] = "rtsp://192.168.2.xx:8554/1";
- av_register_all();
- avformat_network_init();
- pFormatCtx = avformat_alloc_context();
- if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0)////打开网络流或文件流
- {
- printf("Couldn't open input stream.\n");
- return -1;
- }
- if (avformat_find_stream_info(pFormatCtx, NULL)<0)
- {
- printf("Couldn't find stream information.\n");
- return -1;
- }
- videoindex = -1;
- for (i = 0; i<pFormatCtx->nb_streams; i++)
- if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- videoindex = i;
- break;
- }
- if (videoindex == -1)
- {
- printf("Didn't find a video stream.\n");
- return -1;
- }
- pCodecCtx = pFormatCtx->streams[videoindex]->codec;
- pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
- if (pCodec == NULL)
- {
- printf("Codec not found.\n");
- return -1;
- }
- if (avcodec_open2(pCodecCtx, pCodec, NULL)<0)
- {
- printf("Could not open codec.\n");
- return -1;
- }
- pFrame = av_frame_alloc();
- pFrameYUV = av_frame_alloc();
- out_buffer = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
- avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
- //Output Info---输出一些文件(RTSP)信息
- printf("---------------- File Information ---------------\n");
- av_dump_format(pFormatCtx, 0, filepath, 0);
- printf("-------------------------------------------------\n");
- img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
- pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
- packet = (AVPacket *)av_malloc(sizeof(AVPacket));
- FILE *fpSave;
- if ((fpSave = fopen("geth264.h264", "ab")) == NULL) //h264保存的文件名
- return 0;
- for (;;)
- {
- //------------------------------
- if (av_read_frame(pFormatCtx, packet) >= 0)
- {
- if (packet->stream_index == videoindex)
- {
- fwrite(packet->data, 1, packet->size, fpSave);//写数据到文件中
- }
- av_free_packet(packet);
- }
- }
- //--------------
- av_frame_free(&pFrameYUV);
- av_frame_free(&pFrame);
- avcodec_close(pCodecCtx);
- avformat_close_input(&pFormatCtx);
- return 0;
- }
调试结果显示如下:
生成 geth264.h264 文件,可播放。
三、工程下载
下载:利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中 工程
思考,这里就有两个问题未完成,一个就是怎么将 H265的裸流保存到文件,再有怎么保存成其他格式比如MP4。
保存到MP4文件代码如下:
- #include "stdafx.h"
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <libavcodec/avcodec.h>
- #include <libavdevice/avdevice.h>
- #include <libavformat/avformat.h>
- #include <libavfilter/avfilter.h>
- #include <libavutil/avutil.h>
- #include <libswscale/swscale.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #ifdef __cplusplus
- }
- #endif
- AVFormatContext *i_fmt_ctx;
- AVStream *i_video_stream;
- AVFormatContext *o_fmt_ctx;
- AVStream *o_video_stream;
- int _tmain(int argc, char **argv)
- {
- avcodec_register_all();
- av_register_all();
- avformat_network_init();
- /* should set to NULL so that avformat_open_input() allocate a new one */
- i_fmt_ctx = NULL;
- char rtspUrl[] = "rtsp://192.168.2.xx:8554/H264unicast";
- const char *filename = "1.mp4";
- if (avformat_open_input(&i_fmt_ctx, rtspUrl, NULL, NULL) != 0)
- {
- fprintf(stderr, "could not open input file\n");
- return -1;
- }
- if (avformat_find_stream_info(i_fmt_ctx, NULL)<0)
- {
- fprintf(stderr, "could not find stream info\n");
- return -1;
- }
- //av_dump_format(i_fmt_ctx, 0, argv[1], 0);
- /* find first video stream */
- for (unsigned i = 0; i<i_fmt_ctx->nb_streams; i++)
- {
- if (i_fmt_ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- {
- i_video_stream = i_fmt_ctx->streams[i];
- break;
- }
- }
- if (i_video_stream == NULL)
- {
- fprintf(stderr, "didn't find any video stream\n");
- return -1;
- }
- avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, filename);
- /*
- * since all input files are supposed to be identical (framerate, dimension, color format, ...)
- * we can safely set output codec values from first input file
- */
- o_video_stream = avformat_new_stream(o_fmt_ctx, NULL);
- {
- AVCodecContext *c;
- c = o_video_stream->codec;
- c->bit_rate = 400000;
- c->codec_id = i_video_stream->codec->codec_id;
- c->codec_type = i_video_stream->codec->codec_type;
- c->time_base.num = i_video_stream->time_base.num;
- c->time_base.den = i_video_stream->time_base.den;
- fprintf(stderr, "time_base.num = %d time_base.den = %d\n", c->time_base.num, c->time_base.den);
- c->width = i_video_stream->codec->width;
- c->height = i_video_stream->codec->height;
- c->pix_fmt = i_video_stream->codec->pix_fmt;
- printf("%d %d %d", c->width, c->height, c->pix_fmt);
- c->flags = i_video_stream->codec->flags;
- c->flags |= CODEC_FLAG_GLOBAL_HEADER;
- c->me_range = i_video_stream->codec->me_range;
- c->max_qdiff = i_video_stream->codec->max_qdiff;
- c->qmin = i_video_stream->codec->qmin;
- c->qmax = i_video_stream->codec->qmax;
- c->qcompress = i_video_stream->codec->qcompress;
- }
- avio_open(&o_fmt_ctx->pb, filename, AVIO_FLAG_WRITE);
- avformat_write_header(o_fmt_ctx, NULL);
- int last_pts = 0;
- int last_dts = 0;
- int64_t pts, dts;
- while (1)
- {
- AVPacket i_pkt;
- av_init_packet(&i_pkt);
- i_pkt.size = 0;
- i_pkt.data = NULL;
- if (av_read_frame(i_fmt_ctx, &i_pkt) <0)
- break;
- /*
- * pts and dts should increase monotonically
- * pts should be >= dts
- */
- i_pkt.flags |= AV_PKT_FLAG_KEY;
- pts = i_pkt.pts;
- i_pkt.pts += last_pts;
- dts = i_pkt.dts;
- i_pkt.dts += last_dts;
- i_pkt.stream_index = 0;
- //printf("%lld %lld\n", i_pkt.pts, i_pkt.dts);
- static int num = 1;
- printf("frame %d\n", num++);
- av_interleaved_write_frame(o_fmt_ctx, &i_pkt);
- //av_free_packet(&i_pkt);
- //av_init_packet(&i_pkt);
- }
- last_dts += dts;
- last_pts += pts;
- avformat_close_input(&i_fmt_ctx);
- av_write_trailer(o_fmt_ctx);
- avcodec_close(o_fmt_ctx->streams[0]->codec);
- av_freep(&o_fmt_ctx->streams[0]->codec);
- av_freep(&o_fmt_ctx->streams[0]);
- avio_close(o_fmt_ctx->pb);
- av_free(o_fmt_ctx);
- return 0;
- }
利用FFmpeg 将 rtsp 获取H264裸流并保存到文件中的更多相关文章
- ffmpeg学习(二) 通过rtsp获取H264裸流并保存到mp4文件
本篇将使用上节http://www.cnblogs.com/wenjingu/p/3977015.html中编译好的库文件通过rtsp获取网络上的h264裸流并保存到mp4文件中. 1.VS2010建 ...
- 【嵌入式开发】用 VLC 显示 树莓派摄像头 H264 裸流
首先树莓派连上网络,并和电脑在同一网段. 树莓派的IP是: 192.168.3.13 电脑的IP是: 192.168.3.6 1.在树莓派上采集 H264裸流,并用UDP发送到电脑. pi@Neil- ...
- jmeter 发送http请求,并把获取到的请求的订单信息保存到文件中
有一个任务,需要频繁发送订单请求,并分析订单请求中有没有存在重复订单号,思路是用jmeter 发送http请求,使用正则表达式获取到订单号,并把订单号和线程号作为参数提供给java请求,在java请求 ...
- H264裸流分析中,能获取哪些信息?
从H264的裸流中,PPS,SPS中,一定可以获取到的,有图像的宽,高信息. 这部分信息的提取,用Stream eye 分析: 这里需要特别提一下这两个参数: pic_width_in_mbs_mi ...
- 利用FFmpeg将RTSP转码成RTMP发布在RED5
安装jdk,并设置环境 from:http://www.w3c.com.cn/%E5%88%A9%E7%94%A8ffmpeg%E5%B0%86-ipcamera-%E7%9A%84rtsp%E8% ...
- FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放
前言 ffmpeg播放rtsp网络流和摄像头流. Demo 使用ffmpeg播放局域网rtsp1080p海康摄像头:延迟0.2s,存在马赛克 使用ffmpeg播放网络rtsp文件流 ...
- H264裸码流I/P/B帧类型判别
花了两天时间做了个h264裸流nal类型和frame类型检测的工具,已上传至github,有需要的自行下载. 1.NAL类型检测 nal类型检测非常容易,对照下表即可容易判断类型. 较常用nal类型包 ...
- 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统
了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...
- (原)关于获取ffmpeg解析rtsp流sdp中带有sps,pps的情况
转载请注明出处:http://www.cnblogs.com/lihaiping/p/6612511.html 今天同事准备在android下使用ffmpeg来获取rtsp流,问我如何获取获取sps ...
随机推荐
- STM32F207时钟系统解析
在前几天的文章<晶振原理解析>中介绍了晶振如何产生时钟的,板子使用的是25M无源晶振,下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的. 01.时钟系 ...
- USB充电限流芯片,输出短路关闭,过压关闭
PW1503,PW1502是超低RDS(ON)开关,具有可编程的电流限制,以保护电源源于过电流和短路保护.它具有超温保护以及反向闭锁功能. PW1503,PW1502采用薄型(1毫米)5针薄型SOT2 ...
- 10_1_OS模块
1.常用函数目录 函数名 功能 os.name 指示用户正在使用的工作平台 os.getcwd ( ) 获取当前的工作目录 os.listdir ( ) 返回指定目录下的所有文件和目录名 os.rem ...
- Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶
多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...
- 最佳的思维导图生成工具——markmap 使用教程
前言 相信很多程序员朋友都有在用 Markdown 吧,我是大三找实习工作的时候接触到的,简历就是用 Markdown 写的. Markdown 的好处是专注码字的同时还能兼顾排版,不用像 word ...
- 从零搭建一个IdentityServer——集成Asp.net core Identity
前面的文章使用Asp.net core 5.0以及IdentityServer4搭建了一个基础的验证服务器,并实现了基于客户端证书的Oauth2.0授权流程,以及通过access token访问被保护 ...
- 理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng 高可用架构 今天
理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng 高可用架构 今天
- Redis击穿、穿透、雪崩产生原因以及解决思路
击穿 大家都知道,计算机的瓶颈之一就是IO,为了解决内存与磁盘速度不匹配的问题,产生了缓存,将一些热点数据放在内存中,随用随取,降低连接到数据库的请求链接,避免数据库挂掉.需要注意的是,无论是击穿还是 ...
- ASP.NET Core 5.0 MVC中的 Razor 页面 介绍
Razor 是一个用于将基于服务器的代码嵌入到网页中的标记语法. Razor语法由 Razor 标记.c # 和 HTML 组成. 通常包含 Razor 的文件的扩展名 cshtml Razor 语法 ...
- 在 WebAssembly 中实现回调的方式
本文将介绍在 C++ 中实现 js 回调的几种方式. 在使用 wasm 的过程中, 避免不了要从 C++ 回调 js 的函数来实现异步交互. 官网文档 https://emscripten.org/d ...