getLyrics method
- JidoujishoLyricsParameters parameters
Get lyrics
Implementation
Future<JidoujishoLyrics> getLyrics(
JidoujishoLyricsParameters parameters,
) async {
String userAgent =
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36';
String artist = Uri.encodeComponent(parameters.artist.trim());
String title = Uri.encodeComponent(parameters.title.trim());
late String searchUrl;
if (artist.isEmpty) {
searchUrl = 'https://www.google.com/search?q=$title+lyrics';
} else {
searchUrl = 'https://www.google.com/search?q=$title+-+$artist+lyrics';
}
String? text;
bool webViewBusy = true;
HeadlessInAppWebView webView = HeadlessInAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
userAgent: userAgent,
),
android: AndroidInAppWebViewOptions(
blockNetworkImage: true,
),
),
initialUrlRequest: URLRequest(
url: Uri.parse(searchUrl),
),
onLoadStop: (controller, uri) async {
text = await controller.evaluateJavascript(source: '''
[...document.getElementsByClassName('ujudUb')].map((e) => {
return e.innerText;
}).join('\\n\\n');
''');
if (text != null && text!.trim().isEmpty) {
text = null;
}
webViewBusy = false;
},
);
await webView.run();
while (webViewBusy) {
await Future.delayed(const Duration(milliseconds: 100), () {});
}
if (parameters.artist.endsWith(' - Topic') && text == null) {
return getLyrics(
JidoujishoLyricsParameters(
artist: parameters.artist.replaceAll(' - Topic', ''),
title: parameters.title,
),
);
}
if (artist.isNotEmpty && text == null) {
String? firstResultUrl;
bool googleWebViewBusy = true;
HeadlessInAppWebView googleWebView = HeadlessInAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
userAgent: userAgent,
),
android: AndroidInAppWebViewOptions(
blockNetworkImage: true,
),
),
initialUrlRequest: URLRequest(
url: Uri.parse(
'https://google.com/search?q=$artist+$title+歌詞+site:uta-net.com/song'),
),
onLoadStop: (controller, uri) async {
firstResultUrl = await controller.evaluateJavascript(
source:
'document.querySelector(".yuRUbf:nth-of-type(1) > a").href');
googleWebViewBusy = false;
},
);
await googleWebView.run();
while (googleWebViewBusy) {
await Future.delayed(const Duration(milliseconds: 100), () {});
}
if (firstResultUrl != null) {
bool utanetWebViewBusy = true;
HeadlessInAppWebView utanetWebView = HeadlessInAppWebView(
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
userAgent: userAgent,
),
android: AndroidInAppWebViewOptions(
blockNetworkImage: true,
),
),
initialUrlRequest: URLRequest(
url: Uri.parse(firstResultUrl!),
),
onLoadStop: (controller, uri) async {
text = await controller.evaluateJavascript(source: '''
[...document.getElementsByTagName('h2')].map((e) => e.remove());
var kashi = document.getElementsByClassName('row kashi')[0];
kashi.children[0].children[0].innerText;
''');
if (text != null && text!.trim().isEmpty) {
text = null;
}
utanetWebViewBusy = false;
},
);
await utanetWebView.run();
while (utanetWebViewBusy) {
await Future.delayed(const Duration(milliseconds: 100), () {});
}
}
}
/// Try again, but without an artist. This will probably be wrong. But it's
/// better to have tried and gotten a good result sometimes than for this
/// to always fail just because the artist's name might make it difficult.
if (artist.isNotEmpty && text == null) {
return getLyrics(
JidoujishoLyricsParameters(
artist: '',
title: parameters.title,
),
);
}
return JidoujishoLyrics(
includesArtist: artist.isNotEmpty,
text: text,
);
}