private void SetDeviceSpecificData(string itemId,
                                           PlaybackInfoResponse result,
                                           DeviceProfile profile,
                                           AuthorizationInfo auth,
                                           int?maxBitrate,
                                           long startTimeTicks,
                                           string mediaSourceId,
                                           int?audioStreamIndex,
                                           int?subtitleStreamIndex,
                                           int?maxAudioChannels,
                                           string userId)
        {
            var item = _libraryManager.GetItemById(itemId);

            foreach (var mediaSource in result.MediaSources)
            {
                SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, maxAudioChannels, result.PlaySessionId, userId);
            }

            SortMediaSources(result, maxBitrate);
        }
示例#2
0
        /// <summary>
        /// Gets the audio stream information.
        /// </summary>
        /// <param name="serverId">The server identifier.</param>
        /// <param name="options">The options.</param>
        /// <param name="isOffline">if set to <c>true</c> [is offline].</param>
        /// <param name="apiClient">The API client.</param>
        /// <returns>Task&lt;StreamInfo&gt;.</returns>
        public async Task <StreamInfo> GetAudioStreamInfo(string serverId, AudioOptions options, bool isOffline, IApiClient apiClient)
        {
            var streamBuilder = GetStreamBuilder();

            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.BuildAudioItem(options);
                        if (result == null)
                        {
                            _logger.Warn("LocalItem returned no compatible streams. Will dummy up a StreamInfo to force it to direct play.");
                            var mediaSource = localItem.Item.MediaSources.First();
                            result = GetForcedDirectPlayStreamInfo(DlnaProfileType.Audio, options, mediaSource);
                        }
                        result.PlayMethod = PlayMethod.DirectPlay;
                        return(result);
                    }
                }
            }

            PlaybackInfoResponse playbackInfo = null;
            string playSessionId = null;

            if (!isOffline)
            {
                playbackInfo = await apiClient.GetPlaybackInfo(new PlaybackInfoRequest
                {
                    Id     = options.ItemId,
                    UserId = apiClient.CurrentUserId,
                    MaxStreamingBitrate = options.MaxBitrate,
                    MediaSourceId       = options.MediaSourceId
                }).ConfigureAwait(false);

                if (playbackInfo.ErrorCode.HasValue)
                {
                    throw new PlaybackException {
                              ErrorCode = playbackInfo.ErrorCode.Value
                    };
                }

                options.MediaSources = playbackInfo.MediaSources;
                playSessionId        = playbackInfo.PlaySessionId;
            }

            var streamInfo = streamBuilder.BuildAudioItem(options);

            EnsureSuccess(streamInfo);

            if (!isOffline)
            {
                var liveMediaSource = await GetLiveStreamInfo(playSessionId, streamInfo.MediaSource, options, apiClient).ConfigureAwait(false);

                if (liveMediaSource != null)
                {
                    options.MediaSources = new List <MediaSourceInfo> {
                        liveMediaSource
                    };
                    streamInfo = GetStreamBuilder().BuildAudioItem(options);
                    EnsureSuccess(streamInfo);
                }
            }

            if (playbackInfo != null)
            {
                streamInfo.AllMediaSources = playbackInfo.MediaSources.ToList();
                streamInfo.PlaySessionId   = playbackInfo.PlaySessionId;
            }

            return(streamInfo);
        }
示例#3
0
        /// <summary>
        /// Get playback info.
        /// </summary>
        /// <param name="id">Item id.</param>
        /// <param name="userId">User Id.</param>
        /// <param name="mediaSourceId">Media source id.</param>
        /// <param name="liveStreamId">Live stream id.</param>
        /// <returns>A <see cref="Task"/> containing the <see cref="PlaybackInfoResponse"/>.</returns>
        public async Task <PlaybackInfoResponse> GetPlaybackInfo(
            Guid id,
            Guid?userId,
            string?mediaSourceId = null,
            string?liveStreamId  = null)
        {
            var user = userId.HasValue && !userId.Equals(Guid.Empty)
                ? _userManager.GetUserById(userId.Value)
                : null;
            var item   = _libraryManager.GetItemById(id);
            var result = new PlaybackInfoResponse();

            MediaSourceInfo[] mediaSources;
            if (string.IsNullOrWhiteSpace(liveStreamId))
            {
                // TODO (moved from MediaBrowser.Api) handle supportedLiveMediaTypes?
                var mediaSourcesList = await _mediaSourceManager.GetPlaybackMediaSources(item, user, true, true, CancellationToken.None).ConfigureAwait(false);

                if (string.IsNullOrWhiteSpace(mediaSourceId))
                {
                    mediaSources = mediaSourcesList.ToArray();
                }
                else
                {
                    mediaSources = mediaSourcesList
                                   .Where(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase))
                                   .ToArray();
                }
            }
            else
            {
                var mediaSource = await _mediaSourceManager.GetLiveStream(liveStreamId, CancellationToken.None).ConfigureAwait(false);

                mediaSources = new[] { mediaSource };
            }

            if (mediaSources.Length == 0)
            {
                result.MediaSources = Array.Empty <MediaSourceInfo>();

                result.ErrorCode ??= PlaybackErrorCode.NoCompatibleStream;
            }
            else
            {
                // Since we're going to be setting properties on MediaSourceInfos that come out of _mediaSourceManager, we should clone it
                // Should we move this directly into MediaSourceManager?
                var mediaSourcesClone = JsonSerializer.Deserialize <MediaSourceInfo[]>(JsonSerializer.SerializeToUtf8Bytes(mediaSources));
                if (mediaSourcesClone != null)
                {
                    result.MediaSources = mediaSourcesClone;
                }

                result.PlaySessionId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
            }

            if (item is IHasCanReplay replayable)
            {
                if (!replayable.CanReplay(user))
                {
                    result.ErrorCode ??= PlaybackErrorCode.NotAllowed;
                }
            }

            return(result);
        }