mobileraker icon indicating copy to clipboard operation
mobileraker copied to clipboard

WebRTC/MediaMTX Support

Open ihatemyisp opened this issue 1 year ago • 3 comments

Feature Request

Problem Description

I use a couple of Wyze cameras to monitor my printer and enclosure. They are streamed to Mainsail via WyzeBridge which uses WebRTC/MediaMTX. Support for MediaMTX is baked into Mailsail and it works flawlessly.

Proposed Solution

Add WebRTC/MediaMTX support.

Alternatives Considered

Unfortunately in my case, there is no alternative that makes sense.

Additional Context

None necessary, I believe.


Checklist To help us understand your feature request, please ensure you've covered the following points:

  • [x] Provided a clear description of the problem you're facing.
  • [x] Clearly outlined the proposed solution or feature.
  • [x] Mentioned any alternative solutions or ideas you've considered.
  • [x] Included any relevant context or supporting materials.

Your input is valuable in shaping the development of our project. Thank you for taking the time to submit your feature request!

ihatemyisp avatar Mar 26 '24 19:03 ihatemyisp

Can you provide me an example code that shows how the messaging for MediaMTX works?

Clon1998 avatar Mar 26 '24 21:03 Clon1998

I've actually been digging through it trying to figure out if I could get this working myself. I'm having issues making heads or tails of all of it, hah.

WyzeBridge gives me a WebRTC URL (i.e., http://3d2.lan:8889/sv06-plus/) and I plug that into Mainsail. I got started down this rabbit hole via the Crowsnest docs: https://crowsnest.mainsail.xyz/faq/how-to-use-wyze-cams.

When I load the URL by itself I get a player and the stream starts. Here's the source from that: https://url.vogon.dev/YellowGummyNorth

Now that I'm thinking about it, I kind of feel like I could've looked at the Mainsail source and tried to grab more info on how they did it before posting. My apologies.

ihatemyisp avatar Mar 26 '24 22:03 ihatemyisp

https://github.com/mainsail-crew/mainsail/blob/develop/src/components/webcams/streamers/WebrtcMediaMTX.vue

It looks very similar to their WebrtcGo2rtc implementation...I think.

ihatemyisp avatar Apr 23 '24 01:04 ihatemyisp

@Clon1998 I'm also interested in this, and I'm happy to provide whatever you need 👍

This PR implements MediaMTX in Fluidd and includes a docker container for testing MediaMTX locally: https://github.com/fluidd-core/fluidd/pull/1409

kamermans avatar Aug 13 '24 21:08 kamermans

I will look into this once I am back home in two weeks

Clon1998 avatar Aug 14 '24 19:08 Clon1998

If any of you want to try porting the fluidd code to dart/mobileraker. I am using flutter_webrtc. The interface for the WebRtc Manager that handles the connection/states is:

/// Manager
abstract interface class WebRtcManager {
  Stream<WebRtcConnectionEvent> get stream;

  Future<void> startCam();

  Future<void> stopCam();

  void dispose();
}
/// Event Classes
sealed class WebRtcConnectionEvent {}

class WebRtcConnectionEventNew extends WebRtcConnectionEvent {}

class WebRtcConnectionEventClosed extends WebRtcConnectionEvent {}

class WebRtcConnectionEventFailed extends WebRtcConnectionEvent {
  WebRtcConnectionEventFailed([this.error]);

  Object? error;

  @override
  String toString() {
    return 'WebRtcConnectionEventFailed{error: $error}';
  }
}

class WebRtcConnectionEventDisconnected extends WebRtcConnectionEvent {}

class WebRtcConnectionEventConnecting extends WebRtcConnectionEvent {}

class WebRtcConnectionEventConnected extends WebRtcConnectionEvent {
  final RTCVideoRenderer videoRenderer;

  WebRtcConnectionEventConnected(this.videoRenderer);
}

And the Widget to view the WebRtc content is provided via a platform renderer via this Widget:

/// UI/Widget to render the native Texture(WebRtc stream)
class _RtcRenderer extends HookWidget {
  const _RtcRenderer(this._renderer, {Key? key}) : super(key: key);

  final RTCVideoRenderer _renderer;

  @override
  Widget build(BuildContext context) {
    var videoValue = useValueListenable(_renderer);
    if (!videoValue.renderVideo) return const Text('components.web_rtc.renderer_missing').tr();

    return AspectRatio(
      aspectRatio: videoValue.width / videoValue.height,
      child: Texture(
        textureId: _renderer.textureId!,
      ),
    );
  }
}

Clon1998 avatar Aug 16 '24 15:08 Clon1998

Thanks @Clon1998, I'm not a Dart developer, but I do know many other languages, so I'll take a look at it unless you beat me to it :)

kamermans avatar Aug 16 '24 19:08 kamermans