Пример #1
0
        public static Task <Stream> ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id, int offset)
        {
            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);

            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null);

            if (item == null)
            {
                throw new NotFoundException("RetrieveFile: no media item found");
            }

            var files = ResourceAccessUtils.GetResourcePaths(item);
            var ra    = GetResourceAccessor(files[offset]);
            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                throw new InternalServerException("RetrieveFile: failed to create IFileSystemResourceAccessor");
            }

            return(fsra.OpenReadAsync());
        }
Пример #2
0
        internal static WebTVSeasonBasic TVSeasonBasic(IOwinContext context, MediaItem item, Guid?showId = null)
        {
            Guid?       user = ResourceAccessUtils.GetUser(context);
            ISet <Guid> necessaryMIATypespisodes = new HashSet <Guid>();

            necessaryMIATypespisodes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypespisodes.Add(EpisodeAspect.ASPECT_ID);

            IFilter unwatchedEpisodeFilter = BooleanCombinationFilter.CombineFilters(BooleanOperator.And,
                                                                                     new RelationshipFilter(EpisodeAspect.ROLE_EPISODE, SeasonAspect.ROLE_SEASON, item.MediaItemId),
                                                                                     new RelationalUserDataFilter(user.Value, UserDataKeysKnown.KEY_PLAY_PERCENTAGE, RelationalOperator.LT, UserDataKeysKnown.GetSortablePlayPercentageString(100), true));

            int unwatchedCount = MediaLibraryAccess.CountMediaItems(context, necessaryMIATypespisodes, unwatchedEpisodeFilter);

            GetShowId(item, ref showId);

            var mediaAspect    = item.GetAspect(MediaAspect.Metadata);
            var seasonAspect   = item.GetAspect(SeasonAspect.Metadata);
            var importerAspect = item.GetAspect(ImporterAspect.Metadata);

            DateTime?firstAired = mediaAspect.GetAttributeValue <DateTime?>(MediaAspect.ATTR_RECORDINGTIME);

            return(new WebTVSeasonBasic
            {
                Title = mediaAspect.GetAttributeValue <string>(MediaAspect.ATTR_TITLE),
                Id = item.MediaItemId.ToString(),
                ShowId = showId.HasValue ? showId.Value.ToString() : null,
                SeasonNumber = seasonAspect.GetAttributeValue <int>(SeasonAspect.ATTR_SEASON),
                EpisodeCount = seasonAspect.GetAttributeValue <int>(SeasonAspect.ATTR_AVAILABLE_EPISODES),
                UnwatchedEpisodeCount = unwatchedCount,
                DateAdded = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                Year = firstAired.HasValue ? firstAired.Value.Year : 0,
            });
        }
Пример #3
0
        public static Task <IList <string> > ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id)
        {
            if (id == null)
            {
                throw new BadRequestException("GetPathList: id is null");
            }

            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);

            ISet <Guid> optionalMIATypes = new HashSet <Guid>();

            optionalMIATypes.Add(VideoAspect.ASPECT_ID);
            optionalMIATypes.Add(MovieAspect.ASPECT_ID);
            optionalMIATypes.Add(SeriesAspect.ASPECT_ID);
            optionalMIATypes.Add(AudioAspect.ASPECT_ID);
            optionalMIATypes.Add(ImageAspect.ASPECT_ID);

            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, optionalMIATypes);

            if (item == null)
            {
                throw new NotFoundException(String.Format("GetPathList: No MediaItem found with id: {0}", id));
            }

            var output = ResourceAccessUtils.GetPaths(item);

            return(System.Threading.Tasks.Task.FromResult(output));
        }
