94 lines
3.0 KiB
Go
94 lines
3.0 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
func readDownloadRequest(writer http.ResponseWriter, request *http.Request) ([]string, *int, bool) {
|
|
var input struct {
|
|
IDs []string `json:"ids"`
|
|
Quality *int `json:"quality"`
|
|
}
|
|
decoder := json.NewDecoder(http.MaxBytesReader(writer, request.Body, 1<<20))
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(&input); err != nil {
|
|
writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "下载参数无效"})
|
|
return nil, nil, false
|
|
}
|
|
if decoder.Decode(new(any)) != io.EOF || input.Quality != nil && (*input.Quality < 0 || *input.Quality > 4320) {
|
|
writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "下载清晰度选项无效"})
|
|
return nil, nil, false
|
|
}
|
|
ids, ok := cleanIDList(writer, input.IDs)
|
|
if !ok {
|
|
return nil, nil, false
|
|
}
|
|
for index, id := range ids {
|
|
_, sourceID, valid := splitProviderDramaID(id)
|
|
if !valid {
|
|
writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "此版本仅支持红果剧集 ID"})
|
|
return nil, nil, false
|
|
}
|
|
ids[index] = providerDramaID(sourceHongguo, sourceID)
|
|
}
|
|
return ids, input.Quality, true
|
|
}
|
|
|
|
func preferredDownloadQuality(requested int, available []int) int {
|
|
best, lowest := 0, 0
|
|
for _, quality := range available {
|
|
if quality <= 0 || quality > 4320 {
|
|
continue
|
|
}
|
|
if lowest == 0 || quality < lowest {
|
|
lowest = quality
|
|
}
|
|
if (requested <= 0 || quality <= requested) && quality > best {
|
|
best = quality
|
|
}
|
|
}
|
|
if best == 0 {
|
|
return lowest
|
|
}
|
|
return best
|
|
}
|
|
|
|
func (downloader *Downloader) selectDownloadQuality(ctx context.Context, task Task, media providerMedia) (providerMedia, error) {
|
|
qualities := []int{media.Quality}
|
|
validVariants := make([]providerMedia, 0, len(media.Variants)+1)
|
|
for _, variant := range media.Variants {
|
|
if isProviderHTTPMediaURL(variant.URL) {
|
|
qualities = append(qualities, variant.Quality)
|
|
validVariants = append(validVariants, variant)
|
|
}
|
|
}
|
|
if isProviderHTTPMediaURL(media.URL) {
|
|
current := media
|
|
current.Variants = nil
|
|
validVariants = append(validVariants, current)
|
|
}
|
|
media.Variants = validVariants
|
|
if variants := playbackHLSVariants(media.Playlist); len(variants) > 0 {
|
|
qualities = nil
|
|
for _, variant := range variants {
|
|
qualities = append(qualities, variant.quality)
|
|
}
|
|
}
|
|
quality := preferredDownloadQuality(task.DownloadQuality, qualities)
|
|
selected, err := downloader.selectPlaybackQuality(context.WithValue(ctx, playbackQualityKey{}, quality), media)
|
|
if err != nil {
|
|
return providerMedia{}, err
|
|
}
|
|
var available []int
|
|
for _, option := range playbackQualityOptions(selected) {
|
|
available = append(available, option.Value)
|
|
}
|
|
downloader.recordDiagnostic(diagnosticEvent{Level: "info", Event: "download.media", Source: sourceFromDramaID(task.DramaID),
|
|
DramaID: task.DramaID, DramaTitle: task.DramaTitle, Episode: task.Index, Quality: selected.Quality, RequestedQuality: task.DownloadQuality, AvailableQualities: available,
|
|
Message: "下载保留源媒体的音视频编码和分辨率"})
|
|
return selected, nil
|
|
}
|