fipy/lib/providers/home.dart

183 lines
5.7 KiB
Dart

import 'dart:convert';
import 'package:fipy/globals.dart';
import 'package:fipy/models/track.dart';
import 'package:flutter/material.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';
class HomeProvider with ChangeNotifier {
Track? currentTrack;
AudioPlayer player = AudioPlayer(playerId: 'fipyPlayerID');
List<Track> trackList = [];
int trackNbr = 0;
int userPageNbr = 3;
double currentVolume = 1;
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 {
log.d('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(Track track) async {
var yt = YoutubeExplode();
PlayerProvider playerProvider =
Provider.of<PlayerProvider>(homeContext, listen: false);
HomeProvider homeProvider =
Provider.of<HomeProvider>(homeContext, listen: false);
// track = trackList[track.number - 1];
currentTrack = track;
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',
];
player.stop();
Future.delayed(const Duration(milliseconds: 5));
try {
final source = UrlSource(
"https://${invidiousUrl[3]}/latest_version?id=${track.id}&itag=140&local=true&listen=1");
log.d(source.url);
await player.play(source);
} catch (e) {
log.d('Play error: $e');
}
Future.delayed(const Duration(milliseconds: 50));
player.onDurationChanged.listen((event) async {
currentTrack!.duration = await player.getDuration();
playerProvider.reload();
});
player.onPositionChanged.listen((position) async {
currentTrack!.position = position;
playerProvider.reload();
});
player.onPlayerComplete.listen((event) {
var nextTrack =
trackList.firstWhere((element) => element.number == track.number + 1);
currentTrack = nextTrack;
playTrack(nextTrack);
});
playerProvider.reload();
homeProvider.reload();
yt.close();
}
Future nextTrack() async {
if (currentTrack != null && currentTrack!.number < trackList.last.number) {
currentTrack = trackList
.firstWhere((element) => element.number == currentTrack!.number + 1);
await playTrack(currentTrack!);
}
}
Future backTrack() async {
if (currentTrack != null && currentTrack!.number > 1) {
currentTrack = trackList
.firstWhere((element) => element.number == currentTrack!.number - 1);
await playTrack(currentTrack!);
}
}
void resumePlay() {
if (currentTrack == null) {
currentTrack = trackList.first;
playTrack(currentTrack!);
} else {
player.state.name == 'playing' ? player.pause() : player.resume();
}
}
List<DropdownMenuItem<String>> get radioList {
List<DropdownMenuItem<String>> menuItems = [
const DropdownMenuItem(value: "fip", child: Text("FIP")),
const DropdownMenuItem(value: "fip_electro", child: Text("Electro")),
const DropdownMenuItem(value: "fip_groove", child: Text("Groove")),
const DropdownMenuItem(value: "fip_rock", child: Text("Rock")),
const DropdownMenuItem(value: "fip_jazz", child: Text("Jazz")),
const DropdownMenuItem(value: "fip_pop", child: Text("Pop")),
const DropdownMenuItem(value: "fip_reggae", child: Text("Reggae")),
const DropdownMenuItem(value: "fip_world", child: Text("World")),
const DropdownMenuItem(
value: "fip_nouveautes", child: Text("Nouveautés")),
];
return menuItems;
}
List<DropdownMenuItem<String>> get pageList {
List<DropdownMenuItem<String>> menuItems = [
const DropdownMenuItem(value: "3", child: Text("25")),
const DropdownMenuItem(value: "6", child: Text("50")),
const DropdownMenuItem(value: "12", child: Text("100")),
const DropdownMenuItem(value: "25", child: Text("200")),
const DropdownMenuItem(value: "62", child: Text("500")),
];
return menuItems;
}
void reload() {
notifyListeners();
}
}