音视频开发_快速掌握FFmpeg

FFmpeg命令

  1. 视频格式转换

    ffmpeg -i input.avi output.mp4
    
  2. 音频提取

    ffmpeg -i video.mp4 -q:a 0 -map a audio.mp3
    
  3. 视频剪辑

    ffmpeg -i input.mp4 -ss 00:00:10 -to 00:00:20 -c copy output.mp4
    
  4. 视频合并

    ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
    
  5. 变更视频分辨率

    ffmpeg -i input.mp4 -s 1280x720 output.mp4
    
  6. 调整帧率

    ffmpeg -i input.mp4 -r 24 output.mp4
    
  7. 视频稳定化(使用vidstab插件)

    ffmpeg -i input.mp4 -vf vidstabdetect=shakiness=10:accuracy=15 -vf vidstabtransform=input="transforms.trf" output.mp4
    
  8. 视频去噪

    ffmpeg -i input.mp4 -vf "hqdn3d=1.5:1.5:6:6" output.mp4
    
  9. 调整音量

    ffmpeg -i input.mp4 -filter:a "volume=2.0" output.mp4
    
  10. 添加字幕

    ffmpeg -i input.mp4 -vf subtitles=subtitles.srt output.mp4
    
  11. 视频旋转和翻转

    ffmpeg -i input.mp4 -vf "transpose=2, hflip" output.mp4
    
  12. 实时视频流传输

    ffmpeg -re -i input.mp4 -f flv rtmp://live.twitch.tv/app/stream_key
    
  13. 截取视频的一帧作为图片

    ffmpeg -i input.mp4 -ss 00:00:10 -vframes 1 output.jpg
    
  14. 压缩视频

    ffmpeg -i input.mp4 -vcodec h264 -acodec mp3 output.mp4
    
  15. 将视频转换为GIF

    ffmpeg -i video.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v gif -f gif out.gif
    

1.音频PCM/AAC文件提取

音频数据提取是一个涉及到音频编解码、解复用以及可能的格式转换的复杂过程。从音频文件中提取PCM(脉冲编码调制,一种未压缩的音频数据格式)和AAC(高级音频编码,一种有损压缩的音频编码标准)数据的基本步骤。

提取PCM数据

以下是使用ffmpeg提取PCM数据的一个基本命令:

ffmpeg -i input_file -f s16le -ar 44100 -ac 2 output.pcm

在这条命令中:

  • -i input_file 指定输入文件的路径。
  • -f s16le 设置输出格式为有符号16位小端PCM数据。
  • -ar 44100 设置音频采样率为44100Hz。
  • -ac 2 设置音频为双声道。
  • output.pcm 是提取出的PCM数据文件。

PCM数据通常存在于.wav或.raw文件中。要从这些格式提取PCM数据,可以直接读取文件,因为它们没有压缩或编码。使用C++和标准库来读取.wav文件的:

#include <fstream>
#include <iostream>
#include <vector>

int main() {
    std::ifstream file("example.wav", std::ios::binary);

    // 跳过WAV文件头部,通常是44个字节
    file.seekg(44);

    // 读取PCM数据
    std::vector<char> pcmData(std::istreambuf_iterator<char>(file), {});

    // 处理或保存PCM数据
    // ...

    file.close();
    return 0;
}

提取AAC数据

要从AAC编码的文件中提取数据,你可能需要使用专门的音频处理库,如FFmpeg。这里是使用FFmpeg提取AAC编码数据的基本步骤:

  1. 安装FFmpeg:确保你的系统上安装了FFmpeg工具。

  2. 使用ffmpeg命令行:可以通过执行ffmpeg命令行来提取AAC数据。
    以下是基本的FFmpeg命令来提取AAC数据:

ffmpeg -i input_file -vn -acodec copy output.aac

在这条命令里:

  • -i input_file 表示指定的输入文件,可以是视频文件,例如.mp4, .mkv, .avi等,有音频流的文件都可以。
  • -vn 是指在输出中去除视频流,即只处理音频。
  • -acodec copy 表示直接复制音频编码数据而不重新编码。
  • output.aac 是你提取出的AAC数据文件。