Пример #4
0
        public static async Task <WebStringResult> ProcessAsync(IOwinContext context, string identifier, string profileName, long startPosition)
        {
            if (identifier == null)
            {
                throw new BadRequestException("InitStream: identifier is null");
            }
            if (profileName == null)
            {
                throw new BadRequestException("InitStream: profileName is null");
            }

            StreamItem streamItem = await StreamControl.GetStreamItemAsync(identifier);

            if (streamItem == null)
            {
                throw new BadRequestException(string.Format("StartStream: Unknown identifier: {0}", identifier));
            }

            // Prefer getting profile by name
            EndPointProfile profile = ProfileManager.Profiles.Values.FirstOrDefault(p => p.Name == profileName);

            // If no ptofile with the specified name, see if there's one with a matching id
            if (profile == null && !ProfileManager.Profiles.TryGetValue(profileName, out profile))
            {
                throw new BadRequestException(string.Format("StartStream: Unknown profile: {0}", profileName));
            }

            streamItem.Profile = profile;
            // Seeking is not supported in live streams
            streamItem.StartPosition = streamItem.RequestedMediaItem is LiveTvMediaItem ? 0 : startPosition;

            Guid?userId = ResourceAccessUtils.GetUser(context);

            streamItem.TranscoderObject = new ProfileMediaItem(identifier, profile, streamItem.IsLive);
            await streamItem.TranscoderObject.Initialize(userId, streamItem.RequestedMediaItem, null);

            if (streamItem.TranscoderObject.TranscodingParameter is VideoTranscoding vt)
            {
                vt.HlsBaseUrl = string.Format("RetrieveStream?identifier={0}&hls=", identifier);
            }

            await StreamControl.StartStreamingAsync(identifier, startPosition);

            string filePostFix = "&file=media.ts";

            if (profile.MediaTranscoding?.VideoTargets?.Any(t => t.Target.VideoContainerType == VideoContainer.Hls) ?? false)
            {
                filePostFix = "&file=manifest.m3u8"; //Must be added for some clients to work (Android mostly)
            }
            string url = GetBaseStreamUrl.GetBaseStreamURL(context) + "/MPExtended/StreamingService/stream/RetrieveStream?identifier=" + identifier + filePostFix;

            return(new WebStringResult {
                Result = url
            });
        }
Пример #5
0
        internal static WebMovieBasic MovieBasic(MediaItem item)
        {
            MediaItemAspect movieAspect    = item.GetAspect(MovieAspect.Metadata);
            MediaItemAspect videoAspect    = item.GetAspect(VideoAspect.Metadata);
            MediaItemAspect mediaAspect    = item.GetAspect(MediaAspect.Metadata);
            MediaItemAspect importerAspect = item.GetAspect(ImporterAspect.Metadata);

            WebMovieBasic webMovieBasic = new WebMovieBasic
            {
                Title     = movieAspect.GetAttributeValue <string>(MovieAspect.ATTR_MOVIE_NAME),
                Id        = item.MediaItemId.ToString(),
                Type      = WebMediaType.Movie,
                Path      = ResourceAccessUtils.GetPaths(item),
                Year      = mediaAspect.GetAttributeValue <DateTime>(MediaAspect.ATTR_RECORDINGTIME).Year,
                Runtime   = movieAspect.GetAttributeValue <int>(MovieAspect.ATTR_RUNTIME_M),
                Watched   = Convert.ToInt32(item.UserData.FirstOrDefault(d => d.Key == UserDataKeysKnown.KEY_PLAY_PERCENTAGE).Value ?? "0") >= 100,
                DateAdded = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                Rating    = Convert.ToSingle(movieAspect.GetAttributeValue <double>(MovieAspect.ATTR_TOTAL_RATING)),
                Artwork   = ResourceAccessUtils.GetWebArtwork(item),
            };

            IEnumerable <string> aspectActors = videoAspect.GetCollectionAttribute <string>(VideoAspect.ATTR_ACTORS);

            if (aspectActors != null)
            {
                webMovieBasic.Actors = aspectActors.Distinct().Select(a => new WebActor(a)).ToList();
            }

            IList <MediaItemAspect> genres;

            if (item.Aspects.TryGetValue(GenreAspect.ASPECT_ID, out genres))
            {
                webMovieBasic.Genres = genres.Select(g => g.GetAttributeValue <string>(GenreAspect.ATTR_GENRE)).ToList();
            }

            string tmdbId;

            if (MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_TMDB, ExternalIdentifierAspect.TYPE_MOVIE, out tmdbId) && tmdbId != null)
            {
                webMovieBasic.ExternalId.Add(new WebExternalId {
                    Site = "TMDB", Id = tmdbId
                });
            }
            string imdbId;

            if (MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_IMDB, ExternalIdentifierAspect.TYPE_MOVIE, out imdbId) && imdbId != null)
            {
                webMovieBasic.ExternalId.Add(new WebExternalId {
                    Site = "IMDB", Id = imdbId
                });
            }

            return(webMovieBasic);
        }
