阅读目录

视频是怎么被播放的?

我们知道,当下大多数播放器都是基于ffmpeg二次开发的。你有没有想过,你用播放器打开一个视频的时候,是怎么看到的画面,怎么听到的声音?

我们用这张图简单描绘出视频被播放的流程。

下面稍微解释下图中的含义。

  1. 解封装:播放器将输入的封装格式(mp4、mkv)的数据分离,产生音频流和视频流两部分,注意此时这两部分数据还只是压缩的数据,类似分流,后面我们也会介绍如何从视频文件中抽离出音频和视频。
  2. 下一步就是解码操作了,我们说解码就是将视频、音频压缩的编码数据,解码成为非压缩的视频、音频原始数据。这里将音频解码为pcm格式的数据,将视频解码为yuv格式的数据。
  3. 音视频同步播放:把解封装和解码分别拿到的视频信息和音视频数据,发送给显卡和声卡即可播放。

ffmpeg命令的格式

我们在音视频基础概念一文中介绍转码的时候,抛出过一条转码的命令,如下

ffmpeg -i input.flv output.mp4

对于ffmpeg命令的基本格式,参考ffmpeg官网

ffmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

翻译过来就是

ffmpeg [全局选项] {[输入文件选项] -i 输入文件} ... {[输出文件选项] 输出文件} ...

... 表示一条命令可能会有多个输入和多个输出。

比如我们可以通过输入多个文件转码后输出多个文件

ffmpeg -i input1 -i input2 \
-acodec … -vcodec … output1 \
-acodec … -vcodec … output2 \
-acodec … -vcodec … output3

据不完全统计,ffmpeg命令的选项数量就有小几万,所以不仅要多掌握学习技巧,更多的是多积累经验,靠死记硬背是完全行不通的。

那么多的选项,体现在一条命令上,一个基本的通用规则就是:

输入文件选项只作用于它后面的第一个输入文件,自然,输出文件选项也只作用于它后面的第一个输出文件。所以是有顺序要求的。

全局选项倒是可以随便写,比如有个全局选项 -y,询问我们是否要覆盖输出,下面两种写法都可以

ffmpeg -y -i input.flv output.mp4
ffmpeg -i input.flv -y output.mp4

但是,如果命令很长很长(比如我们前面给的音视频案例,一条命令甚至都有几百个字符),类似这种全局选项,最好写在输入文件前面或者输出文件前面。

另外,千万不要先写输出文件,再写输入文件,至少应该写完输入文件,再写输出文件,比如下面这样就是不好的写法

ffmpeg output.mp4 -i input.flv

良好的习惯才是好的开始。

ffmpeg转码输出的过程

ffmpeg -i input.flv output.mp4

还是上面这条简单的转码命令,对于类似这样的一条命令,对于ffmpeg,又是怎么处理的呢?

我们用下面这个图来表示转码输出的过程。

具体描述如下

  1. ffmpeg 调用一个包含解复用器demuxer的libavformat库,从输入文件中读取包含编码的数据包
  2. 然后将编码的数据包传递给解码器(decoder)(流复制操作忽略该步骤)
  3. 解码器(decoder)产生未压缩的帧(即原始帧)可以进一步被滤镜处理
  4. 接下来,被滤镜处理的原始数据被传递给编码器(encoder)
  5. 编码器对传递过来的数据进行编码并输出编码数据包
  6. 最后,这些数据被复用器(muxer)写入输出文件。

任何复杂的命令,都必须经过上面这样的转码过程,底层代码你可以不看,但是整个过程必须了解。

