public byte[] GetVideo(VideoMetaData vmd) { if (_cachedVideos.Keys.Contains(vmd.Id)) { _cacheTimeout.AddOrUpdate(vmd.Id, new Timer(_videoRepositoryOptions.CacheTimeout), (timerKey, timer) => { timer = new Timer(_videoRepositoryOptions.CacheTimeout); timer.Elapsed += (o, args) => ElapseEvent(vmd.Id); timer.Start(); return(timer); }); return(_cachedVideos[vmd.Id]); } else { //Path to file var path = Path.Combine(_fileStoreOptions.VideoPath, vmd.Id.ToString(), vmd.FileName); //Add or get file from cache var videoFile = _cachedVideos.GetOrAdd(vmd.Id, GetNewFile(path)); //Update or add timer. _cacheTimeout.AddOrUpdate(vmd.Id, new Timer(_videoRepositoryOptions.CacheTimeout), (timerKey, timer) => { timer = new Timer(_videoRepositoryOptions.CacheTimeout); timer.Elapsed += (o, args) => ElapseEvent(vmd.Id); timer.Start(); return(timer); }); //return video byte[] return(videoFile); } }
public override List <VideoMetaData> GetAll(int max_results) { if (s_metaDataList == null) { Dictionary <string, VideoMetaData> l = new Dictionary <string, VideoMetaData>(); VideoMetaData video1 = new VideoMetaData(); video1.Id = "AzureMediaServicesOverview"; video1.PubDate = DateTime.Now; video1.VideoLink = new Uri("http://amssamples.streaming.mediaservices.windows.net/91492735-c523-432b-ba01-faba6c2206a2/AzureMediaServicesPromo.ism/manifest(format=m3u8-aapl)"); video1.Title = "Azure Media Services Overview"; video1.WebPageLink = new Uri("http://amsplayer.azurewebsites.net/amssamples.html"); video1.License = "(C) Microsoft Coorporation | All Rights Reserved"; video1.Thumbnail = new Uri("http://t3.gstatic.com/images?q=tbn:ANd9GcRoTu81vs8GuQtJBGUZ0pLEiNHVVx3dFwHsu7JCkvGop8Z-98EsPg"); l.Add(video1.Id, video1); VideoMetaData video2 = new VideoMetaData(); video2.Id = "BigBuckBunnyTrailer"; video2.PubDate = DateTime.Now; video2.VideoLink = new Uri("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_surround-fix.avi"); video2.Title = "Big Buck Bunny"; video2.WebPageLink = new Uri("https://peach.blender.org/"); video2.License = "(CC) Blender Foundation | peach.blender.org"; video2.Thumbnail = new Uri("http://t0.gstatic.com/images?q=tbn:ANd9GcQT54UKh0zX5OUDNLRyXOOwt3pqj0lpaLCJebucva2LSV49aGjRfg"); l.Add(video2.Id, video2); VideoMetaData video3 = new VideoMetaData(); video3.Id = "bc57e088-27ec-44e0-ac20-a85ccbcd50da"; video3.PubDate = DateTime.Now; video3.VideoLink = new Uri("http://amssamples.streaming.mediaservices.windows.net/bc57e088-27ec-44e0-ac20-a85ccbcd50da/TearsOfSteel.ism/manifest(format=mpd-time-csf)"); video3.Title = "Tears of Steel"; video3.WebPageLink = new Uri("https://mango.blender.org/"); video3.License = "(CC) Blender Foundation | durian.blender.org/"; video3.Thumbnail = new Uri("http://t3.gstatic.com/images?q=tbn:ANd9GcQO0MMO_vXf8Q1zjZWLHa1_566Mf_jty6vJKRi9R-C_0W-gXnNOog"); l.Add(video3.Id, video3); //VideoMetaData video4 = new VideoMetaData(); //video4.Id = "b6822ec8-5c2b-4ae0-a851-fd46a78294e9"; //video4.PubDate = DateTime.Now; //video4.VideoLink = new Uri("http://amssamples.streaming.mediaservices.windows.net/b6822ec8-5c2b-4ae0-a851-fd46a78294e9/ElephantsDream.ism/manifest(filtername=FirstFilter,format=mpd-time-csf)"); //video4.Title = "Elephants Dream"; //video4.WebPageLink = new Uri("https://orange.blender.org/"); //video4.License = "(c) copyright 2006, Blender Foundation / Netherlands Media Art Institute / www.elephantsdream.org"; //video4.Thumbnail = new Uri("https://orange.blender.org/wp-content/uploads/2006/05/edscore_cover_l.jpg"); //l.Add(video4.Id, video4); VideoMetaData video5 = new VideoMetaData(); video5.Id = "49b57c87-f5f3-48b3-ba22-c55cfdffa9cb"; video5.PubDate = DateTime.Now; video5.VideoLink = new Uri("http://amssamples.streaming.mediaservices.windows.net/49b57c87-f5f3-48b3-ba22-c55cfdffa9cb/Sintel.ism/manifest(format=m3u8-aapl)"); video5.Title = "Sintel"; video5.WebPageLink = new Uri("https://durian.blender.org/"); video5.License = "© copyright Blender Foundation | www.sintel.org"; video5.Thumbnail = new Uri("https://durian.blender.org/wp-content/uploads/2010/05/sintel_trailer_1080.jpg"); l.Add(video5.Id, video5); s_metaDataList = l; } return(s_metaDataList.Values.ToList <VideoMetaData>()); }
public Scenario01() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetFromID("BigBuckBunnyTrailer"); this.player.Source = video.VideoLink; //Set the source on the MediaElement rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); // Use the compat version of the transport controls this.player.TransportControls.IsCompact = true; //Start Playback player.Play(); }
public void Put(Guid id, [FromBody] VideoMetaData vmd) { var existingEntity = _dbContext.Videos.FirstOrDefault(v => v.Id == vmd.Id); existingEntity = vmd; _dbContext.SaveChanges(); }
protected override void OnNavigatedTo(NavigationEventArgs e) { rootPage = MainPage.Current; if (e.Parameter is DialReceiverActivatedEventArgs) { DialReceiverActivatedEventArgs activationArgs = (DialReceiverActivatedEventArgs)e.Parameter; //Parse the DIAL arguments from the activation arguments DialLaunchArguments dialArgs = DialLaunchArguments.Parse(activationArgs.Arguments); // Get the list of available Azure videos. AzureDataProvider dataProvider = new AzureDataProvider(); // Get the vide that is playing video = dataProvider.GetFromID(dialArgs.VideoId); //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); this.player.Source = video.VideoLink; player.Position = dialArgs.Position; } else { rootPage.NotifyUser("Scenario was not activated using DIAL", NotifyType.ErrorMessage); } }
public Scenario3() { this.InitializeComponent(); rootPage = MainPage.Current; // Get the list of available Azure videos. AzureDataProvider dataProvider = new AzureDataProvider(); List <VideoMetaData> videos = dataProvider.GetAll(MAX_RESULTS); Random indexRandomizer = new Random(); // Pick a random video video = videos[indexRandomizer.Next(0, videos.Count - 1)]; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; //Set the look and feel of the TransportControls player.TransportControls.IsCompact = true; //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); player.Source = video.VideoLink; this.dial_launch_args_textbox.Text = string.Format("v={0}&t=0&pairingCode=E4A8136D-BCD3-45F4-8E49-AE01E9A46B5F", video.Id); }
public override VideoMetaData GetFromID(string id) { if (s_metaDataList == null) { GetAll(20); } VideoMetaData video = s_metaDataList[id]; return(video); }
public Scenario2() { this.InitializeComponent(); rootPage = MainPage.Current; // Get the list of available Azure videos. AzureDataProvider dataProvider = new AzureDataProvider(); List <VideoMetaData> videos = dataProvider.GetAll(MAX_RESULTS); Random indexRandomizer = new Random(); // Pick a random video video = videos[indexRandomizer.Next(0, videos.Count - 1)]; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; //Set the look and feel of the TransportControls player.TransportControls.IsCompact = true; //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); player.Source = video.VideoLink; //Configure the DIAL launch arguments for the current video this.dial_launch_args_textbox.Text = string.Format("v={0}&t=0&pairingCode=E4A8136D-BCD3-45F4-8E49-AE01E9A46B5F", video.Id); //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new DevicePicker(); //Hook up device selected event picker.DeviceSelected += Picker_DeviceSelected; //Hook up device disconnected event picker.DisconnectButtonClicked += Picker_DisconnectButtonClicked; //Hook up device disconnected event picker.DevicePickerDismissed += Picker_DevicePickerDismissed; ////Set the Appearence of the picker //picker.Appearance.BackgroundColor = Colors.Black; //picker.Appearance.ForegroundColor = Colors.White; //picker.Appearance.SelectedAccentColor = Colors.LightGray; //picker.Appearance.SelectedForegroundColor = Colors.White; //picker.Appearance.AccentColor = Colors.White; //picker.Appearance.SelectedAccentColor = Colors.White; pvb.ProjectionStopping += Pvb_ProjectionStopping; }
public Scenario06() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetRandomVideo(); //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); this.player.Source = video.VideoLink; this.LicenseText.Text = "License: " + video.License; //Configure the DIAL launch arguments for the current video this.dial_launch_args_textbox.Text = string.Format("v={0}&t=0&pairingCode=E4A8136D-BCD3-45F4-8E49-AE01E9A46B5F", video.Id); //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new DevicePicker(); //Hook up device selected event picker.DeviceSelected += Picker_DeviceSelected; //Hook up device disconnected event picker.DisconnectButtonClicked += Picker_DisconnectButtonClicked; //Hook up device disconnected event picker.DevicePickerDismissed += Picker_DevicePickerDismissed; //Add the DIAL Filter, so that the application only shows DIAL devices that have the application installed or advertise that they can install them. //BUG: picker.Filter.SupportedDeviceSelectors.Add(DialDevice.GetDeviceSelector(this.dial_appname_textbox.Text)); picker.Filter.SupportedDeviceSelectors.Add("System.Devices.DevObjectType:=6 AND System.Devices.AepContainer.ProtocolIds:~~{0E261DE4-12F0-46E6-91BA-428607CCEF64} AND System.Devices.AepContainer.Categories:~~Multimedia.ApplicationLauncher.DIAL"); //Add the CAST API Filter, so that the application only shows Miracast, Bluetooth, DLNA devices that can render the video // BUG: picker.Filter.SupportedDeviceSelectors.Add(await CastingDevice.GetDeviceSelectorFromCastingSourceAsync(player.GetAsCastingSource())); // BUG: picker.Filter.SupportedDeviceSelectors.Add(CastingDevice.GetDeviceSelector(CastingPlaybackTypes.Video)); picker.Filter.SupportedDeviceSelectors.Add("System.Devices.InterfaceClassGuid:=\"{D0875FB4-2196-4c7a-A63D-E416ADDD60A1}\"" + " AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True"); //Add projection manager filter picker.Filter.SupportedDeviceSelectors.Add(ProjectionManager.GetDeviceSelector()); pvb.ProjectionStopping += Pvb_ProjectionStopping; }
private VideoMetaData ExtractMetadata(ConversionJobOptions cjo) { // Extract the video metadata first - we DO NOT download the information now since // 1. This will hang the thread and we have a queue lock already here, so the GUI will hang // 2. We dont' need the additional information, the information about Filename, Show and Network are already available in existing metadata is not overwritten/supplemented by internet data Log.AppLog.WriteEntry("Extracting metadata from file " + cjo.sourceVideo, Log.LogEntryType.Information); VideoMetaData metaData = new VideoMetaData(cjo, new JobStatus(), Log.AppLog, true); // Do NOT download internet information metaData.Extract(true); // Ignore the suspend since we have a Queue lock right now otherwise the engine will hang if the user pauses return(metaData); }
public ActionResult Post([FromBody] VideoMetaData vmd) { if (!ModelState.IsValid) { return(BadRequest()); } _dbContext.Videos.Add(vmd); _dbContext.SaveChanges(); return(Created("Media/", vmd)); }
private IMediaMetaData GetMetaData(string mediaType) { IMediaMetaData result = default(IMediaMetaData); switch (mediaType) { case "Video": result = new VideoMetaData() as IMediaMetaData; break; case "Audio": result = new AudioMetaData() as IMediaMetaData; break; } return(result); }
public Scenario03() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetRandomVideo(); //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); this.player.PosterSource = new BitmapImage(video.Thumbnail); this.player.Source = video.VideoLink; //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; //Configure the DIAL launch arguments for the current video this.dial_launch_args_textbox.Text = string.Format("v={0}&t=0&pairingCode=E4A8136D-BCD3-45F4-8E49-AE01E9A46B5F", video.Id); //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new DialDevicePicker(); //Add the DIAL Filter, so that the application only shows DIAL devices that have // the application installed or advertise that they can install them. picker.Filter.SupportedAppNames.Add(this.dial_appname_textbox.Text); //Hook up device selected event picker.DialDeviceSelected += Picker_DialDeviceSelected; //Hook up the picker disconnected event picker.DisconnectButtonClicked += Picker_DisconnectButtonClicked; //Hook up the picker dismissed event picker.DialDevicePickerDismissed += Picker_DialDevicePickerDismissed; }
public Scenario02() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetRandomVideo(); //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); player.Source = video.VideoLink; this.LicenseText.Text = "License: " + video.License; //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new CastingDevicePicker(); // Generate the filter based on the content in the MediaElement picker.Filter.SupportedCastingSources.Add(player.GetAsCastingSource()); //Hook up device selected event picker.CastingDeviceSelected += Picker_CastingDeviceSelected; //Hook up device disconnected event picker.CastingDevicePickerDismissed += Picker_CastingDevicePickerDismissed; //Set the Appearence of the picker picker.Appearance.BackgroundColor = Colors.Black; picker.Appearance.ForegroundColor = Colors.White; picker.Appearance.AccentColor = Colors.Gray; picker.Appearance.SelectedAccentColor = Colors.Gray; picker.Appearance.SelectedForegroundColor = Colors.White; picker.Appearance.SelectedBackgroundColor = Colors.Black; }
public Scenario05() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetRandomVideo(); //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); this.player.Source = video.VideoLink; this.LicenseText.Text = "License: " + video.License; //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new DevicePicker(); // Get the device selecter for Miracast devices picker.Filter.SupportedDeviceSelectors.Add(ProjectionManager.GetDeviceSelector()); //Hook up device selected event picker.DeviceSelected += Picker_DeviceSelected; //Hook up device disconnected event picker.DisconnectButtonClicked += Picker_DisconnectButtonClicked; //Hook up picker dismissed event picker.DevicePickerDismissed += Picker_DevicePickerDismissed; // Hook up the events that are received when projection is stoppped pvb.ProjectionStopping += Pvb_ProjectionStopping; }
public async Task <List <VideoMetaData> > GetAllVideos() { var allFiles = _storageManager.GetAllFilesInContainer(_containerName); if (allFiles.Result == null) { return(new List <VideoMetaData>()); } var resultList = new List <VideoMetaData>(); var currentVideo = new VideoMetaData(); foreach (var listBlobItem in allFiles.Result)//NOTE: Assuming here that a thumbnail will be immediately followed by its corresponding mp4 file { if (listBlobItem.Name.Contains("thumbnail")) { currentVideo = new VideoMetaData(); var thumbnail = new byte[listBlobItem.Properties.Length]; for (var k = 0; k < listBlobItem.Properties.Length; k++) { thumbnail[k] = 0x20; } await listBlobItem.DownloadToByteArrayAsync(thumbnail, 0); currentVideo.Thumbnail = thumbnail; } else { currentVideo.Id = listBlobItem.Name.Replace(".mp4", ""); if (listBlobItem.Properties.LastModified != null) { currentVideo.DateStored = listBlobItem.Properties.LastModified.Value.DateTime; } listBlobItem.Metadata.TryGetValue("duration", out var time); currentVideo.Duration = int.Parse(time ?? Empty); listBlobItem.Metadata.TryGetValue("originalName", out var oldName); currentVideo.Name = oldName; resultList.Add(currentVideo); } } return(resultList); }
public Live() { this.InitializeComponent(); player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get an Azure hosted video VideoDataProvider dataProvider = new VideoDataProvider(); video = dataProvider.GetRandomVideo(); //Set the source on the player player.Source = video.VideoLink; //Subscribe for the clicked event on the custom cast button ((MediaTransportControlsWithCustomCastButton)this.player.TransportControls).CastButtonClicked += TransportControls_CastButtonClicked; // Instantiate the Device Picker picker = new CastingDevicePicker(); // Generate the filter based on the content in the MediaElement picker.Filter.SupportedCastingSources.Add(player.GetAsCastingSource()); //Hook up device selected event picker.CastingDeviceSelected += Picker_CastingDeviceSelected; //Hook up device disconnected event picker.CastingDevicePickerDismissed += Picker_CastingDevicePickerDismissed; //Set the Appearence of the picker picker.Appearance.BackgroundColor = Colors.Black; picker.Appearance.ForegroundColor = Colors.White; picker.Appearance.AccentColor = Colors.Gray; picker.Appearance.SelectedAccentColor = Colors.Gray; picker.Appearance.SelectedForegroundColor = Colors.White; picker.Appearance.SelectedBackgroundColor = Colors.Black; }
protected async override void OnNavigatedTo(NavigationEventArgs e) { rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; player.MediaEnded += Player_MediaEnded; if (e.Parameter is DialReceiverActivatedEventArgs) { DialReceiverActivatedEventArgs activationArgs = (DialReceiverActivatedEventArgs)e.Parameter; //Parse the DIAL arguments from the activation arguments DialLaunchArguments dialArgs = DialLaunchArguments.Parse(activationArgs.Arguments); // Get the list of available Azure videos. AzureDataProvider dataProvider = new AzureDataProvider(); // Get the vide that is playing video = dataProvider.GetFromID(dialArgs.VideoId); //Set the source on the player rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); this.player.Source = video.VideoLink; this.LicenseText.Text = "License: " + video.License; player.Position = dialArgs.Position; } else { StorageFile localVideo = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/casting.mp4")); var stream = await localVideo.OpenAsync(FileAccessMode.Read); this.player.SetSource(stream, localVideo.FileType); } }
public Scenario01() { this.InitializeComponent(); rootPage = MainPage.Current; //Subscribe to player events player.MediaOpened += Player_MediaOpened; player.MediaFailed += Player_MediaFailed; player.CurrentStateChanged += Player_CurrentStateChanged; // Get a video AzureDataProvider dataProvider = new AzureDataProvider(); video = dataProvider.GetRandomVideo(); this.player.Source = video.VideoLink; this.LicenseText.Text = "License: " + video.License; //Set the source on the MediaElement rootPage.NotifyUser(string.Format("Opening '{0}'", video.Title), NotifyType.StatusMessage); // Use the compat version of the transport controls this.player.TransportControls.IsCompact = true; }
private static VideoMetaData CreateVideoMetaData(string path) { string mediaType = string.Empty; new FileExtensionContentTypeProvider() .TryGetContentType(Path.Combine(_fileStoreOptions.DumpPath + path), out mediaType); if (!mediaType.CompatibilityCheck()) { throw new UnsupportedFileException(Path.GetFileName(path), mediaType, "Incompatible media type"); } var movieEntity = new VideoMetaData() { Title = Path.GetFileNameWithoutExtension(path), FileName = Path.GetFileName(path), MediaType = mediaType, FileSize = new FileInfo(path).Length, MD5 = path.GetMd5(), CoverArt = _defaultImagedata, CoverArtContentType = "image/png" }; return(movieEntity); }
/// <summary> /// Match the series information by Original Broadcast date /// </summary> private static bool MatchByBroadcastTime(VideoTags videoTags, string seriesID, bool dontOverwriteTitle, Log jobLog) { // If we have no original broadcasttime if (videoTags.OriginalBroadcastDateTime <= Globals.GlobalDefs.NO_BROADCAST_TIME) { jobLog.WriteEntry("No original broadcast date time", Log.LogEntryType.Debug); return(false); } // ************************************** // Get the series and episode information // ************************************** string lang = Localise.TwoLetterISO(); if (!((IList <string>)THETVDB_SUPPORTED_LANGUAGES).Contains(lang)) { lang = "en"; } string queryUrl = "http://www.thetvdb.com/api/" + MCEBUDDY_THETVDB_API_KEY + "/series/" + seriesID + "/all/" + lang + ".xml"; XPathDocument XpS; XPathNavigator NavS; XPathExpression ExpS; XPathNodeIterator ItrS; string overview = ""; string seriesName = ""; string bannerUrl = ""; string imdbID = ""; string firstAiredStr = ""; DateTime firstAired = GlobalDefs.NO_BROADCAST_TIME; int seasonNo = 0; int episodeNo = 0; string episodeName = ""; string episodeOverview = ""; string network = ""; DateTime premiereDate = GlobalDefs.NO_BROADCAST_TIME; List <string> genres = new List <string>(); try { // Get the Series information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Series"); // Series information ItrS = NavS.Select(ExpS); ItrS.MoveNext(); seriesName = XML.GetXMLTagValue("SeriesName", ItrS.Current.OuterXml); overview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("poster", ItrS.Current.OuterXml))) // We get the poster first { if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("fanart", ItrS.Current.OuterXml))) // We get the fanart next { bannerUrl = XML.GetXMLTagValue("banner", ItrS.Current.OuterXml); // We get the banner last } } imdbID = XML.GetXMLTagValue("IMDB_ID", ItrS.Current.OuterXml); network = XML.GetXMLTagValue("Network", ItrS.Current.OuterXml); DateTime.TryParse(XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml), out premiereDate); string genreValue = XML.GetXMLTagValue("Genre", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(genreValue)) { foreach (string genre in genreValue.Split('|')) { if (!String.IsNullOrWhiteSpace(genre)) { genres.Add(genre); } } } // Get the Episode information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Episode"); ItrS = NavS.Select(ExpS); } catch (Exception e) { jobLog.WriteEntry("Unable to navigate TVDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } while (ItrS.MoveNext()) { firstAiredStr = XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml); if (DateTime.TryParse(firstAiredStr, null, DateTimeStyles.AssumeLocal, out firstAired)) { if (firstAired <= GlobalDefs.NO_BROADCAST_TIME) { continue; } // The information is stored on the server using the network timezone // So we assume that the show being converted was recorded locally and is converted locally so the timezones match // Sometimes the timezones get mixed up so we check local time or universal time for a match if ((firstAired.Date == videoTags.OriginalBroadcastDateTime.ToLocalTime().Date) || // TVDB only reports the date not the time (firstAired.Date == videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date)) { episodeName = XML.GetXMLTagValue("EpisodeName", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(episodeName)) { jobLog.WriteEntry("Empty episode name", Log.LogEntryType.Debug); return(false); // WRONG series, if there is no name we're in the incorrect series (probably wrong country) } int.TryParse(XML.GetXMLTagValue("SeasonNumber", ItrS.Current.OuterXml), out seasonNo); int.TryParse(XML.GetXMLTagValue("EpisodeNumber", ItrS.Current.OuterXml), out episodeNo); episodeOverview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); // ******************** // Get the banner file // ******************** VideoMetaData.DownloadBannerFile(videoTags, "http://www.thetvdb.com/banners/" + bannerUrl); // Get bannerfile if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (!String.IsNullOrWhiteSpace(seriesName) && !dontOverwriteTitle) { videoTags.Title = seriesName; // Overwrite Series name since we matching by broadcast time and the name didn't match earlier so likely an issue with the name } if (!String.IsNullOrWhiteSpace(episodeName)) { videoTags.SubTitle = episodeName; // Overwrite episode name, it didn't match earlier in match by episode name, so it's probably wrong on the metadata } if (!String.IsNullOrWhiteSpace(episodeOverview)) { videoTags.Description = episodeOverview; // Overwrite } else if (!String.IsNullOrWhiteSpace(overview)) { videoTags.Description = overview; // Overwrite } if (!String.IsNullOrWhiteSpace(seriesID) && String.IsNullOrWhiteSpace(videoTags.tvdbId)) { videoTags.tvdbId = seriesID; } if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId)) { videoTags.imdbId = imdbID; } if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network)) { videoTags.Network = network; } if (premiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > premiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = premiereDate; // TVDB stores time in network (local) timezone } } if (genres.Count > 0) { if (videoTags.Genres != null) { if (videoTags.Genres.Length == 0) { videoTags.Genres = genres.ToArray(); } } else { videoTags.Genres = genres.ToArray(); } } return(true); // Found a match got all the data, we're done here } } } jobLog.WriteEntry("No match found on TVDB for language " + lang, Log.LogEntryType.Warning); return(false); }
public async Task BroadcastNewVideoInfo(VideoMetaData videoMetaData) { await Clients.Others.SendAsync("OnBroadcastNewVideoInfo", videoMetaData); Debug.WriteLine("Send video: VideoMetaData: \nTitle:{0}, \nPrice{1}, \n Address:{2}", videoMetaData.Title, videoMetaData.Price, videoMetaData.AddressAuthor); }
public string Get(VideoMetaData metadata) => dictionary[metadata];
/// <summary> /// Reads the meta information (if present) in an FLV /// </summary> /// <param name="path">The path to the FLV file</returns> public static VideoMetaData GetMetaDataInfo(MemoryStream memStream, string location) { bool hasMetaData = false; double duration = 0; double width = 0; double height = 0; double videoDataRate = 0; double audioDataRate = 0; Double frameRate = 0; DateTime creationDate = DateTime.MinValue; if (memStream == null) { throw new ArgumentNullException("Parameter MemoryStream is null"); } try { // read where "onMetaData" byte[] bytes = new byte[10]; memStream.Seek(27, SeekOrigin.Begin); int result = memStream.Read(bytes, 0, 10); // if "onMetaData" exists then proceed to read the attributes string onMetaData = ByteArrayToString(bytes); if (onMetaData == "onMetaData") { hasMetaData = true; // 16 bytes past "onMetaData" is the data for "duration" duration = GetNextDouble(memStream, 16, 8); // 8 bytes past "duration" is the data for "width" width = GetNextDouble(memStream, 8, 8); // 9 bytes past "width" is the data for "height" height = GetNextDouble(memStream, 9, 8); // 16 bytes past "height" is the data for "videoDataRate" videoDataRate = GetNextDouble(memStream, 16, 8); // 16 bytes past "videoDataRate" is the data for "audioDataRate" audioDataRate = GetNextDouble(memStream, 16, 8); // 12 bytes past "audioDataRate" is the data for "frameRate" frameRate = GetNextDouble(memStream, 12, 8); // read in bytes for creationDate manually memStream.Seek(17, SeekOrigin.Current); byte[] seekBytes = new byte[24]; result = memStream.Read(seekBytes, 0, 24); /* * string dateString = ByteArrayToString(seekBytes); * // create .NET readable date string * // cut off Day of Week * dateString = dateString.Substring(4); * // grab 1) month and day, 2) year, 3) time * dateString = dateString.Substring(0, 6) + " " + dateString.Substring(16, 4) + " " + dateString.Substring(7, 8); * // .NET 2.0 has DateTime.TryParse * try * { * creationDate = Convert.ToDateTime(dateString); * } * catch { } */ } } catch (Exception) { // no error handling } finally { if (memStream != null) { memStream.Close(); } } return(VideoMetaData.CreateFlvMetaInfo(hasMetaData, duration, width, height, videoDataRate, audioDataRate, frameRate, creationDate, location)); }
public VideoDecal() { MetaData = new VideoMetaData(); Stretch = System.Windows.Media.Stretch.Uniform; }
/// <summary> /// Supplements details by searching for a series show by title or IMDB ID /// Uses MyApiFilms /// </summary> /// <param name="matchByAirDate">If true, First match by airDate and then by Episode name and vice versa</param> /// <param name="videoTags">Video tags information to use and update</param> /// <param name="dontOverwriteTitle">True if the title has been manually corrected and not to be overwritten</param> /// <param name="offset">Initial search results offset</param> /// <returns>True if successful</returns> static private bool DownloadSeriesDetails(bool matchByAirDate, VideoTags videoTags, bool dontOverwriteTitle, Log jobLog, int offset = 0) { try { if (matchByAirDate && (videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME)) { jobLog.WriteEntry("Invalud original broadcast date to match on IMDB", Log.LogEntryType.Debug); return(false); // We can only match by airdate if there is something to match against (otherwise we get false positives) } else if (!matchByAirDate && String.IsNullOrWhiteSpace(videoTags.SubTitle)) { jobLog.WriteEntry("Invalid episode name to match on IMDB", Log.LogEntryType.Debug); return(false); //Nothing to match here } jobLog.WriteEntry("Searching IMDB Series with result offset " + offset, Log.LogEntryType.Debug); List <MyApiFilms.SearchResults> searchResults = new List <MyApiFilms.SearchResults>(); if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // If dont' have a specific imdb id specified, look up the series details { try { WebClient client = new WebClient(); client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"); // Look for matching title string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?title=" + videoTags.Title + "&format=JSON&aka=1&actors=S&seasons=1&limit=" + MY_API_SEARCH_LIMIT.ToString() + "&offset=" + offset.ToString())); searchResults = JsonConvert.DeserializeObject <List <MyApiFilms.SearchResults> >(response); } catch (Exception e) { jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); // invalid JSON string } } else { // We have a series imdb id to match, use MyApiFilms to get the series details try { WebClient client = new WebClient(); client.Headers.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"); string response = client.DownloadString(new Uri("http://www.myapifilms.com/imdb?idIMDB=" + videoTags.imdbId + "&format=JSON&seasons=1&actors=S")); searchResults.Add(JsonConvert.DeserializeObject <MyApiFilms.SearchResults>(response)); } catch (Exception e) { jobLog.WriteEntry("Unable to connect to IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); // invalid JSON string } } foreach (MyApiFilms.SearchResults show in searchResults) // Cycle through all possible combinations { // Get and match the Series name string seriesName = show.title; if (String.IsNullOrWhiteSpace(videoTags.imdbId)) // Match names only if the movie imdb id is not forced, else take what is returned by moviedb { List <MyApiFilms.Aka> akaValues = show.akas; // check AKA names also - Also Known As (for language and localization) string title = videoTags.Title; bool akaMatch = false; if (akaValues != null) // Check if there are any AKA names to match { akaMatch = show.akas.Any(s => (String.Compare(s.title.Trim(), title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0 ? true : false)); } if ((String.Compare(seriesName.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) != 0) && (!akaMatch)) // ignore white space and special characters - check for both, Title and AKA names looking for a match { continue; // No match in name or AKA } } else if (!String.IsNullOrWhiteSpace(seriesName) && !dontOverwriteTitle) // make sure there is actually something returned here otherwise use default title { videoTags.Title = seriesName; // Take what is forced for the imdb id } DateTime seriesPremiereDate = GlobalDefs.NO_BROADCAST_TIME; DateTime.TryParseExact(show.releaseDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None, out seriesPremiereDate); // Look for the right Episode if (show.seasons != null) { foreach (MyApiFilms.Season season in show.seasons) { if (season.episodes != null) { foreach (MyApiFilms.Episode episode in season.episodes) { // Get the Episode name and match it string episodeName = episode.title; // Original broadcast date, some of them have an extra . in the date so get rid of it DateTime airDate = GlobalDefs.NO_BROADCAST_TIME; DateTime.TryParseExact(episode.date.Replace(".", "").Trim(), "d MMM yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out airDate); if ((!matchByAirDate && (String.Compare(episodeName.Trim(), videoTags.SubTitle.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)) || (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToLocalTime().Date == airDate.Date)) || (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date == airDate.Date))) { // Get Genre's string[] genres = (show.genres == null ? null : show.genres.ToArray()); // Get Genres // Get Overview string episodeOverview = episode.plot; // Episode int episodeNo = episode.episode; // Season int seasonNo = season.numSeason; // IMDB Movie Id string imdbID = show.idIMDB; // Home free - update all the info where required if (matchByAirDate) // If we came in matching the Original Air Date - then we overwrite the episode details { // TODO: For now we only update subtitle and description if it is missing since IMDB is not upto date on TV series information yet. This needs to be changed and force updated once IMDB is complete // if (!String.IsNullOrWhiteSpace(episodeName)) videoTags.SubTitle = episodeName; // Overwrite // if (!String.IsNullOrWhiteSpace(episodeOverview)) videoTags.Description = episodeOverview; // Overwrite if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle)) { videoTags.SubTitle = episodeName; } if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description)) { videoTags.Description = episodeOverview; } } else // only update what's missing { if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle)) { videoTags.SubTitle = episodeName; } if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description)) { videoTags.Description = episodeOverview; } } if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId)) { videoTags.imdbId = imdbID; } if (seriesPremiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > seriesPremiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use IMDB dates, IMDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = seriesPremiereDate; // IMDB stores time in network (local) timezone } } if (airDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > airDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use IMDB dates, IMDB Dates are more reliable than video metadata usually { videoTags.OriginalBroadcastDateTime = airDate; // IMDB stores time in network (local) timezone } } if (genres != null) { if (genres.Length > 0) { if (videoTags.Genres != null) { if (videoTags.Genres.Length == 0) { videoTags.Genres = genres; } } else { videoTags.Genres = genres; } } } if (String.IsNullOrWhiteSpace(videoTags.MediaCredits)) // Get the media credits { videoTags.MediaCredits = ((show.actors != null) ? String.Join(";", show.actors.Select(s => s.actorName)) : ""); } if (String.IsNullOrWhiteSpace(videoTags.Rating)) // Get the ratings { videoTags.Rating = show.rated; } // Download the banner file VideoMetaData.DownloadBannerFile(videoTags, show.urlPoster); // Get bannerfile return(true); // Golden } } } } } } // Check if we have reached the limit for the results (currently 10 is the max returned in a single query), if so then check the next set of results if (searchResults.Count == MY_API_SEARCH_LIMIT) { return(DownloadSeriesDetails(matchByAirDate, videoTags, dontOverwriteTitle, jobLog, offset + MY_API_SEARCH_LIMIT)); } jobLog.WriteEntry("No match found on IMDB Series", Log.LogEntryType.Debug); return(false); } catch (Exception e) { jobLog.WriteEntry("Unable to initialize IMDB\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } }
/// <summary> /// Download the information about the show from TV.com /// </summary> /// <param name="matchByAirDate">True to match the Episode by Original AirDate, False to match by Episode Name</param> /// <param name="dontOverwriteTitle">True if the title has been manually corrected and not to be overwritten</param> /// <returns>True if found a match</returns> static private bool DownloadSeriesDetails(bool matchByAirDate, VideoTags videoTags, bool dontOverwriteTitle, Log jobLog) { HtmlDocument htmlDoc; try { if (matchByAirDate && (videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME)) { jobLog.WriteEntry("Invalid original broadcast date to match on TV.com", Log.LogEntryType.Debug); return(false); // We can only match by airdate if there is something to match against (otherwise we get false positives) } else if (!matchByAirDate && String.IsNullOrWhiteSpace(videoTags.SubTitle)) { jobLog.WriteEntry("Invalid episode name to match on TV.com", Log.LogEntryType.Debug); return(false); //Nothing to match here } htmlDoc = new HtmlWeb().Load("http://www.tv.com/search?q=" + videoTags.Title); // Get the matching shows list HtmlNodeCollection nodes = htmlDoc.DocumentNode.SelectNodes("//li[@class='result show']"); foreach (HtmlNode node in nodes) { string seriesTitle = "", seriesLink = "", bannerUrl = ""; HtmlDocument subDoc = new HtmlDocument(); subDoc.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(node.InnerHtml))); // Get the banner URL HtmlNode urlNode = subDoc.DocumentNode.SelectSingleNode("//div[@class='mask']//img[@src]"); if (urlNode != null) { if (urlNode.HasAttributes) { bannerUrl = urlNode.Attributes["src"].Value.Trim(); // URL } else { bannerUrl = ""; // reset each cycle } } else { bannerUrl = ""; // reset each cycle } // Get the series name and link to page HtmlNode subNode = subDoc.DocumentNode.SelectSingleNode("//div[@class='info']//h4//a[@href]"); if (subNode != null) { seriesTitle = subNode.InnerText.Trim(); // Get the title of the series // Compare the series title with the title of the recording if (String.Compare(seriesTitle.Trim(), videoTags.Title.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0) { HtmlNode subNode1 = subDoc.DocumentNode.SelectSingleNode("//ul[@class='sub_links _inline_navigation']"); if (subNode1 != null) { HtmlDocument subDoc1 = new HtmlDocument(); subDoc1.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(subNode1.InnerHtml))); HtmlNode subNode2 = subDoc1.DocumentNode.SelectSingleNode("//li//a[@href]"); if (subNode2 != null) { if (subNode2.HasAttributes) { seriesLink = subNode2.Attributes["href"].Value; // Get the link for the episodes in the series // Now the links to the various season pages HtmlDocument sDoc = new HtmlWeb().Load("http://www.tv.com" + seriesLink); // Get the premiere date HtmlNode pNode = sDoc.DocumentNode.SelectSingleNode("//span[@class='divider']"); int start = pNode.InnerText.IndexOf("Premiered") + "Premiered".Length; int length = pNode.InnerText.IndexOf("In") - start; string premiereString = pNode.InnerText.Substring(start, length).Trim(); DateTime premiereDate = GlobalDefs.NO_BROADCAST_TIME; DateTime.TryParse(premiereString, out premiereDate); // Get the seasons HtmlNodeCollection sNodes = sDoc.DocumentNode.SelectNodes("//li[@class='filter ']//a[@href]"); foreach (HtmlNode sNode in sNodes) // go through each season { string seasonLink; // Now extract the link to the season episodes page if (sNode.HasAttributes) { seasonLink = sNode.Attributes["href"].Value; // the href has the link to the season page // Now the links to the various season pages HtmlDocument eDoc = new HtmlWeb().Load("http://www.tv.com" + seasonLink); HtmlNodeCollection eNodes = eDoc.DocumentNode.SelectNodes("//div[@class='no_toggle_wrapper _clearfix']"); foreach (HtmlNode eNode in eNodes) // Now extract the episode names, original air dates and compare { string episodeName = "", episodeDesc = ""; DateTime airDate = GlobalDefs.NO_BROADCAST_TIME; int episodeNo = 0, seasonNo = 0; HtmlNode tempNode; HtmlDocument tempDoc = new HtmlDocument(); tempDoc.Load(new MemoryStream(System.Text.Encoding.UTF8.GetBytes(eNode.InnerHtml))); // Extract the season number tempNode = eDoc.DocumentNode.SelectSingleNode("//li[@class='filter selected']"); if (tempNode != null) { if (tempNode.HasAttributes) { int.TryParse(tempNode.Attributes["data-season"].Value.Trim(), out seasonNo); // Season number } } // Extract the episode name tempNode = tempDoc.DocumentNode.SelectSingleNode("//a[@class='title']"); if (tempNode != null) { episodeName = tempNode.InnerText.Trim(); // Episode Name } // Extract the episode number tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='ep_info']"); if (tempNode != null) { int.TryParse(tempNode.InnerText.Trim().Replace("Episode", ""), out episodeNo); // Episode number } // Extract the original broadcast date tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='date']"); if (tempNode != null) { DateTime.TryParse(tempNode.InnerText.Trim(), null, DateTimeStyles.AssumeLocal, out airDate); // Air Date } // Extract the episode description tempNode = tempDoc.DocumentNode.SelectSingleNode("//div[@class='description']"); if (tempNode != null) { episodeDesc = tempNode.InnerText.Trim(); // Episode description } // Now match and store - match either episode name or air date // The information is stored on the server using the network timezone // So we assume that the show being converted was recorded locally and is converted locally so the timezones match // Sometimes the timezones get mixed up so we check local time or universal time for a match if ((!matchByAirDate && (String.Compare(episodeName.Trim(), videoTags.SubTitle.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0)) || (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToLocalTime().Date == airDate.Date)) || (matchByAirDate && (videoTags.OriginalBroadcastDateTime.ToUniversalTime().Date == airDate.Date))) { // Home free - update all the info where required if (matchByAirDate) // If we came in matching the Original Air Date - then we overwrite the episode details { if (!String.IsNullOrWhiteSpace(episodeName)) { videoTags.SubTitle = episodeName; // Overwrite } if (!String.IsNullOrWhiteSpace(episodeDesc)) { videoTags.Description = episodeDesc; // Overwrite } } else // only update what's missing { if (!String.IsNullOrWhiteSpace(episodeName) && String.IsNullOrWhiteSpace(videoTags.SubTitle)) { videoTags.SubTitle = episodeName; } if (!String.IsNullOrWhiteSpace(episodeDesc) && String.IsNullOrWhiteSpace(videoTags.Description)) { videoTags.Description = episodeDesc; } } if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (airDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > airDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TV dates, TV Dates are more reliable than video metadata usually { videoTags.OriginalBroadcastDateTime = airDate; // TV stores time in network (local) timezone } } if (premiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > premiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use IMDB dates, IMDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = premiereDate; // IMDB stores time in network (local) timezone } } VideoMetaData.DownloadBannerFile(videoTags, bannerUrl); // Get bannerfile // All Good now return(true); } } } } } } } } } } jobLog.WriteEntry("No match found on TV.com", Log.LogEntryType.Debug); return(false); } catch (Exception e) { jobLog.WriteEntry("Unable to connect to TV.com\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } }
/// <summary> /// Match the series information by Episode name /// </summary> private static bool MatchByEpisodeName(VideoTags videoTags, string seriesID, Log jobLog) { if (String.IsNullOrWhiteSpace(videoTags.SubTitle)) { jobLog.WriteEntry("No episode name to match", Log.LogEntryType.Debug); return(false); //Nothing to match here } // ************************************** // Get the series and episode information // ************************************** foreach (string lang in THETVDB_SUPPORTED_LANGUAGES) // Cycle through all languages looking for a match since people in different countries/locales could be viewing shows recorded in different languages { jobLog.WriteEntry("Looking for Episode name match on TVDB using language " + lang, Log.LogEntryType.Debug); string queryUrl = "http://www.thetvdb.com/api/" + MCEBUDDY_THETVDB_API_KEY + "/series/" + seriesID + "/all/" + lang + ".xml"; XPathDocument XpS; XPathNavigator NavS; XPathExpression ExpS; XPathNodeIterator ItrS; string overview = ""; string bannerUrl = ""; string imdbID = ""; List <String> genres = new List <string>();; int seasonNo = 0; int episodeNo = 0; string episodeName = ""; string episodeOverview = ""; string network = ""; DateTime premiereDate = GlobalDefs.NO_BROADCAST_TIME; string firstAiredStr = ""; DateTime firstAired = GlobalDefs.NO_BROADCAST_TIME; try { // Get the Series information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Series"); // Series information ItrS = NavS.Select(ExpS); ItrS.MoveNext(); overview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("poster", ItrS.Current.OuterXml))) // We get the poster first { if (String.IsNullOrWhiteSpace(bannerUrl = XML.GetXMLTagValue("fanart", ItrS.Current.OuterXml))) // We get the fanart next { bannerUrl = XML.GetXMLTagValue("banner", ItrS.Current.OuterXml); // We get the banner last } } imdbID = XML.GetXMLTagValue("IMDB_ID", ItrS.Current.OuterXml); network = XML.GetXMLTagValue("Network", ItrS.Current.OuterXml); DateTime.TryParse(XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml), out premiereDate); string genreValue = XML.GetXMLTagValue("Genre", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(genreValue)) { foreach (string genre in genreValue.Split('|')) { if (!String.IsNullOrWhiteSpace(genre)) { genres.Add(genre); } } } // Get the episode information XpS = new XPathDocument(queryUrl); NavS = XpS.CreateNavigator(); ExpS = NavS.Compile("//Data/Episode"); // Episode information ItrS = NavS.Select(ExpS); } catch (Exception e) { jobLog.WriteEntry("Unable to nagivate TMDB for language " + lang + "\r\nError -> " + e.ToString(), Log.LogEntryType.Warning); return(false); } while (ItrS.MoveNext()) { episodeName = XML.GetXMLTagValue("EpisodeName", ItrS.Current.OuterXml); if (!String.IsNullOrWhiteSpace(episodeName)) { if (String.Compare(videoTags.SubTitle.Trim(), episodeName.Trim(), CultureInfo.InvariantCulture, (CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase)) == 0) // Compare the episode names (case / special characters / whitespace can change very often) { int.TryParse(XML.GetXMLTagValue("SeasonNumber", ItrS.Current.OuterXml), out seasonNo); int.TryParse(XML.GetXMLTagValue("EpisodeNumber", ItrS.Current.OuterXml), out episodeNo); episodeOverview = XML.GetXMLTagValue("Overview", ItrS.Current.OuterXml); // ******************** // Get the banner file // ******************** VideoMetaData.DownloadBannerFile(videoTags, "http://www.thetvdb.com/banners/" + bannerUrl); // Get bannerfile if ((episodeNo != 0) && (videoTags.Episode == 0)) { videoTags.Episode = episodeNo; } if ((seasonNo != 0) && (videoTags.Season == 0)) { videoTags.Season = seasonNo; } if (!String.IsNullOrWhiteSpace(episodeOverview) && String.IsNullOrWhiteSpace(videoTags.Description)) { videoTags.Description = episodeOverview; } else if (!String.IsNullOrWhiteSpace(overview) && (String.IsNullOrWhiteSpace(videoTags.Description))) { videoTags.Description = overview; } if (!String.IsNullOrWhiteSpace(seriesID) && String.IsNullOrWhiteSpace(videoTags.tvdbId)) { videoTags.tvdbId = seriesID; } if (!String.IsNullOrWhiteSpace(imdbID) && String.IsNullOrWhiteSpace(videoTags.imdbId)) { videoTags.imdbId = imdbID; } if (!String.IsNullOrWhiteSpace(network) && String.IsNullOrWhiteSpace(videoTags.Network)) { videoTags.Network = network; } if (premiereDate > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.SeriesPremiereDate <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.SeriesPremiereDate.Date > premiereDate.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.SeriesPremiereDate = premiereDate; // TVDB stores time in network (local) timezone } } if (genres.Count > 0) { if (videoTags.Genres != null) { if (videoTags.Genres.Length == 0) { videoTags.Genres = genres.ToArray(); } } else { videoTags.Genres = genres.ToArray(); } } firstAiredStr = XML.GetXMLTagValue("FirstAired", ItrS.Current.OuterXml); if (DateTime.TryParse(firstAiredStr, null, DateTimeStyles.AssumeLocal, out firstAired)) { if (firstAired > GlobalDefs.NO_BROADCAST_TIME) { if ((videoTags.OriginalBroadcastDateTime <= GlobalDefs.NO_BROADCAST_TIME) || (videoTags.OriginalBroadcastDateTime.Date > firstAired.Date)) // Sometimes the metadata from the video recordings are incorrect and report the recorded date (which is more recent than the release date) then use TVDB dates, TVDB Dates are more reliable than video metadata usually { videoTags.OriginalBroadcastDateTime = firstAired; // TVDB stores time in network (local) timezone } } } return(true); // Found a match got all the data, we're done here } } } } jobLog.WriteEntry("No match found on TVDB for Episode Name", Log.LogEntryType.Debug); return(false); }
private Dictionary <VideoMetaData, string> dictionary = new Dictionary <VideoMetaData, string>(); // metadata <-> symm key public void Add(VideoMetaData metadata, string symmKey) => dictionary.Add(metadata, symmKey);
/// <summary> /// Generates a new name and path for a file using the metadata and options provided /// </summary> /// <param name="conversionOptions">Conversion job options</param> /// <param name="metaData">Metadata for video file</param> /// <param name="originalFileName">Full path and name for original video file</param> /// <param name="renamedFileExt">File extension for the renamed file</param> /// <param name="newFileName">Will contain the name of the renamed file if successful</param> /// <param name="subDestinationPath">Will contain the path of the renamed file if successful</param> /// <param name="jobLog">JobLog</param> /// <returns>True if rename was successful, false if there was no rename</returns> public static bool GetRenameByMetadata(ConversionJobOptions conversionOptions, VideoMetaData metaData, string originalFileName, string renamedFileExt, out string newFileName, out string subDestinationPath, Log jobLog) { newFileName = subDestinationPath = ""; if (metaData != null) { if ((conversionOptions.renameBySeries) & (!String.IsNullOrEmpty(metaData.MetaData.Title))) { string title = metaData.MetaData.Title; string subTitle = metaData.MetaData.SubTitle; //Get the date field string date; if (metaData.MetaData.RecordedDateTime > GlobalDefs.NO_BROADCAST_TIME) { date = metaData.MetaData.RecordedDateTime.ToLocalTime().ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } else { DateTime dt = Util.FileIO.GetFileCreationTime(originalFileName); if (dt > GlobalDefs.NO_BROADCAST_TIME) { date = dt.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } else { jobLog.WriteEntry("Cannot get recorded date and time, using current date and time", Log.LogEntryType.Warning); date = DateTime.Now.ToString("yyyy-MM-dd", System.Globalization.CultureInfo.InvariantCulture); } } // Build the new file name, check which naming convention we are using if (!String.IsNullOrEmpty(conversionOptions.customRenameBySeries)) { jobLog.WriteEntry("Custom Renaming Command -> " + conversionOptions.customRenameBySeries, Log.LogEntryType.Debug); try { CustomRename.CustomRenameFilename(conversionOptions.customRenameBySeries, ref newFileName, ref subDestinationPath, originalFileName, metaData.MetaData, jobLog); newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; } catch (Exception e) { jobLog.WriteEntry("Error in file naming format detected, fallback to default naming convention.\r\nError : " + e.ToString(), Log.LogEntryType.Warning); // We had an invalid format newFileName = ""; // Reset since we had an error so fall back can work subDestinationPath = ""; // Reset path for failure } } else if (conversionOptions.altRenameBySeries) // Alternate renaming pattern { // ALTERNATE MC COMPATIBLE --> SHOWNAME/SEASON XX/SXXEYY-EPISODENAME.ext if ((metaData.MetaData.Season > 0) && (metaData.MetaData.Episode > 0)) { newFileName += "S" + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture) + "E" + metaData.MetaData.Episode.ToString("00", System.Globalization.CultureInfo.InvariantCulture); if (subTitle != "") { newFileName += "-" + subTitle; } } else { jobLog.WriteEntry("No Season and Episode information available, using show name", Log.LogEntryType.Warning); // if there is not season episode name available newFileName = title; if (subTitle != "") { newFileName += "-" + subTitle; } else { newFileName += "-" + date + " " + DateTime.Now.ToString("HH:MM", System.Globalization.CultureInfo.InvariantCulture); } } newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; // Create the directory structure subDestinationPath += metaData.MetaData.Title; if ((metaData.MetaData.Season > 0)) { subDestinationPath += "\\Season " + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture); } } if (newFileName == "") // this is our default/fallback option { // STANDARD --> SHOWNAME/SHOWNAME-SXXEYY-EPISODENAME<-RECORDDATE>.ext // Record date is used where there is no season and episode info newFileName = title; if ((metaData.MetaData.Season > 0) && (metaData.MetaData.Episode > 0)) { newFileName += "-" + "S" + metaData.MetaData.Season.ToString("00", System.Globalization.CultureInfo.InvariantCulture) + "E" + metaData.MetaData.Episode.ToString("00", System.Globalization.CultureInfo.InvariantCulture); if (subTitle != "") { newFileName += "-" + subTitle; } } else { jobLog.WriteEntry("No Season and Episode information available, using episode name/record date", Log.LogEntryType.Warning); // if there is not season episode name available if (subTitle != "") { newFileName += "-" + subTitle; } else { newFileName += "-" + date + " " + DateTime.Now.ToString("HH:MM", System.Globalization.CultureInfo.InvariantCulture); // Backup to create a unique name if season/episode is not available } } newFileName = newFileName.Replace(@"\\", @"\"); newFileName += renamedFileExt; // Create the directory structure subDestinationPath += metaData.MetaData.Title; } subDestinationPath = Util.FilePaths.RemoveIllegalFilePathChars(subDestinationPath); // clean it up newFileName = Util.FilePaths.RemoveIllegalFileNameChars(newFileName); // clean it up return(true); // We have a new name and path } else { jobLog.WriteEntry("Skipping Renaming by Series details", Log.LogEntryType.Information); } } else { jobLog.WriteEntry("Renaming by Series, no Metadata", Log.LogEntryType.Warning); } return(false); // No new name }