protected override void encodeWithMediaRecorder() { // We need a local socket to forward data output by the camera to the packetizer createSockets(); Android.Util.Log.v(TAG, "Requested audio with " + mQuality.bitRate / 1000 + "kbps" + " at " + mQuality.samplingRate / 1000 + "kHz"); mMediaRecorder = new MediaRecorder(); mMediaRecorder.SetAudioSource((AudioSource)mAudioSource); mMediaRecorder.SetOutputFormat((OutputFormat)mOutputFormat); mMediaRecorder.SetAudioEncoder((AudioEncoder)mAudioEncoder); mMediaRecorder.SetAudioChannels(1); mMediaRecorder.SetAudioSamplingRate(mQuality.samplingRate); mMediaRecorder.SetAudioEncodingBitRate(mQuality.bitRate); // We write the output of the camera in a local socket instead of a file ! // This one little trick makes streaming feasible quiet simply: data from the camera // can then be manipulated at the other end of the socket FileDescriptor fd = null; if (sPipeApi == PIPE_API_PFD) { fd = mParcelWrite.FileDescriptor; } else { fd = mSender.FileDescriptor; } mMediaRecorder.SetOutputFile(fd); mMediaRecorder.SetOutputFile(fd); mMediaRecorder.Prepare(); mMediaRecorder.Start(); InputStream iStream = null; if (sPipeApi == PIPE_API_PFD) { iStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelRead); } else { try { // mReceiver.getInputStream contains the data from the camera iStream = mReceiver.InputStream; } catch (IOException e) { stop(); throw new IOException("Something happened with the local sockets :/ Start failed !"); } } // the mPacketizer encapsulates this stream in an RTP stream and send it over the network mPacketizer.setInputStream(iStream); mPacketizer.start(); mStreaming = true; }
/** * Video encoding is done by a MediaRecorder. */ protected override void encodeWithMediaRecorder() { Log.Debug(TAG,"Video encoded using the MediaRecorder API"); // We need a local socket to forward data output by the camera to the packetizer createSockets(); // Reopens the camera if needed destroyCamera(); createCamera(); // The camera must be unlocked before the MediaRecorder can use it unlockCamera(); try { mMediaRecorder = new MediaRecorder(); mMediaRecorder.SetCamera(mCamera); mMediaRecorder.SetVideoSource(VideoSource.Camera); mMediaRecorder.SetOutputFormat(OutputFormat.ThreeGpp); mMediaRecorder.SetVideoEncoder((VideoEncoder) mVideoEncoder); mMediaRecorder.SetPreviewDisplay(mSurfaceView.Holder.Surface); mMediaRecorder.SetVideoSize(mRequestedQuality.resX,mRequestedQuality.resY); mMediaRecorder.SetVideoFrameRate(mRequestedQuality.framerate); // The bandwidth actually consumed is often above what was requested mMediaRecorder.SetVideoEncodingBitRate((int)(mRequestedQuality.bitrate*0.8)); // We write the output of the camera in a local socket instead of a file ! // This one little trick makes streaming feasible quiet simply: data from the camera // can then be manipulated at the other end of the socket FileDescriptor fd = null; if (sPipeApi == PIPE_API_PFD) { fd = mParcelWrite.FileDescriptor; } else { fd = mSender.FileDescriptor; } mMediaRecorder.SetOutputFile(fd); mMediaRecorder.Prepare(); mMediaRecorder.Start(); } catch (System.Exception e) { throw new ConfNotSupportedException(e.Message); } InputStream inputStream = null; System.IO.Stream inputSStream = null; if (sPipeApi == PIPE_API_PFD) { inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelRead); } else { inputSStream = mReceiver.InputStream; } // This will skip the MPEG4 header if this step fails we can't stream anything :( try { byte[] buffer = new byte[4]; // Skip all atoms preceding mdat atom while (!Thread.Interrupted()) { if (inputSStream != null) { while (inputSStream.ReadByte() != 'm') ; inputSStream.Read(buffer, 0, 3); } else { while (inputStream.Read() != 'm'); inputStream.Read(buffer,0,3); } if (buffer[0] == 'd' && buffer[1] == 'a' && buffer[2] == 't') break; } } catch (IOException e) { Log.Error(TAG,"Couldn't skip mp4 header :/"); stop(); throw e; } // The packetizer encapsulates the bit stream in an RTP stream and send it over the network mPacketizer.setInputStream(inputStream); mPacketizer.setInputSStream(inputSStream); mPacketizer.start(); mStreaming = true; }