如何使用 just_audio - flutter 正确播放音频文件
How to properly play audio file using just_audio - flutter
我正在开发一个音乐应用程序,我想流式传输音频并播放我本地存储的文件。
正在使用 flutter,但并不擅长,实际上正在学习。
我想要的是在如何正确播放文件方面得到帮助,目的是播放提供给播放器路径的文件。下面是我的代码。
import 'package:myApp/shared/MusicProgressIndicator.dart';
import 'package:myApp/just_audio.dart';
import 'package:myApp/app.dart';
class SingleSongScreen extends StatefulWidget {
static const String id = "SingleSongScreen";
static var song = {};
SingleSongScreen({Key key}) : super(key: key);
@override
_SingleSongScreenState createState() => _SingleSongScreenState();
}
class _SingleSongScreenState extends State<SingleSongScreen> with TickerProviderStateMixin {
Duration currentDuration = Duration(milliseconds: 1000);
bool showRemaining = false;
AnimationController controller;
@override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final player = AudioPlayer();
var song = SingleSongScreen.song;
var songPath = app.base+"play.php?file="+song['song'];
print(song);
print(songPath);
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
return Window(
backgroundColor: backgroundColor,
header: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: backIcon,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 40,
onClicked: () {
goBack(context);
},
),
Favicon(onClicked: () {
goto(page: MainScreen.id, context: context);
}),
],
),
),
body: [
VerticalSpacer(
h: 20,
),
Container(
height: 250,
child: Carousel(
boxFit: BoxFit.contain,
autoplay: carouselAutoPlay,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 1000),
dotSize: 6.0,
dotIncreasedColor: Color(0xFF33A3FF),
dotBgColor: Colors.transparent,
dotPosition: DotPosition.bottomCenter,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: images(),
),
)
],
footer: Container(
child: Column(
children: [
Container(
child: Marquee(
child: Label(
song['title'],
bold: true,
),
),
),
Container(
child: Marquee(
child: Label(
song['artist'],
bold: true,
color: Colors.grey,
),
),
),
// ACTION ICONS SECTION
VerticalSpacer(
h: 25,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
VerticalIconicButton(
icon: FontAwesomeIcons.fileDownload,
label: "Download",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: (){
var downloadURL = songPath.replaceAll("play.php", "download.php");
app app2 = new app();
toast("Downloading a file "+song['song']);
app2.fetchServer({'method':'download','file':song['song']}).then((fileInfo){
if(fileInfo['status']=="success"){
toast("Download complete "+song['song']);
app2.saveDownload(song['song'],song['artist'],fileInfo['file']);
}else{
toast("There was an error while downloading a file");
}
print("downloaded file is");
print(fileInfo);
});
},
),
VerticalIconicButton(
icon: Icons.favorite_border_outlined,
label: "Favourite",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
),
VerticalIconicButton(
icon: FontAwesomeIcons.readme,
label: "Lyrics",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: () {
goto(page: LyricsScreen.id, context: context, args: lyric);
},
),
],
),
),
// SONG PLAY PROGRESS INDICATOR
VerticalSpacer(),
MusicProgressIndicator(
progress: currentDuration,
buffered: Duration(milliseconds: 2000),
total: Duration(milliseconds: 5000),
showTotalRemainingTime: showRemaining,
onSeek: (duration) {
setState(() {
currentDuration = duration;
showRemaining = !showRemaining;
});
// _player.seek(duration);
},
),
// MUSIC PLAY CONTROLLER ACTION BUTTON
VerticalSpacer(
h: 20,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: Icons.repeat_one,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
),
Container(
child: Row(
children: [
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_previous_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
SizedBox(width: 15),
IconicButton(
icon: Icons.pause,
iconColor: Colors.grey,
iconCircleColor: Colors.blue,
size: 50,
onClicked: (){
toast("Playing file");
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
},
),
SizedBox(
width: 15,
),
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_next_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
],
),
),
IconicButton(
icon: Icons.queue_music_outlined,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
onClicked: () {
goto(page: AllSongsScreen.id, context: context);
},
),
],
),
),
// BOTTTOM SPACE
VerticalSpacer(
h: 30,
),
],
),
),
);
}
void toast(String message){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message.toString()),
duration: const Duration(seconds: 1),
action: SnackBarAction(
label: 'OK',
onPressed: () { },
),
)
);
}
}
我用来播放声音的代码正在生成
- 烦人的声音,双重声音或波浪交叉
- 允许播放多种声音。
注意:我购买了模板。
谢谢,请帮忙。
您在控制器的addListener 中调用了setState() 方法,并在widget 构建中直接调用了player.stop() 和play()。
在停止或播放方法之前检查播放器是否不为空且 isPlaying = false。
而且你不应该在小部件构建中初始化你的播放器。不可取。
为了避免同时播放多个音频,也许您需要考虑将 AudioPlayer 设为 SINGLETON。上面的代码告诉我,每次你进入那个页面,都会有一个新的 AudioPlayer 创建关联,你没有在 dispose() 上处理它。这是我为我的 flutter 播客开源项目编写的一些代码。
a podcast case using just audio package
我正在开发一个音乐应用程序,我想流式传输音频并播放我本地存储的文件。
正在使用 flutter,但并不擅长,实际上正在学习。
我想要的是在如何正确播放文件方面得到帮助,目的是播放提供给播放器路径的文件。下面是我的代码。
import 'package:myApp/shared/MusicProgressIndicator.dart';
import 'package:myApp/just_audio.dart';
import 'package:myApp/app.dart';
class SingleSongScreen extends StatefulWidget {
static const String id = "SingleSongScreen";
static var song = {};
SingleSongScreen({Key key}) : super(key: key);
@override
_SingleSongScreenState createState() => _SingleSongScreenState();
}
class _SingleSongScreenState extends State<SingleSongScreen> with TickerProviderStateMixin {
Duration currentDuration = Duration(milliseconds: 1000);
bool showRemaining = false;
AnimationController controller;
@override
void initState() {
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final player = AudioPlayer();
var song = SingleSongScreen.song;
var songPath = app.base+"play.php?file="+song['song'];
print(song);
print(songPath);
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
return Window(
backgroundColor: backgroundColor,
header: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: backIcon,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 40,
onClicked: () {
goBack(context);
},
),
Favicon(onClicked: () {
goto(page: MainScreen.id, context: context);
}),
],
),
),
body: [
VerticalSpacer(
h: 20,
),
Container(
height: 250,
child: Carousel(
boxFit: BoxFit.contain,
autoplay: carouselAutoPlay,
animationCurve: Curves.fastOutSlowIn,
animationDuration: Duration(milliseconds: 1000),
dotSize: 6.0,
dotIncreasedColor: Color(0xFF33A3FF),
dotBgColor: Colors.transparent,
dotPosition: DotPosition.bottomCenter,
dotVerticalPadding: 10.0,
showIndicator: true,
indicatorBgPadding: 7.0,
images: images(),
),
)
],
footer: Container(
child: Column(
children: [
Container(
child: Marquee(
child: Label(
song['title'],
bold: true,
),
),
),
Container(
child: Marquee(
child: Label(
song['artist'],
bold: true,
color: Colors.grey,
),
),
),
// ACTION ICONS SECTION
VerticalSpacer(
h: 25,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
VerticalIconicButton(
icon: FontAwesomeIcons.fileDownload,
label: "Download",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: (){
var downloadURL = songPath.replaceAll("play.php", "download.php");
app app2 = new app();
toast("Downloading a file "+song['song']);
app2.fetchServer({'method':'download','file':song['song']}).then((fileInfo){
if(fileInfo['status']=="success"){
toast("Download complete "+song['song']);
app2.saveDownload(song['song'],song['artist'],fileInfo['file']);
}else{
toast("There was an error while downloading a file");
}
print("downloaded file is");
print(fileInfo);
});
},
),
VerticalIconicButton(
icon: Icons.favorite_border_outlined,
label: "Favourite",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
),
VerticalIconicButton(
icon: FontAwesomeIcons.readme,
label: "Lyrics",
iconColor: Colors.grey,
textColor: Colors.grey,
scale: 1.2,
onClicked: () {
goto(page: LyricsScreen.id, context: context, args: lyric);
},
),
],
),
),
// SONG PLAY PROGRESS INDICATOR
VerticalSpacer(),
MusicProgressIndicator(
progress: currentDuration,
buffered: Duration(milliseconds: 2000),
total: Duration(milliseconds: 5000),
showTotalRemainingTime: showRemaining,
onSeek: (duration) {
setState(() {
currentDuration = duration;
showRemaining = !showRemaining;
});
// _player.seek(duration);
},
),
// MUSIC PLAY CONTROLLER ACTION BUTTON
VerticalSpacer(
h: 20,
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconicButton(
icon: Icons.repeat_one,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
),
Container(
child: Row(
children: [
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_previous_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
SizedBox(width: 15),
IconicButton(
icon: Icons.pause,
iconColor: Colors.grey,
iconCircleColor: Colors.blue,
size: 50,
onClicked: (){
toast("Playing file");
player.stop();
player.setUrl(songPath).then((play){
player.play();
print("Playing now");
});
},
),
SizedBox(
width: 15,
),
Container(
child: Center(
child: IconicButton(
icon: Icons.skip_next_rounded,
iconColor: Colors.white,
transparent: true,
circledIcon: false,
size: 50,
),
),
),
],
),
),
IconicButton(
icon: Icons.queue_music_outlined,
iconColor: Colors.grey,
transparent: true,
circledIcon: false,
size: 50,
onClicked: () {
goto(page: AllSongsScreen.id, context: context);
},
),
],
),
),
// BOTTTOM SPACE
VerticalSpacer(
h: 30,
),
],
),
),
);
}
void toast(String message){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message.toString()),
duration: const Duration(seconds: 1),
action: SnackBarAction(
label: 'OK',
onPressed: () { },
),
)
);
}
}
我用来播放声音的代码正在生成
- 烦人的声音,双重声音或波浪交叉
- 允许播放多种声音。
注意:我购买了模板。
谢谢,请帮忙。
您在控制器的addListener 中调用了setState() 方法,并在widget 构建中直接调用了player.stop() 和play()。 在停止或播放方法之前检查播放器是否不为空且 isPlaying = false。 而且你不应该在小部件构建中初始化你的播放器。不可取。
为了避免同时播放多个音频,也许您需要考虑将 AudioPlayer 设为 SINGLETON。上面的代码告诉我,每次你进入那个页面,都会有一个新的 AudioPlayer 创建关联,你没有在 dispose() 上处理它。这是我为我的 flutter 播客开源项目编写的一些代码。 a podcast case using just audio package