Jump to content

Stream mp4 files to html5 <video>


AdrianHoffman

Recommended Posts

Evening Everyone,

Been working on this problem for a couple of days and I am stumped.  I have a single php file to handle download and streaming of files.  It works great with music files, I can download and stream to an <audio> html 5 element just fine.  When it comes to my movies, I can download fine but it fails on streaming to a <video> html 5 element.  I have done some logging and it looks like after a very short time it just quits.

 

log when streaming music:

/path/to/music/124 - Mouth Techno -1.mp3
size: 1508731
ctype: audio/mpeg
range: 0-1508730/1508731
write chunk: 8192-1508731
write chunk: 16384-1508731
....
write chunk: 1507328-1508731
write chunk: 1515520-1508731
completed

log when streaming movie - this is the complete output, it just stops:

Log Started
/path/to/movies/AVP_REQUIEM_UNRATED.Title1.DVDRip.mp4
size: 889628920
ctype: video/mp4
range: 0-889628919/889628920
write chunk: 8192-889628920
write chunk: 16384-889628920
write chunk: 24576-889628920
write chunk: 32768-889628920
write chunk: 40960-889628920
write chunk: 49152-889628920
write chunk: 57344-889628920
write chunk: 65536-889628920

Here is how I am downloading and streaming the files.  Music files work just fine with <audio>, movie files I can only download but want to stream with <video>.  This is a hack from multiple sources on the net.

<?php 

// sanitize the file request, keep just the name and extension
$filename = $filefix = str_replace('%20', ' ', $_GET["name"]);
$file_path  = $filename;
$path_parts = pathinfo($file_path);
$file_dir   = $path_parts['dirname'];
$file_name  = $path_parts['basename'];
$file_ext   = $path_parts['extension'];
$path_default = "/path/to/music/";
$path_types = array(
      "mp3" => "/path/to/music/",
      "mpg" => "/path/to/movies/",
      "avi" => "/path/to/movies/",
      "mp4" => "/path/to/movies/",
);
$path = isset($path_types[$file_ext]) ? $path_types[$file_ext] : $path_default;
$file_path  = "$path"."$filename";

clearLog();
startLog();
writeLog("$file_path\n");

// allow a file to be streamed instead of sent as an attachment
$is_attachment = isset($_GET["play"]) ? false : true;

// make sure the file exists
if (is_file("$file_path")){
	$file_size  = filesize($file_path);
	$file = @fopen($file_path,"rb");

	writeLog("size: $file_size\n");
	
	if ($file){
 		header("Expires: -1");
		header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
     	
     	// set appropriate headers for attachment or streamed file
     	if ($is_attachment){
                header("Content-Disposition: attachment; filename=\"$file_name\"");
     	}else{
                header('Content-Disposition: inline;');
 		}
 		
 		// set the mime type based on extension.
          $ctype_default = "application/octet-stream";
          $content_types = array(
                "exe" => "application/octet-stream",
                "zip" => "application/zip",
                "mp3" => "audio/mpeg",
                "mpg" => "video/mpeg",
                "avi" => "video/x-msvideo",
                "mp4" => "video/mp4",
          );
          $ctype = isset($content_types[$file_ext]) ? $content_types[$file_ext] : $ctype_default;
          header("Content-Type: " . $ctype);
          
          writeLog("ctype: $ctype\n");
		 
		$end   = ($file_size - 1);
		$start = 0;
 
	 	header("Content-Length: $file_size");
		header('Accept-Ranges: bytes');
		header("Content-Range: bytes $start-$end/$file_size");
		
		writeLog("range: $start-$end/$file_size\n");
		$a=0;
		
		while(!feof($file)) {
			$chunk = (1024*;
			echo fread($file, $chunk);
			//ob_flush();
			flush();
			
			$a=$a+$chunk;
			writeLog("write chunk: $a-$file_size\n");

			if (connection_status()!=0){
				writeLog("failed\n");

				fclose($file);
				exit;
			}			
		}
 		
 		
		// file save was a success
		writeLog("completed\n");
		fclose($file);

		exit;
	}else{
		// file couldn't be opened
		header("HTTP/1.0 500 Internal Server Error");
		exit;
	}
}else{
	// file does not exist
	header("HTTP/1.0 404 Not Found");
	exit;
}

function startLog(){
	$myfile = fopen("newfile.txt", "w");
	fwrite($myfile, "Log Started\n");
	fclose($myfile);
}
function writeLog($pstr) {
	$myfile = fopen("newfile.txt", "a");
	fwrite($myfile, $pstr);
	fclose($myfile);
}
function clearLog() {
	//fclose("newfile.txt");
	unlink("newfile.txt");
}

?>

incase it helps, code calling download.php

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="movies.css">
</head>
<body>

<a href="javascript:history.back()"><img src="pics/back.png" style=\"height:50px; width=50px;\"/></a>
<a href="index.html"><img src="pics/home.png" style="height:50px; width=50px;display: in-line;"/></a>
<div id="searchContainer" style="height: 40px; width = 700px; display: block; padding: 10px;">
      <input type="text" id="SearchString" placeholder="Enter Search Address" style="vertical-align: top;padding: 10px;" class="valid">
      <button name="btnSearch" id="btnSearch" type="button"></button> 
</div>
<div id="Mainbox" >
<div id="ItemList">
<ol id="List">


<?php


$dir = '/path/to/movies/';
$dirlist = array_diff(scandir($dir), array('..', '.','Thumbs.db'));
asort($dirlist);
$a=0;
foreach ($dirlist as $file) {
	$size = round(filesize('/path/to/movies/'.$file)/1048576);
	$filefix = str_replace(' ', '%20', $file);
	echo "<li><div class=\"item\" id=\"$a\">";
	//title
	echo "<div id=\"title\">$file</div>";
	echo "<div id=\"mb\">$size MB</div>";
	echo "<div id=\"dl\"><a href=\"download.php?name=$filefix\"><img src=\"pics/download.png\" style=\"height:25px; width=25px;\"/></a></div>";
	if ($size < 1500){		
		$url = 'download.php?name='.$filefix.'&play=true';
		echo "<div id=\"play\" data-value=\"$url\"><a href=\"javascript:void(0)\" onClick=\"updateSource(this);\"><img src=\"pics/play.png\" style=\"height:25px; width=25px;\"/></a></div>";
	}
	echo "</div></li>";
	$a++;
}


?>

</ol>
</div>
</div>
<div id="videocontainer">
<video id="video" controls>
  <source id="mp4movie" type="video/mp4">
  <source src="movie.ogg" type="video/ogg" codecs="avc1.64001E, mp4a.40.2">
Your browser does not support the video tag.
</video>
</div>

<script type="text/javascript">
function updateSource(element) { 
	var dvalue = element.parentElement.getAttribute('data-value');
	var video = document.getElementById('video');
	var source = document.getElementById('mp4movie');
     source.src=dvalue;
	video.load(); //call this to just preload the audio without playing
	video.play(); //call this to play the song right away
}

</script>
</body>
</html>

Thanks for any help!

Link to comment
https://forums.phpfreaks.com/topic/291323-stream-mp4-files-to-html5/
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.