1/** 2* 3* @package qtmplayer 4* @subpackage qtmplayer-radiofeed 5* 6*/ 7 8(function($) { 9 "use strict"; 10 function isXML(xml){ 11 try { 12 xmlDoc = $.parseXML(xml); //is valid XML 13 return true; 14 } catch (err) { 15 // was not XML 16 return false; 17 } 18 } 19 20 21 22 $.qtmplayerRadioFeedObj = { 23 body: $("body"), 24 window: $(window), 25 document: $(document), 26 htmlAndbody: $('html,body'), 27 qtFeedData: {}, 28 timeInterval: 15000, 29 /** 30 * ======================================================================================================================================== | 31 * | 32 * | 33 * START SITE FUNCTIONS | 34 * | 35 * | 36 * ======================================================================================================================================== | 37 */ 38 fn: { 39 cachedThumbsArray: [], // when this changes, we fetch a new cover 40 updateMediaData(){ 41 // console.log( 'updateMediaData: ' ); 42 // console.log( $.qtMplayerGlobalSongData ); 43 if ('mediaSession' in navigator) { 44 if($.qtMplayerGlobalSongData.thumbnail && false !== $.qtMplayerGlobalSongData.thumbnail){ 45 // console.log('Yes art'); 46 navigator.mediaSession.metadata = new MediaMetadata({ 47 title: $.qtMplayerGlobalSongData.title, 48 artist: $.qtMplayerGlobalSongData.artist, 49 artwork: [ 50 { src: $.qtMplayerGlobalSongData.thumbnail, type: "image/jpeg" } 51 ] 52 }); 53 } else { 54 // console.log('No art'); 55 navigator.mediaSession.metadata = new MediaMetadata({ 56 title: $.qtMplayerGlobalSongData.title, 57 artist: $.qtMplayerGlobalSongData.artist 58 }); 59 } 60 } 61 }, 62 // ----------------------------------------------- FEED READERS END ------------------------------------ 63 getThumbnailOriginal: function(that, termArray, callBack){ 64 var preclean = termArray.split('<!--'); 65 if(preclean.length > 1){ 66 termArray = preclean[0]; 67 } 68 69 termArray = termArray.split(' - ').join('-').split(' ').join('+'); 70 71 var thumb; // image from itunes 72 73 var apiUrl; 74 75 76 apiUrl = 77 'https://itunes.apple.com/search' 78 + '?media=music' // limita al catalogo musica 79 + '&entity=album' // ritorna solo album 80 + '&attribute=albumTerm' // match sul titolo album 81 + '&limit=25' 82 + '&term=' + encodeURIComponent(termArray); 83 //console.log('Nerw'); 84 apiUrl = 'https://itunes.apple.com/search?limit=4&media=music&term='+termArray; 85 86 if(termArray == 'Song title unavailable' || termArray == 'No Titles Available'){ 87 thumb = $.qtmplayerRadioFeedObj.qtFeedData.cover; 88 that.cachedThumbsArray[termArray] = thumb; 89 $.qtMplayerGlobalSongData.thumbnail = thumb; 90 callBack(thumb); 91 return; 92 } 93 94 95 if( undefined === that.cachedThumbsArray[termArray] ) { 96 97 if( $.qtmplayerRadioFeedObj.qtFeedData.artwork ){ 98 termArray = termArray.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); 99 callBack($.qtmplayerRadioFeedObj.qtFeedData.artwork+'?song='+termArray); 100 } else { 101 102 $.ajax({ 103 type: 'GET', 104 cache: true, 105 url: apiUrl, 106 async: true, 107 dataType: 'jsonp', 108 context: this, 109 success: function(json) { 110 if('object' !== typeof( json )){ 111 json = JSON.parse(json); 112 } 113 if(json.resultCount > 0){ 114 thumb = json.results[0].artworkUrl100.split('100x100bb.jpg').join('1000x1000bb.jpg'); 115 that.cachedThumbsArray[termArray] = thumb; 116 $.qtMplayerGlobalSongData.thumbnail = thumb; 117 118 119 callBack(thumb); 120 return; 121 } 122 } 123 }); 124 } 125 } else { 126 // return cached image 127 $.qtMplayerGlobalSongData.thumbnail = that.cachedThumbsArray[termArray]; 128 callBack( that.cachedThumbsArray[termArray] ); 129 return; 130 } 131 $.qtmplayerRadioFeedObj.fn.updateMediaData(); 132 }, 133 134 135 getThumbnail: function(that, termArray, callBack){ 136 // keep original preclean + term normalization for cache 137 var preclean = termArray.split('<!--'); 138 if(preclean.length > 1){ termArray = preclean[0]; } 139 var cacheKey = termArray.split(' - ').join('-').split(' ').join('+'); 140 141 // early exit placeholders (preserves original behavior) 142 if(termArray === 'Song title unavailable' || termArray === 'No Titles Available'){ 143 var ph = $.qtmplayerRadioFeedObj.qtFeedData.cover || false; 144 that.cachedThumbsArray[cacheKey] = ph; 145 if(ph){ $.qtMplayerGlobalSongData.thumbnail = ph; } 146 callBack(ph); 147 return; 148 } 149 150 // RAM cache 151 if( that.cachedThumbsArray[cacheKey] !== undefined ){ 152 var c = that.cachedThumbsArray[cacheKey]; 153 if(c){ $.qtMplayerGlobalSongData.thumbnail = c; } 154 callBack(c || false); 155 return; 156 } 157 158 // 1) STATIC ARTWORK PASSTHROUGH (restored) 159 // Keep legacy slug for ?song= param: lowercase, dashes, strip non-word except '-' 160 if( $.qtmplayerRadioFeedObj.qtFeedData.artwork ){ 161 var slug = termArray.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); 162 var staticUrl = $.qtmplayerRadioFeedObj.qtFeedData.artwork + '?song=' + encodeURIComponent(slug); 163 that.cachedThumbsArray[cacheKey] = staticUrl; 164 $.qtMplayerGlobalSongData.thumbnail = staticUrl; 165 callBack(staticUrl); 166 return; 167 } 168 169 // 2) iTunes lookup with iOS-safe query + music-only filtering 170 var ua = navigator.userAgent || navigator.vendor || window.opera; 171 var isiOS = /iPad|iPhone|iPod/.test(ua) && !window.MSStream; 172 // Build query term for API (safer encoding) 173 var q = encodeURIComponent( 174 termArray.toLowerCase().trim().replace(/\s*-\s*/g,'-').replace(/\s+/g,' ') 175 ); 176 177 var apiUrl = isiOS 178 ? ('https://itunes.apple.com/search?limit=20&entity=musicTrack&term=' + q) // no media=music on iOS 179 : ('https://itunes.apple.com/search?limit=4&media=music&term=' + q); 180 181 var isMusicResult = function(r){ 182 if(!r) return false;
183 var badKinds = ['feature-movie','ebook','podcast','tv-episode','software']; 184 if(badKinds.indexOf(r.kind) !== -1) return false; 185 if(r.kind === 'song') return true; 186 187 if(r.wrapperType === 'collection' && (r.collectionType === 'Album' || r.collectionType === 'Compilation')) return true; 188 return false; 189 }; 190 191 var pickArt = function(list){ 192 var picks = (list || []).filter(isMusicResult).sort(function(a,b){ 193 var rank = function(r){ 194 if(r.kind === 'song') return 1; 195 if(r.wrapperType === 'collection') return 2; 196 return 9; 197 }; 198 return rank(a) - rank(b); 199 }); 200 if(!picks.length) return null; 201 var r0 = picks[0]; 202 var art = (r0.artworkUrl100 || r0.artworkUrl60 || r0.artworkUrl30 || '').toString(); 203 return art ? art.replace('100x100bb.jpg','1000x1000bb.jpg') : null; 204 }; 205 206 var done = function(url){ 207 that.cachedThumbsArray[cacheKey] = url || false; 208 if(url){ $.qtMplayerGlobalSongData.thumbnail = url; } 209 callBack(url || false); 210 }; 211 212 var handleSuccess = function(json, triedAlbumFallback){ 213 if(typeof json !== 'object'){ try{ json = JSON.parse(json); }catch(e){ json = {results:[]}; } } 214 var art = pickArt(json.results); 215 if(art){ done(art); return; } 216 217 // iOS fallback: try album entity if track search too strict 218 if(isiOS && !triedAlbumFallback){ 219 $.ajax({ 220 type: 'GET', 221 cache: true, 222 url: 'https://itunes.apple.com/search?limit=20&entity=album&term=' + q, 223 async: true, 224 dataType: 'jsonp', 225 success: function(json2){ handleSuccess(json2, true); }, 226 error: function(){ done($.qtmplayerRadioFeedObj.qtFeedData.cover || false); } 227 }); 228 return; 229 } 230 231 done($.qtmplayerRadioFeedObj.qtFeedData.cover || false); 232 }; 233 $.ajax({ 234 type: 'GET', 235 cache: true, 236 url: apiUrl, 237 async: true, 238 dataType: 'jsonp', 239 success: function(json){ handleSuccess(json, false); }, 240 error: function(){ done($.qtmplayerRadioFeedObj.qtFeedData.cover || false); } 241 }); 242 $.qtmplayerRadioFeedObj.fn.updateMediaData(); 243 }, 244 245 246 /**==================================================================== 247 * 248 * 249 * Marquee for longer texts 250 * 251 * 252 ====================================================================*/ 253 marqueeInstances: [], 254 marqueeText: function(that) { 255 if('function' !== typeof( $.fn.marquee ) ){ // missing marquee library? quit 256 return; 257 } 258 var marquees = $('body').find('.proradio-marquee'); 259 // Destroy any old instance of the marquee 260 if( that.marqueeInstances.length > 0 ){ 261 for( var mi = 0; mi < that.marqueeInstances.length; mi++ ){ 262 if( 'undefined' !== typeof( that.marqueeInstances[mi] )){ 263 that.marqueeInstances[mi].marquee('destroy'); 264 } 265 } 266 that.marqueeInstances = []; // reset 267 } 268 $.each(marquees, function(i,c){ 269 var item = $(c); 270 if(item.find('.marquee').length === 0){ 271 item.html('<span class="marquee">'+item.html()+'</span>'); 272 } 273 if( item.outerWidth() > item.find('.marquee').outerWidth() ){ // the title is short? quit! 274 return; 275 } 276 that.marqueeInstances[i] = item.marquee({ 277 duration: 20000, 278 gap: 150, 279 delayBeforeStart: 0, 280 direction: 'left', 281 duplicated: true, 282 pauseOnCycle: 0, 283 startVisible: true 284 }); 285 }); 286 }, 287 288 /** 289 * ======================================================= 290 * Display listeners when available 291 * @since 2022 06 21 292 * ======================================================= 293 * */ 294 qtApplyListeners: function(listeners, listener_peak){ 295 if($.qtmplayerRadioFeedObj.qtFeedData.listeners || $.qtmplayerRadioFeedObj.qtFeedData.listenerspeak){ 296 if(listeners || listener_peak){ 297 $(".qtmplayer__stats").addClass('show'); 298 if(listeners && $.qtmplayerRadioFeedObj.qtFeedData.listeners){ 299 $('.qtmplayer-listeners span').html(listeners); 300 $('.qtmplayer-listeners').show(); 301 } else { 302 $('.qtmplayer-listeners').hide(); 303 } 304 if(listener_peak && $.qtmplayerRadioFeedObj.qtFeedData.listenerspeak){ 305 $('.qtmplayer-listener_peak span').html(listener_peak); 306 $('.qtmplayer-listener_peak').show(); 307 } else { 308 $('.qtmplayer-listener_peak').hide(); 309 } 310 return true; 311 } 312 } 313 $(".qtmplayer__stats").removeClass('show'); 314 $('.qtmplayer-listeners span').html(''); 315 $('.qtmplayer-listener_peak span').html(''); 316 return; 317 }, 318 319 320 qtApplyTitle: function(result, callBack){ 321 var that = this; 322 if(result && result !== ''){ 323 324 var dmes = '>>>>> qtApplyTitle : '+result; 325 $.qtmplayerRadioFeedObj.fn.log(dmes); 326 327 // result = decodeURIComponent(escape(result)); 328 var feedsplit = result.split(" - "); 329 var artist; 330 var title; 331 if(feedsplit.length > 1){ 332 artist = feedsplit[0], 333 title = feedsplit[1]; 334 } else { 335 feedsplit = result.split("-"); 336 if(feedsplit.length > 1){ 337 artist = feedsplit[0], 338 title = feedsplit[1]; 339 } else { 340 artist = ""; 341 title = result; 342 } 343 } 344 var artistSplit = artist.split('['); 345 if( artistSplit.length > 1 ){ 346 artist = artistSplit[0]; 347 } 348 artistSplit = artist.split(' : '); 349 if( artistSplit.length > 1 ){ 350 artist = artistSplit[1]; 351 } 352 var titleSplit = title.split('['); 353 if( titleSplit.length > 1 ){ 354 title = titleSplit[0]; 355 } 356 title = $.trim(title); 357 artist = $.trim(artist); 358 359 $(".qtmplayer-feed").show(); 360 361 362 363 // Public formatting =================================== 364 var publicTitle = title; 365 var publicArtist = artist; 366 var fd = $.qtmplayerRadioFeedObj && $.qtmplayerRadioFeedObj.qtFeedData; 367 if (fd && String(fd.revt) === '1') { 368 publicTitle = artist; 369 publicArtist = title; 370 } 371 if (fd && String(fd.nobreak) === '1') { 372 publicTitle = publicTitle+ ' - ' +publicArtist; 373 publicArtist = ''; 374 } 375 if (fd && String(fd.radiotitle) === '1' && fd.title) { 376 publicTitle = fd.title+ ' | ' + publicTitle; 377 } 378 $('.qtmplayer__title').html(publicTitle); 379 $('.qtmplayer__artist').html(publicArtist); 380 that.marqueeText( that ); 381 // END Public formatting =================================== 382 383 384 385 386 387 // Search for artwork 388 var termArray = artist+'-'+title; 389 if( callBack ){ 390 this.getThumbnail(that, termArray, callBack ); 391 } 392 // Update media data ============================== 393 if (window.screen.width < 670 ) { 394 var uA = navigator.userAgent || navigator.vendor || window.opera; 395 if ( /Googlebot/i.test(uA) || /Bing/i.test(uA) || /Yandex/i.test(uA) || /Apple Bot/i.test(uA) || /DuckDuck Bot/i.test(uA) ){
396 // Do nothing 397 } else { 398 jQuery(document).prop('title', artist+' - '+title); 399 } 400 } 401 402 $.qtMplayerGlobalSongData.title = title; 403 $.qtMplayerGlobalSongData.artist = artist; 404 $.qtmplayerRadioFeedObj.fn.updateMediaData(); 405 406 } else { 407 $(".qtmplayer-feed").hide(); 408 } 409 return; 410 }, 411 newFeedReading: function(){ 412 413 414 // debug: fix title not changing after pause 415 416 $.qtmplayerRadioFeedObj.fn.log('newFeedReading = REITERATE - '+$.now()); 417 // console.log( $.qtmplayerRadioFeedObj.qtFeedData ); 418 var o = $.qtmplayerRadioFeedObj, 419 fd = o.qtFeedData, 420 callBack = fd.callBack, 421 fn = o.fn, 422 qtradiofeedHost = (undefined !== fd.host) ? fd.host : '', 423 qtradiofeedPort = (undefined !== fd.port) ? fd.port : '', 424 qtradiofeedProtocol = (undefined !== fd.protocol) ? fd.protocol : 'http', 425 theChannel = (undefined !== fd.channel) ? fd.channel : '', 426 qticecasturl = (undefined !== fd.icecasturl) ? fd.icecasturl : '', 427 qticecastmountpoint = (undefined !== fd.icecastmountpoint) ? fd.icecastmountpoint : '', 428 qticecastchannel = (undefined !== fd.icecastchannel) ? fd.icecastchannel : '', 429 qtradiodotco = (undefined !== fd.radiodotco) ? fd.radiodotco : '', 430 qtairtime = (undefined !== fd.airtime) ? fd.airtime : '', 431 qtradionomy = (undefined !== fd.radionomy) ? fd.radionomy : '', 432 qttextfeed = (undefined !== fd.textfeed) ? fd.textfeed : '', 433 qtUseProxy = (undefined !== fd.useproxy) ? fd.useproxy : '', 434 qtlive365 = (undefined !== fd.live365) ? fd.live365 : '', 435 qtradioking = (undefined !== fd.radioking) ? fd.radioking : '', 436 qtazuracast = (undefined !== fd.azuracast) ? fd.azuracast : '', 437 qtsecuresystems = (undefined !== fd.securesystems) ? fd.securesystems : '', 438 qtradiojar = (undefined !== fd.radiojar) ? fd.radiojar : '', 439 qtradioboss = (undefined !== fd.radioboss) ? fd.radioboss : '', 440 qtmaxcast = (undefined !== fd.maxcast) ? fd.maxcast : '', 441 qtsonicpanel = (undefined !== fd.sonicpanel) ? fd.sonicpanel : '', 442 qtsonicpaneldj = (undefined !== fd.sonicpaneldj) ? fd.sonicpaneldj : '', 443 qtjazler = (undefined !== fd.jazler) ? fd.jazler : '', 444 qteverestcast = (undefined !== fd.everestcast) ? fd.everestcast : '', 445 qtstreamerr = (undefined !== fd.streamerr) ? fd.streamerr : '', 446 qtstreamguys_api = (undefined !== fd.streamguys_api) ? fd.streamguys_api : '', 447 qtstreamguys_uuid = (undefined !== fd.streamguys_uuid) ? fd.streamguys_uuid : '', 448 qtradiocult = (undefined !== fd.radiocult) ? fd.radiocult : '', 449 broadcastradio = (undefined !== fd.broadcastradio) ? fd.broadcastradio : '', 450 radiolize = (undefined !== fd.radiolize) ? fd.radiolize : '', 451 stationplaylist = (undefined !== fd.stationplaylist) ? fd.stationplaylist : '', 452 yesstreaming = (undefined !== fd.yesstreaming) ? fd.yesstreaming : '', 453 schedulefilter = (undefined !== fd.schedulefilter) ? fd.schedulefilter : '', 454 qtFeedPlayerTrack = $('#qtFeedPlayerTrack'), 455 qtFeedPlayerAuthor = $('#qtFeedPlayerAuthor'), 456 qtPlayerTrackInfo = $("#qtPlayerTrackInfo"), 457 author, title, result, feedsplit; 458 o = $.qtmplayerRadioFeedObj; 459 var proxyURL = $("#qtmplayer-radiofeed-proxyurl").data('proxyurl'); 460 var timestamp = new Date().getUTCMilliseconds(); 461 var listener_peak = false; 462 var listeners = false; 463 464 465 466 /** 467 * =================================================================== 468 * 469 * Radio show 470 * 471 * =================================================================== 472 */ 473 474 if( fd.servertype == 'type-radioshow' ){ 475 476 477 478 var showUrl = proxyURL+'?proradio-currentshow=1'; 479 480 if( schedulefilter ){ 481 showUrl = showUrl+'&filterquery='+schedulefilter; 482 } 483 // console.log( showUrl ); 484 485 $.ajax({ 486 type: 'GET', 487 cache: false, 488 url: showUrl, 489 async: true, 490 success: function(data) { 491 if('object' !== typeof( data )){ 492 data = JSON.parse(data); 493 } 494 495 // console.log( data.title ); 496 497 if(data.title){ 498 if(data.subtitle2){ 499 data.title = data.subtitle2+' - '+data.title; 500 } 501 fn.qtApplyTitle(data.title); 502 } 503 // image handling 504 if (data.image) { 505 var img = data.image; 506 if (data.title) { 507 var slug = data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); 508 img += '?title=' + encodeURIComponent(slug); 509 } 510 $.qtMplayerGlobalSongData.thumbnail = img; 511 512 if (typeof callBack === 'function') { 513 callBack(img); // do not null the callback 514 } 515 } 516 if (!data.image && data.thumb) { 517 $.qtMplayerGlobalSongData.thumbnail = data.thumb; 518 if (typeof callBack === 'function') callBack(data.thumb); 519 } 520 521 }, 522 error: function(e){ 523 console.log(e); 524 } 525 }); 526 } 527 528 529 /** 530 * =================================================================== 531 * 532 * YesStreaming 533 * 534 * =================================================================== 535 */ 536 537 if( fd.servertype == 'type-yesstreaming' && yesstreaming ){ 538 if(qtUseProxy){ 539 yesstreaming = proxyURL+'?qtproxycall='+window.btoa(yesstreaming); //REQUIRED 540 } 541 $.ajax({ 542 type: 'GET', 543 cache: false, 544 url: yesstreaming, 545 async: true, 546 jsonp: "callback", 547 success: function(data) { 548 549 if (typeof data !== 'object') { 550 try { 551 data = JSON.parse(data); 552 } catch (e) { 553 console.log("Invalid JSON from Radiolize"); 554 return; 555 } 556 } 557 // console.log( data.results[0] ); 558 var results = data.results[0]; 559 var trackTitlte = data.results[0].metadata; 560 if( 'undefined' !== typeof(data.results[0].img_url) && data.results[0].img_url && 'function' === typeof(callBack) ){ 561 console.log( data.results[0].img_url ); 562 callBack( data.results[0].img_url ); 563 callBack = false;
564 } 565 if( trackTitlte ){ 566 fn.qtApplyTitle(trackTitlte, callBack); 567 } else { 568 console.log(yesstreaming); 569 console.log('Yesstreaming title not available'); 570 fn.qtApplyTitle('Title not available', callBack); 571 } 572 }, 573 error: function(e){ 574 console.log(yesstreaming); 575 console.log('Yesstreaming feed not loaded - error ahead:'); 576 console.log(e); 577 } 578 }); 579 return; 580 } 581 582 583 /** 584 * =================================================================== 585 * 586 * stationplaylist 587 * 588 * =================================================================== 589 */ 590 if( fd.servertype == 'type-stationplaylist' && stationplaylist ){ 591 if(qtUseProxy){ 592 stationplaylist = proxyURL+'?qtproxycall='+window.btoa(stationplaylist); //REQUIRED 593 } 594 595 596 $.ajax({ 597 type: "GET", 598 url:stationplaylist, 599 dataType: "xml", 600 async: true, 601 cache: false, 602 success: function(xml) { 603 fn.log(xml); 604 $(xml).find('Current').each(function(){ 605 fn.log($(this)); 606 var song = $(this); 607 var title = song.find('Title').html(); 608 var artist = song.find('Artist').html(); 609 var artwork = song.find('Image'); 610 611 if(artwork){ 612 artwork = artwork.html(); 613 if(artwork != ''){ 614 callBack( artwork ); 615 callBack = false; 616 } 617 } 618 fn.qtApplyTitle(title + ' - ' + artist , callBack); 619 }); 620 }, 621 error: function(e){ 622 console.log('stationplaylist source unreachable - please check your channel settings'); 623 console.log(e); 624 } 625 }); 626 return; 627 } 628 629 630 /** 631 * =================================================================== 632 * 633 * Radiolize 634 * 635 * =================================================================== 636 */ 637 if( fd.servertype == 'type-radiolize' && radiolize ){ 638 if(qtUseProxy){ 639 radiolize = proxyURL+'?qtproxycall='+window.btoa(radiolize); //REQUIRED 640 } 641 $.ajax({ 642 type: 'GET', 643 url: radiolize, 644 cache: false, 645 async: true, 646 dataType: 'json', 647 success: function(data) { 648 if (typeof data !== 'object') { 649 try { 650 data = JSON.parse(data); 651 } catch (e) { 652 console.log("Invalid JSON from Radiolize"); 653 return; 654 } 655 } 656 657 if (!data.now_playing || !data.now_playing.song || !data.now_playing.song.text) { 658 fn.log("Missing data for Radiolize song title"); 659 return; 660 } 661 662 var title = data.now_playing.song.text; 663 664 if (typeof data.now_playing.song.art !== 'undefined' && data.now_playing.song.art && typeof callBack === 'function') { 665 var img = data.now_playing.song.art; 666 $.qtMplayerGlobalSongData.thumbnail = img; 667 callBack(img); 668 callBack = false; 669 } 670 671 fn.qtApplyTitle(title, callBack); 672 }, 673 error: function(e) { 674 console.log('Broadcast.Radio feed not loaded - error ahead:'); 675 console.log(e); 676 } 677 }); 678 679 return; 680 } 681 682 /** 683 * =================================================================== 684 * 685 * Broadcast.Radio 686 * 687 * =================================================================== 688 */ 689 if( fd.servertype == 'type-broadcastradio' && broadcastradio ){ 690 if(qtUseProxy){ 691 broadcastradio = proxyURL+'?qtproxycall='+window.btoa(broadcastradio); //REQUIRED 692 } 693 $.ajax({ 694 type: 'GET', 695 cache: false, 696 url: broadcastradio, 697 async: true, 698 jsonp: true, 699 success: function(data) { 700 if('object' !== typeof( data )){ 701 data = JSON.parse(data); 702 } 703 if(!data.success){ 704 fn.log("Missing data for Broadcast.Radio song title"); 705 return; 706 } 707 title = data.body.now_playing.title; 708 if(data.body.now_playing.artist ){ 709 title = title +' - ' + data.body.now_playing.artist; 710 } 711 if( 'undefined' !== typeof(data.body.now_playing.artworkUrl) && data.body.now_playing.artworkUrl && 'function' === typeof(callBack) ){ 712 if( 'undefined' !== typeof( data.body.now_playing.artworkUrl ) ){ 713 if( data.body.now_playing.artworkUrl ){ 714 var img = data.body.now_playing.artworkUrl; 715 $.qtMplayerGlobalSongData.thumbnail = img; 716 callBack( img ); 717 callBack = false;
718 } 719 } 720 } 721 fn.qtApplyTitle(title, callBack); 722 }, 723 error: function(e){ 724 console.log('Broadcast.Radio feed not loaded - error ahead:'); 725 console.log(e); 726 } 727 }); 728 return; 729 } 730 731 732 733 /** 734 * =================================================================== 735 * 736 * RadioCult 737 * 738 * =================================================================== 739 */ 740 if( fd.servertype == 'type-radiocult' && qtradiocult ){ 741 // if(qtUseProxy){ 742 qtradiocult = proxyURL+'?qtproxycall='+window.btoa(qtradiocult); //REQUIRED 743 // } 744 $.ajax({ 745 type: 'GET', 746 cache: false, 747 url: qtradiocult, 748 async: true, 749 jsonp: true, 750 success: function(data) { 751 if('object' !== typeof( data )){ 752 data = JSON.parse(data); 753 } 754 if(!data.result.metadata){ 755 fn.log("Missing data for Radiocult song title"); 756 return; 757 } 758 title = data.result.metadata.title; 759 760 if(data.result.metadata.artist ){ 761 title = title +' - ' + data.result.metadata.artist; 762 } 763 if( 'undefined' !== typeof(data.result.metadata.artwork) && data.result.metadata.artwork && 'function' === typeof(callBack) ){ 764 if( 'undefined' !== typeof(data.result.metadata.artwork.original ) ){ 765 if( data.result.metadata.artwork.original ){ 766 var img = data.result.metadata.artwork.original; 767 $.qtMplayerGlobalSongData.thumbnail = img; 768 callBack( img ); 769 callBack = false; 770 } 771 } 772 } 773 fn.qtApplyTitle(title, callBack); 774 }, 775 error: function(e){ 776 console.log('Streamguys feed not loaded - error ahead:'); 777 console.log(e); 778 } 779 }); 780 return; 781 } 782 /** 783 * =================================================================== 784 * 785 * SteamGuys 786 * 787 * =================================================================== 788 */ 789 if( fd.servertype == 'type-streamguys' && qtstreamguys_api && qtstreamguys_uuid ){ 790 var apiurl = 'https://jetapi.streamguys.com/'+qtstreamguys_api+'/scraper/'+qtstreamguys_uuid+'/metadata/raw/'; 791 792 if(qtUseProxy){ 793 apiurl = proxyURL+'?qtproxycall='+window.btoa(apiurl); 794 } 795 $.ajax({ 796 type: 'GET', 797 cache: false, 798 url: apiurl, 799 async: true, 800 jsonp: true, 801 success: function(text) { 802 if(text == '{"error":"API Key not found."}'){ 803 return; 804 } 805 // Regular expression to match the StreamTitle value 806 var match = text.match(/StreamTitle='(.*?)'/); 807 var title = match ? match[1] : ""; 808 fn.qtApplyTitle(title, callBack); 809 }, 810 error: function(e){ 811 console.log('Streamguys feed not loaded - error ahead:'); 812 console.log(e); 813 } 814 }); 815 return; 816 } 817 818 /** 819 * =================================================================== 820 * 821 * EverestCast 822 * 823 * =================================================================== 824 */ 825 if( fd.servertype == 'type-everestcast' ){ 826 fn.log(qteverestcast); 827 if(qtUseProxy){ 828 qteverestcast = proxyURL+'?qtproxycall='+window.btoa(qteverestcast); 829 } 830 $.ajax({ 831 type: 'GET', 832 cache: false, 833 url: qteverestcast, 834 async: true, 835 jsonp: true, 836 success: function(data) { 837 if('object' !== typeof( data )){ 838 data = JSON.parse(data); 839 } 840 841 if(!data.current_track.title){ 842 fn.log("Missing data for Everestcast song title"); 843 return; 844 } 845 title = data.current_track.title; 846 if(data.current_track.image && 'function' === typeof(callBack)){ 847 848 $.qtMplayerGlobalSongData.thumbnail = data.current_track.image; 849 callBack( data.current_track.image ); 850 callBack = false; 851 } 852 fn.qtApplyTitle(title, callBack); 853 }, 854 error: function(e){ 855 console.log('MediaCP feed not loaded - error ahead:'); 856 console.log(e); 857 } 858 }); 859 return; 860 } 861 862 863 /** 864 * =================================================================== 865 * 866 * MediaCP 867 * 868 * =================================================================== 869 */ 870 if( fd.servertype == 'type-mediacp' ){ 871 fn.log(qtmediacp); 872 if(qtUseProxy){ 873 qtmediacp = proxyURL+'?qtproxycall='+window.btoa(qtmediacp); 874 } 875 $.ajax({ 876 type: 'GET', 877 cache: false, 878 url: qtmediacp, 879 async: true, 880 jsonp: true, 881 success: function(data) { 882 if('object' !== typeof( data )){ 883 data = JSON.parse(data); 884 } 885 fn.log(data); 886 title = data.nowplaying; 887 if(data.coverart && 'function' === typeof(callBack)){ 888 $.qtMplayerGlobalSongData.thumbnail = data.coverart; 889 callBack( data.coverart ); 890 891 callBack = false;
892 } 893 fn.qtApplyTitle(title, callBack); 894 }, 895 error: function(e){ 896 console.log('MediaCP feed not loaded - error ahead:'); 897 console.log(e); 898 } 899 }); 900 return; 901 } 902 903 904 905 /** 906 * =================================================================== 907 * 908 * Streamerr 909 * 910 * =================================================================== 911 */ 912 if( fd.servertype == 'type-streamerr' ){ 913 fn.log(qtstreamerr); 914 if(qtUseProxy){ 915 qtstreamerr = proxyURL+'?qtproxycall='+window.btoa(qtstreamerr); 916 } 917 $.ajax({ 918 type: 'GET', 919 cache: false, 920 url: qtstreamerr, 921 async: true, 922 jsonp: true, 923 success: function(data) { 924 925 if('object' !== typeof( data )){ 926 data = JSON.parse(data); 927 } 928 929 fn.log(data); 930 title = data.nowplaying; 931 if(data.coverart && 'function' === typeof(callBack)){ 932 $.qtMplayerGlobalSongData.thumbnail = data.coverart; 933 callBack( data.coverart ); 934 935 callBack = false; 936 } 937 fn.qtApplyTitle(title, callBack); 938 }, 939 error: function(e){ 940 console.log('Streamerr not working - error ahead:'); 941 console.log(e); 942 } 943 }); 944 return; 945 } 946 947 948 949 /** 950 * =================================================================== 951 * 952 * sonicpanel 953 * 954 * =================================================================== 955 */ 956 if( fd.servertype == 'type-sonicpanel' ){ 957 if( qtsonicpanel !== ''){ 958 if ( qtsonicpanel.indexOf("?") > -1 ) { 959 qtsonicpanel = qtsonicpanel + '&rand='+timestamp; 960 } else { 961 qtsonicpanel = qtsonicpanel + '?rand='+timestamp; 962 } 963 if(qtUseProxy){ 964 qtsonicpanel = proxyURL+'?qtproxycall='+window.btoa(qtsonicpanel); 965 } 966 $.ajax({ 967 type: 'GET', 968 cache: false, 969 url: qtsonicpanel, 970 async: true, 971 success: function(data) { 972 if('object' !== typeof( data )){ 973 data = JSON.parse(data); 974 } 975 var titles = 'Now live - Streaming'; 976 if(data.title){ 977 titles = data.title; 978 if(data.artist){ 979 titles = data.artist+' - '+data.title; 980 } 981 } 982 if(data.art && 'function' === typeof(callBack)){ 983 if(data.title){ 984 data.art = data.art + '?title=' + data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); 985 } 986 $.qtMplayerGlobalSongData.thumbnail = data.art; 987 callBack(data.art); 988 989 callBack = false; 990 } 991 if(data.thumb && 'function' === typeof(callBack)){ 992 $.qtMplayerGlobalSongData.thumbnail = data.thumb+'#.jpg'; 993 callBack(data.thumb+'#.jpg'); 994 995 callBack = false; 996 } 997 if( '1' == qtsonicpaneldj && data.djusername !== 'No DJ'){ 998 titles = data.title.split(' - ').join(' / ')+' - '+data.djusername; 999 } 1000 if(data.listn){ 1001 listeners = data.listn; 1002 } 1003 if(data.peaklistn){ 1004 listener_peak = data.peaklistn; 1005 } 1006 fn.qtApplyListeners(listeners, listener_peak); 1007 fn.qtApplyTitle(titles, callBack); 1008 }, 1009 error: function(e){ 1010 console.log(e); 1011 } 1012 }); 1013 } 1014 } 1015 1016 1017 /** 1018 * =================================================================== 1019 * 1020 * qtjazler 1021 * 1022 * =================================================================== 1023 */ 1024 if( fd.servertype == 'type-jazler' ){ 1025 var qtjazlerFolder = qtjazler.split('NowOnAir.xml').join('AlbumsCache/'); 1026 if(qtUseProxy){ 1027 qtjazler = proxyURL+'?qtproxycall='+window.btoa(qtjazler); 1028 } 1029 fn.log('=============================================================='); 1030 fn.log(qtjazler); 1031 $.ajax({ 1032 type: "GET", 1033 url:qtjazler, 1034 dataType: "xml", 1035 async: true, 1036 cache: false, 1037 success: function(xml) { 1038 fn.log(xml); 1039 $(xml).find('Event').each(function(){ 1040 fn.log($(this)); 1041 var CacheImageFile = $(this).find('CacheImageFile').html(); 1042 $(this).find('Announcement').each(function(){ 1043 var title = $(this).attr('Display'); 1044 fn.log(title); 1045 if(CacheImageFile && 'function' === typeof(callBack) ){ 1046 fn.log(qtjazlerFolder + CacheImageFile); 1047 1048 $.qtMplayerGlobalSongData.thumbnail = qtjazlerFolder + CacheImageFile; 1049 callBack( qtjazlerFolder + CacheImageFile ); 1050 callBack = false;
1051 } 1052 fn.qtApplyTitle(title , callBack); 1053 }); 1054 1055 }); 1056 }, 1057 error: function(e){ 1058 console.log('Jazler source unreachable - please check your channel settings'); 1059 console.log(e); 1060 } 1061 }); 1062 return; 1063 } 1064 1065 1066 /** 1067 * =================================================================== 1068 * 1069 * laut.FM 1070 * 1071 * =================================================================== 1072 */ 1073 if( fd.servertype == 'type-lautfm' ){ 1074 fn.log('Server type: LAUT.FM'); 1075 fn.log('Stream URL: '+fd.file); 1076 if( fd.file.indexOf('/stream.laut.fm/') != -1 ){ 1077 fn.log('Laut.FM reading titles'); 1078 var radioname = fd.file.split('https').join('http').split('http://stream.laut.fm/').join(''); 1079 var radiourl = 'https://api.laut.fm/station/'+radioname+'/current_song'; 1080 // if ( radiourl.indexOf("?") > -1 ) { 1081 // radiourl = radiourl + '&rand='+timestamp; 1082 // } else { 1083 // radiourl = radiourl + '?rand='+timestamp; 1084 // } 1085 if(qtUseProxy){ 1086 radiourl = proxyURL+'/?qtproxycall='+window.btoa(radiourl); 1087 } 1088 // console.log(radiourl); 1089 $.ajax({ 1090 type: 'GET', 1091 url: radiourl, 1092 async: true, 1093 cache: false, 1094 success: function(data) { 1095 fn.log('Laut.FM Success'); 1096 if('object' !== typeof( data )){ 1097 data = JSON.parse(data); 1098 } 1099 var titles = 'Now live - Streaming'; 1100 1101 if(data.type){ 1102 if(data.type !== 'jingle'){ 1103 if(data.title){ 1104 titles = data.title; 1105 if(data.artist){ 1106 if(data.artist.name){ 1107 titles = data.artist.name +' - '+ titles; 1108 } 1109 } 1110 } 1111 fn.qtApplyTitle( titles, callBack ); 1112 } 1113 } 1114 1115 }, 1116 error: function(e){ 1117 fn.log(e); 1118 console.log(e); 1119 fn.qtApplyTitle('Laut FM API error - Titles not available'); 1120 } 1121 }); 1122 } 1123 return; 1124 } // IF servertype end 1125 1126 1127 1128 if( fd.servertype === 'type-icy' ){ 1129 1130 1131 fn.log('type-icy'); 1132 fn.log( proxyURL+"?qtproxycall="+ window.btoa(fd.file) + '&icymetadata=1' ); 1133 $.ajax({ 1134 type: 'GET', 1135 url: proxyURL, 1136 jsonpCallback: 'parseMusic', 1137 async: true, 1138 cache: false, 1139 data: { "qtproxycall": window.btoa(fd.file), 'icymetadata': '1' }, 1140 success: function(data) { 1141 if(data === 'Song title unavailable' || data === 'Cannot open the stream' ){ 1142 fn.log('ERROR OPENING THE STREAM OR GETTING THE TITLES: '+data); 1143 fn.qtApplyTitle( $.qtmplayerRadioFeedObj.qtFeedData.title, false ); 1144 callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover ); 1145 return; 1146 } 1147 fn.qtApplyTitle( data, callBack ); 1148 fn.log(data); 1149 }, 1150 error: function(e){ 1151 console.log('Error'); 1152 fn.log(e); 1153 console.log(e); 1154 } 1155 }); 1156 } 1157 1158 1159 1160 /** 1161 * =================================================================== 1162 * 1163 * Auto or HTTPS shoutcast 1164 * 1165 * =================================================================== 1166 */ 1167 if( fd.servertype == 'type-auto' ){ 1168 if(fd.file.indexOf('/proxy/') != -1 && fd.file.indexOf('https') != -1 && fd.file.indexOf('?mp=/') != -1){ 1169 fn.log('type-auto TYPE 1 - GET MOUNTPOINT'); 1170 1171 qtradiofeedHost = fd.file.split('?mp=/'); 1172 qtradiofeedHost = qtradiofeedHost[0] + '?mp=/stats' + '&rand='+timestamp; 1173 if(qtUseProxy){ 1174 qtradiofeedHost = proxyURL+'?qtproxycall='+window.btoa(qtradiofeedHost); 1175 } 1176 $.ajax({ 1177 type: 'GET', 1178 url: qtradiofeedHost, 1179 async: true, 1180 cache: false, 1181 dataType: "xml", 1182 success: function(data) { 1183 1184 1185 fn.qtApplyTitle( $(data).find('SONGTITLE').html() , callBack); 1186 1187 // Listeners ====================================== 1188 if($(data).find('CURRENTLISTENERS')){ 1189 listeners = $(data).find('CURRENTLISTENERS').html(); 1190 } 1191 if($(data).find('PEAKLISTENERS')){ 1192 listener_peak = $(data).find('PEAKLISTENERS').html(); 1193 } 1194 fn.qtApplyListeners(listeners, listener_peak); 1195 1196 }, 1197 error: function(e){ 1198 fn.log(e); 1199 console.log(e); 1200 } 1201 }); 1202 } else if(fd.file.indexOf('/proxy/') == -1 && fd.file.indexOf('https') != -1 && fd.file.endsWith('/stream') && fd.file.indexOf('/mp3') == -1 ){ 1203 1204 fn.log('type-auto TYPE 2 - XML:'+fd.file.endsWith('/stream')+'? ----> '+fd.file); 1205 1206 1207 1208 // OLD system 1209 // qtradiofeedHost = fd.file.split('/stream'); 1210 // qtradiofeedHost = qtradiofeedHost[0] + '/stats'; // no random here
1211 // NEW - replace only the last occurrence of /stream 1212 qtradiofeedHost = fd.file.replace(/\/stream$/, '/stats','$1');// fd.file.split('/stream').join('/stats'); 1213 1214 1215 fn.log('Stats link: <a href="'+qtradiofeedHost+'">'+qtradiofeedHost+'</a>'); 1216 1217 if(qtUseProxy){ 1218 qtradiofeedHost = proxyURL+'?qtproxycall='+window.btoa(qtradiofeedHost); 1219 } 1220 fn.log('Proxy stats link: <a href="'+qtradiofeedHost+'">'+qtradiofeedHost+'</a>'); 1221 $.ajax({ 1222 type: 'GET', 1223 url: qtradiofeedHost, 1224 async: true, 1225 //cache: false, 1226 //dataType: "xml", 1227 success: function(data) { 1228 1229 1230 if(data === 'Song title unavailable' ){ 1231 fn.qtApplyTitle( $.qtmplayerRadioFeedObj.qtFeedData.title , false); 1232 callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover ); 1233 return; 1234 } 1235 1236 1237 fn.qtApplyTitle( $(data).find('SONGTITLE').html() , callBack); 1238 1239 1240 // Listeners ====================================== 1241 if($(data).find('CURRENTLISTENERS')){ 1242 listeners = $(data).find('CURRENTLISTENERS').html(); 1243 } 1244 if($(data).find('PEAKLISTENERS')){ 1245 listener_peak = $(data).find('PEAKLISTENERS').html(); 1246 } 1247 fn.qtApplyListeners(listeners, listener_peak); 1248 1249 }, 1250 error: function(e){ 1251 fn.log(e); 1252 console.log(e); 1253 } 1254 }); 1255 1256 } else { 1257 fn.log('type-auto TYPE 3 ICY METADATA'); 1258 1259 1260 fn.log( proxyURL+"?qtproxycall="+ window.btoa(fd.file) + '&icymetadata=1' ); 1261 $.ajax({ 1262 type: 'GET', 1263 url: proxyURL, 1264 jsonpCallback: 'parseMusic', 1265 async: true, 1266 cache: false, 1267 data: { "qtproxycall": window.btoa(fd.file), 'icymetadata': '1' }, 1268 success: function(data) { 1269 if(data === 'Song title unavailable' ){ 1270 fn.qtApplyTitle( $.qtmplayerRadioFeedObj.qtFeedData.title, false ); 1271 callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover ); 1272 return; 1273 } 1274 fn.qtApplyTitle( data, callBack ); 1275 fn.log(data); 1276 } 1277 }); 1278 1279 } 1280 return; 1281 } 1282 1283 /** 1284 * Maxcast 1285 */ 1286 /** 1287 * =================================================================== 1288 * 1289 * Maxcast 1290 * 1291 * =================================================================== 1292 */ 1293 // Demo feeds: 1294 //https://s05.maxcast.com.br/api/status/brasitaliawebradio/current.json 1295 //https://s16.maxcast.com.br/api/status/bocadoacreatualjt/current.json 1296 if( fd.servertype == 'type-maxcast' ){ 1297 fn.log('Maxcast '+ qtmaxcast); 1298 qtmaxcast = qtmaxcast + '?rand='+timestamp; 1299 if(qtUseProxy){ 1300 qtmaxcast = proxyURL+'?qtproxycall='+window.btoa(qtmaxcast); // working without proxy. Leave here just in case 1301 } 1302 $.ajax({ 1303 type: 'GET', 1304 cache: false, 1305 url: qtmaxcast, 1306 async: true, 1307 jsonpCallback: "parseMusic", 1308 jsonp: false, 1309 data: songdata, 1310 success: function(data) { 1311 if('object' !== typeof(data)){ 1312 data = JSON.parse(data); 1313 } 1314 if(data.playing){ 1315 title = data.playing.current; 1316 } 1317 if(data.song_data && 'function' === typeof(callBack)){ 1318 1319 $.qtMplayerGlobalSongData.thumbnail = data.song_data.cover; 1320 callBack( data.song_data.cover ); 1321 callBack = false; 1322 } 1323 fn.qtApplyTitle(title, callBack); 1324 }, 1325 error: function(e){ 1326 console.log(e); 1327 } 1328 }); 1329 return; 1330 } 1331 1332 if(qtradioboss === '' && qtsecuresystems === '' && qtradiojar === '' && qtradioking === '' && qtazuracast === '' && qttextfeed === '' && qtradionomy === '' && qtlive365 === '' && qtairtime === '' && (qtradiofeedHost === '' || qtradiofeedPort === '' || typeof(qtradiofeedHost) === 'undefined') && qticecasturl === '' && qtradiodotco === '') { 1333 fn.qtApplyTitle(); 1334 return; 1335 } else { 1336 1337 1338 1339 1340 1341 /** 1342 * =================================================================== 1343 * 1344 * Radioboss 1345 * 1346 * =================================================================== 1347 */ 1348 if( qtradioboss !== ''){ 1349 qtradioboss = qtradioboss;// + '?rand='+timestamp; 1350 fn.log(qtradioboss); 1351 1352 if(qtUseProxy){ 1353 qtradioboss = proxyURL+'?qtproxycall='+window.btoa(qtradioboss); 1354 } 1355 1356 // qtradioboss = proxyURL+'?qtproxycall='+window.btoa(qtradioboss); 1357 $.ajax({ 1358 type: 'GET', 1359 cache: false, 1360 url: qtradioboss, 1361 async: true, 1362 // contentType: "application/json", 1363 // jsonp: true, 1364 success: function(data) { 1365 if('object' !== typeof( data )){ 1366 data = JSON.parse(data); 1367 } 1368 title = data['nowplaying']; 1369 fn.qtApplyTitle(title, callBack); 1370 }, 1371 error: function(e){ 1372 console.log(e); 1373 } 1374 }); 1375 return; 1376 } 1377 1378 1379 1380 1381 1382 /** 1383 * =================================================================== 1384 * 1385 * Radiojar 1386 * 1387 * =================================================================== 1388 */ 1389 if( qtradiojar !== ''){ 1390 if ( qtradiojar.indexOf("?") > -1 ) { 1391 qtradiojar = qtradiojar + '&rand='+timestamp; 1392 } else { 1393 qtradiojar = qtradiojar + '?rand='+timestamp; 1394 } 1395 if(qtUseProxy){ 1396 qtradiojar = proxyURL+'?qtproxycall='+window.btoa(qtradiojar); 1397 } 1398 $.ajax({ 1399 type: 'GET', 1400 cache: false, 1401 url: qtradiojar, 1402 async: true, 1403 success: function(data) { 1404 if('object' !== typeof( data )){ 1405 data = JSON.parse(data); 1406 } 1407 var titles = 'Now live - Streaming'; 1408 if(data.title){ 1409 titles = data.title; 1410 if(data.artist){ 1411 titles = data.artist+' - '+data.title; 1412 } 1413 } 1414 if(data.art && 'function' === typeof(callBack)){ 1415 if(data.title){ 1416 data.art = data.art + '?title=' + data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, ''); 1417 } 1418 1419 $.qtMplayerGlobalSongData.thumbnail = data.art; 1420 callBack(data.art); 1421 callBack = false;
1422 } 1423 if(data.thumb && 'function' === typeof(callBack)){ 1424 1425 $.qtMplayerGlobalSongData.thumbnail = data.thumb+'#.jpg'; 1426 callBack(data.thumb+'#.jpg'); 1427 callBack = false; 1428 } 1429 fn.qtApplyTitle(titles, callBack); 1430 }, 1431 error: function(e){ 1432 console.log(e); 1433 } 1434 }); 1435 } 1436 1437 1438 1439 1440 /** 1441 * =================================================================== 1442 * 1443 * SecureSystems 1444 * 1445 * =================================================================== 1446 */ 1447 if( qtsecuresystems !== ''){ 1448 qtsecuresystems =qtsecuresystems; 1449 if(qtUseProxy){ 1450 qtsecuresystems = proxyURL+'?qtproxycall='+window.btoa(qtsecuresystems); 1451 } 1452 $.ajax({ 1453 type: 'GET', 1454 cache: false, 1455 url: qtsecuresystems, 1456 async: true, 1457 dataType: "xml", 1458 success: function(data) { 1459 if( $(data).find('cover').length > 0 ){ 1460 if($(data).find('cover').html() !== '' && 'function' === typeof(callBack)){ 1461 1462 $.qtMplayerGlobalSongData.thumbnail = $(data).find('cover').html(); 1463 callBack($(data).find('cover').html()); 1464 callBack = false; 1465 } 1466 } 1467 var title = $(data).find('title').html(); 1468 if( 'undefined' == typeof(title) || 'undefined' == title ){ 1469 title = $(data).find('name').html(); 1470 } 1471 fn.qtApplyTitle( $(data).find('artist').html()+ ' - ' +title , callBack); 1472 }, 1473 error: function(e){ 1474 console.log(e); 1475 } 1476 }); 1477 return; 1478 } 1479 1480 1481 1482 1483 1484 /** 1485 * =================================================================== 1486 * 1487 * qtlive365 1488 * 1489 * =================================================================== 1490 */ 1491 if( qtlive365 !== ''){ 1492 qtlive365 = 'https://api.live365.com/station/'+qtlive365; 1493 if(qtUseProxy){ 1494 qtlive365 = proxyURL+'?qtproxycall='+window.btoa(qtlive365); 1495 } 1496 1497 $.ajax({ 1498 type: 'GET', 1499 cache: false, 1500 url: qtlive365, 1501 async: true, 1502 jsonpCallback: "parseMusic", 1503 jsonp: false, 1504 success: function(data) { 1505 // console.log(data); 1506 jsondata = data; 1507 // console.log(json); 1508 if('object' !== typeof( data )){ 1509 data = JSON.parse(data); 1510 } 1511 if( data['current-track'].art ){ 1512 var art = data['current-track'].art; 1513 if( art != ''){ 1514 1515 // console.log(art); 1516 $.qtMplayerGlobalSongData.thumbnail = art; 1517 callBack(art); 1518 callBack = false; 1519 } 1520 } 1521 fn.qtApplyTitle(data['current-track'].artist+' - '+data['current-track'].title, callBack); 1522 }, 1523 error: function(e){ 1524 console.log(e); 1525 } 1526 }); 1527 } 1528 1529 /** 1530 * =================================================================== 1531 * 1532 * Text 1533 * 1534 * =================================================================== 1535 */ 1536 else if(qttextfeed !== ''){ 1537 var tfeedurl,jsondata, title, proxyURL, mydata; 1538 if(qtUseProxy){ 1539 tfeedurl = $("#qtmplayer-radiofeed-proxyurl").data('proxyurl'); 1540 mydata = { 1541 "qtproxycall": window.btoa(qttextfeed), 1542 }; 1543 } else { 1544 tfeedurl = qttextfeed; 1545 } 1546 $.ajax({ 1547 type: 'GET', 1548 cache: false, 1549 url: tfeedurl, 1550 async: true, 1551 data: mydata, 1552 dataType: "html", 1553 success: function(data) { 1554 fn.qtApplyTitle( data, callBack ); 1555 }, 1556 error: function(e){ 1557 console.log(e); 1558 } 1559 }); 1560 return; 1561 } 1562 /** 1563 * =================================================================== 1564 * 1565 * Radionomy 1566 * 1567 * =================================================================== 1568 */ 1569 else if(qtradionomy !== '' ) { 1570 $.ajax({ 1571 type: 'GET', 1572 url: qtradionomy, 1573 async: true, 1574 cache: false, 1575 dataType: "xml", 1576 success: function(data) { 1577 fn.qtApplyTitle( $(data).find('artists').html()+ ' - ' + $(data).find('title').html() ); 1578 }, 1579 error: function(e){ 1580 console.log(e); 1581 } 1582 }); 1583 } 1584 1585 /** 1586 * =================================================================== 1587 * 1588 * AirTime 1589 * 1590 * =================================================================== 1591 */ 1592 else if(qtairtime !== '' && qtairtime !== 'undefined' && qtairtime !== undefined && typeof(qtairtime) !== 'undefined'){ 1593 var jsondata, title; 1594 $.ajax({ 1595 type: 'GET', 1596 cache: false, 1597 url: qtairtime,//proxyURL, 1598 async: true, 1599 data: { 1600 "qtproxycall": window.btoa(qtairtime), 1601 }, 1602 jsonpCallback: "parseMusic", 1603 jsonp: true,//jsonp: true, 1604 // contentType: "application/json", 1605 success: function(data) { 1606 // console.log(data); 1607 if(typeof(data) !== 'object'){ 1608 data = JSON.parse(data); 1609 } 1610 title = data.tracks.current.name; 1611 fn.qtApplyTitle(title); 1612 }, 1613 error: function(e) { 1614 } 1615 }); 1616 } 1617 1618 /** 1619 * =================================================================== 1620 * 1621 * Icecast 1622 * 1623 * =================================================================== 1624 */ 1625 else if(qticecasturl !== '' && typeof(qticecasturl) !== 'undefined') { 1626 var feedurl = qticecasturl; 1627 var source; 1628 var title; 1629 var songdata; 1630 var listeners = false;
1631 var listener_peak = false; 1632 if(qtUseProxy){ 1633 feedurl = proxyURL; 1634 songdata = { 1635 "qtproxycall": window.btoa(qticecasturl), 1636 }; 1637 } 1638 // beta 1639 fn.log('Radio feed - Icecast '+ qticecasturl); 1640 // generally ok, not working for LN Soulr Icecast 1641 // console.log( proxyURL+'?qtproxycall='+window.btoa(qticecasturl) ); 1642 $.ajax({ 1643 type: 'GET', 1644 cache: false, 1645 url: feedurl, 1646 async: true, 1647 jsonpCallback: "parseMusic", 1648 jsonp: false,//jsonp: true, 1649 // dataType: 'jsonp', // not working with some radios 1650 data: songdata, 1651 // contentType: "application/json", 1652 success: function(json) { 1653 fn.log('Ajax response'); 1654 fn.log( json ); 1655 1656 // console.log(json); 1657 if('object' !== typeof( json )){ 1658 json = JSON.parse(json); 1659 } 1660 if('undefined' === typeof(json.icestats)){ 1661 // This is Icecast HK 1662 1663 if(qticecastmountpoint){ 1664 source = json[qticecastmountpoint]; 1665 } else { 1666 1667 $.each(json, function(index, element) { 1668 source = element; 1669 if(index == 0){ 1670 source = element; 1671 } 1672 }); 1673 // console.log(source); 1674 } 1675 } else { 1676 source = json.icestats.source; 1677 } 1678 1679 if('undefined' === typeof(source)){ 1680 return; 1681 } 1682 if(qticecastmountpoint){ 1683 source = source[qticecastmountpoint]; 1684 } 1685 if(qticecastchannel){ 1686 // console.log("set source to 0"); 1687 source = source[qticecastchannel]; 1688 } 1689 // since PR.3.2.3 1690 // If there is no channel and there is no title, channel must be 0 1691 if(!qticecastchannel && 'undefined' === typeof(source.title)){ 1692 source = source[0]; 1693 } 1694 title = source.title; 1695 if( source.artist ){ 1696 title = title + ' - ' + source.artist; 1697 } 1698 fn.qtApplyTitle(title, callBack); 1699 // Listeners ====================================== 1700 if(source.listeners){ 1701 listeners = source.listeners; 1702 } 1703 if(source.listener_peak){ 1704 listener_peak = source.listener_peak; 1705 } 1706 fn.qtApplyListeners(listeners, listener_peak); 1707 1708 },error: function(e) { 1709 console.log(e); 1710 fn.log('Ajax response'); 1711 fn.log( e ); 1712 } 1713 }); 1714 } 1715 /** 1716 * =================================================================== 1717 * 1718 * ShoutCast 1719 * 1720 * =================================================================== 1721 */ 1722 else if (qtradiofeedHost !== '' && qtradiofeedPort !== '' && typeof(qtradiofeedHost) !== 'undefined'){ 1723 // to tide up 1724 var feedData = { 1725 shoutcast_host: qtradiofeedHost, 1726 shoutcast_port: qtradiofeedPort, 1727 shoutcast_protocol: qtradiofeedProtocol, 1728 shoutcast_channel: theChannel 1729 }; 1730 var channel = feedData.shoutcast_channel || 1; 1731 var protocol = 'http'; 1732 if(feedData.shoutcast_port === '443' || feedData.shoutcast_protocol === 'https' ){ 1733 protocol = 'https'; 1734 } 1735 var shoutcastUrl = protocol+'://'+feedData.shoutcast_host+':'+feedData.shoutcast_port+'/stats?sid='+channel+'&json=1'; 1736 var feedurl = shoutcastUrl; 1737 1738 if(qtUseProxy){ 1739 feedurl = proxyURL; 1740 songdata = { 1741 "qtproxycall": window.btoa(shoutcastUrl), 1742 }; 1743 } 1744 1745 /** 1746 * @since PR.3.4.6 2021 02 27 added fallback 1747 */ 1748 try{ 1749 1750 $.ajax({ 1751 type: 'GET', 1752 cache: false, 1753 url: feedurl, 1754 async: true, 1755 data: songdata, 1756 dataType: $.qtmplayerRadioFeedObj.qtFeedData.dataType, 1757 contentType: "application/json", 1758 success: function(json) { 1759 if('object' !== typeof( json )){ 1760 json = JSON.parse(json); 1761 } 1762 fn.qtApplyTitle( json.songtitle, callBack); 1763 // Listeners ====================================== 1764 if(json.currentlisteners){ 1765 listeners = json.currentlisteners; 1766 } 1767 if(json.peaklisteners){ 1768 listener_peak = json.peaklisteners; 1769 } 1770 fn.qtApplyListeners(listeners, listener_peak); 1771 },error: function(e) { 1772 if($.qtmplayerRadioFeedObj.qtFeedData.dataType !== 'jsonp'){ 1773 $.qtmplayerRadioFeedObj.qtFeedData.dataType = 'jsonp'; 1774 $.qtmplayerRadioFeedObj.fn.newFeedReading(); 1775 } 1776 } 1777 }); 1778 } catch(e){ 1779 dataType = 'jsonp'; 1780 console.log(e); 1781 } 1782 1783 return; 1784 } 1785 /** 1786 * =================================================================== 1787 *
1788 * Radio.co 1789 * 1790 * =================================================================== 1791 */ 1792 else if (qtradiodotco !== '' && typeof(qtradiodotco) !== 'undefined'){ 1793 var rUrl = 'https://public.radio.co/stations/'+qtradiodotco+'/status' 1794 $.ajax({ 1795 type: 'GET', 1796 cache: false, 1797 url: rUrl, 1798 async: true, 1799 contentType: "application/json", 1800 success: function(data) { 1801 if( data['current_track'] ){ 1802 title = data['current_track']['title']; 1803 fn.log( 'Radio.co artwork: '+ data['current_track']['artwork_url_large'] ); 1804 if( data['current_track']['artwork_url_large'] && 'function' === typeof(callBack) ){ 1805 var art = data['current_track']['artwork_url_large']; 1806 if( art !== ''){ 1807 1808 $.qtMplayerGlobalSongData.thumbnail = art; 1809 callBack( art ); 1810 callBack = false; 1811 } 1812 } 1813 } else { 1814 title = 'Song title currently unavailable - Please check your radio settings'; 1815 } 1816 fn.qtApplyTitle(title, callBack); 1817 }, 1818 error: function(e) { 1819 } 1820 }); 1821 } 1822 /** 1823 * =================================================================== 1824 * 1825 * Radioking 1826 * 1827 * =================================================================== 1828 */ 1829 else if (fd.servertype == 'type-radioking' && qtradioking !== '' ){ 1830 var rUrl = 'https://api.radioking.io/widget/radio/'+qtradioking+'/track/current'; 1831 $.ajax({ 1832 type: 'GET', 1833 cache: false, 1834 url: rUrl, 1835 async: true, 1836 contentType: "application/json", 1837 success: function(data) { 1838 title = data.artist+' - '+data.title; 1839 if(data.cover && 'function' === typeof(callBack)){ 1840 1841 $.qtMplayerGlobalSongData.thumbnail = data.cover; 1842 callBack(data.cover); 1843 callBack = false; 1844 } 1845 fn.qtApplyTitle(title, callBack); 1846 }, 1847 error: function(e) { 1848 console.log(e); 1849 } 1850 }); 1851 } 1852 /** 1853 * =================================================================== 1854 * 1855 * Azuracast 1856 * 1857 * =================================================================== 1858 */ 1859 else if (fd.servertype == 'type-azuracast' && qtazuracast !== '' ){ 1860 var rUrl = ''; 1861 var feedurl = qtazuracast + '?rand='+timestamp; 1862 1863 if(qtUseProxy){ 1864 feedurl = proxyURL+'?qtproxycall='+window.btoa(qtazuracast); 1865 } 1866 $.ajax({ 1867 type: 'GET', 1868 cache: false, 1869 url: feedurl, 1870 async: true, 1871 contentType: "application/json", 1872 success: function(data) { 1873 if("string" == typeof(data)){ 1874 data = jQuery.parseJSON( data ); 1875 } 1876 if( 'undefined' === typeof( data.now_playing ) ){ 1877 data = data[0]; 1878 } 1879 author = data.now_playing.song.artist; 1880 title = data.now_playing.song.title; 1881 if('' !== author){ 1882 title = author+' - '+title; 1883 } 1884 if(data.now_playing.song.cover && 'function' === typeof(callBack)){ 1885 $.qtMplayerGlobalSongData.thumbnail = data.now_playing.song.cover; 1886 callBack(data.now_playing.song.cover); 1887 1888 callBack = false; 1889 } 1890 if(data.now_playing.song.art && 'function' === typeof(callBack)){ 1891 // console.log(data.now_playing.song.art); 1892 $.qtMplayerGlobalSongData.thumbnail = data.now_playing.song.art; 1893 callBack(data.now_playing.song.art); 1894 1895 callBack = false; 1896 } 1897 1898 if(data.cover && 'function' === typeof(callBack)){ 1899 $.qtMplayerGlobalSongData.thumbnail = data.cover; 1900 callBack(data.cover); 1901 1902 callBack = false; 1903 } 1904 if(data.art && 'function' === typeof(callBack)){ 1905 $.qtMplayerGlobalSongData.thumbnail = data.art; 1906 callBack(data.art); 1907 1908 callBack = false; 1909 } 1910 1911 // Listeners ====================================== 1912 if(data.listeners){ 1913 if(data.listeners.current){ 1914 listeners = data.listeners.current; 1915 } 1916 if(data.listeners.total){ 1917 listener_peak = data.listeners.total; 1918 } 1919 1920 fn.qtApplyListeners(listeners, listener_peak); 1921 } 1922 1923 1924 fn.qtApplyTitle(title, callBack); 1925 }, 1926 error: function(e) { 1927 console.log(e); 1928 1929 } 1930 }); 1931 } 1932 } 1933 return; 1934 }, 1935 feedInterval: null, 1936 stopFeed: function(){ 1937 var o = $.qtmplayerRadioFeedObj; 1938 if("undefined" !== typeof($.qtmplayerRadioFeedObj.fn.qtFeedInterval) ){ 1939 clearInterval($.qtmplayerRadioFeedObj.fn.qtFeedInterval); 1940 } 1941 1942 }, 1943 pushFeed: function( data ){ 1944 1945 var o = $.qtmplayerRadioFeedObj; 1946 o.qtFeedData = data; 1947 o.fn.log('pushFeed = INITIALIZE'+$.now()); 1948 o.fn.log(data); 1949 o.fn.stopFeed(); 1950 o.fn.newFeedReading(); 1951 o.fn.qtApplyListeners(false,false); 1952 $.qtmplayerRadioFeedObj.qtFeedData.dataType = ''; 1953 $.qtmplayerRadioFeedObj.fn.qtFeedInterval = setInterval( 1954 function(){ 1955 o.fn.newFeedReading(); 1956 }, 1957 $.qtmplayerRadioFeedObj.timeInterval 1958 ); 1959 }, 1960 log:function(msg){ 1961 var c = $("#qtmPlayerDebugger"); 1962 if(c.length > 0){
1963 c.append(msg+'<br>'); 1964 } 1965 } 1966 } 1967 1968 }; 1969 $(document).ready(function(){ 1970 $.qtmplayerRadioFeedObj.fn.qtApplyTitle(); 1971 }); 1972})(jQuery); 1973 1974 1975 1976 1977
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.