Playing mp4 files from rar or zip files - php

I have one problem. I would like to order from (zip) files play video in such a way to get out connection so you can include it in HTML5 badge. As I gave an example. But this not working.
<?php $video = fopen('zip://video.zip#video.mp4', 'r'); ?>
<video>
<source src='<? echo $video; ?>' type='video/mp4' />
</video>

$video in the above code is just a server-side file handle you could use to read the file from the zip. It's not directly usable for the browser.
You'll need to handle reading the file and returning it in a separate HTTP request. Usually you'd use a second script for this. (Or if your video is relatively small, you might be able to use data urls, but it's not something I'd try to do.) Additionally, if you want to allow for byte range requests, you'd have to handle that yourself in your video serving logic.
Here's a fairly simple scenario:
My videos.zip file contains a couple of different videos, and I want to retrieve a specific one and show it on a page called video.php
First I have my viewer, say video.php, [edit: containing the video tag and with a URL to my second script as the source. Since I might want to serve the other file at some point, I set it up to accept a filename in the v query parameter.]
..some html/php..
<video>
<source src='zipserve.php?v=itsrainintoast.mp4' type='video/mp4' />
</video>
..more html/php..
Then, in zipserve.php I have something like this:
$filename = $_GET['v']; //You probably want to check that this exists first, btw.
$fp = fopen('zip://videos.zip#'.$filename, 'r');
if($fp)
{
header('content-type: video/mp4');
//Note: you should probably also output an appropriate content-length header.
while(!feof($fp))
{
echo fread($fp, 8196);
}
fclose($fp);
}
else
{
echo 'Some error message here.';
}
--Addendum--
It should also be noted that this'll require the zip php extension to be enabled.
A more complete example of a video fetching script with range handling and the like can be found in the question at mp4 from PHP - Not playing in HTML5 Video tag but you'd need to tweak it to allow reading from the zip file.

Related

How to create a video stream from a single dynamic image in PHP

