标签: android-mediaprojection

如何在android中使用Mediaprojection库来捕获屏幕并转换成mp4文件?

从Android 5.0开始,他们提供媒体投影库来捕获屏幕内容.但他们提供的示例演示应用程序并不清楚.您可以在此处找到示例应用.在该应用程序中,他们使用virtualdisplay方法投影捕获的屏幕

private void setUpVirtualDisplay() {
    Log.i(TAG, "Setting up a VirtualDisplay: " +
            mSurfaceView.getWidth() + "x" + mSurfaceView.getHeight() +
            " (" + mScreenDensity + ")");
    mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
            mSurfaceView.getWidth(), mSurfaceView.getHeight(), mScreenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mSurface, null, null);
    mButtonToggle.setText(R.string.stop);
}
Run Code Online (Sandbox Code Playgroud)

我想将捕获的屏幕转换为mp4文件,用于我的屏幕录制应用程序.请帮我解决这个问题.

android android-mediarecorder android-mediaprojection

6
推荐指数
1
解决办法
7715
查看次数

Android MediaProjection屏幕通过USB镜像到Web浏览器

我想将Android Screen镜像到桌面Web浏览器.我能够使用MediaProjection捕获屏幕 - 感谢示例应用程序.

但下一部分很难 - 将捕获的数据发送到桌面!我知道通过ADB端口转发建立到桌面程序的HTTP连接的技术,但我猜FPS将非常低.

如何将捕获的屏幕数据流式传输到桌面?我需要什么样的连接以及Android端需要哪些编解码器以确保速度?

谢谢

android video-streaming android-mediaprojection

6
推荐指数
0
解决办法
942
查看次数

使用媒体投影 API 在设备之间共享屏幕

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

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

我知道媒体投影 API 用于屏幕录制,但我只想在录制时共享屏幕。

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

下面是代码:

OutputStream outStream;
Run Code Online (Sandbox Code Playgroud)

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();
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

private class …
Run Code Online (Sandbox Code Playgroud)

android mediamuxer android-mediaprojection android-mediacodec

6
推荐指数
1
解决办法
2134
查看次数

如何从屏幕截图中排除叠加?

基于这个答案,我认为至少对于系统应用程序(或者也可能在有根设备中?)存在一个解决方案。碰巧我不明白答案注释上链接的代码示例。有人可以解释一步一步来实现这一点(如果可能,请提供代码示例)?提前致谢。

android overlay android-studio android-mediaprojection

6
推荐指数
0
解决办法
313
查看次数

在 Android 14 上重用媒体投影 Intent

我有一个 Android 屏幕录制应用程序。在我的应用程序中,用户可以直接在应用程序中启动屏幕录制,也可以通过通知中的按钮(绑定到前台服务)启动屏幕录制。

要开始录制,我通过屏幕录制系统对话框检索创建媒体投影的意图: startActivityForResult(activity, mediaProjectionManager.createScreenCaptureIntent(), requestId)

此意图稍后用于创建 MediaProjection,该 MediaProjection 再次用于获取VirtualDisplay屏幕录制的 a 。

为了避免每次用户通过前台服务的通知开始录制时都必须启动屏幕录制系统对话框,我保存了原始文件Intent以在服务中创建媒体投影,然后只需重复使用该文件即可Intent。这在 Android 14 (API 34) 之前都可以正常工作。

在使用 Android 14 预览版进行测试时,我发现这似乎不再可能了。根据抛出的异常,不再允许检索MediaProjection具有相同的Intent或创建具有相同的多个虚拟显示器MediaProjection

FATAL EXCEPTION: main
Process: com.recording.app.staging, PID: 19029
                 java.lang.SecurityException: Don't re-use the resultData to retrieve the same projection instance, and don't use a token that has timed out. Don't take multiple captures by invoking MediaProjection#createVirtualDisplay multiple times on the same instance.
                    at android.os.Parcel.createExceptionOrNull(Parcel.java:3057)
                    at android.os.Parcel.createException(Parcel.java:3041)
                    at …
Run Code Online (Sandbox Code Playgroud)

android android-mediaprojection android-14

6
推荐指数
0
解决办法
1245
查看次数

屏幕截图与后台服务

我开始使用Lollipop&Media.Projection类来实现一个屏幕共享应用程序.来自Google的演示项目非常适合我理解Lollipop的这一新功能.但后来我发现很难让屏幕捕获变为背景,因为一直按下Home或Back按钮,表面活动就会被破坏,因此捕获线程将不再起作用.这种情况有什么暗示吗?

android background-service android-5.0-lollipop android-mediaprojection

5
推荐指数
1
解决办法
2918
查看次数

使用Android MediaProjection API的输出作为libjingle WebRTC库的源?

我正在尝试创建一个Android应用程序,该应用程序利用libjingle WebRTC原生Android库,使用WebRTC将用户Android桌面投影到对等方.为此,我已成功使用pristine.io libjingle镜像重新创建Android apprtc示例应用程序:

compile 'io.pristine:libjingle:10531@aar'
Run Code Online (Sandbox Code Playgroud)

在我的应用程序build.gradle文件中.apprtc示例适用于https://apprtc.appspot.com/演示网站.我还创建了一个单独的应用程序,使用MediaProjectionAndroid API 21中引入的库,按照此处发布的示例,将用户的屏幕记录为H.264编码的mp4文件.

