Using HtmlMediaElement.captureStream() to get the audio from a video - javascript

I'm trying to capture the audio track from a video and play it separately. I wrote the test page shown below. I'm able to capture the stream and I get a valid audio track with readyState == "live", but I hear nothing. What am I doing wrong?
The video I'm using comes from here: http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4. I'm serving the HTML and the video locally to avoid CORS issues.
<head>
<script>
function captureAudio() {
const videoEl = document.getElementById("video")
videoEl.volume = 0.0
const videoStream = videoEl.captureStream()
const audioTrack = videoStream.getAudioTracks()[0]
const audioStream = new MediaStream()
audioStream.addTrack(audioTrack)
const audioEl = document.createElement("audio")
audioEl.srcObject = audioStream
audioEl.autostart = true
audioEl.volume = 1.0
audioEl.muted = false
}
</script>
<body>
<video id="video" src="http://localhost:3000/BigBuckBunny.mp4" controls onplay="captureAudio()" />
</body>
</html>

It works if you set a volume different than 0 (for example, 0.5). I have modified your code and hosted it on Glitch. When you pause the audio (that I have attached to the DOM so you can interact with it), you can clearly hear the different sources of sound, one from the video and one from the audio.
<html>
<head>
<script>
function captureAudio() {
const videoEl = document.getElementById("video");
videoEl.volume = 0.5;
const videoStream = videoEl.captureStream();
const audioTrack = videoStream.getAudioTracks()[0];
const audioStream = new MediaStream();
audioStream.addTrack(audioTrack);
const audioEl = document.createElement("audio");
audioEl.controls = true;
document.body.append(audioEl);
audioEl.srcObject = audioStream;
audioEl.play();
audioEl.volume = 1.0;
audioEl.muted = false;
}
</script>
</head>
<body>
<video
id="video"
crossorigin
src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
controls
onplay="captureAudio()"
/>
</body>
</html>

Related

why does this keep playing same video instead of random new video?

I'm making a random order video player, adapting code from here but the same video just keeps playing, even though I can see (from text above the video) that the random ordering is working. Live version is here.
Is the problem with the appendChild meaning the new video is end of a list but the first in list keeps playing? I tried replaceChild but that didn't work.
<script type="text/javascript">
$(document).ready(function(){
var videos = [
[{type:'mp4', 'src':'carlos/one-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/two-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/three-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/four-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/five-carlostest.mp4'}]
];
// selecting random item from array as first to be played
var randomitem = videos[Math.floor(Math.random()*videos.length)];
// This function adds a new video source (dynamic) in the video html tag
function videoadd(element, src, type) {
var source = document.createElement('source');
source.src = src;
source.type = type;
element.appendChild(source);
}
// this function fires the video for particular video tag
function newvideo(src){
var vid = document.getElementById("myVideo");
videoadd(vid,src ,'video/ogg');
vid.autoplay = true;
vid.load();
vid.play();
}
// function call
newvideo(randomitem[0].src)
// Added an event listener so that everytime the video finishes ,a new video is loaded from array
document.getElementById('myVideo').addEventListener('ended',handler,false);
function handler(){
var newRandom = videos[Math.floor(Math.random()*videos.length)];
newvideo(newRandom[0].src)
document.getElementById("monitor").innerHTML = "randomitem is " + newRandom[0].src;
}
})
</script>
Also, if anyone can tell me why the autoplay never works that'd be appreciated, though it's the least of my problems.
I have kinda found this solution for your video playing one after other. now in your JS file, now you just will need to add your video src path.
var vidElement = document.getElementById('video');
var vidSources = [
"https://lutins.co.uk/carlos/one-carlostest.mp4",
"http://www.w3schools.com/html/movie.mp4"
];
var activeVideo = Math.floor((Math.random() * vidSources.length));
vidElement.src = vidSources[activeVideo];
vidElement.addEventListener('ended', function(e) {
// update the active video index
activeVideo = (++activeVideo) % vidSources.length;
if(activeVideo === vidSources.length){
activeVideo = 0;
}
// update the video source and play
vidElement.src = vidSources[activeVideo];
vidElement.play();
});
video {
width:350px;
}
<p>wowww you got it!</p>
<video src="https://lutins.co.uk/carlos/one-carlostest.mp4" id="video" autoplay muted playsinline></video>
Change the randomIt variable into a callback, only this way, it will generate new random number each time it get call.
// I have change randomitem into a function with ofcourse a proper name
var getRandomItem = function() {
return videos[Math.floor(Math.random()*videos.length)];
}
You should also call it properly like this:
//newvideo(randomitem[0].src) -> change it to
newvideo(getrandomItem().src)
There might also other adjustments requires for your code to work.

Can put a link in a video element

