How to preview a video upload in react-player? - javascript

I have an input of type file which allows my users to upload video files which will be of type File. In my application there also exists the react-player component which takes a URL prop that can be of type array or MediaStream according to its documentation. having done some research I found the following way to convert the File to a URL to be compatible with the react-player however it is depreciated so I do not wish to use it.
URL.createObjectURL(file)
This returns a URL for a blob or file object. I see that this has been replaced with passing a MediaStream to video.srcObject() but I am unaware how to convert a File to type MediaStream and srcObject() seems like a hacky way to access react-player which exposes its URL for the same purpose and also takes a MediaStream. To summarise how do I get a video uploaded with a file type input to be previewed in a react-player component?

Turns out URL.createObjectURL() is only depreciated for MediaStreams and you can therefore go ahead and use it for Blobs and File types.

Related

Load m3u8 video file as Blob with different orign

I'm attempting to stream video using a Blob URL created from an m3u8 URL.
The m3u8 file contains only relative paths.
E.g.
file1.ts
file2.ts
...
The m3u8 file is stored on a separate host (e.g. the URL is fileserver.com/path/thevideo.m3u8) than the website loading the video (e.g. the URL is website.com).
Therefore, after converting the m3u8 URL to a Blob, the video player subsequently looks for:
website.com/file1.ts
website.com/file2.ts
Whereas, the actual URLs are:
fileserver.com/path/file1.ts
fileserver.com/path/file2.ts
Question is, is there any way to get the video player (I'm using VideoJS) to use the correct URL prefix?
The code I used for Blob URL generation is here: set video objects source file to a blob url
I can confirm that it works if the m3u8 file contains the full *.ts URLs instead of the relative paths, but I want to see if this is possible using only the relative path as that would be more convenient.
You can attach a custom handler for requests made by videojs/http-streaming engine.
player.tech().vhs.xhr.beforeRequest = function(options) {
options.uri = options.uri.replace('example.com', 'foo.com');
return options;
};
Note: You should make a check with safari hls playback if you're using overrideNative option.

Ionic - Read file from URI

Users of my application can select and crop images using Ionic Native - Crop. After they have cropped their image, I will have the URI of that image such as:
file:///storage/emulated/0/Android/data/com.myApp/cache/1535369478970-cropped.jpg?1535369482232
I want to use Ionic's File API, since it has a method readAsDataURL(path, file) which will convert the file to a base64 encoded data url, which is what I exactly need.
However, how would I properly separate the path and file from the URI of the file I have above so that readAsDataURL(path, file) is satisfied?
I also do not know what these numbers behind the .jpg?1535369482232 mean and I do not know what the name of the file would be or if it has a different directory on iOS since the URI above is provided from a test using Android Emulator.
P.S. I have tried calling the method with just the path above and no file name passed as second argument, but got the following error:
{"code":13,"message":"input is not a directory"}
How can I achieve the result I want for both iOS and Android file paths?
Your path refers 'cacheDirectory' this.file.cacheDirectory.
To get the file name.
const pathsplit = "file:///storage/emulated/0/Android/data/com.myApp/cache/1535369478970-cropped.jpg".split('/');
filename = pathsplit[pathsplit.length-1];

Youtube Blob urls don't work in browsers but in src

I know that there are no blob urls only objects.
I made my own blob object for a video buffer and then I used it in a src of video tag which is something like blob://website.com/blablobbla . I opened this url in the browser it worked
when I opened the url of youtube video src (blob url) into a new tab it did't work but mine video src (blob url) worked
I want to know how can I do the same with my blob urls so that they only work in the src of the html video tag and give error or don't work in the external tab/window of the browsers.I just want to know the technology behind this and blob objects and their url properties.
The question seems somewhat vague to me, so here is what I interpret (also from the code in the fiddle-images in your question):
you receive a Blob (image's binary data) through a XMLHttpRequest() GET-request (responseType = 'blob')
you create a Blob URL with URL.createObjectURL() in the URL Store for XMLHttpRequest() response-object (the Blob holding the binary data)
you set the resulting Blob URL-string as src for a image (and append the image to the document, thereby showing the image you just downloaded)
You "don't want it to work in new tab" ("it" being the Blob URL-string I assume).
In your comments you say:
In fiddle I inspected the image and copied the src and then pasted it in new tab and it worked and showed the image I don't want the image to be shown directly with the blob url.
If you go to youtube and open the src of video in new tab : It will not work,, I want this to happen
It appears to me that you do not want the user to be able to view/download the blob when they copy the Blob URL-string (by examining the live source or simply right-click-on-image>>Copy Imagelocation) and paste it into a new tab/window (for which you give youtube as an example).
But you are also talking about video's.
TL;DR: It seems your question/bounty might be mixing up 2 different types of URL returned by window.URL.createObjectURL();:
Blob URL referencing (objects that represent) 'raw local data' (like (Local-)File, Blob, etc.)
For these you want to automatically (or programmatically) revoke the Blob URL from the browser's URL Store (which you could consider a simplified local webserver inside the browser, only available to that browser).
var myBlobURL=window.URL.createObjectURL(object, flag_oneTimeOnly);
returns a re-usable Blob URL which can be revoked with: window.URL.revokeObjectURL(myBlobURL) (adds the Blob URL string to the Revocation List).
Note: there used to be a second argument flag_oneTimeOnly which used to revoke the Blob URL automatically after it's first use, but that is currently no longer part of the spec! Also this flag often didn't work anyway (at least in firefox).
var myBlobURL=window.URL.createFor(object);
returns a Blob URL that is automatically revoked after it's first use.
Note: quite some browsers were 'late' to implement this one.
MediaSource object URL referencing a special MediaSource Object
These URL's are
only intended to link src of a HTMLMediaElement (think <audo> & <video> elements) to the special MediaSource Object
Note: a new tab/window is not an HTMLMediaElement
already automatically revoked
Note: even though they are created through window.URL.createObjectURL();
Here's what's happening for the fiddle in your question's image and similar code that downloaded a video as Blob (where you downloaded the whole video-file's data/binary on the server using an xhr) or any other 'local' data:
You are essentially using the 'bare' 'un-enhanced' File-API.
The URL Store is only maintained during a session (so it will survive a page-refresh, since it is still the same session) and lost when the document is unloaded.
So, if your fiddle is still open, then fiddle-document (the document that created the Blob URL) is obviously not yet unloaded, and therefore it's Blob URLs are available to the browser (any tab/window) as long as it is not revoked!
This is a relevant feature: you can build/download/modify a Blob in the browser, create a Blob URL and set it as href to a file-download link (which the user can right-click and open in a new tab/window!!)
Close the fiddle or revoke the Blob URL from the URL Store and the Blob URL is no longer accessible (also not in a different tab/window).
Try yourself with your modified fiddle: https://jsfiddle.net/7cyoozwv/
In this fiddle it should now no longer be possible to load your sample image into a different tab/window after you copied the image url (once the image is displayed in your page).
Here I revoked the URL manually (revokeObjectURL()) as it is currently the best cross-browser method (partially due to the api not yet fully being stabilized).
Also note: an element's onload event can be an elegant place to revoke your Blob URL.
Here is what's happening to an <audio> or <video> source linked to an MediaSource Object using an MediaSource object URL returned by window.URL.createObjectURL(MediaSource):
The Media Source Extensions (MSE) also extend the File-API's window.URL.createObjectURL() to accept a MediaSource Object. The (current draft of the) URL Object Extension specifies that:
This algorithm is intended to mirror the behavior of the createObjectURL()[FILE-API] method with autoRevoke set to true.
Note that the current spec of the File API's window.URL.createObjectURL() no longer has an autoRevoke (or flag_oneTimeOnly) boolean flag accessible to the programmer who should be using window.URL.createFor() for this purpose instead. I wonder when the Media-Source spec will mimic that (and for backward compatibility alias their createObjectURL() to a new createFor() extension (seems more appropriate as that is how it seems to be intended to work currently)).
These resulting automatically revoked URL-strings are only intended to link the src of a HTMLMediaElement (think <audo> & <video> elements) to the special MediaSource Object.
I don't think that an empty Document (from a new tab/window) is a <audo> or <video> element.
Perhaps "A quick tutorial on MSE"(source: MSDN) might help clarify the difference and basic use:
To use the MSE API, follow these steps:
Define an HTML5 video element in the HTML section of a page.
Create a MediaSource object in JavaScript.
Create a virtual URL using createObjectURL with the MediaSource object as the source.
Assign the virtual URL to the video element's src property.
Create a SourceBuffer using addSourceBuffer, with the mime type of the video you're adding.
Get the video initialization segment from the media file online and add it to the SourceBuffer with appendBuffer.
Get the segments of video data from the media file, append them to the SourceBuffer with appendBuffer.
Call the play method on the video element.
Repeat step 7 until done.
Clean up.
You (or a big-time player like youtube who will dynamically select supported technologies for playback on the client's platform (so there is no way to tell for sure what kind of youtube video URL's you are talking about)) could be using the new special MediaSource Object to play video's (or audio).
This adds buffer-based source options to HTML5 video for streaming support (compared to to downloading a complete video file before playing or use an add-on like Silverlight or Adobe Flash to stream media).
Hope this is what you were after!
Actually, the URL that you're referring is just a "string" reference to the BLOB itself (which is created using the function window.URL.createObjectURL); So, that you can use it like a normal URL. And, the scope is also only until the document is unloaded.
So, I don't think it is possible for you to open the URL just using browser. And also I tried to re-create what you're saying but with no avail (in my own website, create a blob and put the URL into browser).
Below is the code
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://kurrik.github.io/hackathons/static/img/sample-128.png");
xhr.responseType = "blob";
xhr.onload = function response(e) {
var urlCreator = window.URL || window.webkitURL;
var imageUrl = urlCreator.createObjectURL(this.response);
console.log(imageUrl);
var imgDOM = document.createElement("img");
imgDOM.src = imageUrl;
document.getElementById("divImage").appendChild(imgDOM);
};
xhr.send();
The fiddle here
Update :
Ok, after I looked at it. seems like youtube is using media-source to stream the video.
I haven't updated the fiddle (cannot found a video that I can use). But, basically, It still using the same function (createObjectURL) to create the blob URL. But, instead of using the source (image, video, etc) to pass to the function. You should pass the MediaSource object into the function.
And then, you use the blob URL and pass it into the video.src. Therefore, when you try to open the blob link. You should not be able to see the video again.

How do I determine whether a file is an image, regardless of extension, in javascript?

I am using the m0xie File Api polyfill library and would like to know if a file is actually an image before calling image.load() as it seems that in these cases the onerror event isn't always trigged.
the File API (see "Using files from web applications") is your only way if you really don't want to use file extensions. Each File instance has a type property which contains the mime type.

FakePath issue in Chrome browser

I am making a browser based audio player. So for making a playlist from the local directory I am using :
<input type="file" id="getFile" />
Then I am using a button to confirm the playlist.On clicking the button I am calling a javascript function to change the src of the audio tag to play the new audio file selected in the playlist. I want the exact path of the file from the input file to run in the HTML5 audio player but it starts taking the path as C://Fakepath/filename.mp3. Can someone help me with this.
This is a security feature, by design. You should not be able to read the original file path of a file input into a browser form. File input is for reading file contents only, not metadata like path on the user's file system.
The good news is that you don't need the original file path. You can use FileReader's readAsDataURL to convert the file contents into a base64-encoded data URL and use that as the audio src. To read from #myUploadInput and output through #myAudioElement (also available as a working fiddle):
var reader = new FileReader();
reader.onload = function (event) {
document.getElementById("myAudioElement").src = event.target.result;
};
reader.readAsDataURL(document.getElementById("myUploadInput").files[0]);
if the user is 'building' / creating the playlist based on files they have locally you could do a 'browse' field (s) where they select the local audio files, then take the contents of the field (that Should include the paths to those images), build an array of the count/id, filename.mp3, and path... then, based on what is 'chosen' to play, just reassemble the full local path and play that file.
that would be an approach I would take anyway to see if it would work. the necessary piece here is getting the user to disclose the paths to the audio files... but Im still not 100% sure it would work given the security feature that the earlier commenter posted a link to.
if this were included in an application the user approved for local installation you could just refer to it using the 'application directory' and copy the file to that 'safe location' but since its web based it just really opens up a whole can of worms in terms of a potentially unapproved / authorized web function knowing your local directory structure. good luck, let me know if you find a solution.

Categories

Resources