2022-01-10 02:53:15 +00:00
using System ;
2022-01-23 16:37:52 +00:00
using System.Collections.Specialized ;
2022-01-10 02:53:15 +00:00
using System.IO ;
using System.Linq ;
2022-01-23 23:49:14 +00:00
using System.Runtime.Serialization ;
2022-01-10 02:53:15 +00:00
using System.Text.Json ;
using System.Threading.Tasks ;
using Jellyfin.Extensions.Json ;
using MediaBrowser.Model.Dlna ;
using MediaBrowser.Model.Dto ;
using MediaBrowser.Model.Entities ;
using MediaBrowser.Model.Session ;
using Microsoft.Extensions.Logging.Abstractions ;
using Moq ;
using Xunit ;
2022-03-18 21:19:02 +00:00
namespace Jellyfin.Model.Tests
2022-01-10 02:53:15 +00:00
{
public class StreamBuilderTests
{
[Theory]
// Chrome
2022-01-23 23:49:14 +00:00
[InlineData("Chrome", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-10-31 12:51:06 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("Chrome", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
2024-02-20 18:39:15 +00:00
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioCodecNotSupported, "Transcode")]
[InlineData("Chrome", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.SecondaryAudioNotSupported, "Transcode")]
2023-12-19 20:21:57 +00:00
[InlineData("Chrome", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported, "Remux")] // #6450
2024-02-12 14:34:26 +00:00
[InlineData("Chrome", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported | TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("Chrome", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-10 02:53:15 +00:00
// Firefox
2022-01-23 23:49:14 +00:00
[InlineData("Firefox", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-10-31 12:51:06 +00:00
[InlineData("Firefox", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Firefox", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("Firefox", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
2024-02-20 18:39:15 +00:00
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioCodecNotSupported, "Transcode")]
[InlineData("Firefox", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.SecondaryAudioNotSupported, "Transcode")]
2023-12-19 20:21:57 +00:00
[InlineData("Firefox", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported, "Remux")] // #6450
2024-02-12 14:34:26 +00:00
[InlineData("Firefox", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported | TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("Firefox", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-10 02:53:15 +00:00
// Safari
2022-01-23 23:49:14 +00:00
[InlineData("SafariNext", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
2022-02-19 17:02:41 +00:00
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
2022-01-10 02:53:15 +00:00
// AndroidPixel
2022-01-23 23:49:14 +00:00
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("AndroidPixel", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("AndroidPixel", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
2022-01-10 02:53:15 +00:00
// Yatse
2022-03-05 20:58:21 +00:00
[InlineData("Yatse", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-10-31 12:51:06 +00:00
[InlineData("Yatse", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Yatse", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
2022-03-05 20:58:21 +00:00
[InlineData("Yatse", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Yatse", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-10 02:53:15 +00:00
// RokuSSPlus
2022-03-05 20:58:21 +00:00
[InlineData("RokuSSPlus", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450 should be DirectPlay
2022-01-23 23:49:14 +00:00
[InlineData("RokuSSPlus", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("RokuSSPlus", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("RokuSSPlus", "mp4-hevc-ac3-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-10 02:53:15 +00:00
// JellyfinMediaPlayer
2022-03-05 20:58:21 +00:00
[InlineData("JellyfinMediaPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("JellyfinMediaPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("JellyfinMediaPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("JellyfinMediaPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)] // #6450
// Chrome-NoHLS
[InlineData("Chrome-NoHLS", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
2024-02-20 18:39:15 +00:00
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-10-31 12:51:06 +00:00
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome-NoHLS", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode", "http")]
2024-02-20 18:39:15 +00:00
[InlineData("Chrome-NoHLS", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioCodecNotSupported, "Transcode", "http")]
[InlineData("Chrome-NoHLS", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.SecondaryAudioNotSupported, "Transcode", "http")]
2023-12-19 20:21:57 +00:00
[InlineData("Chrome-NoHLS", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported, "Remux")] // #6450
2024-02-12 14:34:26 +00:00
[InlineData("Chrome-NoHLS", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported | TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("Chrome-NoHLS", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-10 02:53:15 +00:00
// TranscodeMedia
2022-02-19 17:02:41 +00:00
[InlineData("TranscodeMedia", "mp4-h264-aac-vtt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
2024-02-20 18:39:15 +00:00
[InlineData("TranscodeMedia", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
2022-02-19 17:02:41 +00:00
[InlineData("TranscodeMedia", "mp4-h264-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
2024-02-20 18:39:15 +00:00
[InlineData("TranscodeMedia", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-hevc-ac3-aacDef-srt-15200k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
2022-02-19 17:02:41 +00:00
[InlineData("TranscodeMedia", "mkv-av1-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-av1-vorbis-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "http")]
2022-01-10 02:53:15 +00:00
// DirectMedia
2022-03-05 20:58:21 +00:00
[InlineData("DirectMedia", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
2022-01-23 23:49:14 +00:00
[InlineData("DirectMedia", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("DirectMedia", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("DirectMedia", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
2022-01-10 02:53:15 +00:00
// LowBandwidth
2022-01-23 23:49:14 +00:00
[InlineData("LowBandwidth", "mp4-h264-aac-vtt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-h264-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
2022-01-10 02:53:15 +00:00
// Null
2022-01-23 23:49:14 +00:00
[InlineData("Null", "mp4-h264-aac-vtt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-h264-ac3-aac-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-h264-ac3-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-hevc-aac-srt-15200k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-hevc-ac3-aac-srt-15200k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-aac-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-ac3-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-vorbis-vtt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
2022-04-15 19:29:20 +00:00
// AndroidTV
[InlineData("AndroidTVExoPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
// Tizen 3 Stereo
[InlineData("Tizen3-stereo", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-dts-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-truehd-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen3-stereo", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
// Tizen 4 4K 5.1
[InlineData("Tizen4-4K-5.1", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-dts-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-truehd-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
2023-04-09 23:44:56 +00:00
public async Task BuildVideoItemSimple ( string deviceName , string mediaSource , PlayMethod ? playMethod , TranscodeReason why = default , string transcodeMode = "DirectStream" , string transcodeProtocol = "" )
2022-01-10 02:53:15 +00:00
{
2022-03-26 11:11:00 +00:00
var options = await GetMediaOptions ( deviceName , mediaSource ) ;
2022-01-23 16:37:52 +00:00
BuildVideoItemSimpleTest ( options , playMethod , why , transcodeMode , transcodeProtocol ) ;
}
[Theory]
// Chrome
2022-01-23 23:49:14 +00:00
[InlineData("Chrome", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450 <BUG: this is direct played>
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("Chrome", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
2023-01-22 19:05:37 +00:00
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioCodecNotSupported, "Transcode")]
2023-12-19 20:21:57 +00:00
[InlineData("Chrome", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported, "Remux")] // #6450
2024-02-12 14:34:26 +00:00
[InlineData("Chrome", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported | TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("Chrome", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 16:37:52 +00:00
// Firefox
2022-01-23 23:49:14 +00:00
[InlineData("Firefox", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("Firefox", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
2023-01-22 19:05:37 +00:00
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.AudioCodecNotSupported, "Transcode")]
2023-12-19 20:21:57 +00:00
[InlineData("Firefox", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported, "Remux")] // #6450
2024-02-12 14:34:26 +00:00
[InlineData("Firefox", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.ContainerNotSupported | TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("Firefox", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 16:37:52 +00:00
// Safari
2022-01-23 23:49:14 +00:00
[InlineData("SafariNext", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
2022-02-19 17:02:41 +00:00
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
2022-01-23 16:37:52 +00:00
// AndroidPixel
2022-01-23 23:49:14 +00:00
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
2022-01-23 16:37:52 +00:00
[InlineData("AndroidPixel", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("AndroidPixel", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
// Yatse
2022-03-05 20:58:21 +00:00
[InlineData("Yatse", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Yatse", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Yatse", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
2022-03-05 20:58:21 +00:00
[InlineData("Yatse", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
// RokuSSPlus
2022-03-05 20:58:21 +00:00
[InlineData("RokuSSPlus", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450 should be DirectPlay
[InlineData("RokuSSPlus", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-03-05 20:58:21 +00:00
[InlineData("RokuSSPlus", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
2022-01-23 16:37:52 +00:00
// JellyfinMediaPlayer
2022-03-05 20:58:21 +00:00
[InlineData("JellyfinMediaPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-01-23 23:49:14 +00:00
[InlineData("JellyfinMediaPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)] // #6450
2022-04-15 19:29:20 +00:00
// AndroidTV
[InlineData("AndroidTVExoPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("AndroidTVExoPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
// Tizen 3 Stereo
[InlineData("Tizen3-stereo", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-h264-dts-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mp4-hevc-truehd-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen3-stereo", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen3-stereo", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
// Tizen 4 4K 5.1
[InlineData("Tizen4-4K-5.1", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-h264-dts-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mp4-hevc-truehd-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("Tizen4-4K-5.1", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
2023-04-09 23:44:56 +00:00
public async Task BuildVideoItemWithFirstExplicitStream ( string deviceName , string mediaSource , PlayMethod ? playMethod , TranscodeReason why = default , string transcodeMode = "DirectStream" , string transcodeProtocol = "" )
2022-01-23 16:37:52 +00:00
{
2022-03-26 11:11:00 +00:00
var options = await GetMediaOptions ( deviceName , mediaSource ) ;
2022-01-23 16:37:52 +00:00
options . AudioStreamIndex = 1 ;
2022-01-23 23:49:14 +00:00
options . SubtitleStreamIndex = options . MediaSources [ 0 ] . MediaStreams . Count - 1 ;
var streamInfo = BuildVideoItemSimpleTest ( options , playMethod , why , transcodeMode , transcodeProtocol ) ;
Assert . Equal ( streamInfo ? . AudioStreamIndex , options . AudioStreamIndex ) ;
Assert . Equal ( streamInfo ? . SubtitleStreamIndex , options . SubtitleStreamIndex ) ;
2022-01-23 16:37:52 +00:00
}
[Theory]
// Chrome
2022-10-31 12:51:06 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2023-12-20 19:38:01 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aac-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2022-01-23 23:49:14 +00:00
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
2023-01-22 19:05:37 +00:00
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.SecondaryAudioNotSupported, "Transcode")]
2022-01-23 16:37:52 +00:00
// Firefox
2022-10-31 12:51:06 +00:00
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2023-12-20 19:38:01 +00:00
[InlineData("Firefox", "mp4-h264-ac3-aac-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-01-22 19:05:37 +00:00
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported | TranscodeReason.SecondaryAudioNotSupported, "Transcode")]
2022-01-23 16:37:52 +00:00
// Yatse
2022-10-31 12:51:06 +00:00
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2023-12-20 19:38:01 +00:00
[InlineData("Yatse", "mp4-h264-ac3-aac-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2022-10-31 12:51:06 +00:00
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")] // #6450
2022-01-23 16:37:52 +00:00
// RokuSSPlus
2022-03-05 20:58:21 +00:00
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
2022-04-04 11:45:45 +00:00
// no streams
[InlineData("Chrome", "no-streams", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")] // #6450
2022-04-15 19:29:20 +00:00
// AndroidTV
[InlineData("AndroidTVExoPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("AndroidTVExoPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
// Tizen 3 Stereo
2023-12-20 19:36:25 +00:00
[InlineData("Tizen3-stereo", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-12-20 19:38:01 +00:00
[InlineData("Tizen3-stereo", "mp4-h264-ac3-aac-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-12-20 19:36:25 +00:00
[InlineData("Tizen3-stereo", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2022-04-15 19:29:20 +00:00
// Tizen 4 4K 5.1
2023-12-20 19:36:25 +00:00
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-12-20 19:38:01 +00:00
[InlineData("Tizen4-4K-5.1", "mp4-h264-ac3-aac-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-12-20 19:36:25 +00:00
[InlineData("Tizen4-4K-5.1", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.SecondaryAudioNotSupported, "Remux")]
2023-04-09 23:44:56 +00:00
public async Task BuildVideoItemWithDirectPlayExplicitStreams ( string deviceName , string mediaSource , PlayMethod ? playMethod , TranscodeReason why = default , string transcodeMode = "DirectStream" , string transcodeProtocol = "" )
2022-01-23 16:37:52 +00:00
{
2022-03-26 11:11:00 +00:00
var options = await GetMediaOptions ( deviceName , mediaSource ) ;
2022-01-23 23:49:14 +00:00
var streamCount = options . MediaSources [ 0 ] . MediaStreams . Count ;
2022-04-04 11:45:45 +00:00
if ( streamCount > 0 )
{
options . AudioStreamIndex = streamCount - 2 ;
options . SubtitleStreamIndex = streamCount - 1 ;
}
2022-01-23 23:49:14 +00:00
var streamInfo = BuildVideoItemSimpleTest ( options , playMethod , why , transcodeMode , transcodeProtocol ) ;
Assert . Equal ( streamInfo ? . AudioStreamIndex , options . AudioStreamIndex ) ;
Assert . Equal ( streamInfo ? . SubtitleStreamIndex , options . SubtitleStreamIndex ) ;
2022-01-23 16:37:52 +00:00
}
2022-03-26 11:11:00 +00:00
private StreamInfo ? BuildVideoItemSimpleTest ( MediaOptions options , PlayMethod ? playMethod , TranscodeReason why , string transcodeMode , string transcodeProtocol )
2022-01-23 16:37:52 +00:00
{
if ( string . IsNullOrEmpty ( transcodeProtocol ) )
{
2022-02-19 17:02:41 +00:00
transcodeProtocol = playMethod = = PlayMethod . DirectStream ? "http" : "HLS.ts" ;
2022-01-23 16:37:52 +00:00
}
var builder = GetStreamBuilder ( ) ;
2022-01-10 02:53:15 +00:00
2022-03-26 11:11:00 +00:00
var streamInfo = builder . GetOptimalVideoStream ( options ) ;
Assert . NotNull ( streamInfo ) ;
2022-01-10 02:53:15 +00:00
2022-12-05 14:01:13 +00:00
if ( playMethod is not null )
2022-01-10 02:53:15 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . Equal ( playMethod , streamInfo . PlayMethod ) ;
2022-01-10 02:53:15 +00:00
}
2022-03-26 11:11:00 +00:00
Assert . Equal ( why , streamInfo . TranscodeReasons ) ;
2022-01-23 16:37:52 +00:00
var audioStreamIndexInput = options . AudioStreamIndex ;
2022-03-26 11:11:00 +00:00
var targetVideoStream = streamInfo . TargetVideoStream ;
var targetAudioStream = streamInfo . TargetAudioStream ;
2022-01-10 02:53:15 +00:00
2022-03-26 11:11:00 +00:00
var mediaSource = options . MediaSources . First ( source = > source . Id = = streamInfo . MediaSourceId ) ;
2022-01-23 16:37:52 +00:00
Assert . NotNull ( mediaSource ) ;
var videoStreams = mediaSource . MediaStreams . Where ( stream = > stream . Type = = MediaStreamType . Video ) ;
var audioStreams = mediaSource . MediaStreams . Where ( stream = > stream . Type = = MediaStreamType . Audio ) ;
2022-05-16 00:22:13 +00:00
// TODO: Check AudioStreamIndex vs options.AudioStreamIndex
2022-01-23 16:37:52 +00:00
var inputAudioStream = mediaSource . GetDefaultAudioStream ( audioStreamIndexInput ? ? mediaSource . DefaultAudioStreamIndex ) ;
2022-03-26 11:11:00 +00:00
var uri = ParseUri ( streamInfo ) ;
2022-01-10 02:53:15 +00:00
if ( playMethod = = PlayMethod . DirectPlay )
{
2022-05-16 00:22:13 +00:00
// Check expected container
2022-01-23 16:37:52 +00:00
var containers = ContainerProfile . SplitValue ( mediaSource . Container ) ;
2022-05-16 00:22:13 +00:00
// TODO: Test transcode too
2022-01-23 23:49:14 +00:00
// Assert.Contains(uri.Extension, containers);
2022-01-10 02:53:15 +00:00
2022-05-16 00:22:13 +00:00
// Check expected video codec (1)
2023-07-29 19:35:38 +00:00
Assert . Contains ( targetVideoStream ? . Codec , streamInfo . TargetVideoCodec ) ;
2022-03-26 11:11:00 +00:00
Assert . Single ( streamInfo . TargetVideoCodec ) ;
2022-01-23 16:37:52 +00:00
2022-05-16 00:22:13 +00:00
// Check expected audio codecs (1)
2023-07-29 19:35:38 +00:00
Assert . Contains ( targetAudioStream ? . Codec , streamInfo . TargetAudioCodec ) ;
2022-03-26 11:11:00 +00:00
Assert . Single ( streamInfo . TargetAudioCodec ) ;
2022-01-23 23:49:14 +00:00
// Assert.Single(val.AudioCodecs);
2022-01-10 02:53:15 +00:00
2022-11-23 14:58:11 +00:00
if ( transcodeMode . Equals ( "DirectStream" , StringComparison . Ordinal ) )
2022-01-23 23:49:14 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . Equal ( streamInfo . Container , uri . Extension ) ;
2022-01-23 23:49:14 +00:00
}
2022-01-23 16:37:52 +00:00
}
else if ( playMethod = = PlayMethod . DirectStream | | playMethod = = PlayMethod . Transcode )
2022-01-10 02:53:15 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . NotNull ( streamInfo . Container ) ;
Assert . NotEmpty ( streamInfo . VideoCodecs ) ;
Assert . NotEmpty ( streamInfo . AudioCodecs ) ;
2022-01-23 16:37:52 +00:00
2022-05-16 00:22:13 +00:00
// Check expected container (todo: this could be a test param)
2022-11-23 14:58:11 +00:00
if ( transcodeProtocol . Equals ( "http" , StringComparison . Ordinal ) )
2022-01-10 02:53:15 +00:00
{
2022-01-23 16:37:52 +00:00
// Assert.Equal("webm", val.Container);
2022-03-26 11:11:00 +00:00
Assert . Equal ( streamInfo . Container , uri . Extension ) ;
2022-01-23 16:37:52 +00:00
Assert . Equal ( "stream" , uri . Filename ) ;
2022-03-26 11:11:00 +00:00
Assert . Equal ( "http" , streamInfo . SubProtocol ) ;
2022-01-23 16:37:52 +00:00
}
2022-11-23 14:58:11 +00:00
else if ( transcodeProtocol . Equals ( "HLS.mp4" , StringComparison . Ordinal ) )
2022-02-19 17:02:41 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . Equal ( "mp4" , streamInfo . Container ) ;
2022-02-19 17:02:41 +00:00
Assert . Equal ( "m3u8" , uri . Extension ) ;
Assert . Equal ( "master" , uri . Filename ) ;
2022-03-26 11:11:00 +00:00
Assert . Equal ( "hls" , streamInfo . SubProtocol ) ;
2022-02-19 17:02:41 +00:00
}
2022-01-23 16:37:52 +00:00
else
{
2022-03-26 11:11:00 +00:00
Assert . Equal ( "ts" , streamInfo . Container ) ;
2022-01-23 16:37:52 +00:00
Assert . Equal ( "m3u8" , uri . Extension ) ;
Assert . Equal ( "master" , uri . Filename ) ;
2022-03-26 11:11:00 +00:00
Assert . Equal ( "hls" , streamInfo . SubProtocol ) ;
2022-01-23 16:37:52 +00:00
}
// Full transcode
2022-11-23 14:58:11 +00:00
if ( transcodeMode . Equals ( "Transcode" , StringComparison . Ordinal ) )
2022-01-23 16:37:52 +00:00
{
2022-03-26 11:11:00 +00:00
if ( ( streamInfo . TranscodeReasons & ( StreamBuilder . ContainerReasons | TranscodeReason . DirectPlayError ) ) = = 0 )
2022-01-23 16:37:52 +00:00
{
2022-01-23 23:49:14 +00:00
Assert . All (
videoStreams ,
2022-03-26 11:11:00 +00:00
stream = > Assert . DoesNotContain ( stream . Codec , streamInfo . VideoCodecs ) ) ;
2022-01-23 16:37:52 +00:00
}
2022-01-10 02:53:15 +00:00
2022-03-26 11:11:00 +00:00
// TODO: fill out tests here
2022-01-10 02:53:15 +00:00
}
2022-01-23 16:37:52 +00:00
// DirectStream and Remux
2022-01-10 02:53:15 +00:00
else
{
2022-05-16 00:22:13 +00:00
// Check expected video codec (1)
2023-07-29 19:35:38 +00:00
Assert . Contains ( targetVideoStream ? . Codec , streamInfo . TargetVideoCodec ) ;
2022-03-26 11:11:00 +00:00
Assert . Single ( streamInfo . TargetVideoCodec ) ;
2022-01-10 02:53:15 +00:00
2022-11-23 14:58:11 +00:00
if ( transcodeMode . Equals ( "DirectStream" , StringComparison . Ordinal ) )
2022-01-23 16:37:52 +00:00
{
2022-05-16 00:22:13 +00:00
// Check expected audio codecs (1)
2023-07-29 19:35:38 +00:00
if ( targetAudioStream ? . IsExternal = = false )
2022-01-23 16:37:52 +00:00
{
2022-03-26 11:11:00 +00:00
// Check expected audio codecs (1)
2023-12-19 20:21:57 +00:00
Assert . DoesNotContain ( targetAudioStream . Codec , streamInfo . AudioCodecs ) ;
2022-01-23 16:37:52 +00:00
}
}
2022-11-23 14:58:11 +00:00
else if ( transcodeMode . Equals ( "Remux" , StringComparison . Ordinal ) )
2022-01-23 16:37:52 +00:00
{
2022-05-16 00:22:13 +00:00
// Check expected audio codecs (1)
2023-07-29 19:35:38 +00:00
Assert . Contains ( targetAudioStream ? . Codec , streamInfo . AudioCodecs ) ;
2022-03-26 11:11:00 +00:00
Assert . Single ( streamInfo . AudioCodecs ) ;
2022-01-23 16:37:52 +00:00
}
2022-01-10 02:53:15 +00:00
2022-05-16 00:22:13 +00:00
// Video details
2022-01-23 16:37:52 +00:00
var videoStream = targetVideoStream ;
2022-03-26 11:11:00 +00:00
Assert . False ( streamInfo . EstimateContentLength ) ;
Assert . Equal ( TranscodeSeekInfo . Auto , streamInfo . TranscodeSeekInfo ) ;
2023-07-29 19:35:38 +00:00
Assert . Contains ( videoStream ? . Profile ? . ToLowerInvariant ( ) ? ? string . Empty , streamInfo . TargetVideoProfile ? . Split ( "," ) . Select ( s = > s . ToLowerInvariant ( ) ) ? ? Array . Empty < string > ( ) ) ;
Assert . Equal ( videoStream ? . Level , streamInfo . TargetVideoLevel ) ;
Assert . Equal ( videoStream ? . BitDepth , streamInfo . TargetVideoBitDepth ) ;
Assert . InRange ( streamInfo . VideoBitrate . GetValueOrDefault ( ) , videoStream ? . BitRate . GetValueOrDefault ( ) ? ? 0 , int . MaxValue ) ;
2022-01-23 16:37:52 +00:00
2022-05-16 00:22:13 +00:00
// Audio codec not supported
2022-03-05 20:58:21 +00:00
if ( ( why & TranscodeReason . AudioCodecNotSupported ) ! = 0 )
2022-01-23 16:37:52 +00:00
{
2022-05-16 00:22:13 +00:00
// Audio stream specified
2022-01-23 16:37:52 +00:00
if ( options . AudioStreamIndex > = 0 )
{
// TODO:fixme
2023-07-29 19:35:38 +00:00
if ( targetAudioStream ? . IsExternal = = false )
2022-01-23 16:37:52 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . DoesNotContain ( targetAudioStream . Codec , streamInfo . AudioCodecs ) ;
2022-01-23 16:37:52 +00:00
}
}
2022-05-16 00:22:13 +00:00
// Audio stream not specified
2022-01-23 16:37:52 +00:00
else
{
2024-02-20 18:32:54 +00:00
bool isDefault = targetAudioStream ? . IsDefault = = true ;
var language = targetAudioStream ? . Language ;
// Collect candidate audio streams
var candidateAudioStreams = audioStreams . Where ( stream = >
{
return isDefault ? stream . IsDefault : ( stream . Language = = language ) ;
} ) ;
Assert . All ( candidateAudioStreams , stream = >
2022-01-23 16:37:52 +00:00
{
if ( ! stream . IsExternal )
{
2022-03-26 11:11:00 +00:00
Assert . DoesNotContain ( stream . Codec , streamInfo . AudioCodecs ) ;
2022-01-23 16:37:52 +00:00
}
} ) ;
}
}
2022-01-10 02:53:15 +00:00
}
}
2022-12-05 14:00:20 +00:00
else if ( playMethod is null )
2022-01-10 02:53:15 +00:00
{
2022-03-26 11:11:00 +00:00
Assert . Null ( streamInfo . SubProtocol ) ;
2022-01-23 23:49:14 +00:00
Assert . Equal ( "stream" , uri . Filename ) ;
2022-01-10 02:53:15 +00:00
2022-03-26 11:11:00 +00:00
Assert . False ( streamInfo . EstimateContentLength ) ;
Assert . Equal ( TranscodeSeekInfo . Auto , streamInfo . TranscodeSeekInfo ) ;
2022-01-10 02:53:15 +00:00
}
2022-01-23 23:49:14 +00:00
2022-03-26 11:11:00 +00:00
return streamInfo ;
2022-01-10 02:53:15 +00:00
}
private static async ValueTask < T > TestData < T > ( string name )
{
var path = Path . Join ( "Test Data" , typeof ( T ) . Name + "-" + name + ".json" ) ;
2023-09-11 10:12:40 +00:00
using var stream = File . OpenRead ( path ) ;
var value = await JsonSerializer . DeserializeAsync < T > ( stream , JsonDefaults . Options ) ;
if ( value is not null )
{
return value ;
2022-01-10 02:53:15 +00:00
}
2023-09-11 10:12:40 +00:00
throw new SerializationException ( "Invalid test data: " + name ) ;
2022-01-10 02:53:15 +00:00
}
private StreamBuilder GetStreamBuilder ( )
{
var transcodeSupport = new Mock < ITranscoderSupport > ( ) ;
var logger = new NullLogger < StreamBuilderTests > ( ) ;
return new StreamBuilder ( transcodeSupport . Object , logger ) ;
}
2022-03-26 11:11:00 +00:00
private static async ValueTask < MediaOptions > GetMediaOptions ( string deviceProfile , params string [ ] sources )
2022-01-10 02:53:15 +00:00
{
var mediaSources = sources . Select ( src = > TestData < MediaSourceInfo > ( src ) )
. Select ( val = > val . Result )
. ToArray ( ) ;
var mediaSourceId = mediaSources [ 0 ] ? . Id ;
var dp = await TestData < DeviceProfile > ( deviceProfile ) ;
2022-03-26 11:11:00 +00:00
return new MediaOptions ( )
2022-01-10 02:53:15 +00:00
{
ItemId = new Guid ( "11D229B7-2D48-4B95-9F9B-49F6AB75E613" ) ,
MediaSourceId = mediaSourceId ,
MediaSources = mediaSources ,
DeviceId = "test-deviceId" ,
Profile = dp ,
2022-01-23 23:49:14 +00:00
AllowAudioStreamCopy = true ,
AllowVideoStreamCopy = true ,
2022-01-10 02:53:15 +00:00
} ;
}
2022-01-23 16:37:52 +00:00
private static ( string Path , NameValueCollection Query , string Filename , string Extension ) ParseUri ( StreamInfo val )
{
var href = val . ToUrl ( "media:" , "ACCESSTOKEN" ) . Split ( "?" , 2 ) ;
var path = href [ 0 ] ;
var queryString = href . ElementAtOrDefault ( 1 ) ;
var query = string . IsNullOrEmpty ( queryString ) ? System . Web . HttpUtility . ParseQueryString ( queryString ? ? string . Empty ) : new NameValueCollection ( ) ;
2022-03-18 21:19:02 +00:00
var filename = Path . GetFileNameWithoutExtension ( path ) ;
var extension = Path . GetExtension ( path ) ;
2022-01-23 16:37:52 +00:00
if ( extension . Length > 0 )
{
extension = extension . Substring ( 1 ) ;
}
return ( path , query , filename , extension ) ;
}
2022-01-10 02:53:15 +00:00
}
}