Marshal json response directly in Video instance

This commit is contained in:
Andrea Fazzi 2021-10-25 09:44:12 +02:00
parent 2e1c34f0c4
commit b282732c29
4 changed files with 5 additions and 218 deletions

View file

@ -1,144 +0,0 @@
package youtube_dl
import (
"context"
"encoding/json"
"fmt"
"log"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
"git.andreafazzi.eu/andrea/youtube-dl-service/task"
"git.andreafazzi.eu/andrea/youtube-dl-service/youtube"
lib "github.com/kkdai/youtube/v2"
)
type YoutubeDlDownloader struct {
Url string
CommandName string
}
func NewYoutubeDlDownloader(url string, commandName string) *YoutubeDlDownloader {
return &YoutubeDlDownloader{url, commandName}
}
func (d *YoutubeDlDownloader) GetVideo() (*youtube.Video, error) {
videoJson, err := d.getVideoJson(d.Url)
thumbnails := make([]youtube.Thumbnail, 0)
thumbnailsJson := videoJson["thumbnails"].([]interface{})
for _, i := range thumbnailsJson {
t := i.(map[string]interface{})
var err error
wString, wOk := t["width"].(string)
hString, hOk := t["height"].(string)
w := 0
h := 0
if wString != "" && hString != "" {
w, err = strconv.Atoi(wString)
if err != nil {
return nil, err
}
h, err = strconv.Atoi(hString)
if err != nil {
return nil, err
}
}
thumbnails = append(thumbnails, youtube.Thumbnail{
URL: t["url"].(string),
Width: uint(w),
Height: uint(h),
})
}
return &youtube.Video{
ID: videoJson["id"].(string),
Title: videoJson["title"].(string),
Duration: time.Duration(videoJson["duration"].(int64) * time.Hour.Nanoseconds()),
Thumbnails: thumbnails,
}, err
}
func (d *YoutubeDlDownloader) StartDownload(video *youtube.Video, tasks task.Tasks) {
tasks[video.ID] = &task.Task{
Status: task.StatusDownloading,
}
log.Printf("Download of video ID %s STARTED.", video.ID)
cmd := exec.CommandContext(context.Background(), d.CommandName, "--newline", d.Url)
stdout, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
if err = cmd.Start(); err != nil {
panic(err)
}
for {
tmp := make([]byte, 1024)
_, err := stdout.Read(tmp)
fmt.Print(string(tmp))
if err != nil {
break
}
}
log.Printf("Download of video ID %s COMPLETED.", video.ID)
tasks[video.ID] = &task.Task{
Status: task.StatusCompleted,
DownloadPath: filepath.Join("data", video.ID+".mp4"),
}
}
func (d *YoutubeDlDownloader) ExtractVideoID() (string, error) {
return lib.ExtractVideoID(d.Url)
}
func (d *YoutubeDlDownloader) getVideoJson(url string) (map[string]interface{}, error) {
cmd := exec.CommandContext(context.Background(), d.CommandName, "-j", url)
output, err := cmd.Output()
if err != nil {
return nil, err
}
result := make(map[string]interface{}, 0)
err = json.Unmarshal(output, &result)
if err != nil {
return nil, err
}
return result, nil
}
func (d *YoutubeDlDownloader) getThumbnails() ([]youtube.Thumbnail, error) {
thumbnails := make([]youtube.Thumbnail, 0)
cmd := exec.CommandContext(context.Background(), d.CommandName, "--list-thumbnails", d.Url)
output, err := cmd.Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(output), "\n")[3:]
for _, line := range lines {
splits := strings.Split(line, " ")
if len(splits) == 4 {
wString := strings.TrimSpace(splits[1])
hString := strings.TrimSpace(splits[2])
w, err := strconv.Atoi(wString)
if err != nil {
return nil, err
}
h, err := strconv.Atoi(hString)
if err != nil {
return nil, err
}
thumbnails = append(thumbnails, youtube.Thumbnail{
URL: strings.TrimSpace(splits[3]),
Width: uint(w),
Height: uint(h),
})
}
}
return thumbnails, nil
}

View file

@ -1 +0,0 @@
andrea@lv5.88143:1634702979

View file

