optimized search for both youtube track & synched subtitle

flutter_distributor .deb build support
This commit is contained in:
Kingkor Roy Tirtho 2022-04-25 22:15:01 +06:00
parent ce6e4dc677
commit cea6fd9797
8 changed files with 120 additions and 13 deletions

View File

@ -24,4 +24,18 @@ releases:
target: appimage
build_args:
dart-define:
APP_ENV: dev
APP_ENV: dev
- name: release-dev-windows-exe
package:
platform: windows
target: exe
build_args:
dart-define:
APP_ENV: dev
- name: release-dev-macos-dmg
package:
platform: macos
target: dmg
build_args:
dart-define:
APP_ENV: dev

View File

@ -12,7 +12,6 @@ import 'package:spotube/components/Category/CategoryCard.dart';
import 'package:spotube/components/Home/Sidebar.dart';
import 'package:spotube/components/Home/SpotubeNavigationBar.dart';
import 'package:spotube/components/Lyrics/SyncedLyrics.dart';
import 'package:spotube/components/Lyrics.dart';
import 'package:spotube/components/Search/Search.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
import 'package:spotube/components/Player/Player.dart';

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/Lyrics.dart';
import 'package:spotube/components/Lyrics/Lyrics.dart';
import 'package:spotube/components/Shared/SpotubeMarqueeText.dart';
import 'package:spotube/helpers/artist-to-string.dart';
import 'package:spotube/helpers/timed-lyrics.dart';
@ -26,9 +26,10 @@ class SyncedLyrics extends HookConsumerWidget {
if (playback.currentTrack == null ||
playback.currentTrack is! SpotubeTrack) return null;
try {
if (failed.value) failed.value = false;
final lyrics =
await getTimedLyrics(playback.currentTrack as SpotubeTrack);
if (failed.value) failed.value = false;
if (lyrics == null) failed.value = true;
return lyrics;
} catch (e) {
if (e == "Subtitle lookup failed") {
@ -52,13 +53,42 @@ class SyncedLyrics extends HookConsumerWidget {
final textTheme = Theme.of(context).textTheme;
useEffect(() {
controller.scrollToIndex(
0,
preferPosition: AutoScrollPosition.middle,
);
controller.scrollToIndex(0);
return null;
}, [playback.currentTrack]);
useEffect(() {
if (lyricsSnapshot.data != null && lyricsSnapshot.data!.rating <= 2) {
Future.delayed(const Duration(seconds: 5), () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
actions: [
TextButton(
child: const Text("No"),
onPressed: () {
Navigator.pop(context);
},
),
TextButton(
child: const Text("Yes"),
onPressed: () {
failed.value = true;
Navigator.pop(context);
},
),
],
content: const Text(
"The found lyrics might not be properly synced. Do you want to default to static (genius.com) lyrics?"),
);
},
);
});
}
return null;
}, [lyricsSnapshot.data]);
// when synced lyrics not found, fallback to GeniusLyrics
if (failed.value) return const Lyrics();

View File

@ -0,0 +1,6 @@
bool containsTextInBracket(String matcher, String text) {
return RegExp(r"(?<=\().+?(?=\))")
.allMatches(matcher)
.map((e) => e.group(0))
.every((match) => match?.contains(text) ?? false);
}

View File

@ -1,5 +1,6 @@
import 'dart:io';
import 'package:spotify/spotify.dart';
import 'package:spotube/helpers/contains-text-in-bracket.dart';
import 'package:spotube/helpers/getLyrics.dart';
import 'package:spotube/models/Logger.dart';
import 'package:spotube/models/SpotubeTrack.dart';
@ -36,15 +37,40 @@ Future<SpotubeTrack> toSpotubeTrack(
// the find should be lazy thus everything case insensitive
final ytTitle = video.title.toLowerCase();
final bool hasTitle = ytTitle.contains(title);
final bool hasYtTitle = title.contains(ytTitle);
final bool hasAllArtists = track.artists?.every(
(artist) => ytTitle.contains(artist.name!.toLowerCase()),
) ??
false;
final bool authorIsArtist = track.artists
?.any((artist) => artist.name?.toLowerCase() == video.author) ??
final bool authorIsArtist = track.artists?.any((artist) {
return artist.name?.toLowerCase() == video.author.toLowerCase();
}) ??
false;
final bool hasNoLive = !containsTextInBracket(ytTitle, "live");
final bool hasOfficialVideo = [
"(official video)",
"[official video]",
"(official music video)",
"[official music video]"
].any((v) => ytTitle.contains(v));
final bool hasOfficialAudio = [
"[official audio]",
"(official audio)",
].any((v) => ytTitle.contains(v));
int rate = 0;
for (final el in [hasTitle, hasAllArtists, authorIsArtist]) {
for (final el in [
hasTitle,
hasYtTitle,
hasAllArtists,
authorIsArtist,
hasNoLive,
!video.isLive,
hasOfficialAudio,
hasOfficialVideo,
]) {
if (el) rate++;
}
return {

View File

@ -2,6 +2,7 @@ import 'package:html/dom.dart';
import 'package:http/http.dart' as http;
import 'package:html/parser.dart';
import 'package:collection/collection.dart';
import 'package:spotube/helpers/contains-text-in-bracket.dart';
import 'package:spotube/helpers/getLyrics.dart';
import 'package:spotube/models/Logger.dart';
import 'package:spotube/models/SpotubeTrack.dart';
@ -12,10 +13,12 @@ class SubtitleSimple {
Uri uri;
String name;
List<LyricSlice> lyrics;
int rating;
SubtitleSimple({
required this.uri,
required this.name,
required this.lyrics,
required this.rating,
});
}
@ -60,9 +63,10 @@ Future<SubtitleSimple?> getTimedLyrics(SpotubeTrack track) async {
.every((artist) => title.contains(artist.toLowerCase())) ??
false;
final hasTrackName = title.contains(track.name!.toLowerCase());
final isNotLive = !containsTextInBracket(title, "live");
final exactYtMatch = title == track.ytTrack.title.toLowerCase();
if (exactYtMatch) points = 8;
for (final criteria in [hasTrackName, hasAllArtists]) {
if (exactYtMatch) points = 7;
for (final criteria in [hasTrackName, hasAllArtists, isNotLive]) {
if (criteria) points++;
}
return {"result": result, "points": points};
@ -111,6 +115,7 @@ Future<SubtitleSimple?> getTimedLyrics(SpotubeTrack track) async {
name: topResult.text.trim(),
uri: subtitleUri,
lyrics: lrcList,
rating: rateSortedResults.first["points"] as int,
);
return subtitle;

View File

@ -0,0 +1,27 @@
display_name: Spotube
package_name: spotube
maintainer:
name: Kingkor Roy Tirtho
email: krtirtho@gmail.com
priority: optional
section: x11
installed_size: 24400
dependencies:
- libkeybinder-3.0-0 (>= 0.3.2)
essential: false
icon: assets/spotube-logo.png
keywords:
- Music
- Spotify
- Media
- Streaming
- YouTube
generic_name: Music Streaming Application
categories:
- Music