Flutter (Android / iOS / Web / MacOS)에서 직접 자산 파일에 저장된 음악 / 오디오를 재생합니다.
URL, 라디오/라이브 스트림 및 로컬 파일을 사용하여 네트워크 에서 오디오 파일을 사용할 수도 있습니다.
안드로이드 및 iOS에 알림을 표시 할 수 있으며 블루투스 작업이 처리됩니다.
flutter :
assets :
- assets/audios/ AssetsAudioPlayer . newPlayer (). open (
Audio ( "assets/audios/song1.mp3" ),
autoStart : true ,
showNotification : true ,
);

dependencies :
assets_audio_player : ^3.0.8 flutter: ">=3.3.0" , SDK를 업그레이드하십시오.
당신은 패키지를 좋아합니까? 나에게 kofi를 사세요 :)
| 오디오 소스 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ? ️ 자산 파일 (자산 경로) | ✅ | ✅ | ✅ | ✅ |
| 네트워크 파일 (URL) | ✅ | ✅ | ✅ | ✅ |
| ? 로컬 파일 (경로) | ✅ | ✅ | ✅ | ✅ |
| ? 네트워크 라이브 스트림 / 라디오 (URL) ( 기본값, HLS, 대시, 스무드 스트림 ) | ✅ | ✅ | ✅ | ✅ |
| 특징 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ? 여러 플레이어 | ✅ | ✅ | ✅ | ✅ |
| ? 재생 목록을 엽니 다 | ✅ | ✅ | ✅ | ✅ |
| 시스템 알림 | ✅ | ✅ | ||
| 블루투스 작업 | ✅ | ✅ | ||
| ? 시스템 침묵 모드를 존중하십시오 | ✅ | ✅ | ||
| ? 전화로 일시 중지하십시오 | ✅ | ✅ |
| 명령 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ▶ 놀기 | ✅ | ✅ | ✅ | ✅ |
| ⏸ 일시 중지 | ✅ | ✅ | ✅ | ✅ |
| ⏹ 그만해 | ✅ | ✅ | ✅ | ✅ |
| ⏩ 추구 (위치) | ✅ | ✅ | ✅ | ✅ |
| Seekby (위치) | ✅ | ✅ | ✅ | ✅ |
| ⏩ 포워드 (속도) | ✅ | ✅ | ✅ | ✅ |
| ⏪ 되감기 (속도) | ✅ | ✅ | ✅ | ✅ |
| 다음 | ✅ | ✅ | ✅ | ✅ |
| ⏮ 이전 | ✅ | ✅ | ✅ | ✅ |
| 위젯 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ? 오디오 위젯 | ✅ | ✅ | ✅ | ✅ |
| ? 위젯 빌더 | ✅ | ✅ | ✅ | ✅ |
| ? Audioplayer Builders 확장 | ✅ | ✅ | ✅ | ✅ |
| 속성 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ? 고리 | ✅ | ✅ | ✅ | ✅ |
| ? 혼합 | ✅ | ✅ | ✅ | ✅ |
| ? 볼륨을 설정하십시오 | ✅ | ✅ | ✅ | ✅ |
| play/플레이 속도를 설정합니다 | ✅ | ✅ | ✅ | ✅ |
| pitch/설정 피치 | ✅ |
| 청취자 | 기계적 인조 인간 | iOS | 편물 | 마코스 |
|---|---|---|---|---|
| ? 리스너 onready (완료) | ✅ | ✅ | ✅ | ✅ |
| ? 리스너 currentPosition | ✅ | ✅ | ✅ | ✅ |
| ? 청취자가 끝났습니다 | ✅ | ✅ | ✅ | ✅ |
| ? 리스너 버퍼링 | ✅ | ✅ | ✅ | ✅ |
| ? 리스너 볼륨 | ✅ | ✅ | ✅ | ✅ |
| ? 청취자 플레이 속도 | ✅ | ✅ | ✅ | ✅ |
| ? 청취자 피치 | ✅ |
assets_audio_player를 사용하면 노래를 미디어 캐시에 복사 할 필요가 없습니다. 자산에서 직접 열 수 있습니다.
flutter :
assets :
- assets/audios/ final assetsAudioPlayer = AssetsAudioPlayer ();
assetsAudioPlayer. open (
Audio ( "assets/audios/song1.mp3" ),
);URL 에서 네트워크 노래를 재생할 수도 있습니다
final assetsAudioPlayer = AssetsAudioPlayer ();
try {
await assetsAudioPlayer. open (
Audio . network ( "http://www.mysite.com/myMp3file.mp3" ),
);
} catch (t) {
//mp3 unreachable
}URL 의 라이브 스트림 / 라디오
네트워크와의 주요 차이점, 잠시 멈추거나 플레이하면 생명이 기간이되기 위해 재개됩니다.
final assetsAudioPlayer = AssetsAudioPlayer ();
try {
await assetsAudioPlayer. open (
Audio . liveStream ( MY_LIVESTREAM_URL ),
);
} catch (t) {
//stream unreachable
}파일에서 노래를 재생합니다
//create a new player
final assetsAudioPlayer = AssetsAudioPlayer ();
assetsAudioPlayer. open (
Audio . file ( FILE_URI ),
);파일의 경우 https://pub.dev/packages/path_provider를 참조하십시오
assetsAudioPlayer. playOrPause ();
assetsAudioPlayer. play ();
assetsAudioPlayer. pause ();assetsAudioPlayer. seek ( Duration to);
assetsAudioPlayer. seekBy ( Duration by);assetsAudioPlayer. forwardRewind ( double speed);
//if positive, forward, if negative, rewind assetsAudioPlayer. stop ();

