[视频资源/网络爬虫] FFMPEG(多媒体音视频处理工具)

概述:音视频封装格式

视频封装格式:MP4、FLV、TS/M3U8、M4S

  • 视频封装格式有:MP4、FLV、TS、M4S 等

视频文件格式: M3U8

M3U8 视频格式

  • M3U8(全称UTF-8编码的M3U,Media Playlist File的缩写)是一种基于HTTP Live StreamingHLS)协议的视频文件格式,由苹果公司提出,广泛应用于iOSmacOStvOS等系统。它将视频内容分割成多个TS片段,并通过M3U8索引文件管理

  • M3U8文件采用UTF-8编码,是纯文本格式,记录TS片段索引信息。
  • 工作原理
  • 将流分成多个TS小文件,客户端根据网络状况选择不同码率下载,保证视频流畅性。支持直播点播自适应码率流播降低服务器负载、适用于非实时视频,并且易于编辑更新。
  • 应用场景:在线视频直播、点播和移动端视频应用等。

视频封装格式ts与m3u8的联系?

TS(Transport Stream)和M3U8之间存在紧密的联系,主要体现在以下几个方面:

  1. M3U8依赖TS文件
    M3U8是一种基于文本的播放列表文件,其核心作用是作为索引文件,用于存储多个TS文件的路径。在HLSHTTP Live Streaming)协议中,整个视频流被分割成多个较小的TS片段文件,而M3U8文件则包含了这些TS片段文件的URL地址列表。播放器通过读取M3U8文件,按照其中的顺序依次下载并播放对应的TS文件,从而实现流媒体的播放。

  1. TS文件的特点使其适合与M3U8配合使用
    TS文件具有良好的兼容性可拼接性。两个TS片段可以无缝拼接,播放器能够连续播放,而不会出现破音或画面间断。这使得TS文件非常适合用于HLS协议中的流媒体传输,因为HLS需要将视频流分割成多个片段,并且在播放过程中可能需要根据网络状况动态切换不同码率的片段。

  2. M3U8与TS共同实现HLS协议的功能
    HLS协议是一种基于HTTP的流媒体网络传输协议,主要用于在不同设备上进行流媒体播放。M3U8文件作为HLS协议的一部分,通过索引TS文件,实现了视频流的分割、下载和播放控制。同时,M3U8文件还可以包含一些元数据信息,如每个TS片段的时长、版本号等,这些信息有助于播放器更好地管理和播放视频流。

  3. TS与M3U8的转换
    由于M3U8文件本质上是一个索引文件,它并不直接存储视频内容,而是通过指向多个TS文件来实现视频的播放。因此,如果需要将M3U8格式的视频转换为其他格式(如MP4),通常需要先下载所有TS文件,然后将它们合并为一个完整的视频文件。

视频封装格式: M4S

M4S 特点与结构

  • M4S 格式(MPEG-4 Segment)是一种基于 ISO-BMFFISO Base Media File Format)标准的文件分段格式,包含视频和音频的多个独立片段,每个片段通常对应一个特定的时间段(如1秒、2秒等),以确保按需加载和快速切换,这些片段都被封装在单独的文件中按顺序播放。

  • M4S 通过小段的多媒体片段文件,能够更快速地响应网络状况的变化,且灵活适应不同的客户端设备分辨率和性能,常用于流媒体技术,尤其是 DASH(Dynamic Adaptive Streaming over HTTP)视频点播直播场景中。

MP4 与 M4S

  • M4SMP4 都基于 ISO-BMFF 格式,都是用 Box 结构来存储和组织元信息和媒体数据,都包含如 ftyp(File Type Box)、mdat(Media Data Box)等基础 Box,但也有如下区别:
  • M4S 文件是分段存储的,它依赖于清单文件来指引播放器按顺序加载片段,不包含 moov(Movie Box),而用 moof(Movie Fragment Box)来存储片段级的元数据,使每个分段可以独立播放,更适合分段流传输。
ftyp  // 文件类型 Box,描述文件格式兼容性
moof  // 片段信息 Box,包含分段的元数据信息
  ├─ mfhd  // 片段头部,标识分段序号
  └─ traf  // 轨道片段,包含轨道信息
      ├─ tfhd  // 轨道片段头,包含轨道ID和基本信息
      └─ tfdt  // 轨道片段解码时间,用于同步
mdat  // 媒体数据 Box,包含音视频数据
  • MP4 文件通常是一个完整的多媒体封装文件,使用 moov 来存储全局元数据信息,包括时间、播放顺序、轨道信息等,依据 moov 信息指导播放顺序和解码时间,适合本地存储、并逐步播放的场景。
ftyp  // 文件类型标识
moov  // 全局媒体信息
  ├─ mvhd  // 电影头部,包含播放时长等信息
  ├─ trak  // 轨道数据
