diff --git a/YoutubeExtractor/ExampleApplication.Portable/ExampleApplication.Portable.csproj b/YoutubeExtractor/ExampleApplication.Portable/ExampleApplication.Portable.csproj
index a52208a..e43f42f 100644
--- a/YoutubeExtractor/ExampleApplication.Portable/ExampleApplication.Portable.csproj
+++ b/YoutubeExtractor/ExampleApplication.Portable/ExampleApplication.Portable.csproj
@@ -32,6 +32,26 @@
4
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll
+ True
+
+
+ ..\packages\NUnit.3.0.1\lib\net45\nunit.framework.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll
+ True
+
@@ -41,6 +61,7 @@
+
diff --git a/YoutubeExtractor/ExampleApplication.Portable/Program.cs b/YoutubeExtractor/ExampleApplication.Portable/Program.cs
index 1b5383c..ce16423 100644
--- a/YoutubeExtractor/ExampleApplication.Portable/Program.cs
+++ b/YoutubeExtractor/ExampleApplication.Portable/Program.cs
@@ -15,7 +15,7 @@ private static void Main(string[] args)
private static async void Run()
{
- IEnumerable videoInfos = await DownloadUrlResolver.GetDownloadUrlsAsync("http://www.youtube.com/watch?v=6bMmhKz6KXg");
+ IEnumerable videoInfos = await DownloadUrlResolver.GetDownloadUrlsAsync("http://www.youtube.com/watch?v=fRh_vgS2dFE");
foreach (VideoInfo videoInfo in videoInfos)
{
diff --git a/YoutubeExtractor/ExampleApplication.Portable/packages.config b/YoutubeExtractor/ExampleApplication.Portable/packages.config
new file mode 100644
index 0000000..abb6f27
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication.Portable/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/YoutubeExtractor/ExampleApplication/ExampleApplication.csproj b/YoutubeExtractor/ExampleApplication/ExampleApplication.csproj
index 2a54837..9c31c90 100644
--- a/YoutubeExtractor/ExampleApplication/ExampleApplication.csproj
+++ b/YoutubeExtractor/ExampleApplication/ExampleApplication.csproj
@@ -47,6 +47,26 @@
false
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.core.interfaces.dll
+ True
+
+
+ ..\packages\NUnit.3.0.1\lib\net20\nunit.framework.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\nunit.util.dll
+ True
+
+
+ ..\packages\NUnitTestAdapter.2.0.0\lib\NUnit.VisualStudio.TestAdapter.dll
+ True
+
@@ -60,6 +80,9 @@
YoutubeExtractor
+
+
+
+
+ PreserveNewest
+
+
+
+
+
+ App.xaml
+
+
+ MainPage.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+ {ea7566f9-ac3b-4c81-b327-786821d5f96b}
+ YoutubeExtractor_Universal
+
+
+
+ 14.0
+
+
+
+
\ No newline at end of file
diff --git a/YoutubeExtractor/ExampleApplication_Universal/ExampleApplication_Universal_TemporaryKey.pfx b/YoutubeExtractor/ExampleApplication_Universal/ExampleApplication_Universal_TemporaryKey.pfx
new file mode 100644
index 0000000..194ea07
Binary files /dev/null and b/YoutubeExtractor/ExampleApplication_Universal/ExampleApplication_Universal_TemporaryKey.pfx differ
diff --git a/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml b/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml
new file mode 100644
index 0000000..19dc3ca
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml.cs b/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml.cs
new file mode 100644
index 0000000..9045d8c
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/MainPage.xaml.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+using YoutubeExtractor;
+
+// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
+
+namespace ExampleApplication_Universal
+{
+ ///
+ /// An empty page that can be used on its own or navigated to within a Frame.
+ ///
+ public sealed partial class MainPage : Page
+ {
+ private IEnumerator videoEnumerator;
+
+ public MainPage()
+ {
+ this.InitializeComponent();
+ }
+
+ private void Page_Loaded(object sender, RoutedEventArgs e)
+ {
+ GetVideoInfos();
+ }
+
+ private async void GetVideoInfos()
+ {
+ var videoInfos = await DownloadUrlResolver.GetDownloadUrlsAsync("http://www.youtube.com/watch?v=fRh_vgS2dFE");
+ videoEnumerator = videoInfos.GetEnumerator();
+ videoEnumerator.MoveNext();
+ PlayVideo();
+ }
+
+ private void PlayVideo()
+ {
+ var currentVideo = videoEnumerator.Current;
+
+ if (currentVideo != null)
+ {
+ this.info.Text = currentVideo.ToString();
+ System.Diagnostics.Debug.WriteLine(currentVideo);
+ this.player.Source = new Uri(currentVideo.DownloadUrl);
+ }
+ }
+
+ private void player_MediaEnded(object sender, RoutedEventArgs e)
+ {
+ System.Diagnostics.Debug.WriteLine("Media Ended");
+ videoEnumerator.MoveNext();
+ PlayVideo();
+ }
+
+ private void player_MediaFailed(object sender, ExceptionRoutedEventArgs e)
+ {
+ System.Diagnostics.Debug.WriteLine("Media failed");
+ videoEnumerator.MoveNext();
+ PlayVideo();
+ }
+
+ private void player_MediaOpened(object sender, RoutedEventArgs e)
+ {
+ System.Diagnostics.Debug.WriteLine("Media Opened");
+ }
+ }
+}
diff --git a/YoutubeExtractor/ExampleApplication_Universal/Package.appxmanifest b/YoutubeExtractor/ExampleApplication_Universal/Package.appxmanifest
new file mode 100644
index 0000000..3d84676
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/Package.appxmanifest
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+ ExampleApplication_Universal
+ Martin
+ Assets\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/YoutubeExtractor/ExampleApplication_Universal/Properties/AssemblyInfo.cs b/YoutubeExtractor/ExampleApplication_Universal/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c318653
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ExampleApplication_Universal")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("ExampleApplication_Universal")]
+[assembly: AssemblyCopyright("Copyright © 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/YoutubeExtractor/ExampleApplication_Universal/Properties/Default.rd.xml b/YoutubeExtractor/ExampleApplication_Universal/Properties/Default.rd.xml
new file mode 100644
index 0000000..80a960c
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/Properties/Default.rd.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/YoutubeExtractor/ExampleApplication_Universal/project.json b/YoutubeExtractor/ExampleApplication_Universal/project.json
new file mode 100644
index 0000000..e3b2dba
--- /dev/null
+++ b/YoutubeExtractor/ExampleApplication_Universal/project.json
@@ -0,0 +1,19 @@
+{
+ "dependencies": {
+ "Microsoft.ApplicationInsights": "1.0.0",
+ "Microsoft.ApplicationInsights.PersistenceChannel": "1.0.0",
+ "Microsoft.ApplicationInsights.WindowsApps": "1.0.0",
+ "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
+ },
+ "frameworks": {
+ "uap10.0": {}
+ },
+ "runtimes": {
+ "win10-arm": {},
+ "win10-arm-aot": {},
+ "win10-x86": {},
+ "win10-x86-aot": {},
+ "win10-x64": {},
+ "win10-x64-aot": {}
+ }
+}
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor.Tests/YoutubeExtractor.Tests.csproj b/YoutubeExtractor/YoutubeExtractor.Tests/YoutubeExtractor.Tests.csproj
index 9f50697..d01a686 100644
--- a/YoutubeExtractor/YoutubeExtractor.Tests/YoutubeExtractor.Tests.csproj
+++ b/YoutubeExtractor/YoutubeExtractor.Tests/YoutubeExtractor.Tests.csproj
@@ -55,6 +55,9 @@
YoutubeExtractor
+
+
+
+
+
+
+
+
+
+
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/VideoInfo.cs b/YoutubeExtractor/YoutubeExtractor_Universal/VideoInfo.cs
new file mode 100644
index 0000000..e52db40
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/VideoInfo.cs
@@ -0,0 +1,211 @@
+using System.Collections.Generic;
+
+namespace YoutubeExtractor
+{
+ public class VideoInfo
+ {
+ internal static IEnumerable Defaults = new List
+ {
+ /* Non-adaptive */
+ new VideoInfo(5, VideoType.Flash, 240, false, AudioType.Mp3, 64, AdaptiveType.None),
+ new VideoInfo(6, VideoType.Flash, 270, false, AudioType.Mp3, 64, AdaptiveType.None),
+ new VideoInfo(13, VideoType.Mobile, 0, false, AudioType.Aac, 0, AdaptiveType.None),
+ new VideoInfo(17, VideoType.Mobile, 144, false, AudioType.Aac, 24, AdaptiveType.None),
+ new VideoInfo(18, VideoType.Mp4, 360, false, AudioType.Aac, 96, AdaptiveType.None),
+ new VideoInfo(22, VideoType.Mp4, 720, false, AudioType.Aac, 192, AdaptiveType.None),
+ new VideoInfo(34, VideoType.Flash, 360, false, AudioType.Aac, 128, AdaptiveType.None),
+ new VideoInfo(35, VideoType.Flash, 480, false, AudioType.Aac, 128, AdaptiveType.None),
+ new VideoInfo(36, VideoType.Mobile, 240, false, AudioType.Aac, 38, AdaptiveType.None),
+ new VideoInfo(37, VideoType.Mp4, 1080, false, AudioType.Aac, 192, AdaptiveType.None),
+ new VideoInfo(38, VideoType.Mp4, 3072, false, AudioType.Aac, 192, AdaptiveType.None),
+ new VideoInfo(43, VideoType.WebM, 360, false, AudioType.Vorbis, 128, AdaptiveType.None),
+ new VideoInfo(44, VideoType.WebM, 480, false, AudioType.Vorbis, 128, AdaptiveType.None),
+ new VideoInfo(45, VideoType.WebM, 720, false, AudioType.Vorbis, 192, AdaptiveType.None),
+ new VideoInfo(46, VideoType.WebM, 1080, false, AudioType.Vorbis, 192, AdaptiveType.None),
+
+ /* 3d */
+ new VideoInfo(82, VideoType.Mp4, 360, true, AudioType.Aac, 96, AdaptiveType.None),
+ new VideoInfo(83, VideoType.Mp4, 240, true, AudioType.Aac, 96, AdaptiveType.None),
+ new VideoInfo(84, VideoType.Mp4, 720, true, AudioType.Aac, 152, AdaptiveType.None),
+ new VideoInfo(85, VideoType.Mp4, 520, true, AudioType.Aac, 152, AdaptiveType.None),
+ new VideoInfo(100, VideoType.WebM, 360, true, AudioType.Vorbis, 128, AdaptiveType.None),
+ new VideoInfo(101, VideoType.WebM, 360, true, AudioType.Vorbis, 192, AdaptiveType.None),
+ new VideoInfo(102, VideoType.WebM, 720, true, AudioType.Vorbis, 192, AdaptiveType.None),
+
+ /* Adaptive (aka DASH) - Video */
+ new VideoInfo(133, VideoType.Mp4, 240, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(134, VideoType.Mp4, 360, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(135, VideoType.Mp4, 480, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(136, VideoType.Mp4, 720, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(137, VideoType.Mp4, 1080, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(138, VideoType.Mp4, 2160, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(160, VideoType.Mp4, 144, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(242, VideoType.WebM, 240, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(243, VideoType.WebM, 360, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(244, VideoType.WebM, 480, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(247, VideoType.WebM, 720, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(248, VideoType.WebM, 1080, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(264, VideoType.Mp4, 1440, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(271, VideoType.WebM, 1440, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(272, VideoType.WebM, 2160, false, AudioType.Unknown, 0, AdaptiveType.Video),
+ new VideoInfo(278, VideoType.WebM, 144, false, AudioType.Unknown, 0, AdaptiveType.Video),
+
+ /* Adaptive (aka DASH) - Audio */
+ new VideoInfo(139, VideoType.Mp4, 0, false, AudioType.Aac, 48, AdaptiveType.Audio),
+ new VideoInfo(140, VideoType.Mp4, 0, false, AudioType.Aac, 128, AdaptiveType.Audio),
+ new VideoInfo(141, VideoType.Mp4, 0, false, AudioType.Aac, 256, AdaptiveType.Audio),
+ new VideoInfo(171, VideoType.WebM, 0, false, AudioType.Vorbis, 128, AdaptiveType.Audio),
+ new VideoInfo(172, VideoType.WebM, 0, false, AudioType.Vorbis, 192, AdaptiveType.Audio)
+ };
+
+ internal VideoInfo(int formatCode)
+ : this(formatCode, VideoType.Unknown, 0, false, AudioType.Unknown, 0, AdaptiveType.None)
+ { }
+
+ internal VideoInfo(VideoInfo info)
+ : this(info.FormatCode, info.VideoType, info.Resolution, info.Is3D, info.AudioType, info.AudioBitrate, info.AdaptiveType)
+ { }
+
+ private VideoInfo(int formatCode, VideoType videoType, int resolution, bool is3D, AudioType audioType, int audioBitrate, AdaptiveType adaptiveType)
+ {
+ this.FormatCode = formatCode;
+ this.VideoType = videoType;
+ this.Resolution = resolution;
+ this.Is3D = is3D;
+ this.AudioType = audioType;
+ this.AudioBitrate = audioBitrate;
+ this.AdaptiveType = adaptiveType;
+ }
+
+ ///
+ /// Gets an enum indicating whether the format is adaptive or not.
+ ///
+ ///
+ /// AdaptiveType.Audio or AdaptiveType.Video if the format is adaptive;
+ /// otherwise, AdaptiveType.None.
+ ///
+ public AdaptiveType AdaptiveType { get; private set; }
+
+ ///
+ /// The approximate audio bitrate in kbit/s.
+ ///
+ /// The approximate audio bitrate in kbit/s, or 0 if the bitrate is unknown.
+ public int AudioBitrate { get; private set; }
+
+ ///
+ /// Gets the audio extension.
+ ///
+ /// The audio extension, or null if the audio extension is unknown.
+ public string AudioExtension
+ {
+ get
+ {
+ switch (this.AudioType)
+ {
+ case AudioType.Aac:
+ return ".aac";
+
+ case AudioType.Mp3:
+ return ".mp3";
+
+ case AudioType.Vorbis:
+ return ".ogg";
+ }
+
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the audio type (encoding).
+ ///
+ public AudioType AudioType { get; private set; }
+
+ ///
+ /// Gets a value indicating whether the audio of this video can be extracted by YoutubeExtractor.
+ ///
+ ///
+ /// true if the audio of this video can be extracted by YoutubeExtractor; otherwise, false.
+ ///
+ public bool CanExtractAudio
+ {
+ get { return this.VideoType == VideoType.Flash; }
+ }
+
+ ///
+ /// Gets the download URL.
+ ///
+ public string DownloadUrl { get; internal set; }
+
+ ///
+ /// Gets the format code, that is used by YouTube internally to differentiate between
+ /// quality profiles.
+ ///
+ public int FormatCode { get; private set; }
+
+ public bool Is3D { get; private set; }
+
+ ///
+ /// Gets a value indicating whether this video info requires a signature decryption before
+ /// the download URL can be used.
+ ///
+ /// This can be achieved with the
+ ///
+ public bool RequiresDecryption { get; internal set; }
+
+ ///
+ /// Gets the resolution of the video.
+ ///
+ /// The resolution of the video, or 0 if the resolution is unkown.
+ public int Resolution { get; private set; }
+
+ ///
+ /// Gets the video title.
+ ///
+ public string Title { get; internal set; }
+
+ ///
+ /// Gets the video extension.
+ ///
+ /// The video extension, or null if the video extension is unknown.
+ public string VideoExtension
+ {
+ get
+ {
+ switch (this.VideoType)
+ {
+ case VideoType.Mp4:
+ return ".mp4";
+
+ case VideoType.Mobile:
+ return ".3gp";
+
+ case VideoType.Flash:
+ return ".flv";
+
+ case VideoType.WebM:
+ return ".webm";
+ }
+
+ return null;
+ }
+ }
+
+ ///
+ /// Gets the video type (container).
+ ///
+ public VideoType VideoType { get; private set; }
+
+ ///
+ /// We use this in the method to
+ /// decrypt the signature
+ ///
+ ///
+ internal string HtmlPlayerVersion { get; set; }
+
+ public override string ToString()
+ {
+ return string.Format("Full Title: {0}, Type: {1}, Resolution: {2}p", this.Title + this.VideoExtension, this.VideoType, this.Resolution);
+ }
+ }
+}
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/VideoNotAvailableException.cs b/YoutubeExtractor/YoutubeExtractor_Universal/VideoNotAvailableException.cs
new file mode 100644
index 0000000..31b32a5
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/VideoNotAvailableException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace YoutubeExtractor
+{
+ ///
+ /// The exception that is thrown when the video is not available for viewing.
+ /// This can happen when the uploader restricts the video to specific countries.
+ ///
+ public class VideoNotAvailableException : Exception
+ {
+ public VideoNotAvailableException()
+ { }
+
+ public VideoNotAvailableException(string message)
+ : base(message)
+ { }
+ }
+}
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/VideoType.cs b/YoutubeExtractor/YoutubeExtractor_Universal/VideoType.cs
new file mode 100644
index 0000000..7b8c2bf
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/VideoType.cs
@@ -0,0 +1,22 @@
+namespace YoutubeExtractor
+{
+ ///
+ /// The video type. Also known as video container.
+ ///
+ public enum VideoType
+ {
+ ///
+ /// Video for mobile devices (3GP).
+ ///
+ Mobile,
+
+ Flash,
+ Mp4,
+ WebM,
+
+ ///
+ /// The video type is unknown. This can occur if YoutubeExtractor is not up-to-date.
+ ///
+ Unknown
+ }
+}
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeExtractor_Universal.csproj b/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeExtractor_Universal.csproj
new file mode 100644
index 0000000..06add23
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeExtractor_Universal.csproj
@@ -0,0 +1,139 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {EA7566F9-AC3B-4C81-B327-786821D5F96B}
+ Library
+ Properties
+ YoutubeExtractor_Universal
+ YoutubeExtractor_Universal
+ en-US
+ UAP
+ 10.0.10240.0
+ 10.0.10240.0
+ 14
+ 512
+ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ ARM
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ ARM
+ bin\ARM\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+
+
+ x64
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ x64
+ bin\x64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+
+
+ x86
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ x86
+ bin\x86\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 14.0
+
+
+
+
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeParseException.cs b/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeParseException.cs
new file mode 100644
index 0000000..a5db795
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/YoutubeParseException.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace YoutubeExtractor
+{
+ ///
+ ///
+ /// The exception that is thrown when the YouTube page could not be parsed.
+ /// This happens, when YouTube changes the structure of their page.
+ ///
+ /// Please report when this exception happens at www.github.com/flagbug/YoutubeExtractor/issues
+ ///
+ public class YoutubeParseException : Exception
+ {
+ public YoutubeParseException(string message, Exception innerException)
+ : base(message, innerException)
+ { }
+ }
+}
\ No newline at end of file
diff --git a/YoutubeExtractor/YoutubeExtractor_Universal/project.json b/YoutubeExtractor/YoutubeExtractor_Universal/project.json
new file mode 100644
index 0000000..2c3ee60
--- /dev/null
+++ b/YoutubeExtractor/YoutubeExtractor_Universal/project.json
@@ -0,0 +1,17 @@
+{
+ "dependencies": {
+ "Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
+ "Newtonsoft.Json": "8.0.2"
+ },
+ "frameworks": {
+ "uap10.0": {}
+ },
+ "runtimes": {
+ "win10-arm": {},
+ "win10-arm-aot": {},
+ "win10-x86": {},
+ "win10-x86-aot": {},
+ "win10-x64": {},
+ "win10-x64-aot": {}
+ }
+}
\ No newline at end of file