private void FeedRequestFinished(HttpResponse response)
        {
            if (response.Successful)
            {
                // process response outside UI thread

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // set your data to view model or control (this code is called in the UI thread)
                    var jsonResponse = response.Response;
                    JObject jsonObject = JObject.Parse(jsonResponse);
                    JArray entries = (JArray)jsonObject["data"];

                    for (int i = 0; i < entries.Count; i++)
                    {
                        if (entries[i]["message"] != null)
                        {
                            FeedItemViewModel feedItem = new FeedItemViewModel();
                            feedItem.Message = entries[i]["message"].ToString();
                            feedItem.Username = entries[i]["from"]["name"].ToString();
                            feedItem.Date = entries[i]["created_time"].ToString();

                            if (entries[i]["picture"] != null)
                            { feedItem.Thumbnail = entries[i]["picture"].ToString(); }
                            if (entries[i]["link"] != null)
                            { feedItem.Link = entries[i]["link"].ToString(); }

                            feeds.Add(feedItem);
                        }
                    }

                    if (jsonObject["paging"] != null)
                    {
                        paging = jsonObject["paging"]["next"].ToString();
                    }
                    else
                    {
                        paging = "";
                    }
                    feedBusy = false;
                    updateBusy();
                });
            }
            else
            {
                if (!response.Canceled)
                {
                    feedBusy = false;
                    updateBusy();
                    // display exception
                    MessageBox.Show("Error loading feeds - Try again");
                }
            }
        }
Example #2
0
        /// <summary>Performs a HTTP GET request. </summary>
        /// <param name="request">The <see cref="HttpGetRequest"/>. </param>
        /// <param name="token">The <see cref="CancellationToken"/>. </param>
        /// <param name="progress">The <see cref="IProgress{T}"/>. </param>
        /// <returns>The <see cref="HttpResponse"/>. </returns>
        public static async Task<HttpResponse> GetAsync(HttpGetRequest request, CancellationToken token, IProgress<HttpProgress> progress = null)
        {
            var uri = GetQueryString(request, request.Query);
            var handler = CreateHandler(request, uri);
            using (var client = CreateClient(request, handler))
            {
                var result = new HttpResponse(request);
                result.HttpClient = client;
                lock (PendingRequests)
                    PendingRequests.Add(result);

                try
                {
                    var response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead, token);
                    await CreateResponse(result, uri, request, handler, response, token, progress);

                    result.HttpStatusCode = response.StatusCode;
                    if (!response.IsSuccessStatusCode)
                        result.Exception = new HttpStatusException(response.StatusCode.ToString())
                        {
                            Result = result,
                            HttpStatusCode = result.HttpStatusCode
                        };
                }
                catch (Exception ex)
                {
                    if (result.Exception == null)
                    {
                        result.Exception = ex;
                        throw;
                    }
                }
                finally
                {
                    lock (PendingRequests)
                        PendingRequests.Remove(result);
                }

                if (result.Exception != null)
                    throw result.Exception;
                return result;
            }
        }
        private void AccesTokenRequestFinished(HttpResponse response)
        {
            if (response.Successful)
            {
                // process response outside UI thread

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // set your data to view model or control (this code is called in the UI thread)

                    var jsonResponse = response.Response;
                    var request = new HttpGetRequest("https://graph.facebook.com/ovaliantheartsmusic/feed");
                    request.Query.Add("access_token", jsonResponse.Split('=')[1]);

                    Http.Get(request, FeedRequestFinished);

                });
            }
            else
            {
                if (!response.Canceled)
                {
                    feedBusy = false;
                    updateBusy();
                    // display exception
                    MessageBox.Show("Error loading feeds - Try again");
                }
            }
        }
