使用ffmpeg将mp4视频转为m3u8格式

下载ffmpeg地址

通过网盘分享的文件:ffmpeg-master-latest-win64-gpl.zip

链接: https://pan.baidu.com/s/1Hryli_SAV2vcOfLLRA8vFg 提取码: 3cnr

配置环境变量

配置好环境变量后CMD:ffmpeg -version

进入需要切片的目录

ffmpeg -y -i myvideo.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb sk.ts

如果报错

纠正错误后的命令

ffmpeg -y -i myvideo.mp4 -vcodec copy -acodec copy sk.ts

会生成 sk.ts文件 然后通过这个文件切片成.m3u8

命令

ffmpeg -i sk.ts -c copy -map 0 -f segment -segment_list sk.m3u8 -segment_time 8 sk%04d.ts

-segment_time 8:8 秒一个片段

kotlin 复制代码
  /**
     * 在后台线程将 assets/sk/ 下的 m3u8 和 ts 文件拷贝到缓存目录,
     * 拷贝完成后切换播放 m3u8
     */
    private fun prepareM3u8Assets() {
        lifecycleScope.launch(Dispatchers.IO) {
            try {
                val m3u8Path = copyAssetsM3u8ToCache("sk", "sk.m3u8")
                if (m3u8Path != null) {
                    // 拷贝完成后切换到 m3u8 播放
                    withContext(Dispatchers.Main) {
                        playM3u8(m3u8Path)
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
kotlin 复制代码
    /**
     * 将 assets 目录下的 m3u8 及所有 ts 分片拷贝到缓存目录
     * 返回 m3u8 文件的绝对路径
     */
    private fun copyAssetsM3u8ToCache(assetDir: String, m3u8FileName: String): String? {
        val cacheDir = File(requireContext().cacheDir, assetDir)
        val m3u8File = File(cacheDir, m3u8FileName)

        // 如果 m3u8 已存在,直接返回(说明已拷贝过)
        if (m3u8File.exists()) return m3u8File.absolutePath

        cacheDir.mkdirs()

        val assetManager = requireContext().assets
        // 列出 assets/sk/ 下所有文件
        val fileList = assetManager.list(assetDir) ?: return null

        for (fileName in fileList) {
            val targetFile = File(cacheDir, fileName)
            if (targetFile.exists()) continue

            try {
                val input = assetManager.open("$assetDir/$fileName")
                val output = FileOutputStream(targetFile)
                input.copyTo(output)
                input.close()
                output.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        return m3u8File.absolutePath
    }
相关推荐
weixin_403810135 小时前
AI智能体写安卓自动化脚本教程:Cursor/Trae+CLI 实战,自然语言生成代码
android·人工智能·自动化·跨境电商·安卓自动化脚本·多账户运营
呆呆小孩7 小时前
零基础学 MySQL(上):从建库建表到增删改查,一篇搭好 SQL 基础
android·sql·mysql
catchadmin7 小时前
NativePHP v4 让 Blade 构建原生 iOS 与 Android 界面
android·ios·ai·php
FfHUCisI9 小时前
Golang 数据库连接池深度调优
android·数据库·golang
OpenCutAI9 小时前
无字幕视频怎么翻译?跨境出海视频本地化实操指南
音视频
科技小E11 小时前
国标GB28181视频平台EasyGBS监控为什么会“瞎”:视频质量诊断EasyVQD如何揪出黑屏卡顿偏色
大数据·人工智能·音视频
古法安卓11 小时前
Android-epoll原理详解
android·java·android studio
字节暗面13 小时前
四款 APP 加固强度测评:让 AI 拆了四个包,结果有点出乎意料
android·逆向工程·加固
ACP广源盛1392462567314 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 Serdes 长距离视频传输芯片 GSV5800 在私有化 AI 服务中的价值与应用场景
大数据·数据库·人工智能·嵌入式硬件·矩阵·开源·音视频
网安蟹佬霸14 小时前
蓝队防御实战:SIEM与SOAR构建安全运营中心(万字详解+实战配置)
android·安全·web安全·网络安全·网安