如何使用spydroid库和媒体投影实现Android镜像应用程序?

时间:2015-06-28 08:28:36

标签: android video rtp

我想知道如何通过RTP发送我的屏幕?这是我的方法。

首先,我使用媒体投影来捕捉我的屏幕。引用的网址为http://mattsnider.com/video-recording-with-mediaprojectionmanager/

其次,我正在使用并尝试修改spydroid库,以流式传输我的屏幕而不是摄像头视图。

引用的网址为https://github.com/fyhertz/spydroid-ipcamera

我使用媒体投影完成了屏幕截图。以下是示例代码的一部分。

private boolean drainEncoder() {
    mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
    while (true) {
        int bufferIndex = mVideoEncoder.dequeueOutputBuffer(mVideoBufferInfo, 0);

        if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
            // nothing available yet
            break;
        }
        else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            // should happen before receiving buffers, and should only happen once
            if (mTrackIndex >= 0) {
                throw new RuntimeException("format changed twice");
            }
            mTrackIndex = mMuxer.addTrack(mVideoEncoder.getOutputFormat());
            if (!mMuxerStarted && mTrackIndex >= 0) {
                mMuxer.start();
                mMuxerStarted = true;
            }
        }
        else if (bufferIndex < 0) {
            // not sure what's going on, ignore it
        }
        else {
            ByteBuffer encodedData = mVideoEncoder.getOutputBuffer(bufferIndex);
            if (encodedData == null) {
                throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex);
            }

            if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                mVideoBufferInfo.size = 0;
            }

            if (mVideoBufferInfo.size != 0) {
                if (mMuxerStarted) {
                    encodedData.position(mVideoBufferInfo.offset);
                    encodedData.limit(mVideoBufferInfo.offset + mVideoBufferInfo.size);
                    mMuxer.writeSampleData(mTrackIndex, encodedData, mVideoBufferInfo);
                }
                else {
                    // muxer not started
                }
            }

            mVideoEncoder.releaseOutputBuffer(bufferIndex, false);

            if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                break;
            }
        }
    }
}

如您所见,

mMuxer.writeSampleData(mTrackIndex, encodedData, mVideoBufferInfo);

如果可以通过RTP发送encodedData,那么镜像将正常工作。

这是spydroid代码,VideoStream.Java

protected void encodeWithMediaRecorder() throws IOException {
    Log.d(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(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mMediaRecorder.setVideoEncoder(mVideoEncoder);
        mMediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
        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 ouput 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
        mMediaRecorder.setOutputFile(mSender.getFileDescriptor());

        mMediaRecorder.prepare();
        mMediaRecorder.start();
    }
    catch (Exception e) {
        throw new ConfNotSupportedException(e.getMessage());
    }

    // This will skip the MPEG4 header if this step fails we can't stream anything :(
    InputStream is = mReceiver.getInputStream();
    try {
        byte buffer[] = new byte[4];
        // Skip all atoms preceding mdat atom
        while (!Thread.interrupted()) {
            while (is.read() != 'm') ;
            is.read(buffer, 0, 3);
            if (buffer[0] == 'd' && buffer[1] == 'a' && buffer[2] == 't') break;
        }
    }
    catch (IOException e) {
        Log.e(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.setDestination(mDestination, mRtpPort, mRtcpPort);
    mPacketizer.setInputStream(mReceiver.getInputStream());
    mPacketizer.start();

    mStreaming = true;
}

有人可以告诉我吗?更多信息如何修改spydroid库来发送镜像数据?

0 个答案:

没有答案