jitsi / jibri

Jitsi BRoadcasting Infrastructure
Apache License 2.0
603 stars 314 forks source link

PulseAudio instead of ALSA #160

Open mishurov opened 5 years ago

mishurov commented 5 years ago

PulseAudio works in userspace and it doesn't require a kernel module. It makes Jibri work nicely within Docker with Xorg and IceWM manually started, without passing any host devices.

part of my script for patching Jibri

# application
sed -i -e 's/alsa/pulse/g' \
  src/main/kotlin/org/jitsi/jibri/capture/ffmpeg/executor/Commands.kt
sed -i -e 's/hw:0,1,0/default/g' \
  src/main/kotlin/org/jitsi/jibri/capture/ffmpeg/executor/Commands.kt

# test
sed -i -e 's/alsa/pulse/g' \
  src/test/kotlin/org/jitsi/jibri/capture/ffmpeg/FfmpegCapturerTest.kt

part of my script for creating a virtual sink, based on this answer https://stackoverflow.com/questions/43312975/record-sound-on-ubuntu-docker-image#43368617

apt-get -y install pulseaudio socat
pulseaudio -D --exit-idle-time=-1
pacmd load-module module-virtual-sink sink_name=v1
pacmd set-default-sink v1
pacmd set-default-source v1.monitor

It would be great if you consider using PulseAudio instead of ALSA or make it configurable.

Additionally. It isn't relevant to this particular issue and I'm not sure whether it's a bug. 6.X versions don't report a correct status to Jitsi from the stable repository. After connecting it immediately goes offline. 5.1 version works though.

saghul commented 5 years ago

Hey @mishurov ! This sounds interesting. I have plans to add jibri to our Docker setup (https://github.com/jitsi/docker-jitsi-meet) and this was something that had crossed my mind.

Question: is socat necessary?

I suggest you open a PR so we can discuss the actual changes.

Additionally. It isn't relevant to this particular issue and I'm not sure whether it's a bug. 6.X versions don't report a correct status to Jitsi from the stable repository. After connecting it immediately goes offline. 5.1 version works though.

Could be a bug! Please open a new issue for this.

Thanks!

damencho commented 5 years ago

The last thing is known, you need latest versions of everything when using latest jibri.

About pulseaudio, if I remember correctly we were using it but we had som glitches or loosing audio in long calls and that's why we moved to using alsa, but Aaron can give more details on the subject.

mishurov commented 5 years ago

@saghul, I'm not sure about socat TBH, I thoughtlessly copypasted it from the StackOverflow link above, I surmise it isn't necessary.

The Docker also requires the --no-sandbox flag for Chrome BTW. IDK why. I pass it via creating a script in /usr/local

echo '/usr/bin/google-chrome --no-sandbox $@/' > /usr/local/bin/google-chrome

just in case

P.S. Yes, it works without installing socat. I've just checked it.

P.P.S. To be more precise, I install pulseaudio as superuser during building the container. The later commands starting from pulseaudio -D --exit-idle-time=-1 and commands launching Xorg and the WM are run by the jibri user as I start the container.

@damencho I suspect that PulseAudio daemon also runs on per-user basis and it creates the possibility to run several Jibris within one virtual machine under different users.

So I think it would be better to wait Aaron so as to don't create unnecessary PRs and issues.

aaronkvanmeerten commented 5 years ago

Yes we had some significant issues with pulseaudio with both audio sync and "clicking" noises when we first tried it. These were inconsistent results during the early days of development. We ended up moving to Alsa because it worked reliably 100% of the time. I think it's reasonable to circle back and try it with pulse again, with the caveat that quite a bit of performance testing will need to be done before the inclusion of this support into the main distributed package.

mishurov commented 5 years ago

Is it difficult to make it configurable through the json? The actual difference is only in passing other arguments to the -f and -i flags of ffmpeg.

aaronkvanmeerten commented 5 years ago

I think if we can show it working with good success, making it configurable is a fine path . @bbaldino want to weigh in on that part too?

mishurov commented 5 years ago

There's also a problem. Since I use Jibri 5.1, I don't know if it's worth creating an issue because it may be fixed or I'm doing something wrong. When everyone leaves conference without explicitly stopping recording, Jibri logs a timeout error and traceback. After that Jibri becomes unavailable. How can it be handled?

bbaldino commented 5 years ago

yeah i think we could look at a way to make the ffmpeg args configurable.

@mishurov as to your issue, i can't tell you much without jibri logs, so i'd open another bug for that. though i'd recommend you use the latest jibri (which requires updating jicofo as well, btw)

mishurov commented 5 years ago

@bbaldino, ok, thank you for the explanation. I'm not in power to set priorities in the project we working on. When Jibri comes to the question, I'll create a bug on that with more detailed data if the problem arises again.

UPD: Jicofo 1.0-443-1 from the unstable repository and a compiled (and patched for pulse) Jibri from current master b6b7b9c424e1cde150b6698037747a50295e425b doesn't have this problem. Thanks.

mishurov commented 5 years ago

Yet another issue connected to Docker and quite possibly it was the cause of my previous issue. Chrome doesn't work within a docker container without the --no-sandbox flag, it seems a common issue.

I was fixing it by creating a script which overrides the chrome executable. E.g. echo '/usr/bin/google-chrome --no-sandbox $@/' > /usr/local/bin/google-chrome

And it appears to be wrong. The problem is that since Selenium runs my script instead of the original executable, it can't kill chrome's process correctly, it throws an exception and Jibri becomes unavailable, and there're also unhandled chrome processes remain hanging around in the system.

I've added the --no-sandbox to src/main/kotlin/org/jitsi/jibri/selenium/JibriSelenium.kt, and now it works fine.

Thus, I think, if you allow to add extra arguments for Chrome through the json, it will make life easier as well.