使用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
    }
相关推荐
纽格立科技36 分钟前
纽格立参展IBC 2026——DRM端到端全链路方案,展位Hall 8 F71
车载系统·音视频·信息与通信·传媒
邪修king37 分钟前
Re:Linux系统篇(二十六):文件系统(二):Ext 文件系统底层详解:从 inode、块组到软硬链接,结合 Windows 讲透文件管理本质
android·java·linux
又见情义1 小时前
RK3568 Android 13 版本号管理实战:基于 ROCKCHIP_BUILD_NUMBER 的定制化方案
android
终端安全笔记1 小时前
iOS 27 强制 TLS 1.2:租赁设备的注册链路会在哪一环断
android·网络·安全·ios·智能手机
mmsx1 小时前
MapLibre 实战 11|用户说"我的地块丢了":一个 sealed class 图层模型,和四个让我重构三版的坑
android·前端·开源
linux_cfan2 小时前
videojs v10 源代码系列解读:10 · `DestroyMixin`:双重 rAF 延迟销毁
前端·javascript·音视频
恋猫de小郭4 小时前
CPF-Flutter 社区提出折叠场景分栏(平行视界) 方案
android·前端·flutter
事圆则缓4 小时前
Java 常用 API 如何建模 Android 订单业务
android
Railshiqian4 小时前
android16单手模式代码走读
android·多屏·单手模式
程序员-珍5 小时前
Android studio 突然打不开
android·java