fish 5 months ago
parent
commit
e6feab9afa
4 changed files with 395 additions and 10 deletions
  1. 2 5
      lib/main.dart
  2. 170 5
      lib/pages/home_page.dart
  3. 222 0
      pubspec.lock
  4. 1 0
      pubspec.yaml

+ 2 - 5
lib/main.dart

@@ -9,11 +9,8 @@ import 'package:flutter_netease_music/routes.dart';
 /// Author     : liuyuqi.gov@msn.cn
 void main() {
   WidgetsFlutterBinding.ensureInitialized();
-  runApp(MutiPrivater(child: const MyApp()));
-
-  if(Platform.isAndroid){
-
-  }
+  runApp(const MyApp());
+  if (Platform.isAndroid) {}
 }
 
 class MyApp extends StatelessWidget {

+ 170 - 5
lib/pages/home_page.dart

@@ -1,25 +1,190 @@
+// ignore_for_file: unnecessary_null_comparison
+
+import 'dart:async';
+
 import 'package:flutter/material.dart';
+import 'package:audioplayers/audioplayers.dart';
 
 /// Description: home page
 /// Time       : 11/06/2023 Monday
 /// Author     : liuyuqi.gov@msn.cn
 class HomePage extends StatefulWidget {
-  const HomePage({super.key});
+  HomePage({super.key});
 
   @override
   State<HomePage> createState() => _HomePageState();
 }
 
 class _HomePageState extends State<HomePage> {
+  String url = "";
+  late PlayerMode mode;
+
+  late AudioPlayer _audioPlayer;
+
+  late Duration _duration;
+  late Duration _position;
+  late StreamSubscription _durationSubscription;
+  late StreamSubscription _positionSubscription;
+  late StreamSubscription _playerCompleteSubscription;
+  late StreamSubscription _playerErrorSubscription;
+  late StreamSubscription _playerStateSubscription;
+
+  get _durationText => _duration.toString().split('.').first;
+  get _positionText => _position.toString().split('.').first;
+
   @override
   Widget build(BuildContext context) {
-    return  Scaffold(
+    return Scaffold(
       appBar: AppBar(
         title: const Text('Netease Music'),
       ),
-      body: const Center(
-        child: Text('Hello World'),
+      body: Column(
+        children: [
+          Text(
+            _position != null
+                ? '${_positionText ?? ''} / ${_durationText ?? ''}'
+                : _duration != null
+                    ? _durationText
+                    : '',
+          ),
+          Padding(
+            padding: const EdgeInsets.all(12.0),
+            child: Stack(
+              children: [
+                Slider(
+                  onChanged: (v) {
+                    final Position = v * _duration.inMilliseconds;
+                    _audioPlayer.seek(Duration(milliseconds: Position.round()));
+                  },
+                  value: (_position.inMilliseconds > 0 &&
+                          _position.inMilliseconds < _duration.inMilliseconds)
+                      ? _position.inMilliseconds / _duration.inMilliseconds
+                      : 0.0,
+                ),
+              ],
+            ),
+          ),
+          Row(
+            children: [
+              IconButton(
+                  icon: const Icon(Icons.play_arrow),
+                  onPressed: () {
+                    _play();
+                  }),
+              IconButton(
+                  icon: const Icon(Icons.pause),
+                  onPressed: () {
+                    _pause();
+                  }),
+              IconButton(
+                  icon: const Icon(Icons.stop),
+                  onPressed: () {
+                    _stop();
+                  }),
+            ],
+          )
+        ],
       ),
     );
   }
-}
+
+  @override
+  void initState() {
+    super.initState();
+    url = 'http://music.163.com/song/media/outer/url?id=476592630.mp3';
+    _initAudioPlayer();
+  }
+
+  @override
+  void dispose() {
+    super.dispose();
+    _audioPlayer.dispose();
+    _durationSubscription.cancel();
+    _positionSubscription.cancel();
+    _playerCompleteSubscription.cancel();
+    _playerErrorSubscription.cancel();
+    _playerStateSubscription.cancel();
+  }
+
+  _initAudioPlayer() {
+    mode = PlayerMode.mediaPlayer;
+    //初始化
+    _audioPlayer = AudioPlayer(mode: mode);
+
+    _durationSubscription = _audioPlayer.onDurationChanged.listen((duration) {
+      setState(() => _duration = duration);
+
+      if (Theme.of(context).platform == TargetPlatform.iOS) {
+        _audioPlayer.startHeadlessService();
+
+        _audioPlayer.setNotification(
+            title: 'App Name',
+            artist: 'Artist or blank',
+            albumTitle: 'Name or blank',
+            imageUrl: 'url or blank',
+            forwardSkipInterval: const Duration(seconds: 30), // default is 30s
+            backwardSkipInterval: const Duration(seconds: 30), // default is 30s
+            duration: duration,
+            elapsedTime: const Duration(seconds: 0));
+      }
+    });
+
+    //监听进度
+    _positionSubscription =
+        _audioPlayer.onAudioPositionChanged.listen((p) => setState(() {
+              _position = p;
+            }));
+
+    //播放完成
+    _playerCompleteSubscription =
+        _audioPlayer.onPlayerCompletion.listen((event) {
+//          _onComplete();
+      setState(() {
+        _position = const Duration();
+      });
+    });
+
+    //监听报错
+    _playerErrorSubscription = _audioPlayer.onPlayerError.listen((msg) {
+      print('audioPlayer error : $msg');
+      setState(() {
+//        _playerState = PlayerState.stopped;
+        _duration = const Duration(seconds: 0);
+        _position = const Duration(seconds: 0);
+      });
+    });
+
+    //播放状态改变
+    _audioPlayer.onPlayerStateChanged.listen((state) {
+      if (!mounted) return;
+      setState(() {});
+    });
+
+    ///// iOS中来自通知区域的玩家状态变化流。
+    _audioPlayer.onDurationChanged.listen((state) {
+      if (!mounted) return;
+    });
+
+//    _playingRouteState = PlayingRouteState.speakers;
+  }
+
+  //开始播放
+  void _play() async {
+    final playPosition = (_position.inMilliseconds > 0 &&
+            _position.inMilliseconds < _duration.inMilliseconds)
+        ? _position
+        : null;
+    await _audioPlayer.play(UrlSource(url), position: playPosition);
+    _audioPlayer.setPlaybackRate(1.0);
+  }
+
+  //暂停
+  void _pause() async {
+    await _audioPlayer.pause();
+  }
+
+  //停止播放
+  _stop() async {
+    await _audioPlayer.stop();
+  }
+}

+ 222 - 0
pubspec.lock

@@ -9,6 +9,62 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "2.11.0"
+  audioplayers:
+    dependency: "direct main"
+    description:
+      name: audioplayers
+      sha256: c05c6147124cd63e725e861335a8b4d57300b80e6e92cea7c145c739223bbaef
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "5.2.1"
+  audioplayers_android:
+    dependency: transitive
+    description:
+      name: audioplayers_android
+      sha256: b00e1a0e11365d88576320ec2d8c192bc21f1afb6c0e5995d1c57ae63156acb5
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.0.3"
+  audioplayers_darwin:
+    dependency: transitive
+    description:
+      name: audioplayers_darwin
+      sha256: "3034e99a6df8d101da0f5082dcca0a2a99db62ab1d4ddb3277bed3f6f81afe08"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "5.0.2"
+  audioplayers_linux:
+    dependency: transitive
+    description:
+      name: audioplayers_linux
+      sha256: "60787e73fefc4d2e0b9c02c69885402177e818e4e27ef087074cf27c02246c9e"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.0"
+  audioplayers_platform_interface:
+    dependency: transitive
+    description:
+      name: audioplayers_platform_interface
+      sha256: "365c547f1bb9e77d94dd1687903a668d8f7ac3409e48e6e6a3668a1ac2982adb"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "6.1.0"
+  audioplayers_web:
+    dependency: transitive
+    description:
+      name: audioplayers_web
+      sha256: "22cd0173e54d92bd9b2c80b1204eb1eb159ece87475ab58c9788a70ec43c2a62"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.1.0"
+  audioplayers_windows:
+    dependency: transitive
+    description:
+      name: audioplayers_windows
+      sha256: "9536812c9103563644ada2ef45ae523806b0745f7a78e89d1b5fb1951de90e1a"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.0"
   boolean_selector:
     dependency: transitive
     description:
@@ -41,6 +97,14 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.17.2"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.0.3"
   cupertino_icons:
     dependency: "direct main"
     description:
@@ -57,6 +121,22 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.3.1"
+  ffi:
+    dependency: transitive
+    description:
+      name: ffi
+      sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.0"
+  file:
+    dependency: transitive
+    description:
+      name: file
+      sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "7.0.0"
   flutter:
     dependency: "direct main"
     description: flutter
@@ -75,6 +155,35 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_web_plugins:
+    dependency: transitive
+    description: flutter
+    source: sdk
+    version: "0.0.0"
+  http:
+    dependency: transitive
+    description:
+      name: http
+      sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.1.0"
+  http_parser:
+    dependency: transitive
+    description:
+      name: http_parser
+      sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.0.2"
+  js:
+    dependency: transitive
+    description:
+      name: js
+      sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.6.7"
   lints:
     dependency: transitive
     description:
@@ -115,6 +224,70 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.8.3"
+  path_provider:
+    dependency: transitive
+    description:
+      name: path_provider
+      sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  path_provider_android:
+    dependency: transitive
+    description:
+      name: path_provider_android
+      sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.2.1"
+  path_provider_foundation:
+    dependency: transitive
+    description:
+      name: path_provider_foundation
+      sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.3.1"
+  path_provider_linux:
+    dependency: transitive
+    description:
+      name: path_provider_linux
+      sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.2.1"
+  path_provider_platform_interface:
+    dependency: transitive
+    description:
+      name: path_provider_platform_interface
+      sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.1"
+  path_provider_windows:
+    dependency: transitive
+    description:
+      name: path_provider_windows
+      sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.2.1"
+  platform:
+    dependency: transitive
+    description:
+      name: platform
+      sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.3"
+  plugin_platform_interface:
+    dependency: transitive
+    description:
+      name: plugin_platform_interface
+      sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.7"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -128,6 +301,14 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.10.0"
+  sprintf:
+    dependency: transitive
+    description:
+      name: sprintf
+      sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "7.0.0"
   stack_trace:
     dependency: transitive
     description:
@@ -152,6 +333,14 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.2.0"
+  synchronized:
+    dependency: transitive
+    description:
+      name: synchronized
+      sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.1.0+1"
   term_glyph:
     dependency: transitive
     description:
@@ -168,6 +357,22 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "0.6.0"
+  typed_data:
+    dependency: transitive
+    description:
+      name: typed_data
+      sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.3.2"
+  uuid:
+    dependency: transitive
+    description:
+      name: uuid
+      sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "4.2.2"
   vector_math:
     dependency: transitive
     description:
@@ -184,5 +389,22 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "0.1.4-beta"
+  win32:
+    dependency: transitive
+    description:
+      name: win32
+      sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "5.1.1"
+  xdg_directories:
+    dependency: transitive
+    description:
+      name: xdg_directories
+      sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "1.0.3"
 sdks:
   dart: ">=3.1.4 <4.0.0"
+  flutter: ">=3.10.0"

+ 1 - 0
pubspec.yaml

@@ -19,6 +19,7 @@ dependencies:
   # path_privoder:
   # get:
   # audioplayers:
+  audioplayers: ^5.2.1
   # flutter_easyrefresh:
 
 dev_dependencies: