build an API for streaming audio/video from GridFS mongodb - php

I have tried the solution given in the link stream audio/video files from gridFS on the browser
Still when I use my code the file gets downloaded or it plays with the default browser player.
My code is as:
header('Content-type: audio/mpeg;');
$stream = $file->getResource();
while (!feof($stream)) {
echo fread($stream, 8192);
}
I actually want a solution to build an API so that I can retrieve the audio/video from mongodb GridFS and play it streaming from a phone application.
Help is urgently needed. Any help on the topic would be welcome.

I found a way to make an API for playing the file straight from the mongoDB GridFS in a HTML audio video image widget. The only problem with it is that it uses the data retrieved from mongoDB as a base64 data. Now the problem that i am talking about is discussed in this link:
http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to.
I hope you find that useful before deciding to use the solution I am using. My solution is as follows:
$stream = $file->getResource();
$stringcoded = stream_get_contents($stream); //converts the stream to string data
$encoded = base64_encode($stringcoded); //encodes string data to base64
Now that you have the audio, video or image data encoded in base64, you just have to echo the data in the 'src' portion of the html5 widget.
I got this solution from a very useful blog. If you need more help on it please go through it:
http://www.iandevlin.com/blog/2012/09/html5/html5-media-and-data-uri
Any enhanced solution to this problem is more than welcome.

Related

Streaming a video using PHP and manipulating it using FFMPEG

I use the class in this tutorial to open a mp4 file in PHP and stream it to HTML5 video player and everything works fine. Now I would like to do some manipulations to the stream on the fly. e.g: adding a watermark to the stream. I am not sure if it can be done using ffmpeg command or PHP-FFMpeg.
The class in the mentioned tutorial opens the file (or the range of the file that is needed by the player), into the $data variable:
$data = fread($this->stream, $bytesToRead);
echo $data;
flush();
I guess I need to pass the $data to ffmpeg somehow, add the watermark and then echo() the manipulated $data instead of the original one. But I am not sure if it's possible or not, and if it is, how it can be done? I don't know how to open a variable in ffmpeg instead of a file and how to get the output as a variable, and not a file.
Any help would be appreciated.

Amazon S3 StreamWrapper fread Issue In PHP

I am using amazon s3 API and setting the client to read as stream. It is working fine for me to use file_get_contents("s3://{bucket}/{key}"), which read the full data for the file(I am using video file & testing on my local system). However, I am trying to optimize the memory used by the script and thus trying to read and return data by chunk as below:
$stream = #fopen("s3://{bucket}/{key}", 'r');
$buffer = 1024;
while(!feof($stream)) {
echo #fread($stream, $buffer);
flush();
}
This is not working on my local system. I am just wondering what might be the issue using this technique. by searching, I found that this is also a very widely used technique. So, if anybody can please give any suggestion about what might be wrong here or any other approach, I should try with, it will be very helpful. Thanks.
OK, finally got the solution. Somehow, some other output are being added to buffer. I had to put:
ob_get_clean();
header('Content-Type: video/quicktime');
In this way to clean anything if were added. Now its working fine.
Thanks Mark Baker for your valuable support through the debugging process.

Recording live stream from IP camera (MJPEG Compression)

