13

I'm currently trying to deliver MP4 video for use in HTML5 video (using video-js) via a PHP script for controlling video access. After some research I was able to get this working, with the help of the stackoverflow article found here. If I navigate to the PHP script, I can view the video as if I were viewing it via its absolute path (for instance localhost/myvideo.mp4 rather than localhost/myscript.php) in Firefox, Safari and IE. My problem is with Google Chrome, which simply shows a blacked out screen with a small media player in the centre, and does nothing.

I did try using a quick rewrite such as localhost/avideo.mp4 which routes to the PHP script, but unfortunately this didn't change anything.

Here's my script:

if (is_file($uri)) {
    header('Content-Type: video/mp4');
    if (isset($_SERVER['HTTP_RANGE'])) {
        $this->rangeDownload($uri);
        exit;
    } else {
        header("Content-Length: ".filesize($uri));
        $this->readfile_chunked($uri);
        exit;
    }
} else {
    //error
}

The rangeDownload method has been taken directly from appendix A of this link as suggested in the aforementioned stackoverflow article.

Community
  • 1
  • 1
AaronDS
  • 851
  • 2
  • 13
  • 31
  • Can you post all of the header info you are sending? – ethrbunny Jul 13 '12 at 14:58
  • Content-type, Accept-Ranges, Content-Range, Content-Length, HTTP/1.1 206 Partial Content. These headers are used in the first case using rangeDownload, which is used for Chrome, although readfile_chunked uses less headers (still doesn't work in chrome). – AaronDS Jul 13 '12 at 15:02
  • The only other one I can suggest is Content-Transfer-Encoding: binary. Im able to transfer audio via PHP to all browsers using this combo. – ethrbunny Jul 13 '12 at 15:09
  • @ethrbunny thanks for your help, but sadly, that header made no difference. – AaronDS Jul 13 '12 at 15:11
  • You may have to read the browser data when it connects and make some shifts on all these params. – ethrbunny Jul 13 '12 at 15:14
  • Is it possible that its conflicting with 'video-js'? Does any of this work with a simple – ethrbunny Jul 13 '12 at 20:14
  • @ethrbunny thanks for another reply, the problem occurs even when the browser is simply being pointed to the file (when video-js is not being used). Of course if I try it within video-js, it still fails. – AaronDS Jul 14 '12 at 00:19
  • 1
    Have you tried it with a known good video? – ethrbunny Jul 15 '12 at 12:31
  • @ethrbunny the video I am currently using is fine, it works flawlessly without the php delivery. – AaronDS Jul 16 '12 at 11:47
  • Maybe check which plugins chrome is using? Though if it plays with the – ethrbunny Jul 16 '12 at 14:20
  • `exit;` only is enough. No need to use `die();` also. – RTB Jul 16 '12 at 16:01

2 Answers2

2

Maybe the problem is with the URL (more specifically, the extension). Normally, you would use Content-Disposition header, but I understand that this is not desirable when delivering content to mobiles.

Try using localhost/myscript.php/myvideo.mp4

It is important not to use the "Content-Disposition" HTTP header, since some phones refuse to accept content when using it. By including the filename on the URL, you will trick the phone to think it's a real file and to accept it.

Now, when you send the download URL to the customer, you don't normally know yet what device the customer has, so you don't know what file formats the device will support. Therefore, you can't include the filename on that URL, and once again, you will need an intermediate download page. Once more, we will use a URL like:

http://wap.mydomain.tld/get.php/123456abcdef

This time, when the customer connects to download the content, the get.php script will not create a temporary file, but point to another script which streams the file contents. Supposing the resultant content to download will be "image.jpg", the intermediate download page could point the customer to a URL like:

http://wap.mydomain.tld/download.php/123456abcdef/image.jpg

From ( http://mobiforge.com/developing/story/content-delivery-mobile-devices )

Yasei No Umi
  • 1,574
  • 9
  • 23
  • Thanks for your response, although as I stated in my question, "I did try using a quick rewrite such as localhost/avideo.mp4 which routes to the PHP script, but unfortunately this didn't change anything.". I'm not sure what else you're suggesting I do differently? – AaronDS Jul 16 '12 at 19:41
  • The difference might be in the actual URL the browser gets. If you are using redirection (30x), then the browser eventually gets the final URL, with the .php extension instead of a .mp4 extension - this can be very important. Did you try comparing all request/response headers (using Fiddler, for example?) – Yasei No Umi Jul 17 '12 at 06:54
  • I'm looking at header info now in Chrome, but I'm not sure what to make of it. What I can say is that there is a clear difference. I'll follow this post up with a screenshot in a couple of hours. – AaronDS Jul 17 '12 at 17:30
  • [Here's that screenshot of the headers shown in Google Chrome](https://dl.dropbox.com/u/17610534/video-headers.png). I confess I'm not particularly knowledgeable on headers, so I'm not sure what to make of this. Are you able to shed any light on the matter? – AaronDS Jul 17 '12 at 22:12
  • The screen-shot only contains the requests, not the headers of each request. Click on the request the see the headers (You should see things like Request URL, Request Method, Status Code and then Request Headers list and Response Headers. You will either see a difference in the response headers (the ones you generate and the ones created by the web-server), otherwise, the offending difference might be the Request URL, as I speculated (meaning, yours will be something.php and theirs something.mp4) browsers use the extension as heuristic to how they should handle the content. – Yasei No Umi Jul 19 '12 at 12:16
  • Taking into account that last post, I decided to stick .mp4 on the end of the URL, so my URL was along the lines of index.php/get_video/1.mp4, then simply using explode(".",$id) to obtain the video id of 1. However, it seemingly made no difference and chrome still fails to play the video. – AaronDS Jul 19 '12 at 15:09
2

I understand you're using video-js but I recommend using html5media (also check out the github page for more info). I had to make videos available on a website for work and I tried a few things including video-js but html5media was the only one that I could get working in all browsers.

A side note that might help others: One of the requirements was that we hosted all files so that we wouldn't be reliant on third-party servers to serve JavaScript files or flash players, I can't remember if with video-js this was easy but I know with html5media we were able to download flowplayer and have everything on our servers.

And to generate the 3 recommend video formats (mp4, WebM and Theora) I used Miro Video Converter

Dean
  • 4,554
  • 7
  • 34
  • 45
  • Thanks for this post, however the problem doesn't lie with Video-JS, it is specifically with chrome (the video doesn't play on chrome with video-js out the picture, and when using the normal video file, video-js works fine). My experiences with video-js have been good; I used handbrake for file conversion and so far I haven't run in to any problems. However, I've noted html5media in case I need to find something new in the future. Cheers. – AaronDS Jul 17 '12 at 17:22
  • No problem @Noobatron. I don't want to discourage people from using video-js, because if you can get it working then hey, great! I just thought someone might benefit from hearing about what I did in case they run into the same sort of problems (maybe I just didn't know what I was doing with video-js). I have Handbrake at home that I use to convert dvd's to my android phone and it works a treat. I would still go to Miro at work for those 3 formats for the web simply because the interface is really simple. Hope you get your videos working Chrome! – Dean Jul 17 '12 at 22:07