Videojs Download Button

Download video button

Nuevo plugin features an option to show media Download Button, by default set to false. However the button does not allow to download video file directly through javascript. By clicking the button 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 the 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 a 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 a number of megabytes. It takes ages to create blob object for such files.

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

To enable downloadButton, simply enable approptiate Nuevo plugin's option.
Code snippet
<script>
var player = videojs('example_video_1');
player.nuevo({ video_id:"v1234", downloadButton: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 script you can get video url or video id. If this is mp4 or 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 tool 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 download 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.