/// <summary> /// Gets the video stream information. /// </summary> /// <param name="serverId">The server identifier.</param> /// <param name="options">The options.</param> /// <returns>Task<StreamInfo>.</returns> public async Task <StreamInfo> GetVideoStreamInfo(string serverId, VideoOptions options) { var streamBuilder = new StreamBuilder(); var localItem = await _localAssetManager.GetLocalItem(serverId, options.ItemId); if (localItem != null) { var localMediaSource = localItem.Item.MediaSources[0]; // Use the local media source, unless a specific server media source was requested if (string.IsNullOrWhiteSpace(options.MediaSourceId) || string.Equals(localMediaSource.Id, options.MediaSourceId, StringComparison.OrdinalIgnoreCase)) { // Finally, check to make sure the local file is actually available at this time var fileExists = await _localAssetManager.FileExists(localMediaSource.Path).ConfigureAwait(false); if (fileExists) { options.MediaSources = localItem.Item.MediaSources; var result = streamBuilder.BuildVideoItem(options); result.PlayMethod = PlayMethod.DirectPlay; return(result); } } } return(streamBuilder.BuildVideoItem(options)); }
private void SetDeviceSpecificData(BaseItem item, MediaSourceInfo mediaSource, DeviceProfile profile, AuthorizationInfo auth, long?maxBitrate, long startTimeTicks, string mediaSourceId, int?audioStreamIndex, int?subtitleStreamIndex, int?maxAudioChannels, string playSessionId, string userId, bool enableDirectPlay, bool forceDirectPlayRemoteMediaSource, bool enableDirectStream, bool enableTranscoding, bool allowVideoStreamCopy, bool allowAudioStreamCopy) { var streamBuilder = new StreamBuilder(_mediaEncoder, Logger); var options = new VideoOptions { MediaSources = new List <MediaSourceInfo> { mediaSource }, Context = EncodingContext.Streaming, DeviceId = auth.DeviceId, ItemId = item.Id.ToString("N"), Profile = profile, MaxAudioChannels = maxAudioChannels }; if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase)) { options.MediaSourceId = mediaSourceId; options.AudioStreamIndex = audioStreamIndex; options.SubtitleStreamIndex = subtitleStreamIndex; } var user = _userManager.GetUserById(userId); if (!enableDirectPlay) { mediaSource.SupportsDirectPlay = false; } if (!enableDirectStream) { mediaSource.SupportsDirectStream = false; } if (!enableTranscoding) { mediaSource.SupportsTranscoding = false; } if (mediaSource.SupportsDirectPlay) { if (mediaSource.IsRemote && forceDirectPlayRemoteMediaSource) { } else { var supportsDirectStream = mediaSource.SupportsDirectStream; // Dummy this up to fool StreamBuilder mediaSource.SupportsDirectStream = true; options.MaxBitrate = maxBitrate; if (item is Audio) { if (!user.Policy.EnableAudioPlaybackTranscoding) { options.ForceDirectPlay = true; } } else if (item is Video) { if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) { options.ForceDirectPlay = true; } } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectPlay = false; } // Set this back to what it was mediaSource.SupportsDirectStream = supportsDirectStream; if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } } if (mediaSource.SupportsDirectStream) { options.MaxBitrate = GetMaxBitrate(maxBitrate); if (item is Audio) { if (!user.Policy.EnableAudioPlaybackTranscoding) { options.ForceDirectStream = true; } } else if (item is Video) { if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) { options.ForceDirectStream = true; } } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectStream = false; } if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } if (mediaSource.SupportsTranscoding) { options.MaxBitrate = GetMaxBitrate(maxBitrate); // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo != null) { streamInfo.PlaySessionId = playSessionId; if (streamInfo.PlayMethod == PlayMethod.Transcode) { streamInfo.StartPositionTicks = startTimeTicks; mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-'); if (!allowVideoStreamCopy) { mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false"; } if (!allowAudioStreamCopy) { mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false"; } mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; } // Do this after the above so that StartPositionTicks is set SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } }
private void SetDeviceSpecificData( BaseItem item, MediaSourceInfo mediaSource, DeviceProfile profile, AuthorizationInfo auth, long?maxBitrate, long startTimeTicks, string mediaSourceId, int?audioStreamIndex, int?subtitleStreamIndex, int?maxAudioChannels, string playSessionId, Guid userId, bool enableDirectPlay, bool forceDirectPlayRemoteMediaSource, bool enableDirectStream, bool enableTranscoding, bool allowVideoStreamCopy, bool allowAudioStreamCopy) { var streamBuilder = new StreamBuilder(_mediaEncoder, Logger); var options = new VideoOptions { MediaSources = new[] { mediaSource }, Context = EncodingContext.Streaming, DeviceId = auth.DeviceId, ItemId = item.Id, Profile = profile, MaxAudioChannels = maxAudioChannels }; if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase)) { options.MediaSourceId = mediaSourceId; options.AudioStreamIndex = audioStreamIndex; options.SubtitleStreamIndex = subtitleStreamIndex; } var user = _userManager.GetUserById(userId); if (!enableDirectPlay) { mediaSource.SupportsDirectPlay = false; } if (!enableDirectStream) { mediaSource.SupportsDirectStream = false; } if (!enableTranscoding) { mediaSource.SupportsTranscoding = false; } if (item is Audio) { Logger.LogInformation("User policy for {0}. EnableAudioPlaybackTranscoding: {1}", user.Name, user.Policy.EnableAudioPlaybackTranscoding); } else { Logger.LogInformation("User policy for {0}. EnablePlaybackRemuxing: {1} EnableVideoPlaybackTranscoding: {2} EnableAudioPlaybackTranscoding: {3}", user.Name, user.Policy.EnablePlaybackRemuxing, user.Policy.EnableVideoPlaybackTranscoding, user.Policy.EnableAudioPlaybackTranscoding); } // Beginning of Playback Determination: Attempt DirectPlay first if (mediaSource.SupportsDirectPlay) { if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding) { mediaSource.SupportsDirectPlay = false; } else { var supportsDirectStream = mediaSource.SupportsDirectStream; // Dummy this up to fool StreamBuilder mediaSource.SupportsDirectStream = true; options.MaxBitrate = maxBitrate; if (item is Audio) { if (!user.Policy.EnableAudioPlaybackTranscoding) { options.ForceDirectPlay = true; } } else if (item is Video) { if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) { options.ForceDirectPlay = true; } } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectPlay = false; } // Set this back to what it was mediaSource.SupportsDirectStream = supportsDirectStream; if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } } if (mediaSource.SupportsDirectStream) { if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding) { mediaSource.SupportsDirectStream = false; } else { options.MaxBitrate = GetMaxBitrate(maxBitrate, user); if (item is Audio) { if (!user.Policy.EnableAudioPlaybackTranscoding) { options.ForceDirectStream = true; } } else if (item is Video) { if (!user.Policy.EnableAudioPlaybackTranscoding && !user.Policy.EnableVideoPlaybackTranscoding && !user.Policy.EnablePlaybackRemuxing) { options.ForceDirectStream = true; } } // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectStream = false; } if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } } if (mediaSource.SupportsTranscoding) { options.MaxBitrate = GetMaxBitrate(maxBitrate, user); // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (mediaSource.IsRemote && user.Policy.ForceRemoteSourceTranscoding) { if (streamInfo != null) { streamInfo.PlaySessionId = playSessionId; streamInfo.StartPositionTicks = startTimeTicks; mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-'); mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false"; if (!allowAudioStreamCopy) { mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false"; } mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; // Do this after the above so that StartPositionTicks is set SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } else { if (streamInfo != null) { streamInfo.PlaySessionId = playSessionId; if (streamInfo.PlayMethod == PlayMethod.Transcode) { streamInfo.StartPositionTicks = startTimeTicks; mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-'); if (!allowVideoStreamCopy) { mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false"; } if (!allowAudioStreamCopy) { mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false"; } mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; } if (!allowAudioStreamCopy) { mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false"; } mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; // Do this after the above so that StartPositionTicks is set SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } } foreach (var attachment in mediaSource.MediaAttachments) { attachment.DeliveryUrl = string.Format( CultureInfo.InvariantCulture, "{0}/Videos/{1}/{2}/Attachments/{3}", ServerConfigurationManager.Configuration.BaseUrl, item.Id, mediaSource.Id, attachment.Index); } }
private void SetDeviceSpecificData(BaseItem item, MediaSourceInfo mediaSource, DeviceProfile profile, AuthorizationInfo auth, int?maxBitrate, long startTimeTicks, string mediaSourceId, int?audioStreamIndex, int?subtitleStreamIndex, string playSessionId) { var streamBuilder = new StreamBuilder(Logger); var options = new VideoOptions { MediaSources = new List <MediaSourceInfo> { mediaSource }, Context = EncodingContext.Streaming, DeviceId = auth.DeviceId, ItemId = item.Id.ToString("N"), Profile = profile }; if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase)) { options.MediaSourceId = mediaSourceId; options.AudioStreamIndex = audioStreamIndex; options.SubtitleStreamIndex = subtitleStreamIndex; } if (mediaSource.SupportsDirectPlay) { var supportsDirectStream = mediaSource.SupportsDirectStream; // Dummy this up to fool StreamBuilder mediaSource.SupportsDirectStream = true; options.MaxBitrate = maxBitrate; // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectPlay = false; } // Set this back to what it was mediaSource.SupportsDirectStream = supportsDirectStream; if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } if (mediaSource.SupportsDirectStream) { options.MaxBitrate = GetMaxBitrate(maxBitrate); // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo == null || !streamInfo.IsDirectStream) { mediaSource.SupportsDirectStream = false; } if (streamInfo != null) { SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } } if (mediaSource.SupportsTranscoding) { options.MaxBitrate = GetMaxBitrate(maxBitrate); // The MediaSource supports direct stream, now test to see if the client supports it var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ? streamBuilder.BuildAudioItem(options) : streamBuilder.BuildVideoItem(options); if (streamInfo != null) { streamInfo.PlaySessionId = playSessionId; SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token); } if (streamInfo != null && streamInfo.PlayMethod == PlayMethod.Transcode) { streamInfo.StartPositionTicks = startTimeTicks; mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-'); mediaSource.TranscodingContainer = streamInfo.Container; mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol; } } }
public void TestVideoProfile() { var profile = new AndroidProfile(true, false, new[] { "high", "baseline", "constrained baseline" }); var builder = new StreamBuilder(); var mediaSources = new List <MediaSourceInfo> { new MediaSourceInfo { Bitrate = 6200000, Container = "mkv", Path = "\\server\\test.mkv", Protocol = Model.MediaInfo.MediaProtocol.File, RunTimeTicks = TimeSpan.FromMinutes(60).Ticks, VideoType = VideoType.VideoFile, Type = MediaSourceType.Default, MediaStreams = new List <MediaStream> { new MediaStream { Codec = "H264", Type = MediaStreamType.Video, Profile = "High", IsCabac = true }, new MediaStream { Codec = "AC3", Type = MediaStreamType.Audio } } } }; var options = new VideoOptions { Context = EncodingContext.Streaming, DeviceId = Guid.NewGuid().ToString(), ItemId = Guid.NewGuid().ToString(), Profile = profile, MediaSources = mediaSources }; var streamInfo = builder.BuildVideoItem(options); var url = streamInfo.ToDlnaUrl("http://localhost:8096"); var containsHighProfile = url.IndexOf(";high;", StringComparison.OrdinalIgnoreCase) != -1; var containsBaseline = url.IndexOf(";baseline;", StringComparison.OrdinalIgnoreCase) != -1; Assert.IsTrue(containsHighProfile); Assert.IsFalse(containsBaseline); var isHls = url.IndexOf("master.m3u8?", StringComparison.OrdinalIgnoreCase) != -1; Assert.IsTrue(isHls); }