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接口。