download.go (1886B)
1 package giffer 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 10 "github.com/OneOfOne/xxhash" 11 "github.com/kkdai/youtube/v2" 12 "github.com/kkdai/youtube/v2/downloader" 13 "github.com/pkg/errors" 14 ) 15 16 // Downloader is responsible for downloading videos. 17 type Downloader struct { 18 Dir string 19 FFmpeg string 20 Debug bool 21 Out io.Writer 22 } 23 24 // Download the video from URL into Dir and return the full path to the 25 // downloaded file. 26 func (dl Downloader) Download( 27 URL string, 28 start, end float64, 29 ) (string, error) { 30 dl.logf("ffmpeg: %q\n", dl.FFmpeg) 31 h, err := hash(fmt.Sprintf("%s_%f_%f", URL, start, end)) 32 if err != nil { 33 return "", errors.Wrap(err, "creating hash") 34 } 35 dir := filepath.Join(dl.Dir, h) 36 if err := os.MkdirAll(dir, 0755); err != nil && !os.IsExist(err) { 37 return "", errors.Wrap(err, "preparing directories") 38 } 39 tmp, err := dl.download(URL, start, end) 40 if err != nil { 41 return "", err 42 } 43 real := filepath.Join(dir, h+filepath.Ext(tmp)) 44 if err := os.Rename(tmp, real); err != nil { 45 return "", errors.Wrap(err, "renaming temporary file") 46 } 47 return real, nil 48 } 49 50 func (dl Downloader) logf(f string, v ...interface{}) { 51 if !dl.Debug || dl.Out == nil { 52 return 53 } 54 fmt.Fprintf(dl.Out, f, v...) 55 } 56 57 // download a video from the specified url. 58 func (dl Downloader) download( 59 videoURL string, 60 start, end float64, 61 ) (string, error) { 62 d := downloader.Downloader{ 63 Client: youtube.Client{}, 64 } 65 v, err := d.GetVideo(videoURL) 66 if err != nil { 67 return "", fmt.Errorf("getting video: %w", err) 68 } 69 outf := filepath.Join(os.TempDir(), downloader.SanitizeFilename(v.Title)) 70 return outf, d.Download(context.TODO(), v, &v.Formats[0], outf) 71 } 72 73 func hash(input string) (string, error) { 74 h := xxhash.New64() 75 if _, err := h.WriteString(input); err != nil { 76 return "", errors.Wrap(err, "writing to hash object") 77 } 78 return fmt.Sprintf("%d", h.Sum64()), nil 79 }