字体预加载
Home
avatar

翻过墙

翻过墙

dart_simple_live-直播工具

dart_simple_live 是一个基于Dart语言开发的开源直播工具,支持多种直播平台的视频流获取和播放。它提供了简洁的API接口,支持直播录制、弹幕获取、多平台聚合等功能,是直播开发者的理想选择。

主要特性

📺 多平台支持

  • 主流平台: 支持斗鱼、虎牙、B站、快手等主流直播平台
  • 统一接口: 提供统一的API接口,简化开发流程
  • 平台扩展: 支持自定义平台插件扩展
  • 实时更新: 及时适配平台接口变化

🎬 直播功能

  • 实时播放: 支持直播流的实时播放
  • 录制功能: 支持直播内容录制保存
  • 弹幕获取: 实时获取和显示弹幕信息
  • 画质选择: 支持多种画质选择

🔧 开发友好

  • 简洁API: 提供简洁易用的API接口
  • 异步支持: 基于Dart的异步编程模型
  • 错误处理: 完善的错误处理和重试机制
  • 文档完善: 提供详细的使用文档和示例

🌐 跨平台支持

  • 桌面端: Windows、macOS、Linux
  • 移动端: Android、iOS
  • Web端: 支持Web平台
  • 服务端: 支持服务端部署

项目地址

dart_simple_live - Github dart_simple_live - 文档

安装配置

1. Dart项目集成

# pubspec.yaml
dependencies:
  simple_live: ^1.0.0
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter

2. 基础使用

import 'package:simple_live/simple_live.dart';

void main() async {
  // 创建直播实例
  final live = SimpleLive();
  
  // 获取直播信息
  final roomInfo = await live.getRoomInfo('https://live.bilibili.com/123456');
  print('房间标题: ${roomInfo.title}');
  print('主播名称: ${roomInfo.hostName}');
  print('观看人数: ${roomInfo.viewerCount}');
  
  // 获取直播流地址
  final streamUrl = await live.getStreamUrl('https://live.bilibili.com/123456');
  print('直播流地址: $streamUrl');
}

3. Flutter集成

// Flutter应用示例
import 'package:flutter/material.dart';
import 'package:simple_live/simple_live.dart';

class LivePlayerPage extends StatefulWidget {
  @override
  _LivePlayerPageState createState() => _LivePlayerPageState();
}

class _LivePlayerPageState extends State<LivePlayerPage> {
  late SimpleLive _live;
  RoomInfo? _roomInfo;
  
  @override
  void initState() {
    super.initState();
    _live = SimpleLive();
    _loadRoomInfo();
  }
  
  Future<void> _loadRoomInfo() async {
    try {
      final roomInfo = await _live.getRoomInfo('https://live.bilibili.com/123456');
      setState(() {
        _roomInfo = roomInfo;
      });
    } catch (e) {
      print('加载房间信息失败: $e');
    }
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('直播播放器')),
      body: _roomInfo == null
          ? Center(child: CircularProgressIndicator())
          : Column(
              children: [
                Text('房间标题: ${_roomInfo!.title}'),
                Text('主播: ${_roomInfo!.hostName}'),
                // 播放器组件
                LivePlayerWidget(roomUrl: 'https://live.bilibili.com/123456'),
              ],
            ),
    );
  }
}

基础配置

1. 平台配置

// 平台配置示例
class LiveConfig {
  static const Map<String, String> platforms = {
    'bilibili': 'https://live.bilibili.com',
    'douyu': 'https://www.douyu.com',
    'huya': 'https://www.huya.com',
    'kuaishou': 'https://live.kuaishou.com',
  };
  
  static const Map<String, Map<String, String>> headers = {
    'bilibili': {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Referer': 'https://live.bilibili.com',
    },
    'douyu': {
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
      'Referer': 'https://www.douyu.com',
    },
  };
}

2. 直播流获取

// 获取直播流示例
class LiveStreamService {
  final SimpleLive _live = SimpleLive();
  
