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.
Related
I have an application that loads an audio clip into an audio tag dynamically at runtime. It does this by converting the audio to a base64 data-url and assigning that to the tag's src attribute.
The issue is that the audio tag does not process the data until after the audio clip has been fully played through once. This issue shows up on the tag as (1) a lack of audio length, (2) a disabled time-scrubber and (3) the 3-dot icon not displaying. These features do appear as soon as the audio clip has been played for the first time.
I need a way to get the audio tag to process the audio clip as soon as it has been assigned. The user needs to be able to download the audio and fastforward with the time-scrubber without being forced to play through the entire audio clip.
I've searched extensively for a solution to this. I've tried audioTag.preload = "auto"; and calling audioTag.load(); after assigning the src. I've also let it sit for 15 minutes, in case it was just slow to load.
I am open to an alternative to using a base64 data-url formatting, if it will allow me to bypass this issue.
Thanks for any help you can provide.
EDIT: I see this issue in Chrome 80 and Firefox 75.
EDIT:
I am generating an audio clip and assigning it to the audio tag in two ways: (1) from a 'file' input tag (2) from a MediaRecorder (connected to the web audio api).
Here is the 'file' input tag loading:
const reader = new FileReader();
reader.onload = () =>
{
const audioTag = document.getElementById("audioTag");
audioTag.preload = "auto";
audioTag.src = reader.result;
audioTag.load();
};
reader.readAsDataURL(fileInputTag.files[0]);
Here is the MediaRecorder loading:
mediaRecorder.onstop = () =>
{
const blob = new Blob(audioChunks, {type : "audio/wav"});
let reader = new FileReader();
reader.onload = () =>
{
let audioTag = document.getElementById("rec");
audioTag.preload = "auto";
audioTag.src = reader.result;
audioTag.load();
};
reader.readAsDataURL(blob);
};
I've just determined that opening a wav file created with audacity works fine. The issue only shows when opening an audio file saved from the MediaRecorder.
I've determined that MediaRecorder is actually producing 'webM/opus' files rather than 'wav' files. Research strongly suggests that 'webM' is the only recording option available for MediaRecorder on chrome (firefox also allows 'ogg'). No 'wav' file support.
I'm going to post a "solution" now.
I've determined that this issue involves my use of MediaRecorder to generate the audio clips and then to save the audio clips to files. The audio is actually in 'webm/opus' format. MediaRecorder doesn't support 'wav' or 'ogg' (at least in chrome). Moreoever, the clips created by MediaRecorder are not seekable and can only be scrubbed or downloaded once they are played through completely at least once, as discussed in this chromium bug.
I will be looking for an alternative way to record audio as MediaRecorder is currently insufficient for my needs due to (1) clip unseekability (2) format incompatibility.
Would anyone be able to point me in the right direction, I'm trying to write a small application for a web-site, where by the user can choose either an image, or choose to capture an image with their phone camera.
We can then display (preview) the image to them, and they can confirm it and carry on, or restart and take the image again.
I've found a few ways to do this using jQuery, which seemed to work well on a computer, However on a phone (tested using a Samsung S5 running the latest chrome) i frequently receive error messages saying that the previous operation could not be completed due to low memory.
Here is an example of the current code i'm using, this is stripped down somewhat just to show a basic example, but you can see the method doesn't seem very efficient:
$(function() {
$("#prev-img-file").on("change", function()
{
var files = !!this.files ? this.files : [];
if (!files.length || !window.FileReader) return; // no file selected, or no FileReader support
if (/^image/.test( files[0].type)){ // only image file
var reader = new FileReader(); // instance of the FileReader
reader.readAsDataURL(files[0]); // read the local file
reader.onloadend = function(){ // set image data as background of div
$(".up-pic-preview").css("background-image", "url("+this.result+")");
}
}
});
});
http://jsfiddle.net/fish_r/vnu7661c/
Would anyone know of anything that doesn't hog as much resources?
Thanks!
Try WebcamJS.
One of the demo pages - test it on my android 4.4 phone minute ago - works fine :-)
This library allows you to:
display preview;
capture image;
upload captured image to server;
fallback to flash if HTML5 getUserMedia() is not supported;
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..
I have a problem with my little project.
Every time the music player is loading new songs into playlist or you are pressing a song on the list to get it playing, it's using a lot of memory, and it stays high until you shut it down. I think its every time I'm using the filereader API that it uses memory, but I'm also loading ID3 information with the jDataView.js script which I also think is taking a lot of memory.
Do you guys have any suggestion, to load,store and play songs with the FileReader, without taking up memory? I've tried to see if it was possible to clear the fileReader after using, but I couldn't find anything. I've only tested in Chrome.
UPDATE:
I have tested my project,and found out, that its when im trying to load the datastring it takes up memory.
reader.onloadend = function(evt) {
if(typeof(e) != "undefined"){
e.pause();
}
e = new Audio();
e.src = evt.target.result; // evt.target.result call takes the memory
e.setAttribute("type", songs[index]["file"].type);
e.play();
e.addEventListener("ended", function() { LoadAudioFile(index + 1) }, false);
};
Is there another way to load the data into the audio element?
This is not because of FileReader but because you are making the src attribute of audio element a 1.33 * mp3filesize string. So instead of the src attribute being a nice short url pointing to a mp3 resource, it's the whole mp3 file in base64 encoding. It's a wonder your browser didn't crash.
You should not read the file with FileReader at all, but create a blob URL from the file and use that as src.
var url = window.URL || window.webkitURL;
//Src will be like "blob:http%3A//stackoverflow.com/d13eb575-4863-4f86-8727-6400119f4afc"
//A very short string that is pointing to the original resource in hard drive
var src = url.createObjectURL( mp3filereference );
audioElement.src = src;