From b8d6d7f3a1f85ad04a700dff0510d701e55370bc Mon Sep 17 00:00:00 2001 From: poka Date: Fri, 29 Apr 2022 17:38:23 +0200 Subject: [PATCH] Change download methode to better way; Add windows exe setup creation script --- .gitignore | 3 +- lib/screens/home.dart | 79 ++++++++++++++++++++++++++++++++----------- make_exe.iss | 54 +++++++++++++++++++++++++++++ pubspec.lock | 2 +- pubspec.yaml | 4 ++- 5 files changed, 120 insertions(+), 22 deletions(-) create mode 100644 make_exe.iss diff --git a/.gitignore b/.gitignore index 9c24271..e8ddc9f 100644 --- a/.gitignore +++ b/.gitignore @@ -47,4 +47,5 @@ app.*.map.json # API custom token api-token.json -assets/ \ No newline at end of file +assets/ +Output/ \ No newline at end of file diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 7cf11c1..838ce16 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -1,5 +1,7 @@ // ignore_for_file: prefer_const_literals_to_create_immutables, avoid_print +import 'dart:io'; + import 'package:fip_parser_ui/globals.dart'; import 'package:fip_parser_ui/providers/home.dart'; import 'package:fip_parser_ui/providers/player.dart'; @@ -8,10 +10,9 @@ import 'package:fip_parser_ui/queries.dart'; import 'package:graphql/client.dart'; import 'package:kplayer/kplayer.dart'; import 'package:miniplayer/miniplayer.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:retry/retry.dart'; -import 'package:url_launcher/url_launcher.dart'; -import 'package:http/http.dart' as http; import 'package:youtube_explode_dart/youtube_explode_dart.dart'; PlayerController? player; @@ -265,7 +266,6 @@ class _HomeScreenState extends State { player?.duration.inSeconds.toString() ?? '2000'), onChanged: (double value) { - print(value); if (player?.position != null) { player!.position = Duration(seconds: value.toInt()); @@ -337,6 +337,7 @@ class Track { final String? album; String? id; Duration? duration; + File? file; Track( {required this.number, @@ -344,7 +345,8 @@ class Track { required this.artiste, this.album, this.id, - this.duration}); + this.duration, + this.file}); } GraphQLClient initClient() { @@ -361,6 +363,7 @@ GraphQLClient initClient() { } Future> getTracks(String radio, int hours) async { + // TODO: Change API to one use on website: https://www.radiofrance.fr/api/v1.7/stations/fip/webradios/fip_groove/songs?pageCursor= const int queryTimeout = 8; final client = initClient(); @@ -521,14 +524,10 @@ TableRow _buildTableRow(Track track, BuildContext context) { track.id = resultUrl.first.id.value; } if (track.id != null) { - final response = await http.get(Uri.parse( - 'https://ytdl.p2p.legal/ytdl.sh?${track.id}')); - final dlLink = response.body; - if (await canLaunchUrl(Uri.parse(dlLink))) { - launchUrl(Uri.parse(dlLink)); - } + downloadMusic(context, track); } isDownloading = -1; + yt.close(); downloadProvider.reload(); }, child: track.number == -1 @@ -559,20 +558,26 @@ Future playTrack(BuildContext context, Track track) async { Provider.of(context, listen: false); HomeProvider homeProvider = Provider.of(context, listen: false); - track = trackList[track.number - 1]; + // 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!); - track.id = resultUrl.first.id.value; - } final currentVolume = player?.volume ?? 1; player?.dispose(); Future.delayed(const Duration(milliseconds: 5)); - player = Player.network( - "https://invidious.fdn.fr/embed/${track.id}?raw=1&?listen=1"); - print(track.id); + + if (track.file == null) { + 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; + } + player = Player.network( + "https://invidious.fdn.fr/embed/${track.id}?raw=1&?listen=1"); + print(track.id); + } else { + player = Player.asset(track.file!.path); + } player!.volume = currentVolume; try { @@ -592,8 +597,44 @@ Future playTrack(BuildContext context, Track track) async { 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 filePath = await getDownloadsDirectory(); + final fileName = '${track.title} - ${track.artiste}' + .replaceAll('\\', '') + .replaceAll('/', '') + .replaceAll(':', '') + .replaceAll('*', '') + .replaceAll('?', '') + .replaceAll('"', '') + .replaceAll('<', '') + .replaceAll('>', '') + .replaceAll('|', ''); + var file = File('${filePath!.path}/$fileName.webm'); + var fileStream = file.openWrite(); + + await stream.pipe(fileStream); + + await fileStream.flush(); + await fileStream.close(); + yt.close(); + + // Play it + track.file = file; + // playTrack(context, track); + + print(file.path); } // final radioList = [ diff --git a/make_exe.iss b/make_exe.iss new file mode 100644 index 0000000..8802874 --- /dev/null +++ b/make_exe.iss @@ -0,0 +1,54 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define MyAppName "Fipy" +#define MyAppVersion "0.1" +#define MyAppPublisher "p2p.legal" +#define MyAppURL "https://p2p.legal" +#define MyAppExeName "fip_parser_ui.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{E23CE492-F14D-495E-A309-016A37B725F6} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={autopf}\{#MyAppName} +DisableProgramGroupPage=yes +; Uncomment the following line to run in non administrative install mode (install for current user only.) +;PrivilegesRequired=lowest +OutputBaseFilename=fipy_setup +Compression=lzma +SolidCompression=yes +WizardStyle=modern + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked + +[Files] +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\dart_vlc_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\flutter_windows.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\libvlc.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\libvlccore.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\url_launcher_windows_plugin.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\data\*"; DestDir: "{app}\data"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "C:\Users\poka\dev\fip_parser_ui\build\windows\runner\Release\plugins\*"; DestDir: "{app}\plugins"; Flags: ignoreversion recursesubdirs createallsubdirs +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}" +Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/pubspec.lock b/pubspec.lock index 96d179f..772d782 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -348,7 +348,7 @@ packages: source: hosted version: "1.8.0" path_provider: - dependency: transitive + dependency: "direct main" description: name: path_provider url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 856d054..fd55baf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: fip_parser_ui description: Advanced FIP radio track explorer publish_to: 'none' # Remove this line if you wish to publish to pub.dev -version: 0.0.0+1 +version: 0.0.1+1 environment: sdk: ">=2.16.2 <3.0.0" @@ -22,6 +22,8 @@ dependencies: url: https://git.p2p.legal/poka/flutter_miniplayer.git ref: master provider: ^6.0.1 + path_provider: ^2.0.9 + dev_dependencies: flutter_test: