If I load from the local file system, I can seek using
foo.currentTime = 2;
foo.play();
I get expected results. However if I load from the server, the seek fails, and the audio plays from the beginning. I have tried the 'oncanplaythrough' event. Here is my code:
var myID = '1111'
var audioElementString = '<audio type="audio/mpeg" id=' +'"' + myID + '"' + '></audio>'
$('body').append(audioElementString);
var audio = document.getElementById(myID);
//audio.src = "contentAssets/audio/some_file.mp3"; // this loads and seeks fine
audio.src = "http://bar.com/mypath/file"; // this loads and plays, but does not seek
audio.addEventListener("canplaythrough", function(){
alert("can play through")
audio.currentTime=3;
audio.play();
});
audio.load();
Solved, we added Accept-Ranges = bytes to the response header.
dt1000 has the correct answer. I have been looking through many different forums for the reason why Chrome will not allow audio.currentTime to be set if streaming an mp3 from PHP and this is the answer that works. Add this to PHP:
header('Accept-Ranges: bytes');
By the way, Firefox and IE do not need the above header to set audio.currentTime. But Chrome needs it. Chrome will also not let you move the audio tag slider control without the above header.
Related
I used this js to export everything in my canvas as an mp4 video. I succeeded in exporting it as a video but the video is always 0 in time.
Here's the js I used
https://github.com/antimatter15/whammy
Here's the code I have so far that can download the canvas and elements inside but not the animation.
var canvas_video = document.querySelector('canvas').getContext('2d');
canvas_video.save();
console.log(canvas_video);
var encoder = new Whammy.Video(15);
var progress = document.getElementById('progress');
encoder.add(canvas_video);
console.log("1",encoder);
encoder.compile(false, function(output){
//var url = (window.URL || window.URL).createObjectURL(output);
var url = URL.createObjectURL(output);
console.log(url);
document.getElementById('download_link').href = url;
});
When I checked on the console to debug it, it shows encodeFrame 0.
Can anyone advise on what should I do and if I miss something?
For anyone who's still looking for the answer -
That Library will only output to .webm instead of .mp4.
As far as I know, except for Chrome, no other browser support webm playback. So, use Chrome to view the video. Other browsers will stuck at 0 time.
I am trying to load an audio file which changes each time a request is sent to my PHP page. For some reason, my site does not like to open the new version of the file.
function reloadFile(command) {
$.post("function.php", { data: command }, function(data) {
console.log("Sever Says : " + data);
}).done(
function(data){
// Error In Here
var audio = new Audio("a.ogg");
audio.play();
});
}
I appreciate all of your help eventually I came to the conclusion that I would need to use the current server time to request the newly edited file in Apache and PHP.
The new code is as follows
var url = "filename.mp3?cb=" + new Date().getTime();
var audio = new Audio(url);
audio.load();
audio.play();
I think the problem is that the Browser only has the old audio loaded. You also need to send the changed audio file to the browser.
I'm using HTML5 Media source extensions (MSE) to stream a video using DASH. I created my media segments using MP4Box from a MP4 file with two video tracks in it. So what I have is a single initialisation segment with moov->sidx boxes and multiple media-segments moof->mdat containing both video tracks. If I push them to the sourceBuffer with appendBuffer function, MSE decodes and shows only the first video track (I assume that the data from the second video track is just discarded).
Here are the relevant parts from my code:
sourceBuffer = mediaSource.addSourceBuffer(stats.mimeType); // mime type: video/mp4
...
// after downloading mediasegment append its contents 'data' to sourceBuffer
sourceBuffer.appendBuffer(new Uint8Array(data));
So my question is, is it possible to control the sourceBuffer in such a way that the client can select which track to decode? I suppose that splitting the video tracks to different adaptation sets (creating separate mp4 files with a single video track in each one) could be a solution but I'm not interested in this approach.
Thank you guys.
Okay I found a way how to do this. Using videoTracks attribute we can access the video tracks and change its selected attribute. So it was pretty simple to do.
Here is an example how to toggle the tracks after third segment was downloaded:
if(segmentCnt==3 && sourceBuffer.videoTracks.length == 2)
{
console.log('tracks cnt: ' + sourceBuffer.videoTracks.length);
for(var i=0; i<sourceBuffer.videoTracks.length; i=i+1) {
var trackID = sourceBuffer.videoTracks[i].id;
var trackSelected = sourceBuffer.videoTracks[i].selected;
console.log('trackID: ' + trackID + ' selected: ' + trackSelected);
sourceBuffer.videoTracks[i].selected = !trackSelected;
}
}
Is it possible to dynamically create a HTML5 video element so that I can access the element by API's like document.getElementById or Name but it may not show up in the webpage.
Something like div.hide() or something in that direction ?
You can try
var video = document.createElement('video');
video.src = 'urlToVideo.ogg';
video.autoplay = true;
you can also use the canPlayType method to check if the browser supports the video format you want to use before setting source
if (video.canPlayType('video/ogg').length > 0) {
/* set some video source */
}
The method returns maybe or perhaps depending on browser. If empty string it means it can't play it.
You can now use the video using the API. Just store it globally. You can later insert it into the DOM. Hope this helps.
Sure you can create everything just using JS. You need nothing to be pre-created in html body.
Here is simple way of creating video element in JS:
var videlem = document.createElement("video");
/// ... some setup like poster image, size, position etc. goes here...
/// now, add sources:
var sourceMP4 = document.createElement("source");
sourceMP4.type = "video/mp4";
sourceMP4.src = "path-to-video-file.mp4";
videlem.appendChild(sourceMP4);
//// same approach add ogg/ogv and webm sources
Before doing this, you should check if browser supports video element, and if so, which file formats can be played. This you can do by:
var supportsVideoElement = !!document.createElement('video').canPlayType;
Then, if video element is supported, test which video formats can be played:
var temp = document.createElement('video');
var canPlay_MP4 = temp.canPlayType('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
var canPlay_OGV = temp.canPlayType('video/ogg; codecs="theora,vorbis"');
var canPlay_WEMB = temp.canPlayType('video/webm; codecs="vp8,vorbis"');
After this, you can add video element to your page using JS only, with proper video sources set. There may be an issue with .htaccess on server side where you need to add lines:
AddType video/ogg .ogv
AddType video/ogg .ogg
AddType video/mp4 .mp4
AddType video/webm .webm
This may not be needed, depending on how your server is set, but if you encounter issue with playing videos from your server, but they play fine from eg. localhost on your dev machine, this can solve the issue. .htaccess with above lines should be placed in the folder where video files are located, on server side.
Ok now, in order to have this element available with getElementById(...), you just need to set id of it, when you create it:
var videlem = document.createElement("video");
videlem.id = "xxxxxx";
And now you can later find it using:
var videlem = document.getElementById("xxxxxx");
However, as someone commented already, you don't need to do this if you have already created the element and have variable pointing to it... just use it directly.
Hope this helps :-)
Updated (and simplest) way to achieve this (since Google searches are leading here):
var x = document.createElement("VIDEO");
if (x.canPlayType("video/mp4")) {
x.setAttribute("src","movie.mp4");
} else {
x.setAttribute("src","movie.ogg");
}
x.setAttribute("width", "320");
x.setAttribute("height", "240");
x.setAttribute("controls", "controls");
document.body.appendChild(x);
I found this SO post, but it is out of date: Play a local video from iPad in an HTML 5 webpage
With iOS 6 came the ability to access the camera roll for uploading a file (e.g., .mov files captured from iPad camera). I am not sure who to give credit to, but I found a jsFiddle that uses an input field to grab a local file and load it into the video element for playback. This works on the desktop accept for .mov files, but removing "video/*" from the accept attribute allows the input file to select a .mov from local, and forcing the file.type to "video/mp4" in the JS allows the .mov to play in the video element.
See jsFiddle referenced above: http://jsfiddle.net/dsbonev/cCCZ2/embedded/result,js,html,css/presentation/
However, when it comes to this working in mobile safari the file still fails to load, even though you see a preview thumbnail and file name in the file input field. I added a link to the page concatenating "?dl=1" to the blob: url, but clicking it just results in mSafari saying “invalid address” even though a link to a hosted .mov plays in quicktime. Ultimately, I want to be able to select a video from the camera roll, play it in an html video player, and (ideally) store the source path of that file in a db to be accessed at a later time. What piece am I missing?
See my edited version of the jsFiddle working here:
http://lt.umn.edu/email/
JS:
playSelectedFile = function playSelectedFileInit(event) {
var file = this.files[0];
//var type = file.type;
var type = "video/mp4";
var videoNode = document.querySelector('video');
var canPlay = videoNode.canPlayType(type);
canPlay = (canPlay === '' ? 'no' : canPlay);
var message = 'Can play type "' + type + '": ' + canPlay;
var isError = canPlay === 'no';
//displayMessage(message, isError);
if (isError) {
return;
}
var fileURL = URL.createObjectURL(file);
var tempURL = fileURL+'?dl=1';
var tempText = ''+tempURL+'?dl=1';
displayMessage(tempText, isError);
videoNode.src = fileURL;
}
Use var videoNode = document.querySelector('video')[0]; when using querySelector
EDIT:
Otherwise try to remove the video node and create it again with the right src. I had the same problem, that the movie wont play. I guess changing the src wont work everywhere..