Javascript: Setting track position form soundcloud api - javascript

I've been trying to play a track from Soundcloud at a specific position.
I have used the code from the following question as a reference
Soundcloud API: how to play only a part of a track?
below is the code that I have used
function playTrack(id) {
SC.whenStreamingReady(function() {
var sound = SC.stream(id);
sound.setPosition(240000); // position, measured in milliseconds
console.log(sound.position)
sound.play()
});
}
The console.log returns 0 and the track plays from the beginning.
alternative code I have tried and had the same result with is below
SC.stream("/tracks/" + id, function(sound){
console.log("playing")
console.log(sound)
sound.setPosition(120000)
console.log(sound.position)
sound.play()
})

Since soundcloud no longer uses soundmanager. the above methods will no longer work.
What must be done is to use a function called "seek()" instead of "setPosition()"
sound.seek(1500);
Here's a better example:
SC.stream(
"/tracks/[trackID]",
function(sound){
sound.seek(1500)
});
And if you wanted to access the seek function outside of the callback I would do this:
var soundTrack;
SC.stream(
"/tracks/[trackID]",
function(sound){
soundTrack = sound;
});
var buttonClickEvent = function(){
soundTrack.seek(1500);
}

According to SoundCloud's docs they are using SoundManager2 to handle playback, so you should be able to use any of its methods or settings. Try this:
function playTrack(id) {
SC.whenStreamingReady(function() {
var sound = SC.stream(id, {
from: 120000, // position to start playback within a sound (msec)
autoLoad: true,
autoPlay: true,
onplay: function(){ console.log(this.position) }
});
});
}
If that doesn't work you can try this instead:
function playTrack(id) {
SC.whenStreamingReady(function() {
var sound = SC.stream(id, { autoPlay: false }, function(sound){
sound.setPosition(240000); // position, measured in milliseconds
console.log(sound.position);
sound.play();
});
sound.load();
});
}

This should work-
var play_sound = function(id) {
SC.whenStreamingReady(function() {
var sound = SC.stream("/tracks/"+id,{autoPlay: false}, function(sound) {
sound.play({
whileplaying: function() {
console.log( this.position );
}
});
});
});
}

Related

Bodymovin hover playing animation only once

Got my animation to trigger play on hover. I got everything to work but when I try to hover to play again, nothing seems to work.
Any ideas what I wrote wrong?
var squares = document.getElementById("test");
var animation = bodymovin.loadAnimation({
container: test,
renderer: "svg",
loop: false,
autoplay: false,
path: "https://dl.dropboxusercontent.com/BodyMovin/squares.json"
});
squares.addEventListener("mouseenter", function () {
animation.play();
});
function playAnim(anim, loop) {
if(anim.isPaused) {
anim.loop = loop;
anim.goToAndPlay(0);
}
}
function pauseAnim(anim) {
if (!anim.isPaused) {
anim.loop = false;
}
}
When the animation reaches it's final frame, it doesn't go back to the first one. That's why if you call play, nothing happens since it has already ended and there is no more to play.
You should do:
squares.addEventListener("mouseenter", function () {
animation.goToAndPlay(0);
});
And if you only want it to replay once it has reached it's final frame, this should work:
var isComplete = true;
svgContainer.addEventListener('mouseenter', function(){
if(isComplete){
squares.goToAndPlay(0);
isComplete = false;
}
})
squares.addEventListener('complete', function(){
isComplete = true;
})
I'm giving a shot on this, although my experience about Bodymovin (and Lottie) is only from React Native world.
This should be quite straight forward to stop animation and restart it when cursor leaves the element:
squares.addEventListener("mouseenter", function () {
animation.play();
});
squares.addEventListener("mouseleave", function () {
animation.gotoAndStop(0);
});

Why can I not save currentTime() to a variable?

I try to automatically get the currentTime()on button click, but the issue I have at the moment is that I cannot access player when the button "create" is clicked. It returns undefinied
How can I get access to player.currentTime() when create is clicked?
var player;
$('.start').on('click', function (event) {
initializePlayer("test.mp4");
$('.create').show();
});
$('.create').on('click', function (event) {
var start = player.currentTime();
// start is always undefined
console.log("start is ".start);
startConverting(start);
});
function startConverting(start) {
// converting
}
function initializePlayer(src) {
player = videojs('media', {
fluid: true,
controls: true,
});
player.src({
type: "video/mp4",
src: src,
});
}
I have been looking at this for a long time and can't see where my problem is. Any help would be great!
Thanks!
Edit:
I realized that if I console.log(player.currentTime()) it would output the time. Now, why can I not pass the value to var start and it is being undefined?