例如,一个MP4视频文件video.mp4提取其中的AAC音频:

ffmpeg -i video.mp4 -vn -acodec copy audio.aac

上述命令会生成一个audio.aac文件,其中包含了从video.mp4复制的AAC音频数据。

  1. 编程提取AAC:如果你更偏向于编程方式,可以使用FFmpeg的库进行编码和解码。这个过程要求你对FFmpeg的API有一定的了解,可能需要从输入文件中解复用AAC编码的流,然后操作解复用后的原始流数据。

2.视频YUV/H264文件提取

提取YUV数据

要提取YUV数据,通常的做法是使用FFmpeg这样的工具来解码视频流并将其保存为YUV格式。以下是使用FFmpeg提取YUV数据的命令:

ffmpeg -i input_video -c:v rawvideo -pix_fmt yuv420p output.yuv

在这条命令中:

  • -i input_video 指定输入视频文件。
  • -c:v rawvideo 设置视频的编解码器为rawvideo,即未压缩的视频数据。
  • -pix_fmt yuv420p 设置像素格式为yuv420p, 这是最常见的YUV4:2:0格式。
  • output.yuv 是提取出的YUV数据文件。

提取H264数据

以下是使用FFmpeg提取H264数据的命令:

ffmpeg -i input_video -c:v copy -bsf:v h264_mp4toannexb -f h264 output.h264

在这条命令中:

  • -i input_video 指定输入视频文件。
  • -c:v copy 表示直接复制视频流而不进行重新编码。
  • -bsf:v h264_mp4toannexb 使用比特流滤镜h264_mp4toannexb确保输出的是一个合适的H264比特流,尤其是如果源文件是MP4格式的话。
  • -f h264 输出格式为raw H264视频流。
  • output.h264 是提取出的H264数据文件。

3.解复用、复用

解复用 (Demultiplexing)

解复用是指从一个包含多种数据流的多媒体容器格式中分离音频、视频和其他数据流的过程。多媒体容器文件,如MP4、MKV或AVI,通常不仅仅包含视频,还包含音频、字幕、元数据等多种类型的流。解复用过程将这些流分离开,然后独立处理每个流(如解码)。

在解复用过程中,解复用器需要解析容器的数据结构,识别出里面的各种流,并将他们从容器中提取出来。这样,视频流就可以送到视频解码器进行解码,音频流送到音频解码器进行解码,其他数据则根据需要处理。

例如,当你在播放器中播放一个MP4视频文件时,播放器的内部机制会解复用这个文件,分别处理其中的音频和视频流。

下面是音视频解复用的典型流程:

  1. 容器格式识别: 解复用器首先要确定文件的容器格式。常见的容器格式有MP4, MKV, AVI, FLV等。这个步骤通常通过读取文件头部的信息来完成,因为头部包含了文件类型的元数据。

  2. 解析媒体信息: 解复用器解析媒体容器的头部信息从而获取关于音、视频流的详细信息,包括编码格式、时间戳、比特率、帧率、分辨率等。

  3. 建立时间线: 多媒体文件中的音频和视频帧都会附带时间戳。解复用器用这些时间戳来建立音频和视频的播放时间线,确保同步播放。

  4. 流分离: 解复用器将文件中的数据流分离成视频帧和音频帧,还可能包括字幕和其他数据。这通常涉及到一定程度的缓冲,以保证数据的连续性和时序正确。

  5. 流派送: 分离后的流会被发送到对应的解码器。例如,视频数据送到视频解码器,音频数据送到音频解码器。在这一步中,如果涉及网络传输,还可能有必要重排列数据包以处理网络引起的延迟。

  6. 错误处理: 如果在解复用过程中遇到错误或缺失的数据,则解复用器需要能够检测这些情况并作出适当的纠正或者至少不会让整个播放进程中断。

  7. 输出: 被分离且同步的音视频流最终会被解码器处理,转换为可以播放的原始信号(提供给视频显示设备或音频播放硬件)。