Пример #6
0
        internal static WebMusicTrackBasic MusicTrackBasic(MediaItem item)
        {
            MediaItemAspect audioAspect    = item.GetAspect(AudioAspect.Metadata);
            MediaItemAspect mediaAspect    = item.GetAspect(MediaAspect.Metadata);
            MediaItemAspect importerAspect = item.GetAspect(ImporterAspect.Metadata);

            WebMusicTrackBasic webTrackBasic = new WebMusicTrackBasic
            {
                Title       = audioAspect.GetAttributeValue <string>(AudioAspect.ATTR_TRACKNAME),
                Id          = item.MediaItemId.ToString(),
                Type        = WebMediaType.MusicTrack,
                Path        = ResourceAccessUtils.GetPaths(item),
                Year        = mediaAspect.GetAttributeValue <DateTime>(MediaAspect.ATTR_RECORDINGTIME).Year,
                Duration    = (int)audioAspect.GetAttributeValue <long>(AudioAspect.ATTR_DURATION),
                DateAdded   = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                Rating      = Convert.ToSingle(audioAspect.GetAttributeValue <double>(AudioAspect.ATTR_TOTAL_RATING)),
                Artwork     = ResourceAccessUtils.GetWebArtwork(item),
                Album       = audioAspect.GetAttributeValue <string>(AudioAspect.ATTR_ALBUM),
                DiscNumber  = audioAspect.GetAttributeValue <int>(AudioAspect.ATTR_DISCID),
                TrackNumber = audioAspect.GetAttributeValue <int>(AudioAspect.ATTR_TRACK),
            };

            IEnumerable <string> aspectArtists = audioAspect.GetCollectionAttribute <string>(AudioAspect.ATTR_ARTISTS);

            if (aspectArtists != null)
            {
                webTrackBasic.Artist = aspectArtists.Distinct().ToList();
            }

            aspectArtists = audioAspect.GetCollectionAttribute <string>(AudioAspect.ATTR_ALBUMARTISTS);
            if (aspectArtists != null)
            {
                webTrackBasic.AlbumArtist = aspectArtists.FirstOrDefault();
            }

            if (MediaItemAspect.TryGetAspects(item.Aspects, RelationshipAspect.Metadata, out var relationAspects))
            {
                webTrackBasic.ArtistId      = relationAspects.Where(r => (Guid?)r[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ARTIST).Select(r => r[RelationshipAspect.ATTR_LINKED_ID].ToString()).ToList();
                webTrackBasic.AlbumId       = relationAspects.Where(r => (Guid?)r[RelationshipAspect.ATTR_LINKED_ROLE] == AudioAlbumAspect.ROLE_ALBUM).Select(r => r[RelationshipAspect.ATTR_LINKED_ID].ToString()).FirstOrDefault();
                webTrackBasic.AlbumArtistId = relationAspects.Where(r => (Guid?)r[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ALBUMARTIST).Select(r => r[RelationshipAspect.ATTR_LINKED_ID].ToString()).FirstOrDefault();
            }

            IList <MediaItemAspect> genres;

            if (item.Aspects.TryGetValue(GenreAspect.ASPECT_ID, out genres))
            {
                webTrackBasic.Genres = genres.Select(g => g.GetAttributeValue <string>(GenreAspect.ATTR_GENRE)).ToList();
            }

            return(webTrackBasic);
        }
Пример #7
0
        internal static WebTVEpisodeBasic EpisodeBasic(MediaItem item, Guid?showId = null, Guid?seasonId = null)
        {
            MediaItemAspect episodeAspect  = item.GetAspect(EpisodeAspect.Metadata);
            MediaItemAspect importerAspect = item.GetAspect(ImporterAspect.Metadata);
            MediaItemAspect mediaAspect    = item.GetAspect(MediaAspect.Metadata);

            IEnumerable <int> episodeNumbers = episodeAspect.GetCollectionAttribute <int>(EpisodeAspect.ATTR_EPISODE);
            int episodeNumber = episodeNumbers != null?episodeNumbers.FirstOrDefault() : 0;

            GetParentIds(item, ref showId, ref seasonId);

            WebTVEpisodeBasic webTvEpisodeBasic = new WebTVEpisodeBasic
            {
                Title         = episodeAspect.GetAttributeValue <string>(EpisodeAspect.ATTR_EPISODE_NAME),
                EpisodeNumber = episodeNumber,
                Id            = item.MediaItemId.ToString(),
                ShowId        = showId.HasValue ? showId.Value.ToString() : null,
                SeasonId      = seasonId.HasValue ? seasonId.Value.ToString() : null,
                Type          = WebMediaType.TVEpisode,
                Path          = ResourceAccessUtils.GetPaths(item),
                Watched       = Convert.ToInt32(item.UserData.FirstOrDefault(d => d.Key == UserDataKeysKnown.KEY_PLAY_PERCENTAGE).Value ?? "0") >= 100,
                DateAdded     = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                SeasonNumber  = episodeAspect.GetAttributeValue <int>(EpisodeAspect.ATTR_SEASON),
                FirstAired    = mediaAspect.GetAttributeValue <DateTime>(MediaAspect.ATTR_RECORDINGTIME),
                Rating        = Convert.ToSingle(episodeAspect.GetAttributeValue <double>(EpisodeAspect.ATTR_TOTAL_RATING)),
                Artwork       = ResourceAccessUtils.GetWebArtwork(item),
            };

            string TvDbId;

            MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_TVDB, ExternalIdentifierAspect.TYPE_SERIES, out TvDbId);
            if (TvDbId != null)
            {
                webTvEpisodeBasic.ExternalId.Add(new WebExternalId {
                    Site = "TVDB", Id = TvDbId
                });
            }
            string ImdbId;

            MediaItemAspect.TryGetExternalAttribute(item.Aspects, ExternalIdentifierAspect.SOURCE_IMDB, ExternalIdentifierAspect.TYPE_SERIES, out ImdbId);
            if (ImdbId != null)
            {
                webTvEpisodeBasic.ExternalId.Add(new WebExternalId {
                    Site = "IMDB", Id = ImdbId
                });
            }

            return(webTvEpisodeBasic);
        }
Пример #8
0
        internal static WebMusicArtistBasic MusicArtistBasic(MediaItem item)
        {
            MediaItemAspect artistAspect = item.GetAspect(PersonAspect.Metadata);

            bool hasAlbum = false;

            if (MediaItemAspect.TryGetAspects(item.Aspects, RelationshipAspect.Metadata, out var relationAspects))
            {
                hasAlbum = relationAspects.Any(r => (Guid?)r[RelationshipAspect.ATTR_LINKED_ROLE] == AudioAlbumAspect.ROLE_ALBUM);
            }

            return(new WebMusicArtistBasic
            {
                HasAlbums = hasAlbum,
                Id = item.MediaItemId.ToString(),
                Title = artistAspect.GetAttributeValue <string>(PersonAspect.ATTR_PERSON_NAME),
                Artwork = ResourceAccessUtils.GetWebArtwork(item)
            });
        }
Пример #9
0
        public static Task <WebFileInfo> ProcessAsync(IOwinContext context, WebMediaType mediatype, WebFileType filetype, string id, int offset)
        {
            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);

            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, id, necessaryMIATypes, null);

            if (item == null)
            {
                throw new NotFoundException("GetFileInfo: no media item found");
            }

            var files = ResourceAccessUtils.GetResourcePaths(item);
            var ra    = GetResourceAccessor(files[offset]);
            IFileSystemResourceAccessor fsra = ra as IFileSystemResourceAccessor;

            if (fsra == null)
            {
                throw new InternalServerException("GetFileInfo: failed to create IFileSystemResourceAccessor");
            }

            WebFileInfo webFileInfo = new WebFileInfo
            {
                Exists           = fsra.Exists,
                Extension        = fsra.Path.Split('.').Last(),
                IsLocalFile      = true,
                IsReadOnly       = true,
                LastAccessTime   = DateTime.Now,
                LastModifiedTime = fsra.LastChanged,
                Name             = fsra.ResourceName,
                OnNetworkDrive   = false,
                Path             = files[offset].FileName,
                Size             = fsra.Size,
            };

            return(Task.FromResult(webFileInfo));
        }