现在,我想将这两个想法结合到一个应用程序中,该应用程序利用来自MediaProjectionMediaRecorder/或至少H.264编码文件的原始流作为WebRTC对等连接的视频/音频流.这甚至可能吗?PeerConnection.addStreamlibjingle中的方法需要一个实例MediaStream.如何MediaStream从原始流或生成的mp4文件创建类型对象?

感谢您提供的任何见解!

android libjingle webrtc android-mediaprojection

5
推荐指数
0
解决办法
610
查看次数

Android调整VirtualDisplay的大小

使用Android的MediaProjection API,我遇到了一些问题(实际上更多,但这些问题更为重要).阅读图形架构并不会有所帮助,所以我只想了解我是否在代码流中跳过了某些内容.

我们假设:

  1. 我有一个专门的GL渲染线程,初始化,并在其上生成GL纹理.我为纹理设置了默认缓冲区大小WxH.

  2. 我使用GL纹理创建SurfaceTexture,为此表面纹理创建Surface.

  3. 通过MediaProjection创建大小为WxH的虚拟显示,并将其曲面设置为上表面.

问题1:一切都运行正常(全帧正确进入)或不正常(所有帧都是黑色;或者每帧只有一半是可见的 - 所有帧的相同一半;或者屏幕的某些部分重复到其他帧部分,有时甚至是倾斜的).

问题2:在一些全屏幕GL游戏中花费时间,在一段固定的时间(大约4分钟)之后,所有传入的帧都被冻结(例如我收到"新"帧,但实际上是同一个图像) .用glReadPixels读取确认结果 - 问题是,实际显示是超过该帧.强制它"恢复"的唯一方法是调出状态栏或导航栏,立即开始向我发送正确的帧.当然,又过了4分钟,又发生了......

问题3:调用VirtualDisplay上的resize(),同时调用setDefaultBUfferSize()到GL纹理后,最终在90%的情况下展示问题#1(黑色/切割帧,其他屏幕区域的工件...... )

我正在使用updateTextureImage的调用序列 - > GL纹理绘制在同一个线程中,所以我的正常理解是它永远不应该发生我以某种方式从半满的GL缓冲区读取,或者某事......对吗?

我也通过将VirtualDisplay直接渲染到MediaCodec的表面(没有涉及自定义GL)来测试这个问题 - 相同的行为. 更新实际上由于MediaCodec有一个固定大小的创建表面,因此我们只能调整虚拟显示器的大小,而不是编码器的表面大小,因此无法重现该错误,所以这不是一个真正的错误(但即便如此,它也会很好VirtualDisplay以某种方式相应地调整表面大小).

我觉得在关闭虚拟显示器时有些东西在泄漏,或者在VirtualDisplay的创建之间没有正确初始化,因为它不一致.很有可能一个全新的MediaProjection屏幕捕获权限,全新的虚拟显示器,刚刚创建的表面纹理,最终只会给我一半的框架......让我有一个大的扑克脸. ..

PS:所有这一切都发生在带有Android 6.0.1的Nexus 6上.

android mediacodec android-mediaprojection

5
推荐指数
1
解决办法
1085
查看次数

通过 MediaProjection 进行 ScreenCapture,无需用户干预 Kiosk 应用程序 - Android

我在一家数字标牌公司工作,该公司的 Android 设备以自助服务终端模式运行。最近,我们想添加用于调试的屏幕截图。最简单的方法是使用

getWindow().getDecorView().getRootView().getDrawingCache()

创建位图并通过网络发送它,但这不会捕获视频,因为它是在表面视图中呈现的。

MediaProjection 的 createVirtualDisplay 看起来很有希望,但使用此功能所需的明确许可是不可接受的。即使是第一次请求用户许可并保留结果以供进一步使用也是不可接受的,因为这会破坏现有的实现。

请帮我解决这个问题。

注意:那里的所有设备,要么是 root,要么,我们的应用程序作为设备所有者运行,并且 android 版本高于 4.4

screen-capture user-permissions rooted-device device-owner android-mediaprojection

5
推荐指数
0
解决办法
339
查看次数

Android 9+ 上的媒体投影问题

我制作了一个 OCR 应用程序,它使用 Android mediaprojection 制作屏幕截图并处理此图像中的文本。这工作正常,除了在 Android 9+ 上。当 mediaprojeciton 启动时,总​​会弹出一个窗口,警告可能记录的敏感数据,以及一个取消或开始记录的按钮。我怎样才能实现这个窗口只显示一次?

我尝试通过创建两个额外的私有静态变量来存储媒体投影的意图和结果数据,并在它不为空时重用它来防止它弹出。但它不起作用(在另一篇文章中阅读了有关此方法的信息)。

弹出窗口

// initializing MP

  mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);

// Starting MediaProjection

 private void startProjection() {
     startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
 }


// OnActivityResult
 protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {

    if (requestCode == 100) {
        if(mProjectionManager == null) {
            cancelEverything();
            return;
        }

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                if(mProjectionManager != null)
                sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
                else
                    cancelEverything();
                if (sMediaProjection != null) {
                    File externalFilesDir …
Run Code Online (Sandbox Code Playgroud)

permissions android android-mediaprojection android-9.0-pie android-10.0

5
推荐指数
1
解决办法
3436
查看次数