Parent directory

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}