How to have multiple instances of a jQuery plugin

I am trying to create a SoundCloud music player. It can play any track from SoundCloud, but this plugin is only working if there is only one instance of it in the page. So it wont work if two of the same plugin are in the page.
Here is an example of having two players in the page: JSFiddle
var trackURL = $(".player").text();
$(".player").empty();
$(".player").append("<div class='playBTN'>Play</div>");
$(".player").append("<div class='title'></div>");
var trackId;
SC.get('/resolve', { url: trackURL }, function (track) {
var trackId = track.id;
//var trackTitle = track.title;
$(".title").text(track.title);
$(".playBTN").on('click tap', function () {
//trackId = $(".DSPlayer").attr('id');
stream(trackId);
});
// first do async action
SC.stream("/tracks/" + trackId, {
useHTML5Audio: true,
preferFlash: false
}, function (goz) {
soundToPlay = goz;
sound = soundToPlay;
scTrack = sound;
//updater = setInterval( updatePosition, 100);
});
});
var is_playing = false,
sound;
function stream(trackId) {
scTrack = sound;
if (sound) {
if (is_playing) {
sound.pause();
is_playing = false;
$(".playBTN").text("Play");
} else {
sound.play();
is_playing = true;
$(".playBTN").text("Pause");
}
} else {
is_playing = true;
}
}
If you remove any of these div elements that hold the .player class, the other element will work. So it only doesn't work because there are two instances of the same plugin.
How can I fix it? to have multiple instances of the player in one page?
I have identified the problem. It has to do with the fact that you are trying to load multiple tracks at the same time, but have not separated the code to do so.
As #Greener mentioned you need to iterate over the .player instances separately and execute a SC.get() for each one of them.
Here is what I see happening that is causing the problem:
var trackURL = $(".player").text();
^The code above returns a string that contains both of the URLs you want to use back-to-back without spaces. This creates a problem down the road because of this code:
SC.get('/resolve', { url: trackURL }, function (track) {...
That is a function that is trying to load the relevant song from SoundCloud. You are passing it a variable "trackURL" for it to try and load a specific URL. The function gets a string that looks like "URLURL" what it needs is just "URL".
What you can do is iterate over all the different ".player" elements that exist and then call the sounds that way. I modified your script a little to make it work using a for loop. I had to move the "empty()" functions into the for loop to make it work correctly. You have to use .eq(index) when referring to JQuery array of elements.
Like this:
var trackURL
var trackId;
for(index = 0; index < $(".player").length; index++){
trackURL = $(".player").eq(index).text();
//alert(trackURL);
$(".player").eq(index).empty();
$(".player").eq(index).append("<div class='playBTN'>Play</div>");
$(".player").eq(index).append("<div class='title'></div>");
SC.get('/resolve', { url: trackURL }, function (track) {
var trackId = track.id;
alert(track.id);
//var trackTitle = track.title;
$(".title").eq(index).text(track.title);
$(".playBTN").eq(index).on('click tap', function () {
//trackId = $(".DSPlayer").attr('id');
stream(trackId);
});
// first do async action
SC.stream("/tracks/" + trackId, {
useHTML5Audio: true,
preferFlash: false
}, function (goz) {
soundToPlay = goz;
sound = soundToPlay;
scTrack = sound;
//updater = setInterval( updatePosition, 100);
});
});
}
This is not a completely finished code here, but it will initiate two separate songs "ready" for streaming. I checked using the commented out alert what IDs SoundCloud was giving us (which shows that its loaded now). You are doing some interesting stuff with your streaming function and with the play and pause. This should give you a good idea on what was happening and you can implement your custom code that way.

JavaScript audio not playing outside of jQuery function

I know the question title doesn't make much sense, but I can't think of a better way to put it. I am a newbie to jQuery and I'm using this code to fade in a <div> and play a sound:
$(document).ready(function(){
$('#speech').fadeIn('medium', function() {
play('msg_appear');
var sptx = $('<p class="stext">').text('There is nothing here.');
$('#speech').append(sptx);
$('.stext').typeOut({marker: '', delay: 22});
});
});
This code runs fine however the sound plays after the fade-in is complete. I wanted it to play while it was fading in, so I tried placing the play() call outside of the fade-in function like this:
$(document).ready(function(){
play('msg_appear');
$('#speech').fadeIn('medium', function() {
However, now it's not playing at all. There's no errors on the JavaScript console so I'm unsure if it's a syntax error, and probably something obvious, but I don't know what.
play() is a function I found to play audio, here it is if it matters at all. I placed it in the same file the above code is; right above the $(document).ready().
function play(sound) {
if (window.HTMLAudioElement) {
var snd = new Audio('');
if(snd.canPlayType('audio/ogg')) {
snd = new Audio(sound + '.ogg');
}
else if(snd.canPlayType('audio/mp3')) {
snd = new Audio(sound + '.mp3');
}
snd.play();
}
else {
alert('HTML5 Audio is not supported by your browser!');
}
}
Based on the comments, I'd recommend modifying the play() function you found:
function play(sound, callback) {
if (window.HTMLAudioElement) {
var snd = new Audio('');
if(snd.canPlayType('audio/ogg')) {
snd = new Audio(sound + '.ogg');
}
else if(snd.canPlayType('audio/mp3')) {
snd = new Audio(sound + '.mp3');
}
if(typeof(callback)=="function"){
snd.addEventListener("canplay", function(){
snd.play();
callback();
});
} else {
snd.addEventListener("canplay", function(){
snd.play();
});
}
snd.load();
}
else {
alert('HTML5 Audio is not supported by your browser!');
}
}
Then call it like:
play('msg_appear', function(){
$('#speech').fadeIn('medium', function() {
var sptx = $('<p class="stext">').text('There is nothing here.');
$('#speech').append(sptx);
$('.stext').typeOut({marker: '', delay: 22});
});
});
That way the audio's play(); won't fire until after the audio can start playing, and the fadeIn() will be started at the same time as the audio.
And of course, the callback isn't necessary; it just makes for more robust timing in varying network conditions.
I can only think that $(document).ready is too early to allow play to happen (in whichever browser is exhibiting this problem), when not delayed by the fadeIn.
Try :
$(window).on('load', function(){
play('msg_appear');
$('#speech').fadeIn('medium', function() {
var sptx = $('<p class="stext">').text('There is nothing here.');
$('#speech').append(sptx);
$('.stext').typeOut({marker: '', delay: 22});
});
});
EDIT:
If necessary, you can introduce further delay as follows:
$(window).on('load', function(){
setTimeout(function() {
play('msg_appear');
$('#speech').fadeIn('medium', function() {
var sptx = $('<p class="stext">').text('There is nothing here.');
$('#speech').append(sptx);
$('.stext').typeOut({marker: '', delay: 22});
});
}, 1000);//adjust up/down to the minimum reliable value
});
First of all, see: HTML5 Audio onLoad
There are some ways to handle loading state. The accepted answer looks weird though.
I recommend code like this:
function makePlayer(sound){
if (window.HTMLAudioElement) {
var snd = new Audio('');
if(snd.canPlayType('audio/ogg')) {
snd = new Audio(sound + '.ogg');
}
else if(snd.canPlayType('audio/mp3')) {
snd = new Audio(sound + '.mp3');
}
return function(){
snd.play();
};
}
};
var play = makePlayer('msg_appear');
$(document).ready(function(){
$('#speech').fadeIn('medium', function() {
play();
var sptx = $('<p class="stext">').text('There is nothing here.');
$('#speech').append(sptx);
$('.stext').typeOut({marker: '', delay: 22});
});
});

how to play a sound file after another sound in javascript

How do I play a sound file after another sound ends? If I do it like
first.play();
second.play();
Both the sounds play at the same time. I want to play first.play() and when it ends, starts second.play().
first.addEventListener('ended', function(){
second.play();
});
first.play();
I would recommend kind of something:
// if using jQuery:
var audios = $('audio');
audios.each(function(idx){
$(this).bind('ended', function(){
var next = audios.get(idx+1);
if(next){
next.get(0).play();
}
});
});
You can also use a promise with a timeout:
const playPromise = first.play()
playPromise.then(() => {
setTimeout(() => {second.play()}, first.duration * 1000)
})
I used the AudioScheduledSourceNode.onended.
I used four sounds, and put this code in a function:
sound1.play();
sound1.onended = function () {
sound2.play();
};
sound2.onended = function () {
sound3.play();
};
sound3.onended = function () {
sound4.play();
}
Here is the app live: insultinator-toy.netlify.app
Click the question mark button.
And the link to the ugly source code. jsahlsa

Categories