解复用

  1. 从一个视频文件中提取视频流:

    ffmpeg -i input.mp4 -c:v copy -an output.h264
    
    • -i input.mp4 指定输入文件。
    • -c:v copy 表示复制视频编码(不进行转码)。
    • -an 表示不处理音频流。
  2. 从一个视频文件中提取音频流:

    ffmpeg -i input.mp4 -c:a copy -vn output.aac
    
    • -c:a copy 表示复制音频编码(不进行转码)。
    • -vn 表示不处理视频流。

复用 (Multiplexing)

复用是解复用的逆过程,它涉及将独立的音频、视频和其他数据流合成为一个单一的、通常较易于传输和存储的容器格式文件。复用器接受多个输入流,如已编码的视频流、音频流等,然后整合成一个多媒体文件,同时保留流之间的同步。

在复用过程中,每个流都将按照特定的容器格式规范来封装,这包括将适当的头信息、元数据和分隔符添加到数据中。复用产生的结果是一个整齐的包装好的文件,可以被分发、保存或播放。

例如,如果你想要将录制的视频和音频合成一个视频文件用于上传到YouTube,你会需要一个复用器来合成这些流并创建一个例如MP4的多媒体文件。

解复用和复用通常是视频编解码中不可或缺的一部分,因为它们允许开发者和用户处理复杂的多媒体数据并适应各种不同的播放设备和网络状况。视频编辑软件、转码工具和流媒体服务器等应用程序都会用到这两个过程。在流媒体应用中,这两个操作尤其关键,因为它们涉及到数据的动态打包和抽取,以实现低延迟和高效的网络传输。

下面是音视频复用的通用步骤:

  1. 准备数据流: 在复用之前,需要确保所有将被复用的音频、视频和其他数据流都已经被相应的编码器(如H.264编码器或AAC编码器)处理过,并准备好被整合。这些流应该是编码并压缩后的数据,以便于存储和传输。

  2. 选择容器格式: 选择一个适当的多媒体容器格式来封装音视频数据,这个选择通常基于最终用途,例如广泛兼容性选择MP4,对于开放格式可能选择MKV等。

  3. 确定同步机制: 在复用的过程中,必须确保音频和视频之间的同步性。这通常通过使用各自的时间戳来实现,确保在播放过程中音视频能够同步输出。

  4. 写入文件头: 文件头中包含了媒体播放所需的基础信息,包括编码格式、持续时间和其他元数据。这个步骤涉及将这些信息写入最终文件的开始部分。

  5. 交错写入数据: 交错将音频和视频数据包写入文件中,确保播放器在任何时间点都可以从容器中有效地提取和处理必要的数据流。这种方式有助于实现流畅的快进和快退操作。

  6. 处理索引和导航信息: 为了支持快速定位到多媒体文件中的特定位置,复用器通常会在文件的尾部写入索引。这项信息允许播放器快速跳转至文件中的特定点。

  7. 错误处理和容错: 在写入数据过程中可能会遇到错误。复用器需要具备一定的错误处理机制来保证最终文件的完整性和可播放性。

  8. 文件封闭: 数据流写入完成之后,复用器会写入任何必要的结束信息,并封闭文件,这样多媒体文件就准备好被存储或传输了。

音视频复用是一个结构化的过程,它允许将多个数据流绑定到一个统一的文件中,同时保持它们之间的同步和组织性。这个过程通常使用专门的多媒体编辑和处理软件,例如FFmpeg,来实现。这些软件不仅可以处理复用任务,还提供了许多其他功能,如转码、剪辑、效果处理等。

以下是如何使用FFmpeg进行解复用和复用的操作示例:

复用

  1. 将视频流和音频流打包成一个新的封装格式的文件:

    ffmpeg -i input.h264 -i input.aac -c:v copy -c:a copy output.mp4
    
    • -i input.h264 指定视频输入文件。
    • -i input.aac 指定音频输入文件。
    • -c:v copy-c:a copy 表示分别复制视频和音频编码。

4. 音视频录制

视频录制原理

