119 lines
2.3 KiB
Go
Raw Normal View History

2020-02-08 20:44:46 +08:00
package ytdl
import (
"fmt"
"net/url"
"strconv"
"github.com/rs/zerolog/log"
)
// FormatKey is a string type containing a key in a video format map
type FormatKey string
// Available format Keys
const (
FormatExtensionKey FormatKey = "ext"
FormatResolutionKey FormatKey = "res"
FormatVideoEncodingKey FormatKey = "videnc"
FormatAudioEncodingKey FormatKey = "audenc"
FormatItagKey FormatKey = "itag"
FormatAudioBitrateKey FormatKey = "audbr"
FormatFPSKey FormatKey = "fps"
)
type Format struct {
Itag
url string
s string
sig string
stream string
conn string
sp string
}
func parseFormat(input string) (*Format, error) {
query, err := url.ParseQuery(input)
if err != nil {
return nil, err
}
format := Format{}
for k, v := range query {
switch k {
case "itag":
i, err := strconv.Atoi(v[0])
if err != nil {
return nil, fmt.Errorf("unable to parse itag param: %w", err)
}
itag := getItag(i)
if itag == nil {
return nil, fmt.Errorf("no metadata found for itag: %v", i)
}
format.Itag = *itag
case "url":
format.url = v[0]
case "s":
format.s = v[0]
case "sig":
format.sig = v[0]
case "stream":
format.stream = v[0]
case "conn":
format.conn = v[0]
case "sp":
format.sp = v[0]
}
}
return &format, nil
}
// ValueForKey gets the format value for a format key, used for filtering
func (f *Format) ValueForKey(key FormatKey) interface{} {
switch key {
case FormatItagKey:
return f.Itag.Number
case FormatExtensionKey:
return f.Extension
case FormatResolutionKey:
return f.Resolution
case FormatVideoEncodingKey:
return f.VideoEncoding
case FormatAudioEncodingKey:
return f.AudioEncoding
case FormatAudioBitrateKey:
return f.AudioBitrate
default:
log.Debug().Msgf("Unknown format key: %v", key)
return nil
}
}
func (f *Format) CompareKey(other *Format, key FormatKey) int {
switch key {
case FormatResolutionKey:
return f.resolution() - other.resolution()
case FormatAudioBitrateKey:
return f.AudioBitrate - other.AudioBitrate
case FormatFPSKey:
return f.FPS - other.FPS
default:
return 0
}
}
// width in pixels
func (f *Format) resolution() int {
res := f.Itag.Resolution
if len(res) < 2 {
return 0
}
width, _ := strconv.Atoi(res[:len(res)-2])
return width
}