Flutter音视频流处理插件flutter_streamer的使用
Flutter音视频流处理插件flutter_streamer的使用
flutter_streamer
是一个基于标准 Dart Stream 的纯 Dart 状态管理类。它可以帮助你轻松地管理和处理应用中的状态变化。
保持简单
实现自己的模式:
class CounterController extends Streamer<int> {
CounterController(super.initialValue);
void increment(Increment event) => emit(++last);
}
一个简单的逻辑类扩展自Streamer
class CounterLogic extends Streamer<CounterState> {
int _value;
CounterLogic(this._value) : super(CounterState(_value)) {
on<Increment>(onIncrement);
}
set value(int newValue) {
if (newValue >= 10) {
emit(MaxReached());
} else {
_value = newValue;
}
}
int get value => _value;
void onIncrement(Increment event) => emit(CounterState(++value));
}
检查示例部分以了解EASE模式的简单实现
EASE模式灵感来源于BloC模式:
- 在BloC模式中,UI发出事件,而Cubit/Bloc类响应状态。
- 这可能会导致处理视图逻辑(如导航、显示对话框)变得复杂。
EASE模式定义了事件、动作、状态和错误类:
- 它们用于通过流在我们的逻辑类和视图之间进行通信。
- 因为一个简单的视图应该只依赖于事件/状态/错误的流,并且发出用户动作。
- 一个简单的逻辑应该只依赖于用户的动作流,并发出事件/状态/错误。
这种方式使得视图触发导航或对话框变得非常容易。 你的视图甚至不需要知道逻辑实现。 你的逻辑甚至不需要知道视图实现。
示例代码
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_inject/flutter_inject.dart';
import 'package:stream_listener_widget/stream_listener_widget.dart';
import 'package:streamer/streamer.dart';
void main() => runApp(
const MaterialApp(
home: CounterView(initialValue: 5),
),
);
class CounterLogic extends StateStreamer<CounterState, CounterIO> {
CounterLogic(int value) : super(CounterState(value)) {
on<Increment>(onIncrement);
on<Decrement>(onDecrement);
}
[@override](/user/override)
CounterIO? mapState(CounterState newState) {
if (newState.value > 10) {
return MaxReached();
} else if (newState.value < 0) {
return UnauthorizedValue('A counter under zero is not allowed');
}
return newState;
}
void onIncrement(Increment event) => state = CounterState(state.value + 1);
void onDecrement(Decrement event) => state = CounterState(state.value - 1);
}
class CounterView extends StatelessWidget {
final int initialValue;
const CounterView({super.key, required this.initialValue});
void _showDialog(BuildContext context, String message) => showDialog(
context: context,
barrierDismissible: true,
builder: (context) {
return Dialog(
child: Padding(
padding: const EdgeInsets.all(20),
child: Text(message),
),
);
},
);
void _onMaxReached(BuildContext context) => _showDialog(context, 'Your counter has reached max value');
void _onError(BuildContext context, CounterError event) => _showDialog(context, event.message);
[@override](/user/override)
Widget build(BuildContext context) {
return Inject<Streamer<CounterIO>>(
factory: (context) => CounterLogic(initialValue),
builder: (context) {
final streamer = Dependency.get<Streamer<CounterIO>>(context);
return StreamListener(
listeners: [
(context) => streamer.on<MaxReached>((e) => _onMaxReached(context)),
(context) => streamer.on<CounterError>((e) => _onError(context, e)),
],
child: Scaffold(
appBar: AppBar(title: const Text('Counter demo')),
body: Center(
child: StreamBuilder<CounterState>(
stream: streamer.select<CounterState>(),
builder: (context, snapshot) {
if (snapshot.hasError) return Text(snapshot.error.toString());
if (!snapshot.hasData) return const CircularProgressIndicator();
final state = snapshot.data!;
return Text('Counter: ${state.value}');
},
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: () => streamer.emit(Increment()),
child: const Icon(Icons.add),
),
FloatingActionButton(
onPressed: () => streamer.emit(Decrement()),
child: const Icon(Icons.remove),
),
],
),
),
);
});
}
}
/// 这里是一个简单的EASE模式实现的例子
/// 事件
sealed class CounterEvent extends CounterIO {}
class MaxReached extends CounterEvent {}
/// 动作
sealed class CounterAction extends CounterIO {}
class Increment extends CounterAction {}
class Decrement extends CounterAction {}
/// 状态
class CounterState extends CounterIO {
final int value;
CounterState(this.value);
}
class Loading extends CounterState {
Loading(super.value);
}
/// 错误
sealed class CounterError extends CounterIO {
final String message;
CounterError(this.message);
}
class UnauthorizedValue extends CounterError {
UnauthorizedValue(super.message);
}
class UnknownError extends CounterError {
UnknownError(super.message);
}
更多关于Flutter音视频流处理插件flutter_streamer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音视频流处理插件flutter_streamer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中进行音视频流处理时,flutter_streamer
是一个强大的插件,它允许开发者在Flutter应用中集成音视频流的播放和处理功能。以下是一个使用 flutter_streamer
的代码案例,展示了如何进行基本的音视频流播放。
首先,确保你已经在 pubspec.yaml
文件中添加了 flutter_streamer
依赖:
dependencies:
flutter:
sdk: flutter
flutter_streamer: ^0.x.x # 请替换为最新版本号
然后,运行 flutter pub get
来获取依赖。
接下来,是一个完整的 Flutter 应用示例,展示如何使用 flutter_streamer
播放一个网络上的视频流:
import 'package:flutter/material.dart';
import 'package:flutter_streamer/flutter_streamer.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Streamer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: StreamerDemo(),
);
}
}
class StreamerDemo extends StatefulWidget {
@override
_StreamerDemoState createState() => _StreamerDemoState();
}
class _StreamerDemoState extends State<StreamerDemo> {
FlutterStreamer? _streamer;
@override
void initState() {
super.initState();
// 初始化 FlutterStreamer 实例
_streamer = FlutterStreamer(
url: 'http://your-video-stream-url-here', // 替换为你的视频流URL
isLive: true, // 如果是直播流,设置为 true
autoPlay: true, // 是否自动播放
controls: true, // 是否显示控制按钮
);
// 监听播放状态变化
_streamer!.playerStatusStream!.listen((status) {
print('Player Status: $status');
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Streamer Demo'),
),
body: Center(
child: _streamer!.videoPlayerController!.value.isInitialized
? AspectRatio(
aspectRatio: _streamer!.videoPlayerController!.value.aspectRatio,
child: _streamer!.videoPlayer!,
)
: CircularProgressIndicator(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (_streamer!.videoPlayerController!.value.isPlaying) {
_streamer!.pause();
} else {
_streamer!.play();
}
},
tooltip: 'Play/Pause',
child: Icon(
_streamer!.videoPlayerController!.value.isPlaying
? Icons.pause
: Icons.play_arrow,
),
),
);
}
@override
void dispose() {
_streamer!.dispose();
super.dispose();
}
}
在这个示例中,我们做了以下几件事情:
- 初始化 FlutterStreamer 实例:在
initState
方法中,我们创建了一个FlutterStreamer
实例,并设置了视频流的 URL、是否是直播流、是否自动播放以及是否显示控制按钮。 - 监听播放状态:通过
_streamer!.playerStatusStream!.listen
方法,我们可以监听播放状态的变化,并在控制台中打印状态信息。 - 构建 UI:在
build
方法中,我们使用AspectRatio
来确保视频播放器能够保持正确的宽高比。如果视频播放器已经初始化,则显示视频播放器;否则,显示一个加载指示器。 - 播放/暂停控制:我们添加了一个浮动操作按钮(FAB),用于控制视频的播放和暂停。
- 释放资源:在
dispose
方法中,我们调用_streamer!.dispose()
来释放资源。
请确保将 'http://your-video-stream-url-here'
替换为你实际的视频流 URL。此外,根据你的需求,你可以进一步自定义和扩展这个示例。