I have a live stream from a Tenvis IP camera through http live streaming and its in mjpeg compression.
I am trying to save it to a file, and I have tried using php to do this. my code looks like this:
<?php
$input = fopen("http://xxx.xxx.xxx.xxx:81/videostream.cgi?user=user&pwd=admin&resolution=8");
$output = fopen("video.mpg", "c+");
$end = time() + 60;
do {
fwrite($output, (fread($input, 30000)), 30000);
} while (time() <= $end);
fclose($output);
fclose($input);
echo "<h1>Recording</h1>";
?>
The code I have creates the file but doesn't write anything to it. Any suggestions will be appreciated
According to the Wikipedia page about MJPEG (http://en.wikipedia.org/wiki/Motion_JPEG#M-JPEG_over_HTTP), the MJPEG stream over HTTP is basically a sequence of JPEG frames, accompanied by a special mime-type. In order to capture these and save them to a video file, I am not sure you can simply write the incoming data to an .mpg file and have a working video.
To be honest, I am not quite sure why your script does not write anything at all, but I came across the following page, which, although it is written for specific software, provides examples on how to capture an MJPEG stream and pass it on to a browser:
http://www.lavrsen.dk/foswiki/bin/view/Motion/MjpegFrameGrabPHP
You could try one of their examples, and instead of passing it to the browser, save it to a file. You can see they read one image at a time:
while (substr_count($r,"Content-Length") != 2) $r.=fread($input,512);
$start = strpos($r,'ΓΏ');
$end = strpos($r,$boundary,$start)-1;
$frame = substr("$r",$start,$end - $start);
If this does fix the stream capturing part but not saving it as a video, another option would be to save all frames individually as a JPEG file, then later stitch them together using a tool such as ffmpeg to create a video: Image sequence to video quality
Update
If you decide to take the ffmpeg road, it is also possible to capture the stream using ffmpeg only. See this question for an example.
Hope this helps.
Most of the time, when a camera supports mjpeg, it also supports rtsp and as such you might want to pursue that as a solution for what you are trying to accomplish. With that, its fairly simple to record using an app like VLC.

Image creation using php

Am trying to create a video clip using .jpg images and ffmpeg, am creating .jpg images as below:
$str=$_REQUEST['data_array'];//gets the base64 encoded image data;
$count =$_REQUEST['count'];//gets number of images i've to create;
$edited_str=substr($str,23,strlen($str)-1);//
$edited_str=base64_decode($edited_str);
$f=fopen("Images/temp".$count.".jpg","w");//am creating temp.jpg file
fwrite($f,$edited_str);//placing my decoded data into file
fclose($f);
are the images am creating above different from normal .jpg images?
This line:
$edited_str=substr($str,23,strlen($str)-1);
makes it different. If this is the full base64 sting of the file, then this cuts it up and corrupts it. Maybe you are adding some stuff on the front.
If you are just removing stuff from the front that was added, then it should be the same as the original file that was encoded with base64.
If you want to get the information this way from another page, I suggest using $_POST as opposed to $_REQUEST for a number of reasons.
EDIT: I wouldn't say video manipulation in php is impossible. I think there is even a toolkit... here's one:
http://phpvideotoolkit.sourceforge.net/
which states:
It can perform video format conversion, extract video frames into separate image files, and assemble a video stream from a set of separate video images.
Haven't tested it, but plan to try it out one day.
EDIT2: On the php site, there were some issues that you could try, but to help more, there needs to be more information. Check with a file directly to make sure it's being sent and decrypted properly.
I haven't got to test any of these yet.
One piece of advice was for large files use:
$decodedstring=base64_decode(chunk_split($encodedstring));
Another was if you use javascript canvas.toDataURL() then you need to convert spaces back to pluses:
$encodedData = str_replace(' ','+',$encodedData);
$decocedData = base64_decode($encodedData);
http://php.net/manual/en/function.base64-decode.php

How to read Lightroom keywords from image file using PHP?

I have a photo community (www.jungledragon.com) that allows users to upload photos. My platform is PHP/CodeIgniter.
As part of the upload process I'm already reading EXIF info using PHP's exif_read_data function, which works fine. I read camera details and show these on an info tab.
On top of that, user's are expected to manually set the photo title, description and tags on the website after uploading the photo. However, some users manage these fields in their image management program, for example Lightroom. It would be great if I could read those as well, uploading would become a total joy.
I already improved my EXIF reading to read the "caption", this way users don't have to set the image title after uploading anymore. Now I'm looking to read keywords, which is where I am stuck. Here's a partial screenshot of an image in Lightroom:
I can read the Metadata, but how do I read the keywords? The fact that it is not inside metadata makes me wonder if it's at all possible? I've tried reading every value I can get (ANY_TAG, IFD0, EXIF, APP12) using exif_read_data, but the keywords are not to be found.
Any thoughts?
As suggested you may have to use another method of reading metadata.
http://www.foto-biz.com/Lightroom/Exif-vs-iptc-vs-xmp
Image keywords may be stored in IPTC and not in EXIF. I don't know if there is a standard platform method for reading iptc but a quick google shows this
http://php.net/manual/en/function.iptcparse.php
Try using PEL, a much more comprehensive library than exif_read_data() for exif data.
After a long research, i found the solution to get keywords exported by lightroom in a jpg file :
$image = getimagesize($imagepath, $info);
if(isset($info['APP13']))
{
$iptc = iptcparse($info['APP13']);
$keywordcount = count($iptc["2#025"]);
for ($i=0; $i<$keywordcount; $i++)
{
echo "keyword : " . $iptc["2#025"][$i] . "<br/>";
}
}

Categories