video.go
3104 bytes
1package models
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/dustin/go-humanize"
8)
9
10type Video struct {
11 // YouTube ID of the video
12 ID string `json:"video_id"`
13 // Name of the channel the video belongs to
14 ChannelName string `json:"channel_name"`
15 // ID of the channel the video belongs to
16 ChannelID string `json:"-"`
17 // Title of the video
18 Title string `json:"title"`
19 // Video publish timestamp
20 PublishedTime time.Time `json:"published_timestamp"`
21 // Video watch timestamp
22 WatchTime *time.Time `json:"watch_timestamp"`
23 // ProgressSeconds is the total duration of the video
24 DurationSeconds int `json:"duration"`
25 // ProgressSeconds is the saved progress of the video
26 ProgressSeconds int `json:"progress"`
27 // IsShort indicates if a video is a YouTube short
28 IsShort bool `json:"short"`
29 // IsLive indicates if the video is a currently active live stream
30 IsLive bool `json:"is_live"`
31 // IsDiscarded indicates if the video was discarded from the feed without watching
32 // This happens to shorts videos for channels that have shorts disabled
33 IsDiscarded bool `json:"is_discarded"`
34 // DownloadedAt is the timestamp when the video was downloaded to the server
35 DownloadedAt *time.Time `json:"downloaded_at"`
36 // FilePath is the path to the downloaded video file on the server
37 FilePath *string `json:"-"`
38 // DownloadStatus tracks the download state: "", "pending", "downloading", "completed", "failed"
39 DownloadStatus *string `json:"download_status"`
40 // DownloadError stores the error message if download failed
41 DownloadError *string `json:"download_error"`
42}
43
44// ProgressPercentage returns the current progress of the video as an integer from 0-100
45func (v Video) ProgressPercentage() int {
46 if v.DurationSeconds <= 0 {
47 return 0
48 }
49
50 percentage := 100 * v.ProgressSeconds / v.DurationSeconds
51 if percentage < 0 {
52 return 0
53 }
54 if percentage > 100 {
55 return 100
56 }
57 return percentage
58}
59
60// WatchURL returns the formatted YouTube watch URL including the timestamp pointing to the current progress
61func (v Video) WatchURL() string {
62 return fmt.Sprintf("https://youtube.com/watch?v=%s&t=%d", v.ID, v.ProgressSeconds)
63}
64
65// Duration returns the total duration of the video in the hh:mm:ss format
66func (v Video) Duration() string {
67 duration := time.Duration(v.DurationSeconds) * time.Second
68 duration = duration.Round(time.Second)
69 h := duration / time.Hour
70 duration -= h * time.Hour
71 m := duration / time.Minute
72 duration -= m * time.Minute
73 s := duration / time.Second
74
75 if h > 0 {
76 return fmt.Sprintf("%02d:%02d:%02d", h, m, s)
77 }
78 return fmt.Sprintf("%02d:%02d", m, s)
79}
80
81func (v Video) HumanizedPublishTime() string {
82 return humanize.Time(v.PublishedTime)
83}
84
85func (v Video) IsDownloaded() bool {
86 return v.DownloadStatus != nil && *v.DownloadStatus == "completed"
87}
88
89func (v Video) IsDownloading() bool {
90 return v.DownloadStatus != nil && (*v.DownloadStatus == "pending" || *v.DownloadStatus == "downloading")
91}
92
93func (v Video) DownloadFailed() bool {
94 return v.DownloadStatus != nil && *v.DownloadStatus == "failed"
95}
96
97type PaginatedVideos struct {
98 Videos []Video
99 NextOffset int
100}