mirror of
https://github.com/KRTirtho/spotube.git
synced 2026-02-04 07:52:55 +00:00
290 lines
6.4 KiB
Markdown
290 lines
6.4 KiB
Markdown
# Lyrics Plugin Template Repository
|
|
|
|
This document provides a complete template for creating a lyrics plugin repository.
|
|
|
|
## Repository Structure
|
|
|
|
```
|
|
spotube-plugin-lrclib-lyrics/
|
|
├── .github/
|
|
│ └── workflows/
|
|
│ └── release.yml
|
|
├── src/
|
|
│ └── main.ht
|
|
├── plugin.json
|
|
├── logo.png
|
|
├── README.md
|
|
├── LICENSE
|
|
└── .gitignore
|
|
```
|
|
|
|
## File Contents
|
|
|
|
### plugin.json
|
|
|
|
```json
|
|
{
|
|
"name": "LrcLib Lyrics",
|
|
"author": "YourName",
|
|
"description": "Free and open-source lyrics provider using LrcLib API",
|
|
"version": "1.0.0",
|
|
"pluginApiVersion": "2.0.0",
|
|
"entryPoint": "LrcLibLyricsPlugin",
|
|
"repository": "https://github.com/yourusername/spotube-plugin-lrclib-lyrics",
|
|
"apis": [],
|
|
"abilities": ["lyrics"]
|
|
}
|
|
```
|
|
|
|
### src/main.ht
|
|
|
|
```hetu
|
|
import 'package:spotube_plugin/spotube_plugin.dart'
|
|
|
|
class LrcLibLyricsPlugin {
|
|
|
|
LrcLibLyricsPlugin() {
|
|
print('LrcLib Lyrics Plugin v1.0.0 initialized')
|
|
}
|
|
|
|
var lyrics = LyricsEndpoint()
|
|
}
|
|
|
|
class LyricsEndpoint {
|
|
|
|
external fun search(Map params) async {
|
|
final trackName = params['trackName']
|
|
final artistName = params['artistName']
|
|
final albumName = params['albumName']
|
|
final duration = params['duration']
|
|
|
|
var url = 'https://lrclib.net/api/search?track_name=${Uri.encodeComponent(trackName)}&artist_name=${Uri.encodeComponent(artistName)}'
|
|
|
|
if (albumName != null && albumName.isNotEmpty) {
|
|
url += '&album_name=${Uri.encodeComponent(albumName)}'
|
|
}
|
|
|
|
try {
|
|
final response = await http.get(url)
|
|
|
|
if (response.statusCode != 200) {
|
|
print('LrcLib API error: ${response.statusCode}')
|
|
return []
|
|
}
|
|
|
|
final data = json.decode(response.body)
|
|
|
|
if (data is! List) {
|
|
return []
|
|
}
|
|
|
|
final results = []
|
|
for (var item in data) {
|
|
final syncedLyrics = item['syncedLyrics']
|
|
final plainLyrics = item['plainLyrics']
|
|
|
|
if (syncedLyrics == null && plainLyrics == null) {
|
|
continue
|
|
}
|
|
|
|
results.add({
|
|
'uri': 'lrclib:${item['id']}',
|
|
'name': '${item['trackName']} - ${item['artistName']}',
|
|
'lyrics': parseLrc(syncedLyrics ?? plainLyrics ?? ''),
|
|
'rating': 5,
|
|
'provider': 'lrclib'
|
|
})
|
|
}
|
|
|
|
return results
|
|
} catch (e) {
|
|
print('LrcLib search error: $e')
|
|
return []
|
|
}
|
|
}
|
|
|
|
external fun getById(String id) async {
|
|
final url = 'https://lrclib.net/api/get/$id'
|
|
|
|
try {
|
|
final response = await http.get(url)
|
|
|
|
if (response.statusCode != 200) {
|
|
return null
|
|
}
|
|
|
|
final data = json.decode(response.body)
|
|
final syncedLyrics = data['syncedLyrics']
|
|
final plainLyrics = data['plainLyrics']
|
|
|
|
if (syncedLyrics == null && plainLyrics == null) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
'uri': 'lrclib:${data['id']}',
|
|
'name': '${data['trackName']} - ${data['artistName']}',
|
|
'lyrics': parseLrc(syncedLyrics ?? plainLyrics ?? ''),
|
|
'rating': 5,
|
|
'provider': 'lrclib'
|
|
}
|
|
} catch (e) {
|
|
print('LrcLib getById error: $e')
|
|
return null
|
|
}
|
|
}
|
|
|
|
external fun isAvailable() async {
|
|
try {
|
|
final response = await http.get('https://lrclib.net/')
|
|
return response.statusCode == 200
|
|
} catch (e) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
fun parseLrc(String lrcContent) {
|
|
if (lrcContent.isEmpty) {
|
|
return []
|
|
}
|
|
|
|
final lines = lrcContent.split('\n')
|
|
final lyrics = []
|
|
|
|
for (var line in lines) {
|
|
final timeMatch = RegExp(r'\[(\d+):(\d+)\.(\d+)\]').firstMatch(line)
|
|
|
|
if (timeMatch != null) {
|
|
final minutes = int.parse(timeMatch.group(1))
|
|
final seconds = int.parse(timeMatch.group(2))
|
|
final centiseconds = int.parse(timeMatch.group(3))
|
|
|
|
final text = line.substring(timeMatch.end).trim()
|
|
|
|
if (text.isNotEmpty) {
|
|
final timeMs = (minutes * 60 + seconds) * 1000 + centiseconds * 10
|
|
|
|
lyrics.add({
|
|
'time': timeMs,
|
|
'text': text
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return lyrics
|
|
}
|
|
}
|
|
```
|
|
|
|
### README.md
|
|
|
|
```markdown
|
|
# LrcLib Lyrics Plugin for Spotube
|
|
|
|
Free and open-source lyrics provider using the LrcLib API.
|
|
|
|
## Features
|
|
|
|
- Time-synced lyrics
|
|
- Free and open-source
|
|
- No API key required
|
|
- Large lyrics database
|
|
|
|
## Installation
|
|
|
|
1. Open Spotube
|
|
2. Go to Settings > Plugins
|
|
3. Click "Add Plugin"
|
|
4. Paste: `https://github.com/yourusername/spotube-plugin-lrclib-lyrics`
|
|
5. Click Install
|
|
|
|
## Building
|
|
|
|
### Prerequisites
|
|
- Dart SDK
|
|
- Hetu Script Dev Tools
|
|
|
|
### Compile
|
|
```bash
|
|
dart pub global activate hetu_script_dev_tools
|
|
hetu compile src/main.ht -o plugin.out
|
|
```
|
|
|
|
### Package
|
|
```bash
|
|
zip spotube-plugin-lrclib-lyrics.smplug plugin.json plugin.out logo.png
|
|
```
|
|
|
|
## API
|
|
|
|
This plugin uses the [LrcLib API](https://lrclib.net/docs).
|
|
|
|
## License
|
|
|
|
MIT License
|
|
```
|
|
|
|
### .github/workflows/release.yml
|
|
|
|
```yaml
|
|
name: Release Plugin
|
|
|
|
on:
|
|
push:
|
|
tags:
|
|
- 'v*'
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- uses: dart-lang/setup-dart@v1
|
|
|
|
- name: Install Hetu
|
|
run: dart pub global activate hetu_script_dev_tools
|
|
|
|
- name: Compile Plugin
|
|
run: hetu compile src/main.ht -o plugin.out
|
|
|
|
- name: Package Plugin
|
|
run: zip spotube-plugin-lrclib-lyrics.smplug plugin.json plugin.out logo.png
|
|
|
|
- name: Create Release
|
|
uses: softprops/action-gh-release@v1
|
|
with:
|
|
files: spotube-plugin-lrclib-lyrics.smplug
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
```
|
|
|
|
### .gitignore
|
|
|
|
```
|
|
plugin.out
|
|
*.smplug
|
|
.DS_Store
|
|
```
|
|
|
|
## Publishing
|
|
|
|
1. Create repository on GitHub
|
|
2. Push code
|
|
3. Create a tag: `git tag v1.0.0`
|
|
4. Push tag: `git push origin v1.0.0`
|
|
5. GitHub Actions will automatically build and release
|
|
|
|
## Testing Locally
|
|
|
|
1. Compile: `hetu compile src/main.ht -o plugin.out`
|
|
2. Package: `zip plugin.smplug plugin.json plugin.out logo.png`
|
|
3. In Spotube, add plugin via file path
|
|
|
|
## Example Plugins
|
|
|
|
- [spotube-plugin-youtube-audio](https://github.com/KRTirtho/spotube/tree/master/assets/plugins/spotube-plugin-youtube-audio)
|
|
- [spotube-plugin-musicbrainz-listenbrainz](https://github.com/KRTirtho/spotube/tree/master/assets/plugins/spotube-plugin-musicbrainz-listenbrainz)
|