Videojs Download Button

Download button for videojs and Nuevo skins

Since version 6.3.14 Nuevo plugin features hidden option to show Download Button, by default set to false. However the button does not allow to download video file directly through javascript. By clicking the ebutton it fires downloadVideo event with 2 parameters passed: current source URL and video_id (if defined). This allows to use server-side language function and force download video, based on video URL or video_id. Using server-side language, it is possible to download video hosted on server, fetch video from other server, or even covert m3u8 source to mp4 online and offer it to download.

The browser does not allow to force download mp4 or webm video file from simple link. Instead, it opens a video player in new cart. Javascript cannot open and download from relative paths to media files. Javascript is client-side language, it cannot download or fetch video from server, cannot use tools like ffmpeg to combine media segments of an HLS or MPEG-DASH stream.
One of the methods to force a file download in javascript is to use XMLHttpRequest and generate blob file-like object. However, this is possible for files hosted on same server only. Also such method is fine for relatively small files, not for video files that filesize is usually many megabytes. It takes ages to create blob object for such files.

In the example above, we send downloadVideo event parameters to simple PHP file with a function to force video download immediately from our server.

To enable downloadButton, simply set nuevo plugin option donwloadButton to true.
Code snippet
<script>
var player = videojs('example_video_1');
  player.nuevo({ video_id:"v1234", donwloadButton:true })
</script>
And here's how you can catch downloadVideo event with current video source parameters. Depending on your preferences, you can send the video id or video url to server-side file with function to force video download.
Code snippet
<script>
  player.on('downloadVideo', function(event,data){
     video_url = data.source;
     video_id = data.id;
     //send file to server-side file with download function 
  });
</script>
You can't use AJAX to download files. When using the most popular PHP language, the most simple way is to open PHP file with data request.
Code snippet
<script>
window.location(download.php?url=video_url);
   or
window.location(download.php?video_id=video_id);
</script>
In PHP you can get video url or video id. If this is mp4/webm file stored on other than production server, you can use CURL to read and save the file.
Code snippet
<?php
  $video_url   = trim($_GET['url']);

  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Disposition: attachment; filename='.basename($file));
  header('Content-Transfer-Encoding: chunked'); 
  header('Expires: 0');
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Pragma: public');
  $stream = fopen('php://output', 'w');
  $ch = curl_init($file);
  curl_setopt($ch, CURLOPT_READFUNCTION, function($ch, $fd, $length) use ($stream) {
	return fwrite($stream, fread($fd, $length));
  });

?>
If this is a file hosted on the same server, you need to find the relative path to the video file on your server, based on source url or video id. Once you have video relative path, check if file exists and order to download it.
Code snippet
<?php
$video_url   = trim($_GET['url']);
$video_id   = trim($_GET['id']);

// your code to get relative file path of video, based on video url or based on video_id and information stored in database for example.
// the result store in $filepath variable

  if (file_exists($filepath) && is_file($filepath) && is_readable($filepath)) {
	ini_set('memory_limit', '-1');
	@ob_end_clean();
	if(ini_get('zlib.output_compression')) {
	   ini_set('zlib.output_compression', 'Off');
	}	    
	header('Content-Type: application/force-download');
	header('Content-Disposition: attachment; filename="'.basename($file).'"');
	header('Content-Transfer-Encoding: binary');
	header('Accept-Ranges: bytes');
	header('Cache-control: private');
	header('Pragma: private');
	header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
	header('Content-Length: ' .filesize($file));             
	readfile($file);
	exit();
   } 
   die();
?>
If the video source is m3u8 or mpd playlist file, server-side language like PHP allows to make use of ffmpeg to combine HLS .ts chunk files or HLS/DASH-MPEG fragmented file into mp4 file and offer it to download.

PHP code examples above are for illustrative purposes only. User or User's company must adopt it, or write own donwload function according to his server settings, file storage system, database, etc. PHP is not the only option to prepare download function, though certainly it's the most popular server-side language.