예제 #1
0
        /// <summary>
        /// Determines whether this PlayableItem can play a Media object
        /// </summary>
        public override bool CanPlay(Media media)
        {
            // can play DVDs and normal videos
            Video video = media as Video;

            if (video == null)
            {
                return false;
            }

            return CanPlay(video.MediaType);
        }
        public static bool CanPlay(Media media)
        {
            bool canPlay = false;
            var video = media as Video;

            if (video != null) {
                var files = video.VideoFiles.ToArray();
                if (files.Length == 1) {
                    canPlay = CanPlay(files[0]);
                }
            }
            return canPlay;
        }
        /// <summary>
        /// Find the first streamable audio stream for the specified language
        /// </summary>
        /// <returns></returns>
        public static int FindAudioStream(Media item, string lang = "")
        {
            if (string.IsNullOrEmpty(lang)) lang = "eng";
            if (item.MediaSources == null || !item.MediaSources.Any()) return 0;

            Logging.Logger.ReportVerbose("Looking for audio stream in {0}", lang);
            MediaStream stream = null;
            foreach (var codec in StreamableCodecs)
            {
                stream = item.MediaSources.First().MediaStreams.OrderBy(s => s.Index).FirstOrDefault(s => s.Type == MediaStreamType.Audio && (s.Language == null || s.Language.Equals(lang, StringComparison.OrdinalIgnoreCase))
                    && s.Codec.Equals(codec, StringComparison.OrdinalIgnoreCase));
                if (stream != null) break;

            }
            Logger.ReportVerbose("Requesting audio stream #{0}", stream != null ? stream.Index : 0);
            return stream != null ? stream.Index : 0;
        }
        protected void OnItemFinished(Media media, long pos)
        {
                try
                {
                    Logger.ReportVerbose("Reporting stopped to server for {0}",media.Name);
                    var newStatus = Application.CurrentInstance.ReportPlaybackStopped(media.ApiId, pos);

                    // Update our status with what was returned from server if valid
                    if (newStatus != null)
                    {
                        // we have to search the loaded library for all occurrences of this item and set the status there
                        foreach (var item in Kernel.Instance.FindItems(media.Id).OfType<Media>())
                        {
                            Logger.ReportVerbose(string.Format("Setting new status on {0} with parent of {1}", item.Name, item.Parent != null ? item.Parent.Name : "<Unknown>"));
                            media.PlaybackStatus.LastPlayed = PlaybackStartTime;
                            item.PlaybackStatus.PositionTicks = newStatus.PositionTicks;
                            item.PlaybackStatus.WasPlayed = newStatus.WasPlayed;
                        }
                        if (newStatus.WasPlayed && !media.PlaybackStatus.WasPlayed && media.Parent != null)
                        {
                            //update our parent's unwatched count
                            media.Parent.AdjustUnwatched(-1);
                        }
                        media.PlaybackStatus.LastPlayed = PlaybackStartTime;
                        media.PlaybackStatus.PositionTicks = newStatus.PositionTicks;
                        media.PlaybackStatus.WasPlayed = newStatus.WasPlayed;
                    }
                    else
                    {
                        Logger.ReportVerbose("New status was null");
                    }
                }
                catch (Exception ex)
                {
                    Logger.ReportException("Error attempting to update status on server", ex);
                }

            if (Config.Instance.RecentItemOption == "watched" || Config.Instance.RecentItemOption == "unwatched")
            {
                // go ahead and force these lists to re-build
                var top = media.TopParent;
                if (top != null) top.OnQuickListChanged(null);
            }

            //MarkWatchedIfNeeded();
        }
        public PlayableItem Create(Media media)
        {
            PlayableItem playable = null;

            foreach (CanPlay canPlay in PlayableItems.Keys)
                if (canPlay(media))
                {
                    Type type = PlayableItems[canPlay];
                    playable = (PlayableItem) Activator.CreateInstance(type, media);
                    break;
                }

            if (playable == null)
                playable = new PlayableVideoFile(media);

            foreach (var controller in Kernel.Instance.PlaybackControllers) {
                if (controller.CanPlay(playable.Filename)) {
                    playable.PlaybackController = controller;
                    return playable;
                }
            }

            return playable;
        }
        public static string BuildStreamingUrl(Media item, int bitrate)
        {
            // build based on WMC profile
            var profile = Application.RunningOnExtender ? new WindowsExtenderProfile() as DefaultProfile : new WindowsMediaCenterProfile();
            var info = item.MediaSources != null && item.MediaSources.Any() ? new StreamBuilder(new LocalPlayer()).BuildVideoItem(new VideoOptions { DeviceId = Kernel.ApiClient.DeviceId, ItemId = item.ApiId, MediaSources = item.MediaSources, MaxBitrate = bitrate, Profile = profile }) : null;
            if (info != null)
            {
                //Further optimize for direct play if possible
                return info.MediaSource.Protocol == MediaProtocol.Http && !string.IsNullOrEmpty(info.MediaSource.Path) && !info.MediaSource.RequiredHttpHeaders.Any() ? info.MediaSource.Path : info.ToUrl(Kernel.ApiClient.ApiUrl, Kernel.ApiClient.AuthToken);
            }

            // fallback to legacy
            return Kernel.ApiClient.GetVideoStreamUrl(new VideoStreamOptions
            {
                ItemId = item.ApiId,
                OutputFileExtension = ".wmv",
                MaxWidth = 1280,
                VideoBitRate = bitrate,
                AudioBitRate = 128000,
                MaxAudioChannels = 2,
                AudioStreamIndex = FindAudioStream(item, Kernel.CurrentUser.Dto.Configuration.AudioLanguagePreference)
            });
            
        }
 public static bool CanPlay(Media media)
 {
     return (media is Video) && (media as Video).MediaType == MediaType.DVD;
 }
 public PlayableExternal(Media media)
 {
     Video video = (media as Video);
     this.path = video.VideoFiles.ToArray()[0];
     this.duration = TimeSpan.FromMinutes(video.RunningTime ?? 0);
 }
        /// <summary>
        /// Determines whether this PlayableItem can play a Media object
        /// </summary>
        public override bool CanPlay(Media media)
        {
            // can play DVDs, music and normal videos

            return CanPlay(media.MediaType);
        }