mdat  // 媒体数据

fmp4 与 m4s

  • fmp4 是指“Fragmented MP4”是一种扩展的 MPEG-4 格式,允许将 MP4 文件分成多个分段独立传输播放,常用于流媒体应用 HLSDASH

  • m4s 是指“Segmented MPEG-4”是 fmp4 格式的实际分段文件的扩展名,每个 m4s 文件通常是 fmp4 的一个片段。

总结:fmp4 是用于流式传输的媒体容器格式,而 m4s 是这种格式的实际分段文件。在 HLSDASH 流媒体中,m4s 文件依赖于 fmp4 的结构来存储和组织视频、音频等数据,同时这些分段通过相应的播放列表(如 .m3u8.mpd 文件)进行引用和管理。

M4S 的文件生成过程(DASH)

(1)视频格式转换

  • 使用 FFmpeg 等工具可以将视频分割成 M4S 格式文件。如下将原始视频文件转为分段的 M4S 片段文件,同时生成相应的清单文件(如 DASH 中的 MPD 文件):
ffmpeg -i v1.mp4 -c:v copy -c:a copy -map 0 -f dash -seg_duration 2 out.mpd

这会将 input.mp4 分割为2秒的 M4S 片段,并生成一个 out.mpd 的 DASH 清单文件,便于播放器按需加载各个片段。
如下日志显示生成了多组 chunk-stream1-000XX.m4s 片段,这些是按 -seg_duration 2 选项指定的2秒时长分段生成的;out.mpd.tmp 清单文件也在不断更新中,描述所有 M4S 片段的顺序、时间戳等信息,最终得到的 out.mpd 文件应包含了每个 M4S 文件的引用;结尾汇总帧和速率信息以及音视频数据量表明转化顺利,音视频流已正确封装入文件,Qavg: 665.629 属于音频质量评估信息。

(2)DASH 下 M4S 视频文件组织播放流程

  • mp4 视频转换得到的 m4s 文件,有一个清单文件 out.mpd,还有很多 chunk-stream1-*.m4s 文件和 init-stream*.m4s 文件,怎么理解这样的视频文件组织关系呢?

清单文件 out.mpd:DASH 协议的清单文件 Media Presentation Description,通常是 XML 格式,描述了所有 M4S 片段和初始化文件的信息,如各片段的引用、每个流的分辨率、码率等,播放器依赖 MPD 文件来加载和播放各个片段。内容包括 AdaptationSet 表示一组音视频流、Representation 表示不同的比特率或分辨率版本、BaseURL 指明片段的基准路径等。

ffprobe out.mpd

  • 初始化文件 init-stream*.m4s:DASH 流的初始化文件 Initialization Segment,每个 Representation 通常都有一个初始化文件,用来存储解码器初始化参数和配置信息 SPS、PPS 等元数据。在播放任何一个视频或音频片段前先下载并处理这个初始化文件。

  • 片段文件 chunk-stream1-*.m4s:实际的视频或音频片段 Media Segment,文件名中的编号通常表示时间戳或片段序号来按时间顺序排列播放。在 DASH 流中第一个片段 chunk-stream1-00001.m4s 文件通常包含了第一个片段所需的关键帧(I 帧)以及视频流的解码信息,作为后续片段的参考帧,因此数据量较大,后续的片段大多为非关键帧(P 或 B 帧),数据量较小。

  • 客户端首先下载 out.mpd 文件解析视频的基本结构;根据清单中的路径找到并下载对应的 init-stream.m4s 初始化文件;再根据网络条件,客户端动态选择并依次下载 chunk-stream1-.m4s 文件进行播放。

接下来我们用播放软件 PotPlayer 或 VLC 打开 out.mpd 清单文件即可加载各段内容完整播放:

M4S 的文件生成过程(HLS)

  • 虽然 HLS 传统上是基于 TS 分段,但苹果公司在 HLS 中引入了 CMAF(Common Media Application Format),这是 MPEG 制定的一种标准化的媒体容器格式,旨在实现流媒体内容的兼容性和高效传输,它允许 HLS 使用 M4S 分段,进一步降低延迟。

(1)视频格式转换

  • 调用 FFmpeg 工具将原始视频文件转为分段的 M4S 片段文件,同时生成相应的 m3u8 播放列表:
ffmpeg -i v1.mp4 -c:v copy -c:a copy -hls_segment_type fmp4 -hls_time 2 -hls_list_size 0 output.m3u8

-hls_segment_type fmp4 指定 HLS 分段文件的类型为 fmp4 即 M4S-hls_time 2 指定每个 HLS 分段的持续时间为 2 秒;-hls_list_size 0 控制所有生成的分段都会包含在 M3U8 文件中。
执行此命令后,FFmpeg 将生成 output.m3u8 播放列表文件以及一系列 output*.m4s 命名的多个 M4S 分段文件,内容为分段的音视频流,持续时间为 2 秒。

