198 lines
5.5 KiB
Go
198 lines
5.5 KiB
Go
package vimeo
|
|
|
|
import (
|
|
"Yimaru-Backend/internal/pkgs/vimeo"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type Service struct {
|
|
client *vimeo.Client
|
|
logger *zap.Logger
|
|
}
|
|
|
|
func NewService(accessToken string, logger *zap.Logger) *Service {
|
|
return &Service{
|
|
client: vimeo.NewClient(accessToken),
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
type VideoInfo struct {
|
|
VimeoID string
|
|
URI string
|
|
Name string
|
|
Description string
|
|
Duration int
|
|
Width int
|
|
Height int
|
|
Link string
|
|
EmbedURL string
|
|
EmbedHTML string
|
|
ThumbnailURL string
|
|
Status string
|
|
TranscodeStatus string
|
|
}
|
|
|
|
type UploadResult struct {
|
|
VimeoID string
|
|
URI string
|
|
Link string
|
|
UploadLink string
|
|
Status string
|
|
}
|
|
|
|
func (s *Service) GetVideoInfo(ctx context.Context, videoID string) (*VideoInfo, error) {
|
|
video, err := s.client.GetVideo(ctx, videoID)
|
|
if err != nil {
|
|
s.logger.Error("Failed to get video from Vimeo", zap.String("video_id", videoID), zap.Error(err))
|
|
return nil, fmt.Errorf("failed to get video: %w", err)
|
|
}
|
|
|
|
info := &VideoInfo{
|
|
VimeoID: videoID,
|
|
URI: video.URI,
|
|
Name: video.Name,
|
|
Description: video.Description,
|
|
Duration: video.Duration,
|
|
Width: video.Width,
|
|
Height: video.Height,
|
|
Link: video.Link,
|
|
Status: video.Status,
|
|
}
|
|
|
|
if video.PlayerEmbedURL != "" {
|
|
info.EmbedURL = video.PlayerEmbedURL
|
|
} else {
|
|
info.EmbedURL = vimeo.GenerateEmbedURL(videoID, nil)
|
|
}
|
|
|
|
if video.Embed != nil {
|
|
info.EmbedHTML = video.Embed.HTML
|
|
}
|
|
|
|
if video.Pictures != nil && len(video.Pictures.Sizes) > 0 {
|
|
info.ThumbnailURL = video.Pictures.Sizes[len(video.Pictures.Sizes)-1].Link
|
|
}
|
|
|
|
if video.Transcode != nil {
|
|
info.TranscodeStatus = video.Transcode.Status
|
|
}
|
|
|
|
return info, nil
|
|
}
|
|
|
|
func (s *Service) CreatePullUpload(ctx context.Context, name, description, sourceURL string, fileSize int64) (*UploadResult, error) {
|
|
resp, err := s.client.CreatePullUpload(ctx, name, description, sourceURL, fileSize)
|
|
if err != nil {
|
|
s.logger.Error("Failed to create pull upload", zap.String("source_url", sourceURL), zap.Error(err))
|
|
return nil, fmt.Errorf("failed to create pull upload: %w", err)
|
|
}
|
|
|
|
videoID := vimeo.ExtractVideoID(resp.URI)
|
|
|
|
return &UploadResult{
|
|
VimeoID: videoID,
|
|
URI: resp.URI,
|
|
Link: resp.Link,
|
|
UploadLink: resp.Upload.UploadLink,
|
|
Status: resp.Upload.Status,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) CreateTusUpload(ctx context.Context, name, description string, fileSize int64) (*UploadResult, error) {
|
|
resp, err := s.client.CreateTusUpload(ctx, name, description, fileSize)
|
|
if err != nil {
|
|
s.logger.Error("Failed to create TUS upload", zap.Error(err))
|
|
return nil, fmt.Errorf("failed to create TUS upload: %w", err)
|
|
}
|
|
|
|
videoID := vimeo.ExtractVideoID(resp.URI)
|
|
|
|
return &UploadResult{
|
|
VimeoID: videoID,
|
|
URI: resp.URI,
|
|
Link: resp.Link,
|
|
UploadLink: resp.Upload.UploadLink,
|
|
Status: resp.Upload.Status,
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) UploadVideoFile(ctx context.Context, name, description string, fileData io.Reader, fileSize int64) (*UploadResult, error) {
|
|
resp, err := s.client.CreateTusUpload(ctx, name, description, fileSize)
|
|
if err != nil {
|
|
s.logger.Error("Failed to create TUS upload slot", zap.Error(err))
|
|
return nil, fmt.Errorf("failed to create TUS upload slot: %w", err)
|
|
}
|
|
|
|
if err := s.client.UploadTusVideoFile(ctx, resp.Upload.UploadLink, fileData, fileSize); err != nil {
|
|
s.logger.Error("Failed to upload video file to Vimeo", zap.Error(err))
|
|
return nil, fmt.Errorf("failed to upload video file: %w", err)
|
|
}
|
|
|
|
videoID := vimeo.ExtractVideoID(resp.URI)
|
|
|
|
return &UploadResult{
|
|
VimeoID: videoID,
|
|
URI: resp.URI,
|
|
Link: resp.Link,
|
|
UploadLink: resp.Upload.UploadLink,
|
|
Status: "uploading",
|
|
}, nil
|
|
}
|
|
|
|
func (s *Service) UpdateVideoMetadata(ctx context.Context, videoID string, name, description *string) (*VideoInfo, error) {
|
|
req := &vimeo.UpdateVideoRequest{
|
|
Name: name,
|
|
Description: description,
|
|
}
|
|
|
|
video, err := s.client.UpdateVideo(ctx, videoID, req)
|
|
if err != nil {
|
|
s.logger.Error("Failed to update video metadata", zap.String("video_id", videoID), zap.Error(err))
|
|
return nil, fmt.Errorf("failed to update video: %w", err)
|
|
}
|
|
|
|
info := &VideoInfo{
|
|
VimeoID: videoID,
|
|
URI: video.URI,
|
|
Name: video.Name,
|
|
Description: video.Description,
|
|
Duration: video.Duration,
|
|
Link: video.Link,
|
|
}
|
|
|
|
return info, nil
|
|
}
|
|
|
|
func (s *Service) DeleteVideo(ctx context.Context, videoID string) error {
|
|
if err := s.client.DeleteVideo(ctx, videoID); err != nil {
|
|
s.logger.Error("Failed to delete video from Vimeo", zap.String("video_id", videoID), zap.Error(err))
|
|
return fmt.Errorf("failed to delete video: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *Service) GetTranscodeStatus(ctx context.Context, videoID string) (string, error) {
|
|
status, err := s.client.GetTranscodeStatus(ctx, videoID)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get transcode status: %w", err)
|
|
}
|
|
return status, nil
|
|
}
|
|
|
|
func (s *Service) GetEmbedCode(ctx context.Context, videoID string, width, height int, opts *vimeo.EmbedOptions) (string, error) {
|
|
return vimeo.GenerateIframeEmbed(videoID, width, height, opts), nil
|
|
}
|
|
|
|
func (s *Service) GetOEmbed(ctx context.Context, vimeoURL string, width, height int) (*vimeo.OEmbedResponse, error) {
|
|
return vimeo.GetOEmbed(ctx, vimeoURL, width, height)
|
|
}
|
|
|
|
func (s *Service) GeneratePlayerURL(videoID string, opts *vimeo.EmbedOptions) string {
|
|
return vimeo.GenerateEmbedURL(videoID, opts)
|
|
}
|