如何使用FFmpeg实现RTSP推送H.264和H.265(HEVC)编码视频

简介: 本文详细介绍了如何使用FFmpeg实现RTSP推送H.264和H.265(HEVC)编码视频。内容涵盖环境搭建、编码配置、服务器端与客户端实现等方面,适合视频监控系统和直播平台等应用场景。通过具体命令和示例代码,帮助读者快速上手并实现目标。

干货:如何实现RTSP推送H.264、RTSP推送H.265(hevc)

实现RTSP(Real Time Streaming Protocol)流媒体服务推送H.264和H.265(HEVC)编码视频是现代视频监控系统、直播平台等应用场景中常见的需求。本文将详细介绍这一过程,包括环境搭建、编码配置、服务器端与客户端实现等方面。

首先,确保你有一个支持H.264和H.265编码的硬件或软件环境。对于软件环境,可以使用FFmpeg,它是一个强大的跨平台多媒体框架,支持多种编解码器和容器格式。安装FFmpeg可以通过包管理器进行,例如,在Ubuntu上可以通过以下命令安装:

sudo apt-get update
sudo apt-get install ffmpeg

接下来,配置FFmpeg以生成RTSP流。假设你想从摄像头捕获视频并推送到RTSP服务器,可以使用以下命令:

ffmpeg -re -f v4l2 -i /dev/video0 -c:v libx264 -preset ultrafast -b:v 1M -rtsp_transport tcp -f rtsp rtsp://localhost:8554/live

这里,-re 表示重定时输入源,以便与指定的帧率匹配;-f v4l2-i /dev/video0 指定从视频设备 /dev/video0 获取视频源;-c:v libx264 设置视频编码器为H.264;-preset ultrafast 选择快速编码预设;-b:v 1M 设定视频比特率为1Mbps;-rtsp_transport tcp 使用TCP传输协议;最后,-f rtsp rtsp://localhost:8554/live 将编码后的流推送到本地RTSP服务器的/live路径。

若要使用H.265(HEVC),只需将视频编码器更改为libx265

ffmpeg -re -f v4l2 -i /dev/video0 -c:v libx265 -preset ultrafast -b:v 1M -rtsp_transport tcp -f rtsp rtsp://localhost:8554/live

为了接收这些RTSP流,你需要一个客户端。可以使用VLC播放器或其他支持RTSP的播放器。在VLC中,输入以下URL即可播放:

rtsp://localhost:8554/live

如果你需要编写自己的服务器或客户端,可以参考下面的C++示例代码,使用libv4l2库读取视频设备,并通过FFmpeg进行编码。此示例仅展示基本结构,实际应用中可能还需要处理错误情况、优化性能等。

服务器端示例代码:

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>

int main() {
   
    AVFormatContext *oc = NULL;
    AVCodecContext *c = NULL;
    AVCodec *codec = NULL;
    int ret, videoindex;

    // 打开输出文件
    if (avformat_alloc_output_context2(&oc, NULL, "rtsp", "rtsp://localhost:8554/live") < 0) {
   
        printf("Could not create output context\n");
        return -1;
    }

    // 查找视频编码器
    codec = avcodec_find_encoder_by_name("libx264");
    if (!codec) {
   
        printf("Codec not found\n");
        return -1;
    }

    // 分配编码上下文
    c = avcodec_alloc_context3(codec);
    if (!c) {
   
        printf("Could not allocate video codec context\n");
        return -1;
    }

    // 设置编码参数
    c->bit_rate = 400000;
    c->width = 352;
    c->height = 288;
    c->time_base = (AVRational){
   1, 25};
    c->gop_size = 12;
    c->pix_fmt = AV_PIX_FMT_YUV420P;

    // 找到视频流索引
    videoindex = av_find_best_stream(oc, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);

    // 打开编码器
    if (avcodec_open2(c, codec, NULL) < 0) {
   
        printf("Could not open codec\n");
        return -1;
    }

    // 初始化输出格式上下文
    if (avio_open(&oc->pb, "rtsp://localhost:8554/live", AVIO_FLAG_WRITE) < 0) {
   
        printf("Failed to open output file\n");
        return -1;
    }

    // 写入文件头
    ret = avformat_write_header(oc, NULL);
    if (ret < 0) {
   
        printf("Error occurred when opening output file\n");
        return -1;
    }

    // 循环读取视频数据并编码
    while (1) {
   
        // 从摄像头获取一帧数据
        // 假设 frame 是 AVFrame* 类型的指针
        AVFrame *frame = av_frame_alloc();
        // 填充 frame 数据
        // ...

        // 编码一帧
        AVPacket pkt;
        av_init_packet(&pkt);
        ret = avcodec_send_frame(c, frame);
        if (ret < 0) {
   
            printf("Error while sending a frame for encoding\n");
            return -1;
        }
        while (ret >= 0) {
   
            ret = avcodec_receive_packet(c, &pkt);
            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
                break;
            else if (ret < 0) {
   
                printf("Error while receiving a packet from the encoder\n");
                return -1;
            }

            // 写入编码后的数据
            ret = av_interleaved_write_frame(oc, &pkt);
            if (ret < 0) {
   
                printf("Error while writing interleave frame\n");
                return -1;
            }

            // 释放packet
            av_packet_unref(&pkt);
        }

        // 释放frame
        av_frame_free(&frame);
    }

    // 写入文件尾
    av_write_trailer(oc);

    // 清理资源
    avformat_free_context(oc);
    return 0;
}

注意:上述代码示例仅供参考,实际应用中还需进一步完善和调试。此外,根据不同的应用场景和需求,可能还需要调整更多的参数以达到最优效果。希望本文能够帮助你成功实现RTSP推送H.264和H.265编码视频的目标。

相关文章
|
2月前
|
Java 数据安全/隐私保护
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
175 1
|
2月前
|
计算机视觉 Python
FFMPEG学习笔记(一): 提取视频的纯音频及无声视频
本文介绍了如何使用FFmpeg工具从视频中提取纯音频和无声视频。提供了具体的命令行操作,例如使用`ffmpeg -i input.mp4 -vn -c:a libmp3lame output.mp3`来提取音频,以及`ffmpeg -i input.mp4 -c:v copy -an output.mp4`来提取无声视频。此外,还包含了一个Python脚本,用于批量处理视频文件,自动提取音频和生成无声视频。
92 1
|
2月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
76 1
|
2月前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
358 0
|
2月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
221 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
2月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
88 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
2月前
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
188 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
2月前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
85 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
3月前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
122 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
116 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库