(2)HLS 下 M4S 视频文件组织播放流程

  • 清单文件 output.m3u8:HLS 清单文件格式,包含视频播放的所有 .m4s 片段的顺序和时长等信息,并指导播放器按顺序加载并播放各个片段。

ffprobe output.m3u8

  • 初始化文件 init.mp4:HLS 的 Fragmented MP4(fMP4)格式的初始化片段,用于定义媒体流的基本信息(如编解码器、分辨率等),这是解析每个片段文件前的必要信息。

ffprobe init.mp4

  • 分片文件 output*.m4s:每个 .m4s 文件是视频的一个 2 秒长片段,对应于 -hls_time 2 参数。

客户端首先下载 output.m3u8 文件解析视频的基本结构,接着加载 init.mp4 获取视频和音频轨道的基础信息,再按照 m3u8 文件指示的顺序依次加载 .m4s 文件,并将其解码播放。

用 VLC 打开 m3u8 文件即可顺利播放

ffplay 打开 m3u8 文件也可顺利播放

(3)DASH/HLS 生成的 M4S 文件区别

  • DASH 方式得到的多组 chunk-streamX-000XX.m4s 片段区分音频和视频,如本案例提供的 chunk-stream0-000XX.m4s 为视频片段,chunk-stream1-000XX.m4s 为音频片段,数据量大小有明显区别。

  • HLS 方式得到的一系列 output*.m4s 片段文件是合在一起的音视频流片段,而不是单独的音频或视频片段。

网络视频格式: WebM

+‌ WebM是一种开放的网络视频格式,由Google提出,基于Matroska容器格式,包含VP8视频编码Ogg Vorbis音轨‌

  • WebM格式旨在为网络提供高质量、开源的视频体验,特别适合在HTML5环境下使用。由于其开源特性WebM在网络流媒体在线视频游戏等方面应用广泛。
  • 常见的平台如YouTube、Netflix等都支持这种格式。‌

Youtube 为例,WebM 文件中只有视频内容,没有音频内容。

  • WebM格式的特点

‌ + **开源性‌:WebM是一个开放、免费的媒体文件格式,基于HTML5标准,适合在网络上使用。‌
‌ + **高效性‌:WebM格式在视频压缩方面表现出色,能够在多种设备上流畅播放,包括上网本、平板电脑和手持设备。
‌>‌ + **广泛支持‌:Google、Adobe、AMD、ARM、Broadcom、Freescale、NVIDIA、Qualcomm和TI等公司都支持WebM格式,尤其是在浏览器方面,Chrome、Firefox和Opera都支持该格式,而Internet Explorer 9则需要额外安装VP8插件才能播放。

  • WebM格式与MP4格式的对比
    ‌>‌ + **兼容性‌:MP4格式(MPEG-4 Part 14)是一种广泛接受的标准视频格式,几乎在所有设备上都能够顺利播放,而WebM的兼容性相对较差。‌

‌ + **‌编辑方便‌:许多视频编辑软件对MP4的支持更加完备,允许用户对视频进行剪辑、混音或添加特效,而WebM在这方面可能有所限制。
‌>‌ + **网络共享‌:许多社交媒体平台和视频分享网站对MP4格式的视频更加友好,可以直接上传并分享,而WebM可能需要特定的播放器或插件才能播放。
‌>‌ + **存储效率‌:MP4格式提供较好的压缩效果,在保证视频质量的情况下占用更少的存储空间,而WebM虽然高效,但在某些设备上的存储和播放可能不如MP4灵活。

音频格式:M4A => MP4的音频标准文件扩展名

  • m4a是一种音频文件格式,专属于苹果设备(现在也逐步扩展到小米手机等厂商)

该格式的音频文件音质较高、文件体积小且可以保留音频的元数据,适用于音乐编辑、存储等多种用途。

  • M4AMPEG-4 音频标准文件的扩展名

MPEG4标准中提到,普通的MPEG4文件扩展名是“.mp4”。
自从Apple开始在它的iTunes以及iPod中使用“.m4a”以区别MPEG4的视频和音频文件以来,“.m4a”这个扩展名变得流行了。
大部分支持MPEG4音频的软件都支持“.m4a”,但是支持情况各异,根据不同的音频通道,不同的软件支持情况也不太一样。

音频格式:MP3

  • MP3是一种音频压缩技术,其全称是动态影像专家压缩标准音频层面3Moving Picture Experts Group Audio Layer III),简称为MP3
  • 它被设计用来大幅度地降低音频数据量
  • 利用 MPEG Audio Layer 3 的技术,将音乐以 1:10 甚至 1:12压缩率,压缩成容量较小的文件,而对于大多数用户来说重放的音质与最初的不压缩音频相比没有明显的下降。
  • 它是在1991年由位于德国埃尔朗根的研究组织Fraunhofer-Gesellschaft的一组工程师发明和标准化的。

  • MP3形式存储的音乐就叫作MP3音乐,能播放MP3音乐的机器就叫作MP3播放器

