I have been trying to figure out this for a week.
I have two completely different video tags with their respective audio. I also have one audio tag. At first, both muted attribute is set for both video tags. When I want to get video1 audio, I would like to get it audio source and assign it to the audio tag. Also do the same for video2.
Is this possible with Javascript? I have tried Web audio API but I'm lost. Please help.
I am not sure I get what you want.
To copy the video's audio stream to an audio element, you could simply set the src of the <audio> element to the video's src :
<audio src="http://media.w3.org/2010/05/sintel/trailer.mp4" controls autoplay></audio>
Then you could try to sync it with your video tag's currentTime, or sync the video's currentTime with the <audio>'s one and unmute the video, while the audio would be muted, but I'm not sure you'll get awesome results. Also, it won't be a surprise if some browsers will load the video twice in the same time.
Now, what can you do with the WebAudioAPI :
It would be really hard to make your audio streams into the audio tags, live and in a cross-browser way.
If you don't need this however, it's pretty easy to create some MediaSource from video elements thanks to the createMediaElementSource() method.
Once these MediaSource objects are created, your original media will be disconnected from the normal output. You need to keep their muted attribute unset or set to false in order to hear it as a MediaSource object.
Here is a simple example that will allow you to mute/unmute a video source, from the WebAudioAPI only :
var vid = document.getElementById('vid');
var audioCtx = new AudioContext();
var gainNode = audioCtx.createGain();
var v1_src = audioCtx.createMediaElementSource(vid);
gainNode.connect(audioCtx.destination);
btn_1.onclick = function() {
var playing = this.textContent.indexOf('listen') < 0;
if (playing) {
v1_src.disconnect();
this.textContent = this.textContent.replace('mute', 'listen');
} else {
v1_src.connect(gainNode);
this.textContent = this.textContent.replace('listen', 'mute');
}
}
video { height: 120px;}
<button id="btn_1">listen</button><br>
<video id="vid" crossOrigin='anonymous' src="http://vjs.zencdn.net/v/oceans.mp4" loop autoplay></video>
Note that the media passed to this method must come from a safe domain request (see CORS).
Related
I am using Plyr audio player for my Rails app, along with Simulus.js.
I dynamically add audio source when the user clicks on different audio buttons. Then I launch the audio player with the .play() method.
However, the beginning of the track can't be heard. You can try it out on this URL, by taping the first audio player. If you put back the audio cursor to the beginning, then you can hear the very beginning of the track.
Here is my HTML:
<audio class="player" controls data-dicteeModule-target="player">
<source class="player-source" src="<%= dictee_modules.first.audio_url %>" type="audio/mp3" />
</audio>
Here is how I initialize the player:
initialize() {
const players = document.getElementsByClassName('player');
var player = [];
Array.from(players).forEach(function (ele, i) {
player[i] = new Plyr(ele, {
controls: ['progress']
});
});
}
Here is my Stimulus onclick action:
var player = this.playerTarget;
var source = audio.getAttribute("data-audio-source");
var audioSource = player.getElementsByClassName("player-source")[0];
audioSource.src = source;
player.load();
player.addEventListener('canplay', (event) => {
player.play();
});
Any idea why the very beginning of the track is not heard?
Thanks.
This happens to me too on various websites that need to use audio after no audio was used for a while, even on YouTube. I'm using Chrome 104.0.5112.81 on Windows 10.
It's likely a driver issue you can't do much about (assuming YouTube would fix it if they could). It looks like Windows or Chrome ends up dimming the sound way too quickly, and takes too long turning it back on.
Unfortunately I couldn't find anything on Google yet. It seems hard to make Google understand this query, it only returned results about audio preventing PC sleep mode (or other unrelated common issues), no matter how I phrased it. Could also indicate it's just a very obscure issue with one or a few particular drivers.
I have a video element like:
<video id="video" width="320" height="240" autoplay controls muted></video><br/>
The stream data are pushed into an array:
let blobs_recorded = [];
media_recorder = new MediaRecorder(camera_stream, { mimeType: 'video/webm' });
media_recorder.addEventListener('dataavailable', function(e) {
blobs_recorded.push(e.data);}
All is running fine and I can record a full video without problem. Well I want to create an new video from this full recorded video and only want to get the last three seconds of this vid until end. I tried to manipulate the Blobs but video is then black. I found out if I put the the first blob to the new video then I can see this video, but I got the metadata of the full big video in the small video. Any idea how I can solve it smart?
Greetings.
I was wondering if someone has had a similar problem:
I have defined fallback mounts in Icecast2 so that one major stream plays at all times. If another fallback mount becomes active, the latter becomes the active.
I have tested the streams (mp3 format), with ffplay and the transition happens with no problem. The problem exists when I use an html5 audio tag to listen to the audio: transition does not happen automatically and I have to reload the browser and click play in order to listen to the stream. That is, using the browser, when the fallback stream gets enabled, the sound stops and I have to reload the browser and click play in order to listen[to the other stream]. The same problems occurs in all major browsers.
Here's an excerpt from my icecast.xml:
<mount>
<public>0</public>
<mount-name>/stream</mount-name>
<hidden>0</hidden>
</mount>
<mount>
<public>0</public>
<mount-name>/stream1</mount-name>
<fallback-mount>/stream</fallback-mount>
<fallback-override>1</fallback-override>
<username>stream1</username>
<password>pass</password>
<hidden>0</hidden>
</mount>
This is what ffplay shows while connecting and disconnecting from the secondary source:
The html5 code that plays the audio is as follows:
<audio controls>
<source src="http://127.0.0.1:3333/stream1" type="audio/mpeg">
</audio>
I got this finally working by going as follows:
First I noticed that when I switched from one mount point to another by enabling the source, the audio stopped playing. I set up a timer to fire every 1 second in order to check audio.currentTime and compare to an previous value. Then when the result is true, I reset the audio source to the same stream. It's kind of a hack but it seems to solve the trick.
html code:
<audio id="audio" controls>
<source src="http://127.0.0.1:3333/stream1" type="audio/mp3">
</audio>
javascript code:
var audio = document.getElementById('audio');
var myVar = setInterval(myTimer, 1000);
var oldTime = "";
function myTimer() {
if ((audio.paused != true && (audio.currentTime - oldTime) == 0 )) {
audio.src="";
audio.src="http://127.0.0.1:3333/stream1";
audio.play();
}
oldTime = audio.currentTime;
};
I have a video tag like this. All this videos have to play dynamically one after other
I tried writing some javascript functions in eventlistner "progress" of the video, but not working.How to play these videos automatically?anybody please suggest any codes in javascript or jquery
<div id="divVid">
<video id="video1" width="320" height="240" autoplay >
<source src="vid_future technology_n.mp4#t=20,50" >
Your browser does not support the video tag.
</video>
</div>
JS Code (Updated from comment section)
document.getElementById("video1")
.addEventListener("progress",
function () {
var i = 0;
var vid = document.getElementById("video1");
if (vid.paused) {
if (vid.currentSrc == myvids[i]) {
vid.currentSrc = myvids[i + 1]; } i = i + 1;
}
});
The set of <source> elements provide alternative formats for the video for different devices, not a playlist.
If you want to have a playlist, then listen for an ended event and change the src with JavaScript.
In response to edits to the question:
No, really change the src. You are trying to change the currentSource which is defined as being readonly
I said ended. Don't touch progress, you what to play the next video when the last one is finished, not when a tiny chunk of it has played
The list of <source> elements still isn't a playlist. Don't try to use them as such. Keep the list of videos somewhere else (e.g. a JS array).
Im trying to make a video player work in all browsers. There is
more then one video and every time you click on demo reel it plays the
video and if you click the video 1 the other video plays. How can i
make them both work in all browsers? Here is my html and javascript
html
<video id="myVideo" controls autoplay></video>
<div>
Demo Reel</div>
video 1</div>
</div>
javascript
function changeVid1() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/demoreel.mp4"
}
function changeVid2() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/video1.mp4";
}
After you switch the source of the video, you need to run .load() on it to force it to load the new file. Also, you need to provide multiple formats, because there is no video codec supported by all browsers.
First, set up your sources like this:
var sources = [
{
'mp4': 'http://video-js.zencoder.com/oceans-clip.mp4',
'webm':'http://video-js.zencoder.com/oceans-clip.webm',
'ogg':'http://video-js.zencoder.com/oceans-clip.ogv'
}
// as many as you need...
];
Then, your switch function should look like this:
function switchVideo(index) {
var s = sources[index], source, i;
video.innerHTML = '';
for (i in s) {
source = document.createElement('source');
source.src = s[i];
source.setAttribute('type', 'video/' + i);
video.appendChild(source);
}
video.load();
video.play(); //optional
}
See a working demo here.
This gives the browser a list of different formats to try. It will go through each URL until it finds one it likes. Setting the "type" attribute on each source element tells the browser in advance what type of video it is so it can skip the ones it doesn't support. Otherwise, it has to hit the server to retrieve the header and figure out what kind of file it is.
This should work in Firefox going back to 3.5 as long as you provide an ogg/theora file. And it will work in iPads, because you only have one video element on the page at a time. However, auto-play won't work until after the user clicks play manually at least once.
For extra credit, you can append a flash fallback to the video element, after the source tags, for older browsers that don't support html5 video. (i.e., IE < 9 - though you'll need to use jQuery or another shim to replace addEventListener.)