Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持多源m3u8,但只选择第一个源 #38

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified build-release.sh
100644 → 100755
Empty file.
47 changes: 40 additions & 7 deletions m3u8-downloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"net/url"
"os"
"os/exec"
"path"
"path/filepath"
"runtime"
"strconv"
"strings"
Expand All @@ -38,7 +38,7 @@ var (
// 命令行参数
urlFlag = flag.String("u", "", "m3u8下载地址(http(s)://url/xx/xx/index.m3u8)")
nFlag = flag.Int("n", 16, "下载线程数(max goroutines num)")
htFlag = flag.String("ht", "apiv1", "设置getHost的方式(apiv1: `http(s):// + url.Host + path.Dir(url.Path)`; apiv2: `http(s)://+ u.Host`")
htFlag = flag.String("ht", "apiv1", "设置getHost的方式(apiv1: `http(s):// + url.Host + filepath.Dir(url.Path)`; apiv2: `http(s)://+ u.Host`")
oFlag = flag.String("o", "movie", "自定义文件名(默认为movie)")
cFlag = flag.String("c", "", "自定义请求 cookie")
sFlag = flag.Int("s", 0, "是否允许不安全的请求(默认为0)")
Expand Down Expand Up @@ -105,12 +105,23 @@ func Run() {
pwd = savePath
}
//pwd = "/Users/chao/Desktop" //自定义地址
download_dir = path.Join(pwd, movieDir)
download_dir = filepath.Join(pwd, movieDir)
if isExist, _ := pathExists(download_dir); !isExist {
os.MkdirAll(download_dir, os.ModePerm)
}
m3u8Host := getHost(m3u8Url, hostType)
m3u8Body := getM3u8Body(m3u8Url)

// 判断该文件是二级目录还是ts列表
if file, path := parseM3U8File(m3u8Body); file == TypeMenu {
// 请求这个地址,并将其作为原代码逻辑中的顶级路径,即 u 指定的参数
parse, err := url.Parse(m3u8Url)
if err != nil {
panic(err)
}
m3u8Body = getM3u8Body(parse.Scheme + "://" + parse.Host + path) // 注意:这里的path直接假设为相同域名下了
}

//m3u8Body := getFromFile()
ts_key := getM3u8Key(m3u8Host, m3u8Body)
if ts_key != "" {
Expand All @@ -130,7 +141,7 @@ func Run() {
default:
unix_merge_file(download_dir)
}
os.Rename(download_dir+"/merge.mp4", download_dir+".mp4")
os.Rename(filepath.Join(download_dir, "merge.mp4"), download_dir+".mp4")
os.RemoveAll(download_dir)
DrawProgressBar("Merging", float32(1), PROGRESS_WIDTH, "merge.ts")
fmt.Printf("\n[Success] 下载保存路径:%s | 共耗时: %6.2fs\n", download_dir+".mp4", time.Now().Sub(now).Seconds())
Expand All @@ -142,7 +153,7 @@ func getHost(Url, ht string) (host string) {
checkErr(err)
switch ht {
case "apiv1":
host = u.Scheme + "://" + u.Host + path.Dir(u.EscapedPath())
host = u.Scheme + "://" + u.Host + filepath.Dir(u.EscapedPath())
case "apiv2":
host = u.Scheme + "://" + u.Host
}
Expand Down Expand Up @@ -204,6 +215,28 @@ func getTsList(host, body string) (tsList []TsInfo) {
return
}

// 文件内容的类别
const TypeMenu = 0 // 二级目录
const TypePlayList = 1 // 播放列表,即 ts 列表

// 解析 M3U8 文件
func parseM3U8File(content string) (int, string) {
lines := strings.Split(content, "\n")
for i, l := 0, len(lines); i < l; i++ {
// 二级 M3U8。多码率适配流。
if strings.HasPrefix(lines[i], "#EXT-X-STREAM-INF") {
// 那么下一行应该是一个播放地址
// 对于我的需求,我只要第一个地址的文件就行,因此我这里直接返回了
if i+1 < l {
return TypeMenu, lines[i+1]
}
}
// 我只考虑这一种形式,因此其他类别不再继续写了
// key、ts的获取都可以在这里完成
}
return TypePlayList, "" // 默认代码原行为
}

func getFromFile() string {
data, _ := ioutil.ReadFile("./ts.txt")
return string(data)
Expand All @@ -229,7 +262,7 @@ func downloadTsFile(ts TsInfo, download_dir, key string, retries int) {
downloadTsFile(ts, download_dir, key, retries-1)
return
} else {
//logger.Printf("[warn] File :%s, Retry %d \n", ts.Url, retries-1)
//logger.Printf("[warn] File :%s", ts.Url)
return
}
}
Expand Down Expand Up @@ -294,7 +327,7 @@ func downloader(tsList []TsInfo, maxGoroutines int, downloadDir string, key stri
}

func checkTsDownDir(dir string) bool {
if isExist, _ := pathExists(path.Join(dir, fmt.Sprintf(TS_NAME_TEMPLATE, 0))); !isExist {
if isExist, _ := pathExists(filepath.Join(dir, fmt.Sprintf(TS_NAME_TEMPLATE, 0))); !isExist {
return true
}
return false
Expand Down