2021-10-27 19:34:59 +00:00
|
|
|
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{
|
2021-11-01 05:28:40 +00:00
|
|
|
YoutubeID: "",
|
2021-10-27 19:34:59 +00:00
|
|
|
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
|
|
|
|
}
|