feat(app): add internal components batch 2
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user