최근에 3개의 응용 프로그램(웹 브라우저, 화상 회의 응용 프로그램 및 스트림 저장을 위한 ffmpeg)에서 동시에 공유할 웹캠이 필요했습니다.
/dev/video* 스트림을 단순히 공유하는 것은 불가능합니다. 한 응용 프로그램에서 이를 사용하면 다른 응용 프로그램에서는 이를 사용할 수 없고 다른 모든 응용 프로그램에서는 "장치 또는 리소스 사용 중" 또는 이와 유사한 상태가 발생하기 때문입니다.
그래서 웹캠을 3개의 루프백으로 미러링할 목적으로 v4l2-loopback으로 전환했습니다.
3개의 루프백을 사용하면 예상대로 작동했지만 정말 놀랐던 점은 실제로는 그렇지 않았다는 것입니다.필요3개의 루프백이 있지만 1개만 있습니다.
루프백을 만들고 ffmpeg로 제공하면단일 미러 루프백사용할 수 있다3가지 애플리케이션을 동시에 모두 적용, "장치 또는 리소스 사용 중" 문제가 없습니다.
그래서 생각보다 잘 됐고, 도움이 필요한 실제 문제도 없었습니다.
하지만 제 질문은 루프백을 사용하여 어떻게 이 작업을 수행할 수 있느냐는 것입니다. 왜 원본 소스를 사용하지 않습니까?
단일 루프백을 생성하는 명령 예:
sudo modprobe v4l2loopback video_nr=30 exclusive_caps=1 card_label="loopback cam"
ffmpeg를 사용하여 /dev/video5를 루프백(/dev/video30)으로 미러링하는 명령 예입니다. 기본값은 원시 데이터이지만 최근 ffmpeg 빌드에서는 MJPEG와 같은 대체 스트림을 사용할 수 있으며 동작은 다음과 관계없이 동일합니다.
ffmpeg -f v4l2 -i /dev/video5 -codec copy -f v4l2 /dev/video30
이 작업이 완료되면 여러 응용 프로그램을 사용하여 /dev/video30에 액세스해 보십시오. 다음은 몇 가지 예입니다.
ffmpeg -f v4l2 -i /dev/video30 -codec libx264 recordstream.mp4
ffplay -f video4linux2 -i /dev/video30
시스템 정보(해당하는 경우):
- 우분투 20.04
- 커널: 5.4.0-31-일반
- 패키지: v4l2loopback-dkms 0.12.3-1
답변1
이것은 의도적으로 설계된 것입니다. 먼저, 여러 프로세스가 /dev/video0 장치를 열 수 있지만 그 중 하나만 특정 명령을 실행할 수 있다고 가정합니다.제어(ioctl()) 스트림이 시작될 때까지.
V4L2제어비트 전송률과 같은 것을 정의하십시오. 스트리밍을 시작한 후에는 커널에서 이를 변경할 수 없으며 EBUSY
시도하면 반환됩니다(장치 또는 리소스 사용 중). 바라보다이 메모커널 소스 코드에서. 스트리밍을 시작하기 전에 설정해야 하므로 다른 소비자를 효과적으로 차단합니다.
v4l2loopback의 차이점은 무엇입니까? 논리와 데이터 구조를 추가합니다.여러 개의 개구부그리고 기본적으로는새로운 컨트롤을 적용하려는 시도가 없습니다.자신만의 세터를 제공합니다.
v4l2loopback에는 여러 개의 오프너가 필요합니다.적어도 2개는 유용하다. 독자이자 작가입니다.