Example #4
0
        /// <summary>
        /// Performs a HTTP POST request. 
        /// </summary>
        /// <param name="request">The <see cref="HttpPostRequest"/>. </param>
        /// <param name="token">The <see cref="CancellationToken"/>. </param>
        /// <param name="progress">The <see cref="IProgress{T}"/>. </param>
        /// <returns>The <see cref="HttpResponse"/>. </returns>
        public static async Task<HttpResponse> PostAsync(HttpPostRequest request, CancellationToken token, IProgress<HttpProgress> progress = null)
        {
            var uri = GetQueryString(request, request.Query);
            var handler = CreateHandler(request, uri);
            using (var client = CreateClient(request, handler))
            {
                var result = new HttpResponse(request);
                result.HttpClient = client;
                lock (PendingRequests)
                    PendingRequests.Add(result);

                try
                {
                    HttpContent content = null;
                    if (request.RawData != null)
                        content = new ByteArrayContent(request.RawData);
                    else if (request.Files == null || request.Files.Count == 0)
                        content = new ByteArrayContent(request.Encoding.GetBytes(GetQueryString(request.Data)));
                    else
                    {
                        var multipartContent = new MultipartFormDataContent();
                        foreach (var pair in request.Data)
                            multipartContent.Add(new ByteArrayContent(request.Encoding.GetBytes(pair.Value)), pair.Key);
                        
                        foreach (var file in request.Files)
                        {
                            try
                            {
                                var byteContent = new ByteArrayContent(await file.Stream.ReadToEndAsync(0, token, null));
                                byteContent.Headers.ContentType = new MediaTypeHeaderValue(
                                    file.ContentType ?? "application/octet-stream");
                                multipartContent.Add(byteContent, file.Name, file.Filename);
                            }
                            finally
                            {
                                if (file.CloseStream)
                                    file.Stream.Dispose();
                            }
                        }
                        content = multipartContent; 
                    }

                    var response = await client.PostAsync(uri, content, token);
                    await CreateResponse(result, uri, request, handler, response, token, progress);

                    result.HttpStatusCode = response.StatusCode;
                    if (!response.IsSuccessStatusCode)
                        result.Exception = new HttpStatusException(response.StatusCode.ToString())
                        {
                            Result = result, 
                            HttpStatusCode = result.HttpStatusCode
                        };
                }
                catch (Exception ex)
                {
                    if (result.Exception == null)
                    {
                        result.Exception = ex;
                        throw;
                    }
                }
                finally
                {
                    lock (PendingRequests)
                        PendingRequests.Remove(result);
                }

                if (result.Exception != null)
                    throw result.Exception;
                return result; 
            }
        }
Example #5
0
        private static async Task CreateResponse(
            HttpResponse result, Uri uri, HttpRequest request, 
            HttpClientHandler handler, HttpResponseMessage response,
            CancellationToken token, IProgress<HttpProgress> progress)
        {
            if (response.Content != null)
            {
                foreach (var header in response.Content.Headers)
                    result.Headers.Add(header.Key, header.Value.First());
            }

            foreach (var header in response.Headers)
                result.Headers.Add(header.Key, header.Value.First());

            foreach (var cookie in handler.CookieContainer.GetCookies(uri))
                result.Cookies.Add((Cookie)cookie);

            var stream = await response.Content.ReadAsStreamAsync();
            if (response.Content.Headers.ContentEncoding.Any(e => e.ToLower() == "gzip"))
                stream = new Ionic.Zlib.GZipStream(stream, Ionic.Zlib.CompressionMode.Decompress);
            else if (response.Content.Headers.ContentEncoding.Any(e => e.ToLower() == "deflate"))
                stream = new Ionic.Zlib.DeflateStream(stream, Ionic.Zlib.CompressionMode.Decompress);

            if (request.ResponseAsStream)
            {
                result.ResponseStream = stream;
                result.RawResponse = null; 
            }
            else
                result.RawResponse = await stream.ReadToEndAsync(
                    response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1, 
                    token, progress);
        }