Пример #10
0
        public static Task <WebMediaItem> ProcessAsync(IOwinContext context, string id)
        {
            if (id == null)
            {
                throw new BadRequestException("GetMediaItem: id is null");
            }

            ISet <Guid> necessaryMIATypes = new HashSet <Guid>();

            necessaryMIATypes.Add(MediaAspect.ASPECT_ID);
            necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID);
            necessaryMIATypes.Add(ImporterAspect.ASPECT_ID);

            ISet <Guid> optionalMIATypes = new HashSet <Guid>();

            optionalMIATypes.Add(VideoAspect.ASPECT_ID);
            optionalMIATypes.Add(MovieAspect.ASPECT_ID);
            optionalMIATypes.Add(EpisodeAspect.ASPECT_ID);
            optionalMIATypes.Add(AudioAspect.ASPECT_ID);
            optionalMIATypes.Add(ImageAspect.ASPECT_ID);

            MediaItem item = MediaLibraryAccess.GetMediaItemById(context, Guid.Parse(id), necessaryMIATypes, optionalMIATypes);

            if (item == null)
            {
                throw new NotFoundException(String.Format("GetMediaItem: No MediaItem found with id: {0}", id));
            }

            WebMediaItem webMediaItem = new WebMediaItem();

            webMediaItem.Id        = item.MediaItemId.ToString();
            webMediaItem.Artwork   = ResourceAccessUtils.GetWebArtwork(item);
            webMediaItem.DateAdded = item.GetAspect(ImporterAspect.Metadata).GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED);
            webMediaItem.Path      = ResourceAccessUtils.GetPaths(item);
            webMediaItem.Type      = ResourceAccessUtils.GetWebMediaType(item);
            webMediaItem.Title     = item.GetAspect(MediaAspect.Metadata).GetAttributeValue <string>(MediaAspect.ATTR_TITLE);

            return(Task.FromResult(webMediaItem));
        }
        internal static WebMusicAlbumBasic MusicAlbumBasic(MediaItem item)
        {
            MediaItemAspect importerAspect = item.GetAspect(ImporterAspect.Metadata);
            MediaItemAspect mediaAspect    = item.GetAspect(MediaAspect.Metadata);
            MediaItemAspect albumAspect    = item.GetAspect(AudioAlbumAspect.Metadata);

            var artists = albumAspect.GetCollectionAttribute <string>(AudioAlbumAspect.ATTR_ARTISTS);

            IList <MultipleMediaItemAspect> genres;

            if (!MediaItemAspect.TryGetAspects(item.Aspects, GenreAspect.Metadata, out genres))
            {
                genres = new List <MultipleMediaItemAspect>();
            }

            var artistIds = new HashSet <string>();

            if (MediaItemAspect.TryGetAspects(item.Aspects, RelationshipAspect.Metadata, out var relationAspects))
            {
                artistIds = new HashSet <string>(relationAspects.Where(r => (Guid?)r[RelationshipAspect.ATTR_LINKED_ROLE] == PersonAspect.ROLE_ALBUMARTIST).Select(r => r[RelationshipAspect.ATTR_LINKED_ID].ToString()));
            }

            return(new WebMusicAlbumBasic
            {
                Id = item.MediaItemId.ToString(),
                Artists = artists?.ToList(),
                ArtistsId = artistIds?.ToList(),
                AlbumArtist = artists?.FirstOrDefault()?.ToString(),
                AlbumArtistId = artistIds?.FirstOrDefault()?.ToString(),
                Genres = genres?.Select(a => a.GetAttributeValue <string>(GenreAspect.ATTR_GENRE)).ToList(),
                Title = albumAspect.GetAttributeValue <string>(AudioAlbumAspect.ATTR_ALBUM),
                Year = mediaAspect.GetAttributeValue <DateTime>(MediaAspect.ATTR_RECORDINGTIME).Year,
                DateAdded = importerAspect.GetAttributeValue <DateTime>(ImporterAspect.ATTR_DATEADDED),
                Rating = Convert.ToSingle(albumAspect.GetAttributeValue <double>(AudioAlbumAspect.ATTR_TOTAL_RATING)),
                Artwork = ResourceAccessUtils.GetWebArtwork(item),
                //Composer = composers.Cast<string>().ToList()
            });
        }
