security-union / videocall-rs

teleconference system written in rust
https://www.videocall.rs
MIT License
1.38k stars 119 forks source link

feat: add safari camera encode support #116

Closed alcolmenar closed 3 months ago

alcolmenar commented 1 year ago

A number of things to happen to fully enable Safari support due its lack of support for Web specific APIs used:

Fixes #58

alcolmenar commented 1 year ago

looking good!! lets see what we can use for audio https://crates.io/crates/opus-oxide

@darioalessandro looks like this package doesn't have any code in it

darioalessandro commented 1 year ago

Goddam! Clickbait

alcolmenar commented 1 year ago

Starting from https://github.com/mmig/opus-encdec, I had decided to try to use ScriptProcessorNodes to obtain Audio samples -> Encode -> Transmit -> Decode -> Audio samples, but it introduced a ton of delay and artifacts. Also ScriptProcessorNodes are deprecated for good reason. I then tried to use AudioWorklets, but the repo only had a Worklet created for the encoding side so I forked the repo here and created one. Also, I had to rebuild the js / wasm files to make sure all of the source files show up in the same file so it loads easier when adding the JS as a module. I added Google's FreeQueue library (a high performance ring buffer), but I had to change a little bit because it was using SharedArrayBuffer's as its backing and they aren't in the GlobalAudioWorkletScope.

Created an AudioWorkletCodec struct that essentially creates and interfaces with the worklet and implemented its usage in the both microphone_encoder and peer_decoder using the respective worklets.

As far as testing, I was able to test video on Safari. However, for Audio, after a ton of debugging and trying to figure out what was going on, Safari disables a bunch of Web API features on newer versions if you aren't connecting to a HTTPS endpoint so I wasn't able test Audio fully. Audio from newer Safari browsers to Chrome works, but not very well. I'm not sure how much of that is due to the non-HTTPS endpoint.

Video from Chrome to Safari iOS works. Safari iOS has HTTPS issues as well. Safari iOS to Chrome Video has issues. It seems like it is due to this.). Suspended AudioContexts were common in Chrome using AudioBufferSources, but switching to AudioWorklets made it less common.

alcolmenar commented 1 year ago

What do you think about adding the forked worklet repo as a submodule to this project?

darioalessandro commented 1 year ago

@alcolmenar you are a rockstar!

I'll review your PR today.

To use https with safari you could use ngrok to expose your localhost in the internet and get valid https certs: https://ngrok.com/

alcolmenar commented 1 year ago

To use https with safari you could use ngrok to expose your localhost in the internet and get valid https certs: https://ngrok.com/

I tried that. Maybe I'm doing something wrong but I figured it wouldn't work since there are a few ports that need to be exposed and a free account only allows 1 at a time. Were you able to get a full test in using it?

darioalessandro commented 1 year ago

@alcolmenar I am looking at this now

alcolmenar commented 1 year ago

@darioalessandro how does it look?

darioalessandro commented 1 year ago

You are a legend my friend!!

POC is fantastic! audio sounds great!!

Video is a bit slow but I am sure that if we work together we can make it fast!!

Screenshot 2023-08-30 at 9 13 36 PM

darioalessandro commented 1 year ago

Hey @alcolmenar ! I noticed that there's compiled wasm both encoder/decoder.js workers? do you have the source code for these and license?

alcolmenar commented 1 year ago

Hey @alcolmenar ! I noticed that there's compiled wasm both encoder/decoder.js workers? do you have the source code for these and license?

I forked the opus-encdec repo here https://github.com/alcolmenar/opus-encdec/tree/audio-worklet and made changes to it to create the decoderWorker Worklet. I think I need to update the license though because I also pulled in a Ring Buffer implementation from Google labs https://github.com/GoogleChromeLabs/web-audio-samples/tree/main/src/audio-worklet/free-queue

The compiled wasm is an emscripten compilation of the c implementation of libopus and speexdsp. The license is in the repo already