Giter Club home page Giter Club logo

rust-media-libs's Introduction

rust-media-libs

Rust based libraries for misc media functionality

License

This project is distributed under the terms of both MIT license and the Apache License (Version 2.0).

Libraries

There are currently 2 supported libraries in this project:

  • rml_amf0 - Crate supporting the serialization and deserialization of amf0 encoded data.
  • rml_rtmp - Crate providing high and low level APIs for supporting the Adobe RTMP protocol.

Examples

Several examples have been created that utilize these libraries

  • tokio_rtmp_server - This is an example of using the library to create an RTMP server with async rust and Tokio. Clients can connect, publish video to a stream, and other clients can connect and play the stream back.

  • mio_rtmp_server - This is a semi-advanced example of creating a mio application that can act as both a client and a server. It supports:

    • Clients can connect and publish video to a stream.
    • Clients can connect and play video that is being published to a stream.
    • The server can pull live video from a remote server and relay the video stream to subscribed players.
    • The server can take a video stream that a client is publishing and republish that out to another RTMP server.
  • threaded_rtmp_server - This is a very simple RTMP server that allows clients to publish video and players to watch video.

Tools

Several tools are provided in this repository:

  • rtmp-log-reader - Allows the reading of raw RTMP binary that are encoded in a file. This is used for debugging RTMP conversations between two parties.

  • handshake-tester - Tool to verify handshaking can be performed with another RTMP server.

rust-media-libs's People

Contributors

alexschhmchr avatar arekkusuva avatar christiaan676 avatar erikstmartin avatar honzamatosik avatar huheng avatar jakobssen avatar jamesbirtles avatar jonathanmurray avatar jonathanusername avatar kalldrexx avatar kcking avatar martijnberger avatar mdorofeev avatar pvheiningen avatar rawler avatar sfackler avatar simon-fu avatar wutchzone avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rust-media-libs's Issues

Player endpoint

Hi, thanks for this package, it's been helpful, however I need some help as I am relatively new to RUST. Please say I am streaming to the Mio example with stream key "rust", what endpoint should the player connect to. Thank you

UnknownPacket1Format error occors when trying to push to YouTube Live

I trying to push rtmp stream to YouTube Live using mio_rtmp_server, but it sccors UnknownPacket1Format error.
How can I deliver to YouTube Live?

$ dig +short a.rtmp.youtube.com # because it do not resolve domain
bartmp.l.google.com.
173.194.49.204
$ cargo run -h 173.194.49.204 -a live2 -t youtube-live-key -s mykey
Application options: AppOptions { log_io: false, pull: None, push: Some(PushOptions { host: "173.194.49.204", app: "live2", source_stream: "mykey", target_stream: "youtube-live-key" }) }
Listening for connections
New connection (id 0)
Spent 5 ms (0% of time) doing work over 11 seconds (avg 5009 microseconds per iteration)
Handshake successful!
Connection 0 requested connection to app 'live2'
Event raised by connection 0: UnhandleableAmf0Command { command_name: "_checkbw", transaction_id: 2.0, command_object: Null, additional_values: [] }
Event raised by connection 0: UnhandleableAmf0Command { command_name: "releaseStream", transaction_id: 3.0, command_object: Null, additional_values: [Utf8String("mykey")] 
}
Event raised by connection 0: UnhandleableAmf0Command { command_name: "FCPublish", transaction_id: 4.0, command_object: Null, additional_values: [Utf8String("mykey")] }   
Publish requested on app 'live2' and stream key 'mykey'
Publishing on the push source stream key!
Starting push to rtmp://173.194.49.204/live2/youtube-live-key
Push client started with connection id 1
Handshake error: HandshakeError { kind: UnknownPacket1Format }
Closing connection id 1

Unable to deserialize AMF0 Command _result('NetConnection.Connect.Success') after requesting Connection in ClientSession

Hi,

I'm trying to connect to Twitch. After a successful handshake I try to use ClientSession::request_connection(), but after receiving some packets and passing them into handle_input() I get the following error: ChunkDeserializationError { kind: NoPreviousChunkOnStream { csid: 46 } }