ffmpeg入门到实战-ffmpeg是怎么转码的?的更多相关文章

  1. FFmpeg入门,简单播放器

    一个偶然的机缘,好像要做直播相关的项目 为了筹备,前期做一些只是储备,于是开始学习ffmpeg 这是学习的第一课 做一个简单的播放器,播放视频画面帧 思路是,将视频文件解码,得到帧,然后使用定时器,1 ...

  2. FFmpeg 入门(7):Seeking

    本文转自:FFmpeg 入门(7):Seeking | www.samirchen.com 处理 seek 命令 我们将为播放器添加 seek 的能力.这个过程中,我们会看到 av_seek_fram ...

  3. FFmpeg 入门(6):音频同步

    本文转自:FFmpeg 入门(6):音频同步 | www.samirchen.com 音频同步 上一节我们做了将视频同步到音频时钟,这一节我们反过来,将音频同步到视频.首先,我们要实现一个视频时钟来跟 ...

  4. FFmpeg 入门(5):视频同步

    本文转自:FFmpeg 入门(5):视频同步 | www.samirchen.com 视频如何同步 在之前的教程中,我们已经可以开始播放视频了,也已经可以开始播放音频了,但是视频和音频的播放还未同步, ...

  5. FFmpeg 入门(4):线程分治

    本文转自:FFmpeg 入门(4):线程分治 | www.samirchen.com 概览 上一节教程中,我们使用 SDL 的音频相关的函数来支持音频播放.SDL 起了一个线程来在需要音频数据的时候去 ...

  6. FFmpeg 入门(2):输出视频到屏幕

    本文转自:FFmpeg 入门(2):输出视频到屏幕 | www.samirchen.com SDL 我们这里使用 SDL 来渲染视频到屏幕.SDL 是 Simple Direct Layer 的缩写, ...

  7. FFmpeg 入门(3):播放音频

    本文转自:FFmpeg 入门(3):播放音频 | www.samirchen.com 音频 SDL 提供了播放音频的方法.SDL_OpenAudio 函数用来让设备播放音频,它需要我们传入一个包含了所 ...

  8. FFmpeg 入门(1):截取视频帧

    本文转自:FFmpeg 入门(1):截取视频帧 | www.samirchen.com 背景 在 Mac OS 上如果要运行教程中的相关代码需要先安装 FFmpeg,建议使用 brew 来安装: // ...

  9. 实战FFmpeg + OpenGLES--iOS平台上视频解码和播放

    一个星期的努力终于搞定了视频的播放,利用FFmpeg解码视频,将解码的数据通过OpenGLES渲染播放.搞清楚了自己想知道的和完成了自己的学习计划,有点小兴奋.明天就是“五一”,放假三天,更开心啦. ...

随机推荐

  1. 用户对象/GDI对象/内核对象

    对象的分类 Windows的对象可以分为三种,分别是用户对象,GDI对象和内核对象.系统使用用户对象支持窗口管理,使用GDI对象支持图形,并使用内核对象支持内存管理,进程执行和进程间通信(IPC) . ...

  2. 有趣的css—简单的下雨效果2.0版

    简单的下雨效果2.0版 前言 笔者上一篇发布的文章有趣的css-简单的下雨效果中有位老哥给我提了一个很棒的建议,大致意思是波纹应该产生于雨滴的消失处. 这是按照老哥的建议完善后的效果图: 由于我制作G ...

  3. Camera.main

    在Unity项目的C#代码中可以看到Camera.main.transform.position.Camera.main.transform.eulerAngles.Camera.main.trans ...

  4. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  5. OO第三单元作业(JML)总结

    OO第三单元作业(JML)总结 目录 OO第三单元作业(JML)总结 JML语言知识梳理 使用jml的目的 jml注释结构 jml表达式 方法规格 类型规格 SMT Solver 部署JMLUnitN ...

  6. Swagger简明教程

    一.什么是swagger Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化RESTful风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法, ...

  7. Hive 安装和配置

    环境准备 已安装 HDFS 和 Yarn 集群环境 Windows 已安装 MySQL 8 (开启远程连接用户权限) 安装步骤 1. 上传并解压 Hive 安装文件 将 apache-hive-3.1 ...

  8. stm32.cube(一)——系统架构及目录结构

    一.前言 Arm的应用场景往往比51单片机复杂得多,如果一个高级应用的开发需要连底层的结构性代码都要重构,那么在成本和研发周期上就会面临巨大的风险.为了简化编码过程,芯片厂商经常会提供一些板卡级支持的 ...

  9. 国外DIY网站

    https://site.douban.com/109950/widget/notes/250072/note/248811721/

  10. 代码动态更换MeshRenderer的材质Materials

    public class metrailstest : MonoBehaviour { Material[] m; Material i; public Material[] n; int index ...