Пример #12
0
        internal static WebRecordingBasic RecordingBasic(MediaItem item)
        {
            MediaItemAspect recordingAspect = item.GetAspect(RecordingAspect.Metadata);

            string genre = string.Empty;

            if (MediaItemAspect.TryGetAttribute(item.Aspects, GenreAspect.ATTR_GENRE, out List <string> genres))
            {
                genre = string.Join(", ", genres);
            }

            return(new WebRecordingBasic
            {
                Id = item.MediaItemId.ToString(),
                Title = (string)item.GetAspect(MediaAspect.Metadata).GetAttributeValue(MediaAspect.ATTR_TITLE),
                ChannelName = (string)recordingAspect.GetAttributeValue(RecordingAspect.ATTR_CHANNEL),
                Description = (string)item.GetAspect(VideoAspect.Metadata).GetAttributeValue(VideoAspect.ATTR_STORYPLOT),
                StartTime = (DateTime)(recordingAspect.GetAttributeValue(RecordingAspect.ATTR_STARTTIME) ?? DateTime.Now),
                EndTime = (DateTime)(recordingAspect.GetAttributeValue(RecordingAspect.ATTR_ENDTIME) ?? DateTime.Now),
                Genre = genre,
                TimesWatched = Convert.ToInt32(item.UserData.FirstOrDefault(d => d.Key == UserDataKeysKnown.KEY_PLAY_COUNT).Value ?? "0"),
                FileName = ResourceAccessUtils.GetPaths(item).FirstOrDefault(),
            });
        }
Пример #13
0
        internal static WebPictureBasic PictureBasic(MediaItem item)
        {
            MediaItemAspect imageAspects = item.GetAspect(ImageAspect.Metadata);

            WebPictureBasic webPictureBasic = new WebPictureBasic
            {
                Type      = WebMediaType.Picture,
                DateAdded = (DateTime)item.GetAspect(ImporterAspect.Metadata).GetAttributeValue(ImporterAspect.ATTR_DATEADDED),
                Id        = item.MediaItemId.ToString(),
                Title     = (string)item.GetAspect(MediaAspect.Metadata).GetAttributeValue(MediaAspect.ATTR_TITLE),
                DateTaken = (DateTime)item.GetAspect(MediaAspect.Metadata)[MediaAspect.ATTR_RECORDINGTIME],
                Path      = ResourceAccessUtils.GetPaths(item),
                Artwork   = ResourceAccessUtils.GetWebArtwork(item),
            };

            webPictureBasic.Categories = new[]
            {
                new WebCategory {
                    Title = (webPictureBasic.DateTaken).ToString("yyyy"), Id = (webPictureBasic.DateTaken).ToString("yyyy")
                }
            };

            return(webPictureBasic);
        }