Example #6
0
        private static void OnHtmlDownloaded(HttpResponse response, YouTubeQuality quality, Action<Exception> onFinished)
        {
            if (response.Successful)
            {
                var urls = new List<YouTubeUrl>();
                try
                {
                    var match = Regex.Match(response.Response, "url_encoded_fmt_stream_map=(.*?)(&|\")");
                    var data = Uri.UnescapeDataString(match.Groups[1].Value);

                    var arr = data.Split(',');
                    foreach (var d in arr)
                    {
                        var tuple = new YouTubeUrl();
                        foreach (var p in d.Split('&'))
                        {
                            var index = p.IndexOf('=');
                            if (index != -1 && index < p.Length)
                            {
                                try
                                {
                                    var key = p.Substring(0, index);
                                    var value = Uri.UnescapeDataString(p.Substring(index + 1));
                                    if (key == "url")
                                        tuple.Url = value;
                                    else if (key == "itag")
                                        tuple.Itag = int.Parse(value);
                                    else if (key == "type" && value.Contains("video/mp4"))
                                        tuple.Type = value;
                                }
                                catch { }
                            }
                        }

                        if (tuple.IsValid)
                            urls.Add(tuple);
                    }

                    var itag = GetQualityIdentifier(quality);
                    foreach (var u in urls.Where(u => u.Itag > itag).ToArray())
                        urls.Remove(u);
                }
                catch (Exception ex)
                {
                    if (onFinished != null)
                        onFinished(ex);
                    return;
                }

                var entry = urls.OrderByDescending(u => u.Itag).FirstOrDefault();
                if (entry != null)
                {
                    if (onFinished != null)
                        onFinished(null);

                    var url = entry.Url;
                    var launcher = new MediaPlayerLauncher
                    {
                        Controls = MediaPlaybackControls.All,
                        Media = new Uri(url, UriKind.Absolute)
                    };
                    launcher.Show();
                }
                else if (onFinished != null)
                    onFinished(new Exception("no_video_urls_found"));
            }
            else if (onFinished != null)
                onFinished(response.Exception);
        }
