问题标签 [android-mediaprojection]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
392 浏览

android - 如果从自己的活动启动,是否可以捕获安全的 Android 应用程序?

我正在寻找一种通过安全通道与服务器共享我的应用程序屏幕内容的方法。使用新的MediaProjection库似乎是一个完美的解决方案。

问题是,应用程序/它的视图必须被标记为安全的。

由于我是活动的所有者,是否有让我的 VirtualDisplay 成为受信任的显示器或忽略我的安全标志?目标是使我能够捕获屏幕,但没有其他人。

谢谢,

大卫

0 投票
1 回答
947 浏览

android - 缓冲 MediaProjection 的最后 X 分钟的最有效方法是什么

我在想一个有效的解决方案时遇到了一些麻烦。我预见到了一些问题,第一个是...

OOM 预防

如果我想要过去的 30 秒甚至 5 分钟,这是可行的,但如果我想要过去的 30 分钟或整小时,或者一切呢?保留字节缓冲区意味着将其存储在 RAM 中。存储超过 100 兆字节听起来像是虚拟内存自杀。

好吧,如果我们将之前录制的媒体的 Y 时间量(比如 30 秒)存储到磁盘中的某个 tmp 文件中,那该怎么办。这可能会起作用,我可以使用像 mp4 解析器这样的库在完成后将它们全部连接起来。然而...

如果我们有 30 分钟的价值,那就是大约 60 个 30 秒的剪辑。这似乎是一种烧录 SD 卡的好方法,即使这不是问题,我也无法想象将一百多个文件连接成一个文件所需的时间。

根据我一直在研究的内容,我正在考虑使用本地套接字来做类似的事情......

MediaRecorder -> setOutputFile(LocalSocket.getFD())

然后在本地套接字中......

LocalSocket -> FileOutputStream -> 写入(数据,位置,bufsiz) -> 刷新()

后台线程处理写入和跟踪位置以及缓冲区的位置。

这纯粹是伪代码,我还不足以测试它,我是否朝着正确的方向前进?从我的想法来看,这只保留一个被覆盖的文件。由于它每 Y 秒只被写入一次,因此它最大限度地减少了 IO 开销,并最大限度地减少了它占用的 RAM 量。

视频长度到缓冲区大小

我将如何从请求的视频大小中获取缓冲区的大小。这很奇怪,因为我看到一些长视频很小,但短视频很大。所以我不知道如何准确地确定这一点。如果我知道从 Media Recorder 设置的视频长度、编码等,任何人都知道如何预测这一点?

例子

有谁知道这方面的任何例子?我不认为这个想法是完全原创的,但我没有看到很多这样的想法,如果是这样,它就是闭源的。一个例子有很长的路要走。

提前致谢

0 投票
0 回答
691 浏览

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

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

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

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

感谢您提供的任何见解!

0 投票
3 回答
2842 浏览

android - android mediaprojection 截图包含黑框

我正在使用 MediaProjection 录制我的屏幕,如下所示

问题是捕获的图像包含如下图所示的黑框。

在此处输入图像描述

编辑

上述问题可以通过位图操作来解决。

但是,我现在正在寻找一种可以应用于MediaProjection或实现设备记录SurfaceView的解决方案。ImageReader

0 投票
2 回答
2716 浏览

android - 如何使用 Android 的 MediaProjection API 录制在 android 设备中输出的系统音频?

拜托,我想知道如何使用 Android 的 MediaProjection API 来记录在 android 设备中输出的系统声音?我要录制的系统声音是从某个用户应用程序、扬声器或耳机、Android 设备中输出的。

注意力:

“拜托,我不想用 Android 的 MediaProjection API 录制或捕捉屏幕,但我想用它录制系统声音。”!

“拜托,我想要一些 Java 代码行,解释如何使用 Android 的 Media Projection API。”!

MediaProjection API 网页是: http: //developer.android.com/intl/pt-br/reference/android/media/projection/MediaProjection.html,葡萄牙语-巴西语。而且,在英语中,它是:http: //developer.android.com/reference/android/media/projection/MediaProjection.html

感谢您的帮助。

最好的问候,
dsfbi_13052013。

0 投票
1 回答
1463 浏览

android - createScreenCaptureIntent 不返回结果

我正在尝试处理新的 Android Lollipop MediaProjection API。

我发现(至少在我的三星 Galaxy S4 jfltexx 股票上)当我开始打算获得捕获屏幕的权限时ProjectionManager.createScreenCaptureIntent()onActivityResult前面的尝试...

结果处理:

权限对话框显示良好,但我的活动被隐藏,它永远不会去onActivityResult

知道出了什么问题吗?

0 投票
0 回答
1092 浏览

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

我想将 Android 屏幕镜像到桌面网络浏览器。我能够使用 MediaProjection 捕获屏幕 - 多亏了示例应用程序。

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

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

谢谢

0 投票
2 回答
1147 浏览

android - MediaProjection 产生扭曲的屏幕截图

我设法得到截图,但结果是这样的:

截图制作

原来的:

原来的

这是我从几个来源获取的代码:

0 投票
0 回答
1185 浏览

android - 调整 VirtualDisplay 大小时调整 Surface 大小

前段时间我问了这个问题,得到了答案。

我已经按照答案建议实施了一个中介Surface,但现在我遇到了另一个问题。在我申请期间的某些时间点,我VirtualDisplay可以更改分辨率。所以,我还想更新中介的大小Surface以匹配VirtualDisplay. 我希望这将是setDefaultBufferSizeSurface's底层的简单调用SurfaceTexture,但这似乎不起作用。