Пример #14
0
 internal static Guid StringToGuid(string value)
 {
     byte[] bytes = ResourceAccessUtils.GetBytes(value);
     return(new Guid(bytes));
 }
Пример #15
0
        public async Task Initialize(Guid?userId, MediaItem item, int?edition, int?audioId = null, int?subtitleId = null)
        {
            MediaItemId = item.MediaItemId;

            var info = await MediaAnalyzer.ParseMediaItemAsync(item);

            if (info == null)
            {
                Logger.Warn("MP2Extended: Mediaitem {0} couldn't be analyzed", item.MediaItemId);
                return;
            }

            int?          audioStreamId         = null;
            List <string> preferredAudioLang    = new List <string>();
            List <string> preferredSubtitleLang = new List <string>();
            await ResourceAccessUtils.AddPreferredLanguagesAsync(userId, preferredAudioLang, preferredSubtitleLang);

            if (audioId.HasValue)
            {
                if (audioId.Value >= EDITION_OFFSET)
                {
                    edition       = (audioId.Value / EDITION_OFFSET) - 1;
                    audioStreamId = audioId.Value - ((audioId.Value / EDITION_OFFSET) * EDITION_OFFSET);
                }
                else
                {
                    audioStreamId = audioId;
                }
            }

            if (item.HasEditions && !edition.HasValue)
            {
                //Find edition with best matching audio that doesn't require transcoding
                int  currentPriority            = -1;
                bool currentRequiresTranscoding = false;
                foreach (var checkEdition in info.Metadata.Keys)
                {
                    for (int idx = 0; idx < info.Audio[checkEdition].Count; idx++)
                    {
                        VideoTranscoding video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                                             info, checkEdition, preferredAudioLang, IsLive, "");

                        bool requiresTranscoding = video != null;

                        for (int priority = 0; priority < preferredAudioLang.Count; priority++)
                        {
                            if (preferredAudioLang[priority].Equals(info.Audio[checkEdition][idx].Language, StringComparison.InvariantCultureIgnoreCase) == true)
                            {
                                if (currentPriority == -1 || priority < currentPriority || (!requiresTranscoding && currentRequiresTranscoding && priority == currentPriority))
                                {
                                    currentPriority            = priority;
                                    currentRequiresTranscoding = requiresTranscoding;
                                    audioStreamId = info.Audio[checkEdition][idx].StreamIndex;
                                    _edition      = checkEdition;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                //Assign first edition
                _edition = info.Metadata.Min(m => m.Key);
            }

            if (item.Aspects.ContainsKey(AudioAspect.ASPECT_ID))
            {
                IsAudio = true;
            }
            else if (item.Aspects.ContainsKey(ImageAspect.ASPECT_ID))
            {
                IsImage = true;
            }
            else if (item.Aspects.ContainsKey(VideoAspect.ASPECT_ID))
            {
                IsVideo = true;
            }
            else
            {
                Logger.Warn("MP2Extended: Mediaitem {0} contains no required aspect information", item.MediaItemId);
                return;
            }

            string transcodeId = item.MediaItemId.ToString() + "_" + Profile.ID;

            if (IsLive)
            {
                transcodeId = Guid.NewGuid().ToString() + "_" + Profile.ID;
            }

            if (MP2Extended.Settings.TranscodingAllowed)
            {
                if (IsAudio)
                {
                    AudioTranscoding audio = TranscodeProfileManager.GetAudioTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                                         info, _edition, IsLive, transcodeId);
                    TranscodingParameter = audio;
                }
                else if (IsImage)
                {
                    ImageTranscoding image = TranscodeProfileManager.GetImageTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                                         info, _edition, transcodeId);
                    TranscodingParameter = image;
                }
                else if (IsVideo)
                {
                    VideoTranscoding video;
                    if (audioStreamId.HasValue)
                    {
                        video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                            info, _edition, audioStreamId.Value, subtitleId, IsLive, transcodeId);
                    }
                    else
                    {
                        video = TranscodeProfileManager.GetVideoTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                            info, _edition, preferredAudioLang, IsLive, transcodeId);
                    }

                    if (video != null)
                    {
                        if (video.TargetVideoContainer == VideoContainer.Hls)
                        {
                            IsSegmented = true;
                        }
                        if (MP2Extended.Settings.HardcodedSubtitlesAllowed == false)
                        {
                            video.TargetSubtitleSupport = SubtitleSupport.None;
                        }
                    }
                    TranscodingParameter = video;
                }
            }

            if (TranscodingParameter == null)
            {
                if (IsLive)
                {
                    if (IsVideo)
                    {
                        if (audioStreamId.HasValue)
                        {
                            TranscodingParameter = TranscodeProfileManager.GetLiveVideoTranscoding(info, audioStreamId.Value, transcodeId);
                        }
                        else
                        {
                            TranscodingParameter = TranscodeProfileManager.GetLiveVideoTranscoding(info, preferredAudioLang, transcodeId);
                        }
                    }
                    else if (IsAudio)
                    {
                        TranscodingParameter = TranscodeProfileManager.GetLiveAudioTranscoding(info, transcodeId);
                    }
                }
                else if (IsVideo)
                {
                    VideoTranscoding video = TranscodeProfileManager.GetVideoSubtitleTranscoding(ProfileManager.TRANSCODE_PROFILE_SECTION, Profile.ID,
                                                                                                 info, _edition, IsLive, transcodeId);
                    if (video != null)
                    {
                        if (video.TargetVideoContainer == VideoContainer.Hls)
                        {
                            IsSegmented = true;
                        }
                        if (MP2Extended.Settings.HardcodedSubtitlesAllowed == false)
                        {
                            video.TargetSubtitleSupport = SubtitleSupport.None;
                        }
                    }
                    TranscodingParameter = video;
                }
            }

            AssignWebMetadata(info, _edition);
        }