  Future<String?> getStreamUrl(String roomUrl) async {
    try {
      final streamUrl = await _live.getStreamUrl(roomUrl);
      return streamUrl;
    } catch (e) {
      print('获取直播流失败: $e');
      return null;
    }
  }
  
  Future<List<StreamQuality>> getStreamQualities(String roomUrl) async {
    try {
      final qualities = await _live.getStreamQualities(roomUrl);
      return qualities;
    } catch (e) {
      print('获取画质列表失败: $e');
      return [];
    }
  }
}

3. 弹幕处理

// 弹幕处理示例
class DanmakuService {
  final SimpleLive _live = SimpleLive();
  
  Stream<DanmakuMessage> getDanmakuStream(String roomUrl) {
    return _live.getDanmakuStream(roomUrl).map((event) {
      return DanmakuMessage(
        content: event.content,
        sender: event.sender,
        timestamp: event.timestamp,
        type: event.type,
      );
    });
  }
  
  void sendDanmaku(String roomUrl, String content) async {
    try {
      await _live.sendDanmaku(roomUrl, content);
    } catch (e) {
      print('发送弹幕失败: $e');
    }
  }
}

高级功能

1. 直播录制

// 直播录制示例
class LiveRecorder {
  final SimpleLive _live = SimpleLive();
  bool _isRecording = false;
  String? _outputPath;
  
  Future<void> startRecording(String roomUrl, String outputPath) async {
    if (_isRecording) return;
    
    try {
      await _live.startRecording(roomUrl, outputPath);
      _isRecording = true;
      _outputPath = outputPath;
      print('开始录制: $outputPath');
    } catch (e) {
      print('开始录制失败: $e');
    }
  }
  
  Future<void> stopRecording() async {
    if (!_isRecording) return;
    
    try {
      await _live.stopRecording();
      _isRecording = false;
      print('录制完成: $_outputPath');
    } catch (e) {
      print('停止录制失败: $e');
    }
  }
  
  bool get isRecording => _isRecording;
}

2. 多房间管理

// 多房间管理示例
class MultiRoomManager {
  final Map<String, SimpleLive> _rooms = {};
  final Map<String, StreamSubscription> _subscriptions = {};
  
  Future<void> addRoom(String roomId, String roomUrl) async {
    if (_rooms.containsKey(roomId)) return;
    
    final live = SimpleLive();
    _rooms[roomId] = live;
    
    // 监听房间状态
    final subscription = live.getRoomStatusStream(roomUrl).listen((status) {
      print('房间 $roomId 状态: $status');
    });
    
    _subscriptions[roomId] = subscription;
  }
  
  Future<void> removeRoom(String roomId) async {
    final subscription = _subscriptions[roomId];
    await subscription?.cancel();
    _subscriptions.remove(roomId);
    _rooms.remove(roomId);
  }
  
  Future<void> closeAll() async {
    for (final subscription in _subscriptions.values) {
      await subscription.cancel();
    }
    _subscriptions.clear();
    _rooms.clear();
  }
}

3. 自定义平台

// 自定义平台示例
class CustomPlatform extends LivePlatform {
  @override
  String get name => 'custom_platform';
  
  @override
  Future<RoomInfo> getRoomInfo(String roomUrl) async {
    // 实现获取房间信息的逻辑
    final response = await http.get(Uri.parse(roomUrl));
    final data = jsonDecode(response.body);
    
    return RoomInfo(
      title: data['title'],
      hostName: data['host_name'],
      viewerCount: data['viewer_count'],
      isLive: data['is_live'],
    );
  }
  
  @override
  Future<String> getStreamUrl(String roomUrl) async {
    // 实现获取直播流地址的逻辑
    final response = await http.get(Uri.parse('$roomUrl/stream'));
    final data = jsonDecode(response.body);
    
    return data['stream_url'];
  }
  
  @override
  Stream<DanmakuEvent> getDanmakuStream(String roomUrl) async* {
    // 实现弹幕流获取的逻辑
    final ws = WebSocket.connect('$roomUrl/danmaku');
    
    await for (final message in ws) {
      final data = jsonDecode(message);
      yield DanmakuEvent(
        content: data['content'],
        sender: data['sender'],
        timestamp: DateTime.now(),
        type: DanmakuType.normal,
      );
    }
  }
}

