Camera4Kivy在Kivy/Android环境下视频录制功能失效求助
Kivy/Android下Camera4Kivy视频录制失败的解决方案
问题根源
从报错信息来看,核心是**VideoCapture对象未初始化(空指针)**,导致调用startRecording和stopRecording时抛出异常。引发这个问题的主要原因有两个:
- 相机连接是异步操作,你在
build方法中直接调用connect_camera后立刻执行select_camera和capture_video,此时相机服务还未完成初始化,相关对象还未创建。 - 缺少必要的Android权限,相机或存储权限未授权会导致相机服务无法正常启动。
整理后的报错信息(中文)
07-21 16:17:14.405 28320 29758 I python : JVM异常发生: 尝试调用空对象的虚拟方法 'void androidx.camera.core.VideoCapture.startRecording(...)',空指针异常 07-21 16:17:14.406 28320 28320 I python : 回溯(最近的调用在最后): ... jnius.jnius.JavaException: JVM异常发生:尝试调用空对象的虚拟方法 'void androidx.camera.lifecycle.ProcessCameraProvider.unbindAll()',空指针异常 ... jnius.jnius.JavaException: JVM异常发生:尝试调用空对象的虚拟方法 'void androidx.camera.core.VideoCapture.stopRecording()',空指针异常
修复方案
1. 添加必要的Android权限
在你的buildozer.spec文件中添加以下权限:
android.permissions = CAMERA, RECORD_AUDIO, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE android.api = 33 android.apptheme = @android:style/Theme.Material.Light.NoActionBar.Fullscreen
2. 等待相机就绪后再执行操作
Camera4Kivy的connect_camera是异步的,必须等待相机就绪事件触发后,再执行选择相机、录制视频的操作。通过重写on_camera_ready方法来处理后续逻辑:
修改后的代码:
from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.uix.button import Button from camera4kivy.preview import Preview class CamApp(App): def build(self): self.cam = Preview() # 绑定相机就绪事件 self.cam.bind(on_camera_ready=self.on_camera_ready) self.cam.connect_camera(enable_analyze_pixels=True) box1 = BoxLayout(orientation='vertical') box1.add_widget(self.cam) # 添加按钮控制录制,避免自动录制导致的问题 self.record_btn = Button(text="开始录制", size_hint=(1, 0.1)) self.record_btn.bind(on_press=self.toggle_recording) box1.add_widget(self.record_btn) self.is_recording = False return box1 def on_camera_ready(self, instance, value): # 相机就绪后再选择相机 self.cam.select_camera('1') # '0'通常是前置,'1'是后置,根据设备调整 def toggle_recording(self, instance): if not self.is_recording: try: # 开始录制 self.cam.capture_video(location='shared', subdir='myapp', name='myvid') self.record_btn.text = "停止录制" self.is_recording = True except Exception as e: print(f"录制启动失败: {e}") else: # 停止录制 self.cam.stop_capture_video() self.record_btn.text = "开始录制" self.is_recording = False def on_stop(self): if self.is_recording: self.cam.stop_capture_video() self.cam.disconnect_camera() return super().on_stop() if __name__ == '__main__': CamApp().run()
3. 关键调整说明
- 移除
build方法中直接调用select_camera和capture_video的代码,改为在on_camera_ready事件触发后执行相机选择。 - 添加按钮手动控制录制的开始和停止,避免应用启动时自动录制可能引发的未初始化问题。
- 在应用停止时检查是否正在录制,确保停止录制后再断开相机。
内容的提问来源于stack exchange,提问作者Mohammad Mujtaba Oria
相关产品推荐
相关产品推荐

