Home / 开发 / golang 利用FFmpeg生成m3u8文件
为什么需要利用FFmpeg生成m3u8文件?
可以先利用 N_m3u8DL-RE 下载ts文件,但是这个程序不能生成m3u8文件,因此需要。
这一套组合拳打下来,还要自己切片吗?拿这别人切好的资源嘎嘎香。
看图:
package main
import (
"flag"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"sort"
"strings"
)
var (
// 命令行参数
dirsrc = flag.String("dir", "", "文件保存路径(默认为当前路径)")
m3u8name = flag.String("m", "webqwe.com.m3u8", "m3u8文件名")
proxy = flag.String("p", "", "http代理")
m3u8url = flag.String("u", "", "m3u8 url")
)
//生成文件夹下面的 m3u8文件
func main() {
// 解析命令行参数
flag.Parse()
dirsrc := *dirsrc
m3u8name := *m3u8name
os.RemoveAll(dirsrc + m3u8name) //下载失败删除残留
// 读取当前目录中的所有文件和子目录
files, err := ioutil.ReadDir(dirsrc)
if err != nil {
panic(err)
}
tsFile := make([]string, 0)
// 获取所有文件,并输出它们的名字
for _, file := range files {
if file.IsDir() {
continue
}
// 判断文件名包含"ts"
if strings.Contains(file.Name(), "ts") {
tsFile = append(tsFile, file.Name())
}
//包含tmp文件名,说明没有下载完,或者失败!
if strings.Contains(file.Name(), "tmp") {
return
}
}
// 对tsFile进行排序
sort.Strings(tsFile)
newM3u8Body := `#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:999
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-DISCONTINUITY`
for _, tsname := range tsFile {
newM3u8Body = newM3u8Body + "\n"
EXTINF := getTsTime(dirsrc + tsname)
newM3u8Body = newM3u8Body + "#EXTINF:" + EXTINF + ",\n"
newM3u8Body = newM3u8Body + tsname
}
newM3u8Body = newM3u8Body + "\n" + "#EXT-X-ENDLIST"
ioutil.WriteFile(dirsrc+m3u8name, []byte(newM3u8Body), 0666) //写入文件(字节数组)
}
func GetAllFile(pathname string, s []string) ([]string, error) {
rd, err := ioutil.ReadDir(pathname)
if err != nil {
fmt.Println("read dir fail:", err)
return s, err
}
for _, fi := range rd {
if !fi.IsDir() {
fileType := path.Ext(fi.Name())
if fileType == ".ts" {
s = append(s, fi.Name())
}
}
}
return s, nil
}
//ffprobe 获取视频长度
func getTsTime(tsfile string) string {
cmd := exec.Command("ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", tsfile)
output, err := cmd.Output()
if err != nil {
fmt.Println("Error executing command:", err)
return ""
}
s := strings.TrimSpace(string(output))
return s
}