炸裂!Spring Boot 3 搭配 AI 实现智能弹幕审核 + Redis 热点缓存 + 上下文识别

我们用 Spring Boot 3 + WebSocket 打造了一个实时弹幕系统。​ 但如果直接上线,你很快会遇到两个大坑:弹幕内容违规:低俗、谩骂、广告等让平台形象瞬间翻车; 高并发压力大:弹幕量一多,数据库吃不消,延迟飙升。

我们用 Spring Boot 3 + WebSocket 打造了一个实时弹幕系统。 但如果直接上线,你很快会遇到两个大坑:

  • 弹幕内容违规:低俗、谩骂、广告等让平台形象瞬间翻车
  • 高并发压力大:弹幕量一多,数据库吃不消,延迟飙升

这次升级,我们带来三个杀手锏:

  1. AI 上下文审核:不仅看当前弹幕,还结合前后语境识别违规内容
  2. Redis 热点缓存:热门视频弹幕秒加载,架构简单高效
  3. 前端实时渲染:秒进直播间就能看到历史弹幕

为什么需要“上下文审核”

传统方式的短板

  • 人工审核:效率低,延迟大
  • 关键词过滤:只能处理已知词库,容易被谐音梗绕过
  • 单句 AI 审核:可能漏判连续擦边球弹幕

上下文审核的优势

  • AI 能够结合前后几条弹幕判断是否存在隐晦违规
  • 可识别“接龙式”或“暗示型”违规行为
  • 有助于减少误判和漏判
整体架构

复制

[前端发弹幕]
      ↓
[WebSocket 收到弹幕]
      ↓
[AI 审核模块(带上下文)] —— 违规 → 丢弃/替换
      ↓
[Redis 缓存 + 推送给前端]
      ↓
[前端实时渲染弹幕]
依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.12.0</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
AI 审核服务(支持上下文)
@Service
public class AiModerationService {
    private static final String API_URL = "https://api.openai.com/v1/chat/completions";
    private static final String API_KEY = "你的AI_KEY";


    // 每个视频保留最近5条弹幕作为上下文
    private final Map<String, Deque<String>> contextMap = new ConcurrentHashMap<>();


