| @@ -16,17 +16,34 @@ import ( | |||
| ) | |||
| const baseScheme = "http" | |||
| const MASTER = "master" | |||
| const PLAYLIST = "playlist" | |||
| type m3u8Json struct { | |||
| master *m3u8.MasterPlaylist | |||
| playlist []*m3u8.MediaPlaylist | |||
| URL string | |||
| BaseUrl string | |||
| Type string | |||
| Manifest interface{} | |||
| } | |||
| func nilIndex(input []*m3u8.MediaSegment) int { | |||
| output := -1 | |||
| for i := range input { | |||
| if input[i] == nil { | |||
| return i | |||
| } | |||
| } | |||
| return output | |||
| } | |||
| func main() { | |||
| isUrl := false | |||
| var data *bufio.Reader | |||
| var baseUrl string | |||
| var outputJson m3u8Json | |||
| recursive := flag.Bool("r", false, "Recursive download master and playlists") | |||
| abs := flag.Bool("a", false, "make URI absolute") | |||
| baseUrl := flag.String("b", "", "Base URL") | |||
| flag.Parse() | |||
| inputs := flag.Args() | |||
| if len(inputs) != 1 { | |||
| @@ -44,19 +61,28 @@ func main() { | |||
| } | |||
| if !isUrl { | |||
| f, err := os.Open("playlist.m3u8") | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| var f *os.File | |||
| var err error | |||
| if input == "-" { | |||
| data = bufio.NewReader(os.Stdin) | |||
| } else { | |||
| f, err = os.Open(input) | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| } | |||
| data = bufio.NewReader(f) | |||
| } | |||
| fmt.Println("ok") | |||
| data = bufio.NewReader(f) | |||
| fmt.Println("ok2") | |||
| } else { | |||
| baseUrl = fmt.Sprintf("%v://%v%v", u.Scheme, u.Host, path.Dir(u.EscapedPath())) | |||
| if *baseUrl == "" { | |||
| *baseUrl = fmt.Sprintf("%v://%v%v", u.Scheme, u.Host, path.Dir(u.EscapedPath())) | |||
| } | |||
| r, err := http.Get(u.String()) | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| } | |||
| outputJson.URL = u.String() | |||
| outputJson.BaseUrl = *baseUrl | |||
| data = bufio.NewReader(r.Body) | |||
| } | |||
| @@ -66,26 +92,63 @@ func main() { | |||
| } | |||
| switch listType { | |||
| case m3u8.MEDIA: | |||
| mediapl := p.(*m3u8.MediaPlaylist) | |||
| fmt.Printf("%+v\n", mediapl) | |||
| output, err := json.MarshalIndent(mediapl, "", " ") | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| outputJson.Type = PLAYLIST | |||
| playlist := p.(*m3u8.MediaPlaylist) | |||
| playlist.Segments = playlist.Segments[:nilIndex(playlist.Segments)] | |||
| for _, entry := range playlist.Segments { | |||
| u, err := url.Parse(entry.URI) | |||
| if err != nil { | |||
| log.Fatal("not a valid URL") | |||
| } | |||
| if *abs && !u.IsAbs() && *baseUrl != "" { | |||
| entry.URI = *baseUrl + "/" + entry.URI | |||
| } | |||
| } | |||
| fmt.Printf("%s", output) | |||
| outputJson.Manifest = playlist | |||
| case m3u8.MASTER: | |||
| outputJson.master = p.(*m3u8.MasterPlaylist) | |||
| fmt.Printf("%+v\n", outputJson.master) | |||
| for _, entry := range outputJson.master.Variants { | |||
| fmt.Println(entry.Resolution) | |||
| if isUrl { | |||
| fmt.Printf("%v/%v\n", baseUrl, entry.URI) | |||
| outputJson.Type = MASTER | |||
| master := p.(*m3u8.MasterPlaylist) | |||
| for _, entry := range master.Variants { | |||
| var chunckUrl string | |||
| u, err := url.Parse(entry.URI) | |||
| if err != nil { | |||
| log.Fatal("not a valid URL") | |||
| } | |||
| if !u.IsAbs() { | |||
| chunckUrl = *baseUrl + "/" + entry.URI | |||
| if *abs && *baseUrl != "" { | |||
| entry.URI = chunckUrl | |||
| } | |||
| } else { | |||
| chunckUrl = entry.URI | |||
| } | |||
| if isUrl && *recursive { | |||
| clist, err := http.Get(chunckUrl) | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| } | |||
| cdata := bufio.NewReader(clist.Body) | |||
| p, _, _ := m3u8.DecodeFrom(cdata, true) | |||
| playlist := p.(*m3u8.MediaPlaylist) | |||
| playlist.Segments = playlist.Segments[:nilIndex(playlist.Segments)] | |||
| for _, entry := range playlist.Segments { | |||
| u, err := url.Parse(entry.URI) | |||
| if err != nil { | |||
| log.Fatal("not a valid URL") | |||
| } | |||
| if *abs && !u.IsAbs() { | |||
| entry.URI = *baseUrl + "/" + entry.URI | |||
| } | |||
| } | |||
| entry.Chunklist = playlist | |||
| } | |||
| } | |||
| output, err := json.MarshalIndent(outputJson.master, "", " ") | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| } | |||
| fmt.Printf("%s", output) | |||
| outputJson.Manifest = master | |||
| } | |||
| output, err := json.MarshalIndent(outputJson, "", " ") | |||
| if err != nil { | |||
| log.Fatal(err) | |||
| } | |||
| fmt.Printf("%s", output) | |||
| } | |||