protected async Task DiscoverData() { OnStateChange(MediaProcessState.FetchingMetadata); // Download the URL given var html = await _client .WithUrl(URL.ToString()) .GetStringAsync(); // Extract the URL from a script tag that looks like this: https://a-v2.sndcdn.com/assets/app-009bd-1ba53b3.js HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); string appJsUrl = doc.DocumentNode.SelectNodes("//script[@src]") .Select(node => node.Attributes["src"].Value) .Where(src => src.Contains("app-")) .Distinct() .Single(); // Download the JS file containing the client_id // client_id:"02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea" var appJs = await _client .WithUrl(new Url(appJsUrl)) .GetStringAsync(); string clientId = _clientIdRegex .Matches(appJs) .Cast <Match>() .Select(x => x.Groups["client_id"].Value) .Distinct() .Single(); // Make sure they are all equal // Find track_id // Look in script tags for JSON _trackId = doc.DocumentNode .SelectNodes("//script[not(@src)]") .Select(node => node.InnerText) // strings containing JavaScript .Select(js => _trackIdRegex.Match(js)) // Regex.Match .Select(match => match.Groups["track_id"].Value) // strings of track IDs .Where(x => !string.IsNullOrEmpty(x)) .Distinct() .Single(); // Find URL of MP3 or the stupid playlist thing // https://api.soundcloud.com/i1/tracks/102140448/streams?client_id=02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea string streamInfoURL = string.Format(_streamInfoUrlFormat, _trackId, clientId); string streamInfoJSON = await _client .WithUrl(streamInfoURL) .GetStringAsync(); var urlMap = new { http_mp3_128_url = "", hls_mp3_128_url = "" }; urlMap = JsonConvert.DeserializeAnonymousType(streamInfoJSON, urlMap); if (!string.IsNullOrWhiteSpace(urlMap.http_mp3_128_url)) { _songDataURL = urlMap.http_mp3_128_url; _mediaType = SoundCloudMediaType.MP3; } else if (!string.IsNullOrWhiteSpace(urlMap.hls_mp3_128_url)) { _songDataURL = urlMap.hls_mp3_128_url; _mediaType = SoundCloudMediaType.Playlist; } else { Clipboard.SetText(streamInfoJSON); throw new InvalidDataException( "Could not find the HTTP MP3/Playlist URL. JSON dump was copied to clipboard."); } _discovered = true; OnStateChange(MediaProcessState.Idle); }
protected async Task DiscoverData() { OnStateChange(MediaProcessState.FetchingMetadata); // Download the URL given var html = await _client .WithUrl(URL.ToString()) .GetStringAsync(); // Extract the URL from a script tag that looks like this: https://a-v2.sndcdn.com/assets/app-009bd-1ba53b3.js HtmlDocument doc = new HtmlDocument(); doc.LoadHtml(html); string appJsUrl = doc.DocumentNode.SelectNodes("//script[@src]") .Select(node => node.Attributes["src"].Value) .Where(src => src.Contains("app-")) .Distinct() .Single(); // Download the JS file containing the client_id // client_id:"02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea" var appJs = await _client .WithUrl(new Url(appJsUrl)) .GetStringAsync(); string clientId = _clientIdRegex .Matches(appJs) .Cast<Match>() .Select(x => x.Groups["client_id"].Value) .Distinct() .Single(); // Make sure they are all equal // Find track_id // Look in script tags for JSON _trackId = doc.DocumentNode .SelectNodes("//script[not(@src)]") .Select(node => node.InnerText) // strings containing JavaScript .Select(js => _trackIdRegex.Match(js)) // Regex.Match .Select(match => match.Groups["track_id"].Value) // strings of track IDs .Where(x => !string.IsNullOrEmpty(x)) .Distinct() .Single(); // Find URL of MP3 or the stupid playlist thing // https://api.soundcloud.com/i1/tracks/102140448/streams?client_id=02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea string streamInfoURL = string.Format(_streamInfoUrlFormat, _trackId, clientId); string streamInfoJSON = await _client .WithUrl(streamInfoURL) .GetStringAsync(); var urlMap = new { http_mp3_128_url = "", hls_mp3_128_url = "" }; urlMap = JsonConvert.DeserializeAnonymousType(streamInfoJSON, urlMap); if (!string.IsNullOrWhiteSpace(urlMap.http_mp3_128_url)) { _songDataURL = urlMap.http_mp3_128_url; _mediaType = SoundCloudMediaType.MP3; } else if (!string.IsNullOrWhiteSpace(urlMap.hls_mp3_128_url)) { _songDataURL = urlMap.hls_mp3_128_url; _mediaType = SoundCloudMediaType.Playlist; } else { Clipboard.SetText(streamInfoJSON); throw new InvalidDataException( "Could not find the HTTP MP3/Playlist URL. JSON dump was copied to clipboard."); } _discovered = true; OnStateChange(MediaProcessState.Idle); }