fipy/lib/providers/home.dart

247 lines
7.9 KiB
Dart

// ignore_for_file: avoid_print
import 'dart:convert';
import 'package:fipy/globals.dart';
import 'package:flutter/foundation.dart';
import 'package:universal_io/io.dart';
import 'package:fipy/models/track.dart';
import 'package:flutter/material.dart';
import 'package:kplayer/kplayer.dart';
import 'package:path_provider/path_provider.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
import 'package:fipy/providers/player.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:kplayer_with_audioplayers/kplayer_with_audioplayers.dart' as kp;
class HomeProvider with ChangeNotifier {
Track? currentTrack;
PlayerController? player;
AudioPlayer audioPlayer = AudioPlayer();
List<Track> trackList = [];
int trackNbr = 0;
int userPageNbr = 3;
Future<List<Track>> getTracks(String radio, {String cursor = ''}) async {
int pageNbr = 0;
trackList.clear();
trackNbr = 0;
bool stop = false;
while (pageNbr < userPageNbr && !stop) {
final req = Uri.parse(
'${proxyHeader}www.radiofrance.fr:443/api/v1.7/stations/fip/webradios/$radio/songs?pageCursor=$cursor');
final res = await get(req, headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
'Content-Type': 'text/plain'
});
if (res.statusCode == 200) {
Map body = jsonDecode(res.body);
if (body['next'] != null) {
cursor = body['next'];
} else {
print('Page N°$pageNbr');
stop = true;
}
for (Map track in body['songs']) {
trackNbr++;
final String title = track['secondLine'] ?? '';
final String artiste = track['firstLine'] ?? '';
final String album = track['release']['title'] ?? '';
final String image = track['visual']?['preview'] ?? '';
final String imageUrl = track['visual']?['src'] ?? '';
final thisTrack = Track(
number: trackNbr,
title: title,
artiste: artiste,
album: album,
image: image,
imageUrl: imageUrl);
trackList.add(thisTrack);
}
pageNbr++;
} else {
throw "Unable to retrieve tracks.";
}
}
return trackList;
}
Future playTrack(BuildContext context, Track track) async {
var yt = YoutubeExplode();
PlayerProvider playerProvider =
Provider.of<PlayerProvider>(context, listen: false);
HomeProvider homeProvider =
Provider.of<HomeProvider>(context, listen: false);
// track = trackList[track.number - 1];
currentTrack = track;
final currentVolume = player?.volume ?? 1;
if (player?.playing ?? false) player?.stop();
Future.delayed(const Duration(milliseconds: 5));
if (track.id == null) {
final secondMatch = track.artiste == '' ? track.album : track.artiste;
final resultUrl = await yt.search
.search(track.title + ' ' + secondMatch!, filter: TypeFilters.video);
track.id = resultUrl.first.id.value;
}
const invidiousUrl = [
'yewtu.be',
'vid.puffyan.us',
'invidious.snopyta.org',
'invidious.fdn.fr',
];
// audioPlayer.stop();
// Future.delayed(const Duration(milliseconds: 5));
// await audioPlayer.play(DeviceFileSource(
// "https://${invidiousUrl[1]}/latest_version?id=${track.id}&itag=140&local=true&listen=1"));
final media = PlayerMedia(
type: PlayerMediaType.network,
resource:
"https://${invidiousUrl[1]}/latest_version?id=${track.id}&itag=140&local=true&listen=1");
player = kp.Player(media: media);
// player = Player.network(
// "https://${invidiousUrl[0]}/latest_version?id=${track.id}&itag=140&local=true&listen=1"); // https://${invidiousUrl[0]}/embed/${track.id}?listen=1&raw=1&local=true
player!.init();
print(player!.media.resource);
player!.volume = currentVolume;
try {
player!.play();
} catch (e) {
print('Play error: ' + e.toString());
}
Future.delayed(const Duration(milliseconds: 500));
player!.callback = (PlayerEvent event) {
print(event.name);
if (event.name == 'position') {
currentTrack!.duration = player!.duration;
playerProvider.reload();
}
if (event.name == 'end' &&
currentTrack == track &&
(currentTrack!.duration!.inSeconds - player!.position.inSeconds <=
1)) {
var nextTrack = trackList
.firstWhere((element) => element.number == track.number + 1);
currentTrack = nextTrack;
playTrack(context, nextTrack);
}
};
playerProvider.reload();
homeProvider.reload();
yt.close();
}
Future downloadMusic(BuildContext context, Track track) async {
var yt = YoutubeExplode();
var manifest = await yt.videos.streamsClient.getManifest(track.id);
var streamManifest = StreamManifest(manifest.streams);
var streamInfo = streamManifest.audioOnly.withHighestBitrate();
var stream = yt.videos.streamsClient.get(streamInfo);
final fileName = '${track.title} - ${track.artiste}'
.replaceAll('\\', '')
.replaceAll('/', '')
.replaceAll(':', '')
.replaceAll('*', '')
.replaceAll('?', '')
.replaceAll('"', '')
.replaceAll('<', '')
.replaceAll('>', '')
.replaceAll('|', '');
if (!kIsWeb) {
final filePath = Platform.isAndroid
? Directory('/storage/emulated/0/Download')
: await getDownloadsDirectory();
var file = File('${filePath!.path}/$fileName.webm');
var fileStream = file.openWrite();
await stream.pipe(fileStream);
await fileStream.flush();
await fileStream.close();
yt.close();
// convertToMp3(file.path);
track.file = file;
print(file.path);
}
}
List<DropdownMenuItem<String>> get radioList {
List<DropdownMenuItem<String>> menuItems = [
const DropdownMenuItem(child: Text("FIP"), value: "fip"),
const DropdownMenuItem(child: Text("Electro"), value: "fip_electro"),
const DropdownMenuItem(child: Text("Groove"), value: "fip_groove"),
const DropdownMenuItem(child: Text("Rock"), value: "fip_rock"),
const DropdownMenuItem(child: Text("Jazz"), value: "fip_jazz"),
const DropdownMenuItem(child: Text("Pop"), value: "fip_pop"),
const DropdownMenuItem(child: Text("Reggae"), value: "fip_reggae"),
const DropdownMenuItem(child: Text("World"), value: "fip_world"),
const DropdownMenuItem(
child: Text("Nouveautés"), value: "fip_nouveautes"),
];
return menuItems;
}
List<DropdownMenuItem<String>> get pageList {
List<DropdownMenuItem<String>> menuItems = [
const DropdownMenuItem(child: Text("25"), value: "3"),
const DropdownMenuItem(child: Text("50"), value: "6"),
const DropdownMenuItem(child: Text("100"), value: "12"),
const DropdownMenuItem(child: Text("200"), value: "25"),
const DropdownMenuItem(child: Text("500"), value: "62"),
];
return menuItems;
}
void reload() {
notifyListeners();
}
}
class DownloadProvider with ChangeNotifier {
void reload() {
notifyListeners();
}
}
// Future convertToMp3(String audioFile) async {
// audioFile = 'E:\\Téléchargements/test.webm';
// final command = FfmpegCommand(
// inputs: [FfmpegInput.asset(audioFile)],
// args: [
// // CliArg(name: 'i', value: audioFile),
// const CliArg(name: 'ab', value: '320'),
// const CliArg(name: 'ar', value: '44100'),
// ],
// filterGraph: const FilterGraph(
// chains: [
// FilterChain(
// inputs: [],
// filters: [],
// outputs: [],
// ),
// ],
// ),
// outputFilepath: "E:\\Téléchargements/test.mp3",
// );
// // Execute command
// await Ffmpeg().run(command);
// }