热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

FFMPEG之RTSP获取H264/H265裸流保存文件

参考:https:blog.csdn.netweixin_42432281articledetails883481241目标背景本文的目的是实现linux嵌入式端f

参考:https://blog.csdn.net/weixin_42432281/article/details/88348124

1 目标背景
本文的目的是实现linux嵌入式端ffmpeg读取网络相机rtsp码流,不经过编解码操作,直接保存为视频文件,ffmpeg有命令的形式可以实现(参考《FFmpeg功能命令汇总》),但是无法灵活设置,而且调用起来也不方便,因此直接使用源码编译,提供功能接口

2 RTSP与H264
通常所说的rtsp协议其实包含三个协议: rtsp协议, rtp协议, rtcp协议。各协议运作流程概要:

第一阶段:rtsp协议负责沟通传输什么数据,传的是图像还是声音,还是两者混合?图像的话传是h264流,还是h265流,还是jpeg流?后续的rtp,rtcp协议是采用tcp还是udp,端口号是多少都是通过第一阶段的rtsp协议确定的。

第二阶段:通过rtp协议传输数据,rtcp进行网络传输质量的监控

第三阶段:通过rtsp协议中断整个协议的传输

3 ffmpeg安装
首先先将设备上的ffmpeg卸载干净,防止后续出错

sudo apt-get remove ffmpeg x264
sudo apt-get autoremove

3.1 x264安装
因为要保存成h264文件,需要有h264编解码器,安装ffmpeg的时候也必须要选择支持x264

git clone https://code.videolan.org/videolan/x264.git
cd x264
//如果git指令下载速度特别慢的话,可以在下边链接里下载压缩包
//https://www.videolan.org/developers/x264.html
./configure --enable-shared --enable-static --prefix=/usr/local
sudo make
sudo make install

3.2 x265安装
依次按照如下指令,注意由于我是在arm嵌入式板子上安装的,所以第3步选择的是arm-linux,自己要结合实际情况来选择,后续的操作方法是一样的

sudo apt-get install mercurial cmake cmake-curses-gui build-essential yasm
hg clone https://bitbucket.org/multicoreware/x265
cd x265/build/arm-linux
sudo sh ./make-Makefiles.bash
# 要把PIC选项打开,见下图,按下“g”退出
sudo make
sudo make install

在这里插入图片描述
3.3 ffmpeg安装
这里推荐采用源码安装,网上很多人推荐的apt安装方式装完之后,有些文件和文件夹找不到,使用源码安装,可以自己配置安装路径,更适合我们源码开发

下载地址:https://ffmpeg.org

下载后解压,使用如下指令安装

./configure --enable-libx264 --enable-libx265 --enable-shared --enable-gpl --prefix=/usr/local
sudo make
sudo make install

安装完后运行ldd which ffmpeg 查看ffmpeg的库是否可以找到

这时一般会打印为:


linux-gate.so.1 => (0x00f90000)
libavdevice.so.52 => not found
libavfilter.so.1 => not found
libavformat.so.52 => not found
libavcodec.so.52 => not found
libpostproc.so.51 => not found
libswscale.so.0 => not found
libavutil.so.50 => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x00821000)
libm.so.6 => /lib/libm.so.6 (0x007da000)
libc.so.6 => /lib/libc.so.6 (0x0067b000)
/lib/ld-linux.so.2 (0x0065c000)


而命令find /usr/local/lib/ | grep -E “libavdevice.so.52|libavfilter.so.1|libavcodec.so.52|libavcore.so.0”

通常会打印输出


/usr/local/lib/libavdevice.so.52.5.0 /usr/local/lib/libavfilter.so.1
/usr/local/lib/libavdevice.so.52 /usr/local/lib/libavfilter.so.1.80.0
/usr/local/lib/libavcodec.so.52.123.0 /usr/local/lib/libavcodec.so.52


说明你有这些库,只是没有识别。当然,路径/usr/local/lib 和/usr/local/include主要是因为ffmpeg的安装前缀是/usr/lcoal,好像用户安装linux的软件默认都是这里。把ffmpeg库路径加入环境变量

sudo vi /etc/ld.so.conf
/usr/local/lib //在文本后边添加该路径
sudo ldconfig //执行ldconfig立即生效

4 实现源码
新建一个文件video2h264.c,内容如下

