/// <summary>Atver kārtējo MP3 fragmentu kā <see cref="sourceStream"/>.</summary> public override async Task Open() { try { if (urlFormat == null) { using (var client = new ProperWebClient(System.Text.Encoding.ASCII)) { string playlist = await client.DownloadStringTaskAsync(baseUrl + "chunklist.m3u8"); urlFormat = baseUrl + "media_{0}.mp3" + new Regex("\\?wowzasessionid=([0-9]+)").Match(playlist).Value; chunkIdx = int.Parse(new Regex("MEDIA-SEQUENCE:([0-9]+)").Match(playlist).Groups[1].Value); } } else if (sourceStream != null) { sourceStream.Dispose(); } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(string.Format(urlFormat, chunkIdx)); request.ApplyProxy(); request.Timeout = 3000; // Trīs sekundes. HttpWebResponse response = (HttpWebResponse)(await request.GetResponseAsync()); sourceStream = response.GetResponseStream(); } catch (Exception) { // Lai nākošreiz mēģina iegūt jaunu atskaņošanas adresi. urlFormat = null; throw; } chunkIdx++; }
private async void Window_Loaded(object sender, EventArgs e) { // [{"id":"988747","artist":"Phoenix","title":"Armistice (Live at Hordern Pavilion, Sydney, 2010)","runtime":"197.037","airtime":"2013-12-24 14:09:35","status":"playing","song_id":"929","artist_id":"299","station_id":"1","images":{"ios":"http:\/\/cdn.pieci.lv\/images\/phoenix-ios.jpg","metadata":{"ios":null,"android":null,"desktop":null},"android":"http:\/\/cdn.pieci.lv\/images\/phoenix-android.jpg","desktop":"http:\/\/cdn.pieci.lv\/images\/phoenix-desktop.jpg"}}, ... ] // Novērots, ka sarakstā dziesmas atkārtojas ar vienādu laiku, bet dažadiem ID. using (var client=new ProperWebClient()) { list.ItemsSource= from song in (await client.GetJson(url)).Elements("item") let title=song.Element("title").Value let splitIdx=title.IndexOf('(') select new PlaylistItem { StartTime=TimeZoneInfo.ConvertTime(DateTime.ParseExact(song.Element("airtime").Value, PieciGuide.TimeFormat, CultureInfo.InvariantCulture), timezone, TimeZoneInfo.Local), Duration=TimeSpan.FromSeconds(double.Parse(song.Element("runtime").Value, CultureInfo.InvariantCulture)), Artist=song.Element("artist").Value, Caption=splitIdx < 1 ? title:title.Substring(0, splitIdx-1), // -1 tukšumam pirms iekavas. <1, jo var būt nosaukums, kurš viss iekavās Description=splitIdx < 1 ? null:title.Substring(splitIdx+1, title.Length-splitIdx-2) // -2 iekavām }; } }
public override Channel GetChannel(uint id) { if (brand == null) brand=new Brand(Colors.White, 0x606060.ToColor(), Colors.White, 0x6C54D5.ToColor(), 0x6C54D5.ToColor(), 0x483998.ToColor(), Colors.Black, Colors.Black); if (id == 0 && Channels.ContainsKey(0)) // Nav izvēlēts neviens kanāls. return new EmptyChannel("101.ru", GetResourceImage("101ru.png"), brand, new ChannelMenu()); var channel=channels.FirstOrDefault(c => c.Id == id); if (channel == null) throw new ChannelNotFoundException(id); BitmapSource logo=GetCachedImage(id.ToString()); if (logo == null) using (var client=new ProperWebClient()) { using (Stream imageStreamSource=client.OpenRead(channel.LogoUrl)) using (var srcBitmap=new D.Bitmap(imageStreamSource)) // Drawing.Bitmap, lai WPF neizstieptu attēlu, pārrēķinot DPI. // Ielādē caurspīdīguma masku, kura izveidota, apgriežot krāsas oriģinālajā cover_000_round.png. using (D.Bitmap bitmap=(D.Bitmap)D.Bitmap.FromStream(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(this.GetType(), "LogoMask.png"))) { var rect=new D.Rectangle(new D.Point(0, 0), bitmap.Size); var inBits=srcBitmap.LockBits(rect, DI.ImageLockMode.ReadOnly, DI.PixelFormat.Format32bppArgb); var outBits=bitmap.LockBits(rect, DI.ImageLockMode.WriteOnly, DI.PixelFormat.Format32bppArgb); unsafe { // Nedrošais kods ar norādēm labākai veiktspējai. // Izkrāso caurspīdīguma masku ar logotipa krāsām. for (int y = 0; y < bitmap.Height; y++) { byte* inRow=(byte*)inBits.Scan0+inBits.Stride*y; byte* outRow=(byte*)outBits.Scan0+outBits.Stride*y; for (int x = 0; x < bitmap.Width; x++) { outRow[4 * x] =inRow[4 * x]; // zilā outRow[4 * x + 1]=inRow[4 * x + 1]; // zaļā outRow[4 * x + 2]=inRow[4 * x + 2]; // sarkanā } } } srcBitmap.UnlockBits(inBits); bitmap.UnlockBits(outBits); logo=System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); } CacheImage(id.ToString(), logo); // {"status":0,"result":{"token":"09270779","playlist":[{"url":"http:\/\/ru2.101.ru:8000\/c14_24?tok=09270779"}]},"errorCode":0,"errorMsg":""} string urlPrefix="http://"+Settings.Default.Region; // Iznests mainīgajā, lai nepārrēķinātu katru reizi, meklējot atskaņošanas adresi. channel.StreamUrl=client.GetJsonSync("http://101.ru/api/getstationstream.php?station_id="+id). Element("result").Element("playlist").Elements("item").First(i => i.Element("url").Value.StartsWith(urlPrefix)).Element("url").Value; } return new IcyChannel(channel.StreamUrl, logo, timezone, true, brand, new ChannelMenu()) { UserAgent="Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:18.0) Gecko/20130119 Firefox/18.0" }; // Lai 101.ru neteiktu, ka jāklausās pārlūkā. }
protected override async Task<Broadcast> GetBroadcast(string title) { if (title == null) return null; string caption, description; if ((title == "LIVE" || title == "Radio SWH LIVE") && listedGuide != null) { caption=listedGuide.CurrentBroadcast.Caption; description=null; } else { if (title[title.Length-1] == '&') { // Gadījumos, kad nosaukumā jābūt apostrofam, tas tiek aizvietots ar ampersandu un pārējās daļas nav. // Tādēļ izgūst pilnos dziesmas datus no XML. /* <PLAYBACKSTATE> <lastBuildDate>2012-03-29 21:35:45</lastBuildDate> <PLAY INDEX="0"> <ARTIST>BEATLES</ARTIST> <TITLE>A HARD DAY'S NIGHT</TITLE> <start_time>02:21</start_time> </PLAY> </PLAYBACKSTATE> <PLAYBACKSTATE> <lastBuildDate>2012-03-30 22:50:48</lastBuildDate> <PLAY INDEX="0"> <ARTIST>SWHPLUS</ARTIST> <TITLE>LIVE</TITLE> <start_time>14:48</start_time> </PLAY> </PLAYBACKSTATE> */ // Vēl ir JSON formātā un ar lielāku informāciju (SWH gadījumā): sobrid_etera_title, bildes sobrid_etera, imgfull, img300 un img135. using (var client=new ProperWebClient(System.Text.Encoding.ASCII)) { Match match=new Regex("<ARTIST>(?'artist'[^<]+)<\\/ARTIST>\\s+<TITLE>(?'title'[^<]+)<", RegexOptions.Multiline).Match(await client.DownloadStringTaskAsync(nowUrl)); caption=match.Groups["title"].Value.ToCapitalized(); description=match.Groups["artist"].Value.ToCapitalized(); } } else caption=(capitalize ? title.ToCapitalized():title).SplitCaption(out description); if (listedGuide != null) description+=Environment.NewLine+listedGuide.CurrentBroadcast.Caption; } return new Broadcast(DateTime.Now, DateTime.Now.AddHours(1), caption, description); }
/// <summary>Atver kārtējo MP3 fragmentu kā <see cref="sourceStream"/>.</summary> public override async Task Open() { try { if (urlFormat == null) using (var client=new ProperWebClient(System.Text.Encoding.ASCII)) { string playlist=await client.DownloadStringTaskAsync(baseUrl+"chunklist.m3u8"); urlFormat=baseUrl+"media_{0}.mp3"+new Regex("\\?wowzasessionid=([0-9]+)").Match(playlist).Value; chunkIdx=int.Parse(new Regex("MEDIA-SEQUENCE:([0-9]+)").Match(playlist).Groups[1].Value); } else if (sourceStream != null) sourceStream.Dispose(); HttpWebRequest request=(HttpWebRequest)WebRequest.Create(string.Format(urlFormat, chunkIdx)); request.ApplyProxy(); request.Timeout=3000; // Trīs sekundes. HttpWebResponse response=(HttpWebResponse)(await request.GetResponseAsync()); sourceStream=response.GetResponseStream(); } catch (Exception) { // Lai nākošreiz mēģina iegūt jaunu atskaņošanas adresi. urlFormat=null; throw; } chunkIdx++; }