前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android FFmpeg 流媒体边播放边录制功能

Android FFmpeg 流媒体边播放边录制功能

原创
作者头像
字节流动
修改于 2021-05-08 02:22:05
修改于 2021-05-08 02:22:05
1.9K0
举报
文章被收录于专栏:字节流动字节流动

前面 FFmpeg 系列的文章中,已经实现了音视频的播放、录制已经添加滤镜等功能,本文将用 FFmpeg 实现流媒体的边播放边录制功能。

流媒体

流媒体(英语:Streaming media)是指将一连串的多媒体资料压缩后,经过互联网分段发送资料,在互联网上即时传输影音以供观赏的一种技术与过程,此技术使得资料数据包得以像流水一样发送,如果不使用此技术,就必须在使用前下载整个媒体文件。

流媒体在播放前并不下载整个文件,只将开始部分内容存入内存,流式媒体的数据流随时传送随时播放,只是在开始时有一些延迟。

流媒体实现的关键技术就是流式传输,流式传输分为:实时流和顺序流。

顺序流传输是顺序下载,在下载文件的同时用户可观看在线媒体,在给定时刻,用户只能观看已下载的那部分,而不能跳到还未下载的前头部分,在传输期间不根据用户连接的速度对下载顺序做调整。

实时流传输指保证媒体信号带宽与网络连接匹配,使媒体可被实时观看到,实时流式传输根据网络情况调整输出音视频的质量从而实现媒体的持续的实时传送,用户可快进或后退以观看前面或后面的内容

FFmpeg 播放流媒体

FFmpeg 中对影音数据的处理,可以划分为协议层、容器层、编码层与原始数据层四个层次:

协议层:提供网络协议收发功能,可以接收或推送含封装格式的媒体流。协议层由 libavformat 库及第三方库(如 librtmp)提供支持。

容器层:处理各种封装格式 (MP4,FLV 等)。容器层由 libavformat 库提供支持。

编码层:处理音视频编码及解码。 编码层由各种丰富的编解码器(libavcodec 库及第三方编解码库(如 libx264))提供支持。

原始数据层:处理未编码的原始音视频帧

FFmpeg 中 libavformat 库提供了丰富的协议处理及封装格式处理功能,在打开输入/输出时,FFmpeg 会根据 输入 URL / 输出 URL 探测输入/输出格式,选择合适的协议和封装格式。

例如,如果输出 URL 是 "rtmp://122.125.10.22/live",那么 FFmpeg 打开输出时,会确定使用 rtmp 协议,封装格式为 flv。

FFmpeg 中打开输入/输出的内部处理细节用户不必关注,不同之处主要在于输入/输出 URL 形式不同,若 URL 携带 "rtmp://"、"rpt://"、"udp://"等前缀,则表示涉及流处理;否则,处理的是本地文件。

由于 FFmpeg 对不同的传输协议进行了封装,使用 FFmpeg 播放流媒体和播放本地文件,流程上没有区别(针对 FFmpeg 4.2.2 以上版本)。

FFmpeg 播放流媒体
FFmpeg 播放流媒体

FFmpeg 边播放边录制

FFmpeg 边播放边录制有两种实现方式:

  • 在解复用时获取到编码数据包,然后重新复用打包;
  • 在解码后获取到原始数据,然后对原始数据处理(如添加滤镜),最后对处理后的数据进行编码打包

本文采用对解码后的原始数据进行重新编码的方式,实现边播放边录制。

视频录制,这里我们可以直接使用在前文 FFmpeg 视频录制中定义的类,启动录制之后,只需要不断往里面塞视频帧即可。

代码语言:txt
AI代码解释
复制
class SingleVideoRecorder {
public:
    SingleVideoRecorder(const char* outUrl, int frameWidth, int frameHeight, long bitRate, int fps);
    ~SingleVideoRecorder();

	//开始录制
    int StartRecord();
	//接收视频数据
    int OnFrame2Encode(VideoFrame *inputFrame);
	//停止录制
    int StopRecord();

private:
	...
};

然后在解码类中进行录制。

代码语言:txt
AI代码解释
复制
/**
 *
 * Created by 公众号:字节流动 on 2021/3/16.
 * https://github.com/githubhaohao/LearnFFmpeg
 * 最新文章首发于公众号:字节流动,有疑问或者技术交流可以添加微信 Byte-Flow ,领取视频教程, 拉你进技术交流群
 *
 * */

#include "VideoDecoder.h"