其视频录制的原理大致可以分为以下几个步骤:

  1. 捕捉和输入

    • FFmpeg使用它的设备捕获能力,可以通过许多不同的输入设备来捕获视频,如摄像头或桌面录制。输入设备被指定为输入源,比如video4linux2用于Linux系统上的摄像头设备。
  2. 帧抓取和编码

    • 每当有视频帧从设备捕获到时,FFmpeg会对其进行处理。这个处理可能包括转换像素格式、调整分辨率等。然后将视频帧送入编码器,编码器将这些帧压缩成指定的视频格式。
  3. 音频捕捉和同步

    • 如果录制同时包含音频,FFmpeg也会捕捉音频流。在音视频录制过程中,保持音视频同步是一个关键的环节。FFmpeg内部有一套机制来确保时间戳正确,音视频同步。
  4. 封装和输出

    • 编码后的音频和视频数据需要被封装到一个容器格式中(如MP4、MKV、AVI等)。FFmpeg支持多种封装格式。在封装的过程中,数据会被分成块,并在每个块前加上时间戳,确保在播放时能正确地同步音视频。
  5. 录制控制

    • 在整个录制过程中,用户可以设置各种参数,如码率、分辨率、录制时间等。用户可以实时监控录制状态,并在需要时停止录制。

用FFmpeg进行视频录制时,会用到诸如ffmpeg的命令行工具,命令行中可以通过各种选项来控制录制的各个方面。一个简单的录制命令可能看起来是这样的:

ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 output.mp4

这条命令指定了使用v4l2(video4linux2)作为视频捕获设备,/dev/video0是设备文件,-c:v libx264指定了视频编码器为libx264,输出文件为output.mp4

音频录制原理

FFmpeg对于音频录制的原理涉及到音频的捕获、编码、封装和输出。下面是这一过程的具体步骤:

  1. 捕获音频

    • FFmpeg使用其输入设备功能来从一个音频源(如麦克风或者其他的音频接口)捕获音频数据。在命令行中,可以通过特定的输入选项来指定音频源。
  2. 音频处理

    • 捕获的音频原始数据可能需要进行某些形式的处理,如重采样、声道转换、音量调节等,以符合输出格式的要求或提升音质。
  3. 编码

    • 捕获到的音频数据是未压缩的原始音频样本。FFmpeg内置了多种音频编码器,可以将原始数据编码成不同的音频格式,如MP3、AAC、Vorbis等。每种编码器都有自己的特点和设置,用户可以根据需要选择编码器和相应的参数。
  4. 封装

    • 编码后的音频数据需要被封装到一个媒体容器格式中。FFmpeg支持许多音频和视频容器格式,如MP3文件只包含音频数据,而MP4和MKV等则可以包含音频和视频的混合数据。容器中的数据会分成块或帧,并配上时间戳,确保在播放或流式传输时能准确同步。
  5. 输出

    • 处理和封装后的音频数据将被输出到指定的文件中或传输到网络上的流媒体服务器。
  6. 实时处理

    • 如果音频录制是实时进行的,比如直播,FFmpeg还会处理和保证实时性,降低延迟,并可能与视频流同步。

一个简单FFmpeg录制音频的命令可能如下所示:

ffmpeg -f alsa -i default -c:a libmp3lame -b:a 320k output.mp3

这个命令表示使用ALSA音频接口(在许多Linux系统中用于捕获和播放声音),default是设备名称,-c:a libmp3lame指定使用libmp3lame编码器进行音频编码,-b:a 320k设置音频比特率为320kbps,输出文件为output.mp3

5.视频裁剪和合并

裁剪

使用其命令行工具,并配合 -ss (起始时间)和 -to-t(持续时间或结束时间)参数。
以下是一些基本命令的例子:

从特定时间点开始剪切一段持续时间的视频:

ffmpeg -ss [start_time] -i input.mp4 -t [duration] -c copy output.mp4
  • [start_time]: 视频剪切的开始时间。可以是以秒为单位的数字(例如 600 表示从第600秒开始),或者是 "hh:mm:ss" 格式的时间码(例如 "01:40:00" 表示从1小时40分钟开始)。
  • [duration]: 从开始时间之后要保留的视频长度。也可用相同的格式表示。
  • -c copy: 表示使用“流复制”模式,即不经过重新编码,直接复制视频流。这样可以快速完成剪切,不损失视频质量,但需要确保起始时间对齐关键帧。

