Reduce audio and video bitrates

This commit is contained in:
Rob Watson 2021-10-19 17:37:54 +02:00
parent 93736abc24
commit 7d91340582
2 changed files with 12 additions and 17 deletions

View File

@ -33,10 +33,9 @@ func FormatDebugString(format *youtubev2.Format, includeURL bool) string {
}
// SortAudio returns the provided formats ordered in descending preferred
// order. The ideal candidate is 44.1kHz stereo audio in a webm container, with
// the highest available bitrate.
// order. The ideal candidate is opus-encoded stereo audio in a webm container,
// with the lowest available bitrate.
func SortAudio(inFormats youtubev2.FormatList) youtubev2.FormatList {
// TODO: sort in-place.
var formats youtubev2.FormatList
for _, format := range inFormats {
if format.FPS == 0 && format.AudioChannels > 0 {
@ -50,12 +49,7 @@ func SortAudio(inFormats youtubev2.FormatList) youtubev2.FormatList {
isStereoI := formats[i].AudioChannels == 2
isStereoJ := formats[j].AudioChannels == 2
if isStereoI && isStereoJ {
is48kI := formats[i].AudioSampleRate == "48000"
is48kJ := formats[j].AudioSampleRate == "48000"
if is48kI && is48kJ {
return formats[i].Bitrate > formats[j].Bitrate
}
return is48kI
return formats[i].ContentLength < formats[j].ContentLength
}
return isStereoI
}
@ -69,10 +63,9 @@ func SortAudio(inFormats youtubev2.FormatList) youtubev2.FormatList {
// bitrate, with audio channels (needed to allow synced playback on the
// website).
func SortVideo(inFormats youtubev2.FormatList) youtubev2.FormatList {
// TODO: sort in-place.
var formats youtubev2.FormatList
for _, format := range inFormats {
if format.FPS > 0 && format.ContentLength > 0 && format.AudioChannels > 0 {
if format.FPS > 0 && format.ContentLength > 0 {
formats = append(formats, format)
}
}
@ -80,7 +73,7 @@ func SortVideo(inFormats youtubev2.FormatList) youtubev2.FormatList {
isMP4I := strings.Contains(formats[i].MimeType, "mp4")
isMP4J := strings.Contains(formats[j].MimeType, "mp4")
if isMP4I && isMP4J {
return formats[i].Bitrate < formats[j].Bitrate
return formats[i].ContentLength < formats[j].ContentLength
}
return isMP4I
})

View File

@ -88,7 +88,7 @@ func (d *Downloader) Download(ctx context.Context, videoID string) (*media.Media
}()
go func() {
defer close(videoResultChan)
video, videoErr := d.downloadVideo(ctx, video, mediaSet.VideoPath(), mediaSet.ThumbnailPath())
video, videoErr := d.downloadVideo(ctx, video, mediaSet.VideoPath())
result := videoResult{video, videoErr}
videoResultChan <- result
wg.Done()
@ -138,6 +138,7 @@ func (d *Downloader) downloadAudio(ctx context.Context, video *youtubev2.Video,
if err != nil {
return nil, fmt.Errorf("error fetching audio stream: %v", err)
}
reader := progressReader{Reader: stream, label: "audio", exp: int(format.ContentLength)}
rawAudioFile, err := os.Create(rawOutPath)
if err != nil {
@ -148,7 +149,7 @@ func (d *Downloader) downloadAudio(ctx context.Context, video *youtubev2.Video,
if err != nil {
return nil, fmt.Errorf("error creating encoded audio file: %v", err)
}
streamReader := io.TeeReader(stream, encodedAudioFile)
streamReader := io.TeeReader(&reader, encodedAudioFile)
var errOut bytes.Buffer
cmd := exec.CommandContext(ctx, "ffmpeg", "-i", "-", "-f", rawAudioFormat, "-ar", strconv.Itoa(rawAudioSampleRate), "-acodec", rawAudioCodec, "-")
@ -191,6 +192,7 @@ func (d *Downloader) downloadAudio(ctx context.Context, video *youtubev2.Video,
type progressReader struct {
io.Reader
label string
total, exp int
}
@ -198,12 +200,12 @@ func (pw *progressReader) Read(p []byte) (int, error) {
n, err := pw.Reader.Read(p)
pw.total += n
log.Printf("[ProgressReader] Read %d of %d (%.02f%%) bytes from the provided reader", pw.total, pw.exp, (float32(pw.total)/float32(pw.exp))*100.0)
log.Printf("[ProgressReader] [%s] Read %d of %d (%.02f%%) bytes from the provided reader", pw.label, pw.total, pw.exp, (float32(pw.total)/float32(pw.exp))*100.0)
return n, err
}
func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video, outPath string, thumbnailOutPath string) (*media.Video, error) {
func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video, outPath string) (*media.Video, error) {
if len(video.Formats) == 0 {
return nil, errors.New("error selecting audio format: no format available")
}
@ -219,7 +221,7 @@ func (d *Downloader) downloadVideo(ctx context.Context, video *youtubev2.Video,
if err != nil {
return nil, fmt.Errorf("error fetching video stream: %v", err)
}
reader := progressReader{Reader: stream, exp: int(format.ContentLength)}
reader := progressReader{Reader: stream, label: "video", exp: int(format.ContentLength)}
videoFile, err := os.Create(outPath)
if err != nil {