예제 #10
0
 public override bool CanPlay(Media media)
 {
     return CanPlay(new Media[] { media });
 }
예제 #11
0
 /// <summary>
 /// Determines if this PlayableItem can play a given Media object within a playlist
 /// </summary>
 protected virtual bool IsPlaylistCapable(Media media)
 {
     Video video = media as Video;
     if (video != null)
     {
         return !video.ContainsRippedMedia;
     }
     return true;
 }
예제 #12
0
 public void AddMedia(Media media)
 {
     AddMedia(new Media[] { media });
 }
        /// <summary>
        /// Takes a Media object and returns the list of files that will be sent to the player
        /// </summary>
        internal override IEnumerable<string> GetPlayableFiles(Media media)
        {
            IEnumerable<string> files = base.GetPlayableFiles(media);

            Video video = media as Video;

            if (video != null)
            {
                files = files.Select(i => FormatPath(i, video.MediaType));
            }

            return files;
        }
예제 #14
0
 protected override bool IsPlaylistCapable(Media media)
 {
     // VLC seems to handle everything in a playlist
     return true;
 }
 public PlayableDvd(Media media)
     : base()
 {
     this.video = media as Video;
 }
예제 #16
0
 public override bool CanPlay(Media media)
 {
     return media is Music;
 }
예제 #17
0
        /// <summary>
        /// This is a helper to update Playstate for an item.
        /// It honors all of the various resume options within configuration.
        /// Play count will be incremented if the last played date doesn't match what's currently in the object
        /// </summary>
        public void UpdatePlayState(Media media, PlaybackStatus playstate, int playlistPosition, long positionTicks, long? duration, DateTime datePlayed, bool saveToDataStore)
        {
            // Increment play count if dates don't match
            bool incrementPlayCount = !playstate.LastPlayed.Equals(datePlayed);

            // The player didn't report the duration, see if we have it in metadata
            if ((!duration.HasValue || duration == 0) && media.Files.Count() == 1)
            {
                // We need duration to pertain only to one file
                // So if there are multiple files don't bother with this
                // since we have no way of breaking it down

                duration = TimeSpan.FromMinutes(media.RunTime).Ticks;
            }

            // If we know the duration then enforce MinResumePct, MaxResumePct and MinResumeDuration
            if (duration.HasValue && duration > 0)
            {
                // Enforce MinResumePct/MaxResumePct
                if (positionTicks > 0)
                {
                    decimal pctIn = Decimal.Divide(positionTicks, duration.Value) * 100;

                    // Don't track in very beginning
                    if (pctIn < Config.Instance.MinResumePct)
                    {
                        positionTicks = 0;

                        if (playlistPosition == 0)
                        {
                            // Assume we're at the very beginning so don't even mark it watched.
                            incrementPlayCount = false;
                        }
                    }

                    // If we're at the end, assume completed
                    if (pctIn > Config.Instance.MaxResumePct || positionTicks >= duration)
                    {
                        positionTicks = 0;

                        // Either advance to the next playlist position, or reset it back to 0
                        if (playlistPosition < (media.Files.Count() - 1))
                        {
                            playlistPosition++;
                        }
                        else
                        {
                            playlistPosition = 0;
                        }
                    }
                }

                // Enforce MinResumeDuration
                if ((duration / TimeSpan.TicksPerMinute) < Config.Instance.MinResumeDuration)
                {
                    positionTicks = 0;
                }
            }

            // If resume is disabled reset positions to 0
            if (!MediaBrowser.Library.Kernel.Instance.ConfigData.EnableResumeSupport)
            {
                positionTicks = 0;
                playlistPosition = 0;
            }

            playstate.PositionTicks = positionTicks;
            playstate.PlaylistPosition = playlistPosition;

            if (incrementPlayCount)
            {
                playstate.LastPlayed = datePlayed;
                playstate.PlayCount++;
            }

            if (saveToDataStore)
            {
                string sDuration = duration.HasValue ? (TimeSpan.FromTicks(duration.Value).ToString()) : "0";

                //Logger.ReportVerbose("Playstate saved for {0} at {1}, duration: {2}, playlist position: {3}", media.Name, TimeSpan.FromTicks(positionTicks), sDuration, playlistPosition);
                Kernel.Instance.SavePlayState(media, playstate);
            }
        }