音频格式:WAV

  • WAV格式不是视频格式,而是音频格式‌

WAVWave Audio Files, 波式音频文件)是微软公司开发的一种标准数字音频文件格式,主要用于保存Windows平台的音频信息资源
它符合资源互换文件格式(RIFF)规范,能够记录实际声音的取样数据,保证声音不失真,但存储空间较大。‌

  • WAV格式的特点:

‌ + 无损压缩‌:WAV文件通常用来保存PCM格式的原始音频数据,因此被称为无损音频。
‌>‌ + 高音质‌:标准格式化的WAV文件和CD格式一样,采用44.1kHz的采样频率和16位量化数字,音质接近CD。
‌>‌ + 广泛支持‌:WAV格式被Windows平台及其应用程序广泛支持,是音乐编辑创作的首选格式,适合保存音乐素材。

FFMPEG:开源的多媒体(音)视频处理工具

  • 项目URL:
  • 项目Intro:
  • 多媒体视频处理工具FFmpeg有非常强大的功能,包括:视频采集功能、视频格式转换、视频抓图、给视频加水印等。
  • FFmpeg这个单词中的“FF”指的是“Fast Forward(快速前进)”。

有些新手写信给“FFmpeg”的项目负责人,询问FF是不是代表“Fast Free”或者“Fast Fourier”等意思,“FFmpeg”的项目负责人回信说:“Just for the record, the original meaning of "FF" in FFmpeg is "Fast Forward"...
这个项目最初是由Fabrice Bellard发起的,而现在是由Michael Niedermayer在进行维护。许多FFmpeg的开发者同时也是MPlayer项目的成员,FFmpegMPlayer项目中是被设计为服务器版本进行开发。 
FFmpeg可使用众多参数,参数内容会根据ffmpeg版本而有差异,使用前建议先参考参数及编解码器的叙述。此外,参数明细可用ffmpeg -h显示;编解码器名称等明细可用ffmpeg -formats显示。

  • FFmpeg是一套可以用来记录、转换*数字音频视频**,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。
  • FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括WindowsMac OS X等。这个项目最早由Fabrice Bellard发起,2004年至2015年间由Michael Niedermayer主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。FFmpeg编码库可以使用GPU加速

FFmpeg 应用场景

CASE:下载网页TS格式视频,并自动合成MP4视频格式

Step1 Chrome浏览器:打开网页,单击F12打开【开发者工具】

  • 开始视频播放,在F12出来的界面中单击【Network】
  • 在Network中有文件列表,检查当中是否存在.m3u8结尾的文件

Step2 如果.m3u8结尾的文件,则将该源地址复制

  • 文件链接示例

https://xxxxxx/d70556509660c1a29b5b0.m3u8

Step3 安装 ffmpeg

Step3.1 下载安装包

  • 进入下载页面

https://ffmpeg.org/download.html

  • 选择window,然后选择第二个

  • 进入下载界面

https://github.com/BtbN/FFmpeg-Builds/releases

  • 选择对应的安装包文件下载(以Windows为例)

https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-02-03-13-00/ffmpeg-N-118406-g957eb2323a-win64-gpl.zip
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-02-03-13-00/ffmpeg-n5.1.6-16-g6e63e49496-win64-gpl-5.1.zip
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-02-03-13-00/ffmpeg-n6.1.2-21-gac60bc2bb0-win64-gpl-6.1.zip 【如√】
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-02-03-13-00/ffmpeg-n7.1-184-gdc07f98934-win64-gpl-7.1.zip
https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2025-02-03-13-00/ffmpeg-n7.1-184-gdc07f98934-win64-lgpl-7.1.zip

Step3.2 解压即安装

  • 下载好后,解压到自定义的文件夹

Step3.3 设置环境变量(可选)

  • 进入 bin目录, 并复制bin文件夹的位置

D:\Program_Files\ffmpeg\ffmpeg-n6.1.2-21-gac60bc2bb0-win64-gpl-6.1\bin

  • 选中“此电脑”右击,然后点击“属性”,进入高级系统设置

  • 进入【环境变量】,找到Path变量,并新增 ffmpegbin路径
  • ffmpeg.exe
  • ffplay.exe
  • ffprobe.exe

Step3.4 验证

检验ffmpeg是否安装成功?

  • win+R 运行 cmd: ffmpeg

看出现的信息是否为安装的文件和版本信息

