Commit 90ebc30a authored by elleo's avatar elleo

Add "Listen" page, allowing users to stream tag radio stations directly from...

Add "Listen" page, allowing users to stream tag radio stations directly from the website via the JavaScript player
Give the JavaScript player support for stations
Add radio authentication to the User class for use by the JavaScript player
parent baf051d2
......@@ -187,6 +187,24 @@ class User {
return $session_id;
}
/**
* Log in to the radio server
*
* @param string $station The station to be played
* @return A string containing the session key to be used for streaming
*/
function getRadioSession($station) {
global $mdb2;
$session_id = md5(mt_rand() . time());
$sql = "INSERT INTO Radio_Sessions(username, session, url, expires) VALUES ("
. $mdb2->quote($this->name, "text") . ","
. $mdb2->quote($session_id, "text") . ","
. $mdb2->quote($station, "text") . ","
. $mdb2->quote(time() + 86400) . ")";
$mdb2->query($sql);
return $session_id;
}
/**
* get user's top 20 tracks
*
......
/*
Libre.fm -- a free network service for sharing your music listening habits
Libre.fm -- a free network service for sharing your music listening hab""s
Copyright (C) 2009 Libre.fm Project
......@@ -24,34 +24,55 @@
*/
var scrobbled, now_playing;
var artist, album, track, session_key;
var playlist, current_song = 0;
var artist, album, track, session_key, radio_key;
var playlist = [], current_song = 0;
var player_ready = false;
var playable_songs = false;
var streaming = false;
function playerInit(list, sk) {
//Explicitly call stop() here, since not everything seems to support 'autoplay="false"' yet
function playerInit(list, sk, rk) {
var audio = document.getElementById("audio");
if (!list) {
// We're playing a stream instead of a playlist
streaming = true;
}
session_key = sk;
radio_key = rk;
if(typeof audio.duration == "undefined") {
//Browser doesn't support <audio>
if(streaming) {
audio.replaceWith("<p>Sorry, you need a browser capable of using the HTML 5 &lt;audio&gt; element to enjoy the streaming service via the Javascript player.</p>");
}
return;
}
$("#fallbackembed").replaceWith(""); // Get rid of the fallback embed, otherwise html5 browsers will play it in addition to the js player
playlist = list;
$("#fallbackembed").replaceWith(""); // Get rid of the fallback embed, otherwise some html5 browsers will play it in addition to the js player
if (streaming) {
// Get playlist from radio service
getRadioPlaylist();
} else {
// Otherwise we have a static playlist
playlist = list;
playerReady();
}
}
function playerReady() {
var audio = document.getElementById("audio");
populatePlaylist();
if(!playable_songs) {
alert("No playable songs");
return;
}
session_key = sk;
loadSong(0);
audio.pause();
audio.addEventListener("ended", songEnded, false);
updateProgress();
$("#play").fadeTo("normal", 1);
$("#progressbar").progressbar({ value: 0 });
scrobbled = false;
now_playing = false;
$("#player > #interface").show();
player_ready = true;
}
function play() {
......@@ -111,6 +132,8 @@ function songEnded() {
function populatePlaylist() {
var i, url;
//Clear the list
$("#playlist > #songs").text("");
for(i = 0; i < playlist.length; i++) {
url = playlist[i]["url"];
// Remove non-streamable tracks
......@@ -178,10 +201,39 @@ function loadSong(song) {
audio.src = url;
audio.load();
if(streaming && current_song > playlist.length - 3) {
//Update the playlist before the user reaches the end
getRadioPlaylist();
}
$("#trackinfo > #artistname").text(artist);
$("#trackinfo > #trackname").text(track);
}
function getRadioPlaylist() {
var tracks, artist, album, title, url, i;
$.get("/radio/xspf.php", {'sk' : radio_key, 'desktop' : 0}, function(data) {
parser=new DOMParser();
xmlDoc=parser.parseFromString(data,"text/xml");
tracks = xmlDoc.getElementsByTagName("track")
for(i = 0; i < tracks.length; i++) {
try {
artist = tracks[i].getElementsByTagName("creator")[0].childNodes[0].nodeValue;
title = tracks[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
album = tracks[i].getElementsByTagName("album")[0].childNodes[0].nodeValue;
url = tracks[i].getElementsByTagName("location")[0].childNodes[0].nodeValue;
playlist.push({"artist" : artist, "album" : album, "track" : title, "url" : url});
} catch(err) {
}
}
if(!player_ready) {
playerReady();
} else {
populatePlaylist();
}
}, "text");
}
function friendlyTime(timestamp) {
mins = Math.floor(timestamp / 60);
sec = String(Math.floor(timestamp % 60));
......
<?php
/* Libre.fm -- a free network service for sharing your music listening habits
Copyright (C) 2009 Libre.fm Project
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
require_once('database.php');
require_once('templating.php');
require_once('data/TagCloud.php');
$aTagCloud = TagCloud::GenerateTagCloud('Scrobbles', 'artist');
if (!PEAR::isError ($aTagCloud)) {
$smarty->assign('tagcloud', $aTagCloud);
}
if(isset($_GET['tag'])) {
$station = "librefm://globaltags/" . $_GET['tag'];
$smarty->assign("station", $station);
}
$smarty->display("listen.tpl");
?>
......@@ -12,9 +12,9 @@
];
{if isset($u_user)}
playerInit(playlist, "{$u_user->getScrobbleSession()}");
playerInit(playlist, "{$u_user->getScrobbleSession()}", false);
{else}
playerInit(playlist, false);
playerInit(playlist, false, false);
{/if}
</script>
......
{include file='header.tpl'}
<h2>Listen</h2><br />
{if isset($station)}
{if isset($u_user)}
{include file='player.tpl'}
<div id='error'></div>
<script type="text/javascript">
{if isset($u_user)}
playerInit(false, "{$u_user->getScrobbleSession()}", "{$u_user->getRadioSession($station)}");
{/if}
</script>
{else}
<p>Sorry, you need to <a href='{$base_url}/login.php'>login</a> to be able to listen to radio streams.</p>
{/if}
{else}
<p>To listen to 100% free (libre) music simply enter the type of music you'd like to hear or select one of the common tags below:</p>
<p><a href="?tag=folk">Folk</a> <a href="?tag=rock">Rock</a> <a href="?tag=metal">Metal</a> <a href="?tag=classical">Classical</a> <a href="?tag=pop">Pop</a> <a href="?tag=blues">Blues</a> <a href="?tag=jazz">Jazz</a> <a href="?tag=punk">Punk</a> <a href="?tag=ambient">Ambient</a></p>
<p><form method='get' action=''><label for="tag">Custom tag:</label> <input type="text" id="tag" name="tag" /> <input type="submit" value="Listen" /></form></p>
{/if}
<br />
<div class="cleaner">&nbsp;</div>
{include file='footer.tpl'}
......@@ -10,6 +10,7 @@
<li><a href="/admin.php">admin</a></li>
{/if}
<li><a href="{$base_url}/login.php?action=logout">Logout</a></li>
<li><a href="{$base_url}/listen.php">Listen</a></li>
{else}
<li><a href="{$base_url}/login.php?return={$this_page|urlencode|htmlentities}">Login</a></li>
{/if}
......
......@@ -2,6 +2,8 @@
<audio id="audio">
{if $track->streamurl}
<object id="fallbackembed" style="width:200px;height:50px;" type="application/ogg" data="{$track->streamurl}"><a type="application/ogg" rel="enclosure" href="{$track->streamurl}">Listen to this track</a></object>
{elseif isset($station)}
<p>Sorry, you need a browser capable of making use of the HTML 5 &lt;audio&gt; tag to enjoy the streaming service via the JavaScript player.</p>
{/if}
</audio>
<div id="interface">
......
......@@ -6,9 +6,9 @@
<script type="text/javascript">
var playlist = [{ldelim}"artist" : "{$track->artist_name}", "album" : "{$track->album_name}", "track" : "{$track->name}", "url" : "{$track->streamurl}"{rdelim}];
{if isset($u_user)}
playerInit(playlist, "{$u_user->getScrobbleSession()}");
playerInit(playlist, "{$u_user->getScrobbleSession()}", false);
{else}
playerInit(playlist, false);
playerInit(playlist, false, false);
{/if}
</script>
<br />
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment