With we have a mp4 file how can we create a base64 src from it using just javascript?
For example, if he have a mp4 file named example.mp4 located at /assets/video/example.mp4, how can extract the base64 data from it using Javascript to create a html tag like the example below?
<video id="video" width="740" controls>
<source type="video/mp4" src="data:video/mp4;base64,[VIDEO BASE64 DATA HERE]">
</video>
Instead of this:
<video id="video" width="740" controls>
<source type="video/mp4" src="/assets/video/example.mp4">
</video>
The motivation to do this is because I need to transfer a encrypted file (for example a video, or a image, etc.) from one place to another. So I need using Javascript, extract the data, encrypt it and then transfer. How can we do this?
This is probably an answer, but I didn't tested yet: (MooTools)
http://jsfiddle.net/eliseosoto/JHQnk/
<div>
<div>
<label for="filePicker">Choose or drag a file:</label><br>
<input type="file" id="filePicker">
</div>
<br>
<div>
<h1>Base64 encoded version</h1>
<textarea id="base64textarea" placeholder="Base64 will appear here" cols="50" rows="15"></textarea>
</div>
</div>
var handleFileSelect = function(evt) {
var files = evt.target.files;
var file = files[0];
if (files && file) {
var reader = new FileReader();
reader.onload = function(readerEvt) {
var binaryString = readerEvt.target.result;
document.getElementById("base64textarea").value = btoa(binaryString);
};
reader.readAsBinaryString(file);
}
};
if (window.File && window.FileReader && window.FileList && window.Blob) {
document.getElementById('filePicker').addEventListener('change', handleFileSelect, false);
} else {
alert('The File APIs are not fully supported in this browser.');
}
Have you been able to adapt that code so that it is not necessary for a user to give a file?
This is, to be able to encode like you initially wanted, by knowing the location of the file and do that automatically, without intervention from the user.
Related
I try to play local video file in html video tag, I use open dialog to choose file and get file's path. Then I put this path in src
export default function VideoContainer() {
const { videoUrl } = useTypeSelector(state => state.video);
console.log(videoUrl);
return (
<div className='VideoContainer'>
{videoUrl !== '' && (
<video className='VideoContainer__video' controls>
<source src={`custom-protocol://${videoUrl}`} type={`video/mp4`} />
</video>
)}
</div>
);
}
For cyrillic files it doesn't work. error with cyrillic
How can I fix this?
I use Electron.js, React.js, Redux.
This what i've tried:
export default function VideoContainer() {
const { videoUrl } = useTypeSelector(state => state.video);
const newStr = decodeURI(videoUrl);
console.log(newStr);
return (
<div className='VideoContainer'>
{videoUrl !== '' && (
<video className='VideoContainer__video' controls>
<source src={`custom-protocol://${newStr}`} type={`video/mp4`} />
</video>
)}
</div>
);
}
but this same error.
You can solve this issue by decoding the URI where you pass your videoURL string as function input.
In Javascript, you can do it like example below (research for same code result via: React / Electron / Redux)...
videoURL = ...some_Cyrillic_text_encoding_with_%_sign...
//# update the string with decoded version of itself
videoURL = decodeURI( videoURL ); //eg: gives шеллы as new URL
You can see it solves the same problem of text encoding shown in your picture:
Code snippet below is a simplified example of an offline HTML video player I'm trying to develop.
The user is able to choose a video file, then this video file content is read into video player so user can play it.
The problem here is that the method I'm reading the video file with causes large memory leakage with large video files.
I'm using readAsDataURL, this is catastrophic in case of big files (e.g. for a ~200MB video file I get ~600MB webpage memory usage).
So, my question is, what's the most efficient way to read a local video file selected by user into my HTML video player?
I need a way that doesn't cause memory leakage like readAsDataURL does.
I think a direction to solution may be something that chunks local video files where only needed slices are loaded/unloaded to/from memory as needed like what happens with online videos. Also, a method that enables to read the video content directly from local hard disk instead of loading it to memory first as DataURL will be helpful.
Function responsible for passing selected video file as src:
function videoUpdateSource(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function() {
var videoTagElement_Exists = document.getElementById("loaded_video");
!videoTagElement_Exists ? videoElementInitiate() : videoRemoveSources();
videoAppendNewSource(reader.result);
}
}
Full test snippet:
function videoElementInitiate() {
var videoElement = document.createElement('video');
videoElement.setAttribute('id', 'loaded_video');
videoElement.setAttribute('width', '480');
videoElement.setAttribute('height', '300');
videoElement.setAttribute('controls', '');
document.getElementById("video_container").appendChild(videoElement);
videoTag = document.getElementById('loaded_video');
}
function videoUpdateSource(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = function() {
var videoTagElement_Exists = document.getElementById("loaded_video");
!videoTagElement_Exists ? videoElementInitiate() : videoRemoveSources();
videoAppendNewSource(reader.result);
}
}
function videoRemoveSources() {
videoTag.pause();
var sourceElements = videoTag.getElementsByTagName('source');
for (var i = sourceElements.length - 1; i >= 0; --i) {
sourceElements[i].remove();
}
videoTag.removeAttribute('src');
}
function videoAppendNewSource(src) {
var source = document.createElement('source');
source.setAttribute('src', src);
videoTag.appendChild(source);
videoTag.load();
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<title>Offline Video Player</title>
</head>
<body>
<form>
<p>Select Video file in order to play</p>
<input type="file" id="fileElem" accept="video/*" onchange="videoUpdateSource(this.files[0])">
<label class="button" for="fileElem">Select video file</label>
</form>
<br/>
<div id='video_container'>
<!-- loaded video element to be placed here -->
</div>
</body>
</html>
Thanks to #AKX (comment) for suggesting a solution to use URL.createObjectURL instead of readAsDataURL.
Updating the function responsible for passing selected video file as src:
function videoUpdateSource(file) {
var url = URL.createObjectURL(file); // file is read as blob by default, check side note below.
var videoTagElement_Exists = document.getElementById("loaded_video");
!videoTagElement_Exists ? videoElementInitiate() : videoRemoveSources();
videoAppendNewSource(url);
}
Side Note:
A File object is a specific kind of a Blob, and can be used in any
context that a Blob can. In particular, FileReader,
URL.createObjectURL(), createImageBitmap(), and XMLHttpRequest.send()
accept both Blobs and Files.
Source
Now loading a 200MB or even 1GB video file results in ~60MB memory usage.
Updated code snippet:
function videoElementInitiate() {
var videoElement = document.createElement('video');
videoElement.setAttribute('id', 'loaded_video');
videoElement.setAttribute('width', '480');
videoElement.setAttribute('height', '300');
videoElement.setAttribute('controls', '');
document.getElementById("video_container").appendChild(videoElement);
videoTag = document.getElementById('loaded_video');
}
function videoUpdateSource(file) {
var url = URL.createObjectURL(file); // file is read as blob by default
var videoTagElement_Exists = document.getElementById("loaded_video");
!videoTagElement_Exists ? videoElementInitiate() : videoRemoveSources();
videoAppendNewSource(url);
}
function videoRemoveSources() {
videoTag.pause();
var sourceElements = videoTag.getElementsByTagName('source');
for (var i = sourceElements.length - 1; i >= 0; --i) {
sourceElements[i].remove();
}
videoTag.removeAttribute('src');
}
function videoAppendNewSource(src) {
var source = document.createElement('source');
source.setAttribute('src', src);
videoTag.appendChild(source);
videoTag.load();
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<title>Offline Video Player</title>
</head>
<body>
<form>
<p>Select Video file in order to play</p>
<input type="file" id="fileElem" accept="video/*" onchange="videoUpdateSource(this.files[0])">
<label class="button" for="fileElem">Select video file</label>
</form>
<br/>
<div id='video_container'>
<!-- loaded video element to be placed here -->
</div>
</body>
</html>
I made a tool which converts images to base64 data.
<input id="inp" type='file'><br>
<br>
<textarea readonly placeholder="Base64 data" id="b64"></textarea>
<br>
<img id="img">
<script>
function readFile() {
if (this.files && this.files[0]) {
var FR= new FileReader();
FR.addEventListener("load", function(e) {
document.getElementById("img").src = e.target.result;
document.getElementById("b64").innerHTML = e.target.result;
});
FR.readAsDataURL( this.files[0] );
}
}
window.addEventListener('paste', e => {
document.getElementById("inp").files = e.clipboardData.files;
});
document.getElementById("inp").addEventListener("change", readFile);
</script>
Image can be uploaded either by using <input id="inp" type='file'>, or by directly copying and pasting the image from clipboard onto the window.
Here is the problem; when image is uploaded through the usual <input>, it renders the base64 data within seconds, however when pasting the image from clipboard onto the window, the input seems to recognize the image as image.png but no data gets rendered. How can I solve this problem?
I'm using jasny bootstrap to include image uploads in my page. See http://jasny.github.io/bootstrap/javascript/#fileinput
My question: I want to save this image into a Javascript database like PouchDB - so I think my only option is to use Base64 (http://pouchdb.com/guides/attachments.html - I will be using webservices to copy this image to another website, so I think it has to be base64). But how can I convert the image to base64 string format?
HTML :
<input type='file' id="asd" />
<img id="img" src="" />
<div id="base"></div>
JS :
function readImage(input) {
if ( input.files && input.files[0] ) {
var FR= new FileReader();
FR.onload = function(e) {
$('#img').attr( "src", e.target.result );
$('#base').text( e.target.result );
};
FR.readAsDataURL( input.files[0] );
}
}
$("#asd").change(function(){
readImage( this );
});
You may also find blob-util to be useful. It has an imgSrcToBlob() method that takes an <img> src and converts it to an HTML5 Blob, and can also convert it to base64, binary string, ArrayBuffer, etc.
I'm using a regular HTML File Picker input form item to allow my users to select files. I'd like to show them a thumbnail of the file they selected as they will be required to select many images and it can get confusing.
Does anyone know if it's possible to display the image they selected without uploading it to the server? If so, how?
If someone can point me to a post or give me an idea of how I might do this it will be greatly appreciated.
<input type="file" name="image" accept="image/*">
<!-- Create an <img> element to preview the image -->
<img id="image-preview" width="320">
<!-- The <input> can go anywhere in your page or <form>. Note the "onchange" attribute -->
<input type="file" name="image" accept="image/*" onchange="handleFileChange">
Make sure the following JavaScript comes after the above <img> and <input> elements. You can put this in your .js file that is loaded at the end of the page or in a <script> element at the end of page.
// Select the preview image element
const imgElement = document.getElementById('image-preview');
function handleFileChange(e) {
// If no file was selected, empty the preview <img>
if(!e.target.files.length) return imgElement.src = '';
// Set the <img>'s src to a reference URL to the selected file
return imgElement.src = URL.createObjectURL(e.target.files.item(0))
}
This should get you started
http://jsfiddle.net/41go76g4/
Basically you read the file in with fileAPI in javascript and set the returned blob as the dataURL for an img tag.
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('fileInput').addEventListener('change', handleFileSelect, false);
ref: http://www.html5rocks.com/en/tutorials/file/dndfiles/