import 'package:flutter/material.dart'; import 'package:just_audio_background/just_audio_background.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'streaming_audio_business_object.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await JustAudioBackground.init( androidNotificationChannelId: 'com.kryzgoflutter.audio.channel', androidNotificationChannelName: 'KRYZ Audio Playback', androidNotificationOngoing: true, ); runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State createState() => _MyAppState(); } class _MyAppState extends State { final StreamingAudioBusinessObject _audio = StreamingAudioBusinessObject(); @override void dispose() { _audio.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Split Screen Player', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.blueGrey), ), home: MainPage(audio: _audio), debugShowCheckedModeBanner: false, ); } } class MainPage extends StatefulWidget { const MainPage({super.key, required this.audio}); final StreamingAudioBusinessObject audio; @override State createState() => _MainPageState(); } class _MainPageState extends State { StreamingAudioBusinessObject get _audio => widget.audio; late final WebViewController _webViewController; @override void initState() { super.initState(); _webViewController = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..loadRequest(Uri.parse('https://kryzradio.org')); _audio.addListener(_handleAudioStateChanged); } void _handleAudioStateChanged() { if (!mounted) { return; } setState(() { // Rebuild when playback state changes from the player. }); } Future _play() async { await _audio.play(); } Future _stop() async { await _audio.stop(); } @override void dispose() { _audio.removeListener(_handleAudioStateChanged); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( children: [ Expanded( flex: 9, child: Padding( padding: const EdgeInsets.all(12), child: Container( width: double.infinity, decoration: BoxDecoration( border: Border.all(color: Colors.black26, width: 2), borderRadius: BorderRadius.circular(8), color: Colors.white, ), child: ClipRRect( borderRadius: BorderRadius.circular(6), child: WebViewWidget(controller: _webViewController), ), ), ), ), Expanded( flex: 1, child: Padding( padding: const EdgeInsets.fromLTRB(12, 0, 12, 12), child: Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.lightBlue.shade50, Colors.lightBlue.shade100, ], ), boxShadow: const [ BoxShadow( color: Color(0x22000000), blurRadius: 14, offset: Offset(0, 6), ), ], ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _audio.isPlaying ? null : _play, child: const Text('▶️'), ), const SizedBox(width: 12), ElevatedButton( onPressed: _audio.isPlaying ? _stop : null, child: const Text('⏹️'), ), const SizedBox(width: 16), Text( _audio.isPlaying ? 'Playing' : 'Stopped', style: const TextStyle(color: Colors.black87), ), ], ), ), ), ), ], ), ), ); } }