101

I want to achieve the following.

<video src="file:///Users/username/folder/video.webm">
</video>

The intent is that the user will be able to select a file from his/her hard drive.

And the reason for not uploading is of course transmission costs and storage quota. There will be no reason to save the file.

Is it possible?

Chris
  • 2,572
  • 4
  • 21
  • 19
  • It definitely won't work with a file input. It may work with HTML5 ondrop, but I don't think you can leverage that for a file upload. Your best bet would probably be to do a Chrome extension. – Brian Nickel Jan 16 '12 at 21:37

4 Answers4

268

It is possible to play a local video file.

<input type="file" accept="video/*"/>
<video controls autoplay></video>

When a file is selected via the input element:

  1. 'change' event is fired
  2. Get the first File object from the input.files FileList
  3. Make an object URL that points to the File object
  4. Set the object URL to the video.src property
  5. Lean back and watch :)

http://jsfiddle.net/dsbonev/cCCZ2/embedded/result,js,html,css/

(function localFileVideoPlayer() {
  'use strict'
  var URL = window.URL || window.webkitURL
  var displayMessage = function(message, isError) {
    var element = document.querySelector('#message')
    element.innerHTML = message
    element.className = isError ? 'error' : 'info'
  }
  var playSelectedFile = function(event) {
    var file = this.files[0]
    var type = file.type
    var videoNode = document.querySelector('video')
    var canPlay = videoNode.canPlayType(type)
    if (canPlay === '') canPlay = 'no'
    var message = 'Can play type "' + type + '": ' + canPlay
    var isError = canPlay === 'no'
    displayMessage(message, isError)

    if (isError) {
      return
    }

    var fileURL = URL.createObjectURL(file)
    videoNode.src = fileURL
  }
  var inputNode = document.querySelector('input')
  inputNode.addEventListener('change', playSelectedFile, false)
})()
video,
input {
  display: block;
}

input {
  width: 100%;
}

.info {
  background-color: aqua;
}

.error {
  background-color: red;
  color: white;
}
<h1>HTML5 local video file player example</h1>
<div id="message"></div>
<input type="file" accept="video/*" />
<video controls autoplay></video>
dota2pro
  • 7,220
  • 7
  • 44
  • 79
Dimitar Bonev
  • 3,326
  • 1
  • 15
  • 16
  • This works for me in chrome on a mac. Doesn't work with safari 6.1 – Patrick Cullen Nov 01 '13 at 16:19
  • 1
    Looks like there are known problems with safari: http://stackoverflow.com/questions/19088400/safari-unable-to-dynamically-load-video-from-blob-url and https://bugs.webkit.org/show_bug.cgi?id=101671 – Patrick Cullen Nov 03 '13 at 23:33
  • Excellent solution, it also works on Chrome for Windows. – J.T. Taylor Mar 12 '14 at 16:49
  • Has anyone done the work to page in and out appropriate chunks of video so as not to kill browser memory for large videos? – Eric Bloch Oct 20 '14 at 23:38
  • Unable to preview .mov or .avi files Asked the question here : http://stackoverflow.com/questions/32599806/preview-videos-in-html5-of-type-mov – mpsbhat Sep 16 '15 at 05:10
  • How to do it through jQuery ? – Sachi-17 Oct 09 '15 at 06:09
  • You won the internet ! – Sujal Mandal Nov 15 '15 at 11:11
  • 1
    This is excellent..i wish i could up vote this 100 times more for not using jQuery – BoundForGlory Feb 28 '16 at 02:50
  • Best Best answer. like – Milad Ghiravani Jul 01 '17 at 16:02
  • An answer style note: even if very useful, I tend to not like answers that are not self contained with actual code when the amount of code necessary is low as in this case. That is what is preventing me from upvoting now. – ceztko Mar 22 '19 at 17:36
  • Works on Safari (Mac) as well – Ronen Rabinovici Dec 31 '20 at 17:49
  • There's just one aspect of this code that I'm struggling to find info on; and that is `window.URL`. If I log it to the console in firefox it returns a function. If I log it to the console in chrome it returns `{native code}` which as far as I can make out is code that 'talks' directly to the processor (CPU). Can anyone else add additional insight to this window object/property? – Fishbite Sep 14 '22 at 10:42
15

That will be possible only if the HTML file is also loaded with the file protocol from the local user's harddisk.

If the HTML page is served by HTTP from a server, you can't access any local files by specifying them in a src attribute with the file:// protocol as that would mean you could access any file on the users computer without the user knowing which would be a huge security risk.

As Dimitar Bonev said, you can access a file if the user selects it using a file selector on their own. Without that step, it's forbidden by all browsers for good reasons. Thus, while his answer might prove useful for many people, it loosens the requirement from the code in the original question.

Holger Just
  • 52,918
  • 14
  • 115
  • 123
  • Dimitrov Bonev's solution shows this solution to be incorrect--you can access local files through input type=file. – J.T. Taylor Mar 12 '14 at 16:48
  • 2
    Well, his solution only works if you let the user select the file first. You still can't name the path to the file in the HTML source (as stated in the question) and access it that way. Thus, his solution is technically for another question. – Holger Just Mar 12 '14 at 17:00
  • vlc player also can play any file on the computer, but so there is also a security risk. It can download files from our hard disk to their servers without us noticing if they want to, can't they? So why there is no security risk then? At worst case they user could be allowed to accept manually if he allows browser to play the file. Because there are situations where user trust 100% the page, because users are the ones who work in same company as web creators. – Dariux Mar 12 '15 at 13:51
  • @holger Yes, I was struggling to find this very solution for my own application and for the very same reasons as the OP. Perhaps the main problem was that I was looking for a way to get hold of the path to the file, which you can't. Perhaps what I should have been looking for was "How do I point my application to a file that the user has selected?" I think the OP's question was phrased well enough to this end, this blinkered peoples thoughts though: ` – Fishbite Sep 14 '22 at 10:55
6

Ran in to this problem a while ago. Website couldn't access video file on local PC due to security settings (understandable really) ONLY way I could get around it was to run a webserver on the local PC (server2Go) and all references to the video file from the web were to the localhost/video.mp4

<div id="videoDiv">
     <video id="video" src="http://127.0.0.1:4001/videos/<?php $videoFileName?>" width="70%" controls>
    </div>
<!--End videoDiv-->

Not an ideal solution but worked for me.

jcoshea
  • 182
  • 1
  • 6
  • 2
    If you copy the file to a cache location and set the path of the video source to it, it will play. Copy file to context.getExternalCacheDir().getAbsolutePath(). Works for me. – Derek Wade Jul 01 '14 at 22:41
  • also can do with any web server in users computer like apache or mongoose – Dariux Mar 13 '15 at 13:07
5

I tried to simplify the answer of Dimitar Bonev as much as I could.

<html>
<head>
<title>HTML5 local video file player example</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<h1>HTML5 local video file player example</h1>
<input type="file" accept="video/*"><br>
<video controls></video>
<script type="text/javascript">
 (function localFileVideoPlayer() {
   'use strict'
   var playSelectedFile = function(event) {
   var file = this.files[0]
   var URL = window.URL || window.webkitURL 
   var fileURL = URL.createObjectURL(file)
   var videoNode = document.querySelector('video')
   videoNode.src = fileURL
   }
  var inputNode = document.querySelector('input')
  inputNode.addEventListener('change', playSelectedFile, false)
 })()
</script>
<p>I hereby signed confess solemnly that I have no idea what this code does. But it now works. 
<p>Firefox Lubuntu 18.03
<p>Simplified: `http://jsfiddle.net/dsbonev/cCCZ2/` `https://stackoverflow.com/users/691308/dimitar-bonev`
</body>
</html>
halfer
  • 19,824
  • 17
  • 99
  • 186
xerostomus
  • 466
  • 4
  • 11
  • Dude, i f*** love you. This is awesome! Works great as a trick to play local flights wich Chromecast (if your browser supports casting). – eltbus May 27 '21 at 20:33
  • I am happy to help. :-) The fact is that it is a crazy piece of a code. – xerostomus May 29 '21 at 04:54
  • Xerostomus, [the community has agreed](https://meta.stackoverflow.com/questions/295810/do-we-allow-religious-invocations-in-questions-answers) that religious proselytisation does not belong in Stack Overflow posts. If you wish to present theistic material here, you can do it on your external website (best) or in your Stack Overflow profile (a wide leeway is given for self-expression here). – halfer Jul 17 '21 at 21:58
  • 2
    Ok, I understand you want to avoid useless quarrels about religion. But anyway I hope I can (privately) thanks God that this crazy piece of code works, don't I? :-) – xerostomus Jul 19 '21 at 06:01