package youtube import ( "fmt" "sort" "strings" youtubev2 "github.com/kkdai/youtube/v2" ) func FormatDebugString(format *youtubev2.Format, includeURL bool) string { var url string 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, ) } // 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. 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 { formats = append(formats, format) } } sort.SliceStable(formats, func(i, j int) bool { isOpusI := strings.Contains(formats[i].MimeType, "opus") isOpusJ := strings.Contains(formats[j].MimeType, "opus") if isOpusI && isOpusJ { 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 isStereoI } return isOpusI }) return formats } // SortVideo returns the provided formats ordered in descending preferred // order. The ideal candidate is video in an mp4 container with a medium // 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.AudioChannels > 0 { formats = append(formats, format) } } sort.SliceStable(formats, func(i, j int) bool { isMP4I := strings.Contains(formats[i].MimeType, "mp4") isMP4J := strings.Contains(formats[j].MimeType, "mp4") if isMP4I && isMP4J { return compareQualityLabel(formats[i].QualityLabel, formats[j].QualityLabel) } return strings.Contains(formats[i].MimeType, "mp4") }) return formats } func compareQualityLabel(a, b string) bool { return (a == "360p" || a == "480p") && (b != "360p" && b != "480p") }