So I'm trying to put a link inside a Video element and It wont work here is the code, also How do You make a Variable as string in JS ??
var link = prompt("Enter The Website You Wanna Stream:");
document.getElementById("PLAYER").innerHTML = "<source src='" + link + "' type='video'>";
A simple way of changing the source of a video based on your code in js:
const link = prompt('Enter video Link');
const video = document.querySelector('video');
video.src = link;
full code for a test:
setTimeout(() =>{
// setting a timeout of 3s
const link = prompt('Enter video Link');
const video = document.querySelector('video');
video.src = link;
} , 3000)
<video src="https://hw5.cdn.asset.aparat.com/aparat-video/09b40b525d19c2459557117619da2c7f12978678-240p.mp4?wmsAuthSign=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0b2tlbiI6IjlkNTQwYTJiMmNkZDAzMDFjODNlNjIxNjlmOWVjY2ZkIiwiZXhwIjoxNjM5MDkyNTY4LCJpc3MiOiJTYWJhIElkZWEgR1NJRyJ9.PTLqt9ltqbosdJr27icnfc_4PhUG4oVX2_IPxVXdqro" autoplay muted controls></video>
and to make a variable string you can use .toString()
const num = 123;
const str = num.toString();
bear in mind in too many cases .toString() is not needed in js. I suggest you see: js data types as well as js operators
Your code is ok. You need only wrapped in the video Tag.
function myFunction() {
const link = prompt("Enter The Website You Wanna Stream:");
if (link != null) {
document.getElementById("PLAYER").innerHTML = `<video width="320" height="240" controls>
<source src="movie.mp4" type="video/mp4">
Your browser does not support the video tag.
</video>`;
}
}
<button onclick="myFunction()">Try it</button>
<div id="PLAYER"></div>

play random video on each visit/refresh with iFrame javascript

How do I create a random video to play every time a user visits/reloads the page with Javascript?
For example, if one person were to go onto my domain, the iFrame would try to load any of the .mp4 files inside of my media file directory where it has like 4 different .mp4 videos. Here is my code below.
Code:
<source src="assets/media/lofi.mp4" type="video/mp4" />
<script type="text/javascript">
const video = document.currentScript.parentElement;
video.volume = 0.15;
function pause_resume() {
const button = document.getElementById("pause_resume_button");
if (video.paused) {
video.play()
button.textContent = "resume video";
} else {
video.pause()
button.textContent = "pause video";
}
}```
You need to use Math.random to choose a random video from a list.
Then add the chosen video url to the html element, and trigger the "play" event.
const videos = ["video1.mp4", "video2.mp4", /* ... */ "video30.mp4"]
const randomNumber = Math.floor(Math.random() * videos.length)
const currentVideo = videos[ randomNumber ]
const videoElement = document.getElementById('video');
videoElement.src = currentVideo
videoElement.play()
Related question: changing source on html5 video tag

Web Audio loops with <audio> as source

I understand that I can manipulate the audio stream with Web Audio using createMediaElementSource() but is it possible to play / loop the audio with Web Audio and use the tag purely for loading the audio?
This is what I tried but it says start() is not a function:
window.onload = init;
var context;
var bufferLoader;
function init() {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
context = new AudioContext();
var audio = $("audio").get(0);
var source = context.createMediaElementSource(audio);
source.connect(context.destination);
source.start(0);
}
window.onload = init;
function init() {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var audio = $("audio").get(0);
audio.addEventListener('loadstart', function() {
var source = context.createMediaElementSource(audio);
source.connect(context.destination);
audio.play(0);
}, false);
}
Refer to https://github.com/Korilakkuma/XSound/blob/master/build/xsound.dev.js#L9703 in XSound.js
You can start playing the audio with audio.play() but your source is a MediaElementAudioSourceNode, not an AudioBufferSourceNode.
If you find a way to get the buffer of the audio tag, maybe you can pass it to an AudioBuffer and make it works...
How about you try the "" command on html?
It's written like so:
<audio controls preload> </li>
<source src="the/source/in/your/library">
</audio>
More info here

sound effect in a html5 game

I'm trying to play sound effect in a game with each hit,but the sound sometimes play and others NOT !!
I'm using the next code :
<script>
var hitSound = new Audio();
function playEffectSound()
{
hitSound = document.getElementById('effects');
hitSound.loop = false;
hitSound.currentTime = 0;
hitSound.play();
}
</script>
<audio id="effects" hidden>
<source src="sound/mp3/effect.mp3" type="audio/mpeg">
<source src="sound/wav/effect.wav" type="audio/wav">
</audio>
any ideas ?
Whenever you are using audio tag try writing its script after audio tag ,If you write script before that audio tag it gives sometime problem in playing the audio,
i would recommend Write Script at the end of the page that's the standard way to write script.
http://jsfiddle.net/LyDWH/4/
<!DOCTYPE html>
<html>
<body>
<audio id="effects" hidden >
<source src="http://www.w3schools.com/html/horse.mp3" type="audio/mpeg">
</audio>
<div onclick= "playEffectSound();">Horse Click Me..!</div>
</body>
<script>
var hitSound = new Audio();
function playEffectSound()
{
hitSound = document.getElementById('effects');
hitSound.currentTime = 0;
hitSound.play();
}
</script>
</html>
​
You could use the following code to play audio
function playEffectSound(sound) {
//Does the sound already exist?
if (document.getElementById(sound) != null) {
document.getElementById(sound).play();
return;
}
//Create elements
var audioElement = document.createElement("audio");
var sourceElement = document.createElement("source");
sourceElement.src = sound + ".mp3";
sourceElement.type = "audio/mpeg";
var sourceElementWave = document.createElement("source");
sourceElementWave.src = sound + ".wav";
sourceElementWave.type = "audio/wav";
//Add sources to audio
document.body.appendChild(sourceElementWave);
document.body.appendChild(audioElement);
audioElement.setAttribute("id", sound);
audioElement.appendChild(sourceElement);
audioElement.loop = false;
audioElement.currentTime = 0;
audioElement.play();
}
You can use it like this: playEffectSound("sounds/effect"); and it will either play sounds/effect.mp3 or sounds/effect.wav
try with each hit to add a new var sound and sound.play() and it will just work fine

Categories