clipper/backend/cmd/ytdebug/main.go

121 lines
2.6 KiB
Go

package main
import (
"context"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"sync"
"time"
"git.netflux.io/rob/clipper/media"
youtubev2 "github.com/kkdai/youtube/v2"
)
func main() {
var (
verbose bool
printMode bool
downloadMode bool
audioOnly bool
videoOnly bool
)
flag.BoolVar(&verbose, "v", false, "verbose output")
flag.BoolVar(&printMode, "print", true, "print format info")
flag.BoolVar(&downloadMode, "download", false, "download all media to ./debug")
flag.BoolVar(&audioOnly, "audio", false, "only print audio formats")
flag.BoolVar(&videoOnly, "video", false, "only print video formats")
flag.Parse()
videoID := flag.Arg(0)
ctx := context.Background()
var youtubeClient youtubev2.Client
video, err := youtubeClient.GetVideoContext(ctx, videoID)
if err != nil {
log.Fatal(err)
}
formats := video.Formats
if downloadMode {
downloadAll(formats)
return
}
switch {
case audioOnly:
formats = media.FilterYoutubeAudio(formats)
case videoOnly:
formats = media.FilterYoutubeVideo(formats)
}
fmt.Println("In descending order of preference:")
for n, f := range formats {
fmt.Printf("%d: %s\n", n+1, formatDebugString(&f, verbose))
}
}
func downloadAll(formats youtubev2.FormatList) {
var wg sync.WaitGroup
for i := range formats {
format := formats[i]
wg.Add(1)
go func() {
defer wg.Done()
start := time.Now()
outpath := fmt.Sprintf("./debug/%s.%s-itag-%d", strings.ReplaceAll(format.MimeType, "/", "'"), format.Quality, format.ItagNo)
output, err := os.Create(outpath)
if err != nil {
log.Fatalf("error opening output file: %v", err)
}
resp, err := http.Get(format.URL)
if err != nil {
log.Fatalf("error fetching media: %v", err)
}
defer resp.Body.Close()
n, err := io.Copy(output, resp.Body)
if err != nil {
log.Fatalf("error reading media: %v", err)
}
dur := time.Since(start)
log.Printf("downloaded itag %d, %d bytes in %v secs", format.ItagNo, n, dur.Seconds())
}()
}
wg.Wait()
}
func formatDebugString(format *youtubev2.Format, includeURL bool) string {
url := "hidden"
if includeURL {
url = format.URL
}
return fmt.Sprintf(
"iTag = %d, mime_type = %s, quality = %s, quality_label = %s, bitrate = %d, fps = %d, width = %d, height = %d, content_length = %d, duration = %v, audio_channels = %d, audio_sample_rate = %s, audio_quality = %s, url = %s",
format.ItagNo,
format.MimeType,
format.Quality,
format.QualityLabel,
format.Bitrate,
format.FPS,
format.Width,
format.Height,
format.ContentLength,
format.ApproxDurationMs,
format.AudioChannels,
format.AudioSampleRate,
format.AudioQuality,
url,
)
}