Bad Webrtc Build For Mac
Building WebRTC from source sometimes feels like engineering the impossible. Photo courtesy of Andrew Lipson. Building WebRTC from source Most of the audience for WebRTC (and ) is made of web developers, JavaScript and cloud ninjas that might not be less familiar with handling external libraries from source. That process is painful. Let’s make it clear, it’s painful for everybody – not only web devs.
What are the cases where you need to build from source?. Writing a native app – mobile, desktop, IoT.). Some kind of server (gateway, media,.). Plugin (either for IE, Safari, Cordova, ) You basically need to build from source anytime you can’t leverage a browser, WebRTC enabled node.js (for the sake of discussion), SDK’s someone how put together for you, or anything else.
These main cases are illustrated below in the context of a comprehensive offering. Figure 1: map of a WebRTC solution Usually, the project owners provide precompiled and tested libraries that you can use yourself (stable) and the most recent version that is compiled but not tested for those who are brave. Pre-compiled libraries are usable out of the box, but do not allow you to modify anything. Sometimes there are build scripts that help you recompile the libs yourselves.
This provides more flexibility in terms of what gets in the lib, and what optimizations/options you set, at the cost of now having to maintain a development environment. Comparing industry approaches For example, Cisco with its library provides both precompiled libraries and build scripts. In their case, using the precompiled library defers H264 royalty issues to them, but that’s another subject. While the project includes build scripts, they are complex use, do not provide a lot of flexibility for modifying the source, and make it difficult to test any modifications. The great cordova plugin from eFace2Face is using a precompiled libWebRTC ( ) (see our on this too). Pristine.io were among the first one to propose build script to make it easier (see; more about that later). Sarandogou/doubango’s webrtc-everywhere plugin for IE and Safari does NOT use automated build scripts, versioning or a, which causes them a and slows their progress.
The guys put a drawing of what the process is, and noted that, conceptually, there is not a big difference between android and iOS build as to the steps you need to follow. Practically, there is a difference in the tools you used though. My build process Here is my build process: Please also note that I mention testing explicitly and there is a good reason for that, learned the hard way. I will come to it in the next section.
You will see I have a “send to dashboard” step. I mean something slightly different than what people usually refer to as a dashboard.
Usually, people want to report the results of the tests to a dashboard to show that a given revision is bug free (as much as possible) and that the corresponding binary can be used in production. If you have performance tests, a dashboard can also help you spot performance regressions. In my case here, I also want to use a common public dashboard as a way to publish failing builds on different systems or with different configurations, and still provide full log access to anyone. It makes solving those problem easier. The one asking the question can point to the dashboard, and interesting parties have an easier time looking at the issue or reproducing it. More problems reported, more problems solved, everyone is happy.
Now that we have reviewed the build from source process a bit, let’s talk about what’s wrong with it. Building from Source Sucks Writing an entire WebRTC stack is insanely hard. That’s why Google went out and bought GIPS, even though they have a lot of very very good engineers at disposal. Most devs and vendors use an existing stack. For historical reasons most people use google’s contributed WebRTC stack based on the GIPS media engine, and Google’s libjingle for the network part.
Even Mozilla is using the same media engine, even though they originally went for a Cisco SIP soft phone code as the base (see, under “list of components”, “SIPCC”) to implement the network part of WebRTC. Since then, Mozilla went on and rewrote almost all that part to support more advanced functionality such as multi-party. However, the point is, their network and signaling is different from Google’s while their media engine is almost identical. Furthermore, Mozilla does not attempt to provide a standalone version of their WebRTC implementation, which makes it hard for developers to make use of it right away. Before Ericson’s OpenWebRTC in October 2014, the Google standalone version was the only viable option out there for most. OpenWebRTC has advantages on some parts, like hardware support for H.264 on iOS for example, but lacks some features and Windows support that can be a showstopper for some.
It is admittedly less mature. It also uses GStreamer, which has its own conventions and own build system (cerbero), which is also tough to learn. The stack is not available in a precompiled library with an installer. This forces developers to compile WebRTC themselves, which is “not a picnic”.
One needs first to become accustomed to Chrome dev tools which are quite unique, adding a learning step to the process. The code changes quite often (4 commits a day), and the designs are poorly documented at best.
Even if you manage to compile the libs, either by yourself or using resources on the web, it is almost certain that you cannot test it before using it in your app, as most of the, and infrastructure is under the control of Google by default. Don’t get me wrong, the bug report and review servers allow anybody to set up an account. What is done with your tickets or suggestions however is up to Google. You can end up with quite frustrating answers. If you dig deep enough in the Chrome infrastructure for developers, you will also find how to replicate their entire infrastructure, but the level you need to have to go through this path, and the amount of effort to get it right is prohibitive for most teams. You want to develop your product, not become a Chrome expert.
Finally, the contributing process at Google allows for bugs to get in. You can actually looks at the logs and see a few “Revert” commits there. Figure 2: Example of a Revert commit message. From the reverted commits (see footnote: 107 since January 2015), one can tell that revisions of WebRTC on the HEAD are arbitrarily broken. Here again, this comment might be perceived as discriminatory against Google. There is nothing wrong there; it always happen for any project, and having only 107 reverts in 6 months while maintaining 4 commits a day is quite an achievement. However, it means that you, as a developer, cannot work with any given commit and expect the library to be stable.
You have at least to test it yourself. My small side project to help My goals are:. Provide information to the community that is not documented elsewhere, or not consolidated. The blog posts on fulfill this goal.
Learn more about WebRTC. Prepare a course for the local university. Do something useful of my current “long vacations”.
Yes, vacations in Boracay, Philippines, once voted #2 most beautiful beach in the world by tripadvisor are nice. But I very quickly get that I-need-to-code urge, and they have Wi-Fi on the beach. More importantly I would like to lower the barrier of adoption / collaboration / contribution by providing:. WebRTC installers that sync with chrome revisions that developers could use blindly out of the box (knowing they’ve been tested). Code for anyone to set up their own build/try/package pipeline, either locally or in the cloud. Easy patching and testing framework to enhance Webrtc.
As an example, provide an h264 compliant WebRTC lib based on work from Kaiduan Xue, Jesup Randell, and others. More examples and applications for Devs to start from. A first example will be a stand-alone, h264 compliant, appRTCDemo desktop app.
Public dashboard for a community to come together, contribute build bots and de duplicate the tests efforts going on at almost every vendor for the base stack. Public dashboard for people to submit their fail builds as a way to ask question on the mailing list and get faster answers. Sorry for the late reply, i do not get notifications on this. Building in itself is not the problem, but one commit out of 7 is broken, and you might not see it at compilation time. Running the tests is NOT easy. Then, as time pass, libwebrtc continues to build, but it introduces a ton of non-backward compatibility changes.
The google tests, examples, chrome, the iOS and android wrappings and all other internal projects (meet, ) are modified accordingly as they go, but your (my) application is not. Maintenance of applications based on libwebrtc is HARD, and is the source of many questions on discuss-webrtc mailing list. To the point that google open a bug about it.
For historical reasons, I define usable as “a gifted master student could do it”. In many aspects, while the default compilation of libwebrtc fits this definition, using and maintaining libwebrtc (1) and compiling for non-default parameters (2) is not.
You can see some of my comments about (1) above in response to paul. In your case I would had: how much do you test your compile library? While google achieve 80+% coverage, the original vsimon scripts did not test at all. Importing google unit test is challenging at best. Linking against an application requires you to maintain the application, and to pass around not only the includes directories, but also the compilation flags. While it s almost trivial under linux (pkgconfig), it’s quite difficult on other platform. Your test hardcode the compilation flags for mac, e.g.
Now some example of difficult questions: 1. Before henrik and I put a flag for RTTI in january, how would have you compile libwebrtc with RTTI (to add an additional video Capturer for example. How do you compile libwebrtc as a shared lib? How do you compile an external shared lib (DLL) linked against libwebrtc as a static lib while having the right runtime library on windows (i.e. How do you switch between the /MT, /MTd, /MD, /MDd, ) and really hard: 4. How do you handle private modifications of libwebrtc in your project/script 5.
How do you handle using your own modified libwebrtc in chrome, when chrome’s libwebrtc and libwebrtc are different git subtrees: Your project is great, and I think it’s already addressing the need of many, just like Axel Isouard project addresses the need of those who want to build in travis, or use a npm package. However, there are still a lot to do to make libwebrtc really usable as a library, and integrated in a CI/CD system.
Webrtc Demo
Safari and WebRTC in the wild. Logos added to photo by Flickr user In June of 2017, Apple became the last major vendor to release support for WebRTC, paving the (still bumpy) road for platform interoperability. And yet, more than a year later, I continue to be surprised by the lack of guidance available for developers to integrate their WebRTC apps with Safari/iOS. Outside of a couple posts by the Webkit team, some scattered StackOverflow questions, the knowledge to be gleaned from scouring the Webkit bug reports for WebRTC, and a, I really haven’t seen much support available. This post is an attempt to begin rectifying the gap. I have spent many months of hard work integrating WebRTC in Safari for a very complex videoconferencing application. Most of my time was spent getting iOS working, although some of the below pointers also apply to Safari on MacOS.
This post assumes you have some level of experience with implementing WebRTC — it’s not meant to be a beginner’s how to, but a guide for experienced developers to smooth the process of integrating their apps with Safari/iOS. Where appropriate I’ll point to related issues filed in the Webkit bug tracker so that you may add your voice to those discussions, as well as some other informative posts. I did an awful lot of bushwacking in order to claim iOS support in my app, hopefully the knowledge below will make a smoother journey for you! Some good news first First, the good news:.
Apple’s current implementation is fairly solid. For something simple like a 1-1 audio/video call, the integration is quite easy Let’s have a look at some requirements and trouble areas. General Guidelines and Annoyances Use the current WebRTC spec If you’re building your application from scratch, I recommend using the current WebRTC API spec (it’s undergone several iterations). The following resources are great in this regard:. For those of you running apps with older WebRTC implementations, I’d recommend you upgrade to the latest spec if you can, as the disables the legacy APIs by default.
In particular, it’s best to avoid the legacy addStream APIs, which make it more difficult to manipulate tracks in a stream. More background on this here: iPhone and iPad have unique rules – test both Since the iPhone and iPad have different rules and limitations, particularly around video, I’d strongly recommend that you test your app on both devices. It’s probably smarter to start by getting it working fully on the iPhone, which seems to have more limitations than the iPad. More background on this here: Let the iOS madness begin It’s possible that may be all you need to get your app working on iOS.
If not, now comes the bad news: the iOS implementation has some rather maddening bugs/restrictions, especially in more complex scenarios like multiparty conference calls. Other browsers on iOS missing WebRTC integration The WebRTC APIs have not yet been exposed to iOS browsers using WKWebView. In practice, this means that your web-based WebRTC application will only work in Safari on iOS, and not in any other browser the user may have installed (Chrome, for example), nor in an ‘in-app’ version of Safari. To avoid user confusion, you’ll probably want to include some helpful user error message if they try to open your app in another browser/environment besides Safari proper.
Related issues:. No beforeunload event, use pagehide According to, the unload event has been deprecated, and the beforeunload event has been completely removed in Safari. So if you’re using these events, for example, to handle call cleanup, you’ll want to refactor your code to use the pagehide event on Safari instead. Playsinline was originally only a requirement for Safari on iOS, but now you might need to use it in some cases in Chrome too – see for more on that. See the thread here for details on this issue requirement: Autoplay rules Next you’ll need to be aware of the Webkit WebRTC rules on autoplaying audio/video.
The main rules are:. MediaStream-backed media will autoplay if the web page is already capturing.
MediaStream-backed media will autoplay if the web page is already playing audio. A user gesture is required to initiate any audio playback – WebRTC or otherwise. This is good news for the common use case of a video call, since you’ve most likely already gotten permission from the user to use their microphone/camera, which satisfies the first rule.
Note that these rules work alongside the base autoplay rules for MacOS and iOS, so it’s good to be aware of them as well. Related webkit posts:. No low/limited video resolutions. Test of common video resolutions and the results in Safari/iOS Visiting (or the webrtcHack’s project) in a WebRTC-compatible browser will give you a quick analysis of common resolutions that are supported by the tested device/browser combination. You’ll notice that in Safari on both MacOS and iOS, there aren’t any available low video resolutions such as the industry standard QQVGA, or 160×120 pixels.
These small resolutions are pretty useful for serving thumbnail-sized videos — think of the filmstrip of users in a Google Hangouts call, for example. Now you could just send whatever the lowest available native resolution is along the peer connection and let the receiver’s browser downscale the video, but you’ll run the risk of saturating the download bandwidth for users that have less speedy internet in mesh/SFU scenarios. I’ve worked around this issue by restricting the bitrate of the sent video, which is a fairly quick and dirty compromise. Another solution that would take a bit more work is to handle downscaling the video stream in your app before passing it to the peer connection, although that will result in the client’s device spending some CPU cycles.
Example code:. New getUserMedia request kills existing stream track.
Apple’s WebRTC implementation only allows one getUserMedia capture at a time If your application grabs media streams from multiple getUserMedia ( ) requests, you are likely in for problems with iOS. From my testing, the issue can be summarized as follows: if getUserMedia ( ) requests a media type requested in a previous getUserMedia ( ), the previously requested media track’s muted property is set to true, and there is no way to programmatically unmute it.
Data will still be sent along a peer connection, but it’s not of much use to the other party with the track muted! This limitation is currently expected behavior on iOS. I was able to successfully work around it by:. Grabbing a global audio/video stream early on in my application’s lifecycle. Using MediaStream.
Clone ( ), MediaStream. AddTrack ( ), MediaStream. RemoveTrack ( ) to create/manipulate additional streams from the global stream without calling getUserMedia ( ) again. Then ( handleSuccess ).
Catch ( handleError ); source: See this post for more: and this related issue: Managing Media Devices Media device IDs change on page reload Many applications include support for user selection of audio/video devices. This eventually boils down to passing the deviceId to getUserMedia ( ) as a constraint. Unfortunately for you as a developer, as part of Webkit’s security protocols, random deviceId’s are generated for all devices on each new page load. This means, unlike every other platform, you can’t simply stuff the user’s selected deviceId into persistent storage for future reuse.
The cleanest workaround I’ve found for this issue is:. Store both device.
Webrtc App
DeviceId and device. Label for the device the user selects. For any code workflow which eventually passes a deviceId to getUserMedia ( ):. Try using the saved deviceId. If that fails, enumerate the devices again, and try looking up the deviceId from the saved device label.
Webrtc Server Windows
On a related note: Webkit further prevents fingerprinting by only exposing a user’s actual available devices after the user has granted device access. In practice, this means you need to make a getUserMedia ( ) call before you call enumerateDevices ( ).