Пример #16
0
        protected static async Task SendAsync(IOwinContext context, Stream resourceStream, ProfileMediaItem item, EndPointProfile profile, bool onlyHeaders, bool partialResource, Range byteRange)
        {
            if (onlyHeaders)
            {
                return;
            }

            bool clientDisconnected = false;
            Guid streamID           = item.StartStreaming();

            if (streamID == Guid.Empty)
            {
                Logger.Error("BaseSendData: Unable to start stream");
                return;
            }
            try
            {
                if (context.Response.ContentLength == 0)
                {
                    //Not allowed to have a content length of zero
                    context.Response.ContentLength = null;
                }
                Logger.Debug("BaseSendData: Sending chunked: {0}", context.Response.ContentLength == null);
                string clientID   = context.Request.RemoteIpAddress;
                int    bufferSize = profile.Settings.Communication.DefaultBufferSize;
                if (bufferSize <= 0)
                {
                    bufferSize = 1500;
                }
                byte[] buffer = new byte[bufferSize];
                int    bytesRead;
                long   count       = 0;
                bool   isStream    = false;
                long   waitForSize = 0;
                if (byteRange.Length == 0 || (byteRange.Length > 0 && byteRange.Length >= profile.Settings.Communication.InitialBufferSize))
                {
                    waitForSize = profile.Settings.Communication.InitialBufferSize;
                }
                if (partialResource == false)
                {
                    if (waitForSize < byteRange.From)
                    {
                        waitForSize = byteRange.From;
                    }
                }
                if (await WaitForMinimumFileSizeAsync(resourceStream, waitForSize) == false)
                {
                    Logger.Error("BaseSendData: Unable to send stream because of invalid length: {0} ({1} required)", resourceStream.Length, waitForSize);
                    return;
                }

                long start = 0;
                if (partialResource == false)
                {
                    start = byteRange.From;
                }
                if (resourceStream.CanSeek)
                {
                    resourceStream.Seek(start, SeekOrigin.Begin);
                }
                long length = byteRange.Length;
                if (length <= 0 || item.IsLive || (item.IsSegmented == false && item.IsTranscoding == true))
                {
                    isStream = true;
                }
                int emptyCount = 0;
                while (item.IsStreamActive(streamID))
                {
                    if (isStream)
                    {
                        if (resourceStream.CanSeek)
                        {
                            length = resourceStream.Length - count;
                        }
                        else
                        {
                            length = bufferSize; //Keep stream alive
                        }
                    }
                    bytesRead = await resourceStream.ReadAsync(buffer, 0, length > bufferSize?bufferSize : (int)length);

                    count += bytesRead;

                    if (bytesRead > 0)
                    {
                        emptyCount = 0;
                        try
                        {
                            //Send fetched bytes
                            await context.Response.WriteAsync(buffer, 0, bytesRead, SendDataCancellation.Token);
                        }
                        catch (Exception)
                        {
                            // Client disconnected
                            Logger.Debug("BaseSendData: Connection lost after {0} bytes", count);
                            clientDisconnected = true;
                            break;
                        }
                        length -= bytesRead;

                        if (isStream == false && length <= 0)
                        {
                            //All bytes in the requested range sent
                            break;
                        }
                    }
                    else
                    {
                        emptyCount++;
                        if (emptyCount > 2)
                        {
                            Logger.Debug("BaseSendData: Buffer underrun delay");
                            await Task.Delay(100);
                        }
                        if (emptyCount > 10)
                        {
                            //Stream is not getting any bigger
                            break;
                        }
                    }

                    if (resourceStream.CanSeek)
                    {
                        if (item.IsTranscoding == false && resourceStream.Position == resourceStream.Length)
                        {
                            //No more data will be available
                            break;
                        }
                    }
                }
            }
            finally
            {
                item.StopStreaming(streamID);

                if (clientDisconnected || item.IsSegmented == false)
                {
                    if (clientDisconnected == false)
                    {
                        //Everything sent to client so presume watched
                        if (item.IsLive == false)
                        {
                            Guid?         userId  = ResourceAccessUtils.GetUser(context);
                            IMediaLibrary library = ServiceRegistration.Get <IMediaLibrary>();
                            if (library != null && userId.HasValue)
                            {
                                library.NotifyUserPlayback(userId.Value, item.MediaItemId, 100, true);
                            }
                        }
                    }
                }
                Logger.Debug("BaseSendData: Sending complete");
            }
        }