例如,如果你想从视频的第1分钟开始,剪切5分钟的视频,命令如下:

ffmpeg -ss 00:01:00 -i input.mp4 -t 00:05:00 -c copy output.mp4

从特定时间点剪切到另一个时间点的视频:

ffmpeg -ss [start_time] -i input.mp4 -to [end_time] -c copy output.mp4

与上面的命令类似,只不过-t被替换为-to,此参数指定了结束时间点而非持续时长。例如,要从视频的第2分钟开始,剪切到第4分钟,可以使用:

ffmpeg -ss 00:02:00 -i input.mp4 -to 00:04:00 -c copy output.mp4
  • 当使用-ss参数在指定的[start_time]进行剪辑时,为了确保精度,推荐将-ss放在-i前面。这样FFmpeg会先寻找最近的关键帧来开始处理,可以加快命令的执行,但可能会在精确度上有所牺牲。如果把-ss放到-i后面,则精确度会更高,但处理速度较慢。
  • 当不需要流复制而希望对视频进行编码时,可以去掉-c copy参数,FFmpeg会根据视频内容重新压缩编码。
  • 确保输出文件格式(如.mp4)支持所选的编码格式。

合并

使用FFmpeg合并视频时,最常见的方法之一是通过concat协议。这种方法针对格式相同(编解码参数、分辨率、帧率等)的视频文件效果最佳。以下是如何使用FFmpeg合并视频的具体步骤:

使用concat协议合并:

  1. 创建一个文件(假设命名为filelist.txt),列出所有要合并的视频文件,每行的格式如下:

    file 'path/to/video1.mp4'
    file 'path/to/video2.mp4'
    file 'path/to/video3.mp4'
    

    这里的路径需要准确指向视频文件,且每个视频文件前需加file '和后面跟上'

  2. 使用FFmpeg的concat协议进行合并:

    ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
    
    • -f concat: 指定使用concat格式来读取输入。
    • -safe 0: 允许使用任意文件路径,包括绝对路径或相对路径。
    • -i filelist.txt: 指定concat列表文件。
    • -c copy: 使用流复制模式,这样不会重新编码视频,可以更快速地完成合并操作。

使用concat协议是一种非常快速且不丢失质量的合并方法,但对文件格式有一定的要求。如果输入的视频文件参数不一致,可以考虑其他方法,如先将每个视频文件转码为相同的参数,再使用concat合并。

除了使用concat协议,可以使用以下方法来合并视频文件:

1. 使用FFmpeg的concat过滤器

如果输入视频的格式略有不同(例如,编码参数或帧率不一致),可以使用concat过滤器来合并视频,这允许视频在合并的过程中进行转码:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v] [0:a] [1:v] [1:a] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" output.mp4
  • -filter_complex: 启用复杂的过滤图。
  • [0:v] [0:a] [1:v] [1:a]: 分别代表第一个输入文件的视频和音频流,以及第二个输入文件的视频和音频流。
  • concat=n=2:v=1:a=1: 指定有几个文件被合并(n=2),每个文件包含的视频流数量(v=1),以及音频流数量(a=1)。
  • [v] [a]: 指定过滤器的输出标签,后续可以用-map来选择。
  • -map: 指定哪些流应该被映射到输出文件。

2. 使用ffmpeg concat命令直接读取多个文件合并

可以在FFmpeg命令中直接使用多个输入文件参数,然后合并它们:

ffmpeg -i "concat:input1.mp4|input2.mp4" -c copy output.mp4

这种方法适合在文件编解码格式相同时使用,因为它也期望输入文件是编码兼容的。

3. 使用编码转换

如果上述方法因为文件格式兼容问题不能应用,可以将所有视频文件转换成完全相同的格式、分辨率及帧率,然后再使用concat过滤器或协议:

ffmpeg -i input1.mp4 -q:v 1 intermediate1.mpg
ffmpeg -i input2.mp4 -q:v 1 intermediate2.mpg
ffmpeg -i "concat:intermediate1.mpg|intermediate2.mpg" -c copy output.mp4

