Reduce audio and video bitrates
This commit is contained in:
parent
93736abc24
commit
7d91340582
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue