From 2bdb119f8e1af76d9528414b72e4d95bb2a86e7e Mon Sep 17 00:00:00 2001 From: chaoqun <27287694+OpenWaygate@users.noreply.github.com> Date: Tue, 4 Jun 2024 22:38:43 +0800 Subject: [PATCH] :sparkles: Add watermark service --- pkg/yutuber/watermark/watermark.go | 143 ++++++++++++++++++++++++ pkg/yutuber/watermark/watermark_test.go | 50 +++++++++ 2 files changed, 193 insertions(+) create mode 100644 pkg/yutuber/watermark/watermark.go create mode 100644 pkg/yutuber/watermark/watermark_test.go diff --git a/pkg/yutuber/watermark/watermark.go b/pkg/yutuber/watermark/watermark.go new file mode 100644 index 0000000..d90aa5a --- /dev/null +++ b/pkg/yutuber/watermark/watermark.go @@ -0,0 +1,143 @@ +package watermark + +import ( + "errors" + "fmt" + "github.com/eat-pray-ai/yutu/pkg/auth" + "google.golang.org/api/youtube/v3" + "log" + "os" +) + +var ( + service *youtube.Service + errOpenFile = errors.New("failed to open file") + errSetWatermark = errors.New("failed to set watermark") + errUnsetWatermark = errors.New("failed to unset watermark") +) + +type watermark struct { + channelId string + file string + inVideoPosition string + durationMs uint64 + offsetMs uint64 + offsetType string + onBehalfOfContentOwner string +} + +type Watermark interface { + Set() + Unset() +} + +type Option func(*watermark) + +func NewWatermark(opts ...Option) Watermark { + w := &watermark{} + + for _, opt := range opts { + opt(w) + } + + return w +} + +func (w watermark) Set() { + file, err := os.Open(w.file) + if err != nil { + log.Fatalln(errors.Join(errOpenFile, err), w.file) + } + defer file.Close() + inVideoBranding := &youtube.InvideoBranding{ + Position: &youtube.InvideoPosition{}, + Timing: &youtube.InvideoTiming{}, + } + if w.inVideoPosition != "" { + inVideoBranding.Position.Type = "corner" + inVideoBranding.Position.CornerPosition = w.inVideoPosition + } + if w.durationMs != 0 { + inVideoBranding.Timing.DurationMs = w.durationMs + } + if w.offsetMs != 0 { + inVideoBranding.Timing.OffsetMs = w.offsetMs + } + if w.offsetType != "" { + inVideoBranding.Timing.Type = w.offsetType + } + + call := service.Watermarks.Set(w.channelId, inVideoBranding).Media(file) + if w.onBehalfOfContentOwner != "" { + call = call.OnBehalfOfContentOwner(w.onBehalfOfContentOwner) + } + + err = call.Do() + if err != nil { + log.Fatalln(errors.Join(errSetWatermark, err)) + } + fmt.Println("Watermark set done") + +} + +func (w *watermark) Unset() { + call := service.Watermarks.Unset(w.channelId) + if w.onBehalfOfContentOwner != "" { + call = call.OnBehalfOfContentOwner(w.onBehalfOfContentOwner) + } + + err := call.Do() + if err != nil { + log.Fatalln(errors.Join(errUnsetWatermark, err)) + } + + fmt.Println("Watermark unset done") +} + +func WithChannelId(channelId string) Option { + return func(w *watermark) { + w.channelId = channelId + } +} + +func WithFile(file string) Option { + return func(w *watermark) { + w.file = file + } +} + +func WithInVideoPosition(inVideoPosition string) Option { + return func(w *watermark) { + w.inVideoPosition = inVideoPosition + } +} + +func WithDurationMs(durationMs uint64) Option { + return func(w *watermark) { + w.durationMs = durationMs + } +} + +func WithOffsetMs(offsetMs uint64) Option { + return func(w *watermark) { + w.offsetMs = offsetMs + } +} + +func WithOffsetType(offsetType string) Option { + return func(w *watermark) { + w.offsetType = offsetType + } +} + +func WithOnBehalfOfContentOwner(onBehalfOfContentOwner string) Option { + return func(w *watermark) { + w.onBehalfOfContentOwner = onBehalfOfContentOwner + } +} + +func WithService() Option { + return func(w *watermark) { + service = auth.NewY2BService() + } +} diff --git a/pkg/yutuber/watermark/watermark_test.go b/pkg/yutuber/watermark/watermark_test.go new file mode 100644 index 0000000..5c5df46 --- /dev/null +++ b/pkg/yutuber/watermark/watermark_test.go @@ -0,0 +1,50 @@ +package watermark + +import ( + "reflect" + "testing" +) + +func TestNewWatermark(t *testing.T) { + type args struct { + opts []Option + } + tests := []struct { + name string + args args + want Watermark + }{ + { + name: "TestNewWatermark", + args: args{ + opts: []Option{ + WithChannelId("channelId"), + WithFile("file"), + WithInVideoPosition("topRight"), + WithDurationMs(1024), + WithOffsetMs(31415), + WithOffsetType("offsetFromEnd"), + WithOnBehalfOfContentOwner("contentOwner"), + }, + }, + want: &watermark{ + channelId: "channelId", + file: "file", + inVideoPosition: "topRight", + durationMs: 1024, + offsetMs: 31415, + offsetType: "offsetFromEnd", + onBehalfOfContentOwner: "contentOwner", + }, + }, + } + for _, tt := range tests { + t.Run( + tt.name, func(t *testing.T) { + if got := NewWatermark(tt.args.opts...); !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewWatermark() = %v, want %v", got, tt.want) + } + }, + ) + } +}