mplayer를 사용하여 프레임 버퍼에서 직접 비디오를 재생하려고 합니다. 현재는 동일한 런레벨에서 오디오와 비디오를 재생할 수 없습니다.
사용자 수준에 있을 때만 오디오 장치가 연결되고 비디오 장치는 거부됩니다.
예를 들어 다음을 실행할 수 있습니다.
mplayer -ao alsa -vo fbdev2 test.mp4
오디오는 재생되지만 비디오 연결은 거부됩니다.
can't open /dev/fb0: Permission Denied
사용하면 sudo mplayer -ao alsa -vo fbdev2 test.mp4
비디오는 재생되지만 오디오는 재생되지 않습니다.
[AO_ALSA] alsa-lib: pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection Refused
[AO_ALSA] Playback open error: Connection Refused
Failed to initialize audio driver 'alsa'
Could not open/initialize audio device -> no sound
Audio: no sound
오디오와 비디오를 함께 재생하는 방법은 무엇입니까? 그들은 모두 서로 다른 실행 수준에서 별도로 작동합니다.
답변1
짧은 대답, 루트 상주 가상 콘솔(예: Ctrl+Alt+N)을 사용하여 로그인한 다음 pulseaudio 데몬을 시작하고 비디오를 재생하십시오.
/usr/bin/pulseaudio --start
mplayer -vo fbdev2 test.mp4
[중요한]/usr/bin/pulseaudio --system
여기서 시도할 필요가 없습니다. 당신은요모든 단계를 수행하려면 루트(sudo 또는 su가 아님) 및 가상 콘솔로 상주해야 합니다.데몬 시작 및 비디오 재생을 포함합니다.효과 없음su
X 세션의 가상 터미널 내에서 데몬을 시작하려고 하는 경우 .
긴 대답, 내가 알아낸 방법:
첫 번째 단계는 새 가상 콘솔을 사용하여 새 터미널을 여는 것입니다. 그 이유는 X 세션이 프레임 버퍼에서 작동하지 않을 가능성이 높기 때문입니다.
이제 mplayer에만 국한되는지 알아야 합니다. 그래서 나는 내장 kde 사운드와 같은 기본 음악을 재생하기 위해 play 명령을 사용하고 play /usr/share/sounds/KDE-Im-Cant-Connect.ogg
새로운 가상 콘솔에서 sudo를 사용해 보았습니다.
$ sudo play /usr/share/sounds/KDE-Im-Cant-Connect.ogg
ALSA lib pulse.c:243:(pulse_connect) PulseAudio: Unable to connect: Connection refused
play FAIL formats: can't open output file `default': snd_pcm_open error: Connection refused
$
mplayer나 복잡한 노래에만 국한되지 않습니다.
이제 우리는 차이점을 조사해야합니다.소음이 있어요그리고소리가 나지 않는다. 일반 사용자를 위한 X 세션에서 strace(사운드 포함)를 시도해 보겠습니다. (여기서 파일 이름 su1.log는 오해의 소지가 있으며 su와 아무 관련이 없습니다.)
strace -o /tmp/su1.log -v -s 1000000 재생 /usr/share/sounds/KDE-Im-Cant-Connect.ogg
및 가상 콘솔(소리 없음):
strace -o /tmp/su2.log -v -s 1000000 재생 /usr/share/sounds/KDE-Im-Cant-Connect.ogg
vi /tmp/su2.log, 끝으로 이동:
connect(8, {sa_family=AF_LOCAL, sun_path="/run/user/0/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
close(8) = 0
socket(PF_LOCAL, SOCK_STREAM|SOCK_CLOEXEC, 0) = 8
fcntl(8, F_GETFD) = 0x1 (flags FD_CLOEXEC)
setsockopt(8, SOL_SOCKET, SO_PRIORITY, [6], 4) = 0
fcntl(8, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(8, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(8, {sa_family=AF_LOCAL, sun_path="/var/run/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
close(8) = 0
write(5, "x", 1) = 1
write(2, "ALSA lib pulse.c:243:(pulse_connect) ", 37) = 37
write(2, "PulseAudio: Unable to connect: Connection refused\n", 50) = 50
write(2, "\n", 1) = 1
futex(0x135a8e0, FUTEX_UNLOCK_PI_PRIVATE, 0) = 0
sendto(7, "W", 1, MSG_NOSIGNAL, NULL, 0) = -1 ENOTSOCK (Socket operation on non-socket)
write(7, "W", 1) = 1
futex(0x135a8e0, FUTEX_UNLOCK_PI_PRIVATE, 0) = 0
futex(0x7f34065089d0, FUTEX_WAIT, 7956, NULL) = -1 EAGAIN (Resource temporarily unavailable)
munmap(0x7f3406509000, 67112960) = 0
unlink("/dev/shm/pulse-shm-3719764676") = 0
close(6) = 0
close(7) = 0
close(5) = 0
close(4) = 0
write(2, "play FAIL formats: ", 19) = 19
write(2, "can't open output file `default': snd_pcm_open error: Connection refused", 72) = 72
write(2, "\n", 1) = 1
두 로그의 "open(""을 비교하는 kdiff3도 있습니다.
$ grep 'open(' /tmp/su1.log > /tmp/su1_open.log
$ grep 'open(' /tmp/su2.log > /tmp/su2_open.log
$ kdiff3 /tmp/su1_open.log /tmp/su2_open.log
$
다음 상황에서는 약간 다릅니다./실행/사용자/0/펄스이제 uid 1000(일반 사용자)과 0(루트)으로 무언가를 구현했습니다. 여기서 "/run/user/1000/pulse" 및 "run/user/0/pulse"는 각각 uid 1000과 0을 사용할 때만 요청됩니다.
$ grep 'run/user/0/pulse' /tmp/su1.log
$ grep 'run/user/1000/pulse' /tmp/su2.log
$ grep 'run/user/1000/pulse' /tmp/su1.log
recvmsg(5, {msg_name(0)=NULL, msg_iov(1)=[{"\1\10\2\0\21\0\0\0\37\0\0\0\0\0\0\0B\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0{34959d136592433aad171659a5cd523f}unix:/run/user/1000/pulse/native\0\0", 4096}], msg_controllen=0, msg_flags=0}, 0) = 100
connect(5, {sa_family=AF_LOCAL, sun_path="/run/user/1000/pulse/native"}, 110) = 0
recvmsg(6, {msg_name(0)=NULL, msg_iov(1)=[{"\1\10\2\0\21\0\0\0\37\0\0\0\0\0\0\0B\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0{34959d136592433aad171659a5cd523f}unix:/run/user/1000/pulse/native\0\0", 4096}], msg_controllen=0, msg_flags=0}, 0) = 100
connect(6, {sa_family=AF_LOCAL, sun_path="/run/user/1000/pulse/native"}, 110) = 0
$ grep 'run/user/0/pulse' /tmp/su2.log
mkdir("/run/user/0/pulse", 0700) = -1 EEXIST (File exists)
open("/run/user/0/pulse", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = 5
lstat("/run/user/0/pulse", {st_dev=makedev(0, 41), st_ino=86867, st_mode=S_IFDIR|0700, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=40, st_atime=2015/07/22-01:44:45, st_mtime=2015/07/22-01:44:45, st_ctime=2015/07/22-01:47:59}) = 0
lstat("/run/user/0/pulse", {st_dev=makedev(0, 41), st_ino=86867, st_mode=S_IFDIR|0700, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=40, st_atime=2015/07/22-01:44:45, st_mtime=2015/07/22-01:44:45, st_ctime=2015/07/22-01:47:59}) = 0
connect(5, {sa_family=AF_LOCAL, sun_path="/run/user/0/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
mkdir("/run/user/0/pulse", 0700) = -1 EEXIST (File exists)
open("/run/user/0/pulse", O_RDONLY|O_NOCTTY|O_NOFOLLOW|O_CLOEXEC) = 8
lstat("/run/user/0/pulse", {st_dev=makedev(0, 41), st_ino=86867, st_mode=S_IFDIR|0700, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=40, st_atime=2015/07/22-01:44:45, st_mtime=2015/07/22-01:44:45, st_ctime=2015/07/22-01:47:59}) = 0
lstat("/run/user/0/pulse", {st_dev=makedev(0, 41), st_ino=86867, st_mode=S_IFDIR|0700, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=40, st_atime=2015/07/22-01:44:45, st_mtime=2015/07/22-01:44:45, st_ctime=2015/07/22-01:47:59}) = 0
connect(8, {sa_family=AF_LOCAL, sun_path="/run/user/0/pulse/native"}, 110) = -1 ENOENT (No such file or directory)
$
/run/user/0/pulse인 경우에만 "해당 파일이나 디렉터리가 없습니다"라고 표시되면 확인해 보겠습니다(루트 사용).
# l /run/user/0/pulse/
total 0
84490 drwx------. 4 root root 80 Jul 22 01:44 ..
86867 drwx------. 2 root root 40 Jul 22 01:44 .
#
# l /run/user/1000/pulse/
total 4.0K
29328 -rw-------. 1 xiaobai xiaobai 5 Jul 22 00:58 pid
30544 srwxrwxrwx. 1 xiaobai xiaobai 0 Jul 22 00:58 native
31058 drwx------. 2 xiaobai xiaobai 80 Jul 22 00:58 .
27430 drwx------. 14 xiaobai xiaobai 280 Jul 22 01:06 ..
# l /run/user/1000/pulse/native
30544 srwxrwxrwx. 1 xiaobai xiaobai 0 Jul 22 00:58 /run/user/1000/pulse/native
# file /run/user/1000/pulse/native
/run/user/1000/pulse/native: socket
# file /run/user/1000/pulse/pid
/run/user/1000/pulse/pid: ASCII text
# cat /run/user/1000/pulse/pid
2205
#
나는 이때를 안다프로세스 번호 2205실행 중이며 제대로 작동하려면 uid 0으로 존재해야 합니다.
구글링해서 찾았어요펄스 오디오 - 확인:
# pulseaudio --check
arg verbose를 사용해 보고 알아냈습니다! 데몬은 다음과 같이 실행됩니다.프로세스 번호 2205, 위에서 관찰한 내용을 증명합니다.
# pulseaudio --check -v
I: [pulseaudio] main.c: Daemon running as PID 2205
#
이제 저는 펄스 오디오가 효과를 발휘할 수 있다고 믿습니다. PID 2205를 확인하여 어떻게 트리거되었는지 확인하세요.
# ps aux|grep 2205
xiaobai 2205 0.0 0.2 565980 11080 ? S<l 00:58 0:01 /usr/bin/pulseaudio --start
root 8747 0.0 0.0 113008 2300 pts/2 S+ 01:58 0:00 grep --color=auto 2205
#
그럼 한번 시도해 봅시다 /usr/bin/pulseaudio --start
:
# /usr/bin/pulseaudio --start
W: [pulseaudio] main.c: This program is not intended to be run as root (unless --system is specified).
N: [pulseaudio] main.c: User-configured server at {34959d136592433aad171659a5cd523f}unix:/run/user/1000/pulse/native, which appears to be local. Probing deeper.
이제 새 pulse 디렉토리가 uid 0 아래에 새 pid와 함께 표시됩니다.
# l /run/user/0/
total 0
17794 drwxr-xr-x. 4 root root 80 Jul 22 01:44 ..
85629 drwxr-xr-x. 2 root root 80 Jul 22 01:44 systemd
84490 drwx------. 4 root root 80 Jul 22 01:44 .
86867 drwx------. 2 root root 80 Jul 22 02:02 pulse
# cat /run/user/0/pulse/pid
9731
#
마침내 소리가 작동합니다. 지금 직접 사용해 보세요.mplayer -vo fbdev2 test.mp4
[참고] su
이상한 상황에서는 작동할 수도 있습니다. 예를 들어 X 세션 11 -> Ctrl+Alt+2 -> uid 1000으로 로그인 -> su - root -> /usr/bin/pulseaudio --start
및 mplayer -vo fbdev2가 제대로 작동합니다. 그런 다음 Ctrl+Alt+3 -> 루트로 로그인 -> /usr/bin/pulseaudio --start
mplayer로 작업 -> Ctrl+Alt+2로 돌아가기 -> 가상 콘솔 2의 mplayer가 더 이상 작동하지 않습니다.