I have a single image file on my server which its content changes every 100 ms.
I can load and serve this image as usual:
$image = file_get_contents('path/to/image.jpg');
header('Content-type: image/jpeg');
echo $image;
<img src="image.php">
Thus, every time the user updates the screen (pressing F5 for example) the server would reply a different image. I can also use Java Script (using setInterval for example) to update the image continuously so the users needn't to update the screen themselves.
However, I need to serve this image as a CONTINUOUS FLOW such as a LIVE VIDEO STREAM in order to be shown as an HTML5 video instead of a static image.
Some examples I`ve found so far use PHP-FFMpeg library for stream videos. It turns out that those examples require that I have a video file at hand (a file in the OS or a URL to a file) instead of a single (dynamic) image as I've described above.
I found this example for how to use PHP to streaming. It looks promisssing. But again the code supposes I have a video file url which I haven't.
I'm wondering if is it possible to adapt this code to my needs. For example, how to adapt the setHeader() method to the scenario where there are no begin and end? And considering that I have loaded the image contents using file_get_contents or so, how to change stream() properly? Or, at other hand, is there other way to serve this image as a video stream?
The code below should reload the image ever 200 ms. Adding a random number avoids any potential caching which is unlikely since you are requesting a PHP page.
<html>
<header>
<script>
function ReloadImage()
{
var image_element = document.getElementById('image_id');
image_element.src = 'image.php?rand=' + Math.random();
}
setInterval(ReloadImage,200);
</script>
</header>
<body>
<img src="image.php" id="image_id">
</body>
</html>
Well, I just found a solution for my needs:
$identifier = "an_identifier";
//set headers
header('Accept-Range: bytes');
header('Connection: close');
header('Content-Type: multipart/x-mixed-replace;boundary=' . $identifier);
header('Cache-Control: no-cache');
// loop to continuously serve an image
while(true) {
$image = load_image_contents();
echo "--" . $identifier . "\r\nContent-Type: image/jpeg\r\nContent-Length: ".strlen($image)."\r\n\r\n".$image;
flush();
usleep(50000);
}
On the browser side I just set a regular image tag:
<img src="image.php">

PHP File As URL Fails Video Stream

I'm have a PHP file that contains HTML markup for a video. Instead of using a full URL in the src part of the source tags, I use a PHP file that contains code that renders the video file.
The PHP file name is appended by a random string of characters that serve as a key to the actual video file name. I store these values in $_SESSION so that the PHP file that is rendering the video file will know which file to look for. I also have it use cookies so that nobody can reuse the tokens.
This works great in Firefox and Chrome, but it fails for Safari and for all mobile browsers I have tried on both Android and iOS.
For the sake of simplicity, I stripped down the whole process to simply have the video rendering PHP file while the PHP file containing the HTML markup calls the that file directly without using unique tokens.
When I do that, sometimes Safari loads it (very slowly) and mobile is still a complete fail.
The pertinent part of the first file looks something like this:
<video>
<source src=\"/videofile.php\" type=\"video/mp4\">
</video>
The other file simply has this just to see if that alone works:
readfile('filename.mp4');
So, non-mobile Safari sometimes loads it (very slowly) like that. However, it always fails whenever I add anything else including storing the file name in a variable and calling the variable as a parameter in readfile(), whenever I use sessions, when I use cookies, and basically anything else.
I tried many other ways to break the file down into chunks since I figured that's why it won't play on mobile, but loading the video file directly into the source tags has no problem. The problem seems to lay with how I'm calling the video file.
I have no idea why it works with Firefox and Chrome, but it won't work for the others stated above. I am not sure what to do at this point. I am not even sure if I'm phrasing the problem correctly since all of my Google queries have failed to yield anything like what I'm talking about.
EDIT: I've added the full file code I'm using
First One
<?php
ini_set('session.use_cookies',1);
session_start();
$mp4=uniqid();
$_SESSION[$mp4]='video.mp4';
$ogv=uniqid();
$_SESSION[$ogv]='video.ogv';
echo "
<div style=\"position: relative;padding-bottom: 56.25%;padding-top:35px;height: 0;overflow: hidden;\" oncontextmenu=\"return false\">
<video style=\"position: absolute;top:0;left: 0;width: 100%;height: 100%;\" height=\"540\" width=\"864\" controls>
<source src=\"/videorender.php?video=" . $mp4 . "\" type=\"video/mp4\">
<source src=\"/videorender.php?video=" . $ogv . "\" type=\"video/ogv\">
</video>
</div>
";
?>
Now for VideoRenderer.php
<?php
ini_set('session.use_cookies',1);
session_start();
$file = $_SESSION[$_GET['video']];
$_SESSION=array();
$params = session_get_cookie_params();
setcookie(session_name(),'', time()-42000,$params["path"],$params["domain"],
$params["secure"], $params["httponly"]);
if(!file_exists($file) || $file === '' || !is_readable($file)){
header('HTTP/1.1 404 File not found',true);
exit;
}
readfile($file);
exit;
?>
Did you compared the http headers between your php script and a direct embedding of the video file?
You have to sent Content-Type:video/mp4 for example:
header("Content-Type:video/mp4");
The Content-Length header is also a good idea:
header('Content-Length: '.filesize($videoFile));
There are several other circumstances like some browsers send more then one requests. See a similar question here: https://stackoverflow.com/a/3125869/2797243
On the other side: Piping a video file through php is a realy bad idea (server performance) like you described. With this approach you will get no solution that will satisfy you.
If you want to implement something like authorization for ex., best approach is using a streaming server. Regardless the video is being streamed or will be provided as a progressive download.
The only solution I can think of, is to make http redirect to the video file. But I guess this could also fails, specially on the native players like the mobile ones.

How to add HTML 5 audio player?

I'm getting source file from a folder. When I select a ready-made mp3 file like song as src in audio tag, It works. But when I select a mp3 file(call recording file) created from base64 encoded string, I doesn't work. File is perfectly created as I checked in folder and played. Problem is that when I move curser on player, it becomes transparent just like an image. If anyone know answer then please explain with an example. Thank You. Here is my code.
<?php
$data = $_REQUEST['data'];
$filename = $_REQUEST['filename'] . ".3gpp";
$imei = $_REQUEST['imei'];
$dir = __DIR__ . "/recordings/";
$file = file_put_contents($dir . $filename, base64_decode($data));
$rloc = "recordings/" . $filename;
$str = "INSERT INTO recording(data, filename, imei) VALUES('$rloc', '$filename', '$imei')";
$qry = mysql_query($str);
?>
<html>
<audio controls autoplay="">
<source src="<?php echo $row['data']; ?>">
</audio>
</html>
You need to prefix the data:audio/mp3;base64, to the Data URI. Use this instead:
<audio controls autoplay="">
<source src="data:audio/mp3;base64,<?php echo $row['data']; ?>">
</audio>
I found this short example:
<audio controls autoplay>
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
May it's helpful.
<audio controls="controls" autobuffer="autobuffer" autoplay="autoplay">
<source src="data:audio/wav;base64,UklGRhwMAABXQVZFZm10IBAAAAABAAEAgD4AAIA+AAABAAgAZGF0Ya4LAACAgICAgICAgICAgICAgICAgICAgICAgICAf3hxeH+AfXZ1eHx6dnR5fYGFgoOKi42aloubq6GOjI2Op7ythXJ0eYF5aV1AOFFib32HmZSHhpCalIiYi4SRkZaLfnhxaWptb21qaWBea2BRYmZTVmFgWFNXVVVhaGdbYGhZbXh1gXZ1goeIlot1k6yxtKaOkaWhq7KonKCZoaCjoKWuqqmurK6ztrO7tbTAvru/vb68vbW6vLGqsLOfm5yal5KKhoyBeHt2dXBnbmljVlJWUEBBPDw9Mi4zKRwhIBYaGRQcHBURGB0XFxwhGxocJSstMjg6PTc6PUxVV1lWV2JqaXN0coCHhIyPjpOenqWppK6xu72yxMu9us7Pw83Wy9nY29ve6OPr6uvs6ezu6ejk6erm3uPj3dbT1sjBzdDFuMHAt7m1r7W6qaCupJOTkpWPgHqAd3JrbGlnY1peX1hTUk9PTFRKR0RFQkRBRUVEQkdBPjs9Pzo6NT04Njs+PTxAPzo/Ojk6PEA5PUJAQD04PkRCREZLUk1KT1BRUVdXU1VRV1tZV1xgXltcXF9hXl9eY2VmZmlna3J0b3F3eHyBfX+JgIWJiouTlZCTmpybnqSgnqyrqrO3srK2uL2/u7jAwMLFxsfEv8XLzcrIy83JzcrP0s3M0dTP0drY1dPR1dzc19za19XX2dnU1NjU0dXPzdHQy8rMysfGxMLBvLu3ta+sraeioJ2YlI+MioeFfX55cnJsaWVjXVlbVE5RTktHRUVAPDw3NC8uLyknKSIiJiUdHiEeGx4eHRwZHB8cHiAfHh8eHSEhISMoJyMnKisrLCszNy8yOTg9QEJFRUVITVFOTlJVWltaXmNfX2ZqZ21xb3R3eHqAhoeJkZKTlZmhpJ6kqKeur6yxtLW1trW4t6+us7axrbK2tLa6ury7u7u9u7vCwb+/vr7Ev7y9v8G8vby6vru4uLq+tri8ubi5t7W4uLW5uLKxs7G0tLGwt7Wvs7avr7O0tLW4trS4uLO1trW1trm1tLm0r7Kyr66wramsqaKlp52bmpeWl5KQkImEhIB8fXh3eHJrbW5mYGNcWFhUUE1LRENDQUI9ODcxLy8vMCsqLCgoKCgpKScoKCYoKygpKyssLi0sLi0uMDIwMTIuLzQ0Njg4Njc8ODlBQ0A/RUdGSU5RUVFUV1pdXWFjZGdpbG1vcXJ2eXh6fICAgIWIio2OkJGSlJWanJqbnZ2cn6Kkp6enq62srbCysrO1uLy4uL+/vL7CwMHAvb/Cvbq9vLm5uba2t7Sysq+urqyqqaalpqShoJ+enZuamZqXlZWTkpGSkpCNjpCMioqLioiHhoeGhYSGg4GDhoKDg4GBg4GBgoGBgoOChISChISChIWDg4WEgoSEgYODgYGCgYGAgICAgX99f398fX18e3p6e3t7enp7fHx4e3x6e3x7fHx9fX59fn1+fX19fH19fnx9fn19fX18fHx7fHx6fH18fXx8fHx7fH1+fXx+f319fn19fn1+gH9+f4B/fn+AgICAgH+AgICAgIGAgICAgH9+f4B+f35+fn58e3t8e3p5eXh4d3Z1dHRzcXBvb21sbmxqaWhlZmVjYmFfX2BfXV1cXFxaWVlaWVlYV1hYV1hYWVhZWFlaWllbXFpbXV5fX15fYWJhYmNiYWJhYWJjZGVmZ2hqbG1ub3Fxc3V3dnd6e3t8e3x+f3+AgICAgoGBgoKDhISFh4aHiYqKi4uMjYyOj4+QkZKUlZWXmJmbm52enqCioqSlpqeoqaqrrK2ur7CxsrGys7O0tbW2tba3t7i3uLe4t7a3t7i3tre2tba1tLSzsrKysbCvrq2sq6qop6alo6OioJ+dnJqZmJeWlJKSkI+OjoyLioiIh4WEg4GBgH9+fXt6eXh3d3V0c3JxcG9ubWxsamppaWhnZmVlZGRjYmNiYWBhYGBfYF9fXl5fXl1dXVxdXF1dXF1cXF1cXF1dXV5dXV5fXl9eX19gYGFgYWJhYmFiY2NiY2RjZGNkZWRlZGVmZmVmZmVmZ2dmZ2hnaGhnaGloZ2hpaWhpamlqaWpqa2pra2xtbGxtbm1ubm5vcG9wcXBxcnFycnN0c3N0dXV2d3d4eHh5ent6e3x9fn5/f4CAgIGCg4SEhYaGh4iIiYqLi4uMjY2Oj5CQkZGSk5OUlJWWlpeYl5iZmZqbm5ybnJ2cnZ6en56fn6ChoKChoqGio6KjpKOko6SjpKWkpaSkpKSlpKWkpaSlpKSlpKOkpKOko6KioaKhoaCfoJ+enp2dnJybmpmZmJeXlpWUk5STkZGQj4+OjYyLioqJh4eGhYSEgoKBgIB/fn59fHt7enl5eHd3dnZ1dHRzc3JycXBxcG9vbm5tbWxrbGxraWppaWhpaGdnZ2dmZ2ZlZmVmZWRlZGVkY2RjZGNkZGRkZGRkZGRkZGRjZGRkY2RjZGNkZWRlZGVmZWZmZ2ZnZ2doaWhpaWpra2xsbW5tbm9ub29wcXFycnNzdHV1dXZ2d3d4eXl6enp7fHx9fX5+f4CAgIGAgYGCgoOEhISFhoWGhoeIh4iJiImKiYqLiouLjI2MjI2OjY6Pj46PkI+QkZCRkJGQkZGSkZKRkpGSkZGRkZKRkpKRkpGSkZKRkpGSkZKRkpGSkZCRkZCRkI+Qj5CPkI+Pjo+OjY6Njo2MjYyLjIuMi4qLioqJiomJiImIh4iHh4aHhoaFhoWFhIWEg4SDg4KDgoKBgoGAgYCBgICAgICAf4CAf39+f35/fn1+fX59fHx9fH18e3x7fHt6e3p7ent6e3p5enl6enl6eXp5eXl4eXh5eHl4eXh5eHl4eXh5eHh3eHh4d3h4d3h3d3h4d3l4eHd4d3h3eHd4d3h3eHh4eXh5eHl4eHl4eXh5enl6eXp5enl6eXp5ent6ent6e3x7fHx9fH18fX19fn1+fX5/fn9+f4B/gH+Af4CAgICAgIGAgYCBgoGCgYKCgoKDgoOEg4OEg4SFhIWEhYSFhoWGhYaHhoeHhoeGh4iHiIiHiImIiImKiYqJiYqJiouKi4qLiouKi4qLiouKi4qLiouKi4qLi4qLiouKi4qLiomJiomIiYiJiImIh4iIh4iHhoeGhYWGhYaFhIWEg4OEg4KDgoOCgYKBgIGAgICAgH+Af39+f359fn18fX19fHx8e3t6e3p7enl6eXp5enl6enl5eXh5eHh5eHl4eXh5eHl4eHd5eHd3eHl4d3h3eHd4d3h3eHh4d3h4d3h3d3h5eHl4eXh5eHl5eXp5enl6eXp7ent6e3p7e3t7fHt8e3x8fHx9fH1+fX59fn9+f35/gH+AgICAgICAgYGAgYKBgoGCgoKDgoOEg4SEhIWFhIWFhoWGhYaGhoaHhoeGh4aHhoeIh4iHiIeHiIeIh4iHiIeIiIiHiIeIh4iHiIiHiIeIh4iHiIeIh4eIh4eIh4aHh4aHhoeGh4aHhoWGhYaFhoWFhIWEhYSFhIWEhISDhIOEg4OCg4OCg4KDgYKCgYKCgYCBgIGAgYCBgICAgICAgICAf4B/f4B/gH+Af35/fn9+f35/fn1+fn19fn1+fX59fn19fX19fH18fXx9fH18fXx9fH18fXx8fHt8e3x7fHt8e3x7fHt8e3x7fHt8e3x7fHt8e3x7fHt8e3x8e3x7fHt8e3x7fHx8fXx9fH18fX5+fX59fn9+f35+f35/gH+Af4B/gICAgICAgICAgICAgYCBgIGAgIGAgYGBgoGCgYKBgoGCgYKBgoGCgoKDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KDgoOCg4KCgoGCgYKBgoGCgYKBgoGCgYKBgoGCgYKBgoGCgYKBgoGCgYKBgoGCgYKBgoGBgYCBgIGAgYCBgIGAgYCBgIGAgYCBgIGAgYCBgIGAgYCAgICBgIGAgYCBgIGAgYCBgIGAgYCBgExJU1RCAAAASU5GT0lDUkQMAAAAMjAwOC0wOS0yMQAASUVORwMAAAAgAAABSVNGVBYAAABTb255IFNvdW5kIEZvcmdlIDguMAAA" />
</audio>
A Data URI takes the format:
data:[][;charset=][;base64],
The MIME-type specifies what type of data the URI contains.
The charset in which it is encoded.
last the encoded data
It looks like you are using wrong variable to set the source. You don't have $row['data'] defined in your php code. Maybe it should be $rloc instead:
<audio controls autoplay="">
<source src="<?php echo $rloc; ?>">
</audio>
Edit:
Did you convert uploaded file (3gpp) to other formats (mp3, ogg), or did you just rename it to a different extension? Looking at binary data at links you posted in comments to other answer this is your situation: all links you posted are exactly the same file, with different name. Binary, they are identical, just file name is different. Format details for the file which is on all your links are:
Format : MPEG-4
Format profile : 3GPP Media Release 4
Codec ID : 3gp4
You can not just change file extension and expect it will play in browser. You need to convert file to other format. You can use ffmpeg or any other conversion tool to convert from 3gpp to mp3 and ogg.
It is possible to use a Data URI for audio, as others have suggested. However, it's not a good idea. Not only are you adding 33% overhead for this encoding, and the CPU overhead on both ends, but there is a 1 MB limit which won't take long to hit with audio.
If you must serve your audio data this way, you can simply reference your PHP script which outputs nothing but raw binary audio data.
<audio src="/audio.php?id=12345"></audio>
Be sure to set the appropriate Content-Type header.
Finally, note that you have serious security issues in your code. As it stands right now, anyone can write pretty much whatever they want to whatever path they want on your hard drive, because you're letting them specify the filename on disk which can contain ../. Also, your SQL is subject to SQL injection attacks. Use prepared/parameterized queries to avoid this issue entirely.

img php src asynchronous

If I use php file as source to image, where:
$file = $_GET["file"];
$file_get = get_file_contents("from/".$file);
$fopen = fopen("to/".$file,"w+");
fwrite($fopen, $file_get);
fclose($fopen);
header("Location:to/".$file);
And if I use many images of that kind on one page, like:
<img src="image.php/?file=img.jpg>
<img src="image.php/?file=img2.jpg>
<img src="image.php/?file=img3.jpg>
...
I found that code in image.php doesn't run asynchronously. Images are downloaded one by one. How can I avoid it?
I see there some problems in your code. The first is that you have a big security whole when you use the $_GET input directly in your code to get an image.
The next one is why do you fetch the content from one file and write them to another file to redirect to them? That is not really fast if you write every time the file to another location.
If you get the content echt echo the content and set the correct header to show the image.
header('Content-type:image/png');
readfile($fullpath);
Its much easier and you have a less IO to show files. Otherwise you can use a script like PHPThumb which generated smaller versions and cache the files.
http://phpthumb.sourceforge.net/

PHP inside img src

Trying to see what actions can be performed with a PHP script that is being called via an image src like so:
<img src="http://example.com/script.php" />
Now, I have tried to include the PHP header() function in script.php:
<?php
header("Location: http://example.com");
I have also tried to echo an image url expecting the img to display it, which it didn't:
<?php
echo 'http://example.com/image.png';
Are there any ways of doing such things with a PHP script that is being called in the img src attribute?
Are there any ways of doing such things with a PHP script that is being called in the img src attribute?
No. A resource that is used as a src for an img tag needs to output image data, nothing else.
There are some exceptions, eg. a header("location: ....") redirect, but the redirect needs to point to another valid image resource, not a web site as you show in your example.
Check out the readfile() as a way to output your image file from your script.php
readfile($file);
Read more about it here in the manual:
http://php.net/manual/en/function.readfile.php
where Example #1 gives an idea of how to set up the headers.
The manual also states that:
readfile() will not present any memory issues, even when sending large
files, on its own.
and
A URL can be used as a filename with this function
ps: This was the way Wordpress Multisite used to open user uploaded (e.g. images) files.
Your script.php should return the output of an image with the correct headers. For instance:
<img src="/html/img/script.php" />
// Script.php
$file = "tiger.jpeg";
$type = "image/jpeg";
header("Content-Type: $type");
header("Content-Length: " . filesize($file));
readfile($file);
You should keep in mind that the src tag should directly point to an image file. However, it is possible to use PHP to create an image, for exmaple by using the GD library:
http://php.net/manual/en/book.image.php
So using:
<img src="http://example.com/script.php" />
is possible, as long as script.php really outputs an image file, for example by using the example as described here:
http://www.php.net/manual/en/image.examples-png.php
I used this kind of processing in the past to overlay texts on JPG images for a broker website (e.g. new, sold, for rent, etc.).
Are there any ways of doing such things with a PHP script that is being called in the img src attribute?
Yes, but the PHP Script has to output image data only, as stated in various other answers.
With that being said, just read the image and output it to the stream with readfile
header('Content-Type: image/png');
readfile($file);
exit();
I know I might be a couple years late to really help you, but the accepted answer just isn't true (anymore).

Categories