#include
#include #ifdef __cplusplus
extern "C"
{
#endif
/*Include ffmpeg header file*/
#include
#include
#include #include
#include
#include
#include
#ifdef __cplusplus
}
#endifvoid main()
{AVFormatContext *pFormatCtx;char filepath[] &#61; "rtsp://admin:jiaxun123&#64;192.168.170.248:554/h264/ch1/main/av_stream";AVPacket *packet;//初始化av_register_all();avformat_network_init();pFormatCtx &#61; avformat_alloc_context();AVDictionary* options &#61; NULL;av_dict_set(&options, "buffer_size", "1024000", 0); //设置缓存大小,1080p可将值跳到最大av_dict_set(&options, "rtsp_transport", "tcp", 0); //以udp的方式打开,av_dict_set(&options, "stimeout", "5000000", 0); //设置超时断开链接时间&#xff0c;单位usav_dict_set(&options, "max_delay", "500000", 0); //设置最大时延packet &#61; (AVPacket *)av_malloc(sizeof(AVPacket));//打开网络流或文件流if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) !&#61; 0){printf("Couldn&#39;t open input stream.\n");return;}//查找码流信息if (avformat_find_stream_info(pFormatCtx, NULL)<0){printf("Couldn&#39;t find stream information.\n");return;}//查找码流中是否有视频流int videoindex &#61; -1;unsigned i &#61; 0;for (i &#61; 0; i<pFormatCtx->nb_streams; i&#43;&#43;)if (pFormatCtx->streams[i]->codec->codec_type &#61;&#61; AVMEDIA_TYPE_VIDEO){videoindex &#61; i;break;}if (videoindex &#61;&#61; -1){printf("Didn&#39;t find a video stream.\n");return;}//保存一段的时间视频&#xff0c;写到文件中FILE *fpSave;fpSave &#61; fopen("geth264_test.h264", "wb");for (i &#61; 0; i < 20000; i&#43;&#43;) //这边可以调整i的大小来改变文件中的视频时间{if (av_read_frame(pFormatCtx, packet) >&#61; 0){if (packet->stream_index &#61;&#61; videoindex){fwrite(packet->data, 1, packet->size, fpSave); }av_packet_unref(packet);}}fclose(fpSave);av_free(pFormatCtx);//av_free(packet);av_packet_unref(packet);
}

编译指令

gcc video2h264.c -o ffmpegtest -lpthread -lm -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswresample -lswscale -lrt -lx264 -ldl

如果编译时报错如下


In file included from /usr/local/include/libavutil/avutil.h:296:0,
from /usr/local/include/libavutil/samplefmt.h:24,
from /usr/local/include/libavcodec/avcodec.h:31,
from video2mp4.cpp:5: /usr/local/include/libavutil/common.h:31:2: error: #error missing
-D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS In file included from /usr/local/include/libavutil/avutil.h:296:0,
from /usr/local/include/libavutil/samplefmt.h:24,
from /usr/local/include/libavcodec/avcodec.h:31,
from video2mp4.cpp:5: /usr/local/include/libavutil/common.h: In function ‘int32_t
av_clipl_int32_c(int64_t)’:
/usr/local/include/libavutil/common.h:209:47: error: ‘UINT64_C’ was
not declared in this scope


则需要修改common.h文件&#xff0c;运行

sudo vi /usr/local/include/libavutil/common.h

在在#error missing -D__STDC_CONSTANT_MACROS / #define __STDC_CONSTANT_MACROS前面前边添加如下

#if defined __cplusplus
#define __STDC_CONSTANT_MACROS
#endif#ifndef UINT64_C
#define UINT64_C(value) __CONCAT(value, ULL)
#endif

推荐阅读
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文深入探讨了Linux系统中网卡绑定(bonding)的七种工作模式。网卡绑定技术通过将多个物理网卡组合成一个逻辑网卡,实现网络冗余、带宽聚合和负载均衡,在生产环境中广泛应用。文章详细介绍了每种模式的特点、适用场景及配置方法。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍如何使用Samba软件配置CIFS文件共享服务,涵盖安装、配置、权限管理及多用户挂载等关键步骤。通过具体示例和命令行操作,帮助读者快速搭建并优化Samba服务器。 ... [详细]
  • 解决微信电脑版无法刷朋友圈问题:使用安卓远程投屏方案
    在工作期间想要浏览微信和朋友圈却不太方便?虽然微信电脑版目前不支持直接刷朋友圈,但通过远程投屏技术,可以轻松实现在电脑上操作安卓设备的功能。 ... [详细]
author-avatar
水门街口卖瓜子的
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有