fipy/lib/providers/home.dart

198 lines
6.3 KiB
Dart

// ignore_for_file: avoid_print
import 'dart:convert';
import 'package:fip_parser_ui/globals.dart';
import 'package:flutter/foundation.dart';
import 'package:universal_io/io.dart';
import 'package:fip_parser_ui/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:fip_parser_ui/providers/player.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart';
class HomeProvider with ChangeNotifier {
Track? currentTrack;
PlayerController? player;
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!);
track.id = resultUrl.first.id.value;
}
const invidiousUrl =
'yewtu.be'; //yewtu.be vid.puffyan.us invidious.snopyta.org invidious.fdn.fr
player = Player.network(
"https://$invidiousUrl/embed/${track.id}?raw=1&listen=1&quality=dash");
print(track.id);
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 == 'status' && player!.position == player!.duration) {
var nextTrack = trackList
.firstWhere((element) => element.number == track.number + 1);
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();
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();
}
}