// 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 trackList = []; int trackNbr = 0; int userPageNbr = 3; Future> 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(context, listen: false); HomeProvider homeProvider = Provider.of(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> get radioList { List> 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> get pageList { List> 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(); } }