构建直播平台大体的流程

发布于:2025-07-20 ⋅ 阅读:(13) ⋅ 点赞:(0)

✅ 直播流程完整链路(基于 SRS + OBS + 前后端)


🧍‍♂️ 用户操作流程:

  1. 用户登录系统(前端)

    • 系统中校验用户身份(JWT 等)

    • 后端可能校验权限,比如“是否有开播资格”

  2. 用户点击“我要开播”

    • 前端调用后端接口,例如:POST /api/live/apply

    • 后端生成并返回推流地址 + 推流码(Key)

      • 示例返回:

        { "livePushUrl": "rtmp://your-srs-ip/live/room123", "livePushSecret": "abc123" // 有些平台把推流码单独拆开 }

  3. 前端展示推流地址 + 推流码

    • 前端展示给用户复制:

      推流地址: rtmp://your-srs-ip/live 推流码(StreamName): room123?token=abc123

  4. 用户打开 OBS

    • 进入设置 > 推流

      • 服务:自定义

      • 推流地址:rtmp://your-srs-ip/live

      • 串流密钥(推流码):room123?token=abc123

    • 开始推流


📡 技术流程图(你可以参考这个思维路径):

[用户点击我要开播]
     ↓
[前端调用后端接口生成推流地址]
     ↓
[后端生成 RTMP 地址和推流密钥]
     ↓
[前端展示推流地址+密钥]
     ↓
[用户复制地址/密钥到 OBS 开始推流]
     ↓
[OBS 推流至 SRS 流媒体服务器]
     ↓
[SRS 接收 RTMP 流并转为 FLV/HLS 等格式]
     ↓
[用户/观众端 前端播放器(flv.js)拉取播放地址,播放视频流]


🎬 观众端播放流程:

  1. 前端页面通过 flv.jsvideo.js 拉取播放地址,比如:

    http://your-srs-ip/live/room123.flv

  2. 播放器组件 flv.js 将流绑定在 <video> 标签上

  3. 用户看到直播画面


🧠 小贴士(进阶要点)

环节 补充说明
推流地址 一般是 rtmp://ip/live/房间号,后面可附加签名参数防盗链
推流码(stream key) 可作为 URL 的查询参数,便于权限控制
播放地址 一般用 .flv.m3u8,给前端播放器使用
OBS 只要填写好推流地址和 key,就能推流成功
SRS 可配置是否开启 flv/hls/webrtc 输出,是否验证签名等

前端组件页面

<template>
  <div class="live-play-wrapper">
    <div class="player-header">
      <h2>直播播放</h2>
      <p v-if="!url" class="error-text">⚠️ 当前无有效直播地址</p>
    </div>

    <div class="player-container" v-if="url">
      <video
        ref="videoElement"
        id="videoElement"
        controls
        autoplay
        muted
        width="100%"
        height="100%"
        class="video-player"
      ></video>
    </div>

    <div v-else class="no-url-placeholder">
      <p>请等待推流或联系管理员开启直播</p>
    </div>
  </div>
</template>

<script>
import flvjs from "flv.js";

export default {
  name: "LivePlay",
  props: {
    url: {
      type: String,
      required: false,
      default: "",
    },
  },
  data() {
    return {
      flvPlayer: null,
    };
  },
  watch: {
    url(newUrl) {
      console.log("播放地址变化:", newUrl);
      this.destroyPlayer();
      if (newUrl) {
        this.initPlayer(newUrl);
      }
    },
  },
  mounted() {
    if (this.url) {
      this.initPlayer(this.url);
    }
  },
  beforeDestroy() {
    this.destroyPlayer();
  },
  methods: {
    initPlayer(playUrl) {
      if (flvjs.isSupported()) {
        const video = this.$refs.videoElement;
        this.flvPlayer = flvjs.createPlayer({
          type: "flv",
          url: playUrl,
          isLive: true,
        });
        this.flvPlayer.attachMediaElement(video);
        this.flvPlayer.load();
        this.flvPlayer.play().catch((err) => {
          console.error("播放失败", err);
        });

        // 监听播放错误
        this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
          console.error("FLV 播放出错", errType, errDetail);
          // 可选:自动重连
          // setTimeout(() => this.initPlayer(playUrl), 3000);
        });
      } else {
        console.warn("浏览器不支持 flv.js 播放");
      }
    },
    destroyPlayer() {
      if (this.flvPlayer) {
        this.flvPlayer.destroy();
        this.flvPlayer = null;
      }
    },
  },
};
</script>

<style scoped>
.live-play-wrapper {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 20px;
}
.player-header {
  text-align: center;
  margin-bottom: 15px;
}
.error-text {
  color: red;
  font-weight: bold;
}
.player-container {
  border: 2px solid #ccc;
  border-radius: 10px;
  overflow: hidden;
  background: #000;
  height: 540px;
}
.video-player {
  width: 100%;
  height: 100%;
  background-color: #000;
}
.no-url-placeholder {
  text-align: center;
  font-size: 16px;
  color: #999;
  margin-top: 30px;
}
</style>

使用组件标签

<LivePlay :url="'http://your-srs-server/live/room123.flv'" />


网站公告

今日签到

点亮在社区的每一天
去签到