使用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
    }
相关推荐
2601_9654490810 分钟前
AI视频制作:做传统文化视频,古文断句配音难,AI怎么正确断句配音?
人工智能·音视频
TimeFine1 小时前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象3272 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
探鸽小钛2 小时前
4G 终端 ES8311 - 挂断一次,下次说话就没声了之解决办法
物联网·音视频·嵌入式·esp32·webrtc
weipt3 小时前
视频人物跨时长快速检索:从一闪而过的背影,精确找到他
音视频
山东孙燕姿3 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
LittroInno4 小时前
边缘AI模组选型:把视频带宽、压缩和推理吞吐分别算清
人工智能·音视频·边缘计算·视频编码·模组选型·视频带宽·tofu6
蒸鱼Yuzheng4 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui4 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果5 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin