namespace VideoBrowser.Core { using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Runtime.CompilerServices; using System.Threading; /// /// Defines the /// public class VideoInfo : INotifyPropertyChanged { #region Fields internal long _duration = 0; internal string _thumbnailUrl = string.Empty; internal string _title = string.Empty; #endregion Fields #region Constructors /// /// Initializes a new instance of the class. /// public VideoInfo() { this.Formats = new List(); } /// /// Initializes a new instance of the class. /// /// The json_file public VideoInfo(string json_file) : this() { this.DeserializeJson(json_file); } #endregion Constructors #region Events /// /// Occurs when one of the format's file size has been updated. /// public event FileSizeUpdateHandler FileSizeUpdated; /// /// Defines the PropertyChanged /// public event PropertyChangedEventHandler PropertyChanged; #endregion Events #region Properties /// /// Gets or sets the Duration /// Gets the video duration in seconds. /// public long Duration { get => _duration; set { _duration = value; this.OnPropertyChanged(); } } /// /// Gets or sets a value indicating whether Failure /// Gets or sets whether there was a failure retrieving video information. /// public bool Failure { get; set; } /// /// Gets or sets the reason for failure retrieving video information. /// public string FailureReason { get; set; } /// /// Gets the Formats /// Gets all the available formats. /// public List Formats { get; private set; } /// /// Gets or sets the video Id. /// public string Id { get; set; } /// /// Gets or sets the playlist index. Default value is -1. /// public int PlaylistIndex { get; set; } = -1; /// /// Gets or sets a value indicating whether RequiresAuthentication /// Gets or sets whether authentication is required to get video information. /// public bool RequiresAuthentication { get; set; } /// /// Gets or sets the ThumbnailUrl /// Gets the video thumbnail url. /// public string ThumbnailUrl { get => _thumbnailUrl; set { _thumbnailUrl = value; this.OnPropertyChanged(); } } /// /// Gets or sets the Title /// Gets the video title. /// public string Title { get => _title; set { _title = value; this.OnPropertyChanged(); } } /// /// Gets the video url. /// public string Url { get; private set; } /////// /////// Gets the video source (Twitch/YouTube). /////// ////public VideoSource VideoSource { get; private set; } #endregion Properties #region Methods /// /// Aborts all the requests for file size for each video format. /// public void AbortUpdateFileSizes() { foreach (VideoFormat format in this.Formats) { format.AbortUpdateFileSize(); } } /// /// The DeserializeJson /// /// The json_file public void DeserializeJson(string json_file) { var raw_json = ReadJSON(json_file); var json = JObject.Parse(raw_json); this.Duration = json.Value("duration"); this.Title = json.Value("fulltitle"); this.Id = json.Value("id"); var displayId = json.Value("display_id"); this.ThumbnailUrl = string.Format("https://i.ytimg.com/vi/{0}/mqdefault.jpg", displayId); this.Url = json.Value("webpage_url"); foreach (JToken token in (JArray)json["formats"]) { this.Formats.Add(new VideoFormat(this, token)); } } /// /// The OnFileSizeUpdated /// /// The videoFormat internal void OnFileSizeUpdated(VideoFormat videoFormat) { this.FileSizeUpdated?.Invoke(this, new FileSizeUpdateEventArgs(videoFormat)); } /// /// The ReadJSON /// /// The json_file /// The private static string ReadJSON(string json_file) { var json = string.Empty; // Should try for about 10 seconds. */ var attempts = 0; var maxAttempts = 20; while ((attempts++) <= maxAttempts) { try { json = File.ReadAllText(json_file); break; } catch (IOException ex) { if (ex is FileNotFoundException || ex.Message.EndsWith("because it is being used by another process.")) { Console.WriteLine(ex); Thread.Sleep(500); } else { throw ex; } } } return json; } /// /// The OnPropertyChanged /// /// The propertyName private void OnPropertyChanged([CallerMemberName] string propertyName = "") { OnPropertyChangedExplicit(propertyName); } /// /// The OnPropertyChangedExplicit /// /// The propertyName private void OnPropertyChangedExplicit(string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } #endregion Methods } }