Python 实战:m4s 视频无损 / 兼容转 MP4,两种方案完美解决 B 站视频格式转换

前言

经常下载 B 站视频的小伙伴都知道,缓存后的视频是视频 m4s + 音频 m4s分离格式,无法直接用普通播放器打开。网上很多转换工具要么收费要么有广告,今天用 Python 结合 FFmpeg 实现 m4s 转 MP4,提供极速合成全平台兼容两种方案,满足不同场景需求!

一、核心知识点

  1. m4s 格式:B 站等平台的分段缓存格式,分为纯视频流和纯音频流,必须合并后才能播放

  2. FFmpeg:开源音视频处理神器,无需复杂配置,命令行即可完成合并、转码

  3. 两种方案对比:

    • 方案一:直接复制音视频流,极速合成,但输出 AV1 编码,兼容性极差
    • 方案二:转码为 H.264 编码,全平台兼容,手机 / 电脑自带播放器都能播放

二、环境准备

  1. 安装 Python(3.6 + 版本即可)

  2. 安装 FFmpeg 并配置环境变量

    • 下载地址:https://ffmpeg.org/download.html
    • 配置教程:将 ffmpeg.exe 所在路径添加到系统环境变量 Path
  3. 无需额外 Python 库,内置subprocess即可调用命令行

三、完整代码实现

python

运行

# -*- coding: utf-8 -*-
import subprocess

def m4s_to_mp4(VIDEO_M4S,AUDIO_M4S,OUTPUT_MP4):
    """
    m4s格式转mp4,支持两种方案
    :param VIDEO_M4S: 视频m4s文件路径
    :param AUDIO_M4S: 音频m4s文件路径
    :param OUTPUT_MP4: 输出mp4文件路径
    """
    # ==================== 方案二:兼容性拉满(推荐) ====================
    # 优点:转码为H.264编码,手机/电脑/平板全平台兼容
    # 缺点:转码速度比方案一慢10-50倍,取决于电脑性能
    print("正在将m4s转成mp4,使用方案二:兼容性高,运行比方案一慢10-50倍,请耐心等待")
    cmd = [
        "ffmpeg",
        "-i", VIDEO_M4S,      # 输入视频m4s
        "-i", AUDIO_M4S,      # 输入音频m4s
        "-c:v", "libx264",    # 视频编码转成 H.264(通用编码)
        "-c:a", "copy",       # 音频直接复制,不转码(节省时间)
        "-preset", "fast",    # 转码速度预设(fast快/medium中/slow慢,越慢画质越好)
        "-crf", "23",         # 画质控制(18-28最优,数值越小画质越好,体积越大)
        "-y",                 # 覆盖同名文件,无需确认
        OUTPUT_MP4            # 输出mp4文件
    ]

    try:
        # 执行命令,捕获输出日志
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"✅ 转码成功!兼容版文件:{OUTPUT_MP4}")
    except subprocess.CalledProcessError as e:
        print(f"❌ 转码失败:{e.stderr}")

    # ==================== 方案一:极速合成(不推荐) ====================
    # 优点:秒级合成,速度极快
    # 缺点:合成的mp4是AV1视频流,电脑自带播放器/手机无法播放画面
    # cmd = [
    #     "ffmpeg",
    #     "-i", VIDEO_M4S,
    #     "-i", AUDIO_M4S,
    #     "-c", "copy",   # 直接复制音视频流,不转码
    #     "-y",
    #     OUTPUT_MP4
    # ]
    #
    # try:
    #     subprocess.run(cmd, check=True, capture_output=True, text=True)
    #     print(f"✅ 合成成功!文件:{OUTPUT_MP4}")
    # except subprocess.CalledProcessError as e:
    #     print(f"❌ 失败:{e.stderr}")

# ==================== 调用示例 ====================
if __name__ == '__main__':
    # 替换为你的m4s文件路径
    video_path = "video.m4s"   # 视频m4s
    audio_path = "audio.m4s"   # 音频m4s
    output_path = "output.mp4" # 输出mp4

    # 执行转换
    m4s_to_mp4(video_path, audio_path, output_path)

四、代码详解

1. 函数参数

  • VIDEO_M4S:视频 m4s 文件的绝对 / 相对路径
  • AUDIO_M4S:音频 m4s 文件的绝对 / 相对路径
  • OUTPUT_MP4:转换后 MP4 的保存路径

2. 方案二核心参数(重点)

表格

参数作用
-c:v libx264强制视频编码为 H.264,解决兼容性问题
-c:a copy音频直接复制,不转码,大幅提升效率
-preset fast转码速度预设,平衡速度与画质
-crf 23标准画质参数,肉眼无损耗,体积适中

3. 异常处理

使用subprocess.CalledProcessError捕获命令执行错误,打印失败原因,方便排查问题(如文件路径错误、FFmpeg 未安装)

五、使用教程

  1. 找到 B 站缓存的 m4s 文件(一般在Android/data/tv.danmaku.bili/download目录下)
  2. 区分视频 m4s(体积大)和音频 m4s(体积小)
  3. 修改代码中的文件路径
  4. 运行代码,等待转换完成即可

六、常见问题

  1. FFmpeg 不是内部命令:未配置环境变量,重新配置 FFmpeg 环境变量
  2. 转换失败:检查 m4s 文件路径是否正确,文件是否损坏
  3. 转码速度慢:方案二是转码机制,属于正常现象,耐心等待即可

七、总结

本文实现了 m4s 转 MP4 的两种方案,方案二是日常使用首选,虽然速度慢一点,但全平台兼容的优势完全覆盖缺点。代码简洁易懂,无需第三方库,新手也能直接使用!

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