예제 #18
0
 /// <summary>
 /// All we do now is check in with the server and let it figure everything else out
 /// </summary>
 public void UpdatePlayState(Media media, PlaybackStatus playstate, bool isPaused, bool saveToDataStore)
 {
     if (saveToDataStore)
     {
         ReportPlaybackProgress(media.ApiId, playstate.PositionTicks, isPaused, currentPlaybackController.IsStreaming);
     }
 }
예제 #19
0
 /// <summary>
 /// All we do now is check in with the server and let it figure everything else out
 /// </summary>
 public void UpdatePlayState(Media media, PlaybackStatus playstate, bool isPaused, bool saveToDataStore)
 {
     if (saveToDataStore)
     {
         ReportPlaybackProgress(media.ApiId, playstate.PositionTicks, isPaused);
     }
 }
예제 #20
0
        public static bool IsVideo(Media media)
        {
            Video video = media as Video;

            if (video != null)
            {
                // See if it has a known video type
                if (video.MediaType != MediaType.Unknown)
                {
                    return true;
                }

                // Hack alert
                if (video.GetType().Name == "Song")
                {
                    return false;
                }

                return true;
            }

            return false;
        }
        void statusRequestCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // If playback just finished, or if there was some type of error, skip it
            if (!_MonitorPlayback || e.Cancelled || e.Error != null || string.IsNullOrEmpty(e.Result))
            {
                return;
            }

            _ConsecutiveFailedHttpRequests = 0;

            string result = e.Result;

            // Logger.ReportVerbose("Response received from MPC-HC web interface: " + result);

            try
            {
                // Sample result
                // OnStatus('test.avi', 'Playing', 5292, '00:00:05', 1203090, '00:20:03', 0, 100, 'C:\test.avi')
                // 5292 = position in ms
                // 00:00:05 = position
                // 1203090 = duration in ms
                // 00:20:03 = duration

                char quoteChar = result.IndexOf(", \"") == -1 ? '\'' : '\"';

                // Strip off the leading "OnStatus(" and the trailing ")"
                result = result.Substring(result.IndexOf(quoteChar));
예제 #22
0
 /// <summary>
 /// Subclasses will have to override this if they want to be able to play a Media object
 /// </summary>
 public virtual bool CanPlay(Media media)
 {
     return false;
 }
 public PlayableMultiFileMusic(Media media)
     : base()
 {
     this.music = media as Music;
 }
        /// <summary>
        /// When playback is based on media items, this will take a single Media object and return the raw list of files that will be played
        /// </summary>
        internal virtual IEnumerable<string> GetPlayableFiles(Media media)
        {
            Video video = media as Video;

            if (video != null && video.MediaType == MediaType.ISO)
            {
                return video.IsoFiles;
            }

            return media.Files.OrderBy(s => s);
        }
 public static bool CanPlay(Media media)
 {
     return (media is Music) && (media as Music).MusicFiles.Count() > 1;
 }
        /// <summary>
        /// Takes a Media object and returns the list of files that will be sent to the player
        /// </summary>
        internal override IEnumerable<string> GetPlayableFiles(Media media)
        {
            IEnumerable<string> files = base.GetPlayableFiles(media);

            Video video = media as Video;

            if (video != null)
            {
                if (video.MediaType == Library.MediaType.BluRay)
                {
                    files = files.Select(i => PlaybackControllerHelper.GetBluRayPath(i));
                }
            }

            return ShouldTranscode ? files.Select(f => PlaybackControllerHelper.GetTranscodedPath(f)) : files;
        }
 public PlayableMusicFile(Media media)
     : base()
 {
     this.music = media as Music;
     this.path = music.MusicFiles.First();
 }