Thomas SIMON 表示,这个官方示例项目(Github.com/android/camera-samples/tree/mAIn/Camera2Basic)的作用只有「显示摄像头、并拍摄一张照片」,但是没想到它包含了很多文件 。

文章插图
仅以 gradle 为关键词搜索,就有一大堆文件:
$:/tmp/Camera2Basic$ find . -type f -name "_gradle_" ./gradlew.bat ./gradle.properties ./gradlew ./settings.gradle ./utils/build.gradle ./gradle/wrapper/gradle-wrapper.jar ./gradle/wrapper/gradle-wrapper.properties ./build.gradle ./app/build.gradleThomas SIMON 表示,自己不可能花时间去慢慢理解这些东西,他只是要修改一些代码,来实现自己想要的功能 。
不过,还没等他开始寻找代码片段,Android Studio 就开始跳出了一个提示:
"不支持 JAVA,点击此处更新 gradle thingy" 。
于是,事情似乎进入了循环:
Thomas SIMON 点击 。
事情发生了变化,左侧窗格中的文件改变了结构,标签页反复打开和关闭 。
"建议更新项目,点击启动 AGP 升级助手”
Thomas SIMON 继续点击:
显示许多选项,其中一些已预选,一个按钮上写着 "运行选定步骤" 。
Thomas SIMON 再次点击:
事情发生了变化,左侧窗格中的文件改变了结构,选项卡反复打开和关闭 。
"建议更新项目,单击启动 AGP 升级助手
Thomas SIMON 点击:
显示大量选项,其中一些已预选,一个按钮显示 "运行选定步骤" 。
Thomas SIMON 继续点击:
事情发生了变化,左侧窗格中的文件改变了结构,标签反复打开和关闭 。
Thomas SIMON 无语道,“这是一款很棒的点击冒险游戏 。”
折腾了一会,Thomas SIMON 的 AGP 和 gradle 终于不再跳出更新提示 。
接下来,正式进入代码部分 。
写过不少 Java 和 Scala 代码的 Thomas SIMON 发现这部分的代码是用 Kotlin 写的 。
“从这里开始,我喜欢我所看到的,代码很清晰 。它在 xml 中定义一个视图,在代码中用标识符与之关联,非常标准且可预测 。清晰的代码让我不需要学习任何东西就能提高工作效率”,Thomas SIMON 说道 。
紧接着,Thomas SIMON 调用一个 Android API 来制作一个简单的 http 服务器,然后把它插入、测试,它就能工作了!
现在,Thomas SIMON 的电脑浏览器标签页上有一个 mjpeg 流 。对于实时调用来说,质量和延迟都还可以 。这样,他就可以在终端输入一行命令将其转换为 Linux 网络摄像头设备:
ffmpeg -f mjpeg -i "http://192.168.1.2:8080" -vf "format=yuv420p" -f v4l2 /dev/video0整体而言,Thomas SIMON 表示,网络世界虽然有一些不必要的步骤和配置,但这个 Android 世界简直是疯了 。
他下载了官方示例之后,删除了未使用的视图,添加了选择相机、分辨率和质量的下拉菜单,将所有功能移至前台服务,以便在锁定手机的情况下保持激活状态,并将其发布在 GitHub 上(https://github.com/Ruddle/RemoteCam),整个项目花了他两个下午的时间(其中大部分时间都在了解 Android 希望你怎么做) 。
实际工作量应该如何?
Thomas SIMON 认为,在理想的情况下,在手机端,只需一行代码就足够了,根本不需要上面那样复杂的操作 。倘若我们想编写一个应用程序,只是为了准确地指定数据流,而不是依赖天才们已经开发出来的高级工具(如桌面上的 ffmpeg 和 v4l2) 。
在理想的世界里,具有这种规格的 App 应具备:
- 允许配置相机、分辨率和质量/比特率
- 没有设计,只有原始功能
- 在本地网络上传输帧流
1CAMERA.getPermission orquit
.NETWORK.getPermission orquit
3
4queue=Producer(size= 1)
5
6server = NETWORK.createHttpServer(port = 8080)
7server.onRequest = req ->
8queue.dropConsumers //only allows 1client, drop old ones
9req.sendHeader( "Content-Type", "multipart/x-mixed-replace;boundary=FRAME")
10queue.consumeUntilDrop( frame, consumer ->
11data =https://www.isolves.com/it/cxkf/ydd/Android/2023-08-21/ "--FRAME=rnContent-Type=image/jpegrn".bytes+frame.bytes
12req.sendBytes(data) orqueue.drop(consumer)
13frame. close// Free camera memory of this frame
推荐阅读
- 女流量top2!杨紫赵丽颖被认为可以把握市场流量,角色风格迥异!
- qq空间视频怎么保存到手机苹果手机 qq空间视频怎么保存到手机
- 手机对方听不到我说话怎么回事 荣耀手机对方听不到我说话怎么回事
- 手机耳机孔坏了解决方法
- 怎么取消来电提醒 苹果手机怎么取消来电提醒
- 李维嘉独居一人吃火锅,进门擦鞋底有洁癖,海涛:别把自己逼太紧
- 三维图怎么看 机械三维图怎么看
- 《好声音》导演柳骊:上海房产一条街、英国城堡,见面要没收手机
- 为何手机都不支持存储卡了?
- 手机耗电快怎么办?
