Fix 3gp header for a streamed video through socket
===

I have a problem with my streamed video from Android to my php server. I can't play my video whatever player i use because the moov atom is missing. I followed the tutorial of <a href="http://www.mattakis.com/blog/kisg/20090708/broadcasting-video-with-android-without-writing-to-the-file-system">Mattakis</a> to stream my video and a little php script to re-encode the header of the received 3gp video.

Android side:

    s = new Socket("192.168.1.5", 6000);
			ParcelFileDescriptor pfd= ParcelFileDescriptor.fromSocket(s);
			recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
			recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
			recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
			recorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
			recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
			recorder.setVideoEncodingBitRate(512 * 1000);
			recorder.setVideoFrameRate(30);
			recorder.setVideoSize(320, 240);
			recorder.setOutputFile(pfd.getFileDescriptor());

Php Script : I used the script in the third Update of <a href="http://stackoverflow.com/questions/10071768/video-streaming-from-android-device-to-lamp-server">this</a> link

Code :

     #!/usr/bin/php5
    <?php


		$socket = stream_socket_server("tcp://192.168.0.102:9000", $errno, $errstr);  
 
     $file = "saved.3gp";

    $threegp_header = "\x00\x00\x00\x18\x66\x74\x79\x70\x33\x67\x70\x34\x00\x00\x03\x00\x33\x67\x70\x34\x33\x67\x70\x36";
     $four_bytes = "\x00\x00\x00\x00";
    if (!$socket) {

	echo "$errstr ($errno)\n";

    } else {

	echo "server start listening\n";

	while ( $conn = @stream_socket_accept($socket, 180))
	{
		echo "phone connected\n";

		$handle = fopen($file,"w");

		//mediaRecorder gives invalid stream header, so I replace it discarding first 32 
		byte, replacing with 28 good byte (standard 3gp header plus 4 empty bytes)
		$discard = stream_get_contents($conn, 32);
		fwrite($handle, $threegp_header);
		fwrite($handle, $four_bytes);

		//then confinue to write stream on file until phone stop streaming
		while(!feof($conn))
		{
			fwrite($handle, stream_get_contents($conn, 1500));
		}
		echo "phone disconnected\n";
		fclose($handle);

		//then i had to update 3gp header (bytes 25 to 28) with the offset where moov atom 
		starts
		$handle = fopen($file,"c"); 
		$output = shell_exec('grep -aobE "moov" '.$file);
		$moov_pos = preg_replace('/moov:(\d+)/i', '\\1', $output);
		$moov_pos_ex = strtoupper(str_pad(dechex($moov_pos - 24), 8, "0", STR_PAD_LEFT));
		fwrite($handle, $threegp_header);
		$tmp = '';
		foreach(str_split($moov_pos_ex,2) as $hex)
		{
			$tmp .= pack('C*', hexdec($hex));
		}
		fwrite($handle, $tmp);
		fclose($handle);


	}
	echo "phone disconnected\n";


     }
     @fclose($handle);
     fclose($socket);
     ?>

i tried also to re-encode the header manually after saving the whole file but it doesn't work.
     