1const restreamUrl = 'https://player-backend.restream.io/public/videos/5475e85e0dfc4fbfb72f621f705eeeda'; 2const afastreamInfoUrl = 'https://stream.afa.net/checklive?alttemplate=checklivestream'; 3const showInfoUrl = '/api/v2/podcast/podcastsbyid/?id=' 4const showInfoUrlV4 = '/api/v4/shows/' 5 6const liveVideoModal = document.getElementById('live-video-modal'); 7 8const triviaFriday = 51503; 9 10 11const audiop = document.querySelector('#audioPlayer'); 12 13//const isPlayingAudio = !audiop.paused && !audiop.ended && audiop.currentTime > 0; 14let wasPlayingAudio = false; 15 16const checkRadioPlaying = () => { 17 console.log('checking radio playing') 18 if(isPlaying){ 19 audiop.pause(); 20 wasPlayingAudio = true 21 }else{ 22 wasPlayingAudio = false; 23 } 24} 25 26startRadioBack = () => { 27 if(wasPlayingAudio){ 28 audiop.play(); 29 } 30} 31 32const restreamHTML = ` 33 <iframe 34 src="https://player.restream.io/?token=5475e85e0dfc4fbfb72f621f705eeeda&vwrs=1" 35 class="stream-embed" 36 allowfullscreen 37 allow="autoplay; 38 loading="lazy" 39 title="AFR Stream Live" 40 ></iframe> 41`; 42 43 44const parseTimeVideo = (x) => { 45 let thisTime = x + parseInt(x.split(':')[0]) >= 12 ? 'PM' : 'AM' 46 return thisTime; 47} 48 49 50const checkTriviaFriday = (id, schedule) => { 51 //console.log(id, schedule) 52} 53 54 55const convertMilTime = (militaryTime) => { 56 // Split the input into hours and minutes 57 let [hours, minutes] = militaryTime.split(':').map(Number); 58 // Determine AM or PM suffix 59 const suffix = hours >= 12 ? 'PM' : 'AM'; 60 // Convert hours to 12-hour format (0 becomes 12) 61 hours = hours % 12 || 12; 62 // Ensure minutes are padded with a leading zero if single digit 63 const formattedMinutes = minutes.toString().padStart(2, '0'); 64 return `${hours}:${formattedMinutes} ${suffix}`; 65} 66 67const getStreamInfo = async (id) => { 68 const res = await fetch(showInfoUrlV4 + id) 69 const data = await res.json() 70 checkTriviaFriday(data.id, data.schedule) 71 document.querySelector('.stream-info-thumb').innerHTML = `<img src="${data.images.image1x1}?width=200" />` 72 if(data.schedule.length === 1){//Dr Nurse Mama and etc. 73 document.querySelector('.stream-info-times-content').textContent = `${data.schedule[0].airDaysFormated} ${data.schedule[0].startTime} - ${data.schedule[0].endTime}` 74 }else{ 75 document.querySelector('.stream-info-times-content').textContent = `${data.schedule[1].airDaysFormated} ${data.schedule[1].startTime} - ${data.schedule[1].endTime}` 76 } 77 document.querySelector('.stream-info-title').textContent = data.name 78 document.querySelector('.afa-stream-link').href = data.videoStreamingPage 79 document.querySelector('.afr-radio-link').href = `${data.url}` 80 document.querySelector('.stream-desc').innerHTML = data.description 81 document.querySelector('.stream-info-hosts').textContent = `Hosted By: ${data.hosts}` 82} 83 84 85 86document.addEventListener("DOMContentLoaded", () => { 87 // ===== Expandable Description (3 lines clamp) ===== 88 const toggleBtn = document.getElementById("streamDescToggle"); 89 const desc = document.getElementById("streamDesc"); 90 const toggleText = document.getElementById("streamDescToggleText"); 91 const arrow = document.getElementById("streamDescArrow"); 92 93 if (toggleBtn && desc) { 94 toggleBtn.addEventListener("click", function () { 95 const isExpanded = desc.classList.toggle("expanded"); 96 arrow.classList.toggle("rotated"); 97 toggleText.textContent = isExpanded ? "Read Less" : "Read More"; 98 }); 99 100 // Check overflow when modal opens (element has no dimensions while hidden) 101 const modal = document.getElementById("streamModal"); 102 if (modal) { 103 modal.addEventListener("shown.bs.modal", function () { 104 requestAnimationFrame(function () { 105 // Temporarily unclamp to get full content height 106 desc.style.setProperty("display", "block"); 107 desc.style.setProperty("-webkit-line-clamp", "unset"); 108 var fullHeight = desc.scrollHeight; 109 desc.style.removeProperty("display"); 110 desc.style.removeProperty("-webkit-line-clamp"); 111 112 var clampedHeight = desc.clientHeight; 113 if (fullHeight <= clampedHeight) { 114 toggleBtn.style.display = "none"; 115 } else { 116 toggleBtn.style.display = ""; 117 } 118 }); 119 }); 120 } 121 } 122}) 123 124//on modal open 125liveVideoModal.addEventListener('show.bs.modal', (e) => { 126 checkRadioPlaying(); 127 if(document.querySelector('.stream-embed-wrap').children.length == 0){ 128 document.querySelector('.stream-embed-wrap').innerHTML = restreamHTML; 129 } 130}); 131//on modal close 132liveVideoModal.addEventListener('hide.bs.modal', (e) => { 133 startRadioBack(); 134 document.querySelector('.stream-embed-wrap').replaceChildren(); 135}); 136 137const checkRestream = async () => { 138 fetch('https://player-backend.restream.io/public/videos/5475e85e0dfc4fbfb72f621f705eeeda').then(res => res.json()).then(data => {
139 if(data.error !== 'no_live_video_found'){ 140 (async () => { 141 document.querySelector('.video-toggle').classList.add('show') 142 document.querySelector('.btn-watch').classList.add('show') 143 const r = await fetch(afastreamInfoUrl); 144 const d = await r.json() 145 getStreamInfo(d.afrId) 146 document.querySelector('.stream-embed-wrap').innerHTML = restreamHTML 147 })(); 148 } 149 }) 150} 151 152 153checkRestream() 154//getStreamInfo() 155//const period = parseInt(timeString.split(':')[0]) >= 12 ? 'PM' : 'AM'; 156
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.