这里使用了.mpg中间文件,因为MPEG格式容错性较好,适合用于concat操作。其中-q:v 1参数指定了视频质量。

如何使用FFmpeg将音频流和视频流合并为一个文件?

要使用FFmpeg将音频流和视频流合并成一个文件,可以使用以下命令进行“复用”操作:

ffmpeg -i video_input.mp4 -i audio_input.mp3 -c:v copy -c:a copy -shortest output.mp4

这里的参数解释如下:

  • -i video_input.mp4: 指定视频输入文件。
  • -i audio_input.mp3: 指定音频输入文件。
  • -c:v copy: 表示复制原来的视频编码(不进行转码)。
  • -c:a copy: 表示复制原来的音频编码(不进行转码)。
  • -shortest: 这个选项是用来确保输出文件的长度与最短的输入流(无论是音频还是视频)相匹配,避免出现多余的空白音频或视频。

如果需要对音频或视频进行转码而不是直接复制流(例如,如果原始格式不兼容),通过指定编解码器进行调整,例如:

ffmpeg -i video_input.mp4 -i audio_input.mp3 -c:v libx264 -c:a aac output.mp4

在这个命令中:

  • -c:v libx264: 表示使用libx264编码器对视频进行编码。
  • -c:a aac: 表示使用AAC编码器对音频进行编码。

如何使用FFmpeg从视频中提取指定帧数的图片?

使用FFmpeg从视频中提取指定帧数的图片,你可以使用以下命令:

ffmpeg -i input_video.mp4 -vf "select='eq(n\,FRAME_INDEX)'" -vsync vfr output_image.png

这里的参数解释如下:

  • -i input_video.mp4: 指定输入视频文件。
  • -vf: 表示视频过滤器。
  • "select='eq(n\,FRAME_INDEX)'": 这是过滤表达式,n 代表当前帧的序列号(从0开始计算),FRAME_INDEX 是你想要提取的帧的序列号。如果你想要第100帧,就将 FRAME_INDEX 替换为 99 (因为帧计数以0为开始)。
  • -vsync vfr: 通过设置为变帧率(variable frame rate)输出只包含选定帧的序列。
  • output_image.png: 输出图片的文件名。

例如,如果你希望提取第100帧的图片,命令将是:

ffmpeg -i input_video.mp4 -vf "select='eq(n\,99)'" -vsync vfr output_image.png

如果你希望提取多个特定帧数的图片,你可以修改选择过滤器的表达式,例如提取第50帧和第100帧:

ffmpeg -i input_video.mp4 -vf "select='eq(n\,49)+eq(n\,99)'" -vsync vfr output_image%d.png

在这个例子中,得到的图片将会是 output_image1.pngoutput_image2.png

如需提取多个连续的帧或是按固定间隔提取,可相应调整 select 过滤器的参数或使用其他过滤器参数,以满足特定的需求。

6.图片/视频转换

图片转视频

若要将一系列图片转换成视频,你可以使用以下命令:

ffmpeg -framerate 1 -i image%d.jpg -c:v libx264 -r 25 -pix_fmt yuv420p out.mp4

解释参数:

  • -framerate 1: 指图片输入时的帧率(每秒显示多少图片),这里设置为每秒1帧。
  • -i image%d.jpg: 这是输入文件的模式,%d是一个占位符,表示数字序列(例如,image1.jpg, image2.jpg, …)。
  • -c:v libx264: 使用libx264编码器对视频进行编码。
  • -r 25: 输出视频的帧率为25fps。
  • -pix_fmt yuv420p: 设置像素格式为yuv420p,这对于H.264编码是一个常见的需求,以提高兼容性。
  • out.mp4: 输出视频文件。

视频转图片

若要从视频中提取图片,可以使用以下命令:

ffmpeg -i video.mp4 -r 1 output%d.png

解释参数:

  • -i video.mp4: 指定输入视频文件。
  • -r 1: 输出时的帧率,这里设置为每秒提取1帧。
  • output%d.png: 输出的图片文件,%d是一个数字序列占位符。

视频格式转换