@ -7,9 +7,6 @@ import (
"log" "log"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv"
"strings"
"time"
"git.andreafazzi.eu/andrea/youtube-dl-service/task" "git.andreafazzi.eu/andrea/youtube-dl-service/task"
"git.andreafazzi.eu/andrea/youtube-dl-service/youtube" "git.andreafazzi.eu/andrea/youtube-dl-service/youtube"
@ -26,41 +23,7 @@ func NewYoutubeDlDownloader(url string, commandName string) *YoutubeDlDownloader
} }
func (d *YoutubeDlDownloader) GetVideo() (*youtube.Video, error) { func (d *YoutubeDlDownloader) GetVideo() (*youtube.Video, error) {
videoJson, err := d.getVideoJson(d.Url) return d.getVideoJson(d.Url)
thumbnails := make([]youtube.Thumbnail, 0)
thumbnailsJson := videoJson["thumbnails"].([]interface{})
for _, i := range thumbnailsJson {
t := i.(map[string]interface{})
var err error
wString := t["width"].(string)
hString := t["height"].(string)
w := 0
h := 0
if wString != "" && hString != "" {
w, err = strconv.Atoi(wString)
if err != nil {
return nil, err
}
h, err = strconv.Atoi(hString)
if err != nil {
return nil, err
}
}
thumbnails = append(thumbnails, youtube.Thumbnail{
URL: t["url"].(string),
Width: uint(w),
Height: uint(h),
})
}
return &youtube.Video{
ID: videoJson["id"].(string),
Title: videoJson["title"].(string),
Duration: time.Duration(videoJson["duration"].(int64) * time.Hour.Nanoseconds()),
Thumbnails: thumbnails,
}, err
} }
func (d *YoutubeDlDownloader) StartDownload(video *youtube.Video, tasks task.Tasks) { func (d *YoutubeDlDownloader) StartDownload(video *youtube.Video, tasks task.Tasks) {
@ -97,48 +60,16 @@ func (d *YoutubeDlDownloader) ExtractVideoID() (string, error) {
return lib.ExtractVideoID(d.Url) return lib.ExtractVideoID(d.Url)
} }
func (d *YoutubeDlDownloader) getVideoJson(url string) (map[string]interface{}, error) { func (d *YoutubeDlDownloader) getVideoJson(url string) (*youtube.Video, error) {
cmd := exec.CommandContext(context.Background(), d.CommandName, "-j", url) cmd := exec.CommandContext(context.Background(), d.CommandName, "-j", url)
output, err := cmd.Output() output, err := cmd.Output()
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := make(map[string]interface{}, 0) result := new(youtube.Video)
err = json.Unmarshal(output, &result) err = json.Unmarshal(output, &result)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return result, nil return result, nil
} }
func (d *YoutubeDlDownloader) getThumbnails() ([]youtube.Thumbnail, error) {
thumbnails := make([]youtube.Thumbnail, 0)
cmd := exec.CommandContext(context.Background(), d.CommandName, "--list-thumbnails", d.Url)
output, err := cmd.Output()
if err != nil {
return nil, err
}
lines := strings.Split(string(output), "\n")[3:]
for _, line := range lines {
splits := strings.Split(line, " ")
if len(splits) == 4 {
wString := strings.TrimSpace(splits[1])
hString := strings.TrimSpace(splits[2])
w, err := strconv.Atoi(wString)
if err != nil {
return nil, err
}
h, err := strconv.Atoi(hString)
if err != nil {
return nil, err
}
thumbnails = append(thumbnails, youtube.Thumbnail{
URL: strings.TrimSpace(splits[3]),
Width: uint(w),
Height: uint(h),
})
}
}
return thumbnails, nil
}

View file

@ -21,9 +21,10 @@ func TestRunner(t *testing.T) {
// End of setup // End of setup
// Tests start here // Tests start here
func (t *testSuite) TestGetThumbnails() { func (t *testSuite) TestGetVideoInfo() {
d := NewYoutubeDlDownloader("https://www.youtube.com/watch?v=mWZ6b_I-Djg", "yt-dlp") d := NewYoutubeDlDownloader("https://www.youtube.com/watch?v=mWZ6b_I-Djg", "yt-dlp")
video, err := d.GetVideo() video, err := d.GetVideo()
t.Nil(err) t.Nil(err)
t.True(video.Title != "")
t.True(video.Thumbnails[0].URL != "") t.True(video.Thumbnails[0].URL != "")
} }