feat: add 'Ask' quality option, language auto-select, and m4a audio remux
All checks were successful
CI / build (push) Successful in 47s
All checks were successful
CI / build (push) Successful in 47s
- Add 'ask' option to audio/video quality settings (stored as '' in DB) - Auto-select when both media type AND quality are set; show filtered format picker when quality is Ask - Auto-skip language picker when user has a matching language preference - Remux audio-only downloads to m4a instead of webm for Telegram compat - Update README to document the new flow and m4a audio output
This commit is contained in:
@@ -161,7 +161,27 @@ func (h *Handler) handleURLInput(ctx context.Context, chatID int64, text string,
|
||||
|
||||
prefs, prefErr := h.Repo.GetOrCreatePreferences(userID)
|
||||
if prefErr == nil && prefs.DefaultMediaType != domain.MediaTypeAsk {
|
||||
h.autoSelectAndDownload(ctx, chatID, userID, url, info, prefs)
|
||||
// Media type is set — check quality preference
|
||||
var qualityPref string
|
||||
switch prefs.DefaultMediaType {
|
||||
case domain.MediaTypeVideo:
|
||||
qualityPref = prefs.DefaultVideoFormat
|
||||
case domain.MediaTypeAudio:
|
||||
qualityPref = prefs.DefaultAudioFormat
|
||||
}
|
||||
if qualityPref != "" {
|
||||
h.autoSelectAndDownload(ctx, chatID, userID, url, info, prefs)
|
||||
return
|
||||
}
|
||||
// Quality is Ask — show filtered format picker
|
||||
ss := &stepState{
|
||||
URL: url,
|
||||
MediaInfo: info,
|
||||
Step: 0,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
h.setUserStepState(chatID, ss)
|
||||
h.showFormatsForType(ctx, chatID, userID, ss, prefs.DefaultMediaType.String())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -239,6 +259,34 @@ func (h *Handler) autoSelectAndDownload(ctx context.Context, chatID int64, userI
|
||||
h.advanceToLanguage(ctx, chatID, msgID, userID, ss)
|
||||
}
|
||||
|
||||
// showFormatsForType sends the format picker filtered by the given media type.
|
||||
// Called when the user has a type preference but quality is Ask.
|
||||
func (h *Handler) showFormatsForType(ctx context.Context, chatID int64, userID int64, ss *stepState, mediaType string) {
|
||||
ids, err := buildFilteredFormatList(ss.MediaInfo.Formats, mediaType)
|
||||
if err != nil {
|
||||
h.sendText(ctx, chatID, "No formats available.")
|
||||
return
|
||||
}
|
||||
ss.FormatIDs = ids
|
||||
h.setUserStepState(chatID, ss)
|
||||
|
||||
labels := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
if id == "best" {
|
||||
labels[i] = "Best"
|
||||
} else {
|
||||
f := findFormatByID(ss.MediaInfo.Formats, id)
|
||||
if f != nil {
|
||||
labels[i] = formatLabelForDisplay(*f)
|
||||
} else {
|
||||
labels[i] = id
|
||||
}
|
||||
}
|
||||
}
|
||||
kb := formatKeyboard("format_", labels, ids)
|
||||
h.sendWithKB(ctx, chatID, "Select format:", kb)
|
||||
}
|
||||
|
||||
// handleTypeSelection processes the initial type picker (Video/Audio/Ask).
|
||||
func (h *Handler) handleTypeSelection(ctx context.Context, chatID int64, msgID int, userID int64, mediaType string) {
|
||||
ss := h.getUserStepState(chatID)
|
||||
@@ -394,6 +442,18 @@ func (h *Handler) advanceToLanguage(ctx context.Context, chatID int64, msgID int
|
||||
h.setUserStepState(chatID, ss)
|
||||
|
||||
if len(ss.MediaInfo.Languages) > 1 {
|
||||
// Check if user has a default language and it's available.
|
||||
prefs, prefErr := h.Repo.GetOrCreatePreferences(userID)
|
||||
if prefErr == nil && prefs.DefaultLanguage != "" {
|
||||
for _, lang := range ss.MediaInfo.Languages {
|
||||
if lang == prefs.DefaultLanguage {
|
||||
ss.Language = lang
|
||||
h.startDownload(ctx, chatID, msgID, userID, ss)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// No match or no preference — show picker.
|
||||
kb := languageKeyboard(ss.MediaInfo.Languages)
|
||||
h.editText(ctx, chatID, msgID, "Select language:", &kb)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user