C:\Users\xxx>ffmpeg
ffmpeg version n6.1.2-21-gac60bc2bb0-20250203 Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 14.2.0 (crosstool-NG 1.26.0.120_4d36f27)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250203
  libavutil      58. 29.100 / 58. 29.100
  libavcodec     60. 31.102 / 60. 31.102
  libavformat    60. 16.100 / 60. 16.100
  libavdevice    60.  3.100 / 60.  3.100
  libavfilter     9. 12.100 /  9. 12.100
  libswscale      7.  5.100 /  7.  5.100
  libswresample   4. 12.100 /  4. 12.100
  libpostproc    57.  3.100 / 57.  3.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

C:\Users\xxx>

Step4 下载目标URL的视频

  • 打开 CMD 窗口,并键入:在 Step2 获取的 m3u8 视频链接
ffmpeg -i https://xxxxxx/d70556509660c1a29b5b0.m3u8 -c copy 自定义视频名.mp4

  • 开始下载视频,并等待视频下载结束。

CASE: 将分别为.m4s格式的音频文件和视频文件合并为1个.mp4视频文件

很多小伙伴会遇到你想收藏某个视频但是某些软件没有下载只有缓存,我们会发现缓存下来的被分成了两个部分,一个视频的,一个音频的(一般大的是视频,小的是音频)。

  • 分别为.m4s格式的音频文件、视频文件

  • powershell 执行:
.\ffmpeg.exe -i 1527000116-1-100048.m4s -i 1527000116-1-30280.m4s -codec copy Output.mp4

若此时报错:

Error opening input: Invalid data found when processing input
Error opening input file 1527000116-1-100048.m4s.
Error opening input files: Invalid data found when processing input

打开输入时出错:处理输入时发现无效数据
打开输入文件1527000116-1-30112.m4s时出错。
打开输入文件时出错:处理输入时发现无效数据

此时将视频音频的m4s利用Notepad++ or UltraiEdit Professional Text/Hex Editorda打开方式

  • 用Notepad++ 打开就删除前面无用的字段的000000000后保存

  • UltraiEdit Professional Text/Hex Editorda打开就删除hex前面的30 30 30 30 30 30 30 30

  • 再打开刚刚的powershell窗口重新输入并运行
.\ffmpeg.exe -i 1527000116-1-100048.m4s -i 1527000116-1-30280.m4s -codec copy Output.mp4


  • 此时转换合成成功
  • 接着我们打开bin文件夹,出现了个Output.mp4,这个就是我们转换合成成功后的mp4文件。

CASE MP4 转 MP3/提取MP4视频中的音频

方法1 ffmpeg -i {xx}.mp4 {xxxx}.mp3 (单个/批量)

  • 单个文件
