KallDrexx

KallDrexx

Elixir Media Libs

For a good number of months I’ve been working on creating a very basic RTMP live video streaming server. Now that I have a very, very basic usable system (after several complete rewrites) I wanted to release it out into the world in case anyone was interested at least.

The libraries are MIT licensed with source code at https://github.com/KallDrexx/elixir-media-libs. The core projects (and hex packages) are:

  • amf0 - Library with functions for serializing and deserializing data in the AMF0 encoding format. It’s not 100% complete on the spec but it has the core types implemented.
  • rtmp_handshake - Library that allows systems to perform an RTMP handshake, both as client and a server. It supports both simple and digest handshake formats.
  • rtmp_session - An abstraction that represents a single peer in an RTMP connection. This is essentially the core brain of an RTMP peer where you give it TCP packets and it spits out events and tcp responses. Right now it is only programmed to work as a server, but the client portion is on my todo list.
  • gen_rtmp_server - Behavior that makes easy to create your own RTMP server and provides callbacks for your own custom application logic to respond to RTMP events

These have all been put together to create a simple RTMP server. This server allows connections via any stream key and application name for publishing and video playback. It is dead simple but it works well enough to watch video from. I definitely would not say it’s production ready yet in any capacity.

The long, long term goal of this project is to create a completely free and open source alternative to Wowza, and the like. RTMP is just the start, I want to support both input and output of RTSP, RTP, Mpeg-TS, HLS and Dash streams (a secondary goal is to get this to a usable state to make an NVR for my home IP cameras as well).

My next high level steps (outside bug fixing) on the project are:

  • Allow saving an RTMP stream into HLS fragments with manifest
  • Create an gen_rtmp_client abstraction to support relaying video out to a secondary RTMP server
  • Add libraries to parse FLV and MP4 files, and serve them to an RTMP player (vod support)
  • Start work on more complex media server

Most Liked

KallDrexx

KallDrexx

Just thought I’d update in case anyone is interested.

I’ve now gotten a fully functional RTMP client behaviour working. With that I have created a RTMP player that can connect to an RTMP server and receive audio, video, and metadata for the specified stream key, as well as an RTMP proxy server that allows you to publish RTMP data to it and will publish that video to an external RTMP server.

I still have a little bit of infrastructure work to do (for example to drop packets if the network is getting backlogged) but for the most part in my tests it has shaped up pretty well.

What’s really exciting about this is that the critical parts are in place for my open source media server plans. Being able to receive and distribute RTMP means that I can now start working on a media server that is not only able to receive RTMP and playback to video players, but can also duplicate and redistribute video feeds to multiple RTMP services (e.g. Youtube and Twitch simultaneously).

Taking it further this capability also opens the door to utilize FFMPEG to patch the holes until I can write Elixir native equivalents. For example HLS feeds can be generated by spinning up ffmpeg to pull in the local rtmp feed and create hls renditions of it. Another example is pulling video from security cameras via RTSP via FFMPEG and pushing it into the RTMP server.

KallDrexx

KallDrexx

Just as an update in case anyone is interested.

Previously I was given the feedback that socket handling should be in its own process for the best performance. At first I was apprehensive because I wanted media data to be sent from publisher to client with as little latency as possible. After doing some benchmarks I came to the conclusion I was doing way too much premature optimization and I should embrace the power of the BEAM VM.

In that vein I did a pretty hefty re-architecture of the system, depreciating some of the previous modules (not totally sure the best way to depreciate them on hex.pm though) and creating the new eml_rtmp library. The code is a lot better organized and easier to follow (imo), though I still have a few areas I personally want to address. It also has better testability I think.

For anyone wondering, the new architecture for server handling has ranch creating a GenServer for the socket handling. After handshaking completes it spawns 2 more processes, a protocol handler process and a server session handler process.

When TCP data comes in it sends it to the protocol handling process. As messages get deserialized it sends those unwrapped messages to the session handler process so it can run it through the core logic processor. It will then send the protocol handler messages it should serialize (which then get sent out over the socket) or it sends events to the parent GenServer to pass back to the implementation of the generic RTMP server (GenRtmpServer behaviour adopter).

The end result of this is I can already see performance increase (and stability) over trying to do everything on one process per connection. Timings seem much better as well, and I still have some more optimizations I want to do.

KallDrexx

KallDrexx

So after getting some feedback I"m in for a pretty big refactor/rearchitecture of this, so if you do actually plan on using this just outside of the higher level simple_rtmp_server then just be aware that things will probably change in a non-backwards compatible way.

Essentially it comes down that socket handling should really be done in it’s own thread for performance and timing reasons. So I need to split out the input/output parsing from the session, and make the session just react to rtmp messages, and send replies to the socket for serialization + output. After thinking about it a lot I think this will make things a lot more testable and more organized anyway, so it’s probably for the better to do this now if I intend to make this into a bigger product later.

KallDrexx

KallDrexx

While flash is dying that just means that RTMP is dying for video playback but not for live video distribution. Most encoders almost always use RTMP to send video out and Twitch, Daily Motion, Beam, Facebook, Periscope etc… only accept RTMP ingestion.

Youtube accepts DASH ingestion but if you want low latency video (to facilitate chat with viewers like is common on the consumer platforms) then DASH and HLS are a no go from a distribution standpoint. Not to mention I don’t really know of any encoder that supports it so you’d have to do something like setup a script to push up manifests and video segments as they are completed.

So RTMP has it’s place, and for a media server that may record and relay live video streams it’s important to support it properly.

KallDrexx

KallDrexx

Added :slight_smile:

Where Next?

Popular in Libraries Top

Qqwy
TypeCheck: Fast and flexible runtime type-checking for your Elixir projects. Core ideas Type- and function specifications are const...
336 13801 100
New
tompave
Hello there, I would like to share a feature toggles library (AKA feature flags) I’ve been working on. The main package is FunWithFlags...
New
oltarasenko
Dear Elixir community, After a year of development, bug fixes, and improvements, we are proudly ready to share the release of Crawly 0.1...
New
mbuhot
Leverage Open Api 3.0 (Swagger) to document, test, validate and explore your Plug and Phoenix APIs. Generate and serve a JSON Open API ...
New
dbern
I’m excited to announce that TaxJar has developed and open-sourced DateTimeParser. We developed it because we found a need to parse user ...
New
Qqwy
Solution is a library to help you with working with ok/error-tuples in case and with-expressions by exposing special matching macros, as ...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
Antrater
Hi everyone! I’m thrilled to announce a huge thing. We have been developing Elixir Moon Design System for quite a while. We are finally ...
New
Hal9000
Here is my first stab at this. README pasted below. https://github.com/Hal9000/elixir_random Comments and critiques are welcome. Th...
New

Other popular topics Top

chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Sub Categories:

We're in Beta

About us Mission Statement