/// <summary>
        /// Gets the video stream information.
        /// </summary>
        /// <param name="serverId">The server identifier.</param>
        /// <param name="options">The options.</param>
        /// <returns>Task&lt;StreamInfo&gt;.</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));
        }
Exemplo n.º 2
0
        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);
                }
            }
        }
Exemplo n.º 3
0
        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);
            }
        }
Exemplo n.º 4
0
        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;
                }
            }
        }
Exemplo n.º 5
0
        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);
        }