我已经在释放我的中间体SurfaceSurfaceTexture制作新的中间体时四处寻找,但是我必须将输出表面设置为VirtualDisplaynull 并执行一些其他同步步骤,如果可能的话我想避免这些步骤。

有没有办法在创建后动态更新Surface/的大小SurfaceTexture

更新:

我尝试过调用VirtualDisplay.setSurface(null)VirtualDisplay.resize(newSize.width, newSize.height)然后向线程发送一条消息,该线程处理中介的回调以SurfaceTexture通过调整纹理大小setDefaultBufferSize,然后让主线程轮询辅助线程,直到该集合调用完成然后调用VirtualDisplay.setSurface(surfaceFromSecondaryThread)

这有时有效。其他时候,纹理全是绿色的,上面有一个灰色条(这也是我的 glClearColor,不确定这是否相关,如此处所示。有时在我的VirtualDisplay. 所以,这似乎是一个时间问题,但我不确定我应该等待什么时间。状态的文档setDefaultBufferSize

For OpenGL ES, the EGLSurface should be destroyed (via eglDestroySurface), made not-current (via eglMakeCurrent), and then recreated (via eglCreateWindowSurface) to ensure that the new default size has taken effect.

问题是我的代码没有从 SurfaceTexture/Surface 创建 EGLSurface,所以我无法销毁它。我假设生产者 ( VirtualDisplay) 确实如此,但是没有公共 API 可供我使用 EGLSurface。

[更新 2] 因此,当我看到问题(带条的绿屏、损坏,可能是因为我glClearColor的为绿色)时,如果我glReadPixels在调用之前执行 aeglSwapBuffers来写入Surfacefor the MediaCodec,我会读取绿色像素。这告诉我这不是MediaCodec问题,要么写入的信息SurfaceVirtualDisplay损坏(并且仍然损坏),要么从 YUV 空间到 RGBA 空间的转换从Surface-> OpenGL 纹理以某种方式损坏。我倾向于有一个问题VirtualDisplay

0 投票
1 回答
13243 浏览

android - Android ImageReader 获取 NV21 格式?

我没有图像或图形方面的背景,所以请多多包涵:)

我在我的一个项目中使用JavaCV。在示例中,Frame构造了具有一定大小的缓冲区的 a 。

public void onPreviewFrame(byte[] data, Camera camera)在Android中使用该函数时,data如果声明Framenew Frame(frameWidth, frameHeight, Frame.DEPTH_UBYTE, 2);whereframeWidthframeHeight声明为,复制这个字节数组是没有问题的

最近,Android 添加了一种捕获屏幕的方法。自然,我想抓取这些图像并将它们转换为Frames。我修改了 Google 的示例代码以使用ImageReader

ImageReader被构造为ImageReader.newInstance(DISPLAY_WIDTH, DISPLAY_HEIGHT, PixelFormat.RGBA_8888, 2);。所以目前它使用 RGBA_8888 像素格式。我使用以下代码将字节复制到Frame,实例化为new Frame(DISPLAY_WIDTH, DISPLAY_HEIGHT, Frame.DEPTH_UBYTE, 2);

但这给了我一个java.nio.BufferOverflowException. 我打印了两个缓冲区的大小,帧的缓冲区大小是 691200 而bytes上面的数组是 size 1413056。弄清楚后一个数字是如何构造的失败了,因为我遇到了这个 native call。很明显,这是行不通的。

经过一番挖掘,我发现NV21 图像格式是“相机预览图像的默认格式,当没有使用 setPreviewFormat(int) 设置时”,但是ImageReader 类不支持 NV21 格式(请参阅格式参数)。所以运气不好。在文档中还写道“对于 android.hardware.camera2 API,建议将 YUV_420_888 格式用于 YUV 输出。”

所以我尝试创建一个像这样的 ImageReader ImageReader.newInstance(DISPLAY_WIDTH, DISPLAY_HEIGHT, ImageFormat.YUV_420_888, 2);,但这给了我java.lang.UnsupportedOperationException: The producer output buffer format 0x1 doesn't match the ImageReader's configured buffer format 0x23.,所以这也行不通。

作为最后的手段,我尝试使用例如这篇文章将 RGBA_8888 转换为 YUV ,但我不明白如何根据答案获得int[] rgba答案。

那么,TL;DR我怎样才能获得 NV21 图像数据,就像你在 Android 的public void onPreviewFrame(byte[] data, Camera camera)相机功能中获得的一样,以实例化我Frame并使用 Android 的 ImageReader(和媒体投影)使用它?

编辑(25-10-2016)

我创建了以下可运行的转换以从 RGBA 转换为 NV21 格式:

yuvImage对象初始化为yuvImage = new Frame(DISPLAY_WIDTH, DISPLAY_HEIGHT, Frame.DEPTH_UBYTE, 2);DISPLAY_WIDTHDISPLAY_HEIGHT只是指定显示大小的两个整数。这是后台处理程序处理 onImageReady 的代码:

这些方法有效,我至少没有收到任何错误,但输出图像格式错误。我的转换出了什么问题?正在创建的示例图像:

畸形图像示例

编辑(15-11-2016)

我已将RGBtoNV21函数修改为以下内容:

现在图像不再畸形,但色度已关闭。

错误的色度

右侧是在该循环中创建的位图,左侧是保存到图像的 NV21。所以RGB像素被正确处理。显然色度已关闭,但 RGB 到 YUV 的转换应该与维基百科描述的相同。这里有什么问题?