Add audio visualisation in resource
This commit is contained in:
parent
15f18f9a5a
commit
d3f60bcbe6
@ -1,48 +1,81 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:audioplayers/audioplayers.dart';
|
//import 'package:audioplayers/audioplayers.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:manager_app/Models/managerContext.dart';
|
|
||||||
import 'package:manager_app/app_context.dart';
|
import 'package:manager_app/app_context.dart';
|
||||||
import 'package:manager_app/constants.dart';
|
import 'package:manager_app/constants.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
|
|
||||||
import 'loading_common.dart';
|
import 'package:just_audio/just_audio.dart';
|
||||||
|
|
||||||
class AudioPlayerContainer extends StatefulWidget {
|
|
||||||
const AudioPlayerContainer({Key key, this.resourceDTO, this.isAuto}) : super(key: key);
|
|
||||||
|
|
||||||
final ResourceDTO resourceDTO;
|
class AudioPlayerFloatingContainer extends StatefulWidget {
|
||||||
|
const AudioPlayerFloatingContainer({Key key, this.audioBytes, this.isAuto}) : super(key: key);
|
||||||
|
|
||||||
|
final Uint8List audioBytes;
|
||||||
final bool isAuto;
|
final bool isAuto;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<AudioPlayerContainer> createState() => _AudioPlayerContainerState();
|
State<AudioPlayerFloatingContainer> createState() => _AudioPlayerFloatingContainerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _AudioPlayerContainerState extends State<AudioPlayerContainer> {
|
class _AudioPlayerFloatingContainerState extends State<AudioPlayerFloatingContainer> {
|
||||||
AudioPlayer player = AudioPlayer();
|
AudioPlayer player = AudioPlayer();
|
||||||
Uint8List audiobytes;
|
Uint8List audiobytes;
|
||||||
bool isplaying = false;
|
bool isplaying = false;
|
||||||
bool audioplayed = false;
|
bool audioplayed = false;
|
||||||
int currentpos = 0;
|
int currentpos = 0;
|
||||||
int maxduration = 100;
|
int maxduration = 100;
|
||||||
|
Duration durationAudio;
|
||||||
String currentpostlabel = "00:00";
|
String currentpostlabel = "00:00";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
//Uint8List base64String = base64Decode(audiobytes); // LOAD DATA
|
Future.delayed(Duration.zero, () async {
|
||||||
|
|
||||||
/*Future.delayed(Duration.zero, () async {
|
audiobytes = widget.audioBytes;
|
||||||
player.onDurationChanged.listen((Duration d) { //get the duration of audio
|
player.durationStream.listen((Duration d) { //get the duration of audio
|
||||||
maxduration = d.inSeconds;
|
maxduration = d.inSeconds;
|
||||||
setState(() {
|
durationAudio = d;
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
player.onAudioPositionChanged.listen((Duration p){
|
//player.bufferedPositionStream
|
||||||
|
|
||||||
|
player.positionStream.listen((event) {
|
||||||
|
if(event != null) {
|
||||||
|
|
||||||
|
currentpos = event.inMilliseconds; //get the current position of playing audio
|
||||||
|
|
||||||
|
//generating the duration label
|
||||||
|
int shours = Duration(milliseconds:durationAudio.inMilliseconds - currentpos).inHours;
|
||||||
|
int sminutes = Duration(milliseconds:durationAudio.inMilliseconds - currentpos).inMinutes;
|
||||||
|
int sseconds = Duration(milliseconds:durationAudio.inMilliseconds - currentpos).inSeconds;
|
||||||
|
|
||||||
|
int rminutes = sminutes - (shours * 60);
|
||||||
|
int rseconds = sseconds - (sminutes * 60 + shours * 60 * 60);
|
||||||
|
|
||||||
|
String minutesToShow = rminutes < 10 ? '0$rminutes': rminutes.toString();
|
||||||
|
String secondsToShow = rseconds < 10 ? '0$rseconds': rseconds.toString();
|
||||||
|
|
||||||
|
currentpostlabel = "$minutesToShow:$secondsToShow";
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
//refresh the UI
|
||||||
|
if(currentpos > player.duration.inMilliseconds) {
|
||||||
|
print("RESET ALL");
|
||||||
|
player.stop();
|
||||||
|
player.seek(const Duration(seconds: 0));
|
||||||
|
isplaying = false;
|
||||||
|
audioplayed = false;
|
||||||
|
currentpostlabel = "00:00";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*player.onPositionChanged.listen((Duration p){
|
||||||
currentpos = p.inMilliseconds; //get the current position of playing audio
|
currentpos = p.inMilliseconds; //get the current position of playing audio
|
||||||
|
|
||||||
//generating the duration label
|
//generating the duration label
|
||||||
@ -61,70 +94,94 @@ class _AudioPlayerContainerState extends State<AudioPlayerContainer> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
//refresh the UI
|
//refresh the UI
|
||||||
});
|
});
|
||||||
});
|
});*/
|
||||||
|
|
||||||
if(widget.isAuto) {
|
if(widget.isAuto) {
|
||||||
player.playBytes(audiobytes);
|
//player.play(BytesSource(audiobytes));
|
||||||
|
await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
player.play();
|
||||||
setState(() {
|
setState(() {
|
||||||
isplaying = true;
|
isplaying = true;
|
||||||
audioplayed = true;
|
audioplayed = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});*/
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
/*player.stop();
|
player.stop();
|
||||||
player.dispose();*/
|
player.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final appContext = Provider.of<AppContext>(context);
|
final appContext = Provider.of<AppContext>(context);
|
||||||
Size size = MediaQuery.of(context).size;
|
|
||||||
|
|
||||||
return FutureBuilder(
|
return FloatingActionButton(
|
||||||
future: getAudio(widget.resourceDTO.id, appContext),
|
backgroundColor: kPrimaryColor.withOpacity(0.7),
|
||||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
|
||||||
print("DOOOONE");
|
|
||||||
if(snapshot.data != null) {
|
|
||||||
print("snapshot.data");
|
|
||||||
print(snapshot.data);
|
|
||||||
//this.player.playBytes(audiobytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
|
|
||||||
Container(
|
|
||||||
child: Text(currentpostlabel, style: TextStyle(fontSize: 25),),
|
|
||||||
),
|
|
||||||
|
|
||||||
Container(
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 10,
|
|
||||||
children: [
|
|
||||||
ElevatedButton.icon(
|
|
||||||
style: ElevatedButton.styleFrom(
|
|
||||||
primary: kPrimaryColor, // Background color
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
print(isplaying);
|
print("TODO");
|
||||||
print(audioplayed);
|
|
||||||
if(!isplaying && !audioplayed){
|
if(!isplaying && !audioplayed){
|
||||||
player.playBytes(audiobytes);
|
//player.play(BytesSource(audiobytes));
|
||||||
//player.playBytes(bytes)
|
await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
player.play();
|
||||||
setState(() {
|
setState(() {
|
||||||
isplaying = true;
|
isplaying = true;
|
||||||
audioplayed = true;
|
audioplayed = true;
|
||||||
});
|
});
|
||||||
}else if(audioplayed && !isplaying){
|
}else if(audioplayed && !isplaying){
|
||||||
player.resume();
|
//player.resume();
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
player.pause();
|
||||||
|
setState(() {
|
||||||
|
isplaying = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: isplaying ? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.pause),
|
||||||
|
Text(currentpostlabel),
|
||||||
|
],
|
||||||
|
) : audioplayed ? Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
const Icon(Icons.play_arrow),
|
||||||
|
Text(currentpostlabel),
|
||||||
|
],
|
||||||
|
): const Icon(Icons.play_arrow),
|
||||||
|
|
||||||
|
/*Column(
|
||||||
|
children: [
|
||||||
|
//Text(currentpostlabel, style: const TextStyle(fontSize: 25)),
|
||||||
|
Wrap(
|
||||||
|
spacing: 10,
|
||||||
|
children: [
|
||||||
|
ElevatedButton.icon(
|
||||||
|
style: ElevatedButton.styleFrom(
|
||||||
|
backgroundColor: kSecondColor, // Background color
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
if(!isplaying && !audioplayed){
|
||||||
|
//player.play(BytesSource(audiobytes));
|
||||||
|
await player.setAudioSource(LoadedSource(audiobytes));
|
||||||
|
player.play();
|
||||||
|
setState(() {
|
||||||
|
isplaying = true;
|
||||||
|
audioplayed = true;
|
||||||
|
});
|
||||||
|
}else if(audioplayed && !isplaying){
|
||||||
|
//player.resume();
|
||||||
|
player.play();
|
||||||
setState(() {
|
setState(() {
|
||||||
isplaying = true;
|
isplaying = true;
|
||||||
audioplayed = true;
|
audioplayed = true;
|
||||||
@ -137,78 +194,48 @@ class _AudioPlayerContainerState extends State<AudioPlayerContainer> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: Icon(isplaying?Icons.pause:Icons.play_arrow),
|
icon: Icon(isplaying?Icons.pause:Icons.play_arrow),
|
||||||
label:Text(isplaying?"Pause":"Play")
|
//label:Text(isplaying?TranslationHelper.getFromLocale("pause", appContext.getContext()):TranslationHelper.getFromLocale("play", appContext.getContext()))
|
||||||
),
|
),
|
||||||
|
|
||||||
ElevatedButton.icon(
|
/*ElevatedButton.icon(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
primary: kPrimaryColor, // Background color
|
backgroundColor: kSecondColor, // Background color
|
||||||
),
|
),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
/*player.stop();
|
player.stop();
|
||||||
|
player.seek(const Duration(seconds: 0));
|
||||||
setState(() {
|
setState(() {
|
||||||
isplaying = false;
|
isplaying = false;
|
||||||
audioplayed = false;
|
audioplayed = false;
|
||||||
currentpostlabel = "00:00";
|
currentpostlabel = "00:00";
|
||||||
});*/
|
});
|
||||||
},
|
},
|
||||||
icon: Icon(Icons.stop),
|
icon: const Icon(Icons.stop),
|
||||||
label:Text("Stop")
|
//label: Text(TranslationHelper.getFromLocale("stop", appContext.getContext()))
|
||||||
),
|
),*/
|
||||||
],
|
],
|
||||||
),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),*/
|
||||||
);
|
|
||||||
}else if (snapshot.connectionState == ConnectionState.none) {
|
|
||||||
return Text("No data");
|
|
||||||
} else {
|
|
||||||
return Center(
|
|
||||||
child: Container(
|
|
||||||
height: size.height * 0.2,
|
|
||||||
child: LoadingCommon()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uint8List> getAudio(String resourceId, AppContext appContext) async {
|
// Feed your own stream of bytes into the player
|
||||||
try {
|
class LoadedSource extends StreamAudioSource {
|
||||||
ManagerAppContext managerAppContext = appContext.getContext() as ManagerAppContext;
|
final List<int> bytes;
|
||||||
var url = managerAppContext.host + "/api/Resource/" + resourceId; // TO TEST TODO UPDATE ROUTE
|
LoadedSource(this.bytes);
|
||||||
print("DOWNLOAD AUDDDDIOOOOO ------------");
|
|
||||||
print(url);
|
|
||||||
//HttpClient client2 = HttpClient();
|
|
||||||
print("before.. hmmm? ");
|
|
||||||
var _downloadData = <int>[];
|
|
||||||
|
|
||||||
print("before.. ? ");
|
@override
|
||||||
|
Future<StreamAudioResponse> request([int start, int end]) async {
|
||||||
/*var test = await http.get(Uri.parse(url));
|
start ??= 0;
|
||||||
print("test");
|
end ??= bytes.length;
|
||||||
print(test);*/
|
return StreamAudioResponse(
|
||||||
|
sourceLength: bytes.length,
|
||||||
var test2 = await http.readBytes(Uri.parse(url));
|
contentLength: end - start,
|
||||||
print("test2");
|
offset: start,
|
||||||
print(test2);
|
stream: Stream.value(bytes.sublist(start, end)),
|
||||||
|
contentType: 'audio/mpeg',
|
||||||
//final HttpClientRequest request = await client2.getUrl(url);
|
);
|
||||||
print("RESPONSE");
|
|
||||||
/*HttpClientResponse response = await request.close();
|
|
||||||
await for(dynamic d in response) { _downloadData.addAll(d); }
|
|
||||||
print("AFTER");*/
|
|
||||||
final base64Str = base64.encode(test2);
|
|
||||||
Uint8List base64String = base64Decode(base64Str); // LOAD DATA
|
|
||||||
return base64String;
|
|
||||||
} catch (e) {
|
|
||||||
print(e);
|
|
||||||
print("IN CATCH");
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:manager_app/Components/audio_player.dart';
|
import 'package:manager_app/Components/audio_player.dart';
|
||||||
|
import 'package:manager_app/Components/loading_common.dart';
|
||||||
|
import 'package:manager_app/Models/managerContext.dart';
|
||||||
import 'package:manager_app/app_context.dart';
|
import 'package:manager_app/app_context.dart';
|
||||||
import 'package:manager_app/constants.dart';
|
import 'package:manager_app/constants.dart';
|
||||||
import 'package:manager_api_new/api.dart';
|
import 'package:manager_api_new/api.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
getElementForResource(dynamic resourceDTO, AppContext appContext) {
|
getElementForResource(dynamic resourceDTO, AppContext appContext) {
|
||||||
switch(resourceDTO.type) {
|
switch(resourceDTO.type) {
|
||||||
@ -49,8 +55,32 @@ getElementForResource(dynamic resourceDTO, AppContext appContext) {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case ResourceType.Audio:
|
case ResourceType.Audio:
|
||||||
//return AudioPlayerContainer(resourceDTO: resourceDTO, isAuto: true);
|
return FutureBuilder(
|
||||||
return Text("Fichier audio - aucune visualisation possible");
|
future: getAudio(resourceDTO.id, appContext),
|
||||||
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||||
|
Size size = MediaQuery.of(context).size;
|
||||||
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
|
var audioBytes;
|
||||||
|
if(snapshot.data != null) {
|
||||||
|
print("snapshot.data");
|
||||||
|
print(snapshot.data);
|
||||||
|
audioBytes = snapshot.data;
|
||||||
|
//this.player.playBytes(audiobytes);
|
||||||
|
}
|
||||||
|
return AudioPlayerFloatingContainer(audioBytes: audioBytes, isAuto: true);
|
||||||
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||||
|
return Text("No data");
|
||||||
|
} else {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
height: size.height * 0.2,
|
||||||
|
child: LoadingCommon()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
//return Text("Fichier audio - aucune visualisation possible");
|
||||||
break;
|
break;
|
||||||
case ResourceType.Video:
|
case ResourceType.Video:
|
||||||
return Text("Vidéo locale - aucune visualisation possible");
|
return Text("Vidéo locale - aucune visualisation possible");
|
||||||
@ -60,3 +90,18 @@ getElementForResource(dynamic resourceDTO, AppContext appContext) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Uint8List> getAudio(String resourceId, AppContext appContext) async {
|
||||||
|
try {
|
||||||
|
ManagerAppContext managerAppContext = appContext.getContext() as ManagerAppContext;
|
||||||
|
var url = managerAppContext.host + "/api/Resource/" + resourceId; // TO TEST TODO UPDATE ROUTE
|
||||||
|
var test2 = await http.readBytes(Uri.parse(url));
|
||||||
|
final base64Str = base64.encode(test2);
|
||||||
|
Uint8List base64String = base64Decode(base64Str); // LOAD DATA
|
||||||
|
return base64String;
|
||||||
|
} catch (e) {
|
||||||
|
print(e);
|
||||||
|
print("IN CATCH");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -5,10 +5,14 @@
|
|||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import audio_session
|
||||||
import audioplayers
|
import audioplayers
|
||||||
|
import just_audio
|
||||||
import path_provider_foundation
|
import path_provider_foundation
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||||
AudioplayersPlugin.register(with: registry.registrar(forPlugin: "AudioplayersPlugin"))
|
AudioplayersPlugin.register(with: registry.registrar(forPlugin: "AudioplayersPlugin"))
|
||||||
|
JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ dependencies:
|
|||||||
#path_provider: ^2.0.2
|
#path_provider: ^2.0.2
|
||||||
encrypt: ^5.0.0
|
encrypt: ^5.0.0
|
||||||
qr_flutter: ^4.0.0
|
qr_flutter: ^4.0.0
|
||||||
audioplayers: 0.18.3
|
just_audio: ^0.9.31
|
||||||
pdf: ^3.6.0
|
pdf: ^3.6.0
|
||||||
multi_select_flutter: ^4.1.2
|
multi_select_flutter: ^4.1.2
|
||||||
#msix: ^2.1.3
|
#msix: ^2.1.3
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user