In WireShark I found out, that it's the AMF0 Command _result('NetConnection.Connect.Success')) packet, that causes the error. Here's a hex dump from WireShark:

0000 c4 9d ed 92 05 9b 18 83 bf 8d 20 18 08 00 45 00
0010 01 63 c4 ca 40 00 3b 06 2f 94 b9 2a cd f4 c0 a8
0020 02 6f 07 8f dc 0a 20 e7 f2 56 f5 31 dd c9 50 18
0030 88 20 9f 4d 00 00 02 00 00 00 00 00 04 05 00 00
0040 00 00 00 26 25 a0 02 00 00 00 00 00 05 06 00 00
0050 00 00 00 26 25 a0 02 02 00 00 00 00 00 06 04 00
0060 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 04
0070 01 00 00 00 00 00 00 10 00 03 00 00 00 00 00 ec
0080 14 00 00 00 00 02 00 07 5f 72 65 73 75 6c 74 00
0090 3f f0 00 00 00 00 00 00 03 00 06 66 6d 73 56 65
00a0 72 02 00 0e 46 4d 53 2f 33 2c 35 2c 37 2c 37 30
00b0 30 39 00 0c 63 61 70 61 62 69 6c 69 74 69 65 73
00c0 00 40 3f 00 00 00 00 00 00 00 04 6d 6f 64 65 00
00d0 3f f0 00 00 00 00 00 00 00 00 09 03 00 05 6c 65
00e0 76 65 6c 02 00 06 73 74 61 74 75 73 00 04 63 6f
00f0 64 65 02 00 1d 4e 65 74 43 6f 6e 6e 65 63 74 69
0100 6f 6e 2e 43 6f 6e 6e 65 63 74 2e 53 75 63 63 65
0110 73 73 00 0b 64 65 73 63 72 69 70 74 69 6f 6e 02
0120 00 14 43 6f 6e 6e 65 63 74 69 6f 6e 20 61 63 63
0130 65 70 74 65 64 2e 00 04 64 61 74 61 03 00 06 73
0140 74 72 69 6e 67 02 00 0a 33 2c 35 2c 37 2c 37 30
0150 30 39 00 00 09 00 0e 6f 62 6a 65 63 74 45 6e 63
0160 6f 64 69 6e 67 00 00 00 00 00 00 00 00 00 00 00
0170 09

The 4 packets before are getting successfully deserialized.

RTMPx

Hi Folks,
is rust-media-libs support RTMPS, RTMPE, RTMPTE, RTMPT AND RTMFP?
Thanks to tell which protocol stil not supported so I will try to join a community task force.

threaded rtmp server example will spin wait resulting in high CPU load

In the threaded_rtmp_server example, the function handle_connections will poll the channels as fast as it can resulting in a 100% CPU load for that thread.

The function handle_connections calls connection_receiver.try_recv() and connection.read() (containing reader.try_recv()) in a loop. As there is no blocking operation, the loop will spin wait until a new connection is established or data is received.

On solution would be to use the crossbeam select macro on the two channels. Though that would require exposing the channel in the connection.read() function.

Make rml_rtmp::handshake::HandshakeError public

Hi!

First, thanks for a great library - really enjoying working with it so far. I am fairly new to Rust and am currently building an rtmp server with tokio (using the mio example as a base).

Currently HandshakeError is only publicly availble through rml_rtmp::handshake::errors but is privately imported in rml_rtmp::handshake.

When working on the handshake phase of the connection, I imported all the components I required via rml_rtmp::handshake::{HandshakeResult, Handshake, PeerType}, but had to have a separate import to get access to the HandshakeError.

I suggest for simplicity publicly exposing HandshakeError through rml_rtmp::handshake.

Removing watching via RTMP functionality.

