【问题标题】:Screen Sharing between Devices using Media Projection API使用 Media Projection API 在设备之间共享屏幕
【发布时间】:2018-11-17 00:26:32
【问题描述】:

我正在开发一款具有与其他应用共享屏幕功能的应用。

我为此使用了媒体投影 API。我还使用 MediaMuxer 来组合音频和视频输出以进行屏幕共享。

我知道 Media Projection API 用于屏幕录制,但我只想在录制时共享屏幕。

为此,我修改了 MediaMuxer 类的 writeSampleData 方法,以通过套接字将字节发送到网络上的其他设备。

下面是代码:

OutputStream outStream;

outStream = ScreenRecordingActivity.getInstance().socket.getOutputStream();

void writeSampleData(final int trackIndex, final ByteBuffer byteBuf, final MediaCodec.BufferInfo bufferInfo) {
    if (mStatredCount > 0) {
        mMediaMuxer.writeSampleData(trackIndex, byteBuf, bufferInfo);

        if (bufferInfo.size != 0) {

            byteBuf.position(bufferInfo.offset);
            byteBuf.limit(bufferInfo.offset + bufferInfo.size);

            if (outStream != null) {

                try {

                    byte[] bytes = new byte[byteBuf.remaining()];
                    byteBuf.get(bytes);

                    //Send the data
                    outStream.write(bytes);
                    outStream.flush();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

字节通过套接字成功传输,我也能够在接收端接收这些字节。

下面是接收端接收字节的代码:

private class SocketThread implements Runnable {
    @Override
    public void run() {

        Socket socket;
        try {
            serverSocket = new ServerSocket(SERVER_PORT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (null != serverSocket) {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    socket = serverSocket.accept();
                    CommunicationThread commThread = new CommunicationThread(socket);
                    new Thread(commThread).start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    class CommunicationThread implements Runnable {

        InputStream in;
        DataInputStream dis;

        public CommunicationThread(Socket clientSocket) {


            updateMessage("Server Started...");
        }

        public void run() {           

            while (!Thread.currentThread().isInterrupted()) {

                try {                       

                    byte[] data = new byte[512];               

                } catch (Exception e) {                    

                    e.printStackTrace();

                    try {
                        fos.close();
                    } catch (Exception e1) {

                        e1.printStackTrace();
                    }
                }
            }
        }
    }
}

我点击以下链接进行屏幕共享:

Screen capture

screenrecorder

Screen recording with mediaProjection

我使用上述示例中的一些代码来制作应用程序。

我只想知道如何在接收端处理字节。如何格式化这些字节以从发送方播放实时流?

我是否遵循发送和接收字节数据的正确方法?

MediaProjection 是否允许在应用程序之间录制时流式传输屏幕?

任何帮助将不胜感激。

【问题讨论】:

  • Media projection api 在 iOS 中使用原生 swift 代码工作有没有可能?

标签: android android-mediacodec mediamuxer android-mediaprojection


【解决方案1】:

通常对于流媒体,包括屏幕共享,音频和视频轨道不会被混合。相反,每个视频帧和音频样本都使用诸如 RTP/RTSP 之类的协议发送,其中每个数据块都使用时间戳等其他内容进行包装。

您可以查看spyadroid,这是通过 RTSP 将音频和视频流式传输到浏览器或 VLC 的良好起点。它流式传输摄像头和麦克风,但您可以根据自己的用例对其进行调整。

如果你暂时想使用套接字,你必须摆脱MediaMuxer 并直接从编码器输出发送帧/样本,至少附加时间戳以同步在发送 CSD 后在接收器端播放 - 假设您以 h.264 格式编码 - 数据(SPS PPS aka csd-0 和 csd-1,当encoder format is changed 时可以获得)到接收器解码器,你可以configure with an output surface 来渲染你的流。

一些额外的链接:

android-h264-stream-demo

RTMP Java Muxer for Android

RTSP

RTP

WebRTC

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多