Пример #17
0
        public static async Task <WebStringResult> ProcessAsync(IOwinContext context, string identifier, string profileName, long startPosition, int audioId = -1, int subtitleId = -1)
        {
            if (identifier == null)
            {
                throw new BadRequestException("StartStreamWithStreamSelection: identifier is null");
            }
            if (profileName == null)
            {
                throw new BadRequestException("StartStreamWithStreamSelection: profileName is null");
            }

            EndPointProfile        profile       = null;
            List <EndPointProfile> namedProfiles = ProfileManager.Profiles.Where(x => x.Value.Name == profileName).Select(namedProfile => namedProfile.Value).ToList();

            if (namedProfiles.Count > 0)
            {
                profile = namedProfiles[0];
            }
            else if (ProfileManager.Profiles.ContainsKey(profileName))
            {
                profile = ProfileManager.Profiles[profileName];
            }
            if (profile == null)
            {
                throw new BadRequestException(string.Format("StartStreamWithStreamSelection: unknown profile: {0}", profileName));
            }

            StreamItem streamItem = await StreamControl.GetStreamItemAsync(identifier);

            if (streamItem == null)
            {
                throw new BadRequestException(string.Format("StartStreamWithStreamSelection: unknown identifier: {0}", identifier));
            }

            streamItem.Profile       = profile;
            streamItem.StartPosition = startPosition;
            if (streamItem.RequestedMediaItem is LiveTvMediaItem)
            {
                streamItem.StartPosition = 0;
            }

            Guid?userId = ResourceAccessUtils.GetUser(context);

            streamItem.TranscoderObject = new ProfileMediaItem(identifier, profile, streamItem.IsLive);
            await streamItem.TranscoderObject.Initialize(userId, streamItem.RequestedMediaItem, audioId >= 0?audioId : (int?)null, subtitleId);

            if ((streamItem.TranscoderObject.TranscodingParameter is VideoTranscoding vt))
            {
                vt.HlsBaseUrl = string.Format("RetrieveStream?identifier={0}&hls=", identifier);
            }

            await StreamControl.StartStreamingAsync(identifier, startPosition);

            string filePostFix = "&file=media.ts";

            if (profile.MediaTranscoding != null && profile.MediaTranscoding.VideoTargets != null)
            {
                foreach (var target in profile.MediaTranscoding.VideoTargets)
                {
                    if (target.Target.VideoContainerType == VideoContainer.Hls)
                    {
                        filePostFix = "&file=manifest.m3u8"; //Must be added for some clients to work (Android mostly)
                        break;
                    }
                }
            }

            string url = GetBaseStreamUrl.GetBaseStreamURL(context) + "/MPExtended/StreamingService/stream/RetrieveStream?identifier=" + identifier + filePostFix;

            return(new WebStringResult {
                Result = url
            });
        }
Пример #18
0
        public static Task <IList <WebArtwork> > ProcessAsync(IOwinContext context, WebMediaType type, string id)
        {
            var output = ResourceAccessUtils.GetWebArtwork(type, Guid.Parse(id));

            return(System.Threading.Tasks.Task.FromResult <IList <WebArtwork> >(output));
        }