Example #7
0
        private static void OnHtmlDownloaded(HttpResponse response, YouTubeQuality quality, Action<YouTubeUri, Exception> completed)
        {
            if (response.Successful)
            {
                var urls = new List<YouTubeUri>();
                try
                {
                    //Debug.WriteLine("match = " + response.Response.ToString());
                    //var match = Regex.Match(response.Response, "url_encoded_fmt_stream_map=(.*?)(&|\")");
                    //var data = Uri.UnescapeDataString(match.Groups[1].Value);

                    var match = Regex.Match(response.Response, @"url_encoded_fmt_stream_map\"":(.*)\""");

                    String a = match.Groups[1].Value;
                    var data = a.Replace("\\u0026", "&");

                    var arr = data.Split(',');
                    foreach (var d in arr)
                    {
                        var url = "";
                        var signature = "";
                        var tuple = new YouTubeUri();
                        foreach (var p in d.Split('&'))
                        {
                            var index = p.IndexOf('=');
                            if (index != -1 && index < p.Length)
                            {
                                try
                                {
                                    var key = p.Substring(0, index);
                                    var value = Uri.UnescapeDataString(p.Substring(index + 1));
                                    if (key == "url")
                                        url = value;
                                    else if (key == "itag")
                                        tuple.Itag = int.Parse(value);
                                    else if (key == "type" && value.Contains("video/mp4"))
                                        tuple.Type = value;
                                    else if (key == "sig")
                                        signature = value;
                                }
                                catch { }
                            }
                        }

                        tuple.url = url + "&signature=" + signature;
                        if (tuple.IsValid)
                            urls.Add(tuple);
                    }

                    var itag = GetQualityIdentifier(quality);
                    foreach (var u in urls.Where(u => u.Itag > itag).ToArray())
                        urls.Remove(u);
                }
                catch (Exception ex)
                {
                    if (completed != null)
                        completed(null, ex);
                    return;
                }

                Debug.WriteLine("entry = " + urls.OrderByDescending(u => u.Itag).FirstOrDefault().ToString());
                var entry = urls.OrderByDescending(u => u.Itag).FirstOrDefault();
                if (entry != null)
                {
                    if (completed != null)
                        completed(entry, null);
                }
                else if (completed != null)
                    completed(null, new Exception("no_video_urls_found"));
            }
            else if (completed != null)
                completed(null, response.Exception);
        }
Example #8
0
		private static void LoadResponse(HttpResponse resp, WebResponse response)
		{
			using (response)
			{
				var stream = response.GetResponseStream();

#if USE_GZIP
#if WINRT || WP8
				if (response.Headers["Content-Encoding"] == "gzip")
					stream = new GZipStream(stream, CompressionMode.Decompress);
#elif SL4 || SL5 || WP7
				if (response.Headers[HttpRequestHeader.ContentEncoding] == "gzip")
					stream = new GZipStream(stream, CompressionMode.Decompress);
#else
				if (response.Headers[HttpResponseHeader.ContentEncoding] == "gzip")
					stream = new GZipStream(stream, CompressionMode.Decompress);
#endif
#endif

				if (resp.Request.ResponseAsStream)
					resp.ResponseStream = stream;
				else
				{
					using (stream)
						resp.RawResponse = stream.ReadToEnd();
				}

				if (response.Headers.AllKeys.Contains("Set-Cookie"))
				{
					var cookies = response.Headers["Set-Cookie"];
					var index = cookies.IndexOf(';');
					if (index != -1)
					{
						foreach (var c in HttpUtilityExtensions.ParseQueryString(cookies.Substring(0, index)))
							resp.Cookies.Add(new Cookie(c.Key, c.Value));
					}
				}

				foreach (var key in response.Headers.AllKeys)
				{
					var value = response.Headers[key];
					resp.Headers.Add(key, value);
				}
			}
		}
Example #9
0
        /// <summary>
        /// This method disables the current page and shows a progress indicator until the youtube movie url has been loaded and starts
        /// </summary>
        /// <param name="youTubeId"></param>
        /// <param name="manualActivatePage">if true add YouTube.CancelPlay() in OnNavigatedTo() of the page (better)</param>
        /// <param name="maxQuality"></param>
        /// <param name="completed"></param>
        public static void Play(string youTubeId, bool manualActivatePage, YouTubeQuality maxQuality = YouTubeQuality.Quality480P, Action<Exception> completed = null)
        {
            //Debug.WriteLine("Play(string youTubeId, bool manualActivatePage, YouTubeQuality maxQuality = YouTubeQuality.Quality480P, Action<Exception> completed = null)");
            lock (typeof(YouTube))
            {
                if (oldState != null)
                    return;

                if (SystemTray.ProgressIndicator == null)
                    SystemTray.ProgressIndicator = new ProgressIndicator();

                SystemTray.ProgressIndicator.IsVisible = true;
                SystemTray.ProgressIndicator.IsIndeterminate = true;

                var page = PhonePage.CurrentPage;
                oldState = PageDeactivator.Inactivate();
                httpResponse = Play(youTubeId, YouTubeQuality.Quality480P, ex => Deployment.Current.Dispatcher.BeginInvoke(
                    delegate
                    {
                        if (page == PhonePage.CurrentPage) // !user navigated away
                            CancelPlay(manualActivatePage);

                        if (completed != null)
                            completed(ex);
                    }));
            }
        }
Example #10
0
		private static HttpResponse Post(HttpPostRequest req, Action<HttpResponse> action, string method)
		{
			var response = new HttpResponse(req);
			try
			{
				var boundary = "";
				var request = CreateRequest(req);

				if (req.Credentials != null)
					request.Credentials = req.Credentials;
				response.WebRequest = request; 

				if (req.Files.Count == 0)
					request.ContentType = "application/x-www-form-urlencoded";
				else
				{
					boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
					request.ContentType = "multipart/form-data; boundary=" + boundary;
				}

				if (req.Cookies.Count > 0)
				{
					request.CookieContainer = new CookieContainer();
					foreach (var c in req.Cookies)
						request.CookieContainer.Add(request.RequestUri, c);
				}

				request.Method = method;
				if (req.ContentType != null)
					request.ContentType = req.ContentType;

				if (req.Headers.Count > 0)
				{
					foreach (var item in req.Headers)
						request.Headers[item.Key] = item.Value;
				}

#if USE_GZIP
				if (req.RequestGzip)
					request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
#endif

				response.CreateTimeoutTimer(request);
				request.BeginGetRequestStream(delegate(IAsyncResult ar1)
				{
					try
					{
						using (var stream = request.EndGetRequestStream(ar1))
						{
							if (req.Files.Count > 0)
								WritePostData(stream, boundary, req);
							else
								WritePostData(stream, req);
						}

						request.BeginGetResponse(r => ProcessResponse(r, request, response, action), request);
					}
					catch (Exception e)
					{
						response.Exception = e;
						if (action != null)
							action(response);
					}
				}, request);
			}
			catch (Exception e)
			{
				response.Exception = e;
				if (action != null)
					action(response);
			}

			lock (pendingRequests) 
				pendingRequests.Add(response);
			return response;
		}
Example #11
0
		private static void ProcessResponse(IAsyncResult asyncResult, WebRequest request, HttpResponse resp, Action<HttpResponse> action)
		{
			lock (pendingRequests)
			{
				if (pendingRequests.Contains(resp))
					pendingRequests.Remove(resp);
			}
			
			try
			{
				var response = request.EndGetResponse(asyncResult);
				resp.IsConnected = true; 
				LoadResponse(resp, response);
			}
			catch (Exception exception)
			{
				if (exception is WebException)
				{
					var response = ((WebException)exception).Response as HttpWebResponse;
					if (response != null)
					{
						resp.HttpStatusCode = response.StatusCode;
						
						try { LoadResponse(resp, response); }
						catch { }
						
						exception = new HttpStatusException(exception.Message)
						{
							Result = resp, 
							WebException = (WebException) exception
						};
					}
				}

				if (resp.ResponseStream != null)
				{
					using (resp.ResponseStream)
						resp.RawResponse = resp.ResponseStream.ReadToEnd();
				}

				resp.Exception = exception; 
				if (action != null)
					action(resp);
				return;
			}

			if (action != null)
				action(resp);
		}
Example #12
0
		public static HttpResponse Get(HttpGetRequest req, Action<HttpResponse> action)
		{
			var response = new HttpResponse(req);
			try
			{
				if (!req.UseCache)
					req.Query["__dcachetime"] = DateTime.Now.Ticks.ToString(); 
				var request = CreateRequest(req);

				if (req.Credentials != null)
					request.Credentials = req.Credentials;
				response.WebRequest = request;

				if (req.Cookies.Count > 0)
				{
					request.CookieContainer = new CookieContainer();
					foreach (var c in req.Cookies)
						request.CookieContainer.Add(request.RequestUri, c);
				}

				request.Method = "GET";
				if (req.ContentType != null)
					request.ContentType = req.ContentType;

				if (req.Headers.Count > 0)
				{
					foreach (var item in req.Headers)
						request.Headers[item.Key] = item.Value;
				}

#if USE_GZIP
				if (req.RequestGzip)
					request.Headers[HttpRequestHeader.AcceptEncoding] = "gzip";
#endif

				response.CreateTimeoutTimer(request);
				request.BeginGetResponse(r => ProcessResponse(r, request, response, action), request);
			}
			catch (Exception e)
			{
				response.Exception = e;
				if (action != null)
					action(response);
			}

			lock (pendingRequests)
				pendingRequests.Add(response);
			return response;
		}
Example #13
0
		private static void ProcessAsyncResponse(TaskCompletionSource<HttpResponse> task, HttpResponse result)
		{
			if (result.Successful)
				task.SetResult(result);
			else if (result.Canceled)
				task.SetCanceled();
			else
				task.SetException(result.Exception);
		}
Example #14
0
		private static void OnHtmlDownloaded(HttpResponse response, YouTubeQuality minQuality, YouTubeQuality maxQuality, Action<YouTubeUri, Exception> completed)
		{
			if (response.Successful)
			{
				var urls = new List<YouTubeUri>();
				try
				{
					var match = Regex.Match(response.Response, "url_encoded_fmt_stream_map\": \"(.*?)\"");
					var data = Uri.UnescapeDataString(match.Groups[1].Value);

					var arr = Regex.Split(data, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); // split by comma but outside quotes
					foreach (var d in arr)
					{
						var url = "";
						var signature = "";
						var tuple = new YouTubeUri();
						foreach (var p in d.Replace("\\u0026", "\t").Split('\t'))
						{
							var index = p.IndexOf('=');
							if (index != -1 && index < p.Length)
							{
								try
								{
									var key = p.Substring(0, index);
									var value = Uri.UnescapeDataString(p.Substring(index + 1));
									if (key == "url")
										url = value;
									else if (key == "itag")
										tuple.Itag = int.Parse(value);
									else if (key == "type" && value.Contains("video/mp4"))
										tuple.Type = value;
									else if (key == "sig")
										signature = value;
								}
								catch { }
							}
						}

						tuple.url = url + "&signature=" + signature;
						if (tuple.IsValid)
							urls.Add(tuple);
					}

					var minTag = GetQualityIdentifier(minQuality);
					var maxTag = GetQualityIdentifier(maxQuality);
					foreach (var u in urls.Where(u => u.Itag < minTag || u.Itag > maxTag).ToArray())
					    urls.Remove(u);
				}
				catch (Exception ex)
				{
					if (completed != null)
						completed(null, ex);
					return; 
				}

				var entry = urls.OrderByDescending(u => u.Itag).FirstOrDefault();
				if (entry != null)
				{
					if (completed != null)
						completed(entry, null);
				}
				else if (completed != null)
					completed(null, new Exception("no_video_urls_found"));
			}
			else if (completed != null)
				completed(null, response.Exception);
		}
        private void TourRequestFinished(HttpResponse response)
        {
            if (response.Successful)
            {
                // process response outside UI thread

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // set your data to view model or control (this code is called in the UI thread)

                    var jsonResponse = response.Response;
                    JObject jsonObject = JObject.Parse(jsonResponse);
                    JArray entries = (JArray)jsonObject["concerts"];

                    for (int i = 0; i < entries.Count; i++)
                    {
                            ConcertItemViewModel concertItem = new ConcertItemViewModel();
                            concertItem.Title = entries[i]["title"].ToString();
                            concertItem.Date = entries[i]["subtitle"].ToString();
                            concertItem.Latitude = entries[i]["latitude"].ToString();
                            concertItem.Longitude = entries[i]["longitude"].ToString();

                            this.Concerts.Add(concertItem);
                    }
                    tourBusy = false;
                    updateBusy();
                });
            }
            else
            {
                if (!response.Canceled)
                {
                    tourBusy = false;
                    updateBusy();
                    // display exception
                    MessageBox.Show("Error loading tour - Try again");
                }
            }
        }
Example #16
0
        private static bool CancelPlay(bool manualActivate)
        {
            lock (typeof(YouTube))
            {
                if (oldState == null && httpResponse == null)
                    return false;

                if (httpResponse != null)
                {
                    httpResponse.Abort();
                    httpResponse = null;
                }

                if (!manualActivate && oldState != null)
                {
                    oldState.Revert();
                    SystemTray.ProgressIndicator.IsVisible = false;
                    oldState = null;
                }

                return true;
            }
        }
        private void VideoListRequestFinished(HttpResponse response)
        {
            if (response.Successful)
            {
                // process response outside UI thread

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    // set your data to view model or control (this code is called in the UI thread)

                    var jsonResponse = response.Response;
                    JObject jsonObject = JObject.Parse(jsonResponse);
                    JArray entries = (JArray)jsonObject["feed"]["entry"];

                    for (int i = 0; i < entries.Count; i++)
                    {
                        VideoItemViewModel videoItem = new VideoItemViewModel();
                        string[] idSplit =  entries[i]["id"]["$t"].ToString().Split(':');
                        videoItem.Id = (idSplit[idSplit.Length-1]);
                        videoItem.Title = entries[i]["title"]["$t"].ToString();
                        videoItem.Thumbnail = ((JArray)entries[i]["media$group"]["media$thumbnail"])[0]["url"].ToString();
                        videoItem.Date = entries[i]["published"]["$t"].ToString();
                        this.Videos.Add(videoItem);
                    }
                    videoBusy = false;
                    updateBusy();
                });
            }
            else
            {
                if (!response.Canceled)
                {
                    videoBusy = false;
                    updateBusy();
                    // display exception
                    MessageBox.Show("Error loading videos - Try again");
                }
            }
        }
Example #18
0
        /// <summary>
        /// This method disables the current page and shows a progress indicator until the youtube movie url has been loaded and starts
        /// </summary>
        /// <param name="youTubeId"></param>
        /// <param name="manualActivatePage">if true add YouTube.CancelPlay() in OnNavigatedTo() of the page (better)</param>
        /// <param name="maxQuality"></param>
        /// <param name="onFailure"></param>
        public static void Play(string youTubeId, bool manualActivatePage, YouTubeQuality maxQuality = YouTubeQuality.Quality480P, Action<Exception> onFailure = null)
        {
            lock (typeof(YouTube))
            {
                if (oldState != null)
                    return;

                if (SystemTray.ProgressIndicator == null)
                    SystemTray.ProgressIndicator = new ProgressIndicator();

                SystemTray.ProgressIndicator.IsVisible = true;
                SystemTray.ProgressIndicator.IsIndeterminate = true;

                var page = PhoneApplication.CurrentPage;
                oldState = PageDeactivator.Inactivate();
                httpResponse = Play(youTubeId, YouTubeQuality.Quality480P, ex => Deployment.Current.Dispatcher.BeginInvoke(
                    delegate
                    {
                        if (page != PhoneApplication.CurrentPage) // user navigated away
                            return;

                        if (ex != null && onFailure != null)
                        {
                            onFailure(ex);
                            CancelPlay(false);
                        }
                        else
                            CancelPlay(manualActivatePage);
                    }));
            }
        }