iOS에서는 MPNowPlayingInfoCenter 사용합니다
final audio = Audio . network ( "/assets/audio/country.mp3" ,
metas : Metas (
title : "Country" ,
artist : "Florent Champigny" ,
album : "CountryAlbum" ,
image : MetasImage . asset ( "assets/images/country.jpg" ), //can be MetasImage.network
),
);showNotification: true 로 열립니다 _player. open (audio, showNotification : true )사용자 정의 아이콘 (Android 만 해당)
android/res/drawable 안에 아이콘을 추가했는지 확인하십시오 !!! 플러터 자산은 아닙니다 !!!!
await _assetsAudioPlayer. open (
myAudio,
showNotification : true ,
notificationSettings : NotificationSettings (
customStopIcon : AndroidResDrawable (name : "ic_stop_custom" ),
customPauseIcon : AndroidResDrawable (name : "ic_pause_custom" ),
customPlayIcon : AndroidResDrawable (name : "ic_play_custom" ),
customPrevIcon : AndroidResDrawable (name : "ic_prev_custom" ),
customNextIcon : AndroidResDrawable (name : "ic_next_custom" ),
)
그리고 Proguard에게 해당 리소스를 릴리스 모드로 유지하도록 잊지 마십시오.
(부품 유지 자원)
https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/resource-shrinking
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< resources xmlns : tools = " http://schemas.android.com/tools "
tools:keep= " @drawable/ic_next_custom, @drawable/ic_prev_custom, @drawable/ic_pause_custom, @drawable/ic_play_custom, @drawable/ic_stop_custom " /> Android의 res 폴더 (Android/App/Src/Main/Res)에 아이콘을 추가하십시오.
이 아이콘을 AndroidManifest (Android/App/Src/Main/AndroidManifest.xml)에 참조하십시오.
< meta-data
android : name = " assets.audio.player.notification.icon "
android : resource = " @drawable/ic_music_custom " />액션 아이콘을 변경할 수도 있습니다
<meta-data
android:name="assets.audio.player.notification.icon.play"
android:resource="@drawable/ic_play_custom"/>
<meta-data
android:name="assets.audio.player.notification.icon.pause"
android:resource="@drawable/ic_pause_custom"/>
<meta-data
android:name="assets.audio.player.notification.icon.stop"
android:resource="@drawable/ic_stop_custom"/>
<meta-data
android:name="assets.audio.player.notification.icon.next"
android:resource="@drawable/ic_next_custom"/>
<meta-data
android:name="assets.audio.player.notification.icon.prev"
android:resource="@drawable/ic_prev_custom"/>
메인을 추가하십시오
AssetsAudioPlayer . setupNotificationsOpenAction ((notification) {
//custom action
return true ; //true : handled, does not notify others listeners
//false : enable others listeners to handle it
});그런 다음 위젯에서 사용자 정의 작업을 원한다면
AssetsAudioPlayer . addNotificationOpenAction ((notification) {
//custom action
return false ; //true : handled, does not notify others listeners
//false : enable others listeners to handle it
});알림 조치를 활성화/비활성화 할 수 있습니다
open ( AUDIO ,
showNotification : true ,
notificationSettings : NotificationSettings (
prevEnabled : false , //disable the previous button
//and have a custom next action (will disable the default action)
customNextAction : (player) {
print ( "next" );
}
)
)오디오 제작 후 전화하십시오
audio. updateMetas (
player : _assetsAudioPlayer, //add the player if the audio is actually played
title : "My new title" ,
artist : "My new artist" ,
//if I not provide a new album, it keep the old one
image : MetasImage . network (
//my new image url
),
);그것들을 작동시키기 위해 알림을 활성화해야합니다
사용 가능한 원격 명령 :
(현재 안드로이드에만 해당)
노래/재생 목록을 열는 동안 전략을 추가하십시오
assetsAudioPlayer. open (
...
headPhoneStrategy : HeadPhoneStrategy .pauseOnUnplug,
//headPhoneStrategy: HeadPhoneStrategy.none, //default
//headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplugPlayOnPlug,
)Bluetooth에서도 작동하도록하려면 AndroidManifest.xml 내부에 Bluetooth 권한을 추가해야합니다.
< uses-permission android : name = " android.permission.BLUETOOTH " />AssetSaudioPlayer.newplayer ()를 사용하여 새로운 자산을 만들 수 있습니다.
이를 통해 동시에 두 곡을 재생할 수 있습니다
원하는만큼 플레이어를 가질 수 있습니다!
///play 3 songs in parallel
AssetsAudioPlayer . newPlayer (). open (
Audio ( "assets/audios/song1.mp3" )
);
AssetsAudioPlayer . newPlayer (). open (
Audio ( "assets/audios/song2.mp3" )
);
//another way, with create, open, play & dispose the player on finish
AssetsAudioPlayer . playAndForget (
Audio ( "assets/audios/song3.mp3" )
); 각 플레이어는 고유 생성 id 가지고 있으므로 사용하여 수동으로 검색하거나 생성 할 수 있습니다.
final player = AssetsAudioPlayer . withId (id : "MY_UNIQUE_ID" );assetsAudioPlayer. open (
Playlist (
audios : [
Audio ( "assets/audios/song1.mp3" ),
Audio ( "assets/audios/song2.mp3" )
]
),
loopMode : LoopMode .playlist //loop the full playlist
);
assetsAudioPlayer. next ();
assetsAudioPlayer. prev ();
assetsAudioPlayer. playlistPlayAtIndex ( 1 ); 더 펄럭이는 오디오를 재생하려면 AudioWidget 사용해보십시오!

//inside a stateful widget
bool _play = false ;
@override
Widget build ( BuildContext context) {
return AudioWidget . assets (
path : "assets/audios/country.mp3" ,
play : _play,
child : RaisedButton (
child : Text (
_play ? "pause" : "play" ,
),
onPressed : () {
setState (() {
_play = ! _play;
});
}
),
onReadyToPlay : (duration) {
//onReadyToPlay
},
onPositionChanged : (current, duration) {
//onPositionChanged
},
);
}어떻게? 멈추다 ? Audiowidget?
나무에서 오디오를 제거하십시오! 또는 단순히 play: false
모든 리스너는 rxdart를 사용하여 스트림을 노출시킵니다. AssetSaudioplayer는 일부 청취자를 ValueObservable로 노출시킵니다 (마지막 방출 항목에 대한 동기식 액세스를 제공하는 관찰 가능).
//The current playing audio, filled with the total song duration
assetsAudioPlayer.current //ValueObservable<PlayingAudio>
//Retrieve directly the current played asset
final PlayingAudio playing = assetsAudioPlayer.current.value;
//Listen to the current playing song
assetsAudioPlayer.current. listen ((playingAudio){
final asset = playingAudio.assetAudio;
final songDuration = playingAudio.duration;
}) //Listen to the current playing song
final duration = assetsAudioPlayer.current.value.duration;assetsAudioPlayer.currentPosition //ValueObservable<Duration>
//retrieve directly the current song position
final Duration position = assetsAudioPlayer.currentPosition.value;
return StreamBuilder (
stream : assetsAudioPlayer.currentPosition,
builder : (context, asyncSnapshot) {
final Duration duration = asyncSnapshot.data;
return Text (duration. toString ());
}),또는 PlayerBuilder를 사용하십시오!
PlayerBuilder . currentPosition (
player : _assetsAudioPlayer,
builder : (context, duration) {
return Text (duration. toString ());
}
)또는 플레이어 빌더 확장
_assetsAudioPlayer. builderCurrentPosition (
builder : (context, duration) {
return Text (duration. toString ());
}
)현재 미디어 플레이어 연주 상태를 나타내는 부울 관찰 가능
assetsAudioPlayer.isPlaying // ValueObservable<bool>
//retrieve directly the current player state
final bool playing = assetsAudioPlayer.isPlaying.value;
//will follow the AssetsAudioPlayer playing state
return StreamBuilder (
stream : assetsAudioPlayer.isPlaying,
builder : (context, asyncSnapshot) {
final bool isPlaying = asyncSnapshot.data;
return Text (isPlaying ? "Pause" : "Play" );
}),또는 PlayerBuilder를 사용하십시오!
PlayerBuilder . isPlaying (
player : _assetsAudioPlayer,
builder : (context, isPlaying) {
return Text (isPlaying ? "Pause" : "Play" );
}
)또는 플레이어 빌더 확장
_assetsAudioPlayer. builderIsPlaying (
builder : (context, isPlaying) {
return Text (isPlaying ? "Pause" : "Play" );
}
)볼륨 변경 (0.0 & 1.0 사이)
assetsAudioPlayer. setVolume ( 0.5 ); 미디어 플레이어는 시스템 "볼륨 모드"(진동, 음소거, 정상) respectSilentMode 따라갈 수 있습니다 true
_player. open ( PLAYABLE , respectSilentMode : true );https://developer.android.com/reference/android/media/audiomanager.html?hl=fr#getringermode ()
https://developer.apple.com/documentation/avfoundation/avaudiosessioncategorysoloambient
볼륨을 들어라
return StreamBuilder (
stream : assetsAudioPlayer.volume,
builder : (context, asyncSnapshot) {
final double volume = asyncSnapshot.data;
return Text ( "volume : $ volume " );
}),또는 PlayerBuilder를 사용하십시오!
PlayerBuilder . volume (
player : _assetsAudioPlayer,
builder : (context, volume) {
return Text ( "volume : $ volume " );
}
)현재 노래가 연주되면 전화를 걸고
방금 완료 한 오디오를 제공합니다
assetsAudioPlayer.playlistAudioFinished //ValueObservable<Playing>
assetsAudioPlayer.playlistAudioFinished. listen (( Playing playing){
})완전한 재생 목록이 재생 될 때 호출됩니다
assetsAudioPlayer.playlistFinished //ValueObservable<bool>
assetsAudioPlayer.playlistFinished. listen ((finished){
}) final LoopMode loopMode = assetsAudioPlayer.loop;
// possible values
// LoopMode.none : not looping
// LoopMode.single : looping a single audio
// LoopMode.playlist : looping the fyll playlist
assetsAudioPlayer. setLoopMode ( LoopMode .single);
assetsAudioPlayer.loopMode. listen ((loopMode){
//listen to loop
})
assetsAudioPlayer. toggleLoop (); //toggle the value of loopingassetsAudioPlayer. setPlaySpeed ( 1.5 );
assetsAudioPlayer.playSpeed. listen ((playSpeed){
//listen to playSpeed
})
//change play speed for a particular Audio
Audio audio = Audio . network (
url,
playSpeed : 1.5
);
assetsAudioPlayer. open (audio);assetsAudioPlayer. setPitch ( 1.2 );
assetsAudioPlayer.pitch. listen ((pitch){
//listen to pitch
})
//change pitch for a particular Audio
Audio audio = Audio . network (
url,
pitch : 1.2
);
assetsAudioPlayer. open (audio);기본적으로 오류가 재생되면 오디오가 중지됩니다
그러나 사용자 정의 동작을 추가 할 수 있습니다
_player.onErrorDo = (handler){
handler.player. stop ();
};다른 오디오를 엽니 다
_player.onErrorDo = (handler){
handler.player. open ( ANOTHER_AUDIO );
};같은 위치에서 다시 열어보십시오
_player.onErrorDo = (handler){
handler.player. open (
handler.playlist. copyWith (
startIndex : handler.playlistIndex
),
seek : handler.currentPosition
);
}; Android는 https 호출 만 허용하고 HTTP를 사용하는 경우 오류가 발생합니다. 인터넷 권한을 추가하는 것을 잊지 말고 Seet usesCleartextTraffic="true" 에서 AndroidManifest.xml 에서 사용합니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
iOS는 https 호출 만 허용하면 HTTP를 사용하는 경우 오류가 발생합니다. 정보를 편집하는 NSAppTransportSecurity 잊지 마십시오 NSAllowsArbitraryLoads
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
MacOS에서 HTTP 호출을 사용하려면 info.plist 에 입력/출력 호출 기능을 추가해야합니다.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
<string>fetch</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
그리고 당신의
Runner/DebugProfile.entitlements
추가하다
<key>com.apple.security.network.client</key>
<true/>
완전한 Runner/DebugProfile.entitlements
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
샘플에 사용 된 모든 음악은 https://www.freemusicarchive.org에서 나왔습니다.