Stream audio file - javascript

So I am trying to stream and download audio file to the browser.
My files are stored on a seperate drive to the web application.
Currently I am using java to send the file:
public static Result recording(Long id) {
PhoneCall currentCall = PhoneCall.getCall(id);
if (currentCall != null) {
File wavFile = new File("D:\\audio\\"
+ currentCall.fileName);
return ok(wavFile);
} else {
return badRequest();
}
}
This works fine in that i can stream the audio and it plays nicely. And I am playing the audio through a html5 element.
But I am trying to use a slider control and using audio.currentTime to set the current time so a user can play midway through but it seems that I cannot set this value. I also cannot get the duration of the audio file using audio.duration.
Even when i use <audio controls="controls" it does not allow me to play midway through
Is there something I am missing? Can I get javascript to download the whole file before it starts playing so that i can get all this information? Or is there another way to send this using play framework?

Related

Sound Lag issue on mousedown in javascript

I am making a website which is a simple piano. I hosted the site, but the audio is lagging now. When I play it from my local system it works fine, but not from the hosted site.
So I want all the audio resources to load and save it in the user's device (as cache or something else) and play the audio from it so the audio won't lag. I can't figure out how do I do it. please help me with a solution.
This is what I tried:
const pianoKeys = document.querySelectorAll('.key');
function playSound(soundUrl){
const sound = new Audio(soundUrl)
sound.currentTime = 0
sound.play()
}
pianoKeys.forEach((pianoKey, i)=> {
const num = i<9 ? '0'+(i+1) : (i+1);
const soundUrl = 'sounds/key'+num+'.ogg';
pianoKey.addEventListener('mousedown', ()=>playSound(soundUrl))
})
The soundUrl creates the directory to the audio file. Is there any way to load the file and play from it?

How can I randomise a song when one has finished? [duplicate]

I'm planning out a project for a very simple audio streamer that would take a mysql database list of songs hosted on my local server, and then randomly stream a song from the list constantly throughout the day. This would be attached to a very simple frontend page that would display the name of the currently playing song.
I know how to get a random file from the database and stream it using a Javascript/HTML front end, but I'm getting lost on how to detect when a song is over - and then load the next song. Is there a simple way to do this? Can someone point me in the right direction?
EDIT: To elaborate on the frontend, I'd most likely be serving up the filename/location via PHP into the HTML5 audio tag (again I want this as simple as possible). I'm thinking the simplest way would be to play the audio file and then refresh the page and play the next file using the same audio tag and new filename - I just don't know how to cause that event to happen at the end of the song. Alternatively I could use a Javascript based player like JPlayer (http://www.jplayer.org/) if I need to.
I'm guessing there's a callback function of some kind I can use in conjunction with JQuery?
HTML5 audio tag has an event "onended" which is run when the media reaches its end, but since you wish to keep playing you should use the "onwaiting" event, which also fires when the media reaches its end, but keeps itself ready to accept a new track/data.
You can then use the XMLHttpRequest object to query for the next track to play, eg.
<script type="text/javascript">
function getNextTrack(e) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "next_track.php", false);
xhttp.send("");
var playback = xhttp.responseXML.childNodes[0];
for(i = 0; i < playback.childNodes.length; ++i) {
if (playback.childNodes[i].nodeName != 'track') continue;
var value = playback.childNodes[i].childNodes[0].nodeValue;
e.currentTarget.src = value;
break;
}
}
</script>
<audio id="player" onwaiting="javascript: getNextTrack(e)" src="first_track.ogg"></audio>
The xml would be in the form of:
<?xml version="1.0" encoding="UTF-8" ?>
<playback>
<track>next_song.ogg</track>
</playback>

Is there a way to download an audio file of all the audio streams playing on a particular page?

I'm building an application using PizzicatoJS + HowlerJS. Those libraries essentially allow me to play multiple audio files at the same time. Imagine a 4 audio tracks with each track containing an instrument like guitar, bass, drums, vocals, etc..
Everything plays fine when using PizzicatoJS's Group functionality or running a forEach loop on all my Howl sounds and firing .play(). However, I would like to download the final resulting sound I am hearing from my speakers. Any idea on how to approach that?
I looked into OfflineAudioContext, but I am unsure on how to use it to generate an audio file. It looks like it needs an Audio source like an <audio> tag. Is what I'm trying to do possible? Any help is appreciated.
I think the OfflineAudioContext can help with your use case.
Let's say you want to create a file with a length of 10 seconds. It should contain one sound playing from the start up to second 8. And there is also another sound which is supposed to start at second 5 and should last until the end. Both sounds are AudioBuffers (named soundBuffer and anotherSoundBuffer) already.
You could arrange and combine the sounds as follows.
const sampleRate = 44100;
const offlineAudioContext = new OfflineAudioContext({
length: sampleRate * 10,
sampleRate
});
const soundSourceNode = new AudioBufferSourceNode({
buffer: soundBuffer
});
soundSourceNode.start(0);
soundSourceNode.stop(8);
soundSourceNode.connect(offlineAudioContext.destination);
const anotherSoundSourceNode = new AudioBufferSourceNode({
buffer: anotherSoundBuffer
});
anotherSoundSourceNode.start(5);
anotherSoundSourceNode.stop(10);
anotherSoundSourceNode.connect(offlineAudioContext.destination);
offlineAudioContext
.startRendering()
.then((audioBuffer) => {
// save the resulting buffer as a file
});
Now you can use a library to turn the resulting AudioBuffer into an encoded audio file. One library which does that is for example audiobuffer-to-wav.

Best way to stream large local media files with electron main process and handle them in the renderer process

Hello there,
I will try to be more specific about my question, I'm using angular 9 and latest electron version 8.1.1.
My goal is to read large media files like videos(>4go), songs(flac) or other large files located on my file system but using the stream api in nodeJS in the main process and sending the result (chunk,buffer) to the renderer process.
How can I handle the stream buffer in the renderer process, I would like to use video and audio api already built in html5, thus using ipc between the main and renderer process, I will send the chunks and would like to be able to display,play,read those chunk using html5 api's (e.g with the video tag and attribute src or audio tag and attribute src) what should I give as a src for these elements so that it works like a basic web stream with an url ?
Here is my main process code (where I use fs with nodejs):
ipcMain.on('getFileStream', (event, arg) => {
try {
if(fs.existsSync(arg.path) && fs.lstatSync(arg.path).isFile()) {
const s = fs.createReadStream(arg.path)
s.on('data', (chunk: Buffer) => {
console.log(chunk)
event.sender.send('getFileStreamResponse', chunk)
}).on('end', () => {
console.log("end stream")
event.sender.send('getFileStreamResponse', false)
s.close()
});
}
} catch(e) {
console.log('getFileStream', e)
}
})
I don't want to wait all chunks to begin to play the media, I want to be able to play the media when enough data is loaded. I have read about Mediasources in html5 but wanted to know if it's the right way or do you know a better way to read large files and rebuilt the chunks in the renderer process ?
Thanks a lot for your time

Play streaming audio in JavaScript

I'm currently using node-lame to encode a raw PCM input stream, and I have the following code in Node.JS that successfully outputs binary MP3 chunks:
server.on('request', (req, res) => {
encoded.pipe(res);
});
I try to request this code inside of my front-end interface with code like the following:
var audio = new Audio('http://localhost:8000/a.mp3'); // the above
audio.play();
However, as the audio source is a continuous input stream, the content just keeps getting downloaded without end:
Instead, I want to be able to play the chunks as they are downloaded.
I can access http://localhost:8000/a.mp3 in an application like VLC or Quicktime Player, and the audio delivery works fine; I'm just stumped as to how to best do this on the web.
Thanks in advance.
This code works for us:
<audio id="music" preload="all">
<source src="http://localhost:8000/a.mp3">
</audio>
<script>
let music = document.getElementById('music');
music.play();
</script>

Categories

Resources