All checks were successful
CI / build (push) Successful in 52s
- Add MediaTypeAsk (0) as the default, mapping old video_audio to Ask - Show Video/Audio/Ask type picker when no default media type is set - Auto-select matching format and skip picker when defaults are configured - Add autoSelectVideoFormat / autoSelectAudioFormat helpers with closest-match - Add buildFilteredFormatList for type-filtered format lists - Add Media Type setting in settings UI (Ask/Video/Audio) - Add --merge-output-format mp4 for video downloads via yt-dlp - Fix formatLabelForDisplay to show Height fallback and Extension - Add cookies volume mount to docker-compose.yml - Document cookies setup and new features in README
183 lines
3.7 KiB
Go
183 lines
3.7 KiB
Go
package domain
|
|
|
|
import "os/exec"
|
|
|
|
// MediaType represents the type of media the user wants to download.
|
|
type MediaType int
|
|
|
|
const (
|
|
MediaTypeAsk MediaType = iota
|
|
MediaTypeAudio
|
|
MediaTypeVideo
|
|
MediaTypeVideoAudio
|
|
)
|
|
|
|
func (m MediaType) String() string {
|
|
switch m {
|
|
case MediaTypeAsk:
|
|
return "ask"
|
|
case MediaTypeAudio:
|
|
return "audio"
|
|
case MediaTypeVideo:
|
|
return "video"
|
|
case MediaTypeVideoAudio:
|
|
return "video_audio"
|
|
default:
|
|
return "unknown"
|
|
}
|
|
}
|
|
|
|
// Format represents a downloadable format from yt-dlp.
|
|
type Format struct {
|
|
ID string
|
|
Extension string
|
|
Width int
|
|
Height int
|
|
Resolution string
|
|
Filesize int64
|
|
Codec string
|
|
Bitrate string
|
|
Language string
|
|
IsAudioOnly bool
|
|
IsVideoOnly bool
|
|
HasAudio bool
|
|
HasVideo bool
|
|
}
|
|
|
|
// MediaInfo holds the full information about a downloadable media item.
|
|
type MediaInfo struct {
|
|
URL string
|
|
Title string
|
|
Uploader string
|
|
Thumbnail string
|
|
Duration float64
|
|
Formats []Format
|
|
Languages []string
|
|
EstimatedSize int64
|
|
}
|
|
|
|
// IsAudioOnlyContent returns true when no format carries a video stream.
|
|
func (m *MediaInfo) IsAudioOnlyContent() bool {
|
|
for _, f := range m.Formats {
|
|
if f.HasVideo {
|
|
return false
|
|
}
|
|
}
|
|
return len(m.Formats) > 0
|
|
}
|
|
|
|
// PlaylistEntry represents a single entry in a playlist.
|
|
type PlaylistEntry struct {
|
|
ID string
|
|
Title string
|
|
URL string
|
|
Duration float64
|
|
}
|
|
|
|
// DownloadStatus represents the current state of a download job.
|
|
type DownloadStatus int
|
|
|
|
const (
|
|
StatusPending DownloadStatus = iota
|
|
StatusFetching
|
|
StatusDownloading
|
|
StatusProcessing
|
|
StatusCompleted
|
|
StatusFailed
|
|
StatusCancelled
|
|
)
|
|
|
|
func (s DownloadStatus) String() string {
|
|
switch s {
|
|
case StatusPending:
|
|
return "Pending"
|
|
case StatusFetching:
|
|
return "Fetching info"
|
|
case StatusDownloading:
|
|
return "Downloading"
|
|
case StatusProcessing:
|
|
return "Processing"
|
|
case StatusCompleted:
|
|
return "Completed"
|
|
case StatusFailed:
|
|
return "Failed"
|
|
case StatusCancelled:
|
|
return "Cancelled"
|
|
default:
|
|
return "Unknown"
|
|
}
|
|
}
|
|
|
|
// DownloadJob represents an active download process for a user.
|
|
type DownloadJob struct {
|
|
ID string
|
|
UserID int64
|
|
ChatID int64
|
|
MessageID int
|
|
URL string
|
|
MediaType MediaType
|
|
SelectedFormat *Format
|
|
FormatString string
|
|
Language string
|
|
Status DownloadStatus
|
|
Progress float64
|
|
Speed string
|
|
ETA string
|
|
FileSize int64
|
|
MaxFileSize int64
|
|
FilePath string
|
|
Title string
|
|
ProgressPrefix string
|
|
QuotaApplied bool
|
|
StderrLog string
|
|
Done chan struct{}
|
|
CancelCh chan struct{}
|
|
Cmd *exec.Cmd
|
|
}
|
|
|
|
// UserPreferences holds per-user default preferences.
|
|
type UserPreferences struct {
|
|
DefaultMediaType MediaType
|
|
DefaultAudioFormat string
|
|
DefaultVideoFormat string
|
|
DefaultAudioContainer string
|
|
DefaultVideoContainer string
|
|
DefaultLanguage string
|
|
}
|
|
|
|
// UserQuotas holds the quota usage and limits for a user.
|
|
type UserQuotas struct {
|
|
DailyLimitMB int64
|
|
DailyUsedMB int64
|
|
DailyDate string
|
|
WeeklyLimitMB int64
|
|
WeeklyUsedMB int64
|
|
WeekStart string
|
|
MonthlyLimitMB int64
|
|
MonthlyUsedMB int64
|
|
MonthStart string
|
|
}
|
|
|
|
// DownloadRecord is a completed download entry stored in history.
|
|
type DownloadRecord struct {
|
|
ID int64
|
|
UserID int64
|
|
URL string
|
|
Title string
|
|
MediaType string
|
|
FormatID string
|
|
Container string
|
|
FileSize int64
|
|
Status string
|
|
CreatedAt string
|
|
}
|
|
|
|
// SearchState tracks the user's current search results flow.
|
|
type SearchState struct {
|
|
Query string
|
|
Entries []PlaylistEntry
|
|
Page int
|
|
PerPage int
|
|
Source string // "youtube" or "ytmusic"
|
|
}
|