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 downloadButton to true.
Code snippet
<script> var player = videojs('example_video_1'); player.nuevo({ video_id:"v1234", downloadButton:true }) </script>
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>
Code snippet
<script> window.location(download.php?url=video_url); or window.location(download.php?video_id=video_id); </script>
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)); }); ?>
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(); ?>
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.