Login | Register (Invite Only)
Title: Page Telegram of Amfile.org
Description: Brown Hats Collective F' Around and Find Out user of the Interwebs and Project Developer for a Cause Toward Insuring a Future of Liberty without Illusion.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@=:---#@@@#%@@@*=+#@%====@@@@..:--@#====@-==#@@@+===#@%=-+@... -@@@@*@@@=+@%-*@ @@@.*@-.@@@.:@@==@:=@+ -..*@@@:# @:@=.=. #%.#@@@@ ::..@.%#.@@ %+ %@@% #@@-.@+ #@ @@@.*@+.@@@:.@@.#@%*@*.@.-*@@%@#.@.@=.%..#% *@@@@ %:+:+:@@=@@ #+ %@@+..@@= %: @@ @@@..-.=@@:* %@.%#=+@+..:@@@@@@*.@@@=..:@@@ %@%%% :.@@+-@:=#@ ...@@@:+ @@+ :- @@ @@@.+@@@@@.- =@.#@.-@*.@:=@@@@@+ @@@+:@-:@% @@*=@ @=%#+-@-.#@ @*.%@@.- #@=. + @@ @@@.+@@@@+.@..@:*%.*@*.@%.@@@@%- +@@=:@%.@@.%@:=@ @@=*#:@::@@ *# =@--% -@:- * @@ @@-::#@@%::+::*@-:=%@::.::@@@@+-::@*:.:::@::...%:::::#@*:==@#==@+:*.:=::%:-=::=@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#-. .-#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*. .+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: .++: .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@= :@@@@@@- -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@# =@@@@@@@@+ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@: =@@@@@@@@@@+ .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@# .@@@@@@@@@@@@. *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@. %@@@@@@@@@@@@%. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@% -@@@@@@@@@@@@@@- #@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@= #@@@@@@@@@@@@@@% -@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@%##***#%@@@@+ %@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@* %@#:.. .:+@% *@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@= =. : -@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@. .=%@@@@@@@+: .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@# .%@@@@@@@@@@@@@- -@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@# .*@@@@@@@@@@@@@@@@%: -@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@%. .@@@@@@*%@@@@%#@@@@@@= *@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@. :@@@@@@@@:-@@*.%@@@@@@@+ %@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@+ :@@@@@@@@@@---.@@@@@@@@@@= :@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@. @@@@@@@@@@@. @@@@@@@@@@@: #@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@= #@@@+--#@@@@ #@@@@%#@@@@@. .@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@. :@%- .%@@- .@@@*. .+@@= #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@# *+. .@@@#*@@@= .#@ -@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@- .# =@@-.@@%. += .@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. -@. @@. %@: #% %@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. #@- +% =% .@@. *@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@% %@% :+ .+ +@@. =@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@# @@@: .: .- .@@@: -@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@* .@@@% # .# =@@@: :@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@* .@@@@= -@ @- .@@@@: :@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@# @@@@@. .@@ @@. %@@@@: -@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@% %@@@@@: :@@@ @@@. .*@@@@@. =@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. #@@@@@@#+#@@@@ @@@@=.:%@@@@@@. *@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. :@@@@@@-..:*@@ @@#-..:%@@@@@# %@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@- .@@@@@: .@ @. .@@@@@- .@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@# *@@@% @. .@ *@@@@ -@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@. .@@@+ @- .@. -@@@= #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@+ +@@%. .@* :@- .*@@%. .@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@. %@@@- *@% #@%. :%@@@. %@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@* .@@@@%=-+@@@. @@@*--#@@@@- -@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@*=@@@@@@@@@@: @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@. .%@@@@@@@@@@@@@@@@@@@- .#@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%. +@@@@@@@@@@@@@@@@#. +@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@%. .+@@@@@@@@@@@@%: +@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%. -*%@@@@@#=. .*@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@: .%@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@#. +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+. .=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@=. .-%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%###%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>PLS/M3U On Anything Player</title> <script src="https://cdn.jsdelivr.net/npm/jsmediatags@latest/dist/jsmediatags.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> <style> body { font-family: 'Courier New', Consolas, monospace; color: #FFC107; background-color: #000000; max-width: 600px; margin: 20px auto; } h1, p, span, div { font-family: 'Courier New', Consolas, monospace; color: #FFC107; } input, button { font-family: 'Courier New', Consolas, monospace; color: #FFC107; background-color: #000000; border: 1px solid #FFC107; padding: 5px; margin: 5px; } input { width: 100%; box-sizing: border-box; } button:hover { background-color: #FFC107; color: #000000; } #controls { margin-top: 10px; } #metadata { margin-top: 10px; padding: 10px; border: 1px solid #FFC107; } #player, #video-player { max-width: 100%; } .popup { display: none; position: fixed; top: 20%; left: 20%; width: 60%; max-height: 60%; overflow-y: auto; background: #000000; border: 1px solid #FFC107; padding: 10px; color: #FFC107; } .popup ul { list-style: none; padding: 0; } .popup li { cursor: pointer; padding: 5px; } .popup li:hover { background: #FFC107; color: #000000; } .popup button { position: sticky; top: 0; float: right; } </style> </head> <body> <h1>PLS/M3U Playlist Player</h1> <p>Enter a PLS, M3U, or M3U8 playlist URL (HTTP or HTTPS) or provide it in the URL (e.g., ?pls=https://example.com/playlist.m3u8). Supports audio, video, and live streams. Single-track playlists play automatically.</p> <input id="pls-url" type="text" placeholder="Enter PLS/M3U URL"> <button onclick="loadPlaylist()">Load Playlist</button> <button onclick="togglePlaylistWindow()">Show Playlist</button> <button onclick="toggleRecentPlaylists()">Show Recent Playlists</button> <div id="player-container"> <audio id="player" controls style="display: none;"></audio> <video id="video-player" controls style="display: none;"></video> </div> <div id="controls"> <button id="prev">Previous</button> <button id="playpause">Play</button> <button id="next">Next</button> <button onclick="changeSpeed(0.25)">Speed +</button> <button onclick="changeSpeed(-0.25)">Speed -</button> <span>Speed: <span id="speed">1.00</span>x</span> </div> <div id="metadata">Metadata will appear here.</div> <div id="playlist-window" class="popup"> <button onclick="togglePlaylistWindow()">Close</button> <ul id="playlist-list"></ul> </div> <div id="recent-playlists" class="popup"> <button onclick="toggleRecentPlaylists()">Close</button> <ul id="recent-playlists-list"></ul> </div> <script> let tracks = []; let currentIndex = 0; const audioPlayer = document.getElementById('player'); const videoPlayer = document.getElementById('video-player'); const playPauseBtn = document.getElementById('playpause'); const speedSpan = document.getElementById('speed'); const metadataDiv = document.getElementById('metadata'); const playlistList = document.getElementById('playlist-list'); const recentPlaylistsList = document.getElementById('recent-playlists-list'); const plsInput = document.getElementById('pls-url'); let currentPlayer = audioPlayer; // Check for ?pls= query parameter on page load window.onload = () => { const params = new URLSearchParams(window.location.search); const plsUrl = params.get('pls'); if (plsUrl) { if (plsUrl.startsWith('http://') || plsUrl.startsWith('https://')) { plsInput.value = plsUrl; loadPlaylist(); } else { alert('Invalid playlist URL in query parameter. Please use http:// or https://'); } } fetchRecentPlaylists(); }; async function loadPlaylist() { const url = plsInput.value; if (!url) { alert('Please enter a playlist URL or provide it in the URL (?pls=...).'); return; } if (!url.startsWith('http://') && !url.startsWith('https://')) { alert('URL must start with http:// or https://'); return; } try { // Save the playlist URL to the server await fetch('save_playlist.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url }) }); // Fetch and parse the playlist const response = await fetch(url, { mode: 'cors' }); if (!response.ok) throw new Error(`Failed to fetch playlist: ${response.statusText}`); const text = await response.text(); const extension = url.split('.').pop().toLowerCase(); tracks = extension === 'pls' ? parsePLS(text) : parseM3U(text); if (tracks.length === 0) { alert('No tracks found in playlist.'); return; } // Update browser URL with ?pls= history.pushState({}, '', `?pls=${encodeURIComponent(url)}`); updatePlaylistWindow(); // Auto-play if only one track if (tracks.length === 1) { playTrack(0); } else { document.getElementById('playlist-window').style.display = 'block'; playTrack(0); } fetchRecentPlaylists(); } catch (error) { console.error('Playlist load error:', error); alert(`Error loading playlist: ${error.message}. Check if the server allows CORS or is online.`); } } function parsePLS(text) { const lines = text.split('\n'); let numEntries = 0; const trackMap = {}; lines.forEach(line => { line = line.trim(); if (!line || line.startsWith('[')) return; const [key, value] = line.split('=').map(part => part.trim()); if (!key || !value) return; if (key === 'NumberOfEntries') { numEntries = parseInt(value, 10); return; } const match = key.match(/^(File|Title|Length)(\d+)$/); if (match) { const [, type, numStr] = match; const num = parseInt(numStr, 10); if (!trackMap[num]) trackMap[num] = {}; if (type === 'File') trackMap[num].url = value; else if (type === 'Title') trackMap[num].title = value; else if (type === 'Length') trackMap[num].length = parseInt(value, 10); } }); const trackList = []; for (let i = 1; i <= numEntries; i++) { if (trackMap[i] && trackMap[i].url) { trackList.push({ url: trackMap[i].url, title: trackMap[i].title || `Track ${i}`, length: trackMap[i].length || -1 }); } } return trackList; } function parseM3U(text) { const lines = text.split('\n'); const trackList = []; let currentTrack = {}; lines.forEach(line => { line = line.trim(); if (!line || line.startsWith('#EXTM3U')) return; if (line.startsWith('#EXTINF:')) { const [, duration, title] = line.match(/#EXTINF:(-?\d+),(.*)/) || [, -1, 'Unknown']; currentTrack = { title: title.trim(), length: parseInt(duration, 10) }; } else if (line.startsWith('http://') || line.startsWith('https://')) { currentTrack.url = line; trackList.push({ ...currentTrack, title: currentTrack.title || 'Unknown', length: currentTrack.length || -1 }); currentTrack = {}; } }); return trackList; } function updatePlaylistWindow() { playlistList.innerHTML = ''; tracks.forEach((track, index) => { const li = document.createElement('li'); li.textContent = track.title; li.onclick = () => playTrack(index); playlistList.appendChild(li); }); } function togglePlaylistWindow() { const win = document.getElementById('playlist-window'); win.style.display = win.style.display === 'none' ? 'block' : 'none'; document.getElementById('recent-playlists').style.display = 'none'; } async function fetchRecentPlaylists() { try { const response = await fetch('save_playlist.php'); const data = await response.json(); recentPlaylistsList.innerHTML = ''; data.forEach(item => { const li = document.createElement('li'); li.textContent = `${item.url} (${new Date(item.timestamp).toLocaleString()})`; li.onclick = () => { plsInput.value = item.url; loadPlaylist(); toggleRecentPlaylists(); }; recentPlaylistsList.appendChild(li); }); } catch (error) { console.error('Error fetching recent playlists:', error); } } function toggleRecentPlaylists() { const win = document.getElementById('recent-playlists'); win.style.display = win.style.display === 'none' ? 'block' : 'none'; document.getElementById('playlist-window').style.display = 'none'; } function playTrack(index) { if (index < 0 || index >= tracks.length) return; currentIndex = index; const track = tracks[index]; const isVideo = track.url.match(/\.(mp4|m3u8)$/i); const isHLS = track.url.endsWith('.m3u8'); audioPlayer.style.display = isVideo ? 'none' : 'block'; videoPlayer.style.display = isVideo ? 'block' : 'none'; currentPlayer = isVideo ? videoPlayer : audioPlayer; if (isHLS && typeof Hls !== 'undefined' && Hls.isSupported()) { const hls = new Hls(); hls.loadSource(track.url); hls.attachMedia(videoPlayer); hls.on(Hls.Events.MANIFEST_PARSED, () => { videoPlayer.play().catch(error => { console.error('HLS playback error:', error); alert('Playback error: ' + error.message + '. Ensure the stream is active and CORS is enabled.'); }); }); hls.on(Hls.Events.ERROR, (event, data) => { console.error('HLS error:', data); alert('HLS stream error: ' + data.type + ' - ' + data.details); }); } else { currentPlayer.src = track.url; currentPlayer.play().catch(error => { console.error('Playback error:', error); alert('Playback error: ' + error.message + '. Check if the stream is accessible.'); }); } playPauseBtn.textContent = 'Pause'; updateMetadata(); if (!isVideo) { try { jsmediatags.read(track.url, { onSuccess: (tag) => { const tags = tag.tags; metadataDiv.innerHTML = ` Title: ${tags.title || track.title}<br> Artist: ${tags.artist || 'Unknown'}<br> Album: ${tags.album || 'Unknown'}<br> Length: ${track.length > 0 ? track.length + ' seconds' : 'Unknown'} `; }, onError: () => updateMetadata() }); } catch (e) { updateMetadata(); } } else { updateMetadata(); } } function updateMetadata() { const track = tracks[currentIndex]; metadataDiv.innerHTML = ` Title: ${track.title}<br> Length: ${track.length > 0 ? track.length + ' seconds' : 'Unknown'} `; } playPauseBtn.addEventListener('click', () => { if (currentPlayer.paused) { currentPlayer.play(); playPauseBtn.textContent = 'Pause'; } else { currentPlayer.pause(); playPauseBtn.textContent = 'Play'; } }); document.getElementById('next').addEventListener('click', () => { playTrack(currentIndex + 1); }); document.getElementById('prev').addEventListener('click', () => { playTrack(currentIndex - 1); }); audioPlayer.addEventListener('ended', () => { playTrack(currentIndex + 1); }); videoPlayer.addEventListener('ended', () => { playTrack(currentIndex + 1); }); function changeSpeed(delta) { currentPlayer.playbackRate = Math.max(0.25, currentPlayer.playbackRate + delta); speedSpan.textContent = currentPlayer.playbackRate.toFixed(2); } </script> </body> </html>
Language: html