package youtube import ( "context" "errors" "fmt" "io" "log" "strconv" "time" "git.netflux.io/rob/clipper/media" youtubev2 "github.com/kkdai/youtube/v2" ) // YoutubeClient wraps the youtube.Client client. type YoutubeClient interface { GetVideoContext(context.Context, string) (*youtubev2.Video, error) GetStreamContext(context.Context, *youtubev2.Video, *youtubev2.Format) (io.ReadCloser, int64, error) } // MediaSetService implements a MediaSetService for Youtube videos. type MediaSetService struct { youtubeClient YoutubeClient } // not used func (s *MediaSetService) GetMediaSet(ctx context.Context, id string) (*media.MediaSet, error) { var video *youtubev2.Video video, err := s.youtubeClient.GetVideoContext(ctx, id) if err != nil { return nil, fmt.Errorf("error fetching video: %v", err) } if len(video.Formats) == 0 { return nil, errors.New("no format available") } audioFormat := SortAudio(video.Formats)[0] videoFormat := SortVideo(video.Formats)[0] durationMsecs, err := strconv.Atoi(videoFormat.ApproxDurationMs) if err != nil { log.Printf("GetMediaSet: invalid duration %s", videoFormat.ApproxDurationMs) return nil, errors.New("error parsing format") } duration := time.Duration(durationMsecs) * time.Millisecond sampleRate, err := strconv.Atoi(videoFormat.AudioSampleRate) if err != nil { log.Printf("GetMediaSet: invalid samplerate %s", videoFormat.AudioSampleRate) return nil, errors.New("error parsing format") } return &media.MediaSet{ YoutubeID: "", Audio: media.Audio{ Bytes: audioFormat.ContentLength, Channels: audioFormat.AudioChannels, Frames: 0, SampleRate: sampleRate, }, Video: media.Video{ Bytes: videoFormat.ContentLength, Duration: duration, ThumbnailWidth: videoFormat.Width, ThumbnailHeight: videoFormat.Height, }, }, nil }