# ffmpeg -i videoplayback.mp4 videoplayback.2.mp3
ffmpeg version N-118658-g7225e307be-20250307 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-shared --disable-static --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --disable-libvvenc --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250307
  libavutil      59. 58.100 / 59. 58.100
  libavcodec     61. 33.102 / 61. 33.102
  libavformat    61.  9.107 / 61.  9.107
  libavdevice    61.  4.100 / 61.  4.100
  libavfilter    10.  9.100 / 10.  9.100
  libswscale      8. 13.100 /  8. 13.100
  libswresample   5.  4.100 /  5.  4.100
  libpostproc    58.  4.100 / 58.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'videoplayback.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2024-12-10T21:55:18.000000Z
    encoder         : Google
  Duration: 00:13:39.92, start: 0.000000, bitrate: 198 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 640x360 [SAR 1:1 DAR 16:9], 67 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
    Metadata:
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:1 -> #0:0 (aac (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
Output #0, mp3, to 'videoplayback.2.mp3':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    TSSE            : Lavf61.9.107
  Stream #0:0(eng): Audio: mp3, 44100 Hz, stereo, fltp (default)
    Metadata:
      encoder         : Lavc61.33.102 libmp3lame
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
[out#0/mp3 @ 00000128b753ef40] video:0KiB audio:12812KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.002630%
size=   12812KiB time=00:13:39.91 bitrate= 128.0kbits/s speed=35.8x

  • 批量操作

比如,文件夹下有*.mp4文件,要批量转换为XX.mp3文件,可以用如下方法

for i in ./*.mp4
do
ffmpeg -i $i ${i}.mp3
done

再比如,文件夹下所有文件文件,都要批量转换为XX.mp3文件,可以用如下方法

for i in ./*
do
ffmpeg -i $i ${i}.mp3
done

方法2 在线网站工具

  • URL

CASE FLV视频文件转 MP3 音频文件

ffmpeg -i foo.flv foobar.mp3

CASE MP4视频文件转WAV音频文件

ffmpeg -i foo.mp4 foobar.wav

CASE WAV音频文件 转 MP3 音频文件

ffmpeg -i foo.wav foobar.mp3

CASE WEBM网络视频文件转 MP4视频文件

例如从 https://www.dlbunny.com/zh-CN/youtube 网站下载的 youtube 文件,默认是: webm 格式的视频文件。

C:\Users\xxx\Downloads>ffmpeg -i videoplayback.webm videoplayback.2.mp4
ffmpeg version N-118658-g7225e307be-20250307 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-shared --disable-static --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --disable-libvvenc --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250307
  libavutil      59. 58.100 / 59. 58.100
  libavcodec     61. 33.102 / 61. 33.102
  libavformat    61.  9.107 / 61.  9.107
  libavdevice    61.  4.100 / 61.  4.100
  libavfilter    10.  9.100 / 10.  9.100
  libswscale      8. 13.100 /  8. 13.100
  libswresample   5.  4.100 /  5.  4.100
  libpostproc    58.  4.100 / 58.  4.100
Input #0, matroska,webm, from 'videoplayback.webm':
  Metadata:
    encoder         : google/video-file
  Duration: 00:13:39.90, start: 0.000000, bitrate: 640 kb/s
  Stream #0:0(eng): Video: vp9 (Profile 0), yuv420p(tv, bt709), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn (default)
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 00000152e7e790c0] using SAR=1/1
[libx264 @ 00000152e7e790c0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 00000152e7e790c0] profile High, level 4.0, 4:2:0, 8-bit
[libx264 @ 00000152e7e790c0] 264 - core 164 - H.264/MPEG-4 AVC codec - Copyleft 2003-2025 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=12 lookahead_threads=2 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=23 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'videoplayback.2.mp4':
  Metadata:
    encoder         : Lavf61.9.107
  Stream #0:0(eng): Video: h264 (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 23.98 fps, 24k tbn (default)
    Metadata:
      encoder         : Lavc61.33.102 libx264
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
[out#0/mp4 @ 00000152e7edd200] video:90773KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.255525%
frame=19658 fps= 54 q=-1.0 Lsize=   91005KiB time=00:13:39.81 bitrate= 909.4kbits/s speed=2.25x
[libx264 @ 00000152e7e790c0] frame I:104   Avg QP:15.79  size:132655
[libx264 @ 00000152e7e790c0] frame P:5007  Avg QP:18.74  size: 10628
[libx264 @ 00000152e7e790c0] frame B:14547 Avg QP:22.77  size:  1783
[libx264 @ 00000152e7e790c0] consecutive B-frames:  0.9%  0.9%  1.1% 97.1%
[libx264 @ 00000152e7e790c0] mb I  I16..4: 18.4% 54.8% 26.8%
[libx264 @ 00000152e7e790c0] mb P  I16..4:  1.0%  3.1%  0.2%  P16..4: 16.5%  4.4%  2.3%  0.0%  0.0%    skip:72.4%
[libx264 @ 00000152e7e790c0] mb B  I16..4:  0.1%  0.2%  0.0%  B16..8: 12.2%  0.5%  0.1%  direct: 0.3%  skip:86.6%  L0:46.6% L1:50.8% BI: 2.6%
[libx264 @ 00000152e7e790c0] 8x8 transform intra:66.9% inter:78.3%
[libx264 @ 00000152e7e790c0] coded y,uvDC,uvAC intra: 34.5% 33.0% 13.9% inter: 2.2% 2.4% 0.1%
[libx264 @ 00000152e7e790c0] i16 v,h,dc,p: 50% 30%  4% 15%
[libx264 @ 00000152e7e790c0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 16% 31%  3%  4%  4%  4%  5%  4%
[libx264 @ 00000152e7e790c0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 37% 23%  9%  4%  6%  6%  5%  5%  4%
[libx264 @ 00000152e7e790c0] i8c dc,h,v,p: 62% 17% 17%  4%
[libx264 @ 00000152e7e790c0] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 00000152e7e790c0] ref P L0: 64.2% 11.4% 18.6%  5.8%  0.0%
[libx264 @ 00000152e7e790c0] ref B L0: 87.5% 10.7%  1.8%
[libx264 @ 00000152e7e790c0] ref B L1: 95.5%  4.5%
[libx264 @ 00000152e7e790c0] kb/s:906.95

CASE 将MP4视频文件V的视频内容 + MP4视频文件A的音频内容合并为新的MP4文件

ffmpeg -i input_video.mp4 -i input_audio.mp4 -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 output_video.mp4

参数

  • -i input_video.mp4 指定了要合并音频的目标视频文件。
  • -i input_audio.mp4 指定了包含音频的源文件。
  • -c:v copy 表示复制视频流。
  • -c:a copy 表示复制音频流。
  • -map 0:v:0 表示选择第一个输入文件(视频文件)的视频流。
  • -map 1:a:0 表示选择第二个输入文件(音频文件)的音频流。

demo

C:\Users\xxx\Downloads>ffmpeg -i videoplayback.2.mp4 -i videoplayback.mp4 -c:v copy -c:a copy -map 0:v:0 -map 1:a:0 output_video.mp4
ffmpeg version N-118658-g7225e307be-20250307 Copyright (c) 2000-2025 the FFmpeg developers
  built with gcc 14.2.0 (crosstool-NG 1.27.0.18_7458341)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-shared --disable-static --disable-w32threads --enable-pthreads --enable-iconv --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-libxml2 --enable-lzma --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-libzmq --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --disable-libvvenc --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20250307
  libavutil      59. 58.100 / 59. 58.100
  libavcodec     61. 33.102 / 61. 33.102
  libavformat    61.  9.107 / 61.  9.107
  libavdevice    61.  4.100 / 61.  4.100
  libavfilter    10.  9.100 / 10.  9.100
  libswscale      8. 13.100 /  8. 13.100
  libswresample   5.  4.100 /  5.  4.100
  libpostproc    58.  4.100 / 58.  4.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'videoplayback.2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf61.9.107
  Duration: 00:13:39.90, start: 0.000000, bitrate: 909 kb/s
  Stream #0:0[0x1](eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 906 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc61.33.102 libx264
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from 'videoplayback.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2024-12-10T21:55:18.000000Z
    encoder         : Google
  Duration: 00:13:39.92, start: 0.000000, bitrate: 198 kb/s
  Stream #1:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 640x360 [SAR 1:1 DAR 16:9], 67 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
    Metadata:
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
  Stream #1:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
  Stream #1:1 -> #0:1 (copy)
Output #0, mp4, to 'output_video.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf61.9.107
  Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 906 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)
    Metadata:
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
      encoder         : Lavc61.33.102 libx264
  Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
    Metadata:
      creation_time   : 2024-12-10T21:55:18.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 12/10/2024.
      vendor_id       : [0][0][0][0]
Press [q] to stop, [?] for help
[out#0/mp4 @ 000001da388b9280] video:90773KiB audio:12811KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: 0.595182%
frame=19658 fps=0.0 q=-1.0 Lsize=  104201KiB time=00:13:39.81 bitrate=1041.2kbits/s speed=1.69e+03x

大型互联网平台的流媒体格式

Bilibili : .m4s格式

  • 前置知识:M4S 分段文件 / M3U8 播放列表

参见:概述 章节

缘起

  • .m4s格式

  • 用户在B站手机客户端缓存的视频文件,查看文件结构发现:视频的音频和视频文件都是 m4s 容器封装格式

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

手机客户端缓存下载视频的文件结构

Windows 客户端缓存下载视频的文件结构

B站视频下载缓存策略思考

(1)ID 认识

  • 熟悉B站的用户应该都会了解到,B站网页端上的视频、音频、专栏文章、用户都是以唯一的 ID 进行标识的。

  • 视频 ID [Anime (Video) ID, aid/avid]、音频 ID [Audio ID, auid]、用户 ID [User ID, uid]、文章 ID [Content Viewing ID, cvid]、通知 ID [Notification ID, nfid]、标签 ID [Tag ID, tid] 等等。

  • 在下载视频的时候,起到主要作用的是 aidcid 这两个唯一 ID。

aidcid 的区别是:aid 既可以指单个视频,也可以指含有多个视频的播放列表,而 cid视频级唯一的,如下面获取的视频文件夹目录可知视频 cid 为 26498501388。

(2)Windows 客户端缓存文件目录分析

在 Bilibili 电脑客户端的缓存视频文件夹中,通常会包含以下几种文件:

  • playurl 文件:通常保存了音视频分片的播放 URL 信息、音视频流链接、支持的编解码封装格式、不同清晰度分辨率下的码率等信息。

video 信息部分

audio 信息部分

支持格式和编解码和分辨率质量版本其中一部分信息

  • videoInfo 文件:包含该视频的基本元数据,如视频标题、描述、作者信息、上传时间、清晰度选项等。

  • 音频和视频的 .m4s 文件:实际的音频和视频数据,Bilibili 缓存的视频一般会将音频和视频分别存储成独立的 .m4s 文件,视频播放时需要同时解码并同步这两个文件。

  • dm1 文件:该视频对应的弹幕信息,一般为 Bilibili 自定义的二进制或 JSON 格式,包含时间戳、弹幕内容、发送者 ID 等,允许客户端在播放缓存视频时加载弹幕信息,并在适当的时间显示。

  • groupimage 文件:视频封面图或相关图片资源,一般为 .jpg 格式的图像。

  • videoInfo 文件(JSON 源文件):另一种视频的 JSON 元数据信息文件,提供视频的基本描述信息,可能与 .videoInfo 内容类似,具体格式视客户端版本而定。

  • view 文件:可能是一个标识文件,用于标记视频的缓存状态或播放进度等信息。

  • 总流程:

在用户播放缓存视频时,客户端首先读取 playurl 和 videoInfo 文件来获得播放信息和元数据,然后读取 .m4s 文件加载音视频内容,最后读取 dm1 文件依照其时间戳数据,在正确的时间与音视频内容同步显示弹幕。
通过分离存储音频和视频,可以实现动态清晰度切换、无缝拼接,以及音视频的分开缓存和传输。

(3)缓存策略

  • 无论是手机客户端还是 Windows 客户端,从B站缓存到本地的视频的文件目录,其音频和视频文件均为整体的 .m4s 文件,这是为什么呢?个人思考如下:

  • M4S 各片段有自己独立的 moofmadt 等,将音视频流作为整体文件缓存,可以减少文件碎片和分段加载的复杂性,便于离线直接读取播放,不需要像在线 HLS 或 DASH 流一样逐个加载片段,简化用户离线体验。

  • 对于我们从B站手机客户端下载得到的 video.m4saudio.m4s 文件,首先我们到文件管理的目录中找到这两个文件,直接改后缀并不能改变文件的实际封装方式,可能导致合并或播放异常,我们可以直接使用 FFmpeg 将音视频 .m4s 文件合并为一个完整的视频文件:

ffmpeg -i video.m4s -i audio.m4s -c copy output.mp4

生成的 output.mp4 文件即可在本地播放器中播放。

搞定!接着我们反过来通过 DASH 和 HLS 途径生成 .m4s 文件分别分析~(参见:概述章节)

抖音:MP4

https://www.douyin.com/search/Res Download?aid=1a792d6d-8338-4c6c-a480-a0ec472d8dfd&modal_id=7193527234668416267&type=general
https://v3-web.douyinvod.com/74a41b07d55e71c79653048226b368c4/67a27dcd/video/tos/cn/tos-cn-ve-15/o4T6DIQUzEXWkBjwghNGA1QO3fO1PxAAJH4e2U/?a=6383&ch=11&cr=3&dr=0&lr=all&cd=0|0|0|3&br=247&bt=247&cs=0&ds=3&ft=4TMWc6DhppftrGLJ.s~.C_fauVq0InHmBtdc6BICTnkl_QdHDD2TP0l6rpfzpusZ.&mime_type=video_mp4&qs=0&rc=Z2Q1ZTdlNmQ7NjgzODZlaUBpM2ptZzo6Zjs7aTMzNGkzM0AtYDQuXy9gXl8xNTQuY2I2YSNwYzU0cjQwal5gLS1kLTBzcw%3D%3D&btag=80000e00030000&cquery=100B_100D_100J_100o_101n&dy_q=1738690981&feature_id=f0150a16a324336cda5d6dd0b69ed299&l=2025020501430041C5E95C57FD92452EA6&__vid=7193527234668416267

HTML5原生的 Video 组件

<video controls="" autoplay="" name="media">
    <source src="https://v3-web.douyinvod.com/74a41b07d55e71c79653048226b368c4/67a27dcd/video/tos/cn/tos-cn-ve-15/o4T6DIQUzEXWkBjwghNGA1QO3fO1PxAAJH4e2U/?a=6383&amp;ch=11&amp;cr=3&amp;dr=0&amp;lr=all&amp;cd=0%7C0%7C0%7C3&amp;br=247&amp;bt=247&amp;cs=0&amp;ds=3&amp;ft=4TMWc6DhppftrGLJ.s~.C_fauVq0InHmBtdc6BICTnkl_QdHDD2TP0l6rpfzpusZ.&amp;mime_type=video_mp4&amp;qs=0&amp;rc=Z2Q1ZTdlNmQ7NjgzODZlaUBpM2ptZzo6Zjs7aTMzNGkzM0AtYDQuXy9gXl8xNTQuY2I2YSNwYzU0cjQwal5gLS1kLTBzcw%3D%3D&amp;btag=80000e00030000&amp;cquery=100B_100D_100J_100o_101n&amp;dy_q=1738690981&amp;feature_id=f0150a16a324336cda5d6dd0b69ed299&amp;l=2025020501430041C5E95C57FD92452EA6&amp;__vid=7193527234668416267" type="video/mp4">
</video>

小红书:.mp4

找到.mp4的视频资源URL

https://sns-video-al.xhscdn.com/stream/1/110/259/01e7a189d60614dd0103700394cf076699_259.mp4

Y 推荐文献

X 参考文献

.\ffplay.exe -f s16le -ar 61000 -ac 2 udp://0.0.0.0:10001

posted @ 2025-02-05 00:39  千千寰宇  阅读(40)  评论(0)    收藏  举报