public void RecreateSite() { var newUtilInstance = Sites.SiteUtilFactory.CloneFreshSiteFromExisting(Site); OnlineVideoSettings.Instance.SiteUtilsList[Name] = newUtilInstance; _site = newUtilInstance; UserSettingsChanged = false; }
/// <summary> /// Gets an Url for the MediaPortal IPTV filter with user settings of the site applied. /// </summary> /// <param name="siteUtil">The <see cref="Sites.SiteUtilBase"/> instance with url settings.</param> /// <param name="url">A string containing the base64 encoded binary serialized data of a supported <see cref="SimpleUrl"/> inheriting class.</param> /// <returns></returns> public static String GetFilterUrl(Sites.SiteUtilBase siteUtil, String url) { int index = url.IndexOf(SimpleUrl.ParameterSeparator); SimpleUrl simpleUrl = null; if (index != -1) { String encodedContent = url.Substring(index + SimpleUrl.ParameterSeparator.Length); simpleUrl = SimpleUrl.FromString(encodedContent); if (simpleUrl == null) { throw new OnlineVideosException(Translation.Instance.UnableToPlayVideo); } } else { simpleUrl = UrlFactory.CreateUrl(url); if (simpleUrl == null) { return(url); } } //simpleUrl.CacheFolder =; simpleUrl.MaximumLogSize =; simpleUrl.MaximumPlugins =; simpleUrl.Verbosity =; if (siteUtil != null) { simpleUrl.ApplySettings(siteUtil); } return(simpleUrl.ToFilterString()); }
public static DownloadInfo Create(VideoInfo video, Category category, Sites.SiteUtilBase site) { DownloadInfo di = (DownloadInfo)CrossDomain.OnlineVideosAppDomain.Domain.CreateInstanceAndUnwrap(typeof(DownloadInfo).Assembly.FullName, typeof(DownloadInfo).FullName, false, System.Reflection.BindingFlags.CreateInstance | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, null, null, null, null); di.VideoInfo = video; di.Category = category; di.Util = site; return(di); }
public SiteViewModel(Sites.SiteUtilBase site) : base(Consts.KEY_NAME, site.Settings.Name) { _site = site; _nameProperty = new WProperty(typeof(string), site.Settings.Name); _languageProperty = new WProperty(typeof(string), site.Settings.Language); _descriptionProperty = new WProperty(typeof(string), site.Settings.Description); _contextMenuEntriesProperty = new WProperty(typeof(ItemsList), null); _settingsListProperty = new WProperty(typeof(ItemsList), null); }
string ApplyMPUrlSourceFilterSiteUserSettings(string url) { Sites.SiteUtilBase siteUtil = null; var item = GetOnlineVideosMediaItemFromPlayerContexts(); if (item != null) { OnlineVideoSettings.Instance.SiteUtilsList.TryGetValue(item.SiteName, out siteUtil); } return(MPUrlSourceFilter.UrlBuilder.GetFilterUrl(siteUtil, url)); }
public OnlineVideosGuiListItem(Sites.SiteUtilBase item) : base(item.Settings.Name) { Label2 = item.Settings.Language; IsFolder = true; Item = item; // use Icon with the same name as the Site string image = SiteImageExistenceCache.GetImageForSite(item.Settings.Name, item.Settings.UtilName, "Icon"); if (!string.IsNullOrEmpty(image)) { ThumbnailImage = image; IconImage = image; IconImageBig = image; } else { MediaPortal.Util.Utils.SetDefaultIcons(this); } }
protected override void OnShowContextMenu() { if (Gui2UtilConnector.Instance.IsBusy || BufferingPlayerFactory != null) return; // wait for any background action e.g. getting next page videos to finish if (CurrentState == State.sites && GetFocusControlId() == GUI_facadeView.GetID) { // handle a site's context menu OnlineVideosGuiListItem selectedItem = GUI_facadeView.SelectedListItem as OnlineVideosGuiListItem; if (selectedItem == null || selectedItem.Item == null) return; // only context menu for items with an object backing them Sites.SiteUtilBase aSite = selectedItem.Item as Sites.SiteUtilBase; if (aSite != null) { selectedSite = SiteUserSettingsDialog.ShowDialog(aSite); selectedItem.Item = selectedSite; } } else if (CurrentState == State.categories && GetFocusControlId() == GUI_facadeView.GetID) { // handle a category's context menu OnlineVideosGuiListItem selectedItem = GUI_facadeView.SelectedListItem as OnlineVideosGuiListItem; if (selectedItem == null || selectedItem.Item == null) return; // only context menu for items with an object backing them Category aCategory = selectedItem.Item as Category; if (aCategory != null && !(aCategory is NextPageCategory)) { GUIDialogMenu dlgCat = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); if (dlgCat == null) return; dlgCat.Reset(); dlgCat.SetHeading(Translation.Instance.Actions); List<KeyValuePair<string, Sites.ContextMenuEntry>> dialogOptions = new List<KeyValuePair<string, Sites.ContextMenuEntry>>(); if (!(SelectedSite is Sites.FavoriteUtil)) { if (selectedItem.IsPlayed) { dlgCat.Add(Translation.Instance.RemoveFromFavorites); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(Translation.Instance.RemoveFromFavorites, null)); } else { dlgCat.Add(Translation.Instance.AddToFavourites); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(Translation.Instance.AddToFavourites, null)); } } foreach (var entry in SelectedSite.GetContextMenuEntries(aCategory, null)) { dlgCat.Add(entry.DisplayText); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(entry.DisplayText, entry)); } dlgCat.DoModal(GUIWindowManager.ActiveWindow); if (dlgCat.SelectedId == -1) return; else { var selectedOption = dialogOptions[dlgCat.SelectedId - 1]; if (selectedOption.Value == null) { if (dlgCat.SelectedLabelText == Translation.Instance.AddToFavourites) { bool result = OnlineVideoSettings.Instance.FavDB.AddFavoriteCategory(aCategory, SelectedSite.Settings.Name); if (result) { cachedFavoritedCategoriesOfSelectedSite = default(KeyValuePair<string, List<string>>); selectedItem.IsPlayed = true; selectedItem.PinImage = SiteImageExistenceCache.GetImageForSite(Translation.Instance.Favourites, type: "Icon"); } } else if (dlgCat.SelectedLabelText == Translation.Instance.RemoveFromFavorites) { bool result = OnlineVideoSettings.Instance.FavDB.RemoveFavoriteCategory(SelectedSite.Settings.Name, aCategory.RecursiveName("|")); if (result) { cachedFavoritedCategoriesOfSelectedSite = default(KeyValuePair<string, List<string>>); selectedItem.IsPlayed = false; selectedItem.PinImage = ""; selectedItem.RefreshCoverArt(); } } } else { HandleCustomContextMenuEntry(selectedOption.Value, aCategory, null); } } } } else if ((CurrentState == State.videos && GetFocusControlId() == GUI_facadeView.GetID) || (CurrentState == State.details && GetFocusControlId() == GUI_infoList.GetID)) { // handle a video's context menu int numItemsShown = (CurrentState == State.videos ? GUI_facadeView.Count : GUI_infoList.Count) - 1; // first item is always ".." OnlineVideosGuiListItem selectedItem = CurrentState == State.videos ? GUI_facadeView.SelectedListItem as OnlineVideosGuiListItem : GUI_infoList.SelectedListItem as OnlineVideosGuiListItem; if (selectedItem == null || selectedItem.Item == null) return; // only context menu for items with an object backing them VideoInfo aVideo = selectedItem.Item as VideoInfo; if (aVideo != null) { GUIDialogMenu dlgSel = (GUIDialogMenu)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_MENU); if (dlgSel == null) return; dlgSel.Reset(); dlgSel.SetHeading(Translation.Instance.Actions); List<KeyValuePair<string, Sites.ContextMenuEntry>> dialogOptions = new List<KeyValuePair<string, Sites.ContextMenuEntry>>(); // these context menu entries should only show if the item will not go to the details view if (!(SelectedSite is IChoice && CurrentState == State.videos && aVideo.HasDetails)) { if (!(SelectedSite is Sites.FavoriteUtil && aVideo.HasDetails && (selectedCategory is Sites.FavoriteUtil.FavoriteCategory && (selectedCategory as Sites.FavoriteUtil.FavoriteCategory).Site is IChoice))) { dlgSel.Add(Translation.Instance.PlayWith); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("PlayWith", null)); if (numItemsShown > 1) { dlgSel.Add(Translation.Instance.PlayAll); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("PlayAll", null)); dlgSel.Add(Translation.Instance.PlayAllFromHere); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("PlayAllFromHere", null)); dlgSel.Add(Translation.Instance.PlayAllRandom); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("PlayAllRandom", null)); } if (SelectedSite.CanSearch) { // Add context keyword search dlgSel.Add(Translation.Instance.SearchRelatedKeywords); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("SearchKeywords", null)); } if (!(SelectedSite is Sites.FavoriteUtil) && !(SelectedSite is Sites.DownloadedVideoUtil)) { dlgSel.Add(Translation.Instance.AddToFavourites); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("AddToFav", null)); } if (!(SelectedSite is Sites.DownloadedVideoUtil)) { dlgSel.Add(string.Format("{0} ({1})", Translation.Instance.Download, Translation.Instance.Concurrent)); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("DownloadConcurrent", null)); dlgSel.Add(string.Format("{0} ({1})", Translation.Instance.Download, Translation.Instance.Queued)); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("DownloadQueued", null)); if (loadParamInfo != null && !string.IsNullOrEmpty(loadParamInfo.DownloadDir) && Directory.Exists(loadParamInfo.DownloadDir)) { if (string.IsNullOrEmpty(loadParamInfo.DownloadMenuEntry)) dlgSel.Add(Translation.Instance.DownloadUserdefined); else dlgSel.Add(loadParamInfo.DownloadMenuEntry); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("UserdefinedDownload", null)); } } foreach (var entry in SelectedSite.GetContextMenuEntries(selectedCategory, aVideo)) { dlgSel.Add(entry.DisplayText); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(entry.DisplayText, entry)); } } } // always allow the VK filtering in videos view if (CurrentState == State.videos && numItemsShown > 1) { dlgSel.Add(Translation.Instance.Filter); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>("Filter", null)); } if (dialogOptions.Count > 0) { dlgSel.DoModal(GUIWindowManager.ActiveWindow); if (dlgSel.SelectedId == -1) return; else { switch (dialogOptions[dlgSel.SelectedId - 1].Key) { case "PlayWith": dialogOptions.Clear(); dlgSel.Reset(); dlgSel.SetHeading(Translation.Instance.Actions); dlgSel.Add("MediaPortal"); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(OnlineVideos.PlayerType.Internal.ToString(), null)); dlgSel.Add("Windows Media Player"); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(OnlineVideos.PlayerType.WMP.ToString(), null)); if (VLCPlayer.IsInstalled) { dlgSel.Add("VLC media player"); dialogOptions.Add(new KeyValuePair<string, Sites.ContextMenuEntry>(OnlineVideos.PlayerType.VLC.ToString(), null)); } dlgSel.DoModal(GUIWindowManager.ActiveWindow); if (dlgSel.SelectedId == -1) return; else { OnlineVideos.PlayerType forcedPlayer = (OnlineVideos.PlayerType)Enum.Parse(typeof(OnlineVideos.PlayerType), dialogOptions[dlgSel.SelectedId - 1].Key); if (CurrentState == State.videos) selectedVideo = aVideo; else selectedClipIndex = GUI_infoList.SelectedListItemIndex; //play the video currentPlaylist = null; currentPlayingItem = null; Play_Step1(new PlayListItem(null, null) { Type = MediaPortal.Playlists.PlayListItem.PlayListItemType.VideoStream, Video = aVideo, Util = selectedSite is Sites.FavoriteUtil ? OnlineVideoSettings.Instance.SiteUtilsList[(selectedVideo as FavoriteDbVideoInfo).SiteName] : selectedSite, ForcedPlayer = forcedPlayer }, true); } break; case "PlayAll": PlayAll(); break; case "PlayAllFromHere": PlayAll(false, aVideo); break; case "PlayAllRandom": PlayAll(true); break; case "SearchKeywords": List<string> searchexpressions = new List<string> { selectedItem.Label }; if (selectedItem.Description.Length > 0) searchexpressions.Add(selectedItem.Description); ContextKeywordSelection(searchexpressions); break; case "AddToFav": string suggestedTitle = SelectedSite.GetFileNameForDownload(aVideo, selectedCategory, null); bool successAddingToFavs = OnlineVideoSettings.Instance.FavDB.AddFavoriteVideo(aVideo, suggestedTitle, SelectedSite.Settings.Name); GUIDialogNotify dlg = (GUIDialogNotify)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_NOTIFY); if (dlg != null) { dlg.Reset(); dlg.SetImage(SiteImageExistenceCache.GetImageForSite("OnlineVideos", type: "Icon")); dlg.SetHeading(successAddingToFavs ? Translation.Instance.Success : Translation.Instance.Error); dlg.SetText(Translation.Instance.AddingToFavorites); dlg.DoModal(GUIWindowManager.ActiveWindow); } break; case "DownloadConcurrent": SaveVideo_Step1(DownloadList.Create(DownloadInfo.Create(aVideo, selectedCategory, selectedSite))); break; case "DownloadQueued": SaveVideo_Step1(DownloadList.Create(DownloadInfo.Create(aVideo, selectedCategory, selectedSite)), true); break; case "UserdefinedDownload": var dlInfo = DownloadInfo.Create(aVideo, selectedCategory, selectedSite); dlInfo.OverrideFolder = loadParamInfo.DownloadDir; dlInfo.OverrideFileName = loadParamInfo.DownloadFilename; SaveVideo_Step1(DownloadList.Create(dlInfo)); break; case "Filter": if (GetUserInputString(ref videosVKfilter, false)) SetVideosToFacade(currentVideoList, currentVideosDisplayMode); break; default: HandleCustomContextMenuEntry(dialogOptions[dlgSel.SelectedId - 1].Value, selectedCategory, aVideo); break; } } } } } }
internal override void ApplySettings(Sites.SiteUtilBase siteUtil) { siteUtil.HttpSettings.Apply(this); }
public static Sites.SiteUtilBase ShowDialog(Sites.SiteUtilBase selectedSite) { List <OnlineVideos.Reflection.FieldPropertyDescriptorByRef> actualProps = selectedSite.GetUserConfigurationProperties(); // limit to what the UI can show actualProps = actualProps.Where(prop => (prop.IsEnum || prop.Namespace == "System")).ToList(); if (actualProps.Count > 0) { bool changes = false; int selectIndex = 0; do { int windowId = GUIDialogSiteUserSettings.GUIDIALOGMENU_ONLINEVIDEO; // try our special dialog first GUIDialogMenu dlgSiteOptions = (GUIDialogMenu)GUIWindowManager.GetWindow(windowId) as GUIDialogSiteUserSettings; if (dlgSiteOptions == null || !((GUIDialogSiteUserSettings)dlgSiteOptions).IsAvailable) // if not available use the default one { windowId = (int)GUIWindow.Window.WINDOW_DIALOG_MENU; dlgSiteOptions = (GUIDialogMenu)GUIWindowManager.GetWindow(windowId); } if (dlgSiteOptions == null) { return(selectedSite); } dlgSiteOptions.Reset(); dlgSiteOptions.SetHeading(string.Format("{0}: {1}", selectedSite.Settings.Name, GUILocalizeStrings.Get(5))); foreach (var ovsUserCfg in actualProps) { /*object valueO = ovsUserCfg.GetValue(selectedSite); * string value = valueO != null ? valueO.ToString() : string.Empty;*/ string value = selectedSite.GetConfigValueAsString(ovsUserCfg); if (ovsUserCfg.IsPassword) { value = new string('*', value.Length); } string desc = ovsUserCfg.Description; dlgSiteOptions.Add(new GUIListItem(ovsUserCfg.DisplayName, value, "", false, null) { // don't set Label3 if we are not using our custom dialog Label3 = windowId == GUIDialogSiteUserSettings.GUIDIALOGMENU_ONLINEVIDEO && !string.IsNullOrEmpty(desc) ? desc : string.Empty }); } dlgSiteOptions.SelectedLabel = selectIndex; dlgSiteOptions.DoModal(GUIWindowManager.ActiveWindow); selectIndex = dlgSiteOptions.SelectedLabel; if (dlgSiteOptions.SelectedId == -1) { break; } else { OnlineVideos.Reflection.FieldPropertyDescriptorByRef prop = actualProps.First(a => a.DisplayName == dlgSiteOptions.SelectedLabelText); if (prop.IsBool) { bool currVal = selectedSite.GetConfigValueAsString(prop) == true.ToString(); selectedSite.SetConfigValueFromString(prop, (!currVal).ToString()); changes = true; } else if (prop.IsEnum) { GUIDialogMenu dlgEnum = (GUIDialogMenu)GUIWindowManager.GetWindow(windowId); dlgEnum.Reset(); dlgEnum.SetHeading(string.Format("{0}: {1}", selectedSite.Settings.Name, prop.DisplayName)); string value = selectedSite.GetConfigValueAsString(prop); int i = 0; foreach (string e in prop.GetEnumValues()) { dlgEnum.Add(e); if (e == value) { dlgEnum.SelectedLabel = i; } i++; } dlgEnum.DoModal(GUIWindowManager.ActiveWindow); if (dlgEnum.SelectedId != -1) { if (value != dlgEnum.SelectedLabelText) { selectedSite.SetConfigValueFromString(prop, dlgEnum.SelectedLabelText); changes = true; } } } else { string value = selectedSite.GetConfigValueAsString(prop); string newValue = (string)value.Clone(); if (GUIOnlineVideos.GetUserInputString(ref newValue, prop.IsPassword)) { if (value != newValue) { try { selectedSite.SetConfigValueFromString(prop, newValue); changes = true; } catch (Exception ex) { // conversion from string not possible, show error GUIDialogOK dlg_error = (GUIDialogOK)GUIWindowManager.GetWindow((int)GUIWindow.Window.WINDOW_DIALOG_OK); if (dlg_error != null) { dlg_error.Reset(); dlg_error.SetHeading(PluginConfiguration.Instance.BasicHomeScreenName); dlg_error.SetLine(1, Translation.Instance.Error); dlg_error.SetLine(2, ex.Message); dlg_error.DoModal(GUIWindowManager.ActiveWindow); } } } } } } } while (true); if (changes) { var newUtilInstance = Sites.SiteUtilFactory.CloneFreshSiteFromExisting(selectedSite); OnlineVideoSettings.Instance.SiteUtilsList[newUtilInstance.Settings.Name] = newUtilInstance; return(newUtilInstance); } } return(selectedSite); }
internal abstract void ApplySettings(Sites.SiteUtilBase siteUtil);
/// <summary> /// This function can be called by a background thread. It finishes building the graph and /// waits until the buffer is filled to the configured percentage. /// If a filter in the graph requires the full file to be downloaded, the function will return only afterwards. /// </summary> /// <returns>true, when playback can be started</returns> public bool BufferFile(Sites.SiteUtilBase siteUtil) { Thread renderPinsThread = null; VideoRendererStatistics.VideoState = VideoRendererStatistics.State.VideoPresent; // prevents the BlackRectangle on first time playback bool PlaybackReady = false; IBaseFilter sourceFilter = null; string sourceFilterName = null; try { sourceFilterName = GetSourceFilterName(m_strCurrentFile); int result = graphBuilder.FindFilterByName(sourceFilterName, out sourceFilter); if (result != 0) { string errorText = DirectShowLib.DsError.GetErrorText(result); if (errorText != null) { errorText = errorText.Trim(); } Log.Instance.Warn("BufferFile : FindFilterByName returned '{0}'{1}", "0x" + result.ToString("X8"), !string.IsNullOrEmpty(errorText) ? " : (" + errorText + ")" : ""); return(false); } OnlineVideos.MPUrlSourceFilter.IFilterStateEx filterStateEx = sourceFilter as OnlineVideos.MPUrlSourceFilter.IFilterStateEx; if (filterStateEx != null) { // MediaPortal IPTV filter and url source splitter Log.Instance.Info("BufferFile : using 'MediaPortal IPTV filter and url source splitter' as source filter"); String url = OnlineVideos.MPUrlSourceFilter.UrlBuilder.GetFilterUrl(siteUtil, m_strCurrentFile); Log.Instance.Info("BufferFile : loading url: '{0}'", url); result = filterStateEx.LoadAsync(url); if (result < 0) { throw new OnlineVideosException(FilterError.ErrorDescription(filterStateEx, result)); } while (!this.BufferingStopped) { Boolean opened = false; result = filterStateEx.IsStreamOpened(out opened); if (result < 0) { throw new OnlineVideosException(FilterError.ErrorDescription(filterStateEx, result)); } if (opened) { break; } Thread.Sleep(1); } // buffer before starting playback bool filterConnected = false; bool filterIsReadyToConnect = false; percentageBuffered = 0.0f; long total = 0, current = 0, last = 0; while (!PlaybackReady && graphBuilder != null && !BufferingStopped) { result = ((IAMOpenProgress)sourceFilter).QueryProgress(out total, out current); if ((result != 0) && (result != 0x00040260)) { // 0x00040260 - VFW_S_ESTIMATED - correct state, but value is estimated throw new OnlineVideosException(FilterError.ErrorDescription(filterStateEx, result)); } result = filterStateEx.IsFilterReadyToConnectPins(out filterIsReadyToConnect); if (result != 0) { throw new OnlineVideosException(FilterError.ErrorDescription(filterStateEx, result)); } percentageBuffered = (float)current / (float)total * 100.0f; // after configured percentage has been buffered, connect the graph if (!filterConnected && (percentageBuffered >= PluginConfiguration.Instance.playbuffer || skipBuffering)) { if (filterIsReadyToConnect) { result = filterStateEx.GetCacheFileName(out cacheFile); if (result != 0) { throw new OnlineVideosException(FilterError.ErrorDescription(filterStateEx, result)); } if (skipBuffering) { Log.Instance.Debug("Buffering skipped at {0}%", percentageBuffered); } filterConnected = true; renderPinsThread = new Thread(delegate() { try { Log.Instance.Debug("BufferFile : Rendering unconnected output pins of source filter ..."); // add audio and video filter from MP Movie Codec setting section AddPreferredFilters(graphBuilder, sourceFilter); // connect the pin automatically -> will buffer the full file in cases of bad metadata in the file or request of the audio or video filter DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, sourceFilter); Log.Instance.Debug("BufferFile : Playback Ready."); PlaybackReady = true; } catch (ThreadAbortException) { Thread.ResetAbort(); Log.Instance.Info("RenderUnconnectedOutputPins foribly aborted."); } catch (Exception ex) { Log.Instance.Warn(ex.Message); StopBuffering(); } }) { IsBackground = true, Name = "OVGraph" }; renderPinsThread.Start(); } } // log every percent if (current > last && current - last >= (double)total * 0.01) { Log.Instance.Debug("Buffering: {0}/{1} KB ({2}%)", current / 1024, total / 1024, (int)percentageBuffered); last = current; } // set the percentage to a gui property, formatted according to percentage, so the user knows very early if anything is buffering string formatString = "###"; if (percentageBuffered == 0f) { formatString = "0.0"; } else if (percentageBuffered < 1f) { formatString = ".00"; } else if (percentageBuffered < 10f) { formatString = "0.0"; } else if (percentageBuffered < 100f) { formatString = "##"; } GUIPropertyManager.SetProperty("#OnlineVideos.buffered", percentageBuffered.ToString(formatString, System.Globalization.CultureInfo.InvariantCulture)); Thread.Sleep(50); // no need to do this more often than 20 times per second } } else { Marshal.ThrowExceptionForHR(((IFileSourceFilter)sourceFilter).Load(m_strCurrentFile, null)); Log.Instance.Info("BufferFile : using unknown filter as source filter"); if (sourceFilter is IAMOpenProgress && !m_strCurrentFile.Contains("live=true") && !m_strCurrentFile.Contains("RtmpLive=1")) { // buffer before starting playback bool filterConnected = false; percentageBuffered = 0.0f; long total = 0, current = 0, last = 0; do { result = ((IAMOpenProgress)sourceFilter).QueryProgress(out total, out current); Marshal.ThrowExceptionForHR(result); percentageBuffered = (float)current / (float)total * 100.0f; // after configured percentage has been buffered, connect the graph if (!filterConnected && (percentageBuffered >= PluginConfiguration.Instance.playbuffer || skipBuffering)) { //cacheFile = filterState.GetCacheFileName(); if (skipBuffering) { Log.Instance.Debug("Buffering skipped at {0}%", percentageBuffered); } filterConnected = true; renderPinsThread = new Thread(delegate() { try { Log.Instance.Debug("BufferFile : Rendering unconnected output pins of source filter ..."); // add audio and video filter from MP Movie Codec setting section AddPreferredFilters(graphBuilder, sourceFilter); // connect the pin automatically -> will buffer the full file in cases of bad metadata in the file or request of the audio or video filter DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, sourceFilter); Log.Instance.Debug("BufferFile : Playback Ready."); PlaybackReady = true; } catch (ThreadAbortException) { Thread.ResetAbort(); Log.Instance.Info("RenderUnconnectedOutputPins foribly aborted."); } catch (Exception ex) { Log.Instance.Warn(ex.Message); StopBuffering(); } }) { IsBackground = true, Name = "OVGraph" }; renderPinsThread.Start(); } // log every percent if (current > last && current - last >= (double)total * 0.01) { Log.Instance.Debug("Buffering: {0}/{1} KB ({2}%)", current / 1024, total / 1024, (int)percentageBuffered); last = current; } // set the percentage to a gui property, formatted according to percentage, so the user knows very early if anything is buffering string formatString = "###"; if (percentageBuffered == 0f) { formatString = "0.0"; } else if (percentageBuffered < 1f) { formatString = ".00"; } else if (percentageBuffered < 10f) { formatString = "0.0"; } else if (percentageBuffered < 100f) { formatString = "##"; } GUIPropertyManager.SetProperty("#OnlineVideos.buffered", percentageBuffered.ToString(formatString, System.Globalization.CultureInfo.InvariantCulture)); Thread.Sleep(50); // no need to do this more often than 20 times per second }while (!PlaybackReady && graphBuilder != null && !BufferingStopped); } else { // add audio and video filter from MP Movie Codec setting section AddPreferredFilters(graphBuilder, sourceFilter); // connect the pin automatically -> will buffer the full file in cases of bad metadata in the file or request of the audio or video filter DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, sourceFilter); percentageBuffered = 100.0f; // no progress reporting possible GUIPropertyManager.SetProperty("#TV.Record.percent3", percentageBuffered.ToString()); PlaybackReady = true; } } } catch (ThreadAbortException) { Thread.ResetAbort(); } catch (OnlineVideosException) { throw; } catch (COMException comEx) { Log.Instance.Warn(comEx.ToString()); string errorText = DirectShowLib.DsError.GetErrorText(comEx.ErrorCode); if (errorText != null) { errorText = errorText.Trim(); } if (!string.IsNullOrEmpty(errorText)) { throw new OnlineVideosException(errorText); } } catch (Exception ex) { Log.Instance.Warn(ex.ToString()); } finally { if (sourceFilter != null) { // the render pin thread was already started and is still runnning if (renderPinsThread != null && (renderPinsThread.ThreadState & ThreadState.Stopped) == 0) { // buffering was stopped by the user -> abort the thread if (BufferingStopped) { renderPinsThread.Abort(); } } // playback is not ready but the source filter is already downloading -> abort the operation if (!PlaybackReady) { Log.Instance.Info("Buffering was aborted."); if (sourceFilter is IAMOpenProgress) { ((IAMOpenProgress)sourceFilter).AbortOperation(); } Thread.Sleep(100); // give it some time int result = graphBuilder.RemoveFilter(sourceFilter); // remove the filter from the graph to prevent lockup later in Dispose } // release the COM pointer that we created DirectShowUtil.ReleaseComObject(sourceFilter); } } return(PlaybackReady); }