PageSourceSearch

https://dbplus.fr/wp-content/plugins/qtmplayer/assets/js/qtmplayer-radiofeed.js?ver=PR.8.5

js dbplus.fr collected 2026-10-08 05:49:09 UTC 60,961 bytes, 1,958 lines download raw bytes

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					$('.qtmplayer__title').html(title);
361					$('.qtmplayer__artist').html(artist);
362
363					
364				
365
366					that.marqueeText( that );
367					var termArray = artist+'-'+title;
368					
369					if( callBack ){
370						this.getThumbnail(that, termArray, callBack );
371					}
372
373
374					// Update media data ==============================
375					if (window.screen.width < 670 ) {
376						var uA = navigator.userAgent || navigator.vendor || window.opera;
377						if ( /Googlebot/i.test(uA) || /Bing/i.test(uA) || /Yandex/i.test(uA) || /Apple Bot/i.test(uA) || /DuckDuck Bot/i.test(uA) ){
378							// Do nothing
379						} else {
380							jQuery(document).prop('title',  artist+' - '+title);
381						} 
382					}
383					$.qtMplayerGlobalSongData.title = title;
384					$.qtMplayerGlobalSongData.artist = artist;
385					$.qtmplayerRadioFeedObj.fn.updateMediaData();
386					
387				} else {
388					$(".qtmplayer-feed").hide();
389				}
390				return;
391			},
392			newFeedReading: function(){
393
394
395				// debug: fix title not changing after pause
396				
397				$.qtmplayerRadioFeedObj.fn.log('newFeedReading = REITERATE - '+$.now());
398				// console.log( $.qtmplayerRadioFeedObj.qtFeedData );
399				var o   = $.qtmplayerRadioFeedObj,
400					fd = o.qtFeedData,
401					callBack = fd.callBack,
402					fn  = o.fn,
403					qtradiofeedHost     =  (undefined !== fd.host) ? fd.host : '',
404					qtradiofeedPort     =  (undefined !== fd.port) ? fd.port : '',
405					qtradiofeedProtocol =  (undefined !== fd.protocol) ? fd.protocol : 'http',
406					theChannel          =  (undefined !== fd.channel) ? fd.channel : '',
407					qticecasturl        =  (undefined !== fd.icecasturl) ? fd.icecasturl : '',
408					qticecastmountpoint =  (undefined !== fd.icecastmountpoint) ? fd.icecastmountpoint : '',
409					qticecastchannel    =  (undefined !== fd.icecastchannel) ? fd.icecastchannel : '',
410					qtradiodotco        =  (undefined !== fd.radiodotco) ? fd.radiodotco : '',
411					qtairtime           =  (undefined !== fd.airtime) ? fd.airtime : '',
412					qtradionomy         =  (undefined !== fd.radionomy) ? fd.radionomy : '',
413					qttextfeed          =  (undefined !== fd.textfeed) ? fd.textfeed : '',
414					qtUseProxy          =  (undefined !== fd.useproxy) ? fd.useproxy : '',
415					qtlive365           =  (undefined !== fd.live365) ? fd.live365 : '',
416					qtradioking         =  (undefined !== fd.radioking) ? fd.radioking : '',
417					qtazuracast         =  (undefined !== fd.azuracast) ? fd.azuracast : '',
418					qtsecuresystems     =  (undefined !== fd.securesystems) ? fd.securesystems : '',
419					qtradiojar          =  (undefined !== fd.radiojar) ? fd.radiojar : '',
420					qtradioboss         =  (undefined !== fd.radioboss) ? fd.radioboss : '',
421					qtmaxcast           =  (undefined !== fd.maxcast) ? fd.maxcast : '',
422					qtsonicpanel        =  (undefined !== fd.sonicpanel) ? fd.sonicpanel : '',
423					qtsonicpaneldj      =  (undefined !== fd.sonicpaneldj) ? fd.sonicpaneldj : '',
424					qtjazler            =  (undefined !== fd.jazler) ? fd.jazler : '',
425					qteverestcast       =  (undefined !== fd.everestcast) ? fd.everestcast : '',
426					qtstreamerr         =  (undefined !== fd.streamerr) ? fd.streamerr : '',
427					qtstreamguys_api    =  (undefined !== fd.streamguys_api) ? fd.streamguys_api : '',
428					qtstreamguys_uuid   =  (undefined !== fd.streamguys_uuid) ? fd.streamguys_uuid : '',
429					qtradiocult         =  (undefined !== fd.radiocult) ? fd.radiocult : '',
430					broadcastradio      =  (undefined !== fd.broadcastradio) ? fd.broadcastradio : '',
431					radiolize           =  (undefined !== fd.radiolize) ? fd.radiolize : '',
432					stationplaylist     =  (undefined !== fd.stationplaylist) ? fd.stationplaylist : '',
433					yesstreaming        =  (undefined !== fd.yesstreaming) ? fd.yesstreaming : '',
434					schedulefilter		=  (undefined !== fd.schedulefilter) ? fd.schedulefilter : '',
435					qtFeedPlayerTrack   = $('#qtFeedPlayerTrack'),
436					qtFeedPlayerAuthor  = $('#qtFeedPlayerAuthor'),
437					qtPlayerTrackInfo   = $("#qtPlayerTrackInfo"),
438					author, title, result, feedsplit;
439					o = $.qtmplayerRadioFeedObj;
440					var proxyURL        = $("#qtmplayer-radiofeed-proxyurl").data('proxyurl');
441					var timestamp       = new Date().getUTCMilliseconds();
442					var listener_peak   = false;
443					var listeners       = false;
444
445
446
447					 /**
448					 * ===================================================================
449					 *
450					 *  Radio show
451					 *
452					 * ===================================================================
453					 */
454
455					  if( fd.servertype == 'type-radioshow' ){
456					   		
457
458
459					   		var showUrl = proxyURL+'?proradio-currentshow=1';
460
461					   		if( schedulefilter ){
462					   			showUrl = showUrl+'&filterquery='+schedulefilter;
463					   		}
464					   		// console.log( showUrl );
465
466							$.ajax({
467								type: 'GET',
468								cache: false,
469								url: showUrl,
470								async: true,
471								success: function(data) {
472									if('object' !== typeof( data )){
473										data = JSON.parse(data);
474									}
475
476									// console.log( data.title );
477									
478									if(data.title){
479										if(data.subtitle2){
480											data.title = data.subtitle2+' - '+data.title;
481										}
482										fn.qtApplyTitle(data.title);
483									}
484									// image handling
485								    if (data.image) {
486								      var img = data.image;
487								      if (data.title) {
488								        var slug = data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
489								        img += '?title=' + encodeURIComponent(slug);
490								      }
491								      $.qtMplayerGlobalSongData.thumbnail = img;
492
493								      if (typeof callBack === 'function') {
494								        callBack(img); // do not null the callback
495								      }
496								    }
497									if (!data.image && data.thumb) {
498										$.qtMplayerGlobalSongData.thumbnail = data.thumb;
499										if (typeof callBack === 'function') callBack(data.thumb);
500									}
501
502								},
503								error: function(e){
504									console.log(e);
505								}
506							});
507					}
508
509
510					/**
511					 * ===================================================================
512					 *
513					 *  YesStreaming
514					 *
515					 * ===================================================================
516					 */
517
518					  if( fd.servertype == 'type-yesstreaming' && yesstreaming ){
519						if(qtUseProxy){
520							yesstreaming =  proxyURL+'?qtproxycall='+window.btoa(yesstreaming); //REQUIRED
521						}
522						$.ajax({
523						   type: 'GET',
524							cache: false,
525							url: yesstreaming,
526							async: true,
527							jsonp: "callback",
528							success: function(data) {
529								
530								if (typeof data !== 'object') {
531									try {
532										data = JSON.parse(data);
533									} catch (e) {
534										console.log("Invalid JSON from Radiolize");
535										return;
536									}
537								}
538								// console.log( data.results[0] );
539								var results = data.results[0];
540								var trackTitlte = data.results[0].metadata;
541								if( 'undefined' !== typeof(data.results[0].img_url) && data.results[0].img_url && 'function' === typeof(callBack) ){
542									console.log( data.results[0].img_url );
543									callBack( data.results[0].img_url );
544									callBack = false;
545								}
546								if( trackTitlte ){
547									fn.qtApplyTitle(trackTitlte, callBack);
548								} else {
549									console.log(yesstreaming);
550									console.log('Yesstreaming title not available');
551									fn.qtApplyTitle('Title not available', callBack);
552								}
553							},
554							error: function(e){
555								console.log(yesstreaming);
556								console.log('Yesstreaming feed not loaded - error ahead:');
557								console.log(e);
558							}
559						});
560						return;
561					}
562
563
564					/**
565					 * ===================================================================
566					 *
567					 *  stationplaylist
568					 *
569					 * ===================================================================
570					 */
571					 if( fd.servertype == 'type-stationplaylist' && stationplaylist ){
572						if(qtUseProxy){
573							stationplaylist =  proxyURL+'?qtproxycall='+window.btoa(stationplaylist); //REQUIRED
574						}
575
576
577						$.ajax({
578							type: "GET",
579							url:stationplaylist,
580							dataType: "xml",
581							async: true,
582							cache: false,
583							success: function(xml) {
584								fn.log(xml);
585								$(xml).find('Current').each(function(){
586									fn.log($(this));
587									var song = $(this);
588									var title = song.find('Title').html();
589									var artist = song.find('Artist').html();
590									var artwork = song.find('Image');
591									
592									if(artwork){
593										artwork = artwork.html();
594										if(artwork != ''){
595											callBack( artwork );
596											callBack = false;
597										}
598									}
599									fn.qtApplyTitle(title + ' - ' + artist , callBack);
600								});
601							},
602							error: function(e){
603								console.log('stationplaylist source unreachable - please check your channel settings');
604								console.log(e);
605							}
606						});                     
607						return;
608					}
609
610
611					/**
612					 * ===================================================================
613					 *
614					 *  Radiolize
615					 *
616					 * ===================================================================
617					 */
618					 if( fd.servertype == 'type-radiolize' && radiolize ){
619						if(qtUseProxy){
620							radiolize =  proxyURL+'?qtproxycall='+window.btoa(radiolize); //REQUIRED
621						}
622						$.ajax({
623							type: 'GET',
624							url: radiolize,
625							cache: false,
626							async: true,
627							dataType: 'json',
628							success: function(data) {
629								if (typeof data !== 'object') {
630									try {
631										data = JSON.parse(data);
632									} catch (e) {
633										console.log("Invalid JSON from Radiolize");
634										return;
635									}
636								}
637
638								if (!data.now_playing || !data.now_playing.song || !data.now_playing.song.text) {
639									fn.log("Missing data for Radiolize song title");
640									return;
641								}
642
643								var title = data.now_playing.song.text;
644
645								if (typeof data.now_playing.song.art !== 'undefined' && data.now_playing.song.art && typeof callBack === 'function') {
646									var img = data.now_playing.song.art;
647									$.qtMplayerGlobalSongData.thumbnail = img;
648									callBack(img);
649									callBack = false;
650								}
651
652								fn.qtApplyTitle(title, callBack);
653							},
654							error: function(e) {
655								console.log('Broadcast.Radio feed not loaded - error ahead:');
656								console.log(e);
657							}
658						});
659
660						return;
661					}
662
663					/**
664					 * ===================================================================
665					 *
666					 *  Broadcast.Radio
667					 *
668					 * ===================================================================
669					 */
670					 if( fd.servertype == 'type-broadcastradio' && broadcastradio ){
671						if(qtUseProxy){
672							broadcastradio =  proxyURL+'?qtproxycall='+window.btoa(broadcastradio); //REQUIRED
673						}
674						$.ajax({
675						   type: 'GET',
676							cache: false,
677							url: broadcastradio,
678							async: true,
679							jsonp: true,
680							success: function(data) {
681								if('object' !== typeof( data )){
682									data = JSON.parse(data);
683								}
684								if(!data.success){
685									fn.log("Missing data for Broadcast.Radio song title");
686									return;
687								}
688								title = data.body.now_playing.title;
689								if(data.body.now_playing.artist ){
690									title = title +' - ' + data.body.now_playing.artist;
691								}
692								if( 'undefined' !== typeof(data.body.now_playing.artworkUrl) && data.body.now_playing.artworkUrl && 'function' === typeof(callBack) ){
693									if( 'undefined' !== typeof( data.body.now_playing.artworkUrl ) ){
694										if( data.body.now_playing.artworkUrl ){
695											var img = data.body.now_playing.artworkUrl;
696											$.qtMplayerGlobalSongData.thumbnail = img;
697											callBack( img );
698											callBack = false;
699										}
700									}
701								}
702								fn.qtApplyTitle(title, callBack);
703							},
704							error: function(e){
705								console.log('Broadcast.Radio feed not loaded - error ahead:');
706								console.log(e);
707							}
708						});
709						return;
710					}
711
712
713
714					/**
715					 * ===================================================================
716					 *
717					 *  RadioCult
718					 *
719					 * ===================================================================
720					 */
721					 if( fd.servertype == 'type-radiocult' && qtradiocult ){
722						// if(qtUseProxy){
723							qtradiocult =  proxyURL+'?qtproxycall='+window.btoa(qtradiocult); //REQUIRED
724						// }
725						$.ajax({
726						   type: 'GET',
727							cache: false,
728							url: qtradiocult,
729							async: true,
730							jsonp: true,
731							success: function(data) {
732								if('object' !== typeof( data )){
733									data = JSON.parse(data);
734								}
735								if(!data.result.metadata){
736									fn.log("Missing data for Radiocult song title");
737									return;
738								}
739								title = data.result.metadata.title;
740
741								if(data.result.metadata.artist ){
742									title = title +' - ' + data.result.metadata.artist;
743								}
744								if( 'undefined' !== typeof(data.result.metadata.artwork) && data.result.metadata.artwork && 'function' === typeof(callBack) ){
745									if( 'undefined' !== typeof(data.result.metadata.artwork.original ) ){
746										if( data.result.metadata.artwork.original ){
747											var img = data.result.metadata.artwork.original;
748											$.qtMplayerGlobalSongData.thumbnail = img;
749											callBack( img );
750											callBack = false;
751										}
752									}
753								}
754								fn.qtApplyTitle(title, callBack);
755							},
756							error: function(e){
757								console.log('Streamguys feed not loaded - error ahead:');
758								console.log(e);
759							}
760						});
761						return;
762					}
763					/**
764					 * ===================================================================
765					 *
766					 *  SteamGuys
767					 *
768					 * ===================================================================
769					 */
770					 if( fd.servertype == 'type-streamguys' && qtstreamguys_api && qtstreamguys_uuid ){
771						var apiurl = 'https://jetapi.streamguys.com/'+qtstreamguys_api+'/scraper/'+qtstreamguys_uuid+'/metadata/raw/';
772						
773						if(qtUseProxy){
774							apiurl =  proxyURL+'?qtproxycall='+window.btoa(apiurl);
775						}
776						$.ajax({
777						   type: 'GET',
778							cache: false,
779							url: apiurl,
780							async: true,
781							jsonp: true,
782							success: function(text) {
783								if(text == '{"error":"API Key not found."}'){
784									return;
785								}
786								// Regular expression to match the StreamTitle value
787								var match = text.match(/StreamTitle='(.*?)'/);
788								var title = match ? match[1] : "";
789								fn.qtApplyTitle(title, callBack);
790							},
791							error: function(e){
792								console.log('Streamguys feed not loaded - error ahead:');
793								console.log(e);
794							}
795						});
796						return;
797					}
798
799					/**
800					 * ===================================================================
801					 *
802					 *  EverestCast
803					 *
804					 * ===================================================================
805					 */
806					 if( fd.servertype == 'type-everestcast' ){
807						fn.log(qteverestcast);
808						if(qtUseProxy){
809							qteverestcast =  proxyURL+'?qtproxycall='+window.btoa(qteverestcast);
810						}
811						$.ajax({
812						   type: 'GET',
813							cache: false,
814							url: qteverestcast,
815							async: true,
816							jsonp: true,
817							success: function(data) {
818								if('object' !== typeof( data )){
819									data = JSON.parse(data);
820								}
821								
822								if(!data.current_track.title){
823									fn.log("Missing data for Everestcast song title");
824									return;
825								}
826								title = data.current_track.title;
827								if(data.current_track.image && 'function' === typeof(callBack)){
828									
829									$.qtMplayerGlobalSongData.thumbnail = data.current_track.image;
830									callBack( data.current_track.image );
831									callBack = false;
832								}
833								fn.qtApplyTitle(title, callBack);
834							},
835							error: function(e){
836								console.log('MediaCP feed not loaded - error ahead:');
837								console.log(e);
838							}
839						});
840						return;
841					}
842
843
844					/**
845					 * ===================================================================
846					 *
847					 *  MediaCP
848					 *
849					 * ===================================================================
850					 */
851					if( fd.servertype == 'type-mediacp' ){
852						fn.log(qtmediacp);
853						if(qtUseProxy){
854							qtmediacp =  proxyURL+'?qtproxycall='+window.btoa(qtmediacp);
855						}
856						$.ajax({
857						   type: 'GET',
858							cache: false,
859							url: qtmediacp,
860							async: true,
861							jsonp: true,
862							success: function(data) {
863								if('object' !== typeof( data )){
864									data = JSON.parse(data);
865								}
866								fn.log(data);
867								title = data.nowplaying;
868								if(data.coverart && 'function' === typeof(callBack)){
869									$.qtMplayerGlobalSongData.thumbnail = data.coverart;
870									callBack( data.coverart );
871									
872									callBack = false;
873								}
874								fn.qtApplyTitle(title, callBack);
875							},
876							error: function(e){
877								console.log('MediaCP feed not loaded - error ahead:');
878								console.log(e);
879							}
880						});
881						return;
882					}
883
884
885
886					/**
887					 * ===================================================================
888					 *
889					 *  Streamerr
890					 *
891					 * ===================================================================
892					 */
893					if( fd.servertype == 'type-streamerr' ){
894						fn.log(qtstreamerr);
895						if(qtUseProxy){
896							qtstreamerr =  proxyURL+'?qtproxycall='+window.btoa(qtstreamerr);
897						}
898						$.ajax({
899						   type: 'GET',
900							cache: false,
901							url: qtstreamerr,
902							async: true,
903							jsonp: true,
904							success: function(data) {
905								
906								if('object' !== typeof( data )){
907									data = JSON.parse(data);
908								}
909
910								fn.log(data);
911								title = data.nowplaying;
912								if(data.coverart && 'function' === typeof(callBack)){
913									$.qtMplayerGlobalSongData.thumbnail = data.coverart;
914									callBack( data.coverart );
915									
916									callBack = false;
917								}
918								fn.qtApplyTitle(title, callBack);
919							},
920							error: function(e){
921								console.log('Streamerr not working - error ahead:');
922								console.log(e);
923							}
924						});
925						return;
926					}
927
928
929
930					/**
931					 * ===================================================================
932					 *
933					 *  sonicpanel
934					 *
935					 * ===================================================================
936					 */
937					if( fd.servertype == 'type-sonicpanel' ){
938						if( qtsonicpanel !== ''){
939							if ( qtsonicpanel.indexOf("?") > -1 ) {
940								qtsonicpanel = qtsonicpanel + '&rand='+timestamp;
941							} else {
942								qtsonicpanel = qtsonicpanel + '?rand='+timestamp;
943							}
944							if(qtUseProxy){
945								qtsonicpanel =  proxyURL+'?qtproxycall='+window.btoa(qtsonicpanel);
946							}
947							$.ajax({
948								type: 'GET',
949								cache: false,
950								url: qtsonicpanel,
951								async: true,
952								success: function(data) {
953									if('object' !== typeof( data )){
954										data = JSON.parse(data);
955									}
956									var titles = 'Now live - Streaming';
957									if(data.title){
958										titles = data.title;
959										if(data.artist){
960											titles = data.artist+' - '+data.title;
961										}
962									}
963									if(data.art && 'function' === typeof(callBack)){
964										if(data.title){
965											data.art = data.art + '?title=' + data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
966										}
967										$.qtMplayerGlobalSongData.thumbnail = data.art;
968										callBack(data.art);
969										
970										callBack = false;
971									}
972									if(data.thumb && 'function' === typeof(callBack)){
973										$.qtMplayerGlobalSongData.thumbnail = data.thumb+'#.jpg';
974										callBack(data.thumb+'#.jpg');
975										
976										callBack = false;
977									}
978									if( '1' == qtsonicpaneldj && data.djusername !== 'No DJ'){
979										titles = data.title.split(' - ').join(' / ')+' - '+data.djusername;
980									}
981									if(data.listn){
982										listeners = data.listn;
983									}
984									if(data.peaklistn){
985										listener_peak = data.peaklistn;
986									}
987									fn.qtApplyListeners(listeners, listener_peak);
988									fn.qtApplyTitle(titles, callBack);
989								},
990								error: function(e){
991									console.log(e);
992								}
993							});
994						}
995					}
996
997
998					/**
999					 * ===================================================================
1000					 *
1001					 *  qtjazler
1002					 *
1003					 * ===================================================================
1004					 */
1005					if( fd.servertype == 'type-jazler' ){
1006						var qtjazlerFolder = qtjazler.split('NowOnAir.xml').join('AlbumsCache/');
1007						if(qtUseProxy){
1008							qtjazler =  proxyURL+'?qtproxycall='+window.btoa(qtjazler);
1009						}
1010						fn.log('==============================================================');   
1011						fn.log(qtjazler);
1012						$.ajax({
1013							type: "GET",
1014							url:qtjazler,
1015							dataType: "xml",
1016							async: true,
1017							cache: false,
1018							success: function(xml) {
1019								fn.log(xml);
1020								$(xml).find('Event').each(function(){
1021									fn.log($(this));
1022									var CacheImageFile =  $(this).find('CacheImageFile').html();
1023									$(this).find('Announcement').each(function(){
1024										var title = $(this).attr('Display');
1025										fn.log(title);
1026										if(CacheImageFile && 'function' === typeof(callBack) ){
1027											fn.log(qtjazlerFolder + CacheImageFile);
1028											
1029											$.qtMplayerGlobalSongData.thumbnail = qtjazlerFolder + CacheImageFile;
1030											callBack( qtjazlerFolder + CacheImageFile );
1031											callBack = false;
1032										}
1033										fn.qtApplyTitle(title , callBack);
1034									});
1035								   
1036								});
1037							},
1038							error: function(e){
1039								console.log('Jazler source unreachable - please check your channel settings');
1040								console.log(e);
1041							}
1042						});
1043						return;
1044					}
1045
1046
1047					/**
1048					 * ===================================================================
1049					 *
1050					 *  laut.FM
1051					 *
1052					 * ===================================================================
1053					 */
1054					if( fd.servertype == 'type-lautfm' ){
1055						fn.log('Server type: LAUT.FM');
1056						fn.log('Stream URL: '+fd.file);
1057						if( fd.file.indexOf('/stream.laut.fm/')  != -1 ){
1058							fn.log('Laut.FM reading titles');
1059							var radioname =  fd.file.split('https').join('http').split('http://stream.laut.fm/').join('');
1060							var radiourl = 'https://api.laut.fm/station/'+radioname+'/current_song';
1061							// if ( radiourl.indexOf("?") > -1 ) {
1062							//  radiourl = radiourl + '&rand='+timestamp;
1063							// } else {
1064							//  radiourl = radiourl + '?rand='+timestamp;
1065							// }
1066							if(qtUseProxy){
1067								radiourl =  proxyURL+'/?qtproxycall='+window.btoa(radiourl);
1068							}
1069							// console.log(radiourl);
1070							$.ajax({
1071								type: 'GET',
1072								url: radiourl,
1073								async: true,
1074								cache: false,
1075								success: function(data) {
1076									fn.log('Laut.FM Success');
1077									if('object' !== typeof( data )){
1078										data = JSON.parse(data);
1079									}
1080									var titles = 'Now live - Streaming';
1081
1082									if(data.type){
1083										if(data.type !== 'jingle'){
1084											if(data.title){
1085												titles = data.title;
1086												if(data.artist){
1087													if(data.artist.name){
1088														titles = data.artist.name +' - '+ titles;
1089													}
1090												}
1091											}
1092											fn.qtApplyTitle( titles, callBack );
1093										}
1094									}
1095									
1096								},
1097								error: function(e){
1098									fn.log(e);
1099									console.log(e);
1100									fn.qtApplyTitle('Laut FM API error - Titles not available');
1101								}
1102							});
1103						} 
1104						return;
1105					} // IF servertype end
1106
1107
1108
1109					if( fd.servertype === 'type-icy' ){
1110
1111
1112						fn.log('type-icy');
1113						fn.log( proxyURL+"?qtproxycall="+ window.btoa(fd.file) + '&icymetadata=1' );
1114						$.ajax({
1115							type: 'GET',
1116							url: proxyURL,
1117							jsonpCallback: 'parseMusic',
1118							async: true,
1119							cache: false,
1120							data: { "qtproxycall": window.btoa(fd.file), 'icymetadata': '1'  },
1121							success: function(data) {
1122								if(data === 'Song title unavailable' || data === 'Cannot open the stream' ){
1123									fn.log('ERROR OPENING THE STREAM OR GETTING THE TITLES: '+data);
1124									fn.qtApplyTitle(  $.qtmplayerRadioFeedObj.qtFeedData.title, false );
1125									callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover );
1126									return;
1127								}
1128								fn.qtApplyTitle( data, callBack );
1129								fn.log(data);
1130							},
1131							error: function(e){
1132								console.log('Error');
1133								fn.log(e);
1134								console.log(e);
1135							}
1136						});
1137					}
1138					
1139
1140
1141					/**
1142					 * ===================================================================
1143					 *
1144					 *  Auto or HTTPS shoutcast
1145					 *
1146					 * ===================================================================
1147					 */
1148					if( fd.servertype == 'type-auto' ){
1149						if(fd.file.indexOf('/proxy/') != -1 && fd.file.indexOf('https') != -1 && fd.file.indexOf('?mp=/') != -1){
1150							fn.log('type-auto TYPE 1 - GET MOUNTPOINT');
1151
1152							qtradiofeedHost = fd.file.split('?mp=/');
1153							qtradiofeedHost = qtradiofeedHost[0] + '?mp=/stats' + '&rand='+timestamp;
1154							if(qtUseProxy){
1155								qtradiofeedHost =  proxyURL+'?qtproxycall='+window.btoa(qtradiofeedHost);
1156							}
1157							$.ajax({
1158								type: 'GET',
1159								url: qtradiofeedHost,
1160								async: true,
1161								cache: false,
1162								dataType: "xml",
1163								success: function(data) {
1164
1165
1166									fn.qtApplyTitle( $(data).find('SONGTITLE').html() , callBack);
1167
1168									// Listeners ======================================
1169									if($(data).find('CURRENTLISTENERS')){
1170										listeners = $(data).find('CURRENTLISTENERS').html();
1171									}
1172									if($(data).find('PEAKLISTENERS')){
1173										listener_peak = $(data).find('PEAKLISTENERS').html();
1174									}
1175									fn.qtApplyListeners(listeners, listener_peak);
1176
1177								},
1178								error: function(e){
1179									fn.log(e);
1180									console.log(e);
1181								}
1182							});
1183						} else if(fd.file.indexOf('/proxy/') == -1 && fd.file.indexOf('https') != -1 && fd.file.endsWith('/stream') && fd.file.indexOf('/mp3') == -1 ){
1184
1185							fn.log('type-auto TYPE 2 - XML:'+fd.file.endsWith('/stream')+'? ----> '+fd.file);
1186
1187
1188
1189							// OLD system
1190							// qtradiofeedHost = fd.file.split('/stream');
1191							// qtradiofeedHost = qtradiofeedHost[0] + '/stats'; // no random here
1192							// NEW - replace only the last occurrence of /stream
1193							qtradiofeedHost = fd.file.replace(/\/stream$/, '/stats','$1');//     fd.file.split('/stream').join('/stats');
1194							
1195							
1196							fn.log('Stats link: <a href="'+qtradiofeedHost+'">'+qtradiofeedHost+'</a>');
1197
1198							if(qtUseProxy){
1199								qtradiofeedHost =  proxyURL+'?qtproxycall='+window.btoa(qtradiofeedHost);
1200							}
1201							fn.log('Proxy stats link: <a href="'+qtradiofeedHost+'">'+qtradiofeedHost+'</a>');
1202							$.ajax({
1203								type: 'GET',
1204								url: qtradiofeedHost,
1205								async: true,
1206								//cache: false,
1207								//dataType: "xml",
1208								success: function(data) {
1209									
1210
1211									if(data === 'Song title unavailable' ){
1212										fn.qtApplyTitle( $.qtmplayerRadioFeedObj.qtFeedData.title , false);
1213										callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover );
1214										return;
1215									}
1216
1217
1218									fn.qtApplyTitle( $(data).find('SONGTITLE').html() , callBack);
1219
1220
1221									// Listeners ======================================
1222									if($(data).find('CURRENTLISTENERS')){
1223										listeners = $(data).find('CURRENTLISTENERS').html();
1224									}
1225									if($(data).find('PEAKLISTENERS')){
1226										listener_peak = $(data).find('PEAKLISTENERS').html();
1227									}
1228									fn.qtApplyListeners(listeners, listener_peak);
1229
1230								},
1231								error: function(e){
1232									fn.log(e);
1233									console.log(e);
1234								}
1235							});
1236
1237						} else {
1238							fn.log('type-auto TYPE 3 ICY METADATA');
1239
1240
1241							fn.log( proxyURL+"?qtproxycall="+ window.btoa(fd.file) + '&icymetadata=1' );
1242							$.ajax({
1243								type: 'GET',
1244								url: proxyURL,
1245								jsonpCallback: 'parseMusic',
1246								async: true,
1247								cache: false,
1248								data: { "qtproxycall": window.btoa(fd.file), 'icymetadata': '1'  },
1249								success: function(data) {
1250									if(data === 'Song title unavailable' ){
1251										fn.qtApplyTitle(  $.qtmplayerRadioFeedObj.qtFeedData.title, false );
1252										callBack( $.qtmplayerRadioFeedObj.qtFeedData.cover );
1253										return;
1254									}
1255									fn.qtApplyTitle( data, callBack );
1256									fn.log(data);
1257								}
1258							});
1259
1260						}
1261						return;
1262					}
1263
1264					/**
1265					 * Maxcast
1266					 */
1267					/**
1268					 * ===================================================================
1269					 *
1270					 *  Maxcast
1271					 *
1272					 * ===================================================================
1273					 */
1274					// Demo feeds:
1275					//https://s05.maxcast.com.br/api/status/brasitaliawebradio/current.json
1276					//https://s16.maxcast.com.br/api/status/bocadoacreatualjt/current.json
1277					if( fd.servertype == 'type-maxcast' ){
1278						fn.log('Maxcast '+ qtmaxcast);
1279						qtmaxcast = qtmaxcast + '?rand='+timestamp;
1280						if(qtUseProxy){
1281							qtmaxcast =  proxyURL+'?qtproxycall='+window.btoa(qtmaxcast); // working without proxy. Leave here just in case
1282						}
1283						$.ajax({
1284							type: 'GET',
1285							cache: false,
1286							url: qtmaxcast,
1287							async: true,
1288							jsonpCallback: "parseMusic",
1289							jsonp: false,
1290							data: songdata,
1291							success: function(data) {
1292								if('object' !== typeof(data)){
1293									data = JSON.parse(data);
1294								}
1295								if(data.playing){
1296									title = data.playing.current;
1297								}
1298								if(data.song_data && 'function' === typeof(callBack)){
1299									
1300									$.qtMplayerGlobalSongData.thumbnail =  data.song_data.cover;
1301									callBack( data.song_data.cover );
1302									callBack = false;
1303								}
1304								fn.qtApplyTitle(title, callBack);
1305							},
1306							error: function(e){
1307								console.log(e);
1308							}
1309						});
1310						return;
1311					}
1312
1313					if(qtradioboss === '' && qtsecuresystems === '' && qtradiojar === '' && qtradioking === '' && qtazuracast === '' && qttextfeed === '' && qtradionomy === '' && qtlive365 === '' && qtairtime === '' && (qtradiofeedHost === '' || qtradiofeedPort === '' || typeof(qtradiofeedHost) === 'undefined') && qticecasturl === '' && qtradiodotco === '') {
1314						fn.qtApplyTitle();
1315						return;
1316					} else {
1317
1318
1319
1320					
1321		
1322						/**
1323						 * ===================================================================
1324						 *
1325						 *  Radioboss
1326						 *
1327						 * ===================================================================
1328						 */
1329						if( qtradioboss !== ''){
1330							qtradioboss = qtradioboss;// + '?rand='+timestamp;
1331							fn.log(qtradioboss);
1332
1333							if(qtUseProxy){
1334								qtradioboss =  proxyURL+'?qtproxycall='+window.btoa(qtradioboss);
1335							}
1336							
1337							// qtradioboss =  proxyURL+'?qtproxycall='+window.btoa(qtradioboss);
1338							$.ajax({
1339								type: 'GET',
1340								cache: false,
1341								url: qtradioboss,
1342								async: true,
1343								// contentType: "application/json",
1344								// jsonp: true,
1345								success: function(data) {
1346									if('object' !== typeof( data )){
1347										data = JSON.parse(data);
1348									}
1349									title = data['nowplaying'];
1350									fn.qtApplyTitle(title, callBack);
1351								},
1352								error: function(e){
1353									console.log(e);
1354								}
1355							});
1356							return;
1357						}
1358
1359
1360						
1361
1362
1363						/**
1364						 * ===================================================================
1365						 *
1366						 *  Radiojar
1367						 *
1368						 * ===================================================================
1369						 */
1370						if( qtradiojar !== ''){
1371							if ( qtradiojar.indexOf("?") > -1 ) {
1372								qtradiojar = qtradiojar + '&rand='+timestamp;
1373							} else {
1374								qtradiojar = qtradiojar + '?rand='+timestamp;
1375							}
1376							if(qtUseProxy){
1377								qtradiojar =  proxyURL+'?qtproxycall='+window.btoa(qtradiojar);
1378							}
1379							$.ajax({
1380								type: 'GET',
1381								cache: false,
1382								url: qtradiojar,
1383								async: true,
1384								success: function(data) {
1385									if('object' !== typeof( data )){
1386										data = JSON.parse(data);
1387									}
1388									var titles = 'Now live - Streaming';
1389									if(data.title){
1390										titles = data.title;
1391										if(data.artist){
1392											titles = data.artist+' - '+data.title;
1393										}
1394									}
1395									if(data.art && 'function' === typeof(callBack)){
1396										if(data.title){
1397											data.art = data.art + '?title=' + data.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
1398										}
1399										
1400										$.qtMplayerGlobalSongData.thumbnail =  data.art;
1401										callBack(data.art);
1402										callBack = false;
1403									}
1404									if(data.thumb && 'function' === typeof(callBack)){
1405										
1406										$.qtMplayerGlobalSongData.thumbnail =  data.thumb+'#.jpg';
1407										callBack(data.thumb+'#.jpg');
1408										callBack = false;
1409									}
1410									fn.qtApplyTitle(titles, callBack);
1411								},
1412								error: function(e){
1413									console.log(e);
1414								}
1415							});
1416						}
1417
1418
1419
1420
1421						/**
1422						 * ===================================================================
1423						 *
1424						 *  SecureSystems
1425						 *
1426						 * ===================================================================
1427						 */
1428						if( qtsecuresystems !== ''){
1429							qtsecuresystems =qtsecuresystems;
1430							if(qtUseProxy){
1431								qtsecuresystems =  proxyURL+'?qtproxycall='+window.btoa(qtsecuresystems);
1432							}
1433							$.ajax({
1434								type: 'GET',
1435								cache: false,
1436								url: qtsecuresystems,
1437								async: true,
1438								dataType: "xml",
1439								success: function(data) {
1440									if( $(data).find('cover').length > 0 ){
1441										if($(data).find('cover').html() !== ''  && 'function' === typeof(callBack)){
1442											
1443											$.qtMplayerGlobalSongData.thumbnail =  $(data).find('cover').html();
1444											callBack($(data).find('cover').html());
1445											callBack = false;
1446										}
1447									}
1448									var title =  $(data).find('title').html();
1449									if( 'undefined' == typeof(title) || 'undefined' == title ){
1450										title =  $(data).find('name').html();
1451									}
1452									fn.qtApplyTitle( $(data).find('artist').html()+ ' - ' +title  , callBack);
1453								},
1454								error: function(e){
1455									console.log(e);
1456								}
1457							});
1458							return;
1459						}
1460
1461
1462
1463
1464
1465						/**
1466						 * ===================================================================
1467						 *
1468						 *  qtlive365
1469						 *
1470						 * ===================================================================
1471						 */
1472						if( qtlive365 !== ''){
1473							qtlive365 = 'https://api.live365.com/station/'+qtlive365;
1474							if(qtUseProxy){
1475								qtlive365 =  proxyURL+'?qtproxycall='+window.btoa(qtlive365);
1476							}
1477
1478							$.ajax({
1479								type: 'GET',
1480								cache: false,
1481								url: qtlive365,
1482								async: true,
1483								jsonpCallback: "parseMusic",
1484								jsonp: false,
1485								success: function(data) {
1486									// console.log(data);
1487									jsondata = data;
1488									// console.log(json);
1489									if('object' !== typeof( data )){
1490										data = JSON.parse(data);
1491									}
1492									if( data['current-track'].art ){
1493										var art = data['current-track'].art;
1494										if( art != ''){
1495											
1496											// console.log(art);
1497											$.qtMplayerGlobalSongData.thumbnail =  art;
1498											callBack(art);
1499											callBack = false;
1500										}
1501									}
1502									fn.qtApplyTitle(data['current-track'].artist+' - '+data['current-track'].title, callBack);                                  
1503								},
1504								error: function(e){
1505									console.log(e);
1506								}
1507							});
1508						}
1509
1510						/**
1511						 * ===================================================================
1512						 *
1513						 *  Text
1514						 *
1515						 * ===================================================================
1516						 */
1517						else if(qttextfeed !== ''){
1518							var tfeedurl,jsondata, title, proxyURL, mydata;
1519							if(qtUseProxy){
1520								tfeedurl = $("#qtmplayer-radiofeed-proxyurl").data('proxyurl');
1521								mydata = { 
1522									"qtproxycall": window.btoa(qttextfeed),
1523								};
1524							} else {
1525								tfeedurl = qttextfeed;
1526							}
1527							$.ajax({
1528								type: 'GET',
1529								cache: false,
1530								url: tfeedurl,
1531								async: true,
1532								data: mydata,
1533								dataType: "html",
1534								success: function(data) {
1535									fn.qtApplyTitle( data, callBack );
1536								},
1537								error: function(e){
1538									console.log(e);
1539								}
1540							});
1541							return;
1542						} 
1543						/**
1544						 * ===================================================================
1545						 *
1546						 *  Radionomy
1547						 *
1548						 * ===================================================================
1549						 */
1550						else if(qtradionomy !== '' ) {
1551							$.ajax({
1552								type: 'GET',
1553								url: qtradionomy,
1554								async: true,
1555								cache: false,
1556								dataType: "xml",
1557								success: function(data) {
1558									fn.qtApplyTitle( $(data).find('artists').html()+ ' - ' + $(data).find('title').html() );
1559								},
1560								error: function(e){
1561									console.log(e);
1562								}
1563							});
1564						} 
1565
1566						/**
1567						 * ===================================================================
1568						 *
1569						 *  AirTime
1570						 *
1571						 * ===================================================================
1572						 */
1573						else if(qtairtime !== '' && qtairtime !== 'undefined' && qtairtime !== undefined && typeof(qtairtime) !== 'undefined'){
1574							var jsondata, title;
1575							$.ajax({
1576								type: 'GET',
1577								cache: false,
1578								url: qtairtime,//proxyURL,
1579								async: true,
1580								data: {
1581									"qtproxycall": window.btoa(qtairtime),
1582								},
1583								jsonpCallback: "parseMusic",
1584								jsonp: true,//jsonp: true,
1585								// contentType: "application/json",
1586								success: function(data) {
1587									// console.log(data);
1588									if(typeof(data) !== 'object'){
1589										data = JSON.parse(data);
1590									}
1591									title = data.tracks.current.name;
1592									fn.qtApplyTitle(title);
1593								},
1594								error: function(e) {
1595								}
1596							});
1597						}
1598
1599						/**
1600						 * ===================================================================
1601						 *
1602						 *  Icecast
1603						 *
1604						 * ===================================================================
1605						 */
1606						else if(qticecasturl !== '' && typeof(qticecasturl) !== 'undefined') {
1607							var feedurl = qticecasturl;
1608							var source;
1609							var title;
1610							var songdata;
1611							var listeners = false;
1612							var listener_peak = false;
1613							if(qtUseProxy){
1614								feedurl = proxyURL;
1615								songdata = {
1616									"qtproxycall":  window.btoa(qticecasturl),
1617								};
1618							}
1619							// beta
1620							fn.log('Radio feed - Icecast '+ qticecasturl);
1621							// generally ok, not working for LN Soulr Icecast
1622							// console.log( proxyURL+'?qtproxycall='+window.btoa(qticecasturl) );
1623							$.ajax({
1624								type: 'GET',
1625								cache: false,
1626								url: feedurl,
1627								async: true,
1628								jsonpCallback: "parseMusic",
1629								jsonp: false,//jsonp: true,
1630								// dataType: 'jsonp', // not working with some radios
1631								data: songdata,
1632								 // contentType: "application/json",
1633								success: function(json) {
1634									fn.log('Ajax response');
1635									fn.log( json );
1636
1637									// console.log(json);
1638									if('object' !== typeof( json )){
1639										json = JSON.parse(json);
1640									}
1641									if('undefined' === typeof(json.icestats)){ 
1642										// This is Icecast HK
1643									
1644										if(qticecastmountpoint){
1645											source = json[qticecastmountpoint];
1646										} else {
1647											
1648											$.each(json, function(index, element) {
1649												source = element;
1650												if(index == 0){ 
1651													source =    element;
1652												}
1653											});
1654											// console.log(source);
1655										}
1656									} else {
1657										source = json.icestats.source;
1658									}
1659									
1660									if('undefined' === typeof(source)){ 
1661										return; 
1662									}
1663									if(qticecastmountpoint){
1664										source = source[qticecastmountpoint];
1665									}
1666									if(qticecastchannel){
1667										// console.log("set source to 0");
1668										source = source[qticecastchannel];
1669									}
1670									// since PR.3.2.3
1671									// If there is no channel and there is no title, channel must be 0
1672									if(!qticecastchannel && 'undefined' === typeof(source.title)){
1673										source = source[0];
1674									}
1675									title = source.title;
1676									if( source.artist ){
1677										title = title + ' - ' + source.artist;
1678									}
1679									fn.qtApplyTitle(title, callBack);
1680									// Listeners ======================================
1681									if(source.listeners){
1682										listeners = source.listeners;
1683									}
1684									if(source.listener_peak){
1685										listener_peak = source.listener_peak;
1686									}
1687									fn.qtApplyListeners(listeners, listener_peak);
1688
1689								},error: function(e) {
1690									console.log(e);
1691									fn.log('Ajax response');
1692									fn.log( e );
1693								}
1694							});
1695						} 
1696						/**
1697						 * ===================================================================
1698						 *
1699						 *  ShoutCast
1700						 *
1701						 * ===================================================================
1702						 */
1703						else if (qtradiofeedHost !== '' && qtradiofeedPort !== '' && typeof(qtradiofeedHost) !== 'undefined'){
1704							// to tide up
1705							var feedData = {
1706								shoutcast_host: qtradiofeedHost,
1707								shoutcast_port: qtradiofeedPort,
1708								shoutcast_protocol: qtradiofeedProtocol,
1709								shoutcast_channel: theChannel
1710							};
1711							var channel = feedData.shoutcast_channel || 1;
1712							var protocol = 'http';
1713							if(feedData.shoutcast_port === '443' || feedData.shoutcast_protocol === 'https' ){
1714								protocol    = 'https';
1715							}
1716							var shoutcastUrl = protocol+'://'+feedData.shoutcast_host+':'+feedData.shoutcast_port+'/stats?sid='+channel+'&json=1';
1717							var feedurl     = shoutcastUrl;
1718							
1719							if(qtUseProxy){
1720								feedurl = proxyURL;
1721								songdata = {
1722									"qtproxycall":  window.btoa(shoutcastUrl),
1723								};
1724							}
1725
1726							/**
1727							 * @since PR.3.4.6 2021 02 27 added fallback
1728							 */
1729							try{
1730								
1731								$.ajax({
1732									type: 'GET',
1733									cache: false,
1734									url: feedurl,
1735									async: true,
1736									data: songdata,
1737									dataType:  $.qtmplayerRadioFeedObj.qtFeedData.dataType,
1738									contentType: "application/json",
1739									success: function(json) {
1740										if('object' !== typeof( json )){
1741											json = JSON.parse(json);
1742										}
1743										fn.qtApplyTitle( json.songtitle, callBack);
1744										// Listeners ======================================
1745										if(json.currentlisteners){
1746											listeners = json.currentlisteners;
1747										}
1748										if(json.peaklisteners){
1749											listener_peak = json.peaklisteners;
1750										}
1751										fn.qtApplyListeners(listeners, listener_peak);
1752									},error: function(e) {
1753										if($.qtmplayerRadioFeedObj.qtFeedData.dataType !== 'jsonp'){
1754											$.qtmplayerRadioFeedObj.qtFeedData.dataType = 'jsonp';
1755											$.qtmplayerRadioFeedObj.fn.newFeedReading(); 
1756										}
1757									}
1758								});
1759							} catch(e){
1760								dataType = 'jsonp';
1761								console.log(e);
1762							}
1763						
1764							return;
1765						} 
1766						/**
1767						 * ===================================================================
1768						 *
1769						 *  Radio.co
1770						 *
1771						 * ===================================================================
1772						 */
1773						else if (qtradiodotco !== '' && typeof(qtradiodotco) !== 'undefined'){
1774							var rUrl = 'https://public.radio.co/stations/'+qtradiodotco+'/status'
1775							$.ajax({
1776								type: 'GET',
1777								cache: false,
1778								url: rUrl,
1779								async: true,
1780								contentType: "application/json",
1781								success: function(data) {
1782									if( data['current_track'] ){
1783										title = data['current_track']['title'];
1784										fn.log( 'Radio.co artwork: '+ data['current_track']['artwork_url_large']  );
1785										if( data['current_track']['artwork_url_large'] && 'function' === typeof(callBack) ){
1786											var art = data['current_track']['artwork_url_large'];
1787											if( art !== ''){
1788												
1789												$.qtMplayerGlobalSongData.thumbnail =  art;
1790												callBack( art );
1791												callBack = false;
1792											}
1793										}
1794									} else {
1795										title = 'Song title currently unavailable - Please check your radio settings';
1796									}
1797									fn.qtApplyTitle(title, callBack);
1798								},
1799								error: function(e) {
1800								}
1801							});
1802						}
1803						/**
1804						 * ===================================================================
1805						 *
1806						 *  Radioking
1807						 *
1808						 * ===================================================================
1809						 */
1810						else if (fd.servertype == 'type-radioking' && qtradioking !== '' ){
1811							var rUrl = 'https://api.radioking.io/widget/radio/'+qtradioking+'/track/current';
1812							$.ajax({
1813								type: 'GET',
1814								cache: false,
1815								url: rUrl,
1816								async: true,
1817								contentType: "application/json",
1818								success: function(data) {
1819									title = data.artist+' - '+data.title;
1820									if(data.cover && 'function' === typeof(callBack)){
1821										
1822										$.qtMplayerGlobalSongData.thumbnail =  data.cover;
1823										callBack(data.cover);
1824										callBack = false;
1825									}
1826									fn.qtApplyTitle(title, callBack);
1827								},
1828								error: function(e) {
1829									console.log(e);
1830								}
1831							});
1832						}
1833						/**
1834						 * ===================================================================
1835						 *
1836						 *  Azuracast
1837						 *
1838						 * ===================================================================
1839						 */
1840						else if (fd.servertype == 'type-azuracast' && qtazuracast !== '' ){
1841							var rUrl = '';
1842							var feedurl = qtazuracast + '?rand='+timestamp;
1843							
1844							if(qtUseProxy){
1845								feedurl =  proxyURL+'?qtproxycall='+window.btoa(qtazuracast);
1846							}
1847							$.ajax({
1848								type: 'GET',
1849								cache: false,
1850								url: feedurl,
1851								async: true,
1852								contentType: "application/json",
1853								success: function(data) {
1854									if("string" == typeof(data)){
1855										data = jQuery.parseJSON( data );
1856									}
1857									if( 'undefined' === typeof( data.now_playing ) ){
1858										data = data[0];
1859									}
1860									author = data.now_playing.song.artist;
1861									title = data.now_playing.song.title;
1862									if('' !== author){
1863										title = author+' - '+title;
1864									}
1865									if(data.now_playing.song.cover && 'function' === typeof(callBack)){
1866										$.qtMplayerGlobalSongData.thumbnail =  data.now_playing.song.cover;
1867										callBack(data.now_playing.song.cover);
1868										
1869										callBack = false;
1870									}
1871									if(data.now_playing.song.art && 'function' === typeof(callBack)){
1872										// console.log(data.now_playing.song.art);
1873										$.qtMplayerGlobalSongData.thumbnail =  data.now_playing.song.art;
1874										callBack(data.now_playing.song.art);
1875										
1876										callBack = false;
1877									}
1878
1879									if(data.cover && 'function' === typeof(callBack)){
1880										$.qtMplayerGlobalSongData.thumbnail =  data.cover;
1881										callBack(data.cover);
1882										
1883										callBack = false;
1884									}
1885									if(data.art && 'function' === typeof(callBack)){
1886										$.qtMplayerGlobalSongData.thumbnail =  data.art;
1887										callBack(data.art);
1888										
1889										callBack = false;
1890									}
1891
1892									// Listeners ======================================
1893									if(data.listeners){
1894										if(data.listeners.current){
1895											listeners = data.listeners.current;
1896										}
1897										if(data.listeners.total){
1898											listener_peak = data.listeners.total;
1899										}
1900										
1901										fn.qtApplyListeners(listeners, listener_peak);
1902									}
1903
1904
1905									fn.qtApplyTitle(title, callBack);
1906								},
1907								error: function(e) {
1908									console.log(e);
1909
1910								}
1911							});
1912						}
1913					}
1914				return;
1915			},
1916			feedInterval: null,
1917			stopFeed: function(){
1918				var o = $.qtmplayerRadioFeedObj;
1919				if("undefined" !== typeof($.qtmplayerRadioFeedObj.fn.qtFeedInterval) ){
1920					clearInterval($.qtmplayerRadioFeedObj.fn.qtFeedInterval);
1921				}
1922
1923			},
1924			pushFeed: function( data ){
1925				
1926				var o = $.qtmplayerRadioFeedObj;
1927				o.qtFeedData = data;
1928				o.fn.log('pushFeed = INITIALIZE'+$.now());
1929				o.fn.log(data);
1930				o.fn.stopFeed();
1931				o.fn.newFeedReading();
1932				o.fn.qtApplyListeners(false,false);
1933				$.qtmplayerRadioFeedObj.qtFeedData.dataType = '';
1934				$.qtmplayerRadioFeedObj.fn.qtFeedInterval = setInterval(
1935					function(){ 
1936						o.fn.newFeedReading(); 
1937					}, 
1938					$.qtmplayerRadioFeedObj.timeInterval
1939				);
1940			},
1941			log:function(msg){
1942				var c = $("#qtmPlayerDebugger");
1943				if(c.length > 0){
1944					c.append(msg+'<br>');
1945				}
1946			}
1947		}
1948
1949	};
1950	$(document).ready(function(){
1951		$.qtmplayerRadioFeedObj.fn.qtApplyTitle();
1952	});
1953})(jQuery);
1954
1955
1956
1957
1958

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.