若要将视频从一种格式转换成另一种格式,可以使用以下命令:

ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4

解释参数:

  • -i input.avi: 指定输入文件。
  • -c:v libx264: 视频编码器设置为libx264。
  • -c:a aac: 音频编码器设置为AAC。
  • output.mp4: 指定输出文件。

如何设置FFmpeg命令行参数来录制实时音频?

  1. 确定音频捕获设备
    首先,你需要知道系统中可用的音频设备。在Linux系统中,可以使用arecord -l来列出录音设备。在Windows系统中,你可能使用dshow(DirectShow)。

  2. 选择编码器和格式
    然后,选择一个适合目标用途的音频编码器和格式,如MP3(libmp3lame)、AAC(aac)、FLAC(flac)等。

  3. 设定输出文件
    指定输出文件的名称和类型,比如output.mp3

以下是根据这些步骤构建起来的FFmpeg命令行参数:

ffmpeg -f <input_format> -i <input_device> -c:a <audio_encoder> -b:a <bit_rate> <output_file>

例如,如果你想使用ALSA接口在Linux上录制MP3格式的音频:

ffmpeg -f alsa -i default -c:a libmp3lame -b:a 192k output.mp3

这个命令的意思是:

  • -f alsa 表明你通过ALSA接口捕获音频。
  • -i default 指定默认捕获设备(这个参数可能根据你的系统和设备而有所不同)。
  • -c:a libmp3lame 设置音频编码器为libmp3lame,用于编码MP3音频。
  • -b:a 192k 设置音频的比特率为192kbps,这是MP3音频质量的一个常见设置。
  • output.mp3 是指定输出文件的名称。

若想在Windows上使用DirectShow接口录制,可以使用类似的命令,但是输入格式和设备名称可能有所不同。

ffmpeg -f dshow -i audio="Microphone (Realtek Audio)" -c:a libmp3lame -b:a 192k output.mp3

在这里:

  • -f dshow 表明通过DirectShow接口捕获音频。
  • -i audio="Microphone (Realtek Audio)" 指定具体的音频输入设备名称。

要找出Windows中的具体音频设备名,可以使用ffmpeg -list_devices true -f dshow -i dummy命令。

附加选项:

  • 使用-ar来指定采样率。
  • 使用-ac来指定音频通道数量,例如-ac 2代表立体声。

7.直播推流和拉流

推流(发送到流媒体服务器)

  1. 获取音视频源:首先,你需要一个音视频源,这可以是一个本地文件、一个捕获设备 like a camera or microphone, 或者是已存在的网络流。
  2. 选择编码器:然后,根据流媒体服务器的要求选择相应的视频(如H.264)和音频(如AAC)编码器。
  3. 设置流媒体服务器地址:指定流媒体服务器的推流地址,通常这会是一个RTMP或HLS地址。
  4. 配置其它编码参数:根据需要调整码率、分辨率、帧率等编码参数。

假设你正在使用一个RTMP服务器来进行推流,一个基本的FFmpeg命令可能如下所示:

ffmpeg -i <input_source> -c:v libx264 -b:v <video_bitrate> -maxrate <max_video_bitrate> -bufsize <buffer_size> -c:a aac -ar <audio_sample_rate> -b:a <audio_bitrate> -f flv rtmp://<server_address>/<stream_key>

这个命令的意义如下:

  • -i <input_source>:指定输入源。
  • -c:v libx264:使用libx264编码器对视频进行H.264编码。
  • -b:v <video_bitrate>:指定视频比特率。
  • -maxrate-bufsize:控制编码器的码率波动。
  • -c:a aac:使用AAC编码器进行音频编码。
  • -ar <audio_sample_rate>:指定音频采样率。
  • -b:a <audio_bitrate>:指定音频比特率。
  • -f flv:封装格式(FLV适用于RTMP)。
  • rtmp://<server_address>/<stream_key>:流媒体服务器的地址和流密钥。

拉流(从流媒体服务器接收)

当你想从流媒体服务器拉取流时,可以使用FFmpeg来接收并输出到文件或播放:

ffmpeg -i rtmp://<server_address>/<stream_path> -c copy -f <output_format> <output_file>