    public boolean isSafe(String videoId, String currentMsg) {
        Deque<String> context = contextMap.computeIfAbsent(videoId, k -> new LinkedList<>());


        // 构建上下文
        List<String> conversation = new ArrayList<>(context);
        conversation.add(currentMsg);


        try (OkHttpClient client = new OkHttpClient()) {
            StringBuilder prompt = new StringBuilder("你是一个弹幕审核系统,请判断以下多条弹幕整体是否存在违规内容(涉黄、暴力、辱骂、广告等)。只返回 true 或 false。\n\n弹幕内容:\n");
            for (String msg : conversation) {
                prompt.append("- ").append(msg).append("\n");
            }


            String json = """
            {
              "model": "gpt-3.5-turbo",
              "messages": [
                {"role": "system", "content": "你是一个安全审核系统"},
                {"role": "user", "content": "%s"}
              ],
              "temperature": 0
            }
            """.formatted(prompt.toString());


            RequestBody body = RequestBody.create(json, MediaType.parse("application/json"));
            Request request = new Request.Builder()
                    .url(API_URL)
                    .post(body)
                    .addHeader("Authorization", "Bearer " + API_KEY)
                    .build();


            Response response = client.newCall(request).execute();
            String result = response.body().string();
            boolean safe = result.toLowerCase().contains("true");


            // 维护上下文(只保留最新5条)
            context.addLast(currentMsg);
            if (context.size() > 5) {
                context.removeFirst();
            }


            return safe;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
  • 每个视频维护一个最近 5 条弹幕的队列
  • 每次审核时,AI 会看到上下文而不是单条弹幕
  • 有助于识别“连续擦边”或“接龙违规”

Redis 热点缓存方案

思路
  • 弹幕审核通过后,直接存入 Redis List,按 videoId 作为 key
  • 前端首次进入视频时,从 Redis 获取最新 N 条弹幕
  • Redis 弹幕过期时间设置为视频播放窗口(例如 1 小时)
核心代码
@Service
public class DanmakuService {
    @Autowired
    private AiModerationService aiService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SimpMessagingTemplate messagingTemplate;


    private static final String REDIS_KEY_PREFIX = "danmaku:";


    public void handleIncomingDanmaku(DanmakuDTO dto) {
        if (aiService.isSafe(dto.getVideoId(), dto.getContent())) {
            String key = REDIS_KEY_PREFIX + dto.getVideoId();
            redisTemplate.opsForList().rightPush(key, dto.getContent());
            redisTemplate.expire(key, Duration.ofHours(1));
            messagingTemplate.convertAndSend("/topic/video/" + dto.getVideoId(), dto);
        } else {
            System.out.println("违规弹幕已拦截: " + dto.getContent());
        }
    }


    public List<String> getLatestDanmakus(String videoId, int limit) {
        String key = REDIS_KEY_PREFIX + videoId;
        Long size = redisTemplate.opsForList().size(key);
        if (size == null || size == 0) return List.of();
        return redisTemplate.opsForList().range(key, Math.max(0, size - limit), size - 1);
    }
}
历史弹幕 API
@RestController
@RequestMapping("/api/danmaku")
public class DanmakuController {
    @Autowired
    private DanmakuService danmakuService;


    @GetMapping("/latest")
    public List<String> getLatestDanmakus(@RequestParam String videoId,
                                          @RequestParam(defaultValue = "20") int limit) {
        return danmakuService.getLatestDanmakus(videoId, limit);
    }
}

    前端弹幕展示实现(Vue 3)

    页面结构
    <template>
      <div class="video-container">
        <video :src="videoSrc" controls autoplay></video>
        <div class="danmaku-container">
          <div v-for="(msg, index) in danmakus" 
               :key="index" 
               class="danmaku"
               :style="{ top: `${getRandomTop()}%` }">
            {{ msg }}
          </div>
        </div>
        <input v-model="inputMsg" placeholder="发送弹幕..." @keyup.enter="sendDanmaku" />
      </div>
    </template>
    样式(CSS 漂浮效果)

    .video-container {
      position: relative;
      width: 800px;
      height: 450px;
    }
    .danmaku-container {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      pointer-events: none;
    }
    .danmaku {
      position: absolute;
      white-space: nowrap;
      animation: danmaku-move 5s linear forwards;
      font-size: 18px;
      color: white;
      text-shadow: 1px 1px 2px black;
    }
    @keyframes danmaku-move {
      from { transform: translateX(100%); }
      to { transform: translateX(-100%); }
    }
    Vue 脚本逻辑
    <script setup>
    import { ref, onMounted, onBeforeUnmount } from "vue";
    import axios from "axios";
    
    
    const videoSrc = "/videos/sample.mp4";
    const videoId = "123"; 
    const danmakus = ref([]);
    const inputMsg = ref("");
    let ws = null;
    
    
    function getRandomTop() {
      return Math.floor(Math.random() * 80);
    }
    
    
    function connectWebSocket() {
      ws = new WebSocket(`ws://localhost:8080/ws/video/${videoId}`);
      ws.onmessage = (event) => {
        const msg = JSON.parse(event.data);
        danmakus.value.push(msg.content);
        if (danmakus.value.length > 50) {
          danmakus.value.shift();
        }
      };
    }
    
    
    async function loadHistoryDanmakus() {
      const res = await axios.get(`/api/danmaku/latest`, {
        params: { videoId, limit: 20 }
      });
      danmakus.value.push(...res.data);
    }
    
    
    function sendDanmaku() {
      if (inputMsg.value.trim()) {
        ws.send(JSON.stringify({
          videoId,
          content: inputMsg.value
        }));
        inputMsg.value = "";
      }
    }
    
    
    onMounted(() => {
      loadHistoryDanmakus();
      connectWebSocket();
    });
    
    
    onBeforeUnmount(() => {
      if (ws) ws.close();
    });
    </script>

    性能优化建议

    1. Redis List 限制长度:防止列表无限增长
    2. 多节点部署 + Redis 集群:保证高可用
    3. AI 审核异步化:减少审核延迟对整体性能的影响
    4. 上下文缓存过期:防止队列内保留过多历史数据
    5. 热点视频提前预热缓存:提升进入直播间的速度

    结语

    这样,你的弹幕系统就能:

    • 毫秒级拦截违规弹幕(结合上下文判断)
    • 热点视频弹幕秒加载
    • 架构简单,无需分库分表
    • 前端体验流畅,进入视频就有历史弹幕

    AI大模型学习福利

    作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

    一、全套AGI大模型学习路线

    AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获取

    二、640套AI大模型报告合集

    这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    三、AI大模型经典PDF籍

    随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。


    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    四、AI大模型商业化落地方案

    因篇幅有限,仅展示部分资料,需要点击文章最下方名片即可前往获

    作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量

    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值