Setting Content_Type

Discussion forum for Extension Writers regarding Extension Development.
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

Appendix A: Streaming for Apple iPhone wrote:Apple iPhone uses HTTP byte-ranges for requesting audio and video files. First, the Safari Web Browser requests the content, and if it’s an audio or video file it opens it’s media player. The media player then requests the first 2 bytes of the content, to ensure that the Webserver supports byte-range requests. Then, if it supports them, the iPhone’s media player requests the rest of the content by byte-ranges and plays it.
You need to handle byte-range requests. Also read here: http://stackoverflow.com/questions/3397 ... -for-video
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

This describes exactly what I am seeing in the Response headers!
kasimi wrote: You need to handle byte-range requests. Also read here: http://stackoverflow.com/questions/3397 ... -for-video
You mean, in phpBB? My Apache server apparently handles it, from the second example... I am not sure I would know how to start in PHP. With iOS having a large share of the mobile market, would this be something the phpBB team is already looking at?

Thank you for your very helpful reply.

Dan
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

shortmort37 wrote:You mean, in phpBB?
Yes. It should be pretty easy to do with Symfony's BinaryFileResponse class which handles the Content-Range and everything for you. You can find an example and how to include it here: http://symfony.com/doc/current/componen ... ving-files

After creating the $response object you call the send() method and exit the script. Not tested:

Code: Select all

if ($attachment_is_mp4)
{
    $filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
    $response = new BinaryFileResponse($filename);
    $response->send();
    exit;
}
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

You are awesome!! OK, I will play with this and see where it takes me.

Thanks!
Dan
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Wow, I've been distracted. Just now getting back to this. I modified functions_download.php to include the HTML5 code - just before the mimetype check - to invoke BinaryFileResponse and exit:

Code: Select all

	if (!@file_exists($filename))
	{
		send_status_line(404, 'Not Found');
		trigger_error('ERROR_NO_ATTACHMENT');
	}
	// *** Adding HTML5 audio/video content!  Caveat Emptor
	if (($category == ATTACHMENT_CATEGORY_HTML5)
		&& ((strpos($attachment['mimetype'], 'video') !== 0)||(strpos($attachment['mimetype'], 'audio') !== 0)))
	{
		$response = new BinaryFileResponse($filename);
		$response->send();
		exit;
	}
	// Correct the mime type - we force application/octetstream for all files, except images
	// Please do not change this, it is a security precaution
	if (($category != ATTACHMENT_CATEGORY_IMAGE || strpos($attachment['mimetype'], 'image') !== 0))
	{
		$attachment['mimetype'] = (strpos(strtolower($user->browser), 'msie') !== false || strpos(strtolower($user->browser), 'opera') !== false) ? 'application/octetstream' : 'application/octet-stream';
	}
But,to no avail. Here's an example:
http://www.59plymouth.net/59test/viewto ... f=3&t=2589
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

According to the docs, this should work:

Code: Select all

$response = new BinaryFileResponse($filename);
$response->prepare();
$response->send();
exit;
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Hmmm... Made the edit, cleared the cache, cleared the browser history.

Still no love.
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

You can set the content type manually like this:

Code: Select all

$response->headers->set('Content-Type', 'video/mp4');
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Still not happy...
Capture.JPG
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Also, while Symfony's BinaryFileResponse may handle range requests, it looks like this code towards the end of functions_download.php was designed to field range requests - No? And if so, why doesn't it work with iOS?

Code: Select all

		if ($fp !== false)
		{
			// Deliver file partially if requested
			if ($range = phpbb_http_byte_range($size))
			{
				fseek($fp, $range['byte_pos_start']);

				send_status_line(206, 'Partial Content');
				header('Content-Range: bytes ' . $range['byte_pos_start'] . '-' . $range['byte_pos_end'] . '/' . $range['bytes_total']);
				header('Content-Length: ' . $range['bytes_requested']);
			}

			while (!feof($fp))
			{
				echo fread($fp, 8192);
			}
			fclose($fp);
		}
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

When I try to download your test file I see this:

Code: Select all

Fatal error: Class 'BinaryFileResponse' not found in [...]/59test/includes/functions_download.php on line 139
You forgot to include it.

Code: Select all

use Symfony\Component\HttpFoundation\BinaryFileResponse; 
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Oops. Well, that would explain it. I admit to not knowing how namespaces work in PHP, and how it knows where to find that component. But that's OK, I don't know how you found the error either :oops:

That said, I added the use to the beginning of functions_download.php, cleared browser, cleared cache, still no love.
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

Download the video using the link below the video player and you'll see the error.

Apparently the prepare() method excepts the request object. Change it to this:

Code: Select all

global $request;
$response->prepare($request); 
User avatar
shortmort37
Registered User
Posts: 507
Joined: Sat Aug 26, 2006 8:40 pm
Location: Upper Darby, PA, USA
Name: Dan Morton
Contact:

Re: Setting Content_Type

Post by shortmort37 »

Hmm...
Catchable fatal error: Argument 1 passed to Symfony\Component\HttpFoundation\BinaryFileResponse::prepare() must be an instance of Symfony\Component\HttpFoundation\Request, instance of phpbb\request\request given, called in /home/sportf5/public_html/59test/includes/functions_download.php on line 142 and defined in /home/sportf5/public_html/59test/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/BinaryFileResponse.php on line 169
User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 4138
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: Setting Content_Type

Post by kasimi »

My bad:

Code: Select all

use phpbb\symfony_request;

global $request;
$response->prepare(new symfony_request($request));
Post Reply

Return to “Extension Writers Discussion”