第8课 利用FFmpeg将摄像头画面与麦克风数据合成后推送到rtmp服务器

33 篇文章 2 订阅
31 篇文章 3 订阅

本课对应源文件下载链接:

https://download.csdn.net/download/XiBuQiuChong/88803267

上节课我们已经拿到了摄像头数据和麦克风数据,这节课我们来看一下如何将二者合并起来推送到rtmp服务器。

一、最终实现的效果

二、音视频合并推流的原理

通过《第5课 使用FFmpeg将rtmp流再转推到rtmp服务器》我们已经知道如何将rtmp流再转发到另一台rtmp服务器,与此类似,直接将音视频数据推送到rtmp服务器也要先创建并打开输出流。为了得到类似于拉取到的rtmp音频包和视频包,就需要对音视频原始数据进行相应的编码和封装,要实现以上功能就需要引入编码器。

三、音视频合并推流的具体实现

推送音视频合成流到rtmp服务器地址的流程如下:

1.创建输出流

//初始化输出流上下文

avformat_alloc_output_context2(&outFormatCtx, NULL, "flv", outFileName);

outFormat = outFormatCtx->oformat;

outFormat->video_codec = AV_CODEC_ID_H264;

outFormat->audio_codec = AV_CODEC_ID_AAC;

2.创建视频编码器

vEncodec = avcodec_find_encoder(AV_CODEC_ID_H264);

vEncodeCtx = avcodec_alloc_context3(vEncodec);

vEncodeCtx->codec_id = vEncodec->id;

vEncodeCtx->codec_type = AVMEDIA_TYPE_VIDEO;

vEncodeCtx->bit_rate = 1000000;

vEncodeCtx->width = backWidth;

vEncodeCtx->height = backHeight;

vEncodeCtx->time_base = { 1, 25 };

vEncodeCtx->framerate = { 25, 1 };

vEncodeCtx->gop_size = 25 * 10;

vEncodeCtx->pix_fmt = *vEncodec->pix_fmts;

vEncodeCtx->max_b_frames = 0;

vEncodeCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

av_dict_set(&vEncodeOpts, "profile", "baseline", 0);

av_dict_set(&vEncodeOpts, "preset", "ultrafast", 0);

av_dict_set(&vEncodeOpts, "tune", "zerolatency", 0);

avcodec_open2(vEncodeCtx, vEncodec, &vEncodeOpts);

3.创建音频编码器

//音频编码器

aEncodec = avcodec_find_encoder(AV_CODEC_ID_AAC);;

aEncodeCtx = avcodec_alloc_context3(aEncodec);

aEncodeCtx->bit_rate = 64000;

aEncodeCtx->sample_rate = 44100;

aEncodeCtx->block_align = 0;

aEncodeCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;

aEncodeCtx->channel_layout = AV_CH_LAYOUT_STEREO;

aEncodeCtx->channels = 2;

aEncodeCtx->time_base.num = 1;

aEncodeCtx->time_base.den = aEncodeCtx->sample_rate;

aEncodeCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

avcodec_open2(aEncodeCtx, aEncodec, NULL);

4.创建输出视频流

//创建输出视频流

videoStream = avformat_new_stream(outFormatCtx, vEncodec);

videoStream->id = outFormatCtx->nb_streams - 1;

videoStream->codecpar->codec_tag = 0;

avcodec_parameters_from_context(videoStream->codecpar, vEncodeCtx);

5.创建输出音频流

//创建输出音频流

audioStream = avformat_new_stream(outFormatCtx, NULL);

audioStream->codecpar->codec_tag = 0;

audioStream->id = outFormatCtx->nb_streams - 1;

avcodec_parameters_from_context(audioStream->codecpar, aEncodeCtx);

6.打开输出流并写入文件头

//打开输出流

av_dump_format(outFormatCtx, 0, outFileName, 1);

ret = avio_open2(&outFormatCtx->pb, outFileName, AVIO_FLAG_READ_WRITE, nullptr, nullptr);

//写文件头

ret = avformat_write_header(outFormatCtx, NULL);

7.分别封装音视频帧并送入编码器

ret = avcodec_send_frame(vEncodeCtx, deVideoFrame);

ret = avcodec_receive_packet(vEncodeCtx, &enVideoPacket);

ret = avcodec_send_frame(aEncodeCtx, deAudioFrame);

ret = avcodec_receive_packet(aEncodeCtx, &enAudioPacket);

8.分别推送音视频流

if (enVideoPacket.size > 0){

 ret = av_interleaved_write_frame(outFormatCtx, &enVideoPacket);                           

}

if (enAudioPacket.size > 0){

 ret = av_interleaved_write_frame(outFormatCtx, &enAudioPacket);                           

}

9.播放测试rtmp流

打开vlc或第一章写好的rtmp播放器测试,对着麦克风说话如果能从播放器听到声音并看到图像说明成功。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
在Android项目中使用FFmpeg来拉取RTSP流并推送RTMP服务器,可以按照以下步骤进行操作: 步骤1:添加FFmpeg库 首先,将FFmpeg库添加到Android项目中。可以使用开源的FFmpeg库,也可以使用第三方的FFmpeg库。在项目的build.gradle文件中添加FFmpeg库的依赖。 步骤2:初始化FFmpeg 在代码中初始化FFmpeg,可以在Application的onCreate()方法中进行初始化操作。 步骤3:拉取RTSP流 使用FFmpeg命令行或者FFmpeg库提供的API来拉取RTSP流。可以通过设置输入源和输出格式等参数,实现从RTSP服务器拉取流数据。 步骤4:推送RTMP服务器 使用FFmpeg命令行或者FFmpeg库提供的API来推送数据RTMP服务器。可以通过设置输出源和RTMP服务器地址等参数,实现将拉取到的流数据推送RTMP服务器。 步骤5:对推送过程进行监听和处理 通过FFmpeg库提供的回调函数,可以对推送过程进行监听和处理。例如,可以监听流传输的状态、推送的进度等。 步骤6:处理异常情况 在使用FFmpeg的过程中,可能会遇到各种异常情况,比如网络异常、编解码错误等。需要在代码中进行异常处理,保证项目的稳定性和可靠性。 需要注意的是,使用FFmpeg进行RTSP流拉取和RTMP推送需要一定的编程技巧和对FFmpeg库的理解。并且,由于FFmpeg库在不同平台和版本之间可能存在差异,因此在集成和使用FFmpeg库时,需要确保库的版本和平台的兼容性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西部秋虫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值