streamdeck_flutter 0.3.1
streamdeck_flutter: ^0.3.1 copied to clipboard
Build Elgato Stream Deck plugins with Flutter. Renders UI offscreen, slices frames into key-sized tiles, and pushes them via the Stream Deck WebSocket protocol.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:macos_window_utils/window_manipulator.dart';
import 'package:streamdeck_flutter/streamdeck_flutter.dart';
import 'package:streamdeck_flutter_example/logger.dart';
import 'package:streamdeck_flutter_example/widgets/animation_key.dart';
import 'package:streamdeck_flutter_example/widgets/dial_driven_animation.dart';
import 'package:streamdeck_flutter_example/widgets/hello_world.dart';
import 'package:streamdeck_flutter_example/widgets/tapper.dart';
const _binaryName = 'streamdeck_flutter_example';
const _uuid = 'com.example.flutter';
const _defaultColors = [
Color(0xFFE53935),
Color(0xFF8E24AA),
Color(0xFF1E88E5),
Color(0xFF43A047),
Color(0xFFFB8C00),
Color(0xFF00ACC1),
Color(0xFF7CB342),
Color(0xFFD81B60),
];
Future<void> main(List<String> args) async {
HeadlessBinding.ensureInitialized();
initLogging();
await WindowManipulator.initialize(enableWindowDelegate: true);
runApp(ExampleApp(connection: ConnectionInfo.fromArgs(args)));
}
class ExampleApp extends StatelessWidget {
const ExampleApp({super.key, required this.connection});
final ConnectionInfo connection;
static Color _colorFor(BuildContext context) {
final ac = StreamDeck.actionOf(context)!;
final hex = ac.payload.setting<String>('color');
if (hex != null && hex.length == 6) {
final value = int.tryParse(hex, radix: 16);
if (value != null) return Color(0x000000 | value);
}
return _defaultColors[ac.context.hashCode.abs() % _defaultColors.length];
}
@override
Widget build(BuildContext context) {
return StreamDeckPlugin(
connection: connection,
maxFps: 10,
actionBuilder: (context) {
final action = StreamDeck.actionOf(context)!;
return switch (action.action) {
'$_uuid.tapper' => TapperAction(),
'$_uuid.animation' => AnimationKey(defaultColor: _colorFor(context)),
'$_uuid.dial-driven' => DialDrivenAnimation(color: _colorFor(context)),
'$_uuid.hello-world' => HelloWorldAction(),
_ => const Placeholder(),
};
},
manifest: Manifest(
uuid: _uuid,
author: 'streamdesk',
name: 'streamdesk flutter',
description: 'Flutter-powered Stream Deck plugin with live keys and encoder dials',
category: 'streamdesk flutter',
categoryIcon: 'assets/imgs/plugin-icon',
icon: 'assets/imgs/marketplace',
version: '0.4.0.0',
codePath: '$_binaryName.app/Contents/MacOS/$_binaryName',
codePathMac: '$_binaryName.app/Contents/MacOS/$_binaryName',
actions: [
ManifestAction(
id: 'tapper',
name: 'Tapper',
tooltip: 'Tracks daily intake from a REST endpoint with remaining/used display and dose logging.',
icon: 'assets/imgs/tapper-image',
propertyInspectorPath: 'assets/ui/tapper.html',
encoder: const ManifestEncoder(
triggerDescription: ManifestTriggerDescription(
rotate: 'Adjust dose',
push: 'Log dose',
touch: 'Toggle display',
),
),
states: const [ManifestState(image: 'assets/imgs/tapper-image')],
),
ManifestAction(
id: 'animation',
name: 'Animation',
tooltip: 'Animated key/dial with 8 styles. Press or tap to cycle. Dial rotate adjusts speed.',
icon: 'assets/imgs/animation',
encoder: const ManifestEncoder(
triggerDescription: ManifestTriggerDescription(
rotate: 'Adjust speed',
push: 'Next animation',
touch: 'Next animation',
),
),
states: [ManifestState(image: 'assets/imgs/bounce', title: 'Bounce')],
),
ManifestAction(
id: 'dial-driven',
name: 'Dial Driven',
tooltip: 'Animation driven by dial rotation. Rotate to scrub, press to toggle auto-play.',
icon: 'assets/imgs/dial_rotate',
encoder: const ManifestEncoder(
triggerDescription: ManifestTriggerDescription(
rotate: 'Scrub animation',
push: 'Play / Pause',
touch: 'Play / Pause',
),
),
states: const [ManifestState(title: 'Dial', image: 'assets/imgs/dial_rotate')],
),
ManifestAction(
id: 'hello-world',
name: 'Hello World',
tooltip: 'A simple tap counter. Press key or rotate dial to count, press dial or touch to reset.',
icon: 'assets/imgs/hello_world',
states: const [ManifestState(image: 'assets/imgs/hello_world')],
),
],
os: const [ManifestOS(platform: 'mac', minimumVersion: '10.15')],
software: const ManifestSoftware(minimumVersion: '6.9'),
),
);
}
}