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!

Edited by AdrianHoffman
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.