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
}
}