使用场景

1. 直播聚合应用

# 直播聚合应用
适用场景:
  - 多平台直播聚合
  - 直播推荐系统
  - 直播搜索功能
  - 个人直播收藏
功能:
  - 统一播放器
  - 跨平台搜索
  - 直播提醒
  - 观看历史

2. 直播数据分析

# 直播数据分析
适用场景:
  - 直播热度分析
  - 观众行为统计
  - 内容质量评估
  - 市场趋势分析
功能:
  - 数据采集
  - 实时统计
  - 报表生成
  - 趋势预测

3. 直播录制工具

# 直播录制工具
适用场景:
  - 直播内容保存
  - 精彩片段剪辑
  - 直播回放
  - 内容分发
功能:
  - 自动录制
  - 画质选择
  - 分段保存
  - 格式转换

性能优化

1. 连接池管理

// 连接池管理
class ConnectionPool {
  final Map<String, WebSocket> _connections = {};
  final int _maxConnections = 10;
  
  Future<WebSocket> getConnection(String url) async {
    if (_connections.containsKey(url)) {
      return _connections[url]!;
    }
    
    if (_connections.length >= _maxConnections) {
      // 关闭最旧的连接
      final oldestUrl = _connections.keys.first;
      await _connections[oldestUrl]!.close();
      _connections.remove(oldestUrl);
    }
    
    final ws = await WebSocket.connect(url);
    _connections[url] = ws;
    return ws;
  }
  
  Future<void> closeAll() async {
    for (final ws in _connections.values) {
      await ws.close();
    }
    _connections.clear();
  }
}

2. 缓存机制

// 缓存机制
class LiveCache {
  final Map<String, dynamic> _cache = {};
  final Duration _cacheExpiry = Duration(minutes: 5);
  
  T? get<T>(String key) {
    final item = _cache[key];
    if (item == null) return null;
    
    final timestamp = item['timestamp'] as DateTime;
    if (DateTime.now().difference(timestamp) > _cacheExpiry) {
      _cache.remove(key);
      return null;
    }
    
    return item['data'] as T;
  }
  
  void set<T>(String key, T data) {
    _cache[key] = {
      'data': data,
      'timestamp': DateTime.now(),
    };
  }
  
  void clear() {
    _cache.clear();
  }
}

3. 错误重试

// 错误重试机制
class RetryHelper {
  static Future<T> retry<T>(
    Future<T> Function() operation, {
    int maxRetries = 3,
    Duration delay = const Duration(seconds: 1),
  }) async {
    int attempts = 0;
    
    while (attempts < maxRetries) {
      try {
        return await operation();
      } catch (e) {
        attempts++;
        if (attempts >= maxRetries) {
          rethrow;
        }
        
        await Future.delayed(delay * attempts);
      }
    }
    
    throw Exception('重试次数已达上限');
  }
}

常见问题

Q: 如何获取直播间的真实观看人数?

A: 不同平台的观看人数统计方式不同,建议使用官方API或第三方数据服务。

Q: 如何处理直播流地址失效?

A: 实现自动重试机制,定期刷新流地址,处理各种异常情况。

Q: 如何优化弹幕显示性能?

A: 使用弹幕池管理、限制显示数量、优化渲染算法等方式提升性能。

Q: 如何支持新的直播平台?

A: 继承LivePlatform类,实现相应的接口方法,注册到平台管理器中。

总结

dart_simple_live 是一个优秀的直播工具库,具有以下优势:

  • 完全免费开源
  • 多平台支持
  • 易于集成
  • 功能完善
  • 性能优异
  • 扩展性强

dart_simple_live 特别适合需要开发直播相关应用的开发者。

使用dart_simple_live时请遵守各直播平台的使用条款,合理使用API接口。

dart_simple_live 直播 开源 流媒体 工具 免费