这个命令的含义:

  • -i rtmp://<server_address>/<stream_path>:指定RTMP流的源地址。
  • -c copy:直接复制音视频数据,不进行重新编码。
  • -f <output_format>:指定输出格式,如mp4flv,或者其他格式。
  • <output_file>:指定输出文件的路径。

FFmpeg是否支持推送到其他流媒体服务器,如RTSP或HLS?

RTSP推流

如果你想使用FFmpeg将流推送到RTSP服务器,你可以使用以下命令作为起点:

ffmpeg -i input_file_or_stream -c:v libx264 -preset veryfast -r 25 -s 640x480 -c:a aac -ar 44100 -f rtsp rtsp://server_address:port/app/stream_key

这个命令使用了和RTMP推流类似的基础设置。主要的不同在于:

  • -f rtsp:这指定了输出格式为RTSP流。
  • rtsp://server_address:port/app/stream_key:这是你的RTSP服务器的链接地址、端口号、应用名称以及流密钥。
HLS推流

与RTMP和RTSP不同,HLS首先需要在本地生成一个m3u8播放列表文件和一系列.ts视频分段文件,然后由服务器或CDN服务对其进行托管和分发。如果你想使用FFmpeg推送流为HLS格式,你可以使用以下命令:

ffmpeg -i input_file_or_stream -c:v libx264 -preset veryfast -g 50 -sc_threshold 0 -hls_time 4 -hls_playlist_type event -hls_segment_filename 'stream_%03d.ts' stream.m3u8

这个命令创建一个HLS播放列表(M3U8文件)以及一系列的视频分段(TS文件):

  • -g 50:每50帧插一次关键帧。
  • -sc_threshold 0:禁止场景切换检测。
  • -hls_time 4:指定每个TS文件的持续时间为4秒。
  • -hls_playlist_type event:生成的M3U8文件类型为event,即作为流媒体直播事件使用。
  • -hls_segment_filename 'stream_%03d.ts':TS文件的名称及排列方式。
  • stream.m3u8:播放列表文件的名称。

08.水印/画中画/九宫格滤镜

水印添加

要在视频中添加水印,可以使用overlay滤镜:

ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4

解释:

  • input.mp4:主视频文件。
  • watermark.png:水印图片文件。
  • overlay=W-w-10:H-h-10:将水印放置在主视频的右下角。WH是视频的宽和高,wh是水印的宽和高。

画中画(Picture-in-Picture)

画中画效果可以用来在主视频中展示小窗口视频。以下命令是将小窗口放置于主视频的右上角:

ffmpeg -i main_video.mp4 -i pip_video.mp4 -filter_complex "[0:v][1:v] overlay=main_w-overlay_w-10:10" -codec:a copy output.mp4

解释:

  • main_video.mp4:主视频文件。
  • pip_video.mp4:画中画视频文件。
  • overlay=main_w-overlay_w-10:10:画中画视频放置的位置,main_wmain_h是主视频的宽和高,overlay_woverlay_h是画中画视频的宽和高。

九宫格视频

九宫格滤镜可以将多个视频分隔成平均的小块。以下命令是一种简单的将四个视频合并成一个2x2的网格:

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -i input4.mp4 -filter_complex "\
nullsrc=size=640x480 [base]; \
[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; \
[1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright]; \
[2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft]; \
[3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright]; \
[base][upperleft] overlay=shortest=1 [tmp1]; \
[tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; \
[tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; \
[tmp3][lowerright] overlay=shortest=1:x=320:y=240" \
-c:v libx264 output.mp4

解释:

  • 该命令使用了nullsrc创建了一个空白的基础视频。
  • 有四个输入视频,分别缩放并放置在网格的不同位置。
  • overlay滤镜被多次用来将每个小视频放到合适的位置。
  • 输出视频的编码器是libx264

参考资料:

音视频流媒体开发课程(从基础到高级,从理论到实践)学习计划、一对一答疑
音视频开发(FFmpeg/WebRTC/RTMP)

整理了一些音视频开发学习资料、面试题 如有需要自行添加群:739729163 领取

  • 14
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值