Skip to content
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
38 changes: 20 additions & 18 deletions dl/dowloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import (
"sync"
"sync/atomic"

"github.com/oopsguy/m3u8/parse"
"github.com/oopsguy/m3u8/tool"
"github.com/kolychen/m3u8/parse"
"github.com/kolychen/m3u8/tool"
)

const (
Expand All @@ -23,19 +23,20 @@ const (
)

type Downloader struct {
lock sync.Mutex
queue []int
folder string
tsFolder string
finish int32
segLen int
lock sync.Mutex
queue []int
folder string
outFileName string
tsFolder string
finish int32
segLen int

result *parse.Result
}

// NewTask returns a Task instance
func NewTask(output string, url string) (*Downloader, error) {
result, err := parse.FromURL(url)
func NewTask(output, fileName string, url string) (*Downloader, error) {
result, err := parse.FromURL(url, true)
if err != nil {
return nil, err
}
Expand All @@ -53,14 +54,15 @@ func NewTask(output string, url string) (*Downloader, error) {
if err := os.MkdirAll(folder, os.ModePerm); err != nil {
return nil, fmt.Errorf("create storage folder failed: %s", err.Error())
}
tsFolder := filepath.Join(folder, tsFolderName)
if err := os.MkdirAll(tsFolder, os.ModePerm); err != nil {
return nil, fmt.Errorf("create ts folder '[%s]' failed: %s", tsFolder, err.Error())
tsFolder, err := ioutil.TempDir(folder, fileName) //解决并发下载的情况下,临时目录冲突的问题
if err != nil {
return nil, fmt.Errorf("create ts folder '[%s]' failed: %s", fileName, err.Error())
}
d := &Downloader{
folder: folder,
tsFolder: tsFolder,
result: result,
folder: folder,
tsFolder: tsFolder,
result: result,
outFileName: fileName,
}
d.segLen = len(result.M3u8.Segments)
d.queue = genSlice(d.segLen)
Expand Down Expand Up @@ -187,8 +189,8 @@ func (d *Downloader) back(segIndex int) error {
return nil
}

// In fact, the number of downloaded segments should be equal to number of m3u8 segments
func (d *Downloader) merge() error {
// In fact, the number of downloaded segments should be equal to number of m3u8 segments
missingCount := 0
for idx := 0; idx < d.segLen; idx++ {
tsFilename := tsFilename(idx)
Expand All @@ -202,7 +204,7 @@ func (d *Downloader) merge() error {
}

// Create a TS file for merging, all segment files will be written to this file.
mFilePath := filepath.Join(d.folder, mergeTSFilename)
mFilePath := filepath.Join(d.folder, d.outFileName+".ts")
mFile, err := os.Create(mFilePath)
if err != nil {
return fmt.Errorf("create main TS file failed:%s", err.Error())
Expand Down
12 changes: 12 additions & 0 deletions parse/m3u8.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ type MasterPlaylist struct {
Resolution string
Codecs string
ProgramID uint32
Duration float64
Width int
Height int
}

// #EXT-X-KEY:METHOD=AES-128,URI="key.key"
Expand Down Expand Up @@ -237,6 +240,9 @@ func parseMasterPlaylist(line string) (*MasterPlaylist, error) {
mp.BandWidth = uint32(v)
case k == "RESOLUTION":
mp.Resolution = v
xPos := strings.Index(v, "x")
mp.Width, _ = strconv.Atoi(v[:xPos])
mp.Height, _ = strconv.Atoi(v[xPos+1:])
case k == "PROGRAM-ID":
v, err := strconv.ParseUint(v, 10, 32)
if err != nil {
Expand All @@ -245,6 +251,12 @@ func parseMasterPlaylist(line string) (*MasterPlaylist, error) {
mp.ProgramID = uint32(v)
case k == "CODECS":
mp.Codecs = v
case k == "TAP-DURATION":
v, err := strconv.ParseFloat(v, 64)
if err != nil {
return nil, err
}
mp.Duration = v
}
}
return mp, nil
Expand Down
8 changes: 4 additions & 4 deletions parse/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ type Result struct {
Keys map[int]string
}

func FromURL(link string) (*Result, error) {
func FromURL(link string, isGetSubPlayerlist bool) (*Result, error) {
u, err := url.Parse(link)
if err != nil {
return nil, err
Expand All @@ -31,11 +31,11 @@ func FromURL(link string) (*Result, error) {
if err != nil {
return nil, err
}
if len(m3u8.MasterPlaylist) != 0 {
if len(m3u8.MasterPlaylist) != 0 && isGetSubPlayerlist {
sf := m3u8.MasterPlaylist[0]
return FromURL(tool.ResolveURL(u, sf.URI))
return FromURL(tool.ResolveURL(u, sf.URI), isGetSubPlayerlist)
}
if len(m3u8.Segments) == 0 {
if len(m3u8.Segments) == 0 && isGetSubPlayerlist {
return nil, errors.New("can not found any TS file description")
}
result := &Result{
Expand Down