You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何搭建并在线托管可同时对接StreamYard平台与Flutter移动端的自定义RTMP服务器?及替代方案咨询

Absolutely, you can set up a cloud-hosted RTMP relay server to bridge StreamYard with your Flutter app and other platforms like Facebook/YouTube. Let's break down the solutions step by step, including both RTMP-based setups and WebRTC alternatives for lower latency.

Cloud-Hosted RTMP Relay Server Setup

Your core goal is to create a central node that receives StreamYard's RTMP stream, then forwards it to Facebook, YouTube, and serves it to your Flutter app. Here's how to implement this with a cloud server:

Choose a Cloud Provider & Server

Pick a cloud host with low latency and sufficient bandwidth (start with a basic instance like AWS t2.micro, DigitalOcean 1GB Droplet, or Google Cloud e2-micro—these are cheap enough for initial testing). Opt for an Ubuntu/Debian-based OS for easy software installation.

Skip the complex Nginx+RTMP setup—SRS (Simple RTMP Server) is an open-source, lightweight media server designed for live streaming, with built-in support for RTMP forwarding and HLS/WebRTC conversion.

  1. SSH into your cloud server and run the official installation script:
    curl -sSL https://github.com/ossrs/srs/releases/download/v5.0.170/srs-ubuntu20-64.tar.gz | tar xzvf -
    cd srs-ubuntu20-64
    
  2. Edit the RTMP configuration file (conf/rtmp.conf) to add your stream key and forwarding targets:
    rtmp {
        server {
            listen 1935;
            chunk_size 4096;
    
            application live {
                live on;
                # Allow StreamYard to push to this address: rtmp://YOUR_SERVER_IP/live/YOUR_STREAM_KEY
                forward rtmp://live-api-s.facebook.com:80/rtmp/FACEBOOK_STREAM_KEY;
                forward rtmp://a.rtmp.youtube.com/live2/YOUTUBE_STREAM_KEY;
            }
        }
    }
    
  3. Start the server:
    ./objs/srs -c conf/rtmp.conf
    
    For persistent running, set up a systemd service (follow SRS's official docs for this).

Configure Stream Forwarding to Facebook/YouTube

Replace FACEBOOK_STREAM_KEY and YOUTUBE_STREAM_KEY with the actual keys from your Facebook Live and YouTube Studio accounts. SRS will automatically forward the incoming StreamYard stream to both platforms as soon as it starts receiving data.

Open Required Ports

In your cloud provider's security group/firewall settings, open:

  • Port 1935 (RTMP for incoming StreamYard pushes and potential direct Flutter playback)
  • Port 80/443 (for HLS stream access, which is more stable on mobile)
  • Port 8000 (if you plan to use WebRTC later)
Flutter App Integration for Live Stream Playback

RTMP isn't the most mobile-friendly protocol, so converting the stream to HLS (HTTP Live Streaming) is the better approach for Flutter apps—it's supported natively by most mobile OSes and has better error handling.

Option 1: Play HLS Stream (Stable, Wide Compatibility)

First, enable HLS in your SRS config by adding this to conf/rtmp.conf:

http_server {
    enabled on;
    listen 80;
    dir ./objs/nginx/html;
}

hls {
    enabled on;
    hls_path ./objs/nginx/html/live;
    hls_fragment 10;
    hls_window 60;
}

Restart SRS, and your HLS stream will be available at http://YOUR_SERVER_IP/live/YOUR_STREAM_KEY.m3u8.

Use Flutter's official video_player package to play this stream:

import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';

class LiveStreamPlayer extends StatefulWidget {
  const LiveStreamPlayer({super.key});

  @override
  State<LiveStreamPlayer> createState() => _LiveStreamPlayerState();
}

class _LiveStreamPlayerState extends State<LiveStreamPlayer> {
  late VideoPlayerController _controller;
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _initPlayer();
  }

  Future<void> _initPlayer() async {
    _controller = VideoPlayerController.networkUrl(
      Uri.parse('http://YOUR_SERVER_IP/live/YOUR_STREAM_KEY.m3u8'),
      videoPlayerOptions: const VideoPlayerOptions(mixWithOthers: true),
    );

    await _controller.initialize();
    setState(() => _isLoading = false);
    await _controller.play();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _isLoading
            ? const CircularProgressIndicator()
            : AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: VideoPlayer(_controller),
              ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(
          () => _controller.value.isPlaying
              ? _controller.pause()
              : _controller.play(),
        ),
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}

Option 2: Direct RTMP Playback (Less Common, Higher Latency)

If you need lower latency than HLS (but higher than WebRTC), use a third-party plugin like flutter_rtmp_player to play the raw RTMP stream. Note that this may have compatibility issues across devices.

WebRTC Alternative for Low-Latency Streaming

If you want sub-1-second latency (critical for interactive use cases), WebRTC is a better choice. SRS supports converting RTMP streams to WebRTC, so you can keep using StreamYard as your source.

Setup SRS with WebRTC Support

Add this to your SRS config (conf/rtmp.conf):

rtc_server {
    enabled on;
    listen 8000; # WebRTC UDP port
    candidate YOUR_SERVER_IP; # Public IP of your cloud server
}

rtc {
    enabled on;
    rtmp_to_rtc on; # Convert incoming RTMP streams to WebRTC
}

Restart SRS to apply changes.

Flutter WebRTC Integration

Use the flutter_webrtc package to connect to the WebRTC stream. Here's a basic example:

import 'package:flutter_webrtc/flutter_webrtc.dart';
import 'package:flutter/material.dart';
import 'dart:convert';

class WebRTCStreamPlayer extends StatefulWidget {
  const WebRTCStreamPlayer({super.key});

  @override
  State<WebRTCStreamPlayer> createState() => _WebRTCStreamPlayerState();
}

class _WebRTCStreamPlayerState extends State<WebRTCStreamPlayer> {
  final _videoRenderer = RTCVideoRenderer();
  RTCPeerConnection? _peerConnection;

  @override
  void initState() {
    super.initState();
    _initRenderer();
    _connectToStream();
  }

  Future<void> _initRenderer() async {
    await _videoRenderer.initialize();
  }

  Future<void> _connectToStream() async {
    final configuration = <String, dynamic>{
      'iceServers': [{'urls': 'stun:stun.l.google.com:19302'}]
    };

    _peerConnection = await createPeerConnection(configuration);

    // Fetch offer from SRS's HTTP API (replace with your server details)
    final offerResponse = await Uri.parse('http://YOUR_SERVER_IP:8080/api/v1/rtc/offer?stream=live/YOUR_STREAM_KEY')
        .get();
    final offerData = jsonDecode(await offerResponse.body);
    final remoteOffer = RTCSessionDescription(
      offerData['sdp'],
      offerData['type'],
    );

    await _peerConnection!.setRemoteDescription(remoteOffer);
    final answer = await _peerConnection!.createAnswer();
    await _peerConnection!.setLocalDescription(answer);

    // Send answer back to SRS to establish connection
    await Uri.parse('http://YOUR_SERVER_IP:8080/api/v1/rtc/answer')
        .post(
          headers: {'Content-Type': 'application/json'},
          body: jsonEncode({
            'stream': 'live/YOUR_STREAM_KEY',
            'sdp': answer.sdp,
            'type': answer.type,
          }),
        );

    // Attach video track to renderer
    _peerConnection!.onTrack = (event) {
      if (event.track.kind == 'video') {
        setState(() => _videoRenderer.srcObject = event.streams[0]);
      }
    };
  }

  @override
  void dispose() {
    _videoRenderer.dispose();
    _peerConnection?.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RTCVideoView(_videoRenderer),
    );
  }
}
Key Considerations
  • Bandwidth: Ensure your cloud server has enough uplink bandwidth to handle simultaneous streams to Facebook, YouTube, and your Flutter app (start with 5-10 Mbps for 720p streams).
  • Security: Restrict RTMP access to your server using IP whitelisting or stream key authentication to prevent unauthorized pushes.
  • Cost: Self-hosted SRS on a basic cloud instance costs ~$5-$10/month. Managed services like Cloudflare Stream or Wowza are more expensive but require less maintenance.

内容的提问来源于stack exchange,提问作者adamu_fura

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 07:18:14