简体   繁体   English

Flutter的一系列音频文件中如何一次播放一个音频文件?

[英]How to play one audio file at a time in a series of audio files in Flutter?

I have several audio files to be played, so I used ListView to represent every audio file as an item of ListView , each one with its own controllers (play/pause button and duration slider).我有几个要播放的音频文件,所以我使用ListView将每个音频文件表示为ListView的一个项目,每个都有自己的控制器(播放/暂停按钮和持续时间滑块)。 The code is as follows (I have used one audio file for all of the items for simplicity sake):代码如下(为简单起见,我对所有项目都使用了一个音频文件):

import 'package:audioplayers/audioplayers.dart';

class AudioTestScreen extends StatelessWidget {
  const AudioTestScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Songs")),
      body: ListView.builder(
        itemCount: 10,
        itemBuilder: (ctx, index) => const AudioItem(),
      ),
    );
  }
}

class AudioItem extends StatefulWidget {
  const AudioItem({Key? key}) : super(key: key);

  @override
  State<AudioItem> createState() => _AudioItemState();
}

class _AudioItemState extends State<AudioItem> {
  final audioPlayer = AudioPlayer();
  bool isPlaying = false;

  Duration duration = Duration.zero;  // For total duration
  Duration position = Duration.zero;  // For the current position

  @override
  void initState() {
    super.initState();

    setAudioPlayer();

    audioPlayer.onDurationChanged.listen((newDuration) {
      setState(() {
        duration = newDuration;
      });
    });

    audioPlayer.onPositionChanged.listen((newPosition) {
      if (mounted) {
        setState(() {
          position = newPosition;
        });
      }
    });

    audioPlayer.onPlayerStateChanged.listen((state) {
      if (mounted) {
        setState(() {
          isPlaying = state == PlayerState.playing;
        });
      }
    });
  }

  Future<void> setAudioPlayer() async {
    final player = AudioCache(prefix: "assets/audios/");
    final url = await player.load("song.mp3");
    audioPlayer.setSourceUrl(url.path);
    audioPlayer.setReleaseMode(ReleaseMode.stop);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
      decoration: BoxDecoration(
        color: const Color(0xFFF4F2FF),
        borderRadius: BorderRadius.circular(12),
        border: Border.all(width: 1, color: Colors.grey)
      ),
      child: Column(
        children: [
          Slider(
            value: position.inMilliseconds.toDouble(),
            max: duration.inMilliseconds.toDouble(),
            onChanged: (value) {
              setState(() {
                position = Duration(milliseconds: value.toInt());
              });
              audioPlayer.seek(position);
            },
          ),
          GestureDetector(
            onTap: () async {
              isPlaying
                  ? await audioPlayer.pause()
                  : await audioPlayer.resume();
            },
            child: CircleAvatar(
              child: Icon(isPlaying ? Icons.pause : Icons.play_arrow),
            ),
          )
        ],
      ),
    );
  }
}

And here is how it looks like:这是它的样子:

在此处输入图像描述

Now when I play a music file, and later tap on another item to play it, both of them plays at the same time, but I want the previous one to pause and only the current one to play.现在,当我播放一个音乐文件,然后点击另一个项目来播放它时,它们会同时播放,但我希望前一个暂停,只播放当前一个。 How can I achieve this behavior?我怎样才能实现这种行为? Thanks in advance.提前致谢。

create the audio player in the parent class and pass it to the children.在父级 class 中创建音频播放器并将其传递给子级。 Then before you play stop the player and then play it with new url然后在播放之前停止播放器,然后使用新的 url 播放

widget.player.stop()

Use this to stop the player使用它来停止播放器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM