diff --git a/app/app.go b/app/app.go index fa1fd18..3f99998 100644 --- a/app/app.go +++ b/app/app.go @@ -20,8 +20,8 @@ import ( "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/renstrom/shortuuid" - "github.com/rylio/ytdl" log "github.com/sirupsen/logrus" + "github.com/wybiral/tube/importers" "github.com/wybiral/tube/media" "github.com/wybiral/tube/utils" ) @@ -339,7 +339,15 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) { sort.Strings(keys) collection := keys[0] - vid, err := ytdl.GetVideoInfo(url) + videoImporter, err := importers.NewImporter(url) + if err != nil { + err := fmt.Errorf("error creating video importer for %s: %w", url, err) + log.Error(err) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + videoInfo, err := videoImporter.GetVideoInfo(url) if err != nil { err := fmt.Errorf("error retriving video info for %s: %w", url, err) log.Error(err) @@ -359,8 +367,7 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) { } defer os.Remove(uf.Name()) - err = vid.Download(vid.Formats[0], uf) - if err != nil { + if err := utils.Download(videoInfo.VideoURL, uf.Name()); err != nil { err := fmt.Errorf("error downloading video %s: %w", url, err) log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) @@ -385,29 +392,12 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) { thumbFn1 := fmt.Sprintf("%s.jpg", strings.TrimSuffix(tf.Name(), filepath.Ext(tf.Name()))) thumbFn2 := fmt.Sprintf("%s.jpg", strings.TrimSuffix(vf, filepath.Ext(vf))) - thumbURL := vid.GetThumbnailURL(ytdl.ThumbnailQualityHigh) - res, err := http.Get(thumbURL.String()) - if err != nil { + if err := utils.Download(videoInfo.ThumbnailURL, thumbFn1); err != nil { err := fmt.Errorf("error downloading thumbnail: %w", err) log.Error(err) http.Error(w, err.Error(), http.StatusInternalServerError) return } - thumbData, err := ioutil.ReadAll(res.Body) - res.Body.Close() - if err != nil { - err := fmt.Errorf("error reading thumbnail data: %w", err) - log.Error(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - if err := ioutil.WriteFile(thumbFn1, thumbData, 0644); err != nil { - err := fmt.Errorf("error writing thumbnail data: %w", err) - log.Error(err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } // TODO: Use a proper Job Queue and make this async if err := utils.RunCmd( @@ -419,8 +409,8 @@ func (a *App) importHandler(w http.ResponseWriter, r *http.Request) { "-acodec", "aac", "-strict", "-2", "-loglevel", "quiet", - "-metadata", fmt.Sprintf("title=%s", vid.Title), - "-metadata", fmt.Sprintf("comment=%s", vid.Description), + "-metadata", fmt.Sprintf("title=%s", videoInfo.Title), + "-metadata", fmt.Sprintf("comment=%s", videoInfo.Description), tf.Name(), ); err != nil { err := fmt.Errorf("error transcoding video: %w", err) diff --git a/go.mod b/go.mod index 09def96..fcf5215 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,8 @@ require ( github.com/mutschler/mt v0.0.0-20200120124658-d48aed259ff6 // indirect github.com/prologic/bitcask v0.3.5 github.com/renstrom/shortuuid v3.0.0+incompatible - github.com/rylio/ytdl v0.6.2 + github.com/rs/zerolog v1.18.0 // indirect + github.com/rylio/ytdl v0.6.3-0.20200220142242-f3a87da86fb8 github.com/sirupsen/logrus v1.4.2 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.6.2 // indirect diff --git a/go.sum b/go.sum index 38a844c..b77c9a2 100644 --- a/go.sum +++ b/go.sum @@ -153,10 +153,14 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.16.0 h1:AaELmZdcJHT8m6oZ5py4213cdFK8XGXkB3dFdAQ+P7Q= github.com/rs/zerolog v1.16.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= +github.com/rs/zerolog v1.18.0 h1:CbAm3kP2Tptby1i9sYy2MGRg0uxIN9cyDb59Ys7W8z8= +github.com/rs/zerolog v1.18.0/go.mod h1:9nvC1axdVrAHcu/s9taAVfBuIdTZLVQmKQyvrUjF5+I= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/rylio/ytdl v0.6.2 h1:ZYzaoUqAniH/yb7yscdWlVoecVRcvpFDgS15NyDTZQA= github.com/rylio/ytdl v0.6.2/go.mod h1:F0WX8szfQ00mhmfla+0xVJp483SBV4VO/ByUaNioNSM= +github.com/rylio/ytdl v0.6.3-0.20200220142242-f3a87da86fb8 h1:Kxmg/DHYGAALeJ4npCxZWTE+IxORgWkJGkXbUiduArU= +github.com/rylio/ytdl v0.6.3-0.20200220142242-f3a87da86fb8/go.mod h1:F0WX8szfQ00mhmfla+0xVJp483SBV4VO/ByUaNioNSM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= diff --git a/importers/importer.go b/importers/importer.go new file mode 100644 index 0000000..c74d621 --- /dev/null +++ b/importers/importer.go @@ -0,0 +1,33 @@ +package importers + +import ( + "errors" + "strings" +) + +var ( + ErrUnsupportedVideoURL = errors.New("error: unsupported video url") +) + +type VideoInfo struct { + ID string `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + + VideoURL string `json:"video_url"` + ThumbnailURL string `json:"thumbnail_url"` +} + +type Importer interface { + GetVideoInfo(url string) (VideoInfo, error) +} + +func NewImporter(url string) (Importer, error) { + if strings.Contains(url, "youtube.com") || strings.HasPrefix(url, "youtube:") { + return &YoutubeImporter{}, nil + } else if strings.Contains(url, "youtube.com") || strings.HasPrefix(url, "youtube:") { + return &VimeoImporter{}, nil + } else { + return nil, ErrUnsupportedVideoURL + } +} diff --git a/importers/vimeo_importer.go b/importers/vimeo_importer.go new file mode 100644 index 0000000..5d5ed02 --- /dev/null +++ b/importers/vimeo_importer.go @@ -0,0 +1,10 @@ +package importers + +import "fmt" + +type VimeoImporter struct{} + +func (i *VimeoImporter) GetVideoInfo(url string) (videoInfo VideoInfo, err error) { + err = fmt.Errorf("Not Implemented") + return +} diff --git a/importers/youtube_importer.go b/importers/youtube_importer.go new file mode 100644 index 0000000..5702b05 --- /dev/null +++ b/importers/youtube_importer.go @@ -0,0 +1,37 @@ +package importers + +import ( + "fmt" + "strings" + + "github.com/rylio/ytdl" +) + +type YoutubeImporter struct{} + +func (i *YoutubeImporter) GetVideoInfo(url string) (videoInfo VideoInfo, err error) { + if strings.HasPrefix(url, "youtube:") { + url = strings.TrimPrefix(url, "youtube:") + } + + info, err := ytdl.GetVideoInfo(url) + if err != nil { + err = fmt.Errorf("error retriving youtube video info: %w", err) + return + } + + videoURL, err := ytdl.DefaultClient.GetDownloadURL(info, info.Formats[0]) + if err != nil { + err = fmt.Errorf("error retriving youtube video url: %w", err) + return + } + videoInfo.VideoURL = videoURL.String() + + videoInfo.ThumbnailURL = info.GetThumbnailURL(ytdl.ThumbnailQualityHigh).String() + + videoInfo.ID = info.ID + videoInfo.Title = info.Title + videoInfo.Description = info.Description + + return +} diff --git a/utils/utils.go b/utils/utils.go index b7ab28f..5293b0a 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -3,11 +3,32 @@ package utils import ( "context" "fmt" + "io/ioutil" + "net/http" "os" "os/exec" "time" ) +func Download(url, filename string) error { + res, err := http.Get(url) + if err != nil { + return err + } + defer res.Body.Close() + + data, err := ioutil.ReadAll(res.Body) + if err != nil { + return err + } + + if err := ioutil.WriteFile(filename, data, 0644); err != nil { + return err + } + + return nil +} + // FileExists ... func FileExists(name string) bool { if _, err := os.Stat(name); err != nil {