I am using JPlayer to stream an Icecast station and would like to show the current song name whenever a track changes. I have PHP that uses a function (https://gist.github.com/fracasula/5781710) to detect the current playing track.
I would like to update the track title and band image every time a track changes. I can't find a way to trigger an event every time a song changes, but know that the song meta-data is sent in the stream every 16,000 bytes (Title of current icecast streamed song).
Is there a way to check for the metadata block containing the song information using Javascript, thereby allowing me to change the song title (and corresponding google image) whenever a new track plays?
My current code is below (I'm just pinging the script to get the current track every minute at the moment):
$(document).ready(function(){
var stream = {
title: "My Stream",
mp3: "http://mystream.com:8000/myStream"
},
ready = false;
$("#jquery_jplayer_1").jPlayer({
ready: function (event) {
ready = true;
$(this).jPlayer("setMedia", stream).jPlayer("play");
},
pause: function() {
$(this).jPlayer("clearMedia");
},
error: function(event) {
if(ready && event.jPlayer.error.type === $.jPlayer.error.URL_NOT_SET) {
$(this).jPlayer("setMedia", stream).jPlayer("play");
}
},
stop: function(event) {
console.log("stop");
$(this).jPlayer("setMedia", stream).jPlayer("play");
},
swfPath: "js",
supplied: "mp3",
preload: "none",
autoPlay: true,
wmode: "window",
keyEnabled: true
});
requestTrack();
setInterval(requestTrack, 60000);
// get the current track info
function requestTrack() {
$.get( "tools/getTrack.php", function( data ) {
console.log(data);
$( "#current-track" ).html( data );
// search for an image with the band/song name
$.get( "https://www.googleapis.com/customsearch/v1?key=MY_KEY&cx=MY_CX&q="+encodeURIComponent(data)+"&searchType=image", function( data ) {
console.log(data.items[0].link);
$("#album").attr("src",data.items[0].link);
});
});
}
});
The metadata block isn't detectable in JavaScript. In fact, it isn't requested by the browser at all. You have to do this server-side. You could implement polling, or modify a script on the server to push data to clients as the metadata changes. (This would require a constant connection to the Icecast/SHOUTcast server from your HTTP server.)
Related
im new here so forgive me if my question seems to be stupid
i have the following code to search youtube video with submit button (normal form)
i want to turned to real time input once the user write any word will fetch result depend on what wrot by hime
so i add
$(".search_input").keyup(function(e) {
instead of
$("form").on("submit", function(e) {
full code is here https://jsfiddle.net/5ymndbax/
function tplawesome(e,t){res=e;for(var n=0;n<t.length;n++){res=res.replace(/\{\{(.*?)\}\}/g,function(e,r){return t[n][r]})}return res}
$(function() {
$(".search_input").keyup(function(e) {
e.preventDefault();
// prepare the request
var request = gapi.client.youtube.search.list({
part: "snippet",
type: "video",
q: $("#search").val(),
order: "viewCount",
publishedAfter: "2000-01-01T00:00:00Z"
});
// execute the request
request.execute(function(response) {
var results = response.result;
$("#results").html("");
$.each(results.items, function(index, item) {
$.get("tpl/item.html", function(data) {
$("#results").append(tplawesome(data, [{"title":item.snippet.title, "videoid":item.id.videoId}]));
});
});
resetVideoHeight();
});
});
$(window).on("resize", resetVideoHeight);
});
function resetVideoHeight() {
$(".video").css("height", $("#results").width() * 9/16);
}
function init() {
gapi.client.setApiKey("key");
gapi.client.load("youtube", "v3", function() {
// yt api is ready
});
}
i hope can i got some help from you ❤
full of love to each of you.
Currently you are using keyup, and that will check entry by letter.
So you need to check did key up ended with " ",",","." etc. for that will mostly mean the end of the word.
Now when we have the word, we want to add that to
previously entered words so you need to
concatenate or append new_word to previous_words.
And only then you should call AJAX call to URL or script that is using YouTube API for search...
It should go something like this:
**
event.preventDefault();
$.ajax({
type:"GET",
url: "youtube url or some script preforming to yt api call",
data:{"search": previous_words,},
success:function(data){
//display data somewhere
console.log(data);
}
});
My purpose is detected if one of the two videos are playing and console.log it.
I try to build dynamic videos play detect.
I read video ID when the user clicks on the play button, and then use the video ID to assign it video for addEventListner but it just works with my first video. the second video doesn't work and
$(function(){
var videoid = "";
$('video').bind('play', function (e) {
videoid = $(this).attr('id');
});
$('video').on("click", function() {
// test if global variable work
console.log(videoid);
});
var abc = 'video1';
document.getElementById(videoid).addEventListener('playing', function(){
console.log('play' + videoid);
})
document.getElementById(videoid).addEventListener('pause', function(){
console.log('3443');
})
document.getElementById(videoid).addEventListener('ended', function(){
console.log('242434');
})
});
what did I wrong?
http://jsfiddle.net/fbc7nn0o/51/
The video variable in the global scope has not been defined, and thus will fall on document.getElementById(variableName) || document.getElementsByName(variable) || undefined (cf Do DOM tree elements with ids become global variables?).
So addEventListener will only be called from the first <video> element, which as the id "video"...
What you want is
$('video').on({
play : onplay,
playing: onplaying,
pause: onpause
...
})
where onplay, onplaying, onpause ... are event handlers functions. e.g function onplaying(e){ $('.text').fadeOut(); console.log('dfdgd'); }.
Also note that $('#'+$(this).attr('id'))[0] is perfect non-sense.
Just use this.
It work for me.
$('video').bind('play', function (e) {
var videoid = $(this).attr('id');
document.getElementById(videoid).addEventListener('playing', function(){
console.log('play' + videoid);
});
document.getElementById(videoid).addEventListener('pause', function(){
console.log('3443');
});
document.getElementById(videoid).addEventListener('ended', function(){
console.log('ended');
});
});
Like the title says, I have a script that is working in Chrome and Firefox, but not IE. A couple unique things to this implementation are: 1) Multiple versions of jQuery (using noConflict), and 2) the majority of the assets used by jPlayer are generated through the script.
The Markup
<a class="audio-trigger" data-type="mp3" data-loop="false" href="/path.to.mp3">Listen</a>
The JS (inside a document.ready function)
// Initialize audio
if ($('.audio-trigger').length) {
//get jQuery 1.10.2 for jPlayer
$.getScript('/rsc/js/libs/jquery-1.10.2.min.js', function () {
$.getScript('/rsc/js/libs/jplayer-2.5.0.min.js', function () {
//jPlayer noConflict option is restricted to strings that contain the term jQuery
var jQuery1102 = jQuery.noConflict(true);
console.log('jQuery ' + $.fn.jquery + ' has been restored to global, and jQuery ' + jQuery1102.fn.jquery + ' has been preserved.');
//create pause button and audio container
var pause = '<a class="audio-pause" href="javascript:;">Pause | <span class="audio-currentTime"></span> / <span class="audio-duration"></span></a><div class="audio-play-area"></div>';
jQuery1102('.audio-trigger').after(pause);
//get audio link
var audioLink = jQuery1102('.audio-trigger').attr('href');
//Init jPlayer
jQuery1102('.audio-play-area').jPlayer( {
ready: function() {
jQuery1102(this).jPlayer('setMedia', {
mp3: audioLink
});
},
swfPath: '/rsc/js/libs',
supplied: jQuery1102('.audio-trigger').data('type'),
cssSelectorAncestor: '',
cssSelector: {
play: '.audio-trigger',
pause: '.audio-pause',
currentTime: '.audio-currentTime',
duration: '.audio-duration'
},
noConflict: 'jQuery1102',
loop: jQuery1102('.audio-trigger').data('loop'),
errorAlerts: true
});
});
});
}
and lastly, when I click on the audio trigger...
The Error
Attempt to issue media playback commands, while no media url is set.
Use setMedia() to set the media URL
Context: play
My .swf path name is 100% accurate and there are no other errors being thrown in any browser.
Thanks in advance for the help!
I discovered the .swf on the server was out of date. Updating it fixed the issue. Womp womp.
i am using the JPlayer for a website.
Now, i want to create playlist from a table with path and artist names.
Now what i did is i added the table to the page and now, using forEach i tried to
read the path and add it to the playlist. but somehow i am confused..
Have a look
this is the code i used for grabbing path and it works fine
<script type="text/javascript">
$(document).ready(function () {
$('#songsPathGridView tr').each(function () {
if (!this.rowIndex) return; // skip first row
var path = this.cells[0].innerHTML;
alert(path);
});
});
</script>
and now this is the playlist that i have (hard coded values). Now if it was in html or something i could have appended that path to it but since it's jquery code please tell me how to do it..
here is the playlist code
<script type="text/javascript">
$(document).ready(function () {
var songName = "Song1";
var theArtist = "The Artist";
var myPlaylist = [
{
mp3: 'music/Mad.mp3', oga: 'mix/1.ogg', title: songName, artist: theArtist,
},
{
mp3: 'mix/EssentialViolet.mp3', oga: 'mix/2.ogg', title: songName, artist: theArtist, cover: 'mix/2.jpg'
}
];
$('body').ttwMusicPlayer(myPlaylist, {
autoPlay: false,
jPlayer: {
swfPath: '../plugin/jquery-jplayer' //You need to override the default swf path any time the directory structure changes
}
});
});
</script>
Somehow i wanna get the filepath and add it dynamically. Please help, thanks.
I'd like to see the HTML code you're using for the table, because it will impact the construction, but essentially this method should work:
$(document).ready(function () {
var myPlaylist = [{}]; // Empty object to push into
$('#songsPathGridView tr').each(function () {
if (!this.rowIndex) return; // skip first row
// Push each row's data into the myPlaylist variable
// Expects MP3 path at column 0, title at column 1, artist at column 2
myPlaylist.push( { mp3: this.cells[0].innerHTML, title: this.cells[1].innerHTML, artist: this.cells[2].innerHTML } );
});
$('body').ttwMusicPlayer(myPlaylist, {
autoPlay: false,
jPlayer: {
swfPath: '../plugin/jquery-jplayer' //You need to override the default swf path any time the directory structure changes
}
});
});
I'm attempting to utilize the Youtube Upload Widget to upload videos from a site. I have the following javascript:
function onYouTubeIframeAPIReady() {
widget = new YT.UploadWidget('widget', {
events: {
onApiReady: function (event) {
event.target.setVideoTitle($("#title"));
event.target.setVideoDescription($("#description"));
event.target.setVideoPrivacy($("#privacy"));
},
onProcessingComplete: function(event) {
document.getElementById('processing').style.display = "none";
clearTimeout(timeout);
player = new YT.Player('player', {
height: 390,
width: 640,
videoId: event.data.videoId,
modestbranding: 1,
rel: 0,
events: {}
});
$("#updates").slideUp('slow', function() { });
},
onUploadSuccess: function(event) {
alert('Video ID ' + event.data.videoId + ' was uploaded and is currently being processed.');
widgetVideoId = videoId = event.data.videoId;
timeout = setTimeout(showProcessing, 1);
}
}
});
}
The video uploads just fine but onApiReady's function never fires. I'm not sure what I'm missing, because it looks complete. Hopefully someone can provide an idea on what I've missed. It doesn't work in IE9, FF, Chrome, or Safari. I'd like to be able to update the metadata on the video when it's uploaded.
event.target.setVideoTitle($("#title"));
event.target.setVideoDescription($("#description"));
event.target.setVideoPrivacy($("#privacy"));
All of these methods require a string parameter, whereas you are passing them a jQuery object.
I believe you mean to use .val()
Ok, I figured it out. It seems that you must use the <div id="widget"></div> format for the widget controller instead of the iframe method in order for onApiReady to fire.
Thanks for your assistance Brad.