Hey there, I'm trying to remove the ability to watch via RTMP because on my setup it's just a vulnerability (easy DDOSing/bypassing of access controls), I have a whole separate service that handles distribution. I commented out "PlayStreamRequested" in handle_raised_event() but noticed there are other places (I think, please correct me if I'm wrong) where clients can get added, such as https://github.com/KallDrexx/rust-media-libs/blob/master/examples/mio_rtmp_server/src/server.rs 277. Can I have some guidance on what to remove? Thanks :)

Limit stream creation in ServerSession?

ServerSession currently always allows the creation of new streams, and maintains a little bit of state for each in a hash map. In a scenario where you're authenticating clients on connect, the current behavior allows for unauthenticated clients to create an unlimited number of streams and e.g. OOM the server.

The RTMP spec is not super explicit, but I think it's implied that the connect command is always expected to come first before any createStreams. Do you think it'd make sense to check that the session is already connected in createStream similar to what's done when handling publish, play, etc?

It might also be nice to allow consumers to limit the number of concurrent streams even post-connect. It seems like RTMP use in the modern era is always one stream per connection (I think?), so enforcing a limit in ServerSession could help protect against malicious/broken clients as well.

Serialization of larger payloads can lead to incorrect chunks

With increased bitrates, the rtmp stream created by the mio-rtmp-server is no longer playable in ffmpeg.

Steps to Reproduce

  1. Build latest version of mio-rtmp-server v0.1.1 and run it
  2. Create a test stream on the same device that is running the rtmp server.

We tested with the following commands:

  • gst-launch-1.0 videotestsrc pattern=1 ! 'video/x-raw,width=1920,height=1080' ! videoconvert ! x264enc bitrate=30000 ! h264parse ! flvmux ! rtmp2sink location='rtmp://localhost:1935/test'
  • ffmpeg -re -f lavfi -i testsrc2=size=1920x1080:rate=30 -b:v 8M -c:v libx264 -profile:v main -pix_fmt yuv420p -threads 7 -f flv rtmp://localhost/test
  1. Connect to the stream with ffmpeg: ffplay -loglevel trace -noinfbuf rtmp://IPADDRESS/live/test
  2. The following errors are observed:
[rtmp @ 0x7f2c78001780] No default whitelist set
[tcp @ 0x7f2c78002040] No default whitelist set
[tcp @ 0x7f2c78002040] Original list of addresses:
[tcp @ 0x7f2c78002040] Address 192.168.2.138 port 1935
[tcp @ 0x7f2c78002040] Interleaved list of addresses:
[tcp @ 0x7f2c78002040] Address 192.168.2.138 port 1935
[tcp @ 0x7f2c78002040] Starting connection attempt to 192.168.2.138 port 1935
[tcp @ 0x7f2c78002040] Successfully connected to 192.168.2.138 port 1935
[rtmp @ 0x7f2c78001780] Handshaking...
[rtmp @ 0x7f2c78001780] Type answer 3B vq=    0KB sq=    0B f=0/0   
[rtmp @ 0x7f2c78001780] Server version 128.0.7.2
[rtmp @ 0x7f2c78001780] Proto = rtmp, path = /live/test, app = live, fname = test
[rtmp @ 0x7f2c78001780] New incoming chunk size = 4096
[rtmp @ 0x7f2c78001780] Window acknowledgement size = 1073741824
[rtmp @ 0x7f2c78001780] Max sent, unacked = 2500000
[rtmp @ 0x7f2c78001780] Creating stream...
[rtmp @ 0x7f2c78001780] Sending play command for 'test' f=0/0   
[rtmp @ 0x7f2c78001780] Unknown packet type received 0x000B f=0/0   
    Last message repeated 9 times
[tcp @ 0x7f2c78002040] RTMP packet size mismatch 9851467 != 14907160

Detailed Description

When lowering the bitrate of the original stream (to 3 Mb/s) the resulting output stream can correctly be played.

We dumped the logs with the --log-io option in the mio-rtmp-server, and parsed them with the rtmp-log-reader v0.1.0. The input logs could be parsed correctly, but parsing the output logs caused a ChunkDeserializationError:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ChunkDeserializationError { kind: NoPreviousChunkOnStream { csid: 7 } }', tools/rtmp-log-reader/src/main.rs:50:70 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

1624005090-1.rtmp.input.log

1624005096-2.rtmp.output.log

It seems like there is a header packet that contains an invalid chunk stream id which caused both the parser and ffmpeg to fail.

Thanks in advance for any advice/help!

Support for pushing MPEG-TS streams to external RTMP servers

Description:
Hello! I am interested in using the rust-media-libs library for streaming MPEG-TS video content to an external RTMP server like YouTube. I have read through the documentation and searched through the examples, but I haven't found any clear instructions on how to do this.

Can you please provide guidance or an example on how to push a MPEG-TS stream to an external RTMP server using this library? It would be really helpful if you could add this functionality to the library as well.

Thank you for your hard work on this library and I appreciate any help you can provide.

Best regards,
Onojeta Brown

rml_rtmp: Update bytes to 0.5 on crates-io

It appears bytes have been upgraded to 0.5 in eb7f41d, however no new release was made to crates-io since, which means peoples using this crates are still stuck at bytes 0.4, would it be possible to do such a release?

Writing video data to file.

Hello! Below is my modified code of the "handle_audio_video_data_received" function in the mio_rtmp_server example. When I write the incoming data to a file and try to play it back, not even ffmpeg is sure what it is. I'm sure I'm missing something obvious, but could someone help me out? Thanks.

fn handle_audio_video_data_received(
        &mut self,
        stream_key: String,
        timestamp: RtmpTimestamp,
        data: Bytes,
        data_type: ReceivedDataType,
        server_results: &mut Vec<ServerResult>,
    ) {
        {
            let file_path = "/Users/example-user/Documents/video_file.flv";

            let cloned_data = data.clone();

            let handle = thread::spawn(move || {
                // Open the file in append mode (creates if it doesn't exist).
                let mut file = match OpenOptions::new().create(true).append(true).open(file_path) {
                    Ok(file) => file,
                    Err(err) => {
                        eprintln!("Error opening the file: {}", err);
                        return;
                    }
                };
        
                // Write the video stream data to the end of the file.
                if let Err(err) = file.write(&cloned_data) {
                    eprintln!("Error writing to the file: {}", err);
                    return;
                }
            });
        
            let channel = match self.channels.get_mut(&stream_key) {
                Some(channel) => channel,
                None => return,
            };
            ```

"onBWDone" in RTMP server session causes some clients to disconnect

As part of the initial outbound messages, the RTMP ServerSession sends out an "onBWDone" Amf0Command. I have discovered that the RTMP live streaming application PRISM Live Studio (v3.8.3, Android) disconnects immediately upon receiving this command.

I have collected two Wireshark captures to demonstrate this behavior, first with the offending command included:
SS_B
And again without the command, displaying normal behavior as expected:
SS_A
Here 192.168.1.41 is the server and 192.168.1.42 the client.

For my use case it would be great to have the option to not send out this command, although I may have to manually send it out for clients that might wait on "onBWDone" before continuing, should I come across one.

In any case, thank you for your work on such a functional and easy-to-use library for a protocol that is anything but.

Help to execute code

Hi, I am trying to use your project (the mio server) but It seems it is not working or I don't understand how... I execute your server, and It works... Also, I execute ffmpeg to send it a video and it seems that it is working well:

ffmpeg -re -i video.mkv -c:v libx264 -preset veryfast -maxrate 3000k -bufsize 6000k -pix_fmt yuv420p -g 50 -c:a aac -b:a 160k -ac 2 -ar 44100 -f flv rtmp://localhost:1935
But If when I use the VLC player, It seems It connects but I can not display anything... (my vlc connect to the rtmp://localhost:1935)
Do you have some extradescription to use it...

send_metadata shouldn't take an Rc

Currently the send_metadata fn on a ServerSession takes the stream metadata as an Rc which seems like an odd design choice when it could easily take &StreamMetadata. This is causing me to need to create an Rc whenever I call this as I don't already have the metadata in an Rc and prevents me from using something like an Arc

pub fn send_metadata(&mut self, stream_id: u32, metadata: Rc<StreamMetadata>) -> Result<Packet, ServerSessionError> {

Happy to submit a PR changing this if there are no objections

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.