Streaming video file? - php

I need to stream an flv file.
Streaming should look like live streaming,
and I there should be a way to change the target file.
Sorry for my poor English.

If by "streaming" you mean "showing a flash-video clip", flv-streaming isn't really streaming, but it's a normal file transfer, with the flash player starting playback even if the file isn't completely downloaded to the client. Time seeking is implemented in a standard HTTP way, with a file download offset - if you scroll the video halfway on the timeline and it hasn't downloaded yet, the current download is (most often) aborted, and restarted with an offset of filesize/2 bytes.
So, you could be fine with just using plain old readfile() and fixing the HTTP mime-type headers appropriately with header(). But, since you'd need seeking, you need to parse the HTTP request and instead of readfile(), use fpassthru(), seeking the right place, instead.
tl;dr: Avoid handling this on the PHP side, and let Apache (or the httpd of your choice) handle this instead.

I'm not quite sure what you're asking about, but if you have a bunch of media files and want to play them with a Youtube-esque media player on your website, I suggest checking out Flowplayer - It has an amazing Javascript API that lets you do all kinds of cool stuff to the player, including handling stuff like playlists and programmatically changing the current video.
I recently used it on a project with great results.

Related

How do I correctly stream a video file to the web with php or perl

So I am new to Perl and web development but I was hoping to get some guidance on the following issue.
Server 1 is transcoding video for me and has an api endpoint for me to access. It will give me the file stream that I want to push to the web.
So for the sake of the problem lets say that it is accessed at:
server1:123\video_stream
Server2 is my web server and I want to have a page that lets us access this video stream file
server2:80\web_stream
I have seen in php you can do readfile("server1:123\video_stream) but the entire video_stream will be read into memory before being output to the page... or so I was told.
I have also seen in Perl that ffmpeg output can but routed through the open(DATA, $ffmpegProcess) then printing the buffer read from this stream to the web_stream page...
This all assumes that the header information about the attributes of the video are correct.
Would it be as simple as making a curl request to Server 1 and returning that stream output like I can already with the ffmpeg output?
I am not looking for complete solution, just some direction on the best and most correct way to do this. Maybe php and Perl are not the right tools to handle this at all?
ffserver seems like the better tool to use. It's part of the ffmpeg family.
PHP readfile() is a good way to do this. If you read the PHP manual page the discussion tells you how to deal with different possibilites of reading the file in chunks and dealing with memory issues.

How do I validate that an uploaded file is a video?

I have a server that has some very sensitive information on it, so security is a big issue. The user needs to be able to upload a video. I know allowing users to upload files poses a security threat because there is no 100% way to keep them from uploading non-videos. But I obviously can choose which files the server will keep.
I know that checking the file-extension won't suffice. Checking the MIME type is better but it can still be faked. So how do I go about checking if the file is a video?
Play it!
Only way to be sure is to have some code that decodes videos of the type in question, take a look at it (and check there's sensible results, like a non-zero duration).
Otherwise though, your risks are low:
Non-malicious scenario:
Uploader uploads video, with a video/* content-type.
You store the octets and content-type.
Downloader downloads video, and you use the content-type you received.
Downloader watches video (or grumbles about codecs, etc.)
Malicious scenario 1:
Uploader uploads a nasty trojan, with a video/* content-type.
You store the octets and content-type.
Downloader downloads nasty trojan, and you use the content-type you received.
Downloader opens nasty trojan in video player. Nasty trojan does nothing because it's not a video. User grumbles about codecs. Worse case scenario is, they write rant on ubuntu forums about lack of support for proprietary formats, adds ill-spelt comments on your page about how the site sucks because the video didn't work, etc.
Malicious scenario 2:
Uploader uploads nasty trojan that is written into a video that exploits some buffer-overflow issue with a popular video player.
You store...
Downloader...
Could just be like one of the above, but it could also be that they get hit by the exploit (if they're using the affected player).
Three things to note about scenario 2 though:
Testing it's a video won't guarantee safety, as it could well have also work fine in some players.
Testing it's a video could make your server vulnerable to the exploit, if the vulnerability is in ffmpeg!
Exploits of this type are both rare, and hard to do. The general risk is the same as uploading and downloading jpegs or pngs. Indeed it's a bit smaller (there was indeed an exploit of this type affecting commonly-used jpeg libraries for a while).
In all, just make sure you only output with the content-types you accept, and force file-extensions to match them; if the user uploads a video/mpeg called hahaha.exe, then rename it hahaha.mpg
Edit: Oh, also:
Malicious scenario 3:
Uploader uploads video that exploits some players in a way that uses a lot of resources. In this case a downloader will just kill-9/ctrl-alt-delete/your-OSs-kill-them-all-of-choice, but if your server is testing it's a video, then it could end up in trouble as there's no one on hand to step in and kill the 200 (and growing as the script-kiddies's script keeps uploading more) "videos" it's trying to interpret.
Just doing normal video-processing could be enough to introduce the ability to DoS you (video processing is relatively heavy after all), so testing the file could introduce more dangers than it saves you from.
You can call ffmpeg via a php extension:
https://github.com/char0n/ffmpeg-php/
which essentially wraps the output of ffmpeg, which you then can check in php. However, you should familliarize yourself with ffmpeg first, which is a whole topic on its own. If you don't want to use the library, you can execute ffmpeg on your own via exec.
Additionally, I would check the mimetype. You can also check the file on the client side within a file input via JS (not in all browsers and this is no replacement for a true validation).
lg,
flo
Users can safely upload anything as long as it goes to the right directory and nothing on the server tries to run it (and if it's supposed to be a video, nothing will try). Malware can't do anything unless the victim somehow activates it.
I agree that unless video players have a issue that can be exploited via some corrupted video files I won't worry much. But say for not necessarily security reasons one had to check whether the file you have is a video file and all of it is valid you could execute the following steps
Run ffprobe on the file without arguments. It will give some information about the file. The codecs, containers, duration, frame rate, bitrate.
Now run ffprobe with -show_packets. It should give out frame by frame information about the file. You should get as many video frames as duration*frame_rate given by the first command. This can be checked because someone could just give a crafted header or initial section of the file could be valid video (ffmpeg and ffprobe will only test the first few seconds of the video to verify its type) the rest could be corrupted.
Run ffprobe with -show_frames. This will try and decode headers of each frame to ensure each one is a valid video frame. This is an additional step because some container simply have a table that can be used for show_packets. Hence ffprobe could have simply read that table and the data it is pointing to may be corrupt.
Now it is theoretically possible that a file has all valid headers for every frame but wrong data but without decoding the actual content and viewing it on a player this is the best you can do afaik. And I would say that is good enough and it is very fast.

Uploading video, with PHP serverside formatting & encoding

We've currently developed an ExpressionEngine site (php), and are using a paid JWPlayer to display video uploaded by the client.
At present we're running into a number of issues, as the client is:
Uploading video at the wrong size
Uploading video randomly in both flv or mp4 format
And the player is chugging along terribly with multiple pauses throughout the video - sometimes buffering the entire clip before it is played.
I know FFMPEG can be installed serverside, but I'm not sure of the way in which to go about this, and how it might interact between ExpressionEngine and JWPlayer. I'm also not sure about the formatting - the ability for this automated encoding process to also crop/resize the video to suit the player dimensions on the site.
We would really like to have the videos playable on all browsers & iOS devices.
A HQ option would also be great where applicable, but it's just a nice to have - as we're struggling with the formatting / encoding issues first and foremost.
Any help figuring out the best process, and what tools I might need would be greatly appreciated.
I'd reccomend using a service like zencoder
I've used them in the past and no matter what video format I've thrown at them it works great. (PS. I'm not affiliated with them at all)
There is a PHP API with a whole lot of resizing, quality and format options. After you've uploaded your video you can send it to zencoder and they'll send you a response some time later with success or fail.
They can put the processed video on Amazon S3 or FTP it to a server.
You'll need a HTML5 player for iOS devices though, unless JWPlayer has come a long way since I used it last.
You could get zencoder to output in mp4. and then you still only need mp4 for JWPlayer/flash and the HTML5 version for iOS, as long as your happy to use flash for all desktop browsers there's no problem.
As far as the buffering issues you are having - I have found that using a CDN version of the swf for JWPlayer (or whatever player you are using) has caused it to load the entire video file before playing. Easily fixed by hosting it yourself.
I have found many times the video conversion capabilities of different CMS to be limited, and often restricting video formats to what the developers thought was appropriate, such as FLV, which nowadays is turning obsolete for video delivery.
One of the ways you can approach it is by creating a custom script to process the videos uploaded by your client using FFmpeg, which in fact can accept almost any video format, and generate the correct output formats and dimensions, ensuring that the resulting videos will be suitable for web playback using your player.
The problem with the video buffering you are facing is because the video file is not prepared for progressive download or pseudo-streaming, so your browser needs to download the whole video before starting to play. This can be solved with programs like qt-faststart for MP4 and MOV video files, and flvtool2 for FLV files. So your script would need to also optimize the encoded videos using these tools.
Also note that if you use an HTML5 video player (browser native or recent JWPlayer), then you can enjoy from random seeking the video files without buffering them.
If starting from scratch is not an option, you can look into a commercial solution like tremendum transcoder which also uses FFmpeg and is quite simple to use, yet it does all you need in regards to dealing with different input formats and aspect ratios automatically.
I have done a few setups this way, separating the CMS part from the video processing part, and it saved me some headaches.

How to read a client-side file header from a webpage?

I am making an online tool for identifying certain file types. I need to access some byte values from the file header to do this.
The user selects the file on the client machine. Somehow, I need to get the key byte values from the file, and then these are looked up in a server side database to categorize the file.
How can I read bytes from a client-side file?
I know I could have the user upload the file to the server, but these files are very large, and I only need a few bytes, so it would be slow and wasteful to upload the whole file.
Could I somehow upload part of the file? It seems it is difficult to cancel a html form upload and the file-part is not available after cancel. Is this correct?
Is it possible to read a file in javascript? I have googled this, but the answer is unclear. I have read that it is possible with a java applet, but only if the applet is signed.
Is there some other way?
You can use html5, but will need to fallback on flash or some other non-javascript method for older browsers.
http://www.html5rocks.com/en/tutorials/file/dndfiles/
So. as Said above you must use non-javascript methodds. But each of this methods has some minus.
FLASH - bad work with proxy. Really bad. Of course you can use flash obly for get base64 code of file and give it to js. In this case this will be work greate.
Java Applet - greate work but not many users have JVM or versions of JVM may not be sasme (but if you will use JDK1.4 or 1.5 thi is no problem).
ActiveX - work only in IE and on Windows
HTML5 File Api - not cross browsers solution. Will be work only on last browsers and not in all.
of course much better use server side - in php for example getmimetype and other functions.
But I can manually change headers of my file. For example i can add to php file headers from jpeg or png - and your script will be think that is image.
So this is bad solution : use headers. For check filetype maybe simple use mimetype of file of trust to user and generate icon through file extension

Large file uploads from web pages

I code primarily in PHP and Perl. I have a client who is insisting on seeking video submissions (any encoding) from the public via one of their pages rather than letting YouTube do its job.
Server in question is a virtual machine and I can adjust ini settings for max post, max upload size etc as needed.
My initial thought is to use a Flash based uploader with PHP on the back end but I wondered if someone might have useful advice and experience on the subject?
Doing large file transfers of HTTP is not usually fun -- but sometimes it's necessary.
For large files, you'll definitely want to provide some kind of progress gauge for end-users.
There are flash-based tools that do this (swfUpload comes to mind).
If you want to avoid flash and do it with pretty html/javascript/css, you can leverage PHP's APC extension, which for some reason provides support for getting upload status from the server, as explained here
You can adjust the post size and use a normal html form. The big problem is not Apache, its http. If anything goes wrong in the transmission you will have no way to detect the error. Further more there is no way to resume the transfer. This is exactly why BitTorrent is so popular.
I don't know how against youtube your client is, but you can use their api to do the uploads from a page on your site.
http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html#Uploading_Videos
See: browser based uploading.
For web-based uploads, there's not many options. Regardless of web platform, web server, etc. you're still transferring over HTTP. The transfer is all or nothing.
Your best option might be to find a Flash, Java, or other client side option that can chunk files and upload them piecemeal, then do a checksum to verify. That will allow for resuming uploads. Unfortunately, I don't know of any such open source component that does this.
Try to convince your client to change point of view.
Using http (and the browser, hell, the browser!) for this kind of issue is rarely a good deal; Will his users wait 40 minutes with the computer and the browser running until the upload is complete?
I dont think so.
Maybe, you could set up a public ftp account, where users can upload but not download and see the others user's files.. then, who want to use FTP software can, who like to do it via browser can too.
The big problem dealing using a browser is that, if something go wrong, you cant resume but have to restart from zero again.
the past year i had the same issue, i gave a look to ZUpload
, but i didnt use it so i can suggest (we wrote a small python script that we send to our customer; the python script create a torrent of the folder our costumer need to send to us, and we download it via utorrent ;)
p.s: again, sorry for my bad english ;)
I used jupload. Yes it looks horrible, but it just works.
With that said, it's still a better idea to convince the client that doing so is stupid.
I would agree with others stating that using HTML is a poor option. I believe there is a size limitation using Flash as well. I know of a script that uses a JavaScript Applet to perform an actual FTP transfer. It is called Simple2FTP and can be found at http://www.simple2ftp.com
Not sure but perhaps worth a try?

Categories