mirror of
https://github.com/yattee/yattee.git
synced 2026-08-05 23:01:28 +00:00
Show and label WebDAV/SMB video streams in the quality selector
Media-source streams from WebDAV/SMB were invisible in the Video list: the filter required remote URLs to carry a resolution, which MediaFile.toStream never sets. Include non-adaptive remote streams without resolution (only media sources produce those), extend the mpv-track display enrichment to the currently playing stream regardless of URL scheme, and classify metadata-less streams as recommended — a nil codec previously counted as software-decoded, hiding the row behind advanced mode with a spurious warning. The warning now uses the enriched codec.
This commit is contained in:
@@ -695,15 +695,17 @@ extension QualitySelectorView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A local file's Stream carries no resolution/codec/fps metadata
|
/// A media-source Stream (local folder, WebDAV, SMB) carries no
|
||||||
/// (`MediaFile.toStream` cannot know them before demux), which would label
|
/// resolution/codec/fps metadata (`MediaFile.toStream` cannot know them
|
||||||
/// the row "Unknown". Once mpv reports the file's video track, fill those
|
/// before demux), which would label the row "Unknown". Once mpv reports
|
||||||
/// fields for display. The enriched copy is display-only — selection and
|
/// the loaded file's video track, fill those fields for display. Gated to
|
||||||
/// tap handling keep using the original stream (compared by URL).
|
/// local files and the currently playing stream — the track info describes
|
||||||
|
/// whatever mpv has loaded. The enriched copy is display-only — selection
|
||||||
|
/// and tap handling keep using the original stream (compared by URL).
|
||||||
func displayStream(for stream: Stream) -> Stream {
|
func displayStream(for stream: Stream) -> Stream {
|
||||||
guard stream.url.isFileURL,
|
guard stream.resolution == nil,
|
||||||
stream.resolution == nil,
|
|
||||||
!stream.isAudioOnly,
|
!stream.isAudioOnly,
|
||||||
|
stream.url.isFileURL || stream.url == currentStream?.url,
|
||||||
let track = embeddedVideoTrack,
|
let track = embeddedVideoTrack,
|
||||||
let width = track.width,
|
let width = track.width,
|
||||||
let height = track.height else {
|
let height = track.height else {
|
||||||
@@ -731,14 +733,18 @@ extension QualitySelectorView {
|
|||||||
? stream.url == currentStream?.url
|
? stream.url == currentStream?.url
|
||||||
: stream.url == selectedVideoStream?.url
|
: stream.url == selectedVideoStream?.url
|
||||||
let isPreferredQuality: Bool = stream.resolution == preferredQuality.maxResolution
|
let isPreferredQuality: Bool = stream.resolution == preferredQuality.maxResolution
|
||||||
|
// Metadata-less media-source streams get resolution/codec/fps filled
|
||||||
|
// from the mpv-reported video track for display; the warning must use
|
||||||
|
// the enriched codec too or a nil codec reads as software-decoded
|
||||||
|
let display: Stream = displayStream(for: stream)
|
||||||
|
|
||||||
VideoStreamRowView(
|
VideoStreamRowView(
|
||||||
stream: displayStream(for: stream),
|
stream: display,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
isPreferredQuality: isPreferredQuality,
|
isPreferredQuality: isPreferredQuality,
|
||||||
isDownloaded: isDownloadedStream,
|
isDownloaded: isDownloadedStream,
|
||||||
showAdvancedDetails: showAdvancedStreamDetails,
|
showAdvancedDetails: showAdvancedStreamDetails,
|
||||||
requiresSoftwareDecode: !stream.isMuxed && requiresSoftwareDecode(stream.videoCodec),
|
requiresSoftwareDecode: !display.isMuxed && display.videoCodec != nil && requiresSoftwareDecode(display.videoCodec),
|
||||||
onTap: {
|
onTap: {
|
||||||
handleVideoStreamTap(stream, isDownloaded: isDownloadedStream)
|
handleVideoStreamTap(stream, isDownloaded: isDownloadedStream)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,17 @@ extension QualitySelectorView {
|
|||||||
var videoStreams: [Stream] {
|
var videoStreams: [Stream] {
|
||||||
let maxRes: StreamResolution? = preferredQuality.maxResolution
|
let maxRes: StreamResolution? = preferredQuality.maxResolution
|
||||||
|
|
||||||
// Separate downloaded streams (always include them, shown first)
|
// Separate downloaded/media-source streams (always include them, shown
|
||||||
let downloadedStreams: [Stream] = streams.filter { $0.url.isFileURL && !$0.isAudioOnly }
|
// first). Local files are file URLs; WebDAV/SMB media-source streams
|
||||||
|
// are remote URLs that carry no resolution metadata — nothing else
|
||||||
|
// produces a non-adaptive remote stream without resolution, so that
|
||||||
|
// combination identifies them.
|
||||||
|
let downloadedStreams: [Stream] = streams.filter { (stream: Stream) -> Bool in
|
||||||
|
guard !stream.isAudioOnly else { return false }
|
||||||
|
if stream.url.isFileURL { return true }
|
||||||
|
let format = StreamFormat.detect(from: stream)
|
||||||
|
return stream.resolution == nil && format != .hls && format != .dash
|
||||||
|
}
|
||||||
|
|
||||||
// Online streams need resolution to be shown
|
// Online streams need resolution to be shown
|
||||||
let onlineVideoStreams: [Stream] = streams
|
let onlineVideoStreams: [Stream] = streams
|
||||||
@@ -95,6 +104,9 @@ extension QualitySelectorView {
|
|||||||
let allowSoftware = allowSoftwareDecodedFormats
|
let allowSoftware = allowSoftwareDecodedFormats
|
||||||
return videoStreams.filter { (stream: Stream) -> Bool in
|
return videoStreams.filter { (stream: Stream) -> Bool in
|
||||||
if stream.url.isFileURL { return true }
|
if stream.url.isFileURL { return true }
|
||||||
|
// Media-source streams (no resolution metadata, nil codec) must
|
||||||
|
// not be misclassified as software-decoded and hidden
|
||||||
|
if stream.resolution == nil { return true }
|
||||||
if stream.isMuxed { return true }
|
if stream.isMuxed { return true }
|
||||||
if allowSoftware { return true }
|
if allowSoftware { return true }
|
||||||
return !requiresSoftwareDecode(stream.videoCodec)
|
return !requiresSoftwareDecode(stream.videoCodec)
|
||||||
@@ -105,6 +117,7 @@ extension QualitySelectorView {
|
|||||||
if allowSoftwareDecodedFormats { return [] }
|
if allowSoftwareDecodedFormats { return [] }
|
||||||
return videoStreams.filter { (stream: Stream) -> Bool in
|
return videoStreams.filter { (stream: Stream) -> Bool in
|
||||||
if stream.url.isFileURL { return false }
|
if stream.url.isFileURL { return false }
|
||||||
|
if stream.resolution == nil { return false }
|
||||||
if stream.isMuxed { return false }
|
if stream.isMuxed { return false }
|
||||||
return requiresSoftwareDecode(stream.videoCodec)
|
return requiresSoftwareDecode(stream.videoCodec)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user