原由:

最近在极客时间上购买一波 Go语言从入门到实战 视频课程,但又不想受到网络环境的限制,所以就有了这篇文章。

操作:

一、ffmpeg 下载和安装

  • mac OS X :

    1
    2
    3
    4
    5
    # 安装 homebrew
    /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

    # 安装 ffmpeg
    brew install ffmpeg
  • Linux 安装:

    1
    yum install ffmpeg

二、使用ffmpeg下载且合并成mp4

1
2
3
ffmpeg  -i "http://xxxxxx/video/movie.m3u8" -vcodec copy -acodec copy -absf aac_adtstoasc  output.mp4

# m3u8 链接, output.mp4 输出文件名

三、使用Go实现批量合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os/exec"
)

type Datas struct {
Data List `json:"data"`
}

type List struct {
L []VideoMap `json:"list"`
}

type VideoMap struct {
ArticleTitle string `json:"article_title"`
VideoMediaMap struct {
HD struct {
URL string `json:"url"`
Size int64 `json:"size"`
} `json:"hd"`
} `json:"video_media_map"`
}

var (
video Datas
path string = "/Users/gxm/Movies/time_go/" // 保存文件的路径
)

func main() {
body, err := ioutil.ReadFile("./ Go语言从入门到实战.json") # m3u8 视频列表的json文件
if err != nil {
log.Fatalln(err)
}

err = json.Unmarshal(body, &video)

if err != nil {
log.Fatalln(err)
}

// fmt.Println(video)

for _, v := range video.L {
fmt.Println(v.VideoMediaMap.HD.URL, v.ArticleTitle)
merge(v.VideoMediaMap.HD.URL, v.ArticleTitle)
}
}

//ffmpeg -i "http://xxxxxx/video/movie.m3u8" -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4
func merge(url string, name string) {

cmd := exec.Command("ffmpeg", "-i", url, "-vcodec", "copy", "-acodec", "copy", "-absf", "aac_adtstoasc", path+name+".mp4")
message, err := cmd.CombinedOutput()

if err != nil {
log.Println(err)
}

log.Println(string(message))
}

总结:

要是不想把m3u8的数据json下载本地在运行的话,你可以使用爬虫模拟登录去获m3u8的数据,然后在去执行merge函数来合并。

本文章仅提供学习,如有违规和侵权请联系本人。