void VideoDecoder::OnDecoderReady() {
    LOGCATE("VideoDecoder::OnDecoderReady");
    m_VideoWidth = GetCodecContext()->width;
    m_VideoHeight = GetCodecContext()->height;

    if(m_VideoRender != nullptr) {
        int dstSize[2] = {0};
        m_VideoRender->Init(m_VideoWidth, m_VideoHeight, dstSize);
        m_RenderWidth = dstSize[0];
        m_RenderHeight = dstSize[1];

		//初始化
        int fps = 25;
        long videoBitRate = m_RenderWidth * m_RenderHeight * fps * 0.2;
        m_pVideoRecorder = new SingleVideoRecorder("/sdcard/learnffmpeg_output.mp4", m_RenderWidth, m_RenderHeight, videoBitRate, fps);
		//开始录制
        m_pVideoRecorder->StartRecord();

    } else {
        LOGCATE("VideoDecoder::OnDecoderReady m_VideoRender == null");
    }
}

void VideoDecoder::OnDecoderDone() {
    LOGCATE("VideoDecoder::OnDecoderDone");

    if(m_VideoRender)
        m_VideoRender->UnInit();

	//视频播放结束,停止录制
    if(m_pVideoRecorder != nullptr) {
        m_pVideoRecorder->StopRecord();
        delete m_pVideoRecorder;
        m_pVideoRecorder = nullptr;
    }

}

void VideoDecoder::OnFrameAvailable(AVFrame *frame) {
    LOGCATE("VideoDecoder::OnFrameAvailable frame=%p", frame);
    if(m_VideoRender != nullptr && frame != nullptr) {
        NativeImage image;
        sws_scale(m_SwsContext, frame->data, frame->linesize, 0,
                  m_VideoHeight, m_RGBAFrame->data, m_RGBAFrame->linesize);
        image.format = IMAGE_FORMAT_RGBA;
        image.width = m_RenderWidth;
        image.height = m_RenderHeight;
        image.ppPlane[0] = m_RGBAFrame->data[0];
        image.pLineSize[0] = image.width * 4;

        m_VideoRender->RenderVideoFrame(&image);

		//不断塞视频帧
        if(m_pVideoRecorder != nullptr) {
            m_pVideoRecorder->OnFrame2Encode(&image);
        }
    }

}

完整的实现代码可以参考项目:

代码语言:txt
AI代码解释
复制
https://github.com/githubhaohao/LearnFFmpeg

参考文章

https://zh.wikipedia.org/wiki/%E6%B5%81%E5%AA%92%E4%BD%93

https://zhuanlan.zhihu.com/p/29567587

https://www.cnblogs.com/leisure_chn/p/10623968.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Android FFmpeg 实现带滤镜的微信小视频录制功能
上一集,有读者吐槽这个系列更新太慢了,其实实现代码一直都有,只能每天花一点时间整理一些,慢慢整理出来。
字节流动
2021/03/22
1.7K0
Android FFmpeg 实现带滤镜的微信小视频录制功能
FFmpeg 开发(02):FFmpeg + ANativeWindow 实现视频解码播放
本文将利用 FFmpeg 对一个 Mp4 文件的视频流进行解码,然后使用 libswscale 将解码后的 YUV 帧转换为 RGBA 帧,最后使用 ANativeWindow 进行渲染。
字节流动
2020/07/03
1.2K0
FFmpeg 开发(02):FFmpeg + ANativeWindow 实现视频解码播放
FFmpeg + OpenGLES 实现视频解码播放和视频滤镜
前面 Android FFmpeg 开发系列文章中,我们已经利用 FFmpeg 的解码功能和 ANativeWindow 的渲染功能,实现了的视频的解码播放。
字节流动
2020/08/20
3.1K0
FFmpeg + OpenGLES 实现视频解码播放和视频滤镜
Android FFmpeg + MediaCodec 实现视频硬解码
本文将利用 FFmpeg+ MediaCodec 做一个播放器,实现视频的硬解码和音视频同步等功能。
字节流动
2022/01/05
3.8K0
Android FFmpeg + MediaCodec 实现视频硬解码
FFmpeg 播放器实现音视频同步的三种方式
前文中,我们基于 FFmpeg 利用 OpenGL ES 和 OpenSL ES 分别实现了对解码后视频和音频的渲染,本文将实现播放器的最后一个重要功能:音视频同步。
字节流动
2020/09/03
2.7K1
FFmpeg 播放器实现音视频同步的三种方式
FFmpeg流媒体处理-收流与推流
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10623968.html
叶余
2019/04/19
10.4K1
FFmpeg流媒体处理-收流与推流
FFmpeg 视频录制 - 视频添加滤镜和编码
音视频开发中,视频编码是另一个重要的部分,基于 FFmpeg 软件解码前面系列文章已经介绍过了,接下来主要介绍软件编码这一块,包括视频编码、音频编码、为视频添加滤镜等。后期文章安排将介绍 Android MediaCodec 硬件编解码。
字节流动
2021/03/09
2K0
FFmpeg 视频录制 - 视频添加滤镜和编码
ffmpeg常用库、术语、API、数据结构总结
封装格式步骤: 1、分配解复用器上下文(avformat_alloc_context()); 2、根据url打开本地文件或网络流(avformat_open_input()); 3、读取媒体的数据包,查找流信息(avformat_find_stream_info()); 4、遍历数据 (4-1)、从文件中读取数据包(av_read_frame()); (4-2)、或者 定位文件位置进行遍历(avformat_seek_file()、av_seek_frame()); 5、关闭解复用器(avformat_close_input())或释放不使用的资源; ​
手撕代码八百里
2021/12/28
1.1K0
Android FFmpeg 音视频解码播放(十五)
通常情况下,媒体文件以如MP4,MKV、FLV等等格式存在我们的计算机,手机等设备中,而这些文件格式都属于封装格式,就是把音视频数据按照相应的规范,打包成文件。
PengJie
2021/01/15
2.4K0
知识:视频流媒体播放的一些知识
内嵌 flash 的方式必须要有浏览器支持。这样的方式已经被各大浏览器放弃,在谷歌浏览器中已经不再支持flash。本文不再说明。
张云飞Vir
2021/05/06
1.8K0
Android中如何使用OpenGL播放视频
视频播放主要经历这么几个步骤:解协议 -> 解封装 -> 解码音视频 -> 音视频同步,流程如下图:
雪月清
2020/06/23
2.5K0
Android FFmpeg 简介(十三)
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。
PengJie
2021/01/14
1.8K0
FFmpeg简易播放器的实现-音视频播放
下图引用自“雷霄骅,视音频编解码技术零基础学习方法”,因原图太小,看不太清楚,故重新制作了一张图片。
叶余
2019/04/02
2.7K0
FFmpeg简易播放器的实现-音视频播放
FFmpeg学习笔记汇总
FFmpeg既是一款音视频编解码工具,同时也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口。 FFmpeg提供了多种媒体格式的封装和解封装,包括多种音视频编码、多种协议的流媒体、多种色彩格式转换、多种采样率转换、多种码率转换等;FFmpeg框架提供了多种丰富的插件模块,包含封装与解封装的插件、编码与解码的插件等。
天天Lotay
2022/11/14
1.3K0
FFmpeg学习笔记汇总
FFmpeg 使用教程
默认的编译会生成4个可执行文件和8个静态库。可执行文件包括用于转码、推流、Dump媒体文件的ffmpeg、用于播放媒体文件的ffplay、
派大星在吗
2021/12/06
1.6K0
直播间源码android音视频开发
简介: 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及如何技术选型,如何解决遇到的坑,本文抛砖引玉,欢迎大咖交流。
云豹短视频嘉兴
2020/08/24
3.8K0
音视频平凡之路之FFmpeg全面介绍
FFmpeg中的FF全称是"Fast Forward",后面的mpeg全称是"Moving Picture Experts Group"(动态图像专家组),FFmpeg既是一款音视频编解码工具,也是一组音视频编解码开发套件,作为编解码开发套件,它为开发者提供了丰富的音视频处理的调用接口。
马上就说
2020/11/11
2.1K0
音视频平凡之路之FFmpeg全面介绍
ffmpeg结构梳理总结
导语:初学ffmpeg的人往往觉得ffmpeg纷繁复杂,不知道从何处下手,感觉理不清头绪。这篇文章就是尽量帮助大家理清ffmpeg的逻辑结构和学习路线。
汪秀军
2018/08/11
2.6K1
ffmpeg结构梳理总结
如何使用 FFmpeg 打造自己的播放器
前面 FFmpeg 系列的文章中,已经实现了 FFmpeg 的编译和集成,基于 FFmpeg 实现音视频的播放、录制,并结合 OpenGL 添加丰富的滤镜等功能,这些 demo 基本上将 FFmpeg 使用涉及到的知识点基本上覆盖了。
字节流动
2022/12/14
2K0
如何使用 FFmpeg 打造自己的播放器
FFmpeg代码导读——基础篇
视频流媒体中程中视频数据的传输占据了绝大部分的带宽,如何提升编码效率,使用更少的带宽,提供更优质的画面质量,是音视频开发人员一直努力的重点。HEVC(High Efficiency Video Coding,也叫H.265)编码格式的推出,给这一方向带来了突破点,但由于其算法复杂度较高,前期未曾得到普遍应用,而随着移动设备计算能力的提高和越来越多的设备开始支持HEVC的硬件编/解码,直播平台也开始逐渐引入HEVC视频格式。
LiveVideoStack
2021/09/02
1.5K0
FFmpeg代码导读——基础篇
相关推荐
Android FFmpeg 实现带滤镜的微信小视频录制功能
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档