Add Byte-Range to Gallery2 php code for iPhone Video

Arnoldjw
Arnoldjw's picture

Joined: 2004-05-16
Posts: 54
Posted: Mon, 2008-12-29 06:37

So I'd like my gallery to work on the iPhone. So far pictures work great, but video, not so good.

The problem is the code doesn't handle byte-ranges. Since the new G3 looks to be more simple, I'm guessing it won't handle video, so I'd like to modify my gallery to do it, but I'm stuck, because the iphone uses byte-ranges for mp3 and videos.

I know what to do in general. I need change the basic gallery.class around lines 870 based on if $_SERVER['HTTP_RANGE']. If its set the code needs to look at the range requested, and send some additional headers and output the file.

I have the code based on a few sites I've found that can read a file and deliver in via byte-ranges, but now I need to figure out how to add it to my gallery.

Do I add a new class base on gallery? Make edits to gallery.class?

And how would I find out if the gallery has been requested to send a range. I can't read $_SERVER within the gallery class.

 
Arnoldjw
Arnoldjw's picture

Joined: 2004-05-16
Posts: 54
Posted: Thu, 2009-01-01 02:02

I think I've done it, at least it works.

I changed gallery.class starting around line 862 by adding a test for $_SERVER['HTTP_RANGE']
if there isn't a range, its the current code, if there is then its basicly the same headers with Range headers and a different while loop.

Not sure if this is the right way or not, and with G3 not that it matters.

if (file_exists($path) && $fd = fopen($path, 'rb')) {
		if(!isset($_SERVER['HTTP_RANGE'])) //John added if test if HTTP_RANGE is Requested
		{ 
			header('Content-Disposition: inline; filename="' . $filename . '"');
			header('Last-Modified: ' . $lastModified);
			header('Content-type: ' . $mimeType);
			header('Content-length: ' . $contentLength);
			header('Expires: ' . $this->getHttpDate(2147483647));
			header('Cache-Control: public');
			set_magic_quotes_runtime(0);
			set_time_limit(0);
			while (!feof($fd)) {
			print fread($fd, 4096);
			}
			fclose($fd);
	
		}
		else      	 
		{
			/** HTTP_RANGE Code to Send Byte Range for Streaming **/	
			// First get value from range
			list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
			$range  = explode('-', $range);
			$begin = $range[0];
			$end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $contentLength;
			$length = $end - $contentLength + 1; // Calculate new content length
			
			//See if value range requested and return Partial Content headers
			if($begin>0||$end<$contentLength){
				header("Accept-Ranges: $begin-$contentLength");
				header('HTTP/1.0 206 Partial Content');
				header("Content-Range: bytes $begin-$end/$contentLength");
			}
			
			//Return Remaining Headers
			header('Content-Disposition: inline; filename="' . $filename . '"');
			header("Last-Modified: $lastModified");
			header("Content-type: $mimeType"); 
			header('Content-length: '.($contentLength));
			$etag = md5_file($path); 
			header('Etag: "'.$etag.'"');	
			header('Expires: ' . $this->getHttpDate(2147483647));
			header('Cache-Control: public');
			
			$cur=$begin;
			fseek($fd,$begin,0);
		
			while(!feof($fd)&&$cur<$end&&(connection_status()==0))
			{ 
				print fread($fd,min(1024*16,$end-$cur));
				$cur+=1024*16;
			}
			
		}
		return true;
	}
 
carnold5

Joined: 2006-02-27
Posts: 62
Posted: Thu, 2009-01-22 18:14

This would be really cool if i could get it to work with my iphone. I inserted the above code and then went to my video on my iphone and the video does not appear. Does this still work for you on G2 2.3?

 
Arnoldjw
Arnoldjw's picture

Joined: 2004-05-16
Posts: 54
Posted: Mon, 2009-01-26 02:23

I'm using Gallery 2.3, but I'll grab a fresh build and re try the code.
You do need a file that is compatible with the iphone. I export my mp4 from Quicktime. I also rename the file m4v.
I'll re-test and put up my steps.

 
Arnoldjw
Arnoldjw's picture

Joined: 2004-05-16
Posts: 54
Posted: Mon, 2009-01-26 23:38

Steps I did,

Installed G2.3,
Configured ffmpeg plugin.
Activate ffmpeg plugin.
Added m4v to video/mp4 mime type.
Added Video from local server (the file was too big to upload via web page.)
Edited Movie, Added Height and Width (480X272)
Changed /gallery2/modules/core/classes/Gallery.class
lines 862 - 878 with the code above.

Be sure you have a movie that works on the iPhone. I did Quicktime Export "Movie to iPhone" for my site.

 
cipc

Joined: 2009-12-17
Posts: 8
Posted: Sun, 2010-01-03 12:16

I went through exactly the same steps, but without success. All I get is a non-playable QT image.

Has anyone else succeded with this method.

I tried with both: Gallery 2.3 and 2.3.1

Thanks

 
littlejam

Joined: 2010-06-04
Posts: 6
Posted: Fri, 2010-06-04 08:15

Some changes have to be made to the code from Arnoldjw to make videos work for the IPhone...

        if (file_exists($path) && $fd = fopen($path, 'rb')) {
                if(!isset($_SERVER['HTTP_RANGE'])) //John added if test if HTTP_RANGE is Requested
                {
                        header('Content-Disposition: inline; filename="' . $filename . '"');
                        header('Last-Modified: ' . $lastModified);
                        header('Content-type: ' . $mimeType);
                        header('Content-length: ' . $contentLength);
                        header('Expires: ' . $this->getHttpDate(2147483647));
                        header('Cache-Control: public');
                        set_magic_quotes_runtime(0);
                        set_time_limit(0);
                        while (!feof($fd)) {
                        print fread($fd, 4096);
                        }
                        fclose($fd);

                }
                else
                {
                        /** HTTP_RANGE Code to Send Byte Range for Streaming **/
                        // First get value from range
                        list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
                        $range  = explode('-', $range);
                        $begin = $range[0];
                        $end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $contentLength;
                        $length = $end - $contentLength + 1; // Calculate new content length

                        //See if value range requested and return Partial Content headers
                        if($begin>0||$end<$contentLength){
                                //header("Accept-Ranges: $begin-$contentLength");
                                header("Accept-Ranges: bytes");
                                header('HTTP/1.1 206 Partial Content');
                                header("Content-Range: bytes $begin-$end/$contentLength");
                        }

                        //Return Remaining Headers
                        header('Content-Disposition: inline; filename="' . $filename . '"');
                        header("Last-Modified: $lastModified");
                        header("Content-type: $mimeType");
                        header('Content-length: '.($contentLength));
                        $etag = md5_file($path);
                        header('Etag: "'.$etag.'"');
                        header('Expires: ' . $this->getHttpDate(2147483647));
                        header('Cache-Control: public');

                        $cur=$begin;
                        fseek($fd,$begin,0);

                        while(!feof($fd)&&$cur<$end&&(connection_status()==0))
                        {
                                print fread($fd,min(1024*16,$end-$cur+1));
                                $cur+=1024*16;
                        }

                }
                return true;
        }

This code works fine with Gallery 2.3.1 and the IPhone OS 3.1

The following 3 lines have to be changed...

[...]
header("Accept-Ranges: bytes");
header('HTTP/1.1 206 Partial Content');
[...]
print fread($fd,min(1024*16,$end-$cur+1));

I don´t know whether this is totally correct and conform to standards, but the apache throws no errors and the videostreaming works fine on the phone and any browser.

I also don´t think that

header('Content-length: '.($contentLength));

is necessary or even correct, as my Apache adds this header on its own with the correct value.
$contentLength should be - at least in the else branch - wrong. The value should be $end-$begin+1.

Regards

 
scaturan
scaturan's picture

Joined: 2004-09-12
Posts: 1153
Posted: Sun, 2010-06-13 02:20

which iPhone client do you use to upload photos? preferably batch uploading - that's the only feature I am interested anyway. Please advise, thank you!
___________________________________________________
http://pixi.me/

 
suprsidr
suprsidr's picture

Joined: 2005-04-17
Posts: 8339
Posted: Fri, 2012-02-17 06:19

Comments are now permitted for this topic.

I've created a true module for this topic.
http://www.flashyourweb.com/filemgmt/index.php?id=51

 
suprsidr
suprsidr's picture

Joined: 2005-04-17
Posts: 8339
Posted: Fri, 2012-02-17 06:22

Comments are now locked for this topic.