linux安装ffmpeg详细教程
https://blog.csdn.net/raoxiaoya/article/details/109130549

顺序
1、下载m3u8
2、根据m3u8下载ts
3、将ts合成mp4

download.go
package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"regexp"
)

var fileChan chan string
var endChan chan string
var tsChan chan string
var folder = "/data/www/mv/dian_shi_ju/ping_fan_de_shi_jie"
var num = 56 // 56集

func main() {
	fileChan = make(chan string, num)
	endChan = make(chan string, num)
	tsChan = make(chan string, num)

	for i := 0; i < num; i++ {
		s := fmt.Sprintf("https://u5-web.scbaiduwk.com/dianshiju/tv_ji0cjkun/tv_ji0cjkun_%s.mp4/index.m3u8", fmt.Sprintf("%02d", i+1))
		fileChan <- s
	}

	// 下载m3u8
	for n := 0; n < 10; n++ {
		go consumer(fileChan, tsChan)
	}

	// 下载ts
	for m := 0; m < 30; m++ {
		go readTs(tsChan, endChan)
	}

	k := 0
	for {
		<-endChan
		k++
		if k == num {
			break
		}
	}
}

func consumer(fc chan string, tsChan chan string) {
	for {
		str := <-fc
		reg := regexp.MustCompile(`tv_ji0cjkun_(\d+).mp4`)
		res := reg.FindAllStringSubmatch(str, -1)
		no := res[0][1]

		os.Mkdir(folder+"/"+no, os.ModePerm)

		response, _ := http.Get(str)
		filename := folder + "/" + no + "/" + no + ".m3u8"

		f, _ := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, os.ModePerm)
		defer f.Close()
		defer response.Body.Close()

		io.Copy(f, response.Body)

		tsChan <- no
	}
}

func readTs(tsChan chan string, endChan chan string) {
	for {
		no := <-tsChan
		fold := folder + "/" + no + "/"
		data, _ := ioutil.ReadFile(fold + no + ".m3u8")
		reg := regexp.MustCompile(`(segment-\d+-v1-a1.ts)`)
		res := reg.FindAllStringSubmatch(string(data), -1)
		for _, v := range res {
			url := fmt.Sprintf("https://u5-web.scbaiduwk.com/dianshiju/tv_ji0cjkun/tv_ji0cjkun_%s.mp4/%s", no, v[1])
			response, _ := http.Get(url)
			f, _ := os.OpenFile(fold+v[1], os.O_CREATE|os.O_RDWR, os.ModePerm)
			defer f.Close()
			defer response.Body.Close()

			io.Copy(f, response.Body)
		}

		endChan <- ""
	}
}

createMp4.go
package main

import (
	"fmt"
	"os"
	"os/exec"
	"regexp"
	"sort"
	"strconv"
	"strings"
)

var dirname = "/data/www/mv/dian_shi_ju/ping_fan_de_shi_jie"
var savedir = "/data/www/mv/dian_shi_ju/00_ok"

func main() {
	fs, err := os.Open(dirname)
	if err != nil {
		panic(err)
	}
	defer fs.Close()

	fiss, err := fs.Readdir(0)
	if err != nil {
		panic(err)
	}

	for _, vv := range fiss {
		temp := vv

		// 如果电脑配置好的话使用协程
		fold := dirname + "/" + temp.Name()
		f, err := os.Open(fold)
		if err != nil {
			panic(err)
		}
		defer func() {
			f.Close()

		}()

		fis, err := f.Readdir(0)
		if err != nil {
			panic(err)
		}
		names := make([]string, 0)
		toSort := make([]int, 0)
		for _, v := range fis {
			if strings.Contains(v.Name(), "segment") { // segment-1-v1-a1.ts
				reg := regexp.MustCompile(`segment-(\d+)-v1-a1`)
				res := reg.FindAllStringSubmatch(v.Name(), -1)
				id, _ := strconv.Atoi(res[0][1])
				toSort = append(toSort, id)
			}
		}

		sort.Ints(toSort)

		for _, v := range toSort {
			names = append(names, fold+"/"+fmt.Sprintf("segment-%d-v1-a1.ts", v))
		}

		str := strings.Join(names, "|")
		makeMp4(str, temp.Name())
	}
}

// ffmpeg -i "concat:segment-1-v1-a1.ts|segment-2-v1-a1.ts" -acodec copy -vcodec copy -absf aac_adtstoasc output.mp4
func makeMp4(str string, no string) {
	binary, lookErr := exec.LookPath("ffmpeg")
	if lookErr != nil {
		panic(lookErr)
	}

	args := []string{
		"-i",
		fmt.Sprintf("concat:%s", str),
		"-acodec",
		"copy",
		"-vcodec",
		"copy",
		"-absf",
		"aac_adtstoasc",
		fmt.Sprintf("%s/%s.mp4", savedir, no),
	}

	cmd := exec.Command(binary, args...)
	r, err := cmd.Output()

	fmt.Println(err)
	fmt.Println(string(r))
}

go run download.go

go run createMp4.go

当然也可以整合到一个程序。

在这里插入图片描述