Compare commits

..

1 Commits

Author SHA1 Message Date
neonItem
6cff45b773
Merge 729bdd43b9 into 88699e9a3b 2025-11-02 20:52:34 +01:00
212 changed files with 7591 additions and 14263 deletions

25
.github/Dockerfile vendored Normal file
View File

@ -0,0 +1,25 @@
ARG FLUTTER_VERSION
FROM --platform=linux/arm64 krtirtho/flutter_distributor:${FLUTTER_VERSION}
ARG BUILD_VERSION
WORKDIR /app
COPY . .
RUN chown -R $(whoami) /app
RUN rustup target add aarch64-unknown-linux-gnu
RUN flutter pub get
RUN alias dpkg-deb="dpkg-deb --Zxz" &&\
flutter_distributor package --platform=linux --targets=deb --skip-clean
RUN make tar VERSION=${BUILD_VERSION} ARCH=arm64 PKG_ARCH=aarch64
RUN mv build/spotube-linux-*-aarch64.tar.xz dist/ &&\
mv dist/**/spotube-*-linux.deb dist/Spotube-linux-aarch64.deb
CMD [ "sleep", "5000000" ]

View File

@ -12,10 +12,10 @@ on:
type: boolean type: boolean
default: true default: true
jobs: jobs:
description: Jobs to run (flathub,aur,winget,chocolatey) description: Jobs to run (flathub,aur,winget,chocolatey,playstore)
required: true required: true
type: string type: string
default: "flathub,aur,winget,chocolatey" default: "flathub,aur,winget,chocolatey,playstore"
jobs: jobs:
flathub: flathub:
@ -112,26 +112,26 @@ jobs:
- name: Tagname (workflow dispatch) - name: Tagname (workflow dispatch)
run: echo 'TAG_NAME=${{inputs.version}}' >> $GITHUB_ENV run: echo 'TAG_NAME=${{inputs.version}}' >> $GITHUB_ENV
# - uses: robinraju/release-downloader@main - uses: robinraju/release-downloader@main
# with: with:
# repository: KRTirtho/spotube repository: KRTirtho/spotube
# tag: v${{ env.TAG_NAME }} tag: v${{ env.TAG_NAME }}
# tarBall: false tarBall: false
# zipBall: false zipBall: false
# out-file-path: dist out-file-path: dist
# fileName: "Spotube-playstore-all-arch.aab" fileName: "Spotube-playstore-all-arch.aab"
# - name: Create service-account.json - name: Create service-account.json
# run: | run: |
# echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_BASE64 }}" | base64 -d > service-account.json echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_BASE64 }}" | base64 -d > service-account.json
# - name: Upload Android Release to Play Store - name: Upload Android Release to Play Store
# if: ${{!inputs.dry_run}} if: ${{!inputs.dry_run}}
# uses: r0adkll/upload-google-play@v1 uses: r0adkll/upload-google-play@v1
# with: with:
# serviceAccountJson: ./service-account.json serviceAccountJson: ./service-account.json
# releaseFiles: ./dist/Spotube-playstore-all-arch.aab releaseFiles: ./dist/Spotube-playstore-all-arch.aab
# packageName: oss.krtirtho.spotube packageName: oss.krtirtho.spotube
# track: production track: production
# status: draft status: draft
# releaseName: ${{ env.TAG_NAME }} releaseName: ${{ env.TAG_NAME }}

View File

@ -37,20 +37,19 @@ jobs:
files: | files: |
dist/Spotube-linux-x86_64.deb dist/Spotube-linux-x86_64.deb
dist/Spotube-linux-x86_64.rpm dist/Spotube-linux-x86_64.rpm
dist/Spotube-linux-x86_64.AppImage
dist/spotube-linux-*-x86_64.tar.xz dist/spotube-linux-*-x86_64.tar.xz
- os: ubuntu-22.04-arm - os: ubuntu-22.04-arm
platform: linux platform: linux
arch: arm64 arch: arm64
files: | files: |
dist/Spotube-linux-aarch64.deb dist/Spotube-linux-aarch64.deb
dist/Spotube-linux-aarch64.AppImage
dist/spotube-linux-*-aarch64.tar.xz dist/spotube-linux-*-aarch64.tar.xz
- os: ubuntu-22.04 - os: ubuntu-22.04
platform: android platform: android
arch: all arch: all
files: | files: |
build/Spotube-android-all-arch.apk build/Spotube-android-all-arch.apk
build/Spotube-playstore-all-arch.aab
- os: windows-latest - os: windows-latest
platform: windows platform: windows
arch: x86 arch: x86
@ -78,14 +77,6 @@ jobs:
cache: true cache: true
git-source: https://github.com/flutter/flutter.git git-source: https://github.com/flutter/flutter.git
- name: free disk space
if: ${{ matrix.platform == 'android' }}
run: |
sudo swapoff -a
sudo rm -f /swapfile
sudo apt clean
docker rmi $(docker image ls -aq)
df -h
- name: Setup Java - name: Setup Java
if: ${{matrix.platform == 'android'}} if: ${{matrix.platform == 'android'}}
uses: actions/setup-java@v4 uses: actions/setup-java@v4
@ -109,7 +100,7 @@ jobs:
- name: Install ${{matrix.platform}} dependencies - name: Install ${{matrix.platform}} dependencies
run: | run: |
flutter pub get flutter pub get
dart cli/cli.dart install-dependencies --platform=${{matrix.platform}} --arch=${{matrix.arch}} dart cli/cli.dart install-dependencies --platform=${{matrix.platform}}
- name: Sign Apk - name: Sign Apk
if: ${{matrix.platform == 'android'}} if: ${{matrix.platform == 'android'}}

1
.gitignore vendored
View File

@ -9,7 +9,6 @@
.history .history
.svn/ .svn/
# IntelliJ related # IntelliJ related
*.iml *.iml
*.ipr *.ipr

View File

@ -1,29 +1,5 @@
# Changelog # Changelog
## [5.1.0](https://github.com/KRTirtho/spotube/compare/v5.0.0...v5.1.0) (2025-11-14)
### Features
- Show plugin source and set the only plugin as default if no plugin is there
- **playback**: Add dab music source
- **playback**: Add uncompressed flac playback support
- Add plugin audio source models and api service
- **plugins**: Filter plugins by abilities in plugins page and show abilities as badge
- Add setting default audio source support
- Move away from track source query and preferences audio quality and codec
- Add NewPipe support for desktop platforms
- Add default plugin loading capability
- **queue**: Add multi-select and bulk actions to queue ([#2839](https://github.com/KRTirtho/spotube/issues/2839))
- **android**: Add 16KB page size support
### Bug Fixes
- Change plugin download directory to application support
- **playback**: Play next not working
- Downloaded tracks are not tagged with metadata
- Download not working in different devices and slow
- **playback**: Use stream instead of chunked serving of audio bytes
## [5.0.0](https://github.com/KRTirtho/spotube/compare/v4.0.2...v5.0.0) (2025-09-08) ## [5.0.0](https://github.com/KRTirtho/spotube/compare/v4.0.2...v5.0.0) (2025-09-08)
### Features ### Features

View File

@ -2,7 +2,7 @@
<img width="600" src="assets/branding/spotube_banner.png" alt="Spotube Logo"> <img width="600" src="assets/branding/spotube_banner.png" alt="Spotube Logo">
A cross-platform extensible open-source music streaming platform.<br> A cross-platform extensible open-source music streaming platform.<br>
Bring your own music metadata/playlist/audio-source with plugins created by community or by yourself. A small step towards the decentralized music streaming era! Bring your own music metadata/playlist with plugins created by community or by yourself. A small step towards the decentralized music streaming era!
Btw it's not just another Electron app 😉 Btw it's not just another Electron app 😉
@ -202,7 +202,7 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [Invidious](https://invidious.io/) - Invidious is an open source alternative front-end to YouTube. 1. [Invidious](https://invidious.io/) - Invidious is an open source alternative front-end to YouTube.
1. [yt-dlp](https://github.com/yt-dlp/yt-dlp) - A feature-rich command-line audio/video downloader. 1. [yt-dlp](https://github.com/yt-dlp/yt-dlp) - A feature-rich command-line audio/video downloader.
1. [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) - NewPipe's core library for extracting data from streaming sites. 1. [NewPipeExtractor](https://github.com/TeamNewPipe/NewPipeExtractor) - NewPipe's core library for extracting data from streaming sites.
1. [YouTubeExplodeDart](https://github.com/Hexer10/youtube_explode_dart) - A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key. 1. [SongLink](https://song.link) - SongLink is a free smart link service that helps you share music with your audience. It's a one-stop-shop for creating smart links for music, podcasts, and other audio content
1. [LRCLib](https://lrclib.net/) - A public synced lyric API. 1. [LRCLib](https://lrclib.net/) - A public synced lyric API.
1. [Linux](https://www.linux.org) - Linux is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged in a Linux distribution 1. [Linux](https://www.linux.org) - Linux is a family of open-source Unix-like operating systems based on the Linux kernel, an operating system kernel first released on September 17, 1991, by Linus Torvalds. Linux is typically packaged in a Linux distribution
1. [AUR](https://aur.archlinux.org) - AUR stands for Arch User Repository. It is a community-driven repository for Arch-based Linux distributions users 1. [AUR](https://aur.archlinux.org) - AUR stands for Arch User Repository. It is a community-driven repository for Arch-based Linux distributions users
@ -216,6 +216,7 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [app_links](https://github.com/llfbandit/app_links) - Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included). 1. [app_links](https://github.com/llfbandit/app_links) - Android App Links, Deep Links, iOs Universal Links and Custom URL schemes handler for Flutter (desktop included).
1. [args](https://pub.dev/packages/args) - Library for defining parsers for parsing raw command-line arguments into a set of options and values using GNU and POSIX style options. 1. [args](https://pub.dev/packages/args) - Library for defining parsers for parsing raw command-line arguments into a set of options and values using GNU and POSIX style options.
1. [async](https://pub.dev/packages/async) - Utility functions and classes related to the 'dart:async' library.
1. [audio_service](https://pub.dev/packages/audio_service) - Flutter plugin to play audio in the background while the screen is off. 1. [audio_service](https://pub.dev/packages/audio_service) - Flutter plugin to play audio in the background while the screen is off.
1. [audio_service_mpris](https://github.com/bdrazhzhov/audio-service-mpris) - audio_service platform interface supporting Media Player Remote Interfacing Specification. 1. [audio_service_mpris](https://github.com/bdrazhzhov/audio-service-mpris) - audio_service platform interface supporting Media Player Remote Interfacing Specification.
1. [audio_session](https://github.com/ryanheise/audio_session) - Sets the iOS audio session category and Android audio attributes for your app, and manages your app's audio focus, mixing and ducking behaviour. 1. [audio_session](https://github.com/ryanheise/audio_session) - Sets the iOS audio session category and Android audio attributes for your app, and manages your app's audio focus, mixing and ducking behaviour.
@ -242,11 +243,15 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [flutter_inappwebview](https://inappwebview.dev/) - A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window. 1. [flutter_inappwebview](https://inappwebview.dev/) - A Flutter plugin that allows you to add an inline webview, to use an headless webview, and to open an in-app browser window.
1. [flutter_native_splash](https://pub.dev/packages/flutter_native_splash) - Customize Flutter's default white native splash screen with background color and splash image. Supports dark mode, full screen, and more. 1. [flutter_native_splash](https://pub.dev/packages/flutter_native_splash) - Customize Flutter's default white native splash screen with background color and splash image. Supports dark mode, full screen, and more.
1. [flutter_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze. 1. [flutter_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
1. [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) - Flutter Secure Storage provides API to store data in secure storage. Keychain is used in iOS, KeyStore based solution is used in Android.
1. [flutter_sharing_intent](https://github.com/bhagat-techind/flutter_sharing_intent.git) - A flutter plugin that allow flutter apps to receive photos, videos, text, urls or any other file types from another app. 1. [flutter_sharing_intent](https://github.com/bhagat-techind/flutter_sharing_intent.git) - A flutter plugin that allow flutter apps to receive photos, videos, text, urls or any other file types from another app.
1. [flutter_undraw](https://github.com/KRTirtho/flutter_undraw) - Undraw.co Illustrations for Flutter with customization options 1. [flutter_undraw](https://github.com/KRTirtho/flutter_undraw) - Undraw.co Illustrations for Flutter with customization options
1. [form_builder_validators](https://github.com/flutter-form-builder-ecosystem) - Form Builder Validators set of validators for FlutterFormBuilder. Provides common validators and a way to make your own. 1. [form_builder_validators](https://github.com/flutter-form-builder-ecosystem) - Form Builder Validators set of validators for FlutterFormBuilder. Provides common validators and a way to make your own.
1. [form_validator](https://github.com/TheMisir/form-validator) - Simplest form validation library for flutter's form field widgets
1. [freezed_annotation](https://pub.dev/packages/freezed_annotation) - Annotations for the freezed code-generator. This package does nothing without freezed too. 1. [freezed_annotation](https://pub.dev/packages/freezed_annotation) - Annotations for the freezed code-generator. This package does nothing without freezed too.
1. [fuzzywuzzy](https://github.com/sphericalkat/dart-fuzzywuzzy) - An implementation of the popular fuzzywuzzy package in Dart, to suit all your fuzzy string matching/searching needs! 1. [fuzzywuzzy](https://github.com/sphericalkat/dart-fuzzywuzzy) - An implementation of the popular fuzzywuzzy package in Dart, to suit all your fuzzy string matching/searching needs!
1. [gap](https://github.com/letsar/gap) - Flutter widgets for easily adding gaps inside Flex widgets such as Columns and Rows or scrolling views.
1. [google_fonts](https://pub.dev/packages/google_fonts) - A Flutter package to use fonts from fonts.google.com. Supports HTTP fetching, caching, and asset bundling.
1. [home_widget](https://pub.dev/packages/home_widget) - A plugin to provide a common interface for creating HomeScreen Widgets for Android and iOS. 1. [home_widget](https://pub.dev/packages/home_widget) - A plugin to provide a common interface for creating HomeScreen Widgets for Android and iOS.
1. [hooks_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze. 1. [hooks_riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
1. [html](https://pub.dev/packages/html) - APIs for parsing and manipulating HTML content outside the browser. 1. [html](https://pub.dev/packages/html) - APIs for parsing and manipulating HTML content outside the browser.
@ -254,10 +259,15 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [http](https://pub.dev/packages/http) - A composable, multi-platform, Future-based API for HTTP requests. 1. [http](https://pub.dev/packages/http) - A composable, multi-platform, Future-based API for HTTP requests.
1. [image_picker](https://pub.dev/packages/image_picker) - Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera. 1. [image_picker](https://pub.dev/packages/image_picker) - Flutter plugin for selecting images from the Android and iOS image library, and taking new pictures with the camera.
1. [intl](https://pub.dev/packages/intl) - Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues. 1. [intl](https://pub.dev/packages/intl) - Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
1. [invidious](https://pub.dev/packages/invidious) - Invidious API client for Dart and Flutter.
1. [jiosaavn](https://github.com/KRTirtho/jiosaavn) - Unofficial API client for jiosaavn.com
1. [json_annotation](https://pub.dev/packages/json_annotation) - Classes and helper functions that support JSON code generation via the `json_serializable` package.
1. [local_notifier](https://github.com/leanflutter/local_notifier) - This plugin allows Flutter desktop apps to displaying local notifications. 1. [local_notifier](https://github.com/leanflutter/local_notifier) - This plugin allows Flutter desktop apps to displaying local notifications.
1. [logger](https://pub.dev/packages/logger) - Small, easy to use and extensible logger which prints beautiful logs. 1. [logger](https://pub.dev/packages/logger) - Small, easy to use and extensible logger which prints beautiful logs.
1. [logging](https://pub.dev/packages/logging) - Provides APIs for debugging and error logging, similar to loggers in other languages, such as the Closure JS Logger and java.util.logging.Logger. 1. [logging](https://pub.dev/packages/logging) - Provides APIs for debugging and error logging, similar to loggers in other languages, such as the Closure JS Logger and java.util.logging.Logger.
1. [lrc](https://pub.dev/packages/lrc) - A Dart-only package that creates, parses, and handles LRC, which is a format that stores song lyrics. 1. [lrc](https://pub.dev/packages/lrc) - A Dart-only package that creates, parses, and handles LRC, which is a format that stores song lyrics.
1. [media_kit](https://github.com/media-kit/media-kit) - A cross-platform video player & audio player for Flutter & Dart. Performant, stable, feature-proof & modular.
1. [media_kit_libs_audio](https://github.com/media-kit/media-kit.git) - package:media_kit audio (only) playback native libraries for all platforms.
1. [metadata_god](https://pub.dev/packages/metadata_god) - Plugin for retrieving and writing audio tags/metadata from audio files 1. [metadata_god](https://pub.dev/packages/metadata_god) - Plugin for retrieving and writing audio tags/metadata from audio files
1. [mime](https://pub.dev/packages/mime) - Utilities for handling media (MIME) types, including determining a type from a file extension and file contents. 1. [mime](https://pub.dev/packages/mime) - Utilities for handling media (MIME) types, including determining a type from a file extension and file contents.
1. [open_file](https://pub.dev/packages/open_file) - A plug-in that can call native APP to open files with string result in flutter, support iOS(UTI) / android(intent) / PC(ffi) / web(dart:html) 1. [open_file](https://pub.dev/packages/open_file) - A plug-in that can call native APP to open files with string result in flutter, support iOS(UTI) / android(intent) / PC(ffi) / web(dart:html)
@ -266,6 +276,7 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [path](https://pub.dev/packages/path) - A string-based path manipulation library. All of the path operations you know and love, with solid support for Windows, POSIX (Linux and Mac OS X), and the web. 1. [path](https://pub.dev/packages/path) - A string-based path manipulation library. All of the path operations you know and love, with solid support for Windows, POSIX (Linux and Mac OS X), and the web.
1. [path_provider](https://pub.dev/packages/path_provider) - Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. 1. [path_provider](https://pub.dev/packages/path_provider) - Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories.
1. [permission_handler](https://pub.dev/packages/permission_handler) - Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions. 1. [permission_handler](https://pub.dev/packages/permission_handler) - Permission plugin for Flutter. This plugin provides a cross-platform (iOS, Android) API to request and check permissions.
1. [piped_client](https://github.com/KRTirtho/piped_client) - API Client for piped.video
1. [riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze. 1. [riverpod](https://riverpod.dev) - A reactive caching and data-binding framework. Riverpod makes working with asynchronous code a breeze.
1. [scroll_to_index](https://github.com/quire-io/scroll-to-index) - Scroll to a specific child of any scrollable widget in Flutter 1. [scroll_to_index](https://github.com/quire-io/scroll-to-index) - Scroll to a specific child of any scrollable widget in Flutter
1. [shadcn_flutter](https://github.com/sunarya-thito/shadcn_flutter) - Beautifully designed components from Shadcn/UI is now available for Flutter 1. [shadcn_flutter](https://github.com/sunarya-thito/shadcn_flutter) - Beautifully designed components from Shadcn/UI is now available for Flutter
@ -280,6 +291,9 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [smtc_windows](https://pub.dev/packages/smtc_windows) - Windows `SystemMediaTransportControls` implementation for Flutter giving access to Windows OS Media Control applet. 1. [smtc_windows](https://pub.dev/packages/smtc_windows) - Windows `SystemMediaTransportControls` implementation for Flutter giving access to Windows OS Media Control applet.
1. [sqlite3](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3) - Provides lightweight yet convenient bindings to SQLite by using dart:ffi 1. [sqlite3](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3) - Provides lightweight yet convenient bindings to SQLite by using dart:ffi
1. [sqlite3_flutter_libs](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3_flutter_libs) - Flutter plugin to include native sqlite3 libraries with your app 1. [sqlite3_flutter_libs](https://github.com/simolus3/sqlite3.dart/tree/main/sqlite3_flutter_libs) - Flutter plugin to include native sqlite3 libraries with your app
1. [stroke_text](https://github.com/MohamedAbd0/stroke_text) - A Simple Flutter plugin for applying stroke (border) style to a text widget
1. [system_theme](https://github.com/bdlukaa/system_theme/tree/master/system_theme) - A plugin to get the current system theme info. Supports Android, Web, Windows, Linux and macOS
1. [test](https://pub.dev/packages/test) - A full featured library for writing and running Dart tests across platforms.
1. [timezone](https://pub.dev/packages/timezone) - Time zone database and time zone aware DateTime. 1. [timezone](https://pub.dev/packages/timezone) - Time zone database and time zone aware DateTime.
1. [titlebar_buttons](https://github.com/gtk-flutter/titlebar_buttons) - A package which provides most of the titlebar buttons from windows, linux and macos. 1. [titlebar_buttons](https://github.com/gtk-flutter/titlebar_buttons) - A package which provides most of the titlebar buttons from windows, linux and macos.
1. [tray_manager](https://github.com/leanflutter/tray_manager) - This plugin allows Flutter desktop apps to defines system tray. 1. [tray_manager](https://github.com/leanflutter/tray_manager) - This plugin allows Flutter desktop apps to defines system tray.
@ -291,17 +305,12 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [web_socket_channel](https://pub.dev/packages/web_socket_channel) - StreamChannel wrappers for WebSockets. Provides a cross-platform WebSocketChannel API, a cross-platform implementation of that API that communicates over an underlying StreamChannel. 1. [web_socket_channel](https://pub.dev/packages/web_socket_channel) - StreamChannel wrappers for WebSockets. Provides a cross-platform WebSocketChannel API, a cross-platform implementation of that API that communicates over an underlying StreamChannel.
1. [wikipedia_api](https://github.com/KRTirtho/wikipedia_api) - Wikipedia API for dart and flutter 1. [wikipedia_api](https://github.com/KRTirtho/wikipedia_api) - Wikipedia API for dart and flutter
1. [win32_registry](https://pub.dev/packages/win32_registry) - A package that provides a friendly Dart API for accessing the Windows Registry. 1. [win32_registry](https://pub.dev/packages/win32_registry) - A package that provides a friendly Dart API for accessing the Windows Registry.
1. [window_manager](https://leanflutter.dev) - This plugin allows Flutter desktop apps to resizing and repositioning the window. 1. [window_manager](https://github.com/leanflutter/window_manager) - This plugin allows Flutter desktop apps to resizing and repositioning the window.
1. [youtube_explode_dart](https://github.com/Hexer10/youtube_explode_dart) - A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key. 1. [youtube_explode_dart](https://github.com/Hexer10/youtube_explode_dart) - A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
1. [http_parser](https://pub.dev/packages/http_parser) - A platform-independent package for parsing and serializing HTTP formats. 1. [http_parser](https://pub.dev/packages/http_parser) - A platform-independent package for parsing and serializing HTTP formats.
1. [collection](https://pub.dev/packages/collection) - Collections and utilities functions and classes related to collections. 1. [collection](https://pub.dev/packages/collection) - Collections and utilities functions and classes related to collections.
1. [archive](https://pub.dev/packages/archive) - Provides encoders and decoders for various archive and compression formats such as zip, tar, bzip2, gzip, and zlib. 1. [otp_util](https://github.com/dushiling) - otp_util is a dart package to generate and verify one-time passwords,it It provides two methods TOPT and HOTP.They are Time-based OTPs and Counter-based OTPs.
1. [hetu_script](https://github.com/hetu-script/hetu-script) - Hetu is a lightweight scripting language for embedding in Flutter apps. 1. [dio_http2_adapter](https://github.com/cfug/dio) - An adapter that combines HTTP/2 and dio. Supports reusing connections, header compression, etc.
1. [get_it](https://github.com/flutter-it/get_it) - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App"
1. [flutter_markdown_plus](https://pub.dev/packages/flutter_markdown_plus) - A Markdown renderer for Flutter. Create rich text output, including text styles, tables, links, and more, from plain text data formatted with simple Markdown tags.
1. [pub_semver](https://pub.dev/packages/pub_semver) - Versions and version constraints implementing pub's versioning policy. This is very similar to vanilla semver, with a few corner cases.
1. [change_case](https://github.com/mrgnhnt96/change_case) - An extension on String for the missing methods for camelCase, PascalCase, Capital Case, snake_case, param-case, CONSTANT_CASE and others.
1. [flutter_secure_storage](https://pub.dev/packages/flutter_secure_storage) - Flutter Secure Storage provides API to store data in secure storage. Keychain is used in iOS, KeyStore based solution is used in Android.
1. [build_runner](https://pub.dev/packages/build_runner) - A build system for Dart code generation and modular compilation. 1. [build_runner](https://pub.dev/packages/build_runner) - A build system for Dart code generation and modular compilation.
1. [envied_generator](https://github.com/petercinibulk/envied) - Generator for the Envied package. See https://pub.dev/packages/envied. 1. [envied_generator](https://github.com/petercinibulk/envied) - Generator for the Envied package. See https://pub.dev/packages/envied.
1. [flutter_gen_runner](https://github.com/FlutterGen/flutter_gen) - The Flutter code generator for your assets, fonts, colors, … — Get rid of all String-based APIs. 1. [flutter_gen_runner](https://github.com/FlutterGen/flutter_gen) - The Flutter code generator for your assets, fonts, colors, … — Get rid of all String-based APIs.
@ -312,23 +321,17 @@ If you are curious, you can [read the reason of choosing this license](https://d
1. [process_run](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run) - Process run helpers for Linux/Win/Mac and which like feature for finding executables. 1. [process_run](https://github.com/tekartik/process_run.dart/blob/master/packages/process_run) - Process run helpers for Linux/Win/Mac and which like feature for finding executables.
1. [pubspec_parse](https://pub.dev/packages/pubspec_parse) - Simple package for parsing pubspec.yaml files with a type-safe API and rich error reporting. 1. [pubspec_parse](https://pub.dev/packages/pubspec_parse) - Simple package for parsing pubspec.yaml files with a type-safe API and rich error reporting.
1. [pub_api_client](https://github.com/leoafarias/pub_api_client) - An API Client for Pub to interact with public package information. 1. [pub_api_client](https://github.com/leoafarias/pub_api_client) - An API Client for Pub to interact with public package information.
1. [xml](https://github.com/renggli/dart-xml) - A lightweight library for parsing, traversing, querying, transforming and building XML documents.
1. [io](https://pub.dev/packages/io) - Utilities for the Dart VM Runtime including support for ANSI colors, file copying, and standard exit code values. 1. [io](https://pub.dev/packages/io) - Utilities for the Dart VM Runtime including support for ANSI colors, file copying, and standard exit code values.
1. [drift_dev](https://drift.simonbinder.eu/) - Dev-dependency for users of drift. Contains the generator and development tools. 1. [drift_dev](https://drift.simonbinder.eu/) - Dev-dependency for users of drift. Contains the generator and development tools.
1. [test](https://pub.dev/packages/test) - A full featured library for writing and running Dart tests across platforms.
1. [auto_route_generator](https://github.com/Milad-Akarie/auto_route_library) - AutoRoute is a declarative routing solution, where everything needed for navigation is automatically generated for you. 1. [auto_route_generator](https://github.com/Milad-Akarie/auto_route_library) - AutoRoute is a declarative routing solution, where everything needed for navigation is automatically generated for you.
1. [desktop_webview_window](https://github.com/MixinNetwork/flutter-plugins/tree/main/packages/desktop_webview_window) - Show a webview window on your flutter desktop application. 1. [desktop_webview_window](https://github.com/MixinNetwork/flutter-plugins/tree/main/packages/desktop_webview_window) - Show a webview window on your flutter desktop application.
1. [disable_battery_optimization](https://github.com/pvsvamsi/Disable-Battery-Optimizations) - Flutter plugin to check and disable battery optimizations. Also shows custom steps to disable the optimizations in devices like mi, xiaomi, samsung, oppo, huawei, oneplus etc 1. [disable_battery_optimization](https://github.com/pvsvamsi/Disable-Battery-Optimizations) - Flutter plugin to check and disable battery optimizations. Also shows custom steps to disable the optimizations in devices like mi, xiaomi, samsung, oppo, huawei, oneplus etc
1. [draggable_scrollbar](https://github.com/fluttercommunity/flutter-draggable-scrollbar) - A scrollbar that can be dragged for quickly navigation through a vertical list. Additional option is showing label next to scrollthumb with information about current item. 1. [draggable_scrollbar](https://github.com/fluttercommunity/flutter-draggable-scrollbar) - A scrollbar that can be dragged for quickly navigation through a vertical list. Additional option is showing label next to scrollthumb with information about current item.
1. [flutter_broadcasts](https://github.com/KRTirtho/flutter_broadcasts.git) - A plugin for sending and receiving broadcasts with Android intents and iOS notifications. 1. [flutter_broadcasts](https://github.com/KRTirtho/flutter_broadcasts.git) - A plugin for sending and receiving broadcasts with Android intents and iOS notifications.
1. [scrobblenaut](https://github.com/Nebulino/Scrobblenaut) - A deadly simple LastFM API Wrapper for Dart. So deadly simple that it's gonna hit the mark. 1. [scrobblenaut](https://github.com/Nebulino/Scrobblenaut) - A deadly simple LastFM API Wrapper for Dart. So deadly simple that it's gonna hit the mark.
1. [yt_dlp_dart](https://github.com/KRTirtho/yt_dlp_dart.git) - A starting point for Dart libraries or applications. 1. [yt_dlp_dart](https://github.com/KRTirtho/yt_dlp_dart.git) - yt-dlp binding in Dart
1. [flutter_new_pipe_extractor](https://github.com/KRTirtho/flutter_new_pipe_extractor) - NewPipeExtractor binding for Flutter (Android only) 1. [flutter_new_pipe_extractor](https://github.com/KRTirtho/flutter_new_pipe_extractor) - NewPipeExtractor binding for Flutter (Android only)
1. [hetu_std](https://github.com/hetu-community/hetu_std.git) - A sample command-line application.
1. [hetu_otp_util](https://github.com/hetu-community/hetu_otp_util.git) - A sample command-line application.
1. [hetu_spotube_plugin](https://github.com/KRTirtho/hetu_spotube_plugin) - A new Flutter package project.
1. [media_kit](https://github.com/media-kit/media-kit) - A cross-platform video player & audio player for Flutter & Dart. Performant, stable, feature-proof & modular.
1. [media_kit_libs_audio](https://github.com/media-kit/media-kit.git) - package:media_kit audio (only) playback native libraries for all platforms.
</details> </details>
<div align="center"><h4>© Copyright Spotube 2025</h4></div> <div align="center"><h4>© Copyright Spotube 2025</h4></div>

1
android/.gitignore vendored
View File

@ -11,4 +11,3 @@ GeneratedPluginRegistrant.java
key.properties key.properties
**/*.keystore **/*.keystore
**/*.jks **/*.jks
.kotlin

View File

@ -36,7 +36,7 @@ android {
compileSdkVersion 36 compileSdkVersion 36
ndkVersion = "29.0.14206865" ndkVersion = "27.0.12077973"
compileOptions { compileOptions {
coreLibraryDesugaringEnabled true coreLibraryDesugaringEnabled true

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -2,7 +2,9 @@ import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
import 'package:xml/xml.dart';
import '../../core/env.dart'; import '../../core/env.dart';
import 'common.dart'; import 'common.dart';
@ -22,6 +24,39 @@ class AndroidBuildCommand extends Command with BuildCommandCommonSteps {
"flutter build apk --flavor ${CliEnv.channel.name}", "flutter build apk --flavor ${CliEnv.channel.name}",
); );
await dotEnvFile.writeAsString(
"\nENABLE_UPDATE_CHECK=0"
"\nHIDE_DONATIONS=1",
mode: FileMode.append,
);
final androidManifestFile = File(
join(cwd.path, "android", "app", "src", "main", "AndroidManifest.xml"));
final androidManifestXml =
XmlDocument.parse(await androidManifestFile.readAsString());
final deletingElement =
androidManifestXml.findAllElements("meta-data").firstWhereOrNull(
(el) =>
el.getAttribute("android:name") ==
"com.google.android.gms.car.application",
);
deletingElement?.parent?.children.remove(deletingElement);
await androidManifestFile.writeAsString(
androidManifestXml.toXmlString(pretty: true),
);
await shell.run(
"""
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
flutter build appbundle --flavor ${CliEnv.channel.name}
""",
);
final ogApkFile = File( final ogApkFile = File(
join( join(
"build", "build",
@ -36,6 +71,22 @@ class AndroidBuildCommand extends Command with BuildCommandCommonSteps {
join(cwd.path, "build", "Spotube-android-all-arch.apk"), join(cwd.path, "build", "Spotube-android-all-arch.apk"),
); );
final ogAppbundleFile = File(
join(
cwd.path,
"build",
"app",
"outputs",
"bundle",
"${CliEnv.channel.name}Release",
"app-${CliEnv.channel.name}-release.aab",
),
);
await ogAppbundleFile.copy(
join(cwd.path, "build", "Spotube-playstore-all-arch.aab"),
);
stdout.writeln("✅ Built Android Apk and Appbundle"); stdout.writeln("✅ Built Android Apk and Appbundle");
} }
} }

View File

@ -59,7 +59,7 @@ mixin BuildCommandCommonSteps on Command {
""" """
flutter pub get flutter pub get
dart run build_runner build --delete-conflicting-outputs dart run build_runner build --delete-conflicting-outputs
dart pub global activate fastforge dart pub global activate flutter_distributor
""", """,
); );
} }

View File

@ -37,11 +37,12 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps {
await bootstrap(); await bootstrap();
await shell.run( await shell.run(
"fastforge package --platform=linux --targets=deb,appimage", "flutter_distributor package --platform=linux --targets=deb",
); );
if (architecture == "x86") { if (architecture == "x86") {
await shell.run( await shell.run(
"fastforge package --platform=linux --targets=rpm", "flutter_distributor package --platform=linux --targets=rpm",
); );
} }
@ -115,23 +116,6 @@ class LinuxBuildCommand extends Command with BuildCommandCommonSteps {
await ogRpm.delete(); await ogRpm.delete();
} }
final ogAppImage = File(
join(
cwd.path,
"dist",
pubspec.version.toString(),
"spotube-${pubspec.version}-linux.AppImage",
),
);
await ogAppImage.copy(
join(
cwd.path,
"dist",
"Spotube-linux-$bundleArchName.AppImage",
),
);
await ogAppImage.delete();
stdout.writeln("✅ Linux building done"); stdout.writeln("✅ Linux building done");
} }
} }

View File

@ -21,7 +21,7 @@ class MacosBuildCommand extends Command with BuildCommandCommonSteps {
""" """
flutter build macos flutter build macos
appdmg appdmg.json ${join(cwd.path, "build", "Spotube-macos-universal.dmg")} appdmg appdmg.json ${join(cwd.path, "build", "Spotube-macos-universal.dmg")}
fastforge package --platform=macos --targets pkg --skip-clean flutter_distributor package --platform=macos --targets pkg --skip-clean
""", """,
); );

View File

@ -61,7 +61,7 @@ class WindowsBuildCommand extends Command with BuildCommandCommonSteps {
); );
await shell.run( await shell.run(
"fastforge package --platform=windows --targets=exe --skip-clean", "flutter_distributor package --platform=windows --targets=exe --skip-clean",
); );
final ogExe = File( final ogExe = File(

View File

@ -37,8 +37,6 @@ class InstallDependenciesCommand extends Command {
FutureOr? run() async { FutureOr? run() async {
final shell = Shell(); final shell = Shell();
final arch = argResults?.option("arch") == "x86" ? "x86_64" : "aarch64";
switch (argResults!.option("platform")) { switch (argResults!.option("platform")) {
case "windows": case "windows":
await shell.run( await shell.run(
@ -51,10 +49,7 @@ class InstallDependenciesCommand extends Command {
await shell.run( await shell.run(
""" """
sudo apt-get update -y sudo apt-get update -y
sudo apt-get install -y wget tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev sudo apt-get install -y tar clang cmake ninja-build pkg-config libgtk-3-dev make python3-pip python3-setuptools desktop-file-utils libgdk-pixbuf2.0-dev fakeroot strace fuse libunwind-dev locate patchelf gir1.2-appindicator3-0.1 libappindicator3-1 libappindicator3-dev libsecret-1-0 libjsoncpp25 libsecret-1-dev libjsoncpp-dev libnotify-bin libnotify-dev mpv libmpv-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libsoup-3.0-0 libsoup-3.0-dev
wget -O appimagetool "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$arch.AppImage"
chmod +x appimagetool
sudo mv appimagetool /usr/local/bin/
""", """,
); );
break; break;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -66,19 +66,6 @@ class $AssetsImagesGen {
]; ];
} }
class $AssetsPluginsGen {
const $AssetsPluginsGen();
/// Directory path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz
$AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen
get spotubePluginMusicbrainzListenbrainz =>
const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen();
/// Directory path: assets/plugins/spotube-plugin-youtube-audio
$AssetsPluginsSpotubePluginYoutubeAudioGen get spotubePluginYoutubeAudio =>
const $AssetsPluginsSpotubePluginYoutubeAudioGen();
}
class $AssetsImagesLogosGen { class $AssetsImagesLogosGen {
const $AssetsImagesLogosGen(); const $AssetsImagesLogosGen();
@ -94,30 +81,13 @@ class $AssetsImagesLogosGen {
AssetGenImage get jiosaavn => AssetGenImage get jiosaavn =>
const AssetGenImage('assets/images/logos/jiosaavn.png'); const AssetGenImage('assets/images/logos/jiosaavn.png');
/// List of all assets /// File path: assets/images/logos/songlink-transparent.png
List<AssetGenImage> get values => [dabMusic, invidious, jiosaavn]; AssetGenImage get songlinkTransparent =>
} const AssetGenImage('assets/images/logos/songlink-transparent.png');
class $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen {
const $AssetsPluginsSpotubePluginMusicbrainzListenbrainzGen();
/// File path: assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug
String get plugin =>
'assets/plugins/spotube-plugin-musicbrainz-listenbrainz/plugin.smplug';
/// List of all assets /// List of all assets
List<String> get values => [plugin]; List<AssetGenImage> get values =>
} [dabMusic, invidious, jiosaavn, songlinkTransparent];
class $AssetsPluginsSpotubePluginYoutubeAudioGen {
const $AssetsPluginsSpotubePluginYoutubeAudioGen();
/// File path: assets/plugins/spotube-plugin-youtube-audio/plugin.smplug
String get plugin =>
'assets/plugins/spotube-plugin-youtube-audio/plugin.smplug';
/// List of all assets
List<String> get values => [plugin];
} }
class Assets { class Assets {
@ -126,7 +96,6 @@ class Assets {
static const String license = 'LICENSE'; static const String license = 'LICENSE';
static const $AssetsBrandingGen branding = $AssetsBrandingGen(); static const $AssetsBrandingGen branding = $AssetsBrandingGen();
static const $AssetsImagesGen images = $AssetsImagesGen(); static const $AssetsImagesGen images = $AssetsImagesGen();
static const $AssetsPluginsGen plugins = $AssetsPluginsGen();
/// List of all assets /// List of all assets
static List<String> get values => [license]; static List<String> get values => [license];

View File

@ -135,7 +135,7 @@ abstract class SpotubeIcons {
static const list = FeatherIcons.list; static const list = FeatherIcons.list;
static const device = FeatherIcons.smartphone; static const device = FeatherIcons.smartphone;
static const engine = FeatherIcons.server; static const engine = FeatherIcons.server;
static const extensions = Icons.extension_rounded; static const extensions = FeatherIcons.package;
static const message = FeatherIcons.send; static const message = FeatherIcons.send;
static const upload = FeatherIcons.uploadCloud; static const upload = FeatherIcons.uploadCloud;
static const plugin = Icons.extension_outlined; static const plugin = Icons.extension_outlined;

View File

@ -12,12 +12,13 @@ class ReplaceDownloadedDialog extends ConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final groupValue = ref.watch(replaceDownloadedFileState);
final replaceAll = ref.watch(replaceDownloadedFileState); final replaceAll = ref.watch(replaceDownloadedFileState);
return AlertDialog( return AlertDialog(
title: Text(context.l10n.track_exists(track.name)), title: Text(context.l10n.track_exists(track.name)),
content: RadioGroup( content: RadioGroup(
value: replaceAll, value: groupValue,
onChanged: (value) { onChanged: (value) {
ref.read(replaceDownloadedFileState.notifier).state = value; ref.read(replaceDownloadedFileState.notifier).state = value;
}, },

View File

@ -7,7 +7,8 @@ import 'package:spotube/extensions/constrains.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/extensions/duration.dart'; import 'package:spotube/extensions/duration.dart';
import 'package:spotube/models/metadata/metadata.dart'; import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/provider/server/sourced_track_provider.dart'; import 'package:spotube/models/playback/track_sources.dart';
import 'package:spotube/provider/server/track_sources.dart';
class TrackDetailsDialog extends HookConsumerWidget { class TrackDetailsDialog extends HookConsumerWidget {
final SpotubeFullTrackObject track; final SpotubeFullTrackObject track;
@ -20,7 +21,8 @@ class TrackDetailsDialog extends HookConsumerWidget {
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final theme = Theme.of(context); final theme = Theme.of(context);
final mediaQuery = MediaQuery.of(context); final mediaQuery = MediaQuery.of(context);
final sourcedTrack = ref.read(sourcedTrackProvider(track)); final sourcedTrack =
ref.read(trackSourcesProvider(TrackSourceQuery.fromTrack(track)));
final detailsMap = { final detailsMap = {
context.l10n.title: track.name, context.l10n.title: track.name,
@ -37,7 +39,8 @@ class TrackDetailsDialog extends HookConsumerWidget {
// style: const TextStyle(color: Colors.blue), // style: const TextStyle(color: Colors.blue),
// ), // ),
context.l10n.duration: sourcedTrack.asData != null context.l10n.duration: sourcedTrack.asData != null
? sourcedTrack.asData!.value.info.duration.toHumanReadableString() ? Duration(milliseconds: sourcedTrack.asData!.value.info.durationMs)
.toHumanReadableString()
: Duration(milliseconds: track.durationMs).toHumanReadableString(), : Duration(milliseconds: track.durationMs).toHumanReadableString(),
if (track.album.releaseDate != null) if (track.album.releaseDate != null)
context.l10n.released: track.album.releaseDate, context.l10n.released: track.album.releaseDate,
@ -54,7 +57,7 @@ class TrackDetailsDialog extends HookConsumerWidget {
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
context.l10n.channel: Text(sourceInfo.artists.join(", ")), context.l10n.channel: Text(sourceInfo.artists),
if (sourcedTrack.asData?.value.url != null) if (sourcedTrack.asData?.value.url != null)
context.l10n.streamUrl: Hyperlink( context.l10n.streamUrl: Hyperlink(
sourcedTrack.asData!.value.url ?? "", sourcedTrack.asData!.value.url ?? "",

View File

@ -8,10 +8,12 @@ import 'package:spotube/components/dialogs/playlist_add_track_dialog.dart';
import 'package:spotube/components/track_presentation/presentation_props.dart'; import 'package:spotube/components/track_presentation/presentation_props.dart';
import 'package:spotube/components/track_presentation/presentation_state.dart'; import 'package:spotube/components/track_presentation/presentation_state.dart';
import 'package:spotube/extensions/context.dart'; import 'package:spotube/extensions/context.dart';
import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/metadata/metadata.dart'; import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/provider/download_manager_provider.dart'; import 'package:spotube/provider/download_manager_provider.dart';
import 'package:spotube/provider/history/history.dart'; import 'package:spotube/provider/history/history.dart';
import 'package:spotube/provider/audio_player/audio_player.dart'; import 'package:spotube/provider/audio_player/audio_player.dart';
import 'package:spotube/provider/user_preferences/user_preferences_provider.dart';
ToastOverlay showToastForAction( ToastOverlay showToastForAction(
BuildContext context, BuildContext context,
@ -68,6 +70,8 @@ class TrackPresentationActionsSection extends HookConsumerWidget {
final downloader = ref.watch(downloadManagerProvider.notifier); final downloader = ref.watch(downloadManagerProvider.notifier);
final playlistNotifier = ref.watch(audioPlayerProvider.notifier); final playlistNotifier = ref.watch(audioPlayerProvider.notifier);
final historyNotifier = ref.watch(playbackHistoryActionsProvider); final historyNotifier = ref.watch(playbackHistoryActionsProvider);
final audioSource =
ref.watch(userPreferencesProvider.select((s) => s.audioSource));
final state = ref.watch(presentationStateProvider(options.collection)); final state = ref.watch(presentationStateProvider(options.collection));
final notifier = final notifier =
@ -81,15 +85,16 @@ class TrackPresentationActionsSection extends HookConsumerWidget {
}) async { }) async {
final fullTrackObjects = final fullTrackObjects =
tracks.whereType<SpotubeFullTrackObject>().toList(); tracks.whereType<SpotubeFullTrackObject>().toList();
final confirmed = await showDialog<bool>( final confirmed = audioSource == AudioSource.piped ||
context: context, (await showDialog<bool>(
builder: (context) { context: context,
return const ConfirmDownloadDialog(); builder: (context) {
}, return const ConfirmDownloadDialog();
) ?? },
false; ) ??
false);
if (confirmed != true) return; if (confirmed != true) return;
downloader.addAllToQueue(fullTrackObjects); downloader.batchAddToQueue(fullTrackObjects);
notifier.deselectAllTracks(); notifier.deselectAllTracks();
if (!context.mounted) return; if (!context.mounted) return;
showToastForAction(context, action, fullTrackObjects.length); showToastForAction(context, action, fullTrackObjects.length);

View File

@ -1,7 +1,10 @@
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:shadcn_flutter/shadcn_flutter.dart'; import 'package:shadcn_flutter/shadcn_flutter.dart';
import 'package:shadcn_flutter/shadcn_flutter_extension.dart'; import 'package:shadcn_flutter/shadcn_flutter_extension.dart';
import 'package:spotube/collections/assets.gen.dart';
import 'package:spotube/collections/routes.dart'; import 'package:spotube/collections/routes.dart';
import 'package:spotube/collections/spotube_icons.dart'; import 'package:spotube/collections/spotube_icons.dart';
import 'package:spotube/components/ui/button_tile.dart'; import 'package:spotube/components/ui/button_tile.dart';
@ -33,6 +36,7 @@ class TrackOptions extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, ref) { Widget build(BuildContext context, ref) {
final mediaQuery = MediaQuery.of(context); final mediaQuery = MediaQuery.of(context);
final ThemeData(:colorScheme) = Theme.of(context);
final trackOptionActions = ref.watch(trackOptionActionsProvider(track)); final trackOptionActions = ref.watch(trackOptionActionsProvider(track));
final ( final (
@ -42,7 +46,7 @@ class TrackOptions extends HookConsumerWidget {
:isActiveTrack, :isActiveTrack,
:isAuthenticated, :isAuthenticated,
:isLiked, :isLiked,
:downloadTask :progressNotifier
) = ref.watch(trackOptionsStateProvider(track)); ) = ref.watch(trackOptionsStateProvider(track));
final isLocalTrack = track is SpotubeLocalTrackObject; final isLocalTrack = track is SpotubeLocalTrackObject;
@ -209,19 +213,12 @@ class TrackOptions extends HookConsumerWidget {
}, },
enabled: !isInDownloadQueue, enabled: !isInDownloadQueue,
leading: isInDownloadQueue leading: isInDownloadQueue
? StreamBuilder( ? HookBuilder(builder: (context) {
stream: downloadTask?.downloadedBytesStream, final progress = useListenable(progressNotifier);
builder: (context, snapshot) { return CircularProgressIndicator(
final progress = downloadTask?.totalSizeBytes == null || value: progress?.value,
downloadTask?.totalSizeBytes == 0 );
? 0 })
: (snapshot.data ?? 0) /
downloadTask!.totalSizeBytes!;
return CircularProgressIndicator(
value: progress.toDouble(),
);
},
)
: const Icon(SpotubeIcons.download), : const Icon(SpotubeIcons.download),
title: Text(context.l10n.download_track), title: Text(context.l10n.download_track),
), ),
@ -263,6 +260,24 @@ class TrackOptions extends HookConsumerWidget {
leading: const Icon(SpotubeIcons.share), leading: const Icon(SpotubeIcons.share),
title: Text(context.l10n.share), title: Text(context.l10n.share),
), ),
if (!isLocalTrack)
ButtonTile(
style: ButtonVariance.menu,
onPressed: () async {
await trackOptionActions.action(
rootNavigatorKey.currentContext!,
TrackOptionValue.songlink,
playlistId,
);
onTapItem?.call();
},
leading: Assets.images.logos.songlinkTransparent.image(
width: 22,
height: 22,
color: colorScheme.foreground.withValues(alpha: 0.5),
),
title: Text(context.l10n.song_link),
),
if (!isLocalTrack) if (!isLocalTrack)
ButtonTile( ButtonTile(
style: ButtonVariance.menu, style: ButtonVariance.menu,

View File

@ -39,7 +39,6 @@ class TrackTile extends HookConsumerWidget {
final int? index; final int? index;
final SpotubeTrackObject track; final SpotubeTrackObject track;
final bool selected; final bool selected;
final bool selectionMode;
final ValueChanged<bool?>? onChanged; final ValueChanged<bool?>? onChanged;
final Future<void> Function()? onTap; final Future<void> Function()? onTap;
final VoidCallback? onLongPress; final VoidCallback? onLongPress;
@ -54,7 +53,6 @@ class TrackTile extends HookConsumerWidget {
this.index, this.index,
required this.track, required this.track,
this.selected = false, this.selected = false,
this.selectionMode = false,
required this.playlist, required this.playlist,
this.onTap, this.onTap,
this.onLongPress, this.onLongPress,
@ -83,12 +81,6 @@ class TrackTile extends HookConsumerWidget {
[track.album.images], [track.album.images],
); );
// Treat either explicit selectionMode or presence of onChanged as selection
// context. Some lists enable selection by providing `onChanged` without
// toggling a dedicated `selectionMode` flag (e.g. playlists), so we must
// disable inner navigation in both cases.
final effectiveSelection = selectionMode || onChanged != null;
return LayoutBuilder(builder: (context, constrains) { return LayoutBuilder(builder: (context, constrains) {
return Listener( return Listener(
onPointerDown: (event) { onPointerDown: (event) {
@ -230,9 +222,7 @@ class TrackTile extends HookConsumerWidget {
children: [ children: [
Expanded( Expanded(
flex: 6, flex: 6,
child: AbsorbPointer( child: switch (track) {
absorbing: selectionMode,
child: switch (track) {
SpotubeLocalTrackObject() => Text( SpotubeLocalTrackObject() => Text(
track.name, track.name,
maxLines: 1, maxLines: 1,
@ -242,17 +232,15 @@ class TrackTile extends HookConsumerWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Flexible( Flexible(
child: Button( child: Button(
style: ButtonVariance.link.copyWith( style: ButtonVariance.link.copyWith(
padding: (context, states, value) => padding: (context, states, value) =>
EdgeInsets.zero, EdgeInsets.zero,
), ),
onPressed: effectiveSelection onPressed: () {
? null context
: () { .navigateTo(TrackRoute(trackId: track.id));
context },
.navigateTo(TrackRoute(trackId: track.id));
},
child: Text( child: Text(
track.name, track.name,
maxLines: 1, maxLines: 1,
@ -263,7 +251,6 @@ class TrackTile extends HookConsumerWidget {
], ],
), ),
}, },
),
), ),
if (constrains.mdAndUp) ...[ if (constrains.mdAndUp) ...[
const SizedBox(width: 8), const SizedBox(width: 8),
@ -294,25 +281,20 @@ class TrackTile extends HookConsumerWidget {
), ),
subtitle: Align( subtitle: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: track is SpotubeLocalTrackObject child: track is SpotubeLocalTrackObject
? Text( ? Text(
track.artists.asString(), track.artists.asString(),
) )
: ClipRect( : ClipRect(
child: ConstrainedBox( child: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 40), constraints: const BoxConstraints(maxHeight: 40),
child: AbsorbPointer( child: ArtistLink(
absorbing: effectiveSelection, artists: track.artists,
child: ArtistLink( onOverflowArtistClick: () {
artists: track.artists, context.navigateTo(
onOverflowArtistClick: effectiveSelection TrackRoute(trackId: track.id),
? () {} );
: () { },
context.navigateTo(
TrackRoute(trackId: track.id),
);
},
),
), ),
), ),
), ),

View File

@ -1,168 +0,0 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
extension ChunkDownloaderDioExtension on Dio {
Future<Response> chunkDownload(
String urlPath,
dynamic savePath, {
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
bool deleteOnError = true,
FileAccessMode fileAccessMode = FileAccessMode.write,
String lengthHeader = Headers.contentLengthHeader,
Object? data,
Options? options,
int connections = 4,
}) async {
final targetFile = File(savePath.toString());
final tempRootDir = await getTemporaryDirectory();
final tempSaveDir = Directory(
join(
tempRootDir.path,
'Spotube',
'.chunk_dl_${targetFile.uri.pathSegments.last}',
),
);
if (await tempSaveDir.exists()) await tempSaveDir.delete(recursive: true);
await tempSaveDir.create(recursive: true);
try {
int? totalLength;
bool supportsRange = false;
Response? headResp;
try {
headResp = await head(
urlPath,
queryParameters: queryParameters,
options: Options(
headers: {'Range': 'bytes=0-0'},
followRedirects: true,
),
);
} catch (_) {
// Some servers reject HEAD -> ignore
}
final lengthStr = headResp?.headers[lengthHeader]?.first;
if (lengthStr != null) {
final parsed = int.tryParse(lengthStr);
if (parsed != null && parsed > 1) {
totalLength = parsed;
}
}
supportsRange = headResp?.statusCode == 206 ||
headResp?.headers.value(HttpHeaders.acceptRangesHeader) == 'bytes';
if (totalLength == null || totalLength <= 1) {
final resp = await get<ResponseBody>(
urlPath,
options: Options(
responseType: ResponseType.stream,
),
queryParameters: queryParameters,
cancelToken: cancelToken,
);
final len = int.tryParse(resp.headers[lengthHeader]?.first ?? '');
if (len == null || len <= 1) {
// cant safely chunk fallback
return download(
urlPath,
savePath,
onReceiveProgress: onReceiveProgress,
queryParameters: queryParameters,
cancelToken: cancelToken,
deleteOnError: deleteOnError,
options: options,
data: data,
);
}
totalLength = len;
supportsRange =
resp.headers.value(HttpHeaders.acceptRangesHeader)?.toLowerCase() ==
'bytes';
}
if (!supportsRange || connections <= 1) {
return download(
urlPath,
savePath,
onReceiveProgress: onReceiveProgress,
queryParameters: queryParameters,
cancelToken: cancelToken,
deleteOnError: deleteOnError,
options: options,
data: data,
);
}
final chunkSize = (totalLength / connections).ceil();
int downloaded = 0;
final partFiles = List.generate(
connections,
(i) => File(join(tempSaveDir.path, 'part_$i')),
);
final futures = List.generate(connections, (i) async {
final start = i * chunkSize;
final end = (i + 1) * chunkSize - 1;
if (start >= totalLength!) return;
final resp = await get<ResponseBody>(
urlPath,
options: Options(
responseType: ResponseType.stream,
headers: {'Range': 'bytes=$start-$end'},
),
queryParameters: queryParameters,
cancelToken: cancelToken,
);
final file = partFiles[i];
if (await file.exists()) await file.delete();
await file.create(recursive: true);
final sink = file.openWrite();
await for (final chunk in resp.data!.stream) {
sink.add(chunk);
downloaded += chunk.length;
onReceiveProgress?.call(downloaded, totalLength);
}
await sink.close();
});
await Future.wait(futures);
final targetSink = targetFile.openWrite();
for (final f in partFiles) {
await targetSink.addStream(f.openRead());
}
await targetSink.close();
await tempSaveDir.delete(recursive: true);
return Response(
requestOptions: RequestOptions(path: urlPath),
data: targetFile,
statusCode: 200,
statusMessage: 'Chunked download completed ($connections connections)',
);
} catch (e) {
if (deleteOnError) {
if (await targetFile.exists()) await targetFile.delete();
if (await tempSaveDir.exists()) {
await tempSaveDir.delete(recursive: true);
}
}
rethrow;
}
}
}

View File

@ -477,18 +477,5 @@
"available_plugins": "الإضافات المتوفّرة", "available_plugins": "الإضافات المتوفّرة",
"configure_your_own_metadata_plugin": "تهيئة مزوّد بيانات للقائمة/الألبوم/الفنان/المصدر خاص بك", "configure_your_own_metadata_plugin": "تهيئة مزوّد بيانات للقائمة/الألبوم/الفنان/المصدر خاص بك",
"audio_scrobblers": "أجهزة تتبع الصوت", "audio_scrobblers": "أجهزة تتبع الصوت",
"scrobbling": "التتبع", "scrobbling": "التتبع"
"download_music_format": "تنسيق تنزيل الموسيقى",
"streaming_music_format": "تنسيق بث الموسيقى",
"download_music_quality": "جودة تنزيل الموسيقى",
"streaming_music_quality": "جودة بث الموسيقى",
"default_metadata_source": "مصدر البيانات الوصفية الافتراضي",
"set_default_metadata_source": "تعيين مصدر البيانات الوصفية الافتراضي",
"default_audio_source": "مصدر الصوت الافتراضي",
"set_default_audio_source": "تعيين مصدر الصوت الافتراضي",
"plugins": "الإضافات",
"configure_plugins": "قم بتكوين مزود البيانات الوصفية ومكونات مصدر الصوت الخاصة بك",
"source": "المصدر: ",
"uncompressed": "غير مضغوط",
"dab_music_source_description": "لمحبي الصوتيات. يوفر تدفقات صوتية عالية الجودة/بدون فقدان. مطابقة دقيقة للمسارات بناءً على ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "উপলব্ধ প্লাগইনগুলো", "available_plugins": "উপলব্ধ প্লাগইনগুলো",
"configure_your_own_metadata_plugin": "নিজস্ব প্লেলিস্ট/অ্যালবাম/শিল্পী/ফিড মেটাডেটা প্রদানকারী কনফিগার করুন", "configure_your_own_metadata_plugin": "নিজস্ব প্লেলিস্ট/অ্যালবাম/শিল্পী/ফিড মেটাডেটা প্রদানকারী কনফিগার করুন",
"audio_scrobblers": "অডিও স্ক্রোব্বলার্স", "audio_scrobblers": "অডিও স্ক্রোব্বলার্স",
"scrobbling": "স্ক্রোব্বলিং", "scrobbling": "স্ক্রোব্বলিং"
"download_music_format": "গান ডাউনলোডের বিন্যাস",
"streaming_music_format": "গান স্ট্রিমিং এর বিন্যাস",
"download_music_quality": "গান ডাউনলোডের মান",
"streaming_music_quality": "গান স্ট্রিমিং এর মান",
"default_metadata_source": "ডিফল্ট মেটাডেটা উৎস",
"set_default_metadata_source": "ডিফল্ট মেটাডেটা উৎস সেট করুন",
"default_audio_source": "ডিফল্ট অডিও উৎস",
"set_default_audio_source": "ডিফল্ট অডিও উৎস সেট করুন",
"plugins": "প্লাগইন",
"configure_plugins": "আপনার নিজের মেটাডেটা প্রদানকারী এবং অডিও উৎস প্লাগইন কনফিগার করুন",
"source": "উৎস: ",
"uncompressed": "অ-সংকুচিত",
"dab_music_source_description": "অডিওফাইলদের জন্য। উচ্চ-মানের/লসলেস অডিও স্ট্রিম প্রদান করে। সঠিক ISRC ভিত্তিক ট্র্যাক ম্যাচিং।"
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Complements disponibles", "available_plugins": "Complements disponibles",
"configure_your_own_metadata_plugin": "Configura el teu propi proveïdor de metadades per llistes/reproduccions àlbum/artista/flux", "configure_your_own_metadata_plugin": "Configura el teu propi proveïdor de metadades per llistes/reproduccions àlbum/artista/flux",
"audio_scrobblers": "Scrobblers dàudio", "audio_scrobblers": "Scrobblers dàudio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Format de descàrrega de música",
"streaming_music_format": "Format de reproducció de música en temps real",
"download_music_quality": "Qualitat de descàrrega de música",
"streaming_music_quality": "Qualitat de reproducció de música en temps real",
"default_metadata_source": "Font de metadades per defecte",
"set_default_metadata_source": "Estableix la font de metadades per defecte",
"default_audio_source": "Font d'àudio per defecte",
"set_default_audio_source": "Estableix la font d'àudio per defecte",
"plugins": "Connectors",
"configure_plugins": "Configura els teus propis connectors de proveïdor de metadades i de font d'àudio",
"source": "Font: ",
"uncompressed": "Sense comprimir",
"dab_music_source_description": "Per als audiòfils. Ofereix fluxos d'àudio d'alta qualitat/sense pèrdua. Coincidència precisa de pistes basada en ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Dostupné pluginy", "available_plugins": "Dostupné pluginy",
"configure_your_own_metadata_plugin": "Nakonfigurujte si vlastního poskytovatele metadat pro playlist/album/umělec/fid", "configure_your_own_metadata_plugin": "Nakonfigurujte si vlastního poskytovatele metadat pro playlist/album/umělec/fid",
"audio_scrobblers": "Audio scrobblers", "audio_scrobblers": "Audio scrobblers",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Formát stahování hudby",
"streaming_music_format": "Formát streamování hudby",
"download_music_quality": "Kvalita stahování hudby",
"streaming_music_quality": "Kvalita streamování hudby",
"default_metadata_source": "Výchozí zdroj metadat",
"set_default_metadata_source": "Nastavit výchozí zdroj metadat",
"default_audio_source": "Výchozí zdroj zvuku",
"set_default_audio_source": "Nastavit výchozí zdroj zvuku",
"plugins": "Pluginy",
"configure_plugins": "Konfigurujte své vlastní pluginy poskytovatele metadat a zdroje zvuku",
"source": "Zdroj: ",
"uncompressed": "Nekomprimováno",
"dab_music_source_description": "Pro audiofily. Poskytuje vysoce kvalitní/bezztrátové zvukové toky. Přesná shoda skladeb na základě ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Verfügbare Plugins", "available_plugins": "Verfügbare Plugins",
"configure_your_own_metadata_plugin": "Eigenen Anbieter für Playlist-/Album-/Künstler-/Feed-Metadaten konfigurieren", "configure_your_own_metadata_plugin": "Eigenen Anbieter für Playlist-/Album-/Künstler-/Feed-Metadaten konfigurieren",
"audio_scrobblers": "Audio-Scrobbler", "audio_scrobblers": "Audio-Scrobbler",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Musik-Downloadformat",
"streaming_music_format": "Musik-Streamingformat",
"download_music_quality": "Musik-Downloadqualität",
"streaming_music_quality": "Musik-Streamingqualität",
"default_metadata_source": "Standard-Metadatenquelle",
"set_default_metadata_source": "Standard-Metadatenquelle festlegen",
"default_audio_source": "Standard-Audioquelle",
"set_default_audio_source": "Standard-Audioquelle festlegen",
"plugins": "Plugins",
"configure_plugins": "Richte deine eigenen Metadatenanbieter- und Audioquellen-Plugins ein",
"source": "Quelle: ",
"uncompressed": "Unkomprimiert",
"dab_music_source_description": "Für Audiophile. Bietet hochwertige/verlustfreie Audiostreams. Präzises ISRC-basiertes Track-Matching."
} }

View File

@ -264,10 +264,8 @@
"change_cover": "Change cover", "change_cover": "Change cover",
"add_cover": "Add cover", "add_cover": "Add cover",
"restore_defaults": "Restore defaults", "restore_defaults": "Restore defaults",
"download_music_format": "Download music format", "download_music_codec": "Download music codec",
"streaming_music_format": "Streaming music format", "streaming_music_codec": "Streaming music codec",
"download_music_quality": "Download music quality",
"streaming_music_quality": "Streaming music quality",
"login_with_lastfm": "Login with Last.fm", "login_with_lastfm": "Login with Last.fm",
"connect": "Connect", "connect": "Connect",
"disconnect_lastfm": "Disconnect Last.fm", "disconnect_lastfm": "Disconnect Last.fm",
@ -436,10 +434,7 @@
"update_available": "Update available", "update_available": "Update available",
"supports_scrobbling": "Supports scrobbling", "supports_scrobbling": "Supports scrobbling",
"plugin_scrobbling_info": "This plugin scrobbles your music to generate your listening history.", "plugin_scrobbling_info": "This plugin scrobbles your music to generate your listening history.",
"default_metadata_source": "Default metadata source", "default_plugin": "Default",
"set_default_metadata_source": "Set default metadata source",
"default_audio_source": "Default audio source",
"set_default_audio_source": "Set default audio source",
"set_default": "Set default", "set_default": "Set default",
"support": "Support", "support": "Support",
"support_plugin_development": "Support plugin development", "support_plugin_development": "Support plugin development",
@ -457,14 +452,14 @@
"disclaimer": "Disclaimer", "disclaimer": "Disclaimer",
"third_party_plugin_dmca_notice": "The Spotube team does not hold any responsibility (including legal) for any \"Third-party\" plugins.\nPlease use them at your own risk. For any bugs/issues, please report them to the plugin repository.\n\nIf any \"Third-party\" plugin is breaking ToS/DMCA of any service/legal entity, please ask the \"Third-party\" plugin author or the hosting platform .e.g GitHub/Codeberg to take action. Above listed (\"Third-party\" labelled) are all public/community maintained plugins. We're not curating them, so we cannot take any action on them.\n\n", "third_party_plugin_dmca_notice": "The Spotube team does not hold any responsibility (including legal) for any \"Third-party\" plugins.\nPlease use them at your own risk. For any bugs/issues, please report them to the plugin repository.\n\nIf any \"Third-party\" plugin is breaking ToS/DMCA of any service/legal entity, please ask the \"Third-party\" plugin author or the hosting platform .e.g GitHub/Codeberg to take action. Above listed (\"Third-party\" labelled) are all public/community maintained plugins. We're not curating them, so we cannot take any action on them.\n\n",
"input_does_not_match_format": "Input doesn't match the required format", "input_does_not_match_format": "Input doesn't match the required format",
"plugins": "Plugins", "metadata_provider_plugins": "Metadata Provider Plugins",
"paste_plugin_download_url": "Paste download url or GitHub/Codeberg repo url or direct link to .smplug file", "paste_plugin_download_url": "Paste download url or GitHub/Codeberg repo url or direct link to .smplug file",
"download_and_install_plugin_from_url": "Download and install plugin from url", "download_and_install_plugin_from_url": "Download and install plugin from url",
"failed_to_add_plugin_error": "Failed to add plugin: {error}", "failed_to_add_plugin_error": "Failed to add plugin: {error}",
"upload_plugin_from_file": "Upload plugin from file", "upload_plugin_from_file": "Upload plugin from file",
"installed": "Installed", "installed": "Installed",
"available_plugins": "Available plugins", "available_plugins": "Available plugins",
"configure_plugins": "Configure your own metadata provider and audio source plugins", "configure_your_own_metadata_plugin": "Configure your own playlist/album/artist/feed metadata provider",
"audio_scrobblers": "Audio Scrobblers", "audio_scrobblers": "Audio Scrobblers",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling",
"source": "Source: ", "source": "Source: ",

View File

@ -477,18 +477,5 @@
"available_plugins": "Complementos disponibles", "available_plugins": "Complementos disponibles",
"configure_your_own_metadata_plugin": "Configura tu propio proveedor de metadatos para listas/álbum/artista/feeds", "configure_your_own_metadata_plugin": "Configura tu propio proveedor de metadatos para listas/álbum/artista/feeds",
"audio_scrobblers": "Scrobblers de audio", "audio_scrobblers": "Scrobblers de audio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Formato de descarga de música",
"streaming_music_format": "Formato de transmisión de música",
"download_music_quality": "Calidad de descarga de música",
"streaming_music_quality": "Calidad de transmisión de música",
"default_metadata_source": "Fuente de metadatos predeterminada",
"set_default_metadata_source": "Establecer fuente de metadatos predeterminada",
"default_audio_source": "Fuente de audio predeterminada",
"set_default_audio_source": "Establecer fuente de audio predeterminada",
"plugins": "Plugins",
"configure_plugins": "Configura tus propios plugins de proveedor de metadatos y fuente de audio",
"source": "Fuente: ",
"uncompressed": "Sin comprimir",
"dab_music_source_description": "Para audiófilos. Proporciona transmisiones de audio de alta calidad/sin pérdida. Coincidencia precisa de pistas basada en ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Eskaintzen diren pluginak", "available_plugins": "Eskaintzen diren pluginak",
"configure_your_own_metadata_plugin": "Konfiguratu zureko playlists-/album-/artista-/feed-metadaten hornitzailea", "configure_your_own_metadata_plugin": "Konfiguratu zureko playlists-/album-/artista-/feed-metadaten hornitzailea",
"audio_scrobblers": "Audio scrobbler-ak", "audio_scrobblers": "Audio scrobbler-ak",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Musika deskargatzeko formatua",
"streaming_music_format": "Musika streaming bidezko formatua",
"download_music_quality": "Musika deskargaren kalitatea",
"streaming_music_quality": "Streaming bidezko musika kalitatea",
"default_metadata_source": "Metadatu-iturburu lehenetsia",
"set_default_metadata_source": "Ezarri metadatu-iturburu lehenetsia",
"default_audio_source": "Audio-iturburu lehenetsia",
"set_default_audio_source": "Ezarri audio-iturburu lehenetsia",
"plugins": "Pluginak",
"configure_plugins": "Konfiguratu zure metadatu-hornitzaile eta audio-iturburu pluginak",
"source": "Iturburua: ",
"uncompressed": "Konprimitu gabea",
"dab_music_source_description": "Audiozaleentzat. Kalitate handiko/galerarik gabeko audio-streamak eskaintzen ditu. ISRC oinarritutako pistaren parekatze zehatza."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "افزونه‌های موجود", "available_plugins": "افزونه‌های موجود",
"configure_your_own_metadata_plugin": "پیکربندی ارائه‌دهندهٔ متادیتا برای پلی‌لیست/آلبوم/هنرمند/فید به‌صورت سفارشی", "configure_your_own_metadata_plugin": "پیکربندی ارائه‌دهندهٔ متادیتا برای پلی‌لیست/آلبوم/هنرمند/فید به‌صورت سفارشی",
"audio_scrobblers": "اسکراب‌بلرهای صوتی", "audio_scrobblers": "اسکراب‌بلرهای صوتی",
"scrobbling": "اسکراب‌بلینگ", "scrobbling": "اسکراب‌بلینگ"
"download_music_format": "فرمت دانلود موسیقی",
"streaming_music_format": "فرمت پخش آنلاین موسیقی",
"download_music_quality": "کیفیت دانلود موسیقی",
"streaming_music_quality": "کیفیت پخش آنلاین موسیقی",
"default_metadata_source": "منبع پیش‌فرض فراداده",
"set_default_metadata_source": "تنظیم منبع پیش‌فرض فراداده",
"default_audio_source": "منبع پیش‌فرض صوت",
"set_default_audio_source": "تنظیم منبع پیش‌فرض صوت",
"plugins": "افزونه‌ها",
"configure_plugins": "افزونه‌های منبع صوت و ارائه‌دهنده فراداده خود را پیکربندی کنید",
"source": "منبع: ",
"uncompressed": "بدون فشرده‌سازی",
"dab_music_source_description": "مخصوص علاقه‌مندان صدا. ارائه‌دهنده استریم‌های باکیفیت/بدون افت. تطبیق دقیق آهنگ بر اساس ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Saatavilla olevat lisäosat", "available_plugins": "Saatavilla olevat lisäosat",
"configure_your_own_metadata_plugin": "Määritä oma soittolistan/albumin/artistin/syötteen metatietojen tarjoaja", "configure_your_own_metadata_plugin": "Määritä oma soittolistan/albumin/artistin/syötteen metatietojen tarjoaja",
"audio_scrobblers": "Äänen scrobblerit", "audio_scrobblers": "Äänen scrobblerit",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Musiikin latausmuoto",
"streaming_music_format": "Musiikin suoratoistomuoto",
"download_music_quality": "Musiikin latauslaatu",
"streaming_music_quality": "Musiikin suoratoistolaadun",
"default_metadata_source": "Oletusarvoinen metatietolähde",
"set_default_metadata_source": "Aseta oletusmetatietolähde",
"default_audio_source": "Oletusarvoinen äänilähde",
"set_default_audio_source": "Aseta oletusäänilähde",
"plugins": "Laajennukset",
"configure_plugins": "Määritä omat metatietojen tarjoaja- ja äänilähdelaajennukset",
"source": "Lähde: ",
"uncompressed": "Pakkaamaton",
"dab_music_source_description": "Audiofiileille. Tarjoaa korkealaatuisia/häviöttömiä äänivirtoja. Tarkka ISRC-pohjainen kappaleiden tunnistus."
} }

View File

@ -478,18 +478,5 @@
"available_plugins": "Plugins disponibles", "available_plugins": "Plugins disponibles",
"configure_your_own_metadata_plugin": "Configurer votre propre fournisseur de métadonnées de playlist/album/artiste/flux", "configure_your_own_metadata_plugin": "Configurer votre propre fournisseur de métadonnées de playlist/album/artiste/flux",
"audio_scrobblers": "Scrobblers audio", "audio_scrobblers": "Scrobblers audio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Format de téléchargement de musique",
"streaming_music_format": "Format de streaming de musique",
"download_music_quality": "Qualité de téléchargement de musique",
"streaming_music_quality": "Qualité de streaming de musique",
"default_metadata_source": "Source de métadonnées par défaut",
"set_default_metadata_source": "Définir la source de métadonnées par défaut",
"default_audio_source": "Source audio par défaut",
"set_default_audio_source": "Définir la source audio par défaut",
"plugins": "Plugins",
"configure_plugins": "Configurez vos propres plugins de fournisseur de métadonnées et de source audio",
"source": "Source : ",
"uncompressed": "Non compressé",
"dab_music_source_description": "Pour les audiophiles. Fournit des flux audio de haute qualité/sans perte. Correspondance précise des pistes basée sur ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "उपलब्ध प्लगइन", "available_plugins": "उपलब्ध प्लगइन",
"configure_your_own_metadata_plugin": "अपनी खुद की प्लेलिस्ट/एल्बम/कलाकार/फ़ीड मेटाडेटा प्रदाता कॉन्फ़िगर करें", "configure_your_own_metadata_plugin": "अपनी खुद की प्लेलिस्ट/एल्बम/कलाकार/फ़ीड मेटाडेटा प्रदाता कॉन्फ़िगर करें",
"audio_scrobblers": "ऑडियो स्क्रॉबलर्स", "audio_scrobblers": "ऑडियो स्क्रॉबलर्स",
"scrobbling": "स्क्रॉबलिंग", "scrobbling": "स्क्रॉबलिंग"
"download_music_format": "संगीत डाउनलोड प्रारूप",
"streaming_music_format": "संगीत स्ट्रीमिंग प्रारूप",
"download_music_quality": "संगीत डाउनलोड गुणवत्ता",
"streaming_music_quality": "संगीत स्ट्रीमिंग गुणवत्ता",
"default_metadata_source": "डिफ़ॉल्ट मेटाडेटा स्रोत",
"set_default_metadata_source": "डिफ़ॉल्ट मेटाडेटा स्रोत सेट करें",
"default_audio_source": "डिफ़ॉल्ट ऑडियो स्रोत",
"set_default_audio_source": "डिफ़ॉल्ट ऑडियो स्रोत सेट करें",
"plugins": "प्लगइन्स",
"configure_plugins": "अपने स्वयं के मेटाडेटा प्रदाता और ऑडियो स्रोत प्लगइन्स कॉन्फ़िगर करें",
"source": "स्रोत: ",
"uncompressed": "असंपीड़ित",
"dab_music_source_description": "ऑडियोफाइलों के लिए। उच्च-गुणवत्ता/बिना हानि वाले ऑडियो स्ट्रीम प्रदान करता है। सटीक ISRC आधारित ट्रैक मिलान।"
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Plugin yang tersedia", "available_plugins": "Plugin yang tersedia",
"configure_your_own_metadata_plugin": "Konfigurasi penyedia metadata playlist/album/artis/feed Anda sendiri", "configure_your_own_metadata_plugin": "Konfigurasi penyedia metadata playlist/album/artis/feed Anda sendiri",
"audio_scrobblers": "Scrobblers Audio", "audio_scrobblers": "Scrobblers Audio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Format unduh musik",
"streaming_music_format": "Format streaming musik",
"download_music_quality": "Kualitas unduh musik",
"streaming_music_quality": "Kualitas streaming musik",
"default_metadata_source": "Sumber metadata default",
"set_default_metadata_source": "Atur sumber metadata default",
"default_audio_source": "Sumber audio default",
"set_default_audio_source": "Atur sumber audio default",
"plugins": "Plugin",
"configure_plugins": "Konfigurasi plugin penyedia metadata dan sumber audio Anda sendiri",
"source": "Sumber: ",
"uncompressed": "Tidak terkompresi",
"dab_music_source_description": "Untuk audiophile. Menyediakan aliran audio berkualitas tinggi/tanpa kehilangan. Pencocokkan trek yang akurat berdasarkan ISRC."
} }

View File

@ -478,18 +478,5 @@
"available_plugins": "Plugin disponibili", "available_plugins": "Plugin disponibili",
"configure_your_own_metadata_plugin": "Configura il tuo provider di metadati per playlist/album/artista/feed", "configure_your_own_metadata_plugin": "Configura il tuo provider di metadati per playlist/album/artista/feed",
"audio_scrobblers": "Scrobbler audio", "audio_scrobblers": "Scrobbler audio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Formato download musica",
"streaming_music_format": "Formato streaming musica",
"download_music_quality": "Qualità download musica",
"streaming_music_quality": "Qualità streaming musica",
"default_metadata_source": "Fonte metadati predefinita",
"set_default_metadata_source": "Imposta fonte metadati predefinita",
"default_audio_source": "Fonte audio predefinita",
"set_default_audio_source": "Imposta fonte audio predefinita",
"plugins": "Plugin",
"configure_plugins": "Configura i tuoi plugin per fornitore metadati e fonte audio",
"source": "Fonte: ",
"uncompressed": "Non compresso",
"dab_music_source_description": "Per audiophile. Fornisce flussi audio di alta qualità/senza perdita. Abbinamento traccia accurato basato su ISRC."
} }

View File

@ -476,18 +476,5 @@
"available_plugins": "利用可能なプラグイン", "available_plugins": "利用可能なプラグイン",
"configure_your_own_metadata_plugin": "独自のプレイリスト/アルバム/アーティスト/フィードのメタデータプロバイダーを構成", "configure_your_own_metadata_plugin": "独自のプレイリスト/アルバム/アーティスト/フィードのメタデータプロバイダーを構成",
"audio_scrobblers": "オーディオスクロッブラー", "audio_scrobblers": "オーディオスクロッブラー",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "音楽ダウンロード形式",
"streaming_music_format": "音楽ストリーミング形式",
"download_music_quality": "音楽ダウンロード品質",
"streaming_music_quality": "音楽ストリーミング品質",
"default_metadata_source": "デフォルトメタデータソース",
"set_default_metadata_source": "デフォルトメタデータソースを設定",
"default_audio_source": "デフォルトオーディオソース",
"set_default_audio_source": "デフォルトオーディオソースを設定",
"plugins": "プラグイン",
"configure_plugins": "独自のメタデータプロバイダーとオーディオソースプラグインを設定",
"source": "ソース: ",
"uncompressed": "非圧縮",
"dab_music_source_description": "オーディオファイル向け。高品質/ロスレスオーディオストリームを提供。正確なISRCベースのトラックマッチング。"
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "ხელმისაწვდომი პლაგინები", "available_plugins": "ხელმისაწვდომი პლაგინები",
"configure_your_own_metadata_plugin": "დააყენეთ თქვენი საკუთარი პლეილისტის/ალბომის/არტისტის/ფიდის მეტამონაცემების პროვაიდერი", "configure_your_own_metadata_plugin": "დააყენეთ თქვენი საკუთარი პლეილისტის/ალბომის/არტისტის/ფიდის მეტამონაცემების პროვაიდერი",
"audio_scrobblers": "აუდიო სქრობლერები", "audio_scrobblers": "აუდიო სქრობლერები",
"scrobbling": "სქრობლინგი", "scrobbling": "სქრობლინგი"
"download_music_format": "მუსიკის ჩამოტვირთვის ფორმატი",
"streaming_music_format": "სტრიმინგის მუსიკის ფორმატი",
"download_music_quality": "ჩამოტვირთვის ხარისხი",
"streaming_music_quality": "სტრიმინგის ხარისხი",
"default_metadata_source": "ნაგულისხმევი მეტამონაცემების წყარო",
"set_default_metadata_source": "ნაგულისხმევი მეტამონაცემების წყაროს დაყენება",
"default_audio_source": "ნაგულისხმევი აუდიო წყარო",
"set_default_audio_source": "ნაგულისხმევი აუდიო წყაროს დაყენება",
"plugins": "პლაგინები",
"configure_plugins": "თქვენი საკუთარი მეტამონაცემებისა და აუდიო წყაროს პლაგინების კონფიგურაცია",
"source": "წყარო: ",
"uncompressed": "შეუკუმშავი",
"dab_music_source_description": "აუდიოფილებისთვის. უზრუნველყოფს მაღალი ხარისხის/უკომპრესო აუდიო სტრიმებს. ზუსტი შესაბამისობა ISRC-ის მიხედვით."
} }

View File

@ -478,18 +478,5 @@
"available_plugins": "사용 가능한 플러그인", "available_plugins": "사용 가능한 플러그인",
"configure_your_own_metadata_plugin": "자신만의 플레이리스트/앨범/아티스트/피드 메타데이터 제공자 구성", "configure_your_own_metadata_plugin": "자신만의 플레이리스트/앨범/아티스트/피드 메타데이터 제공자 구성",
"audio_scrobblers": "오디오 스크로블러", "audio_scrobblers": "오디오 스크로블러",
"scrobbling": "스크로블링", "scrobbling": "스크로블링"
"download_music_format": "다운로드 음악 포맷",
"streaming_music_format": "스트리밍 음악 포맷",
"download_music_quality": "다운로드 음질",
"streaming_music_quality": "스트리밍 음질",
"default_metadata_source": "기본 메타데이터 소스",
"set_default_metadata_source": "기본 메타데이터 소스 설정",
"default_audio_source": "기본 오디오 소스",
"set_default_audio_source": "기본 오디오 소스 설정",
"plugins": "플러그인",
"configure_plugins": "직접 메타데이터 제공자와 오디오 소스 플러그인을 구성하세요",
"source": "출처: ",
"uncompressed": "비압축",
"dab_music_source_description": "오디오파일을 위한 소스입니다. 고음질/무손실 오디오 스트림을 제공하며 ISRC 기반으로 정확한 트랙 매칭을 지원합니다."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "उपलब्ध प्लगइनहरू", "available_plugins": "उपलब्ध प्लगइनहरू",
"configure_your_own_metadata_plugin": "तपाईंको आफ्नै प्लेलिस्ट/एल्बम/कलाकार/फिड मेटाडेटा प्रदायक कन्फिगर गर्नुहोस्", "configure_your_own_metadata_plugin": "तपाईंको आफ्नै प्लेलिस्ट/एल्बम/कलाकार/फिड मेटाडेटा प्रदायक कन्फिगर गर्नुहोस्",
"audio_scrobblers": "अडियो स्क्रब्बलरहरू", "audio_scrobblers": "अडियो स्क्रब्बलरहरू",
"scrobbling": "स्क्रब्बलिंग", "scrobbling": "स्क्रब्बलिंग"
"download_music_format": "सङ्गीत डाउनलोड ढाँचा",
"streaming_music_format": "स्ट्रिमिङ सङ्गीत ढाँचा",
"download_music_quality": "डाउनलोड गुणस्तर",
"streaming_music_quality": "स्ट्रिमिङ गुणस्तर",
"default_metadata_source": "पूर्वनिर्धारित मेटाडाटा स्रोत",
"set_default_metadata_source": "पूर्वनिर्धारित मेटाडाटा स्रोत सेट गर्नुहोस्",
"default_audio_source": "पूर्वनिर्धारित अडियो स्रोत",
"set_default_audio_source": "पूर्वनिर्धारित अडियो स्रोत सेट गर्नुहोस्",
"plugins": "प्लगइनहरू",
"configure_plugins": "आफ्नै मेटाडाटा प्रदायक र अडियो स्रोत प्लगइनहरू कन्फिगर गर्नुहोस्",
"source": "स्रोत: ",
"uncompressed": "असंक्षिप्त",
"dab_music_source_description": "अडियोप्रेमीहरूका लागि। उच्च गुणस्तर/लसलेस अडियो स्ट्रिमहरू उपलब्ध गराउँछ। ISRC-मा आधारित सटीक ट्र्याक मिलान।"
} }

View File

@ -477,19 +477,5 @@
"available_plugins": "Beschikbare plugins", "available_plugins": "Beschikbare plugins",
"configure_your_own_metadata_plugin": "Configureer uw eigen metadata-aanbieder voor afspeellijst/album/artiest/feed", "configure_your_own_metadata_plugin": "Configureer uw eigen metadata-aanbieder voor afspeellijst/album/artiest/feed",
"audio_scrobblers": "Audioscrobblers", "audio_scrobblers": "Audioscrobblers",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Download muziekformaat",
"streaming_music_format": "Streaming muziekformaat",
"download_music_quality": "Downloadkwaliteit",
"streaming_music_quality": "Streamingkwaliteit",
"default_metadata_source": "Standaard metadata-bron",
"set_default_metadata_source": "Standaard metadata-bron instellen",
"default_audio_source": "Standaard audiobron",
"set_default_audio_source": "Standaard audiobron instellen",
"plugins": "Plug-ins",
"configure_plugins": "Configureer je eigen metadata- en audiobron-plug-ins",
"source": "Bron: ",
"uncompressed": "Ongecomprimeerd",
"dab_music_source_description": "Voor audiofielen. Biedt hoge kwaliteit/lossless audiostreams. Nauwkeurige trackmatching op basis van ISRC.",
"audio_source": "Audiobron"
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Dostępne wtyczki", "available_plugins": "Dostępne wtyczki",
"configure_your_own_metadata_plugin": "Skonfiguruj własnego dostawcę metadanych dla playlisty/albumu/artysty/kanału", "configure_your_own_metadata_plugin": "Skonfiguruj własnego dostawcę metadanych dla playlisty/albumu/artysty/kanału",
"audio_scrobblers": "Scrobblery audio", "audio_scrobblers": "Scrobblery audio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Format pobierania muzyki",
"streaming_music_format": "Format strumieniowania muzyki",
"download_music_quality": "Jakość pobierania",
"streaming_music_quality": "Jakość strumieniowania",
"default_metadata_source": "Domyślne źródło metadanych",
"set_default_metadata_source": "Ustaw domyślne źródło metadanych",
"default_audio_source": "Domyślne źródło audio",
"set_default_audio_source": "Ustaw domyślne źródło audio",
"plugins": "Wtyczki",
"configure_plugins": "Skonfiguruj własne wtyczki dostawców metadanych i źródeł audio",
"source": "Źródło: ",
"uncompressed": "Nieskompresowany",
"dab_music_source_description": "Dla audiofilów. Oferuje strumienie audio wysokiej jakości/lossless. Precyzyjne dopasowanie utworów na podstawie ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Plugins disponíveis", "available_plugins": "Plugins disponíveis",
"configure_your_own_metadata_plugin": "Configure seu próprio provedor de metadados de playlist/álbum/artista/feed", "configure_your_own_metadata_plugin": "Configure seu próprio provedor de metadados de playlist/álbum/artista/feed",
"audio_scrobblers": "Scrobblers de áudio", "audio_scrobblers": "Scrobblers de áudio",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Formato de download de música",
"streaming_music_format": "Formato de streaming de música",
"download_music_quality": "Qualidade de download",
"streaming_music_quality": "Qualidade de streaming",
"default_metadata_source": "Fonte padrão de metadados",
"set_default_metadata_source": "Definir fonte padrão de metadados",
"default_audio_source": "Fonte de áudio padrão",
"set_default_audio_source": "Definir fonte de áudio padrão",
"plugins": "Plugins",
"configure_plugins": "Configure seus próprios plugins de provedores de metadados e fontes de áudio",
"source": "Fonte: ",
"uncompressed": "Não comprimido",
"dab_music_source_description": "Para audiófilos. Fornece streams de áudio de alta qualidade/sem perdas. Correspondência precisa de faixas baseada em ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Доступные плагины", "available_plugins": "Доступные плагины",
"configure_your_own_metadata_plugin": "Настройте свой собственный поставщик метаданных для плейлиста/альбома/артиста/ленты", "configure_your_own_metadata_plugin": "Настройте свой собственный поставщик метаданных для плейлиста/альбома/артиста/ленты",
"audio_scrobblers": "Аудио скробблеры", "audio_scrobblers": "Аудио скробблеры",
"scrobbling": "Скробблинг", "scrobbling": "Скробблинг"
"download_music_format": "Формат загрузки музыки",
"streaming_music_format": "Формат потоковой музыки",
"download_music_quality": "Качество загрузки",
"streaming_music_quality": "Качество стриминга",
"default_metadata_source": "Источник метаданных по умолчанию",
"set_default_metadata_source": "Задать источник метаданных по умолчанию",
"default_audio_source": "Источник аудио по умолчанию",
"set_default_audio_source": "Задать источник аудио по умолчанию",
"plugins": "Плагины",
"configure_plugins": "Настройте собственные плагины провайдеров метаданных и источников аудио",
"source": "Источник: ",
"uncompressed": "Несжатый",
"dab_music_source_description": "Для аудиофилов. Предоставляет высококачественные/lossless аудиопотоки. Точное совпадение треков по ISRC."
} }

View File

@ -475,18 +475,5 @@
"available_plugins": "கிடைக்கக்கூடிய பிளகின்கள்", "available_plugins": "கிடைக்கக்கூடிய பிளகின்கள்",
"configure_your_own_metadata_plugin": "உங்கள் சொந்த பிளேலிஸ்ட்/ஆல்பம்/கலைஞர்/ஊட்ட மெட்டாடேட்டா வழங்குநரை உள்ளமைக்கவும்", "configure_your_own_metadata_plugin": "உங்கள் சொந்த பிளேலிஸ்ட்/ஆல்பம்/கலைஞர்/ஊட்ட மெட்டாடேட்டா வழங்குநரை உள்ளமைக்கவும்",
"audio_scrobblers": "ஆடியோ ஸ்க்ரோப்ளர்கள்", "audio_scrobblers": "ஆடியோ ஸ்க்ரோப்ளர்கள்",
"scrobbling": "ஸ்க்ரோப்ளிங்", "scrobbling": "ஸ்க்ரோப்ளிங்"
"download_music_format": "இசை பதிவிறக்க வடிவம்",
"streaming_music_format": "இசை ஸ்ட்ரீமிங் வடிவம்",
"download_music_quality": "பதிவிறக்க தரம்",
"streaming_music_quality": "ஸ்ட்ரீமிங் தரம்",
"default_metadata_source": "இயல்புநிலை மெட்டாடேட்டா மூலம்",
"set_default_metadata_source": "இயல்புநிலை மெட்டாடேட்டா மூலத்தை அமை",
"default_audio_source": "இயல்புநிலை ஆடியோ மூலம்",
"set_default_audio_source": "இயல்புநிலை ஆடியோ மூலத்தை அமை",
"plugins": "செருகுநிரல்கள்",
"configure_plugins": "உங்கள் சொந்த மெட்டாடேட்டா வழங்குநர் மற்றும் ஆடியோ மூல செருகுநிரல்களை அமைக்கவும்",
"source": "மூலம்: ",
"uncompressed": "அழுத்தப்படாத",
"dab_music_source_description": "ஆடியோஃபைல்களுக்காக. உயர்தர/லாஸ்லெஸ் ஆடியோ ஸ்ட்ரீம்களை வழங்குகிறது. ISRC அடிப்படையில் துல்லியமான பாடல் பொருத்தம்."
} }

View File

@ -478,18 +478,5 @@
"available_plugins": "ปลั๊กอินที่มีอยู่", "available_plugins": "ปลั๊กอินที่มีอยู่",
"configure_your_own_metadata_plugin": "กำหนดค่าผู้ให้บริการเมตาดาต้าเพลย์ลิสต์/อัลบั้ม/ศิลปิน/ฟีดของคุณเอง", "configure_your_own_metadata_plugin": "กำหนดค่าผู้ให้บริการเมตาดาต้าเพลย์ลิสต์/อัลบั้ม/ศิลปิน/ฟีดของคุณเอง",
"audio_scrobblers": "เครื่อง scrobbler เสียง", "audio_scrobblers": "เครื่อง scrobbler เสียง",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "รูปแบบการดาวน์โหลดเพลง",
"streaming_music_format": "รูปแบบการสตรีมเพลง",
"download_music_quality": "คุณภาพการดาวน์โหลด",
"streaming_music_quality": "คุณภาพการสตรีม",
"default_metadata_source": "แหล่งเมตาดาต้าพื้นฐาน",
"set_default_metadata_source": "ตั้งค่าแหล่งเมตาดาต้าพื้นฐาน",
"default_audio_source": "แหล่งเสียงพื้นฐาน",
"set_default_audio_source": "ตั้งค่าแหล่งเสียงพื้นฐาน",
"plugins": "ปลั๊กอิน",
"configure_plugins": "กำหนดค่าปลั๊กอินผู้ให้บริการเมตาดาต้าและแหล่งเสียงของคุณเอง",
"source": "แหล่งที่มา: ",
"uncompressed": "ไม่บีบอัด",
"dab_music_source_description": "สำหรับคนรักเสียงเพลง ให้สตรีมเสียงคุณภาพสูง/ไร้การสูญเสียการบีบอัด การจับคู่แทร็กแม่นยำตาม ISRC"
} }

View File

@ -475,18 +475,5 @@
"available_plugins": "Mga available na plugin", "available_plugins": "Mga available na plugin",
"configure_your_own_metadata_plugin": "I-configure ang iyong sariling playlist/album/artist/feed metadata provider", "configure_your_own_metadata_plugin": "I-configure ang iyong sariling playlist/album/artist/feed metadata provider",
"audio_scrobblers": "Mga Audio Scrobbler", "audio_scrobblers": "Mga Audio Scrobbler",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "I-download na format ng musika",
"streaming_music_format": "Format ng streaming ng musika",
"download_music_quality": "Kalidad ng i-download na musika",
"streaming_music_quality": "Kalidad ng streaming ng musika",
"default_metadata_source": "Default na pinagmulan ng metadata",
"set_default_metadata_source": "Itakda ang default na pinagmulan ng metadata",
"default_audio_source": "Default na pinagmulan ng audio",
"set_default_audio_source": "Itakda ang default na pinagmulan ng audio",
"plugins": "Mga plugin",
"configure_plugins": "I-configure ang sarili mong metadata provider at mga audio source plugin",
"source": "Pinagmulan: ",
"uncompressed": "Hindi naka-compress",
"dab_music_source_description": "Para sa mga audiophile. Nagbibigay ng de-kalidad/walang loss na audio streams. Tumpak na pagtutugma ng track batay sa ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Mevcut eklentiler", "available_plugins": "Mevcut eklentiler",
"configure_your_own_metadata_plugin": "Kendi çalma listenizi/albümünüzü/sanatçınızı/akış meta veri sağlayıcınızı yapılandırın", "configure_your_own_metadata_plugin": "Kendi çalma listenizi/albümünüzü/sanatçınızı/akış meta veri sağlayıcınızı yapılandırın",
"audio_scrobblers": "Ses Scrobbler'lar", "audio_scrobblers": "Ses Scrobbler'lar",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Müzik indirme formatı",
"streaming_music_format": "Müzik akış formatı",
"download_music_quality": "İndirilen müzik kalitesi",
"streaming_music_quality": "Yayınlanan müzik kalitesi",
"default_metadata_source": "Varsayılan meta veri kaynağı",
"set_default_metadata_source": "Varsayılan meta veri kaynağını ayarla",
"default_audio_source": "Varsayılan ses kaynağı",
"set_default_audio_source": "Varsayılan ses kaynağını ayarla",
"plugins": "Eklentiler",
"configure_plugins": "Kendi meta veri sağlayıcı ve ses kaynağı eklentilerinizi yapılandırın",
"source": "Kaynak: ",
"uncompressed": "Sıkıştırılmamış",
"dab_music_source_description": "Audiophile'ler için. Yüksek kaliteli/kayıpsız ses akışları sağlar. Doğru ISRC tabanlı parça eşleştirme."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Доступні плагіни", "available_plugins": "Доступні плагіни",
"configure_your_own_metadata_plugin": "Налаштуйте свій власний провайдер метаданих для плейлиста/альбому/виконавця/стрічки", "configure_your_own_metadata_plugin": "Налаштуйте свій власний провайдер метаданих для плейлиста/альбому/виконавця/стрічки",
"audio_scrobblers": "Аудіо скробблери", "audio_scrobblers": "Аудіо скробблери",
"scrobbling": "Скроблінг", "scrobbling": "Скроблінг"
"download_music_format": "Формат завантаження музики",
"streaming_music_format": "Формат потокової музики",
"download_music_quality": "Якість завантаженої музики",
"streaming_music_quality": "Якість потокової музики",
"default_metadata_source": "Джерело метаданих за замовчуванням",
"set_default_metadata_source": "Встановити джерело метаданих за замовчуванням",
"default_audio_source": "Джерело аудіо за замовчуванням",
"set_default_audio_source": "Встановити джерело аудіо за замовчуванням",
"plugins": "Плагіни",
"configure_plugins": "Налаштуйте власні плагіни метаданих і аудіоджерела",
"source": "Джерело: ",
"uncompressed": "Без стиснення",
"dab_music_source_description": "Для аудіофілів. Забезпечує високоякісні/без втрат аудіопотоки. Точна відповідність треків на основі ISRC."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "Các plugin có sẵn", "available_plugins": "Các plugin có sẵn",
"configure_your_own_metadata_plugin": "Cấu hình nhà cung cấp siêu dữ liệu danh sách phát/album/nghệ sĩ/nguồn cấp dữ liệu của riêng bạn", "configure_your_own_metadata_plugin": "Cấu hình nhà cung cấp siêu dữ liệu danh sách phát/album/nghệ sĩ/nguồn cấp dữ liệu của riêng bạn",
"audio_scrobblers": "Bộ scrobbler âm thanh", "audio_scrobblers": "Bộ scrobbler âm thanh",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "Định dạng nhạc tải về",
"streaming_music_format": "Định dạng nhạc phát trực tuyến",
"download_music_quality": "Chất lượng nhạc tải về",
"streaming_music_quality": "Chất lượng nhạc phát trực tuyến",
"default_metadata_source": "Nguồn siêu dữ liệu mặc định",
"set_default_metadata_source": "Đặt nguồn siêu dữ liệu mặc định",
"default_audio_source": "Nguồn âm thanh mặc định",
"set_default_audio_source": "Đặt nguồn âm thanh mặc định",
"plugins": "Tiện ích bổ sung",
"configure_plugins": "Cấu hình nhà cung cấp siêu dữ liệu và tiện ích nguồn âm thanh riêng",
"source": "Nguồn: ",
"uncompressed": "Không nén",
"dab_music_source_description": "Dành cho người yêu âm nhạc chất lượng cao. Cung cấp luồng âm thanh chất lượng cao/không nén. Phù hợp bài hát dựa trên ISRC chính xác."
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "可用插件", "available_plugins": "可用插件",
"configure_your_own_metadata_plugin": "配置您自己的播放列表/专辑/艺人/订阅元数据提供者", "configure_your_own_metadata_plugin": "配置您自己的播放列表/专辑/艺人/订阅元数据提供者",
"audio_scrobblers": "音频 Scrobblers", "audio_scrobblers": "音频 Scrobblers",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "下载音乐格式",
"streaming_music_format": "流媒体音乐格式",
"download_music_quality": "下载音乐质量",
"streaming_music_quality": "流媒体音乐质量",
"default_metadata_source": "默认元数据源",
"set_default_metadata_source": "设置默认元数据源",
"default_audio_source": "默认音频源",
"set_default_audio_source": "设置默认音频源",
"plugins": "插件",
"configure_plugins": "配置您自己的元数据提供者和音频源插件",
"source": "来源:",
"uncompressed": "无损",
"dab_music_source_description": "适合发烧友。提供高质量/无损音频流。基于 ISRC 的精确曲目匹配。"
} }

View File

@ -477,18 +477,5 @@
"available_plugins": "可用的外掛程式", "available_plugins": "可用的外掛程式",
"configure_your_own_metadata_plugin": "設定您自己的播放清單/專輯/藝人/動態中繼資料供應商", "configure_your_own_metadata_plugin": "設定您自己的播放清單/專輯/藝人/動態中繼資料供應商",
"audio_scrobblers": "音訊 Scrobblers", "audio_scrobblers": "音訊 Scrobblers",
"scrobbling": "Scrobbling", "scrobbling": "Scrobbling"
"download_music_format": "下載音樂格式",
"streaming_music_format": "串流音樂格式",
"download_music_quality": "下載音樂品質",
"streaming_music_quality": "串流音樂品質",
"default_metadata_source": "預設中繼資料來源",
"set_default_metadata_source": "設定預設中繼資料來源",
"default_audio_source": "預設音訊來源",
"set_default_audio_source": "設定預設音訊來源",
"plugins": "外掛程式",
"configure_plugins": "配置您自己的中繼資料提供者和音訊來源外掛程式",
"source": "來源:",
"uncompressed": "未壓縮",
"dab_music_source_description": "適合音響發燒友。提供高品質/無損音訊串流。精確的 ISRC 曲目比對。"
} }

View File

@ -1743,29 +1743,17 @@ abstract class AppLocalizations {
/// **'Restore defaults'** /// **'Restore defaults'**
String get restore_defaults; String get restore_defaults;
/// No description provided for @download_music_format. /// No description provided for @download_music_codec.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Download music format'** /// **'Download music codec'**
String get download_music_format; String get download_music_codec;
/// No description provided for @streaming_music_format. /// No description provided for @streaming_music_codec.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Streaming music format'** /// **'Streaming music codec'**
String get streaming_music_format; String get streaming_music_codec;
/// No description provided for @download_music_quality.
///
/// In en, this message translates to:
/// **'Download music quality'**
String get download_music_quality;
/// No description provided for @streaming_music_quality.
///
/// In en, this message translates to:
/// **'Streaming music quality'**
String get streaming_music_quality;
/// No description provided for @login_with_lastfm. /// No description provided for @login_with_lastfm.
/// ///
@ -2775,29 +2763,11 @@ abstract class AppLocalizations {
/// **'This plugin scrobbles your music to generate your listening history.'** /// **'This plugin scrobbles your music to generate your listening history.'**
String get plugin_scrobbling_info; String get plugin_scrobbling_info;
/// No description provided for @default_metadata_source. /// No description provided for @default_plugin.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Default metadata source'** /// **'Default'**
String get default_metadata_source; String get default_plugin;
/// No description provided for @set_default_metadata_source.
///
/// In en, this message translates to:
/// **'Set default metadata source'**
String get set_default_metadata_source;
/// No description provided for @default_audio_source.
///
/// In en, this message translates to:
/// **'Default audio source'**
String get default_audio_source;
/// No description provided for @set_default_audio_source.
///
/// In en, this message translates to:
/// **'Set default audio source'**
String get set_default_audio_source;
/// No description provided for @set_default. /// No description provided for @set_default.
/// ///
@ -2901,11 +2871,11 @@ abstract class AppLocalizations {
/// **'Input doesn\'t match the required format'** /// **'Input doesn\'t match the required format'**
String get input_does_not_match_format; String get input_does_not_match_format;
/// No description provided for @plugins. /// No description provided for @metadata_provider_plugins.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Plugins'** /// **'Metadata Provider Plugins'**
String get plugins; String get metadata_provider_plugins;
/// No description provided for @paste_plugin_download_url. /// No description provided for @paste_plugin_download_url.
/// ///
@ -2943,11 +2913,11 @@ abstract class AppLocalizations {
/// **'Available plugins'** /// **'Available plugins'**
String get available_plugins; String get available_plugins;
/// No description provided for @configure_plugins. /// No description provided for @configure_your_own_metadata_plugin.
/// ///
/// In en, this message translates to: /// In en, this message translates to:
/// **'Configure your own metadata provider and audio source plugins'** /// **'Configure your own playlist/album/artist/feed metadata provider'**
String get configure_plugins; String get configure_your_own_metadata_plugin;
/// No description provided for @audio_scrobblers. /// No description provided for @audio_scrobblers.
/// ///

View File

@ -874,16 +874,10 @@ class AppLocalizationsAr extends AppLocalizations {
String get restore_defaults => 'استعادة الإعدادات الافتراضية'; String get restore_defaults => 'استعادة الإعدادات الافتراضية';
@override @override
String get download_music_format => 'تنسيق تنزيل الموسيقى'; String get download_music_codec => 'تنزيل ترميز الموسيقى';
@override @override
String get streaming_music_format => 'تنسيق بث الموسيقى'; String get streaming_music_codec => 'ترميز الموسيقى بالتدفق';
@override
String get download_music_quality => 'جودة تنزيل الموسيقى';
@override
String get streaming_music_quality => 'جودة بث الموسيقى';
@override @override
String get login_with_lastfm => 'تسجيل الدخول باستخدام Last.fm'; String get login_with_lastfm => 'تسجيل الدخول باستخدام Last.fm';
@ -1449,17 +1443,7 @@ class AppLocalizationsAr extends AppLocalizations {
'تقوم هذه الإضافة بتتبع مقاطعك الموسيقية لإنشاء سجل الاستماع الخاص بك.'; 'تقوم هذه الإضافة بتتبع مقاطعك الموسيقية لإنشاء سجل الاستماع الخاص بك.';
@override @override
String get default_metadata_source => 'مصدر البيانات الوصفية الافتراضي'; String get default_plugin => 'الافتراضي';
@override
String get set_default_metadata_source =>
'تعيين مصدر البيانات الوصفية الافتراضي';
@override
String get default_audio_source => 'مصدر الصوت الافتراضي';
@override
String get set_default_audio_source => 'تعيين مصدر الصوت الافتراضي';
@override @override
String get set_default => 'تعيين كافتراضي'; String get set_default => 'تعيين كافتراضي';
@ -1520,7 +1504,7 @@ class AppLocalizationsAr extends AppLocalizations {
'المدخل لا يتوافق مع التنسيق المطلوب'; 'المدخل لا يتوافق مع التنسيق المطلوب';
@override @override
String get plugins => 'الإضافات'; String get metadata_provider_plugins => 'إضافات مزود البيانات';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1545,8 +1529,8 @@ class AppLocalizationsAr extends AppLocalizations {
String get available_plugins => 'الإضافات المتوفّرة'; String get available_plugins => 'الإضافات المتوفّرة';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'قم بتكوين مزود البيانات الوصفية ومكونات مصدر الصوت الخاصة بك'; 'تهيئة مزوّد بيانات للقائمة/الألبوم/الفنان/المصدر خاص بك';
@override @override
String get audio_scrobblers => 'أجهزة تتبع الصوت'; String get audio_scrobblers => 'أجهزة تتبع الصوت';
@ -1555,12 +1539,12 @@ class AppLocalizationsAr extends AppLocalizations {
String get scrobbling => 'التتبع'; String get scrobbling => 'التتبع';
@override @override
String get source => 'المصدر: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'غير مضغوط'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'لمحبي الصوتيات. يوفر تدفقات صوتية عالية الجودة/بدون فقدان. مطابقة دقيقة للمسارات بناءً على ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -873,16 +873,10 @@ class AppLocalizationsBn extends AppLocalizations {
String get restore_defaults => 'ডিফল্ট সেটিংস পুনরুদ্ধার করুন'; String get restore_defaults => 'ডিফল্ট সেটিংস পুনরুদ্ধার করুন';
@override @override
String get download_music_format => 'গান ডাউনলোডের বিন্যাস'; String get download_music_codec => 'সঙ্গীত কোডেক ডাউনলোড করুন';
@override @override
String get streaming_music_format => 'গান স্ট্রিমিং এর বিন্যাস'; String get streaming_music_codec => 'স্ট্রিমিং সঙ্গীত কোডেক';
@override
String get download_music_quality => 'গান ডাউনলোডের মান';
@override
String get streaming_music_quality => 'গান স্ট্রিমিং এর মান';
@override @override
String get login_with_lastfm => 'Last.fm দিয়ে লগইন করুন'; String get login_with_lastfm => 'Last.fm দিয়ে লগইন করুন';
@ -1449,16 +1443,7 @@ class AppLocalizationsBn extends AppLocalizations {
'এই প্লাগইনটি আপনার সঙ্গীত স্ক্রোব্বল করে আপনার শোনা ইতিহাস তৈরি করে।'; 'এই প্লাগইনটি আপনার সঙ্গীত স্ক্রোব্বল করে আপনার শোনা ইতিহাস তৈরি করে।';
@override @override
String get default_metadata_source => 'ডিফল্ট মেটাডেটা উৎস'; String get default_plugin => 'ডিফল্ট';
@override
String get set_default_metadata_source => 'ডিফল্ট মেটাডেটা উৎস সেট করুন';
@override
String get default_audio_source => 'ডিফল্ট অডিও উৎস';
@override
String get set_default_audio_source => 'ডিফল্ট অডিও উৎস সেট করুন';
@override @override
String get set_default => 'ডিফল্ট হিসাবে নির্ধারণ করুন'; String get set_default => 'ডিফল্ট হিসাবে নির্ধারণ করুন';
@ -1520,7 +1505,7 @@ class AppLocalizationsBn extends AppLocalizations {
'ইনপুট প্রয়োজনীয় ফরম্যাটের সাথে মেলে না'; 'ইনপুট প্রয়োজনীয় ফরম্যাটের সাথে মেলে না';
@override @override
String get plugins => 'প্লাগইন'; String get metadata_provider_plugins => 'মেটাডেটা প্রদানকারী প্লাগইনসমূহ';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1545,8 +1530,8 @@ class AppLocalizationsBn extends AppLocalizations {
String get available_plugins => 'উপলব্ধ প্লাগইনগুলো'; String get available_plugins => 'উপলব্ধ প্লাগইনগুলো';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'আপনার নিজের মেটাডেটা প্রদানকারী এবং অডিও উৎস প্লাগইন কনফিগার করুন'; 'নিজস্ব প্লেলিস্ট/অ্যালবাম/শিল্পী/ফিড মেটাডেটা প্রদানকারী কনফিগার করুন';
@override @override
String get audio_scrobblers => 'অডিও স্ক্রোব্বলার্স'; String get audio_scrobblers => 'অডিও স্ক্রোব্বলার্স';
@ -1555,12 +1540,12 @@ class AppLocalizationsBn extends AppLocalizations {
String get scrobbling => 'স্ক্রোব্বলিং'; String get scrobbling => 'স্ক্রোব্বলিং';
@override @override
String get source => 'উৎস: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'অ-সংকুচিত'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'অডিওফাইলদের জন্য। উচ্চ-মানের/লসলেস অডিও স্ট্রিম প্রদান করে। সঠিক ISRC ভিত্তিক ট্র্যাক ম্যাচিং।'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -876,18 +876,10 @@ class AppLocalizationsCa extends AppLocalizations {
String get restore_defaults => 'Restaura els valors per defecte'; String get restore_defaults => 'Restaura els valors per defecte';
@override @override
String get download_music_format => 'Format de descàrrega de música'; String get download_music_codec => 'Descarrega el codec de música';
@override @override
String get streaming_music_format => String get streaming_music_codec => 'Codec de música en streaming';
'Format de reproducció de música en temps real';
@override
String get download_music_quality => 'Qualitat de descàrrega de música';
@override
String get streaming_music_quality =>
'Qualitat de reproducció de música en temps real';
@override @override
String get login_with_lastfm => 'Inicia la sessió amb Last.fm'; String get login_with_lastfm => 'Inicia la sessió amb Last.fm';
@ -1458,18 +1450,7 @@ class AppLocalizationsCa extends AppLocalizations {
'Aquest complement fa scrobbling de la teva música per generar lhistorial descoltes.'; 'Aquest complement fa scrobbling de la teva música per generar lhistorial descoltes.';
@override @override
String get default_metadata_source => 'Font de metadades per defecte'; String get default_plugin => 'Predeterminat';
@override
String get set_default_metadata_source =>
'Estableix la font de metadades per defecte';
@override
String get default_audio_source => 'Font d\'àudio per defecte';
@override
String get set_default_audio_source =>
'Estableix la font d\'àudio per defecte';
@override @override
String get set_default => 'Establir com a predeterminat'; String get set_default => 'Establir com a predeterminat';
@ -1533,7 +1514,8 @@ class AppLocalizationsCa extends AppLocalizations {
'Lentrada no coincideix amb el format requerit'; 'Lentrada no coincideix amb el format requerit';
@override @override
String get plugins => 'Connectors'; String get metadata_provider_plugins =>
'Complements de proveïdor de metadades';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1558,8 +1540,8 @@ class AppLocalizationsCa extends AppLocalizations {
String get available_plugins => 'Complements disponibles'; String get available_plugins => 'Complements disponibles';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configura els teus propis connectors de proveïdor de metadades i de font d\'àudio'; 'Configura el teu propi proveïdor de metadades per llistes/reproduccions àlbum/artista/flux';
@override @override
String get audio_scrobblers => 'Scrobblers dàudio'; String get audio_scrobblers => 'Scrobblers dàudio';
@ -1568,12 +1550,12 @@ class AppLocalizationsCa extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Font: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Sense comprimir'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Per als audiòfils. Ofereix fluxos d\'àudio d\'alta qualitat/sense pèrdua. Coincidència precisa de pistes basada en ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -869,16 +869,10 @@ class AppLocalizationsCs extends AppLocalizations {
String get restore_defaults => 'Obnovit výchozí'; String get restore_defaults => 'Obnovit výchozí';
@override @override
String get download_music_format => 'Formát stahování hudby'; String get download_music_codec => 'Kodek pro stahování';
@override @override
String get streaming_music_format => 'Formát streamování hudby'; String get streaming_music_codec => 'Kodek pro streamování';
@override
String get download_music_quality => 'Kvalita stahování hudby';
@override
String get streaming_music_quality => 'Kvalita streamování hudby';
@override @override
String get login_with_lastfm => 'Přihlásit se pomocí Last.fm'; String get login_with_lastfm => 'Přihlásit se pomocí Last.fm';
@ -1448,16 +1442,7 @@ class AppLocalizationsCs extends AppLocalizations {
'Tento plugin scrobbles vaši hudbu pro vytvoření historie poslechů.'; 'Tento plugin scrobbles vaši hudbu pro vytvoření historie poslechů.';
@override @override
String get default_metadata_source => 'Výchozí zdroj metadat'; String get default_plugin => 'Výchozí';
@override
String get set_default_metadata_source => 'Nastavit výchozí zdroj metadat';
@override
String get default_audio_source => 'Výchozí zdroj zvuku';
@override
String get set_default_audio_source => 'Nastavit výchozí zdroj zvuku';
@override @override
String get set_default => 'Nastavit jako výchozí'; String get set_default => 'Nastavit jako výchozí';
@ -1520,7 +1505,7 @@ class AppLocalizationsCs extends AppLocalizations {
'Vstup neodpovídá požadovanému formátu'; 'Vstup neodpovídá požadovanému formátu';
@override @override
String get plugins => 'Pluginy'; String get metadata_provider_plugins => 'Pluginy poskytovatelů metadat';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1545,8 +1530,8 @@ class AppLocalizationsCs extends AppLocalizations {
String get available_plugins => 'Dostupné pluginy'; String get available_plugins => 'Dostupné pluginy';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Konfigurujte své vlastní pluginy poskytovatele metadat a zdroje zvuku'; 'Nakonfigurujte si vlastního poskytovatele metadat pro playlist/album/umělec/fid';
@override @override
String get audio_scrobblers => 'Audio scrobblers'; String get audio_scrobblers => 'Audio scrobblers';
@ -1555,12 +1540,12 @@ class AppLocalizationsCs extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Zdroj: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Nekomprimováno'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Pro audiofily. Poskytuje vysoce kvalitní/bezztrátové zvukové toky. Přesná shoda skladeb na základě ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -879,16 +879,10 @@ class AppLocalizationsDe extends AppLocalizations {
String get restore_defaults => 'Standardeinstellungen wiederherstellen'; String get restore_defaults => 'Standardeinstellungen wiederherstellen';
@override @override
String get download_music_format => 'Musik-Downloadformat'; String get download_music_codec => 'Musik-Codec herunterladen';
@override @override
String get streaming_music_format => 'Musik-Streamingformat'; String get streaming_music_codec => 'Streaming-Musik-Codec';
@override
String get download_music_quality => 'Musik-Downloadqualität';
@override
String get streaming_music_quality => 'Musik-Streamingqualität';
@override @override
String get login_with_lastfm => 'Mit Last.fm anmelden'; String get login_with_lastfm => 'Mit Last.fm anmelden';
@ -1461,17 +1455,7 @@ class AppLocalizationsDe extends AppLocalizations {
'Dieses Plugin scrobbelt Ihre Musik, um Ihre Hörhistorie zu erstellen.'; 'Dieses Plugin scrobbelt Ihre Musik, um Ihre Hörhistorie zu erstellen.';
@override @override
String get default_metadata_source => 'Standard-Metadatenquelle'; String get default_plugin => 'Standard';
@override
String get set_default_metadata_source =>
'Standard-Metadatenquelle festlegen';
@override
String get default_audio_source => 'Standard-Audioquelle';
@override
String get set_default_audio_source => 'Standard-Audioquelle festlegen';
@override @override
String get set_default => 'Als Standard festlegen'; String get set_default => 'Als Standard festlegen';
@ -1533,7 +1517,7 @@ class AppLocalizationsDe extends AppLocalizations {
'Eingabe entspricht nicht dem geforderten Format'; 'Eingabe entspricht nicht dem geforderten Format';
@override @override
String get plugins => 'Plugins'; String get metadata_provider_plugins => 'Plugins für Metadatenanbieter';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1558,8 +1542,8 @@ class AppLocalizationsDe extends AppLocalizations {
String get available_plugins => 'Verfügbare Plugins'; String get available_plugins => 'Verfügbare Plugins';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Richte deine eigenen Metadatenanbieter- und Audioquellen-Plugins ein'; 'Eigenen Anbieter für Playlist-/Album-/Künstler-/Feed-Metadaten konfigurieren';
@override @override
String get audio_scrobblers => 'Audio-Scrobbler'; String get audio_scrobblers => 'Audio-Scrobbler';
@ -1568,12 +1552,12 @@ class AppLocalizationsDe extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Quelle: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Unkomprimiert'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Für Audiophile. Bietet hochwertige/verlustfreie Audiostreams. Präzises ISRC-basiertes Track-Matching.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -871,16 +871,10 @@ class AppLocalizationsEn extends AppLocalizations {
String get restore_defaults => 'Restore defaults'; String get restore_defaults => 'Restore defaults';
@override @override
String get download_music_format => 'Download music format'; String get download_music_codec => 'Download music codec';
@override @override
String get streaming_music_format => 'Streaming music format'; String get streaming_music_codec => 'Streaming music codec';
@override
String get download_music_quality => 'Download music quality';
@override
String get streaming_music_quality => 'Streaming music quality';
@override @override
String get login_with_lastfm => 'Login with Last.fm'; String get login_with_lastfm => 'Login with Last.fm';
@ -1448,16 +1442,7 @@ class AppLocalizationsEn extends AppLocalizations {
'This plugin scrobbles your music to generate your listening history.'; 'This plugin scrobbles your music to generate your listening history.';
@override @override
String get default_metadata_source => 'Default metadata source'; String get default_plugin => 'Default';
@override
String get set_default_metadata_source => 'Set default metadata source';
@override
String get default_audio_source => 'Default audio source';
@override
String get set_default_audio_source => 'Set default audio source';
@override @override
String get set_default => 'Set default'; String get set_default => 'Set default';
@ -1518,7 +1503,7 @@ class AppLocalizationsEn extends AppLocalizations {
'Input doesn\'t match the required format'; 'Input doesn\'t match the required format';
@override @override
String get plugins => 'Plugins'; String get metadata_provider_plugins => 'Metadata Provider Plugins';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1543,8 +1528,8 @@ class AppLocalizationsEn extends AppLocalizations {
String get available_plugins => 'Available plugins'; String get available_plugins => 'Available plugins';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configure your own metadata provider and audio source plugins'; 'Configure your own playlist/album/artist/feed metadata provider';
@override @override
String get audio_scrobblers => 'Audio Scrobblers'; String get audio_scrobblers => 'Audio Scrobblers';

View File

@ -876,16 +876,10 @@ class AppLocalizationsEs extends AppLocalizations {
String get restore_defaults => 'Restaurar valores predeterminados'; String get restore_defaults => 'Restaurar valores predeterminados';
@override @override
String get download_music_format => 'Formato de descarga de música'; String get download_music_codec => 'Descargar códec de música';
@override @override
String get streaming_music_format => 'Formato de transmisión de música'; String get streaming_music_codec => 'Códec de música en streaming';
@override
String get download_music_quality => 'Calidad de descarga de música';
@override
String get streaming_music_quality => 'Calidad de transmisión de música';
@override @override
String get login_with_lastfm => 'Iniciar sesión con Last.fm'; String get login_with_lastfm => 'Iniciar sesión con Last.fm';
@ -1458,18 +1452,7 @@ class AppLocalizationsEs extends AppLocalizations {
'Este complemento scrobblea tu música para generar tu historial de reproducción.'; 'Este complemento scrobblea tu música para generar tu historial de reproducción.';
@override @override
String get default_metadata_source => 'Fuente de metadatos predeterminada'; String get default_plugin => 'Predeterminado';
@override
String get set_default_metadata_source =>
'Establecer fuente de metadatos predeterminada';
@override
String get default_audio_source => 'Fuente de audio predeterminada';
@override
String get set_default_audio_source =>
'Establecer fuente de audio predeterminada';
@override @override
String get set_default => 'Establecer como predeterminado'; String get set_default => 'Establecer como predeterminado';
@ -1534,7 +1517,8 @@ class AppLocalizationsEs extends AppLocalizations {
'La entrada no coincide con el formato requerido'; 'La entrada no coincide con el formato requerido';
@override @override
String get plugins => 'Plugins'; String get metadata_provider_plugins =>
'Complementos de proveedor de metadatos';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1559,8 +1543,8 @@ class AppLocalizationsEs extends AppLocalizations {
String get available_plugins => 'Complementos disponibles'; String get available_plugins => 'Complementos disponibles';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configura tus propios plugins de proveedor de metadatos y fuente de audio'; 'Configura tu propio proveedor de metadatos para listas/álbum/artista/feeds';
@override @override
String get audio_scrobblers => 'Scrobblers de audio'; String get audio_scrobblers => 'Scrobblers de audio';
@ -1569,12 +1553,12 @@ class AppLocalizationsEs extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Fuente: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Sin comprimir'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Para audiófilos. Proporciona transmisiones de audio de alta calidad/sin pérdida. Coincidencia precisa de pistas basada en ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -876,16 +876,10 @@ class AppLocalizationsEu extends AppLocalizations {
String get restore_defaults => 'Berrezarri berezko balioak'; String get restore_defaults => 'Berrezarri berezko balioak';
@override @override
String get download_music_format => 'Musika deskargatzeko formatua'; String get download_music_codec => 'Deskargatutako musikaren codec-a';
@override @override
String get streaming_music_format => 'Musika streaming bidezko formatua'; String get streaming_music_codec => 'Streaming musikaren codec-a';
@override
String get download_music_quality => 'Musika deskargaren kalitatea';
@override
String get streaming_music_quality => 'Streaming bidezko musika kalitatea';
@override @override
String get login_with_lastfm => 'Hasi saioa Last.fm-n'; String get login_with_lastfm => 'Hasi saioa Last.fm-n';
@ -1457,17 +1451,7 @@ class AppLocalizationsEu extends AppLocalizations {
'Plugin honek zure musika scrobbled egiten du zure entzuteen historia sortzeko.'; 'Plugin honek zure musika scrobbled egiten du zure entzuteen historia sortzeko.';
@override @override
String get default_metadata_source => 'Metadatu-iturburu lehenetsia'; String get default_plugin => 'Lehenetsia';
@override
String get set_default_metadata_source =>
'Ezarri metadatu-iturburu lehenetsia';
@override
String get default_audio_source => 'Audio-iturburu lehenetsia';
@override
String get set_default_audio_source => 'Ezarri audio-iturburu lehenetsia';
@override @override
String get set_default => 'Lehenetsi gisa ezarri'; String get set_default => 'Lehenetsi gisa ezarri';
@ -1531,7 +1515,7 @@ class AppLocalizationsEu extends AppLocalizations {
'Sarrera ezin da beharrezko formatutik desberdina izan'; 'Sarrera ezin da beharrezko formatutik desberdina izan';
@override @override
String get plugins => 'Pluginak'; String get metadata_provider_plugins => 'Metadaten hornitzailearen pluginak';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1556,8 +1540,8 @@ class AppLocalizationsEu extends AppLocalizations {
String get available_plugins => 'Eskaintzen diren pluginak'; String get available_plugins => 'Eskaintzen diren pluginak';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Konfiguratu zure metadatu-hornitzaile eta audio-iturburu pluginak'; 'Konfiguratu zureko playlists-/album-/artista-/feed-metadaten hornitzailea';
@override @override
String get audio_scrobblers => 'Audio scrobbler-ak'; String get audio_scrobblers => 'Audio scrobbler-ak';
@ -1566,12 +1550,12 @@ class AppLocalizationsEu extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Iturburua: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Konprimitu gabea'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Audiozaleentzat. Kalitate handiko/galerarik gabeko audio-streamak eskaintzen ditu. ISRC oinarritutako pistaren parekatze zehatza.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -870,16 +870,10 @@ class AppLocalizationsFa extends AppLocalizations {
String get restore_defaults => 'بازیابی پیش فرض ها'; String get restore_defaults => 'بازیابی پیش فرض ها';
@override @override
String get download_music_format => 'فرمت دانلود موسیقی'; String get download_music_codec => 'دانلود کدک موسیقی';
@override @override
String get streaming_music_format => 'فرمت پخش آنلاین موسیقی'; String get streaming_music_codec => 'کدک موسیقی استریمینگ';
@override
String get download_music_quality => 'کیفیت دانلود موسیقی';
@override
String get streaming_music_quality => 'کیفیت پخش آنلاین موسیقی';
@override @override
String get login_with_lastfm => 'ورود با Last.fm'; String get login_with_lastfm => 'ورود با Last.fm';
@ -1447,16 +1441,7 @@ class AppLocalizationsFa extends AppLocalizations {
'این افزونه موسیقی شما را اسکراب می‌کند تا تاریخچهٔ شنیداری‌تان را تولید کند.'; 'این افزونه موسیقی شما را اسکراب می‌کند تا تاریخچهٔ شنیداری‌تان را تولید کند.';
@override @override
String get default_metadata_source => 'منبع پیش‌فرض فراداده'; String get default_plugin => 'پیش‌فرض';
@override
String get set_default_metadata_source => 'تنظیم منبع پیش‌فرض فراداده';
@override
String get default_audio_source => 'منبع پیش‌فرض صوت';
@override
String get set_default_audio_source => 'تنظیم منبع پیش‌فرض صوت';
@override @override
String get set_default => 'تنظیم به عنوان پیش‌فرض'; String get set_default => 'تنظیم به عنوان پیش‌فرض';
@ -1518,7 +1503,7 @@ class AppLocalizationsFa extends AppLocalizations {
'ورودی با قالب مورد نیاز تطابق ندارد'; 'ورودی با قالب مورد نیاز تطابق ندارد';
@override @override
String get plugins => 'افزونه‌ها'; String get metadata_provider_plugins => 'افزونه‌های ارائه‌دهندهٔ متادیتا';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1543,8 +1528,8 @@ class AppLocalizationsFa extends AppLocalizations {
String get available_plugins => 'افزونه‌های موجود'; String get available_plugins => 'افزونه‌های موجود';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'افزونه‌های منبع صوت و ارائه‌دهنده فراداده خود را پیکربندی کنید'; 'پیکربندی ارائه‌دهندهٔ متادیتا برای پلی‌لیست/آلبوم/هنرمند/فید به‌صورت سفارشی';
@override @override
String get audio_scrobblers => 'اسکراب‌بلرهای صوتی'; String get audio_scrobblers => 'اسکراب‌بلرهای صوتی';
@ -1553,12 +1538,12 @@ class AppLocalizationsFa extends AppLocalizations {
String get scrobbling => 'اسکراب‌بلینگ'; String get scrobbling => 'اسکراب‌بلینگ';
@override @override
String get source => 'منبع: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'بدون فشرده‌سازی'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'مخصوص علاقه‌مندان صدا. ارائه‌دهنده استریم‌های باکیفیت/بدون افت. تطبیق دقیق آهنگ بر اساس ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -872,16 +872,10 @@ class AppLocalizationsFi extends AppLocalizations {
String get restore_defaults => 'Palauta oletukset'; String get restore_defaults => 'Palauta oletukset';
@override @override
String get download_music_format => 'Musiikin latausmuoto'; String get download_music_codec => 'Ladatun musiikin codefc';
@override @override
String get streaming_music_format => 'Musiikin suoratoistomuoto'; String get streaming_music_codec => 'Suoratoistetun musiikin codec';
@override
String get download_music_quality => 'Musiikin latauslaatu';
@override
String get streaming_music_quality => 'Musiikin suoratoistolaadun';
@override @override
String get login_with_lastfm => 'Kirjaudu sisään Last.fm:llä'; String get login_with_lastfm => 'Kirjaudu sisään Last.fm:llä';
@ -1449,16 +1443,7 @@ class AppLocalizationsFi extends AppLocalizations {
'Tämä lisäosa scrobblaa musiikkisi luodakseen kuunteluhistoriasi.'; 'Tämä lisäosa scrobblaa musiikkisi luodakseen kuunteluhistoriasi.';
@override @override
String get default_metadata_source => 'Oletusarvoinen metatietolähde'; String get default_plugin => 'Oletus';
@override
String get set_default_metadata_source => 'Aseta oletusmetatietolähde';
@override
String get default_audio_source => 'Oletusarvoinen äänilähde';
@override
String get set_default_audio_source => 'Aseta oletusäänilähde';
@override @override
String get set_default => 'Aseta oletukseksi'; String get set_default => 'Aseta oletukseksi';
@ -1518,7 +1503,7 @@ class AppLocalizationsFi extends AppLocalizations {
String get input_does_not_match_format => 'Syöte ei vastaa vaadittua muotoa'; String get input_does_not_match_format => 'Syöte ei vastaa vaadittua muotoa';
@override @override
String get plugins => 'Laajennukset'; String get metadata_provider_plugins => 'Metatietojen tarjoajan lisäosat';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1543,8 +1528,8 @@ class AppLocalizationsFi extends AppLocalizations {
String get available_plugins => 'Saatavilla olevat lisäosat'; String get available_plugins => 'Saatavilla olevat lisäosat';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Määritä omat metatietojen tarjoaja- ja äänilähdelaajennukset'; 'Määritä oma soittolistan/albumin/artistin/syötteen metatietojen tarjoaja';
@override @override
String get audio_scrobblers => 'Äänen scrobblerit'; String get audio_scrobblers => 'Äänen scrobblerit';
@ -1553,12 +1538,12 @@ class AppLocalizationsFi extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Lähde: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Pakkaamaton'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Audiofiileille. Tarjoaa korkealaatuisia/häviöttömiä äänivirtoja. Tarkka ISRC-pohjainen kappaleiden tunnistus.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -880,16 +880,10 @@ class AppLocalizationsFr extends AppLocalizations {
String get restore_defaults => 'Restaurer les valeurs par défaut'; String get restore_defaults => 'Restaurer les valeurs par défaut';
@override @override
String get download_music_format => 'Format de téléchargement de musique'; String get download_music_codec => 'Télécharger le codec musical';
@override @override
String get streaming_music_format => 'Format de streaming de musique'; String get streaming_music_codec => 'Codec de musique en streaming';
@override
String get download_music_quality => 'Qualité de téléchargement de musique';
@override
String get streaming_music_quality => 'Qualité de streaming de musique';
@override @override
String get login_with_lastfm => 'Se connecter avec Last.fm'; String get login_with_lastfm => 'Se connecter avec Last.fm';
@ -1463,17 +1457,7 @@ class AppLocalizationsFr extends AppLocalizations {
'Ce plugin scrobble votre musique pour générer votre historique d\'écoute.'; 'Ce plugin scrobble votre musique pour générer votre historique d\'écoute.';
@override @override
String get default_metadata_source => 'Source de métadonnées par défaut'; String get default_plugin => 'Par défaut';
@override
String get set_default_metadata_source =>
'Définir la source de métadonnées par défaut';
@override
String get default_audio_source => 'Source audio par défaut';
@override
String get set_default_audio_source => 'Définir la source audio par défaut';
@override @override
String get set_default => 'Définir par défaut'; String get set_default => 'Définir par défaut';
@ -1537,7 +1521,8 @@ class AppLocalizationsFr extends AppLocalizations {
'L\'entrée ne correspond pas au format requis'; 'L\'entrée ne correspond pas au format requis';
@override @override
String get plugins => 'Plugins'; String get metadata_provider_plugins =>
'Plugins de fournisseur de métadonnées';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1563,8 +1548,8 @@ class AppLocalizationsFr extends AppLocalizations {
String get available_plugins => 'Plugins disponibles'; String get available_plugins => 'Plugins disponibles';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configurez vos propres plugins de fournisseur de métadonnées et de source audio'; 'Configurer votre propre fournisseur de métadonnées de playlist/album/artiste/flux';
@override @override
String get audio_scrobblers => 'Scrobblers audio'; String get audio_scrobblers => 'Scrobblers audio';
@ -1573,12 +1558,12 @@ class AppLocalizationsFr extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Source : '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Non compressé'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Pour les audiophiles. Fournit des flux audio de haute qualité/sans perte. Correspondance précise des pistes basée sur ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -872,16 +872,10 @@ class AppLocalizationsHi extends AppLocalizations {
String get restore_defaults => 'डिफ़ॉल्ट सेटिंग्स को बहाल करें'; String get restore_defaults => 'डिफ़ॉल्ट सेटिंग्स को बहाल करें';
@override @override
String get download_music_format => 'संगीत डाउनलोड प्रारूप'; String get download_music_codec => 'संगीत कोडेक डाउनलोड करें';
@override @override
String get streaming_music_format => 'संगीत स्ट्रीमिंग प्रारूप'; String get streaming_music_codec => 'स्ट्रीमिंग संगीत कोडेक';
@override
String get download_music_quality => 'संगीत डाउनलोड गुणवत्ता';
@override
String get streaming_music_quality => 'संगीत स्ट्रीमिंग गुणवत्ता';
@override @override
String get login_with_lastfm => 'Last.fm से लॉगिन करें'; String get login_with_lastfm => 'Last.fm से लॉगिन करें';
@ -1454,16 +1448,7 @@ class AppLocalizationsHi extends AppLocalizations {
'यह प्लगइन आपके सुनने के इतिहास को उत्पन्न करने के लिए आपके संगीत को स्क्रॉबल करता है।'; 'यह प्लगइन आपके सुनने के इतिहास को उत्पन्न करने के लिए आपके संगीत को स्क्रॉबल करता है।';
@override @override
String get default_metadata_source => 'डिफ़ॉल्ट मेटाडेटा स्रोत'; String get default_plugin => 'डिफ़ॉल्ट';
@override
String get set_default_metadata_source => 'डिफ़ॉल्ट मेटाडेटा स्रोत सेट करें';
@override
String get default_audio_source => 'डिफ़ॉल्ट ऑडियो स्रोत';
@override
String get set_default_audio_source => 'डिफ़ॉल्ट ऑडियो स्रोत सेट करें';
@override @override
String get set_default => 'डिफ़ॉल्ट सेट करें'; String get set_default => 'डिफ़ॉल्ट सेट करें';
@ -1524,7 +1509,7 @@ class AppLocalizationsHi extends AppLocalizations {
'इनपुट आवश्यक प्रारूप से मेल नहीं खाता है'; 'इनपुट आवश्यक प्रारूप से मेल नहीं खाता है';
@override @override
String get plugins => 'प्लगइन्स'; String get metadata_provider_plugins => 'मेटाडेटा प्रदाता प्लगइन';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1549,8 +1534,8 @@ class AppLocalizationsHi extends AppLocalizations {
String get available_plugins => 'उपलब्ध प्लगइन'; String get available_plugins => 'उपलब्ध प्लगइन';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'अपने स्वयं के मेटाडेटा प्रदाता और ऑडियो स्रोत प्लगइन्स कॉन्फ़िगर करें'; 'अपनी खुद की प्लेलिस्ट/एल्बम/कलाकार/फ़ीड मेटाडेटा प्रदाता कॉन्फ़िगर करें';
@override @override
String get audio_scrobblers => 'ऑडियो स्क्रॉबलर्स'; String get audio_scrobblers => 'ऑडियो स्क्रॉबलर्स';
@ -1559,12 +1544,12 @@ class AppLocalizationsHi extends AppLocalizations {
String get scrobbling => 'स्क्रॉबलिंग'; String get scrobbling => 'स्क्रॉबलिंग';
@override @override
String get source => 'स्रोत: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'असंपीड़ित'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'ऑडियोफाइलों के लिए। उच्च-गुणवत्ता/बिना हानि वाले ऑडियो स्ट्रीम प्रदान करता है। सटीक ISRC आधारित ट्रैक मिलान।'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -874,16 +874,10 @@ class AppLocalizationsId extends AppLocalizations {
String get restore_defaults => 'Kembalikan semula'; String get restore_defaults => 'Kembalikan semula';
@override @override
String get download_music_format => 'Format unduh musik'; String get download_music_codec => 'Unduh codec musik';
@override @override
String get streaming_music_format => 'Format streaming musik'; String get streaming_music_codec => 'Streaming codec musik';
@override
String get download_music_quality => 'Kualitas unduh musik';
@override
String get streaming_music_quality => 'Kualitas streaming musik';
@override @override
String get login_with_lastfm => 'Masuk dengan Last.fm'; String get login_with_lastfm => 'Masuk dengan Last.fm';
@ -1455,16 +1449,7 @@ class AppLocalizationsId extends AppLocalizations {
'Plugin ini scrobble musik Anda untuk menghasilkan riwayat mendengarkan Anda.'; 'Plugin ini scrobble musik Anda untuk menghasilkan riwayat mendengarkan Anda.';
@override @override
String get default_metadata_source => 'Sumber metadata default'; String get default_plugin => 'Bawaan';
@override
String get set_default_metadata_source => 'Atur sumber metadata default';
@override
String get default_audio_source => 'Sumber audio default';
@override
String get set_default_audio_source => 'Atur sumber audio default';
@override @override
String get set_default => 'Atur sebagai bawaan'; String get set_default => 'Atur sebagai bawaan';
@ -1526,7 +1511,7 @@ class AppLocalizationsId extends AppLocalizations {
'Masukan tidak cocok dengan format yang diperlukan'; 'Masukan tidak cocok dengan format yang diperlukan';
@override @override
String get plugins => 'Plugin'; String get metadata_provider_plugins => 'Plugin Penyedia Metadata';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1551,8 +1536,8 @@ class AppLocalizationsId extends AppLocalizations {
String get available_plugins => 'Plugin yang tersedia'; String get available_plugins => 'Plugin yang tersedia';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Konfigurasi plugin penyedia metadata dan sumber audio Anda sendiri'; 'Konfigurasi penyedia metadata playlist/album/artis/feed Anda sendiri';
@override @override
String get audio_scrobblers => 'Scrobblers Audio'; String get audio_scrobblers => 'Scrobblers Audio';
@ -1561,12 +1546,12 @@ class AppLocalizationsId extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Sumber: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Tidak terkompresi'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Untuk audiophile. Menyediakan aliran audio berkualitas tinggi/tanpa kehilangan. Pencocokkan trek yang akurat berdasarkan ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -874,16 +874,10 @@ class AppLocalizationsIt extends AppLocalizations {
String get restore_defaults => 'Ripristina default'; String get restore_defaults => 'Ripristina default';
@override @override
String get download_music_format => 'Formato download musica'; String get download_music_codec => 'Codec musicale scaricamento';
@override @override
String get streaming_music_format => 'Formato streaming musica'; String get streaming_music_codec => 'Codec musicale streaming';
@override
String get download_music_quality => 'Qualità download musica';
@override
String get streaming_music_quality => 'Qualità streaming musica';
@override @override
String get login_with_lastfm => 'Accesso a Last.fm'; String get login_with_lastfm => 'Accesso a Last.fm';
@ -1454,17 +1448,7 @@ class AppLocalizationsIt extends AppLocalizations {
'Questo plugin scrobbla la tua musica per generare la tua cronologia di ascolti.'; 'Questo plugin scrobbla la tua musica per generare la tua cronologia di ascolti.';
@override @override
String get default_metadata_source => 'Fonte metadati predefinita'; String get default_plugin => 'Predefinito';
@override
String get set_default_metadata_source =>
'Imposta fonte metadati predefinita';
@override
String get default_audio_source => 'Fonte audio predefinita';
@override
String get set_default_audio_source => 'Imposta fonte audio predefinita';
@override @override
String get set_default => 'Imposta come predefinito'; String get set_default => 'Imposta come predefinito';
@ -1526,7 +1510,7 @@ class AppLocalizationsIt extends AppLocalizations {
'L\'input non corrisponde al formato richiesto'; 'L\'input non corrisponde al formato richiesto';
@override @override
String get plugins => 'Plugin'; String get metadata_provider_plugins => 'Plugin del provider di metadati';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1551,8 +1535,8 @@ class AppLocalizationsIt extends AppLocalizations {
String get available_plugins => 'Plugin disponibili'; String get available_plugins => 'Plugin disponibili';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configura i tuoi plugin per fornitore metadati e fonte audio'; 'Configura il tuo provider di metadati per playlist/album/artista/feed';
@override @override
String get audio_scrobblers => 'Scrobbler audio'; String get audio_scrobblers => 'Scrobbler audio';
@ -1561,12 +1545,12 @@ class AppLocalizationsIt extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Fonte: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Non compresso'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Per audiophile. Fornisce flussi audio di alta qualità/senza perdita. Abbinamento traccia accurato basato su ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -861,16 +861,10 @@ class AppLocalizationsJa extends AppLocalizations {
String get restore_defaults => '設定を初期化'; String get restore_defaults => '設定を初期化';
@override @override
String get download_music_format => '音楽ダウンロード形式'; String get download_music_codec => 'ダウンロード用の音声コーデック';
@override @override
String get streaming_music_format => '音楽ストリーミング形式'; String get streaming_music_codec => 'ストリーミング用の音声コーデック';
@override
String get download_music_quality => '音楽ダウンロード品質';
@override
String get streaming_music_quality => '音楽ストリーミング品質';
@override @override
String get login_with_lastfm => 'Last.fmでログイン'; String get login_with_lastfm => 'Last.fmでログイン';
@ -1422,16 +1416,7 @@ class AppLocalizationsJa extends AppLocalizations {
String get plugin_scrobbling_info => 'このプラグインは、あなたの音楽をscrobbleして視聴履歴を生成します。'; String get plugin_scrobbling_info => 'このプラグインは、あなたの音楽をscrobbleして視聴履歴を生成します。';
@override @override
String get default_metadata_source => 'デフォルトメタデータソース'; String get default_plugin => 'デフォルト';
@override
String get set_default_metadata_source => 'デフォルトメタデータソースを設定';
@override
String get default_audio_source => 'デフォルトオーディオソース';
@override
String get set_default_audio_source => 'デフォルトオーディオソースを設定';
@override @override
String get set_default => 'デフォルトに設定'; String get set_default => 'デフォルトに設定';
@ -1489,7 +1474,7 @@ class AppLocalizationsJa extends AppLocalizations {
String get input_does_not_match_format => '入力が必須フォーマットと一致しません'; String get input_does_not_match_format => '入力が必須フォーマットと一致しません';
@override @override
String get plugins => 'プラグイン'; String get metadata_provider_plugins => 'メタデータプロバイダープラグイン';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1514,7 +1499,8 @@ class AppLocalizationsJa extends AppLocalizations {
String get available_plugins => '利用可能なプラグイン'; String get available_plugins => '利用可能なプラグイン';
@override @override
String get configure_plugins => '独自のメタデータプロバイダーとオーディオソースプラグインを設定'; String get configure_your_own_metadata_plugin =>
'独自のプレイリスト/アルバム/アーティスト/フィードのメタデータプロバイダーを構成';
@override @override
String get audio_scrobblers => 'オーディオスクロッブラー'; String get audio_scrobblers => 'オーディオスクロッブラー';
@ -1523,12 +1509,12 @@ class AppLocalizationsJa extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'ソース: '; String get source => 'Source: ';
@override @override
String get uncompressed => '非圧縮'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'オーディオファイル向け。高品質/ロスレスオーディオストリームを提供。正確なISRCベースのトラックマッチング。'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -872,16 +872,10 @@ class AppLocalizationsKa extends AppLocalizations {
String get restore_defaults => 'ნაგულისხმევი პარამეტრების აღდგენა'; String get restore_defaults => 'ნაგულისხმევი პარამეტრების აღდგენა';
@override @override
String get download_music_format => 'მუსიკის ჩამოტვირთვის ფორმატი'; String get download_music_codec => 'მუსიკის კოდეკის გადმოწერა';
@override @override
String get streaming_music_format => 'სტრიმინგის მუსიკის ფორმატი'; String get streaming_music_codec => 'სტრიმინგ მუსიკის კოდეკი';
@override
String get download_music_quality => 'ჩამოტვირთვის ხარისხი';
@override
String get streaming_music_quality => 'სტრიმინგის ხარისხი';
@override @override
String get login_with_lastfm => 'Last.fm-ით შესვლა'; String get login_with_lastfm => 'Last.fm-ით შესვლა';
@ -1454,17 +1448,7 @@ class AppLocalizationsKa extends AppLocalizations {
'ეს პლაგინი აწარმოებს თქვენი მუსიკის სქრობლინგს, რათა შექმნას თქვენი მოსმენის ისტორია.'; 'ეს პლაგინი აწარმოებს თქვენი მუსიკის სქრობლინგს, რათა შექმნას თქვენი მოსმენის ისტორია.';
@override @override
String get default_metadata_source => 'ნაგულისხმევი მეტამონაცემების წყარო'; String get default_plugin => 'ნაგულისხმევი';
@override
String get set_default_metadata_source =>
'ნაგულისხმევი მეტამონაცემების წყაროს დაყენება';
@override
String get default_audio_source => 'ნაგულისხმევი აუდიო წყარო';
@override
String get set_default_audio_source => 'ნაგულისხმევი აუდიო წყაროს დაყენება';
@override @override
String get set_default => 'ნაგულისხმევად დაყენება'; String get set_default => 'ნაგულისხმევად დაყენება';
@ -1527,7 +1511,8 @@ class AppLocalizationsKa extends AppLocalizations {
'შეყვანა არ ემთხვევა საჭირო ფორმატს'; 'შეყვანა არ ემთხვევა საჭირო ფორმატს';
@override @override
String get plugins => 'პლაგინები'; String get metadata_provider_plugins =>
'მეტამონაცემების პროვაიდერების პლაგინები';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1552,8 +1537,8 @@ class AppLocalizationsKa extends AppLocalizations {
String get available_plugins => 'ხელმისაწვდომი პლაგინები'; String get available_plugins => 'ხელმისაწვდომი პლაგინები';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'თქვენი საკუთარი მეტამონაცემებისა და აუდიო წყაროს პლაგინების კონფიგურაცია'; 'დააყენეთ თქვენი საკუთარი პლეილისტის/ალბომის/არტისტის/ფიდის მეტამონაცემების პროვაიდერი';
@override @override
String get audio_scrobblers => 'აუდიო სქრობლერები'; String get audio_scrobblers => 'აუდიო სქრობლერები';
@ -1562,12 +1547,12 @@ class AppLocalizationsKa extends AppLocalizations {
String get scrobbling => 'სქრობლინგი'; String get scrobbling => 'სქრობლინგი';
@override @override
String get source => 'წყარო: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'შეუკუმშავი'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'აუდიოფილებისთვის. უზრუნველყოფს მაღალი ხარისხის/უკომპრესო აუდიო სტრიმებს. ზუსტი შესაბამისობა ISRC-ის მიხედვით.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -862,16 +862,10 @@ class AppLocalizationsKo extends AppLocalizations {
String get restore_defaults => '기본값으로 복원'; String get restore_defaults => '기본값으로 복원';
@override @override
String get download_music_format => '다운로드 음악 포맷'; String get download_music_codec => '다운로드 음악 코덱';
@override @override
String get streaming_music_format => '스트리밍 음악 포맷'; String get streaming_music_codec => '스트리밍 음악 코덱';
@override
String get download_music_quality => '다운로드 음질';
@override
String get streaming_music_quality => '스트리밍 음질';
@override @override
String get login_with_lastfm => 'Last.fm에 로그인'; String get login_with_lastfm => 'Last.fm에 로그인';
@ -1427,16 +1421,7 @@ class AppLocalizationsKo extends AppLocalizations {
String get plugin_scrobbling_info => '이 플러그인은 음악을 스크로블하여 청취 기록을 생성합니다.'; String get plugin_scrobbling_info => '이 플러그인은 음악을 스크로블하여 청취 기록을 생성합니다.';
@override @override
String get default_metadata_source => '기본 메타데이터 소스'; String get default_plugin => '기본';
@override
String get set_default_metadata_source => '기본 메타데이터 소스 설정';
@override
String get default_audio_source => '기본 오디오 소스';
@override
String get set_default_audio_source => '기본 오디오 소스 설정';
@override @override
String get set_default => '기본값으로 설정'; String get set_default => '기본값으로 설정';
@ -1494,7 +1479,7 @@ class AppLocalizationsKo extends AppLocalizations {
String get input_does_not_match_format => '입력이 필요한 형식과 일치하지 않습니다'; String get input_does_not_match_format => '입력이 필요한 형식과 일치하지 않습니다';
@override @override
String get plugins => '플러그인'; String get metadata_provider_plugins => '메타데이터 제공자 플러그인';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1518,7 +1503,8 @@ class AppLocalizationsKo extends AppLocalizations {
String get available_plugins => '사용 가능한 플러그인'; String get available_plugins => '사용 가능한 플러그인';
@override @override
String get configure_plugins => '직접 메타데이터 제공자와 오디오 소스 플러그인을 구성하세요'; String get configure_your_own_metadata_plugin =>
'자신만의 플레이리스트/앨범/아티스트/피드 메타데이터 제공자 구성';
@override @override
String get audio_scrobblers => '오디오 스크로블러'; String get audio_scrobblers => '오디오 스크로블러';
@ -1527,12 +1513,12 @@ class AppLocalizationsKo extends AppLocalizations {
String get scrobbling => '스크로블링'; String get scrobbling => '스크로블링';
@override @override
String get source => '출처: '; String get source => 'Source: ';
@override @override
String get uncompressed => '비압축'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'오디오파일을 위한 소스입니다. 고음질/무손실 오디오 스트림을 제공하며 ISRC 기반으로 정확한 트랙 매칭을 지원합니다.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -880,16 +880,10 @@ class AppLocalizationsNe extends AppLocalizations {
String get restore_defaults => 'पूर्वनिर्धारितहरू पुनः स्थापित गर्नुहोस्'; String get restore_defaults => 'पूर्वनिर्धारितहरू पुनः स्थापित गर्नुहोस्';
@override @override
String get download_music_format => 'सङ्गीत डाउनलोड ढाँचा'; String get download_music_codec => 'साङ्गीत कोडेक डाउनलोड गर्नुहोस्';
@override @override
String get streaming_music_format => 'स्ट्रिमिङ सङ्गीत ढाँचा'; String get streaming_music_codec => 'स्ट्रिमिङ साङ्गीत कोडेक';
@override
String get download_music_quality => 'डाउनलोड गुणस्तर';
@override
String get streaming_music_quality => 'स्ट्रिमिङ गुणस्तर';
@override @override
String get login_with_lastfm => 'लास्ट.एफ.एम सँग लगइन गर्नुहोस्'; String get login_with_lastfm => 'लास्ट.एफ.एम सँग लगइन गर्नुहोस्';
@ -1460,18 +1454,7 @@ class AppLocalizationsNe extends AppLocalizations {
'यो प्लगइनले तपाईंको सुन्ने इतिहास उत्पन्न गर्न तपाईंको संगीतलाई स्क्रब्बल गर्दछ।'; 'यो प्लगइनले तपाईंको सुन्ने इतिहास उत्पन्न गर्न तपाईंको संगीतलाई स्क्रब्बल गर्दछ।';
@override @override
String get default_metadata_source => 'पूर्वनिर्धारित मेटाडाटा स्रोत'; String get default_plugin => 'पूर्वनिर्धारित';
@override
String get set_default_metadata_source =>
'पूर्वनिर्धारित मेटाडाटा स्रोत सेट गर्नुहोस्';
@override
String get default_audio_source => 'पूर्वनिर्धारित अडियो स्रोत';
@override
String get set_default_audio_source =>
'पूर्वनिर्धारित अडियो स्रोत सेट गर्नुहोस्';
@override @override
String get set_default => 'पूर्वनिर्धारित सेट गर्नुहोस्'; String get set_default => 'पूर्वनिर्धारित सेट गर्नुहोस्';
@ -1532,7 +1515,7 @@ class AppLocalizationsNe extends AppLocalizations {
String get input_does_not_match_format => 'इनपुट आवश्यक ढाँचासँग मेल खाँदैन'; String get input_does_not_match_format => 'इनपुट आवश्यक ढाँचासँग मेल खाँदैन';
@override @override
String get plugins => 'प्लगइनहरू'; String get metadata_provider_plugins => 'मेटाडेटा प्रदायक प्लगइनहरू';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1557,8 +1540,8 @@ class AppLocalizationsNe extends AppLocalizations {
String get available_plugins => 'उपलब्ध प्लगइनहरू'; String get available_plugins => 'उपलब्ध प्लगइनहरू';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'आफ्नै मेटाडाटा प्रदायक र अडियो स्रोत प्लगइनहरू कन्फिगर गर्नुहोस्'; 'तपाईंको आफ्नै प्लेलिस्ट/एल्बम/कलाकार/फिड मेटाडेटा प्रदायक कन्फिगर गर्नुहोस्';
@override @override
String get audio_scrobblers => 'अडियो स्क्रब्बलरहरू'; String get audio_scrobblers => 'अडियो स्क्रब्बलरहरू';
@ -1567,12 +1550,12 @@ class AppLocalizationsNe extends AppLocalizations {
String get scrobbling => 'स्क्रब्बलिंग'; String get scrobbling => 'स्क्रब्बलिंग';
@override @override
String get source => 'स्रोत: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'असंक्षिप्त'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'अडियोप्रेमीहरूका लागि। उच्च गुणस्तर/लसलेस अडियो स्ट्रिमहरू उपलब्ध गराउँछ। ISRC-मा आधारित सटीक ट्र्याक मिलान।'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -815,7 +815,7 @@ class AppLocalizationsNl extends AppLocalizations {
String get search_mode => 'Zoekmodus'; String get search_mode => 'Zoekmodus';
@override @override
String get audio_source => 'Audiobron'; String get audio_source => 'Audio Source';
@override @override
String get ok => 'Oké'; String get ok => 'Oké';
@ -872,16 +872,10 @@ class AppLocalizationsNl extends AppLocalizations {
String get restore_defaults => 'Standaardwaarden herstellen'; String get restore_defaults => 'Standaardwaarden herstellen';
@override @override
String get download_music_format => 'Download muziekformaat'; String get download_music_codec => 'Download-codec';
@override @override
String get streaming_music_format => 'Streaming muziekformaat'; String get streaming_music_codec => 'Streaming-codec';
@override
String get download_music_quality => 'Downloadkwaliteit';
@override
String get streaming_music_quality => 'Streamingkwaliteit';
@override @override
String get login_with_lastfm => 'Inloggen met Last.fm'; String get login_with_lastfm => 'Inloggen met Last.fm';
@ -1452,16 +1446,7 @@ class AppLocalizationsNl extends AppLocalizations {
'Deze plugin scrobblet uw muziek om uw luistergeschiedenis te genereren.'; 'Deze plugin scrobblet uw muziek om uw luistergeschiedenis te genereren.';
@override @override
String get default_metadata_source => 'Standaard metadata-bron'; String get default_plugin => 'Standaard';
@override
String get set_default_metadata_source => 'Standaard metadata-bron instellen';
@override
String get default_audio_source => 'Standaard audiobron';
@override
String get set_default_audio_source => 'Standaard audiobron instellen';
@override @override
String get set_default => 'Instellen als standaard'; String get set_default => 'Instellen als standaard';
@ -1524,7 +1509,7 @@ class AppLocalizationsNl extends AppLocalizations {
'Invoer komt niet overeen met het vereiste formaat'; 'Invoer komt niet overeen met het vereiste formaat';
@override @override
String get plugins => 'Plug-ins'; String get metadata_provider_plugins => 'Metadata-aanbieder Plugins';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1549,8 +1534,8 @@ class AppLocalizationsNl extends AppLocalizations {
String get available_plugins => 'Beschikbare plugins'; String get available_plugins => 'Beschikbare plugins';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configureer je eigen metadata- en audiobron-plug-ins'; 'Configureer uw eigen metadata-aanbieder voor afspeellijst/album/artiest/feed';
@override @override
String get audio_scrobblers => 'Audioscrobblers'; String get audio_scrobblers => 'Audioscrobblers';
@ -1559,12 +1544,12 @@ class AppLocalizationsNl extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Bron: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Ongecomprimeerd'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Voor audiofielen. Biedt hoge kwaliteit/lossless audiostreams. Nauwkeurige trackmatching op basis van ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -873,16 +873,10 @@ class AppLocalizationsPl extends AppLocalizations {
String get restore_defaults => 'Przywróć domyślne'; String get restore_defaults => 'Przywróć domyślne';
@override @override
String get download_music_format => 'Format pobierania muzyki'; String get download_music_codec => 'Pobierz kodek muzyczny';
@override @override
String get streaming_music_format => 'Format strumieniowania muzyki'; String get streaming_music_codec => 'Kodek strumieniowy muzyki';
@override
String get download_music_quality => 'Jakość pobierania';
@override
String get streaming_music_quality => 'Jakość strumieniowania';
@override @override
String get login_with_lastfm => 'Zaloguj się z Last.fm'; String get login_with_lastfm => 'Zaloguj się z Last.fm';
@ -1455,16 +1449,7 @@ class AppLocalizationsPl extends AppLocalizations {
'Ta wtyczka scrobbluje Twoją muzykę, aby wygenerować historię odsłuchań.'; 'Ta wtyczka scrobbluje Twoją muzykę, aby wygenerować historię odsłuchań.';
@override @override
String get default_metadata_source => 'Domyślne źródło metadanych'; String get default_plugin => 'Domyślna';
@override
String get set_default_metadata_source => 'Ustaw domyślne źródło metadanych';
@override
String get default_audio_source => 'Domyślne źródło audio';
@override
String get set_default_audio_source => 'Ustaw domyślne źródło audio';
@override @override
String get set_default => 'Ustaw jako domyślną'; String get set_default => 'Ustaw jako domyślną';
@ -1526,7 +1511,7 @@ class AppLocalizationsPl extends AppLocalizations {
'Wprowadzony tekst nie pasuje do wymaganego formatu'; 'Wprowadzony tekst nie pasuje do wymaganego formatu';
@override @override
String get plugins => 'Wtyczki'; String get metadata_provider_plugins => 'Wtyczki dostawców metadanych';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1551,8 +1536,8 @@ class AppLocalizationsPl extends AppLocalizations {
String get available_plugins => 'Dostępne wtyczki'; String get available_plugins => 'Dostępne wtyczki';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Skonfiguruj własne wtyczki dostawców metadanych i źródeł audio'; 'Skonfiguruj własnego dostawcę metadanych dla playlisty/albumu/artysty/kanału';
@override @override
String get audio_scrobblers => 'Scrobblery audio'; String get audio_scrobblers => 'Scrobblery audio';
@ -1561,12 +1546,12 @@ class AppLocalizationsPl extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Źródło: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Nieskompresowany'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Dla audiofilów. Oferuje strumienie audio wysokiej jakości/lossless. Precyzyjne dopasowanie utworów na podstawie ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -873,16 +873,10 @@ class AppLocalizationsPt extends AppLocalizations {
String get restore_defaults => 'Restaurar padrões'; String get restore_defaults => 'Restaurar padrões';
@override @override
String get download_music_format => 'Formato de download de música'; String get download_music_codec => 'Descarregar codec de música';
@override @override
String get streaming_music_format => 'Formato de streaming de música'; String get streaming_music_codec => 'Codec de streaming de música';
@override
String get download_music_quality => 'Qualidade de download';
@override
String get streaming_music_quality => 'Qualidade de streaming';
@override @override
String get login_with_lastfm => 'Iniciar sessão com o Last.fm'; String get login_with_lastfm => 'Iniciar sessão com o Last.fm';
@ -1452,16 +1446,7 @@ class AppLocalizationsPt extends AppLocalizations {
'Este plugin faz o scrobbling de sua música para gerar seu histórico de audição.'; 'Este plugin faz o scrobbling de sua música para gerar seu histórico de audição.';
@override @override
String get default_metadata_source => 'Fonte padrão de metadados'; String get default_plugin => 'Padrão';
@override
String get set_default_metadata_source => 'Definir fonte padrão de metadados';
@override
String get default_audio_source => 'Fonte de áudio padrão';
@override
String get set_default_audio_source => 'Definir fonte de áudio padrão';
@override @override
String get set_default => 'Definir como padrão'; String get set_default => 'Definir como padrão';
@ -1523,7 +1508,7 @@ class AppLocalizationsPt extends AppLocalizations {
'A entrada não corresponde ao formato exigido'; 'A entrada não corresponde ao formato exigido';
@override @override
String get plugins => 'Plugins'; String get metadata_provider_plugins => 'Plugins do provedor de metadados';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1548,8 +1533,8 @@ class AppLocalizationsPt extends AppLocalizations {
String get available_plugins => 'Plugins disponíveis'; String get available_plugins => 'Plugins disponíveis';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Configure seus próprios plugins de provedores de metadados e fontes de áudio'; 'Configure seu próprio provedor de metadados de playlist/álbum/artista/feed';
@override @override
String get audio_scrobblers => 'Scrobblers de áudio'; String get audio_scrobblers => 'Scrobblers de áudio';
@ -1558,12 +1543,12 @@ class AppLocalizationsPt extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Fonte: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Não comprimido'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Para audiófilos. Fornece streams de áudio de alta qualidade/sem perdas. Correspondência precisa de faixas baseada em ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -874,16 +874,10 @@ class AppLocalizationsRu extends AppLocalizations {
String get restore_defaults => 'Восстановить настройки по умолчанию'; String get restore_defaults => 'Восстановить настройки по умолчанию';
@override @override
String get download_music_format => 'Формат загрузки музыки'; String get download_music_codec => 'Загрузить кодек для музыки';
@override @override
String get streaming_music_format => 'Формат потоковой музыки'; String get streaming_music_codec => 'Кодек потоковой передачи музыки';
@override
String get download_music_quality => 'Качество загрузки';
@override
String get streaming_music_quality => 'Качество стриминга';
@override @override
String get login_with_lastfm => 'Войти с помощью Last.fm'; String get login_with_lastfm => 'Войти с помощью Last.fm';
@ -1454,17 +1448,7 @@ class AppLocalizationsRu extends AppLocalizations {
'Этот плагин скробблит вашу музыку для создания вашей истории прослушиваний.'; 'Этот плагин скробблит вашу музыку для создания вашей истории прослушиваний.';
@override @override
String get default_metadata_source => 'Источник метаданных по умолчанию'; String get default_plugin => 'По умолчанию';
@override
String get set_default_metadata_source =>
'Задать источник метаданных по умолчанию';
@override
String get default_audio_source => 'Источник аудио по умолчанию';
@override
String get set_default_audio_source => 'Задать источник аудио по умолчанию';
@override @override
String get set_default => 'Установить по умолчанию'; String get set_default => 'Установить по умолчанию';
@ -1527,7 +1511,7 @@ class AppLocalizationsRu extends AppLocalizations {
'Введенные данные не соответствуют требуемому формату'; 'Введенные данные не соответствуют требуемому формату';
@override @override
String get plugins => 'Плагины'; String get metadata_provider_plugins => 'Плагины поставщика метаданных';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1552,8 +1536,8 @@ class AppLocalizationsRu extends AppLocalizations {
String get available_plugins => 'Доступные плагины'; String get available_plugins => 'Доступные плагины';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Настройте собственные плагины провайдеров метаданных и источников аудио'; 'Настройте свой собственный поставщик метаданных для плейлиста/альбома/артиста/ленты';
@override @override
String get audio_scrobblers => 'Аудио скробблеры'; String get audio_scrobblers => 'Аудио скробблеры';
@ -1562,12 +1546,12 @@ class AppLocalizationsRu extends AppLocalizations {
String get scrobbling => 'Скробблинг'; String get scrobbling => 'Скробблинг';
@override @override
String get source => 'Источник: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Несжатый'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Для аудиофилов. Предоставляет высококачественные/lossless аудиопотоки. Точное совпадение треков по ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -879,16 +879,10 @@ class AppLocalizationsTa extends AppLocalizations {
String get restore_defaults => 'இயல்புநிலைகளை மீட்டமை'; String get restore_defaults => 'இயல்புநிலைகளை மீட்டமை';
@override @override
String get download_music_format => 'இசை பதிவிறக்க வடிவம்'; String get download_music_codec => 'இசை கோடெக்கை பதிவிறக்கு';
@override @override
String get streaming_music_format => 'இசை ஸ்ட்ரீமிங் வடிவம்'; String get streaming_music_codec => 'இசை கோடெக்கை ஸ்ட்ரீம் செய்';
@override
String get download_music_quality => 'பதிவிறக்க தரம்';
@override
String get streaming_music_quality => 'ஸ்ட்ரீமிங் தரம்';
@override @override
String get login_with_lastfm => 'Last.fm உடன் உள்நுழைக'; String get login_with_lastfm => 'Last.fm உடன் உள்நுழைக';
@ -1461,17 +1455,7 @@ class AppLocalizationsTa extends AppLocalizations {
'இந்த பிளகின் உங்கள் கேட்பதின் வரலாற்றை உருவாக்க உங்கள் இசையை ஸ்க்ரோப்ள் செய்கிறது.'; 'இந்த பிளகின் உங்கள் கேட்பதின் வரலாற்றை உருவாக்க உங்கள் இசையை ஸ்க்ரோப்ள் செய்கிறது.';
@override @override
String get default_metadata_source => 'இயல்புநிலை மெட்டாடேட்டா மூலம்'; String get default_plugin => 'இயல்புநிலை';
@override
String get set_default_metadata_source =>
'இயல்புநிலை மெட்டாடேட்டா மூலத்தை அமை';
@override
String get default_audio_source => 'இயல்புநிலை ஆடியோ மூலம்';
@override
String get set_default_audio_source => 'இயல்புநிலை ஆடியோ மூலத்தை அமை';
@override @override
String get set_default => 'இயல்புநிலையாக அமைக்கவும்'; String get set_default => 'இயல்புநிலையாக அமைக்கவும்';
@ -1533,7 +1517,7 @@ class AppLocalizationsTa extends AppLocalizations {
'உள்ளீடு தேவையான வடிவத்துடன் பொருந்தவில்லை'; 'உள்ளீடு தேவையான வடிவத்துடன் பொருந்தவில்லை';
@override @override
String get plugins => 'செருகுநிரல்கள்'; String get metadata_provider_plugins => 'மெட்டாடேட்டா வழங்குநர் பிளகின்கள்';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1558,8 +1542,8 @@ class AppLocalizationsTa extends AppLocalizations {
String get available_plugins => 'கிடைக்கக்கூடிய பிளகின்கள்'; String get available_plugins => 'கிடைக்கக்கூடிய பிளகின்கள்';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'உங்கள் சொந்த மெட்டாடேட்டா வழங்குநர் மற்றும் ஆடியோ மூல செருகுநிரல்களை அமைக்கவும்'; 'உங்கள் சொந்த பிளேலிஸ்ட்/ஆல்பம்/கலைஞர்/ஊட்ட மெட்டாடேட்டா வழங்குநரை உள்ளமைக்கவும்';
@override @override
String get audio_scrobblers => 'ஆடியோ ஸ்க்ரோப்ளர்கள்'; String get audio_scrobblers => 'ஆடியோ ஸ்க்ரோப்ளர்கள்';
@ -1568,12 +1552,12 @@ class AppLocalizationsTa extends AppLocalizations {
String get scrobbling => 'ஸ்க்ரோப்ளிங்'; String get scrobbling => 'ஸ்க்ரோப்ளிங்';
@override @override
String get source => 'மூலம்: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'அழுத்தப்படாத'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'ஆடியோஃபைல்களுக்காக. உயர்தர/லாஸ்லெஸ் ஆடியோ ஸ்ட்ரீம்களை வழங்குகிறது. ISRC அடிப்படையில் துல்லியமான பாடல் பொருத்தம்.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -872,16 +872,10 @@ class AppLocalizationsTh extends AppLocalizations {
String get restore_defaults => 'คืนค่าเริ่มต้น'; String get restore_defaults => 'คืนค่าเริ่มต้น';
@override @override
String get download_music_format => 'รูปแบบการดาวน์โหลดเพลง'; String get download_music_codec => 'ดาวน์โหลดโคเดคเพลง';
@override @override
String get streaming_music_format => 'รูปแบบการสตรีมเพลง'; String get streaming_music_codec => 'สตรีมมิ่งโคเดคเพลง';
@override
String get download_music_quality => 'คุณภาพการดาวน์โหลด';
@override
String get streaming_music_quality => 'คุณภาพการสตรีม';
@override @override
String get login_with_lastfm => 'เข้าสู่ระบบด้วย Last.fm'; String get login_with_lastfm => 'เข้าสู่ระบบด้วย Last.fm';
@ -1446,16 +1440,7 @@ class AppLocalizationsTh extends AppLocalizations {
'ปลั๊กอินนี้จะ scrobble เพลงของคุณเพื่อสร้างประวัติการฟังของคุณ'; 'ปลั๊กอินนี้จะ scrobble เพลงของคุณเพื่อสร้างประวัติการฟังของคุณ';
@override @override
String get default_metadata_source => 'แหล่งเมตาดาต้าพื้นฐาน'; String get default_plugin => 'ค่าเริ่มต้น';
@override
String get set_default_metadata_source => 'ตั้งค่าแหล่งเมตาดาต้าพื้นฐาน';
@override
String get default_audio_source => 'แหล่งเสียงพื้นฐาน';
@override
String get set_default_audio_source => 'ตั้งค่าแหล่งเสียงพื้นฐาน';
@override @override
String get set_default => 'ตั้งค่าเริ่มต้น'; String get set_default => 'ตั้งค่าเริ่มต้น';
@ -1515,7 +1500,7 @@ class AppLocalizationsTh extends AppLocalizations {
String get input_does_not_match_format => 'อินพุตไม่ตรงกับรูปแบบที่ต้องการ'; String get input_does_not_match_format => 'อินพุตไม่ตรงกับรูปแบบที่ต้องการ';
@override @override
String get plugins => 'ปลั๊กอิน'; String get metadata_provider_plugins => 'ปลั๊กอินผู้ให้บริการเมตาดาต้า';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1540,8 +1525,8 @@ class AppLocalizationsTh extends AppLocalizations {
String get available_plugins => 'ปลั๊กอินที่มีอยู่'; String get available_plugins => 'ปลั๊กอินที่มีอยู่';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'กำหนดค่าปลั๊กอินผู้ให้บริการเมตาดาต้าและแหล่งเสียงของคุณเอง'; 'กำหนดค่าผู้ให้บริการเมตาดาต้าเพลย์ลิสต์/อัลบั้ม/ศิลปิน/ฟีดของคุณเอง';
@override @override
String get audio_scrobblers => 'เครื่อง scrobbler เสียง'; String get audio_scrobblers => 'เครื่อง scrobbler เสียง';
@ -1550,12 +1535,12 @@ class AppLocalizationsTh extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'แหล่งที่มา: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'ไม่บีบอัด'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'สำหรับคนรักเสียงเพลง ให้สตรีมเสียงคุณภาพสูง/ไร้การสูญเสียการบีบอัด การจับคู่แทร็กแม่นยำตาม ISRC'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -878,16 +878,10 @@ class AppLocalizationsTl extends AppLocalizations {
String get restore_defaults => 'Ibalik ang mga default'; String get restore_defaults => 'Ibalik ang mga default';
@override @override
String get download_music_format => 'I-download na format ng musika'; String get download_music_codec => 'Codec para sa pag-download ng musika';
@override @override
String get streaming_music_format => 'Format ng streaming ng musika'; String get streaming_music_codec => 'Codec para sa pag-stream ng musika';
@override
String get download_music_quality => 'Kalidad ng i-download na musika';
@override
String get streaming_music_quality => 'Kalidad ng streaming ng musika';
@override @override
String get login_with_lastfm => 'Mag-login gamit ang Last.fm'; String get login_with_lastfm => 'Mag-login gamit ang Last.fm';
@ -1462,18 +1456,7 @@ class AppLocalizationsTl extends AppLocalizations {
'Sinis-scrobble ng plugin na ito ang iyong musika upang mabuo ang iyong kasaysayan ng pakikinig.'; 'Sinis-scrobble ng plugin na ito ang iyong musika upang mabuo ang iyong kasaysayan ng pakikinig.';
@override @override
String get default_metadata_source => 'Default na pinagmulan ng metadata'; String get default_plugin => 'Default';
@override
String get set_default_metadata_source =>
'Itakda ang default na pinagmulan ng metadata';
@override
String get default_audio_source => 'Default na pinagmulan ng audio';
@override
String get set_default_audio_source =>
'Itakda ang default na pinagmulan ng audio';
@override @override
String get set_default => 'Itakda bilang default'; String get set_default => 'Itakda bilang default';
@ -1535,7 +1518,7 @@ class AppLocalizationsTl extends AppLocalizations {
'Ang input ay hindi tumutugma sa kinakailangang format'; 'Ang input ay hindi tumutugma sa kinakailangang format';
@override @override
String get plugins => 'Mga plugin'; String get metadata_provider_plugins => 'Mga Plugin ng Metadata Provider';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1560,8 +1543,8 @@ class AppLocalizationsTl extends AppLocalizations {
String get available_plugins => 'Mga available na plugin'; String get available_plugins => 'Mga available na plugin';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'I-configure ang sarili mong metadata provider at mga audio source plugin'; 'I-configure ang iyong sariling playlist/album/artist/feed metadata provider';
@override @override
String get audio_scrobblers => 'Mga Audio Scrobbler'; String get audio_scrobblers => 'Mga Audio Scrobbler';
@ -1570,12 +1553,12 @@ class AppLocalizationsTl extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Pinagmulan: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Hindi naka-compress'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Para sa mga audiophile. Nagbibigay ng de-kalidad/walang loss na audio streams. Tumpak na pagtutugma ng track batay sa ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -875,16 +875,10 @@ class AppLocalizationsTr extends AppLocalizations {
String get restore_defaults => 'Varsayılanları geri yükle'; String get restore_defaults => 'Varsayılanları geri yükle';
@override @override
String get download_music_format => 'Müzik indirme formatı'; String get download_music_codec => 'Müzik codec bileşenini indir';
@override @override
String get streaming_music_format => 'Müzik akış formatı'; String get streaming_music_codec => 'Müzik codec\'i akışı';
@override
String get download_music_quality => 'İndirilen müzik kalitesi';
@override
String get streaming_music_quality => 'Yayınlanan müzik kalitesi';
@override @override
String get login_with_lastfm => 'Last.fm ile giriş yap'; String get login_with_lastfm => 'Last.fm ile giriş yap';
@ -1456,17 +1450,7 @@ class AppLocalizationsTr extends AppLocalizations {
'Bu eklenti, dinleme geçmişinizi oluşturmak için müziğinizi scrobble eder.'; 'Bu eklenti, dinleme geçmişinizi oluşturmak için müziğinizi scrobble eder.';
@override @override
String get default_metadata_source => 'Varsayılan meta veri kaynağı'; String get default_plugin => 'Varsayılan';
@override
String get set_default_metadata_source =>
'Varsayılan meta veri kaynağını ayarla';
@override
String get default_audio_source => 'Varsayılan ses kaynağı';
@override
String get set_default_audio_source => 'Varsayılan ses kaynağını ayarla';
@override @override
String get set_default => 'Varsayılan olarak ayarla'; String get set_default => 'Varsayılan olarak ayarla';
@ -1527,7 +1511,7 @@ class AppLocalizationsTr extends AppLocalizations {
String get input_does_not_match_format => 'Girdi, gerekli biçimle eşleşmiyor'; String get input_does_not_match_format => 'Girdi, gerekli biçimle eşleşmiyor';
@override @override
String get plugins => 'Eklentiler'; String get metadata_provider_plugins => 'Meta Veri Sağlayıcısı Eklentileri';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1552,8 +1536,8 @@ class AppLocalizationsTr extends AppLocalizations {
String get available_plugins => 'Mevcut eklentiler'; String get available_plugins => 'Mevcut eklentiler';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Kendi meta veri sağlayıcı ve ses kaynağı eklentilerinizi yapılandırın'; 'Kendi çalma listenizi/albümünüzü/sanatçınızı/akış meta veri sağlayıcınızı yapılandırın';
@override @override
String get audio_scrobblers => 'Ses Scrobbler\'lar'; String get audio_scrobblers => 'Ses Scrobbler\'lar';
@ -1562,12 +1546,12 @@ class AppLocalizationsTr extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Kaynak: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Sıkıştırılmamış'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Audiophile\'ler için. Yüksek kaliteli/kayıpsız ses akışları sağlar. Doğru ISRC tabanlı parça eşleştirme.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -875,16 +875,10 @@ class AppLocalizationsUk extends AppLocalizations {
String get restore_defaults => 'Відновити налаштування за замовчуванням'; String get restore_defaults => 'Відновити налаштування за замовчуванням';
@override @override
String get download_music_format => 'Формат завантаження музики'; String get download_music_codec => 'Завантажити кодек для музики';
@override @override
String get streaming_music_format => 'Формат потокової музики'; String get streaming_music_codec => 'Кодек потокової передачі музики';
@override
String get download_music_quality => 'Якість завантаженої музики';
@override
String get streaming_music_quality => 'Якість потокової музики';
@override @override
String get login_with_lastfm => 'Увійти з Last.fm'; String get login_with_lastfm => 'Увійти з Last.fm';
@ -1452,18 +1446,7 @@ class AppLocalizationsUk extends AppLocalizations {
'Цей плагін скроббить вашу музику, щоб створити вашу історію прослуховувань.'; 'Цей плагін скроббить вашу музику, щоб створити вашу історію прослуховувань.';
@override @override
String get default_metadata_source => 'Джерело метаданих за замовчуванням'; String get default_plugin => 'За замовчуванням';
@override
String get set_default_metadata_source =>
'Встановити джерело метаданих за замовчуванням';
@override
String get default_audio_source => 'Джерело аудіо за замовчуванням';
@override
String get set_default_audio_source =>
'Встановити джерело аудіо за замовчуванням';
@override @override
String get set_default => 'Встановити за замовчуванням'; String get set_default => 'Встановити за замовчуванням';
@ -1524,7 +1507,7 @@ class AppLocalizationsUk extends AppLocalizations {
'Введені дані не відповідають необхідному формату'; 'Введені дані не відповідають необхідному формату';
@override @override
String get plugins => 'Плагіни'; String get metadata_provider_plugins => 'Плагіни провайдера метаданих';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1549,8 +1532,8 @@ class AppLocalizationsUk extends AppLocalizations {
String get available_plugins => 'Доступні плагіни'; String get available_plugins => 'Доступні плагіни';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Налаштуйте власні плагіни метаданих і аудіоджерела'; 'Налаштуйте свій власний провайдер метаданих для плейлиста/альбому/виконавця/стрічки';
@override @override
String get audio_scrobblers => 'Аудіо скробблери'; String get audio_scrobblers => 'Аудіо скробблери';
@ -1559,12 +1542,12 @@ class AppLocalizationsUk extends AppLocalizations {
String get scrobbling => 'Скроблінг'; String get scrobbling => 'Скроблінг';
@override @override
String get source => 'Джерело: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Без стиснення'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Для аудіофілів. Забезпечує високоякісні/без втрат аудіопотоки. Точна відповідність треків на основі ISRC.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -875,16 +875,10 @@ class AppLocalizationsVi extends AppLocalizations {
String get restore_defaults => 'Khôi phục mặc định'; String get restore_defaults => 'Khôi phục mặc định';
@override @override
String get download_music_format => 'Định dạng nhạc tải về'; String get download_music_codec => 'Định dạng tải xuống';
@override @override
String get streaming_music_format => 'Định dạng nhạc phát trực tuyến'; String get streaming_music_codec => 'Định dạng nghe';
@override
String get download_music_quality => 'Chất lượng nhạc tải về';
@override
String get streaming_music_quality => 'Chất lượng nhạc phát trực tuyến';
@override @override
String get login_with_lastfm => 'Đăng nhập bằng tài khoản Last.fm'; String get login_with_lastfm => 'Đăng nhập bằng tài khoản Last.fm';
@ -1456,16 +1450,7 @@ class AppLocalizationsVi extends AppLocalizations {
'Plugin này scrobble nhạc của bạn để tạo lịch sử nghe của bạn.'; 'Plugin này scrobble nhạc của bạn để tạo lịch sử nghe của bạn.';
@override @override
String get default_metadata_source => 'Nguồn siêu dữ liệu mặc định'; String get default_plugin => 'Mặc định';
@override
String get set_default_metadata_source => 'Đặt nguồn siêu dữ liệu mặc định';
@override
String get default_audio_source => 'Nguồn âm thanh mặc định';
@override
String get set_default_audio_source => 'Đặt nguồn âm thanh mặc định';
@override @override
String get set_default => 'Đặt làm mặc định'; String get set_default => 'Đặt làm mặc định';
@ -1528,7 +1513,7 @@ class AppLocalizationsVi extends AppLocalizations {
'Đầu vào không khớp với định dạng yêu cầu'; 'Đầu vào không khớp với định dạng yêu cầu';
@override @override
String get plugins => 'Tiện ích bổ sung'; String get metadata_provider_plugins => 'Plugin Nhà cung cấp siêu dữ liệu';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1553,8 +1538,8 @@ class AppLocalizationsVi extends AppLocalizations {
String get available_plugins => 'Các plugin có sẵn'; String get available_plugins => 'Các plugin có sẵn';
@override @override
String get configure_plugins => String get configure_your_own_metadata_plugin =>
'Cấu hình nhà cung cấp siêu dữ liệu và tiện ích nguồn âm thanh riêng'; 'Cấu hình nhà cung cấp siêu dữ liệu danh sách phát/album/nghệ sĩ/nguồn cấp dữ liệu của riêng bạn';
@override @override
String get audio_scrobblers => 'Bộ scrobbler âm thanh'; String get audio_scrobblers => 'Bộ scrobbler âm thanh';
@ -1563,12 +1548,12 @@ class AppLocalizationsVi extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => 'Nguồn: '; String get source => 'Source: ';
@override @override
String get uncompressed => 'Không nén'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'Dành cho người yêu âm nhạc chất lượng cao. Cung cấp luồng âm thanh chất lượng cao/không nén. Phù hợp bài hát dựa trên ISRC chính xác.'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }

View File

@ -859,16 +859,10 @@ class AppLocalizationsZh extends AppLocalizations {
String get restore_defaults => '恢复默认值'; String get restore_defaults => '恢复默认值';
@override @override
String get download_music_format => '下载音乐格式'; String get download_music_codec => '下载音乐编解码器';
@override @override
String get streaming_music_format => '流媒体音乐格式'; String get streaming_music_codec => '流媒体音乐编解码器';
@override
String get download_music_quality => '下载音乐质量';
@override
String get streaming_music_quality => '流媒体音乐质量';
@override @override
String get login_with_lastfm => '使用 Last.fm 登录'; String get login_with_lastfm => '使用 Last.fm 登录';
@ -1418,16 +1412,7 @@ class AppLocalizationsZh extends AppLocalizations {
String get plugin_scrobbling_info => '此插件会 scrobble 您的音乐以生成您的收听历史记录。'; String get plugin_scrobbling_info => '此插件会 scrobble 您的音乐以生成您的收听历史记录。';
@override @override
String get default_metadata_source => '默认元数据源'; String get default_plugin => '默认';
@override
String get set_default_metadata_source => '设置默认元数据源';
@override
String get default_audio_source => '默认音频源';
@override
String get set_default_audio_source => '设置默认音频源';
@override @override
String get set_default => '设为默认'; String get set_default => '设为默认';
@ -1484,7 +1469,7 @@ class AppLocalizationsZh extends AppLocalizations {
String get input_does_not_match_format => '输入与所需格式不匹配'; String get input_does_not_match_format => '输入与所需格式不匹配';
@override @override
String get plugins => '插件'; String get metadata_provider_plugins => '元数据提供者插件';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -1508,7 +1493,7 @@ class AppLocalizationsZh extends AppLocalizations {
String get available_plugins => '可用插件'; String get available_plugins => '可用插件';
@override @override
String get configure_plugins => '配置您自己的元数据提供者和音频源插件'; String get configure_your_own_metadata_plugin => '配置您自己的播放列表/专辑/艺人/订阅元数据提供者';
@override @override
String get audio_scrobblers => '音频 Scrobblers'; String get audio_scrobblers => '音频 Scrobblers';
@ -1517,14 +1502,14 @@ class AppLocalizationsZh extends AppLocalizations {
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override @override
String get source => '来源:'; String get source => 'Source: ';
@override @override
String get uncompressed => '无损'; String get uncompressed => 'Uncompressed';
@override @override
String get dab_music_source_description => String get dab_music_source_description =>
'适合发烧友。提供高质量/无损音频流。基于 ISRC 的精确曲目匹配。'; 'For audiophiles. Provides high-quality/lossless audio streams. Accurate ISRC based track matching.';
} }
/// The translations for Chinese, as used in Taiwan (`zh_TW`). /// The translations for Chinese, as used in Taiwan (`zh_TW`).
@ -2382,16 +2367,10 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get restore_defaults => '恢復預設值'; String get restore_defaults => '恢復預設值';
@override @override
String get download_music_format => '下載音樂格式'; String get download_music_codec => '下載音樂編解碼器';
@override @override
String get streaming_music_format => '串流音樂格式'; String get streaming_music_codec => '串流音樂編解碼器';
@override
String get download_music_quality => '下載音樂品質';
@override
String get streaming_music_quality => '串流音樂品質';
@override @override
String get login_with_lastfm => '使用 Last.fm 登入'; String get login_with_lastfm => '使用 Last.fm 登入';
@ -2941,16 +2920,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get plugin_scrobbling_info => '此外掛程式會 Scrobble 您的音樂以產生您的收聽記錄。'; String get plugin_scrobbling_info => '此外掛程式會 Scrobble 您的音樂以產生您的收聽記錄。';
@override @override
String get default_metadata_source => '預設中繼資料來源'; String get default_plugin => '預設';
@override
String get set_default_metadata_source => '設定預設中繼資料來源';
@override
String get default_audio_source => '預設音訊來源';
@override
String get set_default_audio_source => '設定預設音訊來源';
@override @override
String get set_default => '設為預設'; String get set_default => '設為預設';
@ -3007,7 +2977,7 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get input_does_not_match_format => '輸入不符合所需格式'; String get input_does_not_match_format => '輸入不符合所需格式';
@override @override
String get plugins => '外掛程式'; String get metadata_provider_plugins => '中繼資料供應商外掛程式';
@override @override
String get paste_plugin_download_url => String get paste_plugin_download_url =>
@ -3031,21 +3001,11 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
String get available_plugins => '可用的外掛程式'; String get available_plugins => '可用的外掛程式';
@override @override
String get configure_plugins => '配置您自己的中繼資料提供者和音訊來源外掛程式'; String get configure_your_own_metadata_plugin => '設定您自己的播放清單/專輯/藝人/動態中繼資料供應商';
@override @override
String get audio_scrobblers => '音訊 Scrobblers'; String get audio_scrobblers => '音訊 Scrobblers';
@override @override
String get scrobbling => 'Scrobbling'; String get scrobbling => 'Scrobbling';
@override
String get source => '來源:';
@override
String get uncompressed => '未壓縮';
@override
String get dab_music_source_description =>
'適合音響發燒友。提供高品質/無損音訊串流。精確的 ISRC 曲目比對。';
} }

View File

@ -83,8 +83,6 @@ Future<void> main(List<String> rawArgs) async {
// force High Refresh Rate on some Android devices (like One Plus) // force High Refresh Rate on some Android devices (like One Plus)
if (kIsAndroid) { if (kIsAndroid) {
await FlutterDisplayMode.setHighRefreshRate(); await FlutterDisplayMode.setHighRefreshRate();
}
if (kIsAndroid || kIsDesktop) {
await NewPipeExtractor.init(); await NewPipeExtractor.init();
} }
@ -152,13 +150,11 @@ class Spotube extends HookConsumerWidget {
ref.listen(audioPlayerStreamListenersProvider, (_, __) {}); ref.listen(audioPlayerStreamListenersProvider, (_, __) {});
ref.listen(bonsoirProvider, (_, __) {}); ref.listen(bonsoirProvider, (_, __) {});
ref.listen(connectClientsProvider, (_, __) {}); ref.listen(connectClientsProvider, (_, __) {});
ref.listen(serverProvider, (_, __) {});
ref.listen(trayManagerProvider, (_, __) {});
ref.listen(metadataPluginsProvider, (_, __) {}); ref.listen(metadataPluginsProvider, (_, __) {});
ref.listen(metadataPluginProvider, (_, __) {}); ref.listen(metadataPluginProvider, (_, __) {});
ref.listen(audioSourcePluginProvider, (_, __) {}); ref.listen(serverProvider, (_, __) {});
ref.listen(trayManagerProvider, (_, __) {});
ref.listen(metadataPluginUpdateCheckerProvider, (_, __) {}); ref.listen(metadataPluginUpdateCheckerProvider, (_, __) {});
ref.listen(audioSourcePluginUpdateCheckerProvider, (_, __) {});
useFixWindowStretching(); useFixWindowStretching();
useDisableBatteryOptimizations(); useDisableBatteryOptimizations();

View File

@ -16,14 +16,13 @@ import 'package:spotube/models/metadata/market.dart';
import 'package:spotube/models/metadata/metadata.dart'; import 'package:spotube/models/metadata/metadata.dart';
import 'package:spotube/services/kv_store/encrypted_kv_store.dart'; import 'package:spotube/services/kv_store/encrypted_kv_store.dart';
import 'package:spotube/services/kv_store/kv_store.dart'; import 'package:spotube/services/kv_store/kv_store.dart';
import 'package:spotube/services/sourced_track/enums.dart';
import 'package:flutter/widgets.dart' hide Table, Key, View; import 'package:flutter/widgets.dart' hide Table, Key, View;
import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart'; import 'package:spotube/modules/settings/color_scheme_picker_dialog.dart';
import 'package:drift/native.dart'; import 'package:drift/native.dart';
import 'package:spotube/services/logger/logger.dart';
import 'package:spotube/services/youtube_engine/newpipe_engine.dart'; import 'package:spotube/services/youtube_engine/newpipe_engine.dart';
import 'package:spotube/services/youtube_engine/youtube_explode_engine.dart'; import 'package:spotube/services/youtube_engine/youtube_explode_engine.dart';
import 'package:spotube/services/youtube_engine/yt_dlp_engine.dart'; import 'package:spotube/services/youtube_engine/yt_dlp_engine.dart';
import 'package:spotube/utils/platform.dart';
import 'package:sqlite3/sqlite3.dart'; import 'package:sqlite3/sqlite3.dart';
import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart'; import 'package:sqlite3_flutter_libs/sqlite3_flutter_libs.dart';
@ -59,14 +58,14 @@ part 'typeconverters/subtitle.dart';
AudioPlayerStateTable, AudioPlayerStateTable,
HistoryTable, HistoryTable,
LyricsTable, LyricsTable,
PluginsTable, MetadataPluginsTable,
], ],
) )
class AppDatabase extends _$AppDatabase { class AppDatabase extends _$AppDatabase {
AppDatabase() : super(_openConnection()); AppDatabase() : super(_openConnection());
@override @override
int get schemaVersion => 10; int get schemaVersion => 8;
@override @override
MigrationStrategy get migration { MigrationStrategy get migration {
@ -200,43 +199,6 @@ class AppDatabase extends _$AppDatabase {
} }
}); });
}, },
from8To9: (m, schema) async {
await m
.renameTable(schema.pluginsTable, "metadata_plugins_table")
.catchError((e, stack) => AppLogger.reportError(e, stack));
await m
.renameColumn(
schema.pluginsTable,
"selected",
pluginsTable.selectedForMetadata,
)
.catchError((e, stack) => AppLogger.reportError(e, stack));
await m
.addColumn(
schema.pluginsTable,
pluginsTable.selectedForAudioSource,
)
.catchError((e, stack) => AppLogger.reportError(e, stack));
},
from9To10: (m, schema) async {
await m
.dropColumn(schema.preferencesTable, "piped_instance")
.catchError((e, stack) => AppLogger.reportError(e, stack));
await m
.dropColumn(schema.preferencesTable, "invidious_instance")
.catchError((e, stack) => AppLogger.reportError(e, stack));
await m
.addColumn(
schema.sourceMatchTable,
sourceMatchTable.sourceInfo,
)
.catchError((e, stack) => AppLogger.reportError(e, stack));
await customStatement("DROP INDEX IF EXISTS uniq_track_match;")
.catchError((e, stack) => AppLogger.reportError(e, stack));
await m
.dropColumn(schema.sourceMatchTable, "source_id")
.catchError((e, stack) => AppLogger.reportError(e, stack));
},
), ),
); );
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
// dart format width=80
import 'package:drift/internal/versioned_schema.dart' as i0; import 'package:drift/internal/versioned_schema.dart' as i0;
import 'package:drift/drift.dart' as i1; import 'package:drift/drift.dart' as i1;
import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import import 'package:drift/drift.dart'; // ignore_for_file: type=lint,unused_import
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:spotube/models/database/database.dart'; import 'package:spotube/models/database/database.dart';
import 'package:spotube/models/metadata/market.dart'; import 'package:spotube/models/metadata/market.dart';
import 'package:spotube/services/sourced_track/enums.dart';
// GENERATED BY drift_dev, DO NOT MODIFY. // GENERATED BY drift_dev, DO NOT MODIFY.
final class Schema2 extends i0.VersionedSchema { final class Schema2 extends i0.VersionedSchema {
@ -329,7 +329,8 @@ class Shape2 extends i0.VersionedTable {
i1.GeneratedColumn<String> _column_7(String aliasedName) => i1.GeneratedColumn<String> _column_7(String aliasedName) =>
i1.GeneratedColumn<String>('audio_quality', aliasedName, false, i1.GeneratedColumn<String>('audio_quality', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: Constant("high")); type: i1.DriftSqlType.string,
defaultValue: Constant(SourceQualities.high.name));
i1.GeneratedColumn<bool> _column_8(String aliasedName) => i1.GeneratedColumn<bool> _column_8(String aliasedName) =>
i1.GeneratedColumn<bool>('album_color_sync', aliasedName, false, i1.GeneratedColumn<bool>('album_color_sync', aliasedName, false,
type: i1.DriftSqlType.bool, type: i1.DriftSqlType.bool,
@ -416,13 +417,16 @@ i1.GeneratedColumn<String> _column_25(String aliasedName) =>
defaultValue: Constant(ThemeMode.system.name)); defaultValue: Constant(ThemeMode.system.name));
i1.GeneratedColumn<String> _column_26(String aliasedName) => i1.GeneratedColumn<String> _column_26(String aliasedName) =>
i1.GeneratedColumn<String>('audio_source', aliasedName, false, i1.GeneratedColumn<String>('audio_source', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: Constant("youtube")); type: i1.DriftSqlType.string,
defaultValue: Constant(AudioSource.youtube.name));
i1.GeneratedColumn<String> _column_27(String aliasedName) => i1.GeneratedColumn<String> _column_27(String aliasedName) =>
i1.GeneratedColumn<String>('stream_music_codec', aliasedName, false, i1.GeneratedColumn<String>('stream_music_codec', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: Constant("weba")); type: i1.DriftSqlType.string,
defaultValue: Constant(SourceCodecs.weba.name));
i1.GeneratedColumn<String> _column_28(String aliasedName) => i1.GeneratedColumn<String> _column_28(String aliasedName) =>
i1.GeneratedColumn<String>('download_music_codec', aliasedName, false, i1.GeneratedColumn<String>('download_music_codec', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: Constant("m4a")); type: i1.DriftSqlType.string,
defaultValue: Constant(SourceCodecs.m4a.name));
i1.GeneratedColumn<bool> _column_29(String aliasedName) => i1.GeneratedColumn<bool> _column_29(String aliasedName) =>
i1.GeneratedColumn<bool>('discord_presence', aliasedName, false, i1.GeneratedColumn<bool>('discord_presence', aliasedName, false,
type: i1.DriftSqlType.bool, type: i1.DriftSqlType.bool,
@ -507,7 +511,8 @@ i1.GeneratedColumn<String> _column_38(String aliasedName) =>
type: i1.DriftSqlType.string); type: i1.DriftSqlType.string);
i1.GeneratedColumn<String> _column_39(String aliasedName) => i1.GeneratedColumn<String> _column_39(String aliasedName) =>
i1.GeneratedColumn<String>('source_type', aliasedName, false, i1.GeneratedColumn<String>('source_type', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: Constant("youtube")); type: i1.DriftSqlType.string,
defaultValue: Constant(SourceType.youtube.name));
class Shape6 extends i0.VersionedTable { class Shape6 extends i0.VersionedTable {
Shape6({required super.source, required super.alias}) : super.aliased(); Shape6({required super.source, required super.alias}) : super.aliased();
@ -1402,7 +1407,7 @@ final class Schema5 extends i0.VersionedSchema {
i1.GeneratedColumn<String> _column_55(String aliasedName) => i1.GeneratedColumn<String> _column_55(String aliasedName) =>
i1.GeneratedColumn<String>('accent_color_scheme', aliasedName, false, i1.GeneratedColumn<String>('accent_color_scheme', aliasedName, false,
type: i1.DriftSqlType.string, type: i1.DriftSqlType.string,
defaultValue: const Constant("Orange:0xFFf97315")); defaultValue: const Constant("Slate:0xff64748b"));
final class Schema6 extends i0.VersionedSchema { final class Schema6 extends i0.VersionedSchema {
Schema6({required super.database}) : super(version: 6); Schema6({required super.database}) : super(version: 6);
@ -2048,7 +2053,7 @@ final class Schema8 extends i0.VersionedSchema {
_column_13, _column_13,
_column_14, _column_14,
_column_15, _column_15,
_column_69, _column_55,
_column_17, _column_17,
_column_18, _column_18,
_column_19, _column_19,
@ -2183,7 +2188,7 @@ final class Schema8 extends i0.VersionedSchema {
_column_65, _column_65,
_column_66, _column_66,
_column_67, _column_67,
_column_70, _column_69,
], ],
attachedDatabase: database, attachedDatabase: database,
), ),
@ -2195,550 +2200,8 @@ final class Schema8 extends i0.VersionedSchema {
} }
i1.GeneratedColumn<String> _column_69(String aliasedName) => i1.GeneratedColumn<String> _column_69(String aliasedName) =>
i1.GeneratedColumn<String>('accent_color_scheme', aliasedName, false,
type: i1.DriftSqlType.string,
defaultValue: const Constant("Slate:0xff64748b"));
i1.GeneratedColumn<String> _column_70(String aliasedName) =>
i1.GeneratedColumn<String>('plugin_api_version', aliasedName, false, i1.GeneratedColumn<String>('plugin_api_version', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant('1.0.0')); type: i1.DriftSqlType.string, defaultValue: const Constant('1.0.0'));
final class Schema9 extends i0.VersionedSchema {
Schema9({required super.database}) : super(version: 9);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
authenticationTable,
blacklistTable,
preferencesTable,
scrobblerTable,
skipSegmentTable,
sourceMatchTable,
audioPlayerStateTable,
historyTable,
lyricsTable,
pluginsTable,
uniqueBlacklist,
uniqTrackMatch,
];
late final Shape0 authenticationTable = Shape0(
source: i0.VersionedTable(
entityName: 'authentication_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 blacklistTable = Shape1(
source: i0.VersionedTable(
entityName: 'blacklist_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_4,
_column_5,
_column_6,
],
attachedDatabase: database,
),
alias: null);
late final Shape13 preferencesTable = Shape13(
source: i0.VersionedTable(
entityName: 'preferences_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_7,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
_column_13,
_column_14,
_column_15,
_column_69,
_column_17,
_column_18,
_column_19,
_column_20,
_column_21,
_column_22,
_column_23,
_column_24,
_column_25,
_column_26,
_column_54,
_column_27,
_column_28,
_column_29,
_column_30,
_column_31,
_column_56,
_column_53,
],
attachedDatabase: database,
),
alias: null);
late final Shape3 scrobblerTable = Shape3(
source: i0.VersionedTable(
entityName: 'scrobbler_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_33,
_column_34,
],
attachedDatabase: database,
),
alias: null);
late final Shape4 skipSegmentTable = Shape4(
source: i0.VersionedTable(
entityName: 'skip_segment_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_35,
_column_36,
_column_37,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape5 sourceMatchTable = Shape5(
source: i0.VersionedTable(
entityName: 'source_match_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_38,
_column_39,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape14 audioPlayerStateTable = Shape14(
source: i0.VersionedTable(
entityName: 'audio_player_state_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_40,
_column_41,
_column_42,
_column_43,
_column_57,
_column_58,
],
attachedDatabase: database,
),
alias: null);
late final Shape9 historyTable = Shape9(
source: i0.VersionedTable(
entityName: 'history_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_50,
_column_51,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape10 lyricsTable = Shape10(
source: i0.VersionedTable(
entityName: 'lyrics_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape16 pluginsTable = Shape16(
source: i0.VersionedTable(
entityName: 'plugins_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_59,
_column_60,
_column_61,
_column_62,
_column_63,
_column_64,
_column_65,
_column_71,
_column_72,
_column_67,
_column_73,
],
attachedDatabase: database,
),
alias: null);
final i1.Index uniqueBlacklist = i1.Index('unique_blacklist',
'CREATE UNIQUE INDEX unique_blacklist ON blacklist_table (element_type, element_id)');
final i1.Index uniqTrackMatch = i1.Index('uniq_track_match',
'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_id, source_type)');
}
class Shape16 extends i0.VersionedTable {
Shape16({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get name =>
columnsByName['name']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get description =>
columnsByName['description']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get version =>
columnsByName['version']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get author =>
columnsByName['author']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get entryPoint =>
columnsByName['entry_point']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get apis =>
columnsByName['apis']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get abilities =>
columnsByName['abilities']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get selectedForMetadata =>
columnsByName['selected_for_metadata']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get selectedForAudioSource =>
columnsByName['selected_for_audio_source']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get repository =>
columnsByName['repository']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get pluginApiVersion =>
columnsByName['plugin_api_version']! as i1.GeneratedColumn<String>;
}
i1.GeneratedColumn<bool> _column_71(String aliasedName) =>
i1.GeneratedColumn<bool>('selected_for_metadata', aliasedName, false,
type: i1.DriftSqlType.bool,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
'CHECK ("selected_for_metadata" IN (0, 1))'),
defaultValue: const Constant(false));
i1.GeneratedColumn<bool> _column_72(String aliasedName) =>
i1.GeneratedColumn<bool>('selected_for_audio_source', aliasedName, false,
type: i1.DriftSqlType.bool,
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
'CHECK ("selected_for_audio_source" IN (0, 1))'),
defaultValue: const Constant(false));
i1.GeneratedColumn<String> _column_73(String aliasedName) =>
i1.GeneratedColumn<String>('plugin_api_version', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant('2.0.0'));
final class Schema10 extends i0.VersionedSchema {
Schema10({required super.database}) : super(version: 10);
@override
late final List<i1.DatabaseSchemaEntity> entities = [
authenticationTable,
blacklistTable,
preferencesTable,
scrobblerTable,
skipSegmentTable,
sourceMatchTable,
audioPlayerStateTable,
historyTable,
lyricsTable,
pluginsTable,
uniqueBlacklist,
uniqTrackMatch,
];
late final Shape0 authenticationTable = Shape0(
source: i0.VersionedTable(
entityName: 'authentication_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_1,
_column_2,
_column_3,
],
attachedDatabase: database,
),
alias: null);
late final Shape1 blacklistTable = Shape1(
source: i0.VersionedTable(
entityName: 'blacklist_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_4,
_column_5,
_column_6,
],
attachedDatabase: database,
),
alias: null);
late final Shape17 preferencesTable = Shape17(
source: i0.VersionedTable(
entityName: 'preferences_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_8,
_column_9,
_column_10,
_column_11,
_column_12,
_column_13,
_column_14,
_column_15,
_column_69,
_column_17,
_column_18,
_column_19,
_column_20,
_column_21,
_column_22,
_column_25,
_column_74,
_column_54,
_column_29,
_column_30,
_column_31,
_column_56,
_column_53,
],
attachedDatabase: database,
),
alias: null);
late final Shape3 scrobblerTable = Shape3(
source: i0.VersionedTable(
entityName: 'scrobbler_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_33,
_column_34,
],
attachedDatabase: database,
),
alias: null);
late final Shape4 skipSegmentTable = Shape4(
source: i0.VersionedTable(
entityName: 'skip_segment_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_35,
_column_36,
_column_37,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape18 sourceMatchTable = Shape18(
source: i0.VersionedTable(
entityName: 'source_match_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_75,
_column_76,
_column_32,
],
attachedDatabase: database,
),
alias: null);
late final Shape14 audioPlayerStateTable = Shape14(
source: i0.VersionedTable(
entityName: 'audio_player_state_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_40,
_column_41,
_column_42,
_column_43,
_column_57,
_column_58,
],
attachedDatabase: database,
),
alias: null);
late final Shape9 historyTable = Shape9(
source: i0.VersionedTable(
entityName: 'history_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_32,
_column_50,
_column_51,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape10 lyricsTable = Shape10(
source: i0.VersionedTable(
entityName: 'lyrics_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_37,
_column_52,
],
attachedDatabase: database,
),
alias: null);
late final Shape16 pluginsTable = Shape16(
source: i0.VersionedTable(
entityName: 'plugins_table',
withoutRowId: false,
isStrict: false,
tableConstraints: [],
columns: [
_column_0,
_column_59,
_column_60,
_column_61,
_column_62,
_column_63,
_column_64,
_column_65,
_column_71,
_column_72,
_column_67,
_column_73,
],
attachedDatabase: database,
),
alias: null);
final i1.Index uniqueBlacklist = i1.Index('unique_blacklist',
'CREATE UNIQUE INDEX unique_blacklist ON blacklist_table (element_type, element_id)');
final i1.Index uniqTrackMatch = i1.Index('uniq_track_match',
'CREATE UNIQUE INDEX uniq_track_match ON source_match_table (track_id, source_info, source_type)');
}
class Shape17 extends i0.VersionedTable {
Shape17({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<bool> get albumColorSync =>
columnsByName['album_color_sync']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get amoledDarkTheme =>
columnsByName['amoled_dark_theme']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get checkUpdate =>
columnsByName['check_update']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get normalizeAudio =>
columnsByName['normalize_audio']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get showSystemTrayIcon =>
columnsByName['show_system_tray_icon']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get systemTitleBar =>
columnsByName['system_title_bar']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get skipNonMusic =>
columnsByName['skip_non_music']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<String> get closeBehavior =>
columnsByName['close_behavior']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get accentColorScheme =>
columnsByName['accent_color_scheme']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get layoutMode =>
columnsByName['layout_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get locale =>
columnsByName['locale']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get market =>
columnsByName['market']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get searchMode =>
columnsByName['search_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get downloadLocation =>
columnsByName['download_location']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get localLibraryLocation =>
columnsByName['local_library_location']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get themeMode =>
columnsByName['theme_mode']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get audioSourceId =>
columnsByName['audio_source_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get youtubeClientEngine =>
columnsByName['youtube_client_engine']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<bool> get discordPresence =>
columnsByName['discord_presence']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get endlessPlayback =>
columnsByName['endless_playback']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<bool> get enableConnect =>
columnsByName['enable_connect']! as i1.GeneratedColumn<bool>;
i1.GeneratedColumn<int> get connectPort =>
columnsByName['connect_port']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<bool> get cacheMusic =>
columnsByName['cache_music']! as i1.GeneratedColumn<bool>;
}
i1.GeneratedColumn<String> _column_74(String aliasedName) =>
i1.GeneratedColumn<String>('audio_source_id', aliasedName, true,
type: i1.DriftSqlType.string);
class Shape18 extends i0.VersionedTable {
Shape18({required super.source, required super.alias}) : super.aliased();
i1.GeneratedColumn<int> get id =>
columnsByName['id']! as i1.GeneratedColumn<int>;
i1.GeneratedColumn<String> get trackId =>
columnsByName['track_id']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get sourceInfo =>
columnsByName['source_info']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<String> get sourceType =>
columnsByName['source_type']! as i1.GeneratedColumn<String>;
i1.GeneratedColumn<DateTime> get createdAt =>
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
}
i1.GeneratedColumn<String> _column_75(String aliasedName) =>
i1.GeneratedColumn<String>('source_info', aliasedName, false,
type: i1.DriftSqlType.string, defaultValue: const Constant("{}"));
i1.GeneratedColumn<String> _column_76(String aliasedName) =>
i1.GeneratedColumn<String>('source_type', aliasedName, false,
type: i1.DriftSqlType.string);
i0.MigrationStepWithVersion migrationSteps({ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2, required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3, required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
@ -2747,8 +2210,6 @@ i0.MigrationStepWithVersion migrationSteps({
required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6, required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6,
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7, required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8, required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
}) { }) {
return (currentVersion, database) async { return (currentVersion, database) async {
switch (currentVersion) { switch (currentVersion) {
@ -2787,16 +2248,6 @@ i0.MigrationStepWithVersion migrationSteps({
final migrator = i1.Migrator(database, schema); final migrator = i1.Migrator(database, schema);
await from7To8(migrator, schema); await from7To8(migrator, schema);
return 8; return 8;
case 8:
final schema = Schema9(database: database);
final migrator = i1.Migrator(database, schema);
await from8To9(migrator, schema);
return 9;
case 9:
final schema = Schema10(database: database);
final migrator = i1.Migrator(database, schema);
await from9To10(migrator, schema);
return 10;
default: default:
throw ArgumentError.value('Unknown migration from $currentVersion'); throw ArgumentError.value('Unknown migration from $currentVersion');
} }
@ -2811,8 +2262,6 @@ i1.OnUpgrade stepByStep({
required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6, required Future<void> Function(i1.Migrator m, Schema6 schema) from5To6,
required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7, required Future<void> Function(i1.Migrator m, Schema7 schema) from6To7,
required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8, required Future<void> Function(i1.Migrator m, Schema8 schema) from7To8,
required Future<void> Function(i1.Migrator m, Schema9 schema) from8To9,
required Future<void> Function(i1.Migrator m, Schema10 schema) from9To10,
}) => }) =>
i0.VersionedSchema.stepByStepHelper( i0.VersionedSchema.stepByStepHelper(
step: migrationSteps( step: migrationSteps(
@ -2823,6 +2272,4 @@ i1.OnUpgrade stepByStep({
from5To6: from5To6, from5To6: from5To6,
from6To7: from6To7, from6To7: from6To7,
from7To8: from7To8, from7To8: from7To8,
from8To9: from8To9,
from9To10: from9To10,
)); ));

View File

@ -1,6 +1,6 @@
part of '../database.dart'; part of '../database.dart';
class PluginsTable extends Table { class MetadataPluginsTable extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get name => text().withLength(min: 1, max: 50)(); TextColumn get name => text().withLength(min: 1, max: 50)();
TextColumn get description => text()(); TextColumn get description => text()();
@ -9,11 +9,8 @@ class PluginsTable extends Table {
TextColumn get entryPoint => text()(); TextColumn get entryPoint => text()();
TextColumn get apis => text().map(const StringListConverter())(); TextColumn get apis => text().map(const StringListConverter())();
TextColumn get abilities => text().map(const StringListConverter())(); TextColumn get abilities => text().map(const StringListConverter())();
BoolColumn get selectedForMetadata => BoolColumn get selected => boolean().withDefault(const Constant(false))();
boolean().withDefault(const Constant(false))();
BoolColumn get selectedForAudioSource =>
boolean().withDefault(const Constant(false))();
TextColumn get repository => text().nullable()(); TextColumn get repository => text().nullable()();
TextColumn get pluginApiVersion => TextColumn get pluginApiVersion =>
text().withDefault(const Constant('2.0.0'))(); text().withDefault(const Constant('1.0.0'))();
} }

View File

@ -11,6 +11,17 @@ enum CloseBehavior {
close, close,
} }
enum AudioSource {
youtube("YouTube"),
piped("Piped"),
jiosaavn("JioSaavn"),
invidious("Invidious"),
dabMusic("DAB Music");
final String label;
const AudioSource(this.label);
}
enum YoutubeClientEngine { enum YoutubeClientEngine {
ytDlp("yt-dlp"), ytDlp("yt-dlp"),
youtubeExplode("YouTubeExplode"), youtubeExplode("YouTubeExplode"),
@ -45,6 +56,8 @@ enum SearchMode {
class PreferencesTable extends Table { class PreferencesTable extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get audioQuality => textEnum<SourceQualities>()
.withDefault(Constant(SourceQualities.high.name))();
BoolColumn get albumColorSync => BoolColumn get albumColorSync =>
boolean().withDefault(const Constant(true))(); boolean().withDefault(const Constant(true))();
BoolColumn get amoledDarkTheme => BoolColumn get amoledDarkTheme =>
@ -76,11 +89,20 @@ class PreferencesTable extends Table {
TextColumn get downloadLocation => text().withDefault(const Constant(""))(); TextColumn get downloadLocation => text().withDefault(const Constant(""))();
TextColumn get localLibraryLocation => TextColumn get localLibraryLocation =>
text().withDefault(const Constant("")).map(const StringListConverter())(); text().withDefault(const Constant("")).map(const StringListConverter())();
TextColumn get pipedInstance =>
text().withDefault(const Constant("https://pipedapi.kavin.rocks"))();
TextColumn get invidiousInstance =>
text().withDefault(const Constant("https://inv.nadeko.net"))();
TextColumn get themeMode => TextColumn get themeMode =>
textEnum<ThemeMode>().withDefault(Constant(ThemeMode.system.name))(); textEnum<ThemeMode>().withDefault(Constant(ThemeMode.system.name))();
TextColumn get audioSourceId => text().nullable()(); TextColumn get audioSource =>
textEnum<AudioSource>().withDefault(Constant(AudioSource.youtube.name))();
TextColumn get youtubeClientEngine => textEnum<YoutubeClientEngine>() TextColumn get youtubeClientEngine => textEnum<YoutubeClientEngine>()
.withDefault(Constant(YoutubeClientEngine.youtubeExplode.name))(); .withDefault(Constant(YoutubeClientEngine.youtubeExplode.name))();
TextColumn get streamMusicCodec =>
textEnum<SourceCodecs>().withDefault(Constant(SourceCodecs.weba.name))();
TextColumn get downloadMusicCodec =>
textEnum<SourceCodecs>().withDefault(Constant(SourceCodecs.m4a.name))();
BoolColumn get discordPresence => BoolColumn get discordPresence =>
boolean().withDefault(const Constant(true))(); boolean().withDefault(const Constant(true))();
BoolColumn get endlessPlayback => BoolColumn get endlessPlayback =>
@ -94,6 +116,7 @@ class PreferencesTable extends Table {
static PreferencesTableData defaults() { static PreferencesTableData defaults() {
return PreferencesTableData( return PreferencesTableData(
id: 0, id: 0,
audioQuality: SourceQualities.high,
albumColorSync: true, albumColorSync: true,
amoledDarkTheme: false, amoledDarkTheme: false,
checkUpdate: true, checkUpdate: true,
@ -109,11 +132,13 @@ class PreferencesTable extends Table {
searchMode: SearchMode.youtube, searchMode: SearchMode.youtube,
downloadLocation: "", downloadLocation: "",
localLibraryLocation: [], localLibraryLocation: [],
pipedInstance: "https://pipedapi.kavin.rocks",
invidiousInstance: "https://inv.nadeko.net",
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
audioSourceId: null, audioSource: AudioSource.youtube,
youtubeClientEngine: kIsIOS youtubeClientEngine: YoutubeClientEngine.youtubeExplode,
? YoutubeClientEngine.youtubeExplode streamMusicCodec: SourceCodecs.m4a,
: YoutubeClientEngine.newPipe, downloadMusicCodec: SourceCodecs.m4a,
discordPresence: true, discordPresence: true,
endlessPlayback: true, endlessPlayback: true,
enableConnect: false, enableConnect: false,

View File

@ -1,9 +1,26 @@
part of '../database.dart'; part of '../database.dart';
enum SourceType {
youtube._("YouTube"),
youtubeMusic._("YouTube Music"),
jiosaavn._("JioSaavn"),
dabMusic._("DAB Music");
final String label;
const SourceType._(this.label);
}
@TableIndex(
name: "uniq_track_match",
columns: {#trackId, #sourceId, #sourceType},
unique: true,
)
class SourceMatchTable extends Table { class SourceMatchTable extends Table {
IntColumn get id => integer().autoIncrement()(); IntColumn get id => integer().autoIncrement()();
TextColumn get trackId => text()(); TextColumn get trackId => text()();
TextColumn get sourceInfo => text().withDefault(const Constant("{}"))(); TextColumn get sourceId => text()();
TextColumn get sourceType => text()(); TextColumn get sourceType =>
textEnum<SourceType>().withDefault(Constant(SourceType.youtube.name))();
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)(); DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
} }

View File

@ -1,110 +0,0 @@
part of 'metadata.dart';
final oneOptionalDecimalFormatter = NumberFormat('0.#', 'en_US');
enum SpotubeMediaCompressionType {
lossy,
lossless,
}
@Freezed(unionKey: 'type')
class SpotubeAudioSourceContainerPreset
with _$SpotubeAudioSourceContainerPreset {
const SpotubeAudioSourceContainerPreset._();
@FreezedUnionValue("lossy")
factory SpotubeAudioSourceContainerPreset.lossy({
required SpotubeMediaCompressionType type,
required String name,
required List<SpotubeAudioLossyContainerQuality> qualities,
}) = SpotubeAudioSourceContainerPresetLossy;
@FreezedUnionValue("lossless")
factory SpotubeAudioSourceContainerPreset.lossless({
required SpotubeMediaCompressionType type,
required String name,
required List<SpotubeAudioLosslessContainerQuality> qualities,
}) = SpotubeAudioSourceContainerPresetLossless;
factory SpotubeAudioSourceContainerPreset.fromJson(
Map<String, dynamic> json) =>
_$SpotubeAudioSourceContainerPresetFromJson(json);
String getFileExtension() {
return switch (name) {
"mp4" => "m4a",
"webm" => "weba",
_ => name,
};
}
}
@freezed
class SpotubeAudioLossyContainerQuality
with _$SpotubeAudioLossyContainerQuality {
const SpotubeAudioLossyContainerQuality._();
factory SpotubeAudioLossyContainerQuality({
required int bitrate, // bits per second
}) = _SpotubeAudioLossyContainerQuality;
factory SpotubeAudioLossyContainerQuality.fromJson(
Map<String, dynamic> json) =>
_$SpotubeAudioLossyContainerQualityFromJson(json);
@override
toString() {
return "${oneOptionalDecimalFormatter.format(bitrate / 1000)}kbps";
}
}
@freezed
class SpotubeAudioLosslessContainerQuality
with _$SpotubeAudioLosslessContainerQuality {
const SpotubeAudioLosslessContainerQuality._();
factory SpotubeAudioLosslessContainerQuality({
required int bitDepth, // bit
required int sampleRate, // hz
}) = _SpotubeAudioLosslessContainerQuality;
factory SpotubeAudioLosslessContainerQuality.fromJson(
Map<String, dynamic> json) =>
_$SpotubeAudioLosslessContainerQualityFromJson(json);
@override
toString() {
return "${bitDepth}bit • ${oneOptionalDecimalFormatter.format(sampleRate / 1000)}kHz";
}
}
@freezed
class SpotubeAudioSourceMatchObject with _$SpotubeAudioSourceMatchObject {
factory SpotubeAudioSourceMatchObject({
required String id,
required String title,
required List<String> artists,
required Duration duration,
String? thumbnail,
required String externalUri,
}) = _SpotubeAudioSourceMatchObject;
factory SpotubeAudioSourceMatchObject.fromJson(Map<String, dynamic> json) =>
_$SpotubeAudioSourceMatchObjectFromJson(json);
}
@freezed
class SpotubeAudioSourceStreamObject with _$SpotubeAudioSourceStreamObject {
factory SpotubeAudioSourceStreamObject({
required String url,
required String container,
required SpotubeMediaCompressionType type,
String? codec,
double? bitrate,
int? bitDepth,
double? sampleRate,
}) = _SpotubeAudioSourceStreamObject;
factory SpotubeAudioSourceStreamObject.fromJson(Map<String, dynamic> json) =>
_$SpotubeAudioSourceStreamObjectFromJson(json);
}

View File

@ -5,7 +5,6 @@ import 'dart:typed_data';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:intl/intl.dart';
import 'package:metadata_god/metadata_god.dart'; import 'package:metadata_god/metadata_god.dart';
import 'package:mime/mime.dart'; import 'package:mime/mime.dart';
import 'package:path/path.dart'; import 'package:path/path.dart';
@ -16,7 +15,6 @@ import 'package:spotube/utils/primitive_utils.dart';
part 'metadata.g.dart'; part 'metadata.g.dart';
part 'metadata.freezed.dart'; part 'metadata.freezed.dart';
part 'audio_source.dart';
part 'album.dart'; part 'album.dart';
part 'artist.dart'; part 'artist.dart';
part 'browse.dart'; part 'browse.dart';

File diff suppressed because it is too large Load Diff

View File

@ -6,123 +6,6 @@ part of 'metadata.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
_$SpotubeAudioSourceContainerPresetLossyImpl
_$$SpotubeAudioSourceContainerPresetLossyImplFromJson(Map json) =>
_$SpotubeAudioSourceContainerPresetLossyImpl(
type: $enumDecode(_$SpotubeMediaCompressionTypeEnumMap, json['type']),
name: json['name'] as String,
qualities: (json['qualities'] as List<dynamic>)
.map((e) => SpotubeAudioLossyContainerQuality.fromJson(
Map<String, dynamic>.from(e as Map)))
.toList(),
);
Map<String, dynamic> _$$SpotubeAudioSourceContainerPresetLossyImplToJson(
_$SpotubeAudioSourceContainerPresetLossyImpl instance) =>
<String, dynamic>{
'type': _$SpotubeMediaCompressionTypeEnumMap[instance.type]!,
'name': instance.name,
'qualities': instance.qualities.map((e) => e.toJson()).toList(),
};
const _$SpotubeMediaCompressionTypeEnumMap = {
SpotubeMediaCompressionType.lossy: 'lossy',
SpotubeMediaCompressionType.lossless: 'lossless',
};
_$SpotubeAudioSourceContainerPresetLosslessImpl
_$$SpotubeAudioSourceContainerPresetLosslessImplFromJson(Map json) =>
_$SpotubeAudioSourceContainerPresetLosslessImpl(
type: $enumDecode(_$SpotubeMediaCompressionTypeEnumMap, json['type']),
name: json['name'] as String,
qualities: (json['qualities'] as List<dynamic>)
.map((e) => SpotubeAudioLosslessContainerQuality.fromJson(
Map<String, dynamic>.from(e as Map)))
.toList(),
);
Map<String, dynamic> _$$SpotubeAudioSourceContainerPresetLosslessImplToJson(
_$SpotubeAudioSourceContainerPresetLosslessImpl instance) =>
<String, dynamic>{
'type': _$SpotubeMediaCompressionTypeEnumMap[instance.type]!,
'name': instance.name,
'qualities': instance.qualities.map((e) => e.toJson()).toList(),
};
_$SpotubeAudioLossyContainerQualityImpl
_$$SpotubeAudioLossyContainerQualityImplFromJson(Map json) =>
_$SpotubeAudioLossyContainerQualityImpl(
bitrate: (json['bitrate'] as num).toInt(),
);
Map<String, dynamic> _$$SpotubeAudioLossyContainerQualityImplToJson(
_$SpotubeAudioLossyContainerQualityImpl instance) =>
<String, dynamic>{
'bitrate': instance.bitrate,
};
_$SpotubeAudioLosslessContainerQualityImpl
_$$SpotubeAudioLosslessContainerQualityImplFromJson(Map json) =>
_$SpotubeAudioLosslessContainerQualityImpl(
bitDepth: (json['bitDepth'] as num).toInt(),
sampleRate: (json['sampleRate'] as num).toInt(),
);
Map<String, dynamic> _$$SpotubeAudioLosslessContainerQualityImplToJson(
_$SpotubeAudioLosslessContainerQualityImpl instance) =>
<String, dynamic>{
'bitDepth': instance.bitDepth,
'sampleRate': instance.sampleRate,
};
_$SpotubeAudioSourceMatchObjectImpl
_$$SpotubeAudioSourceMatchObjectImplFromJson(Map json) =>
_$SpotubeAudioSourceMatchObjectImpl(
id: json['id'] as String,
title: json['title'] as String,
artists: (json['artists'] as List<dynamic>)
.map((e) => e as String)
.toList(),
duration: Duration(microseconds: (json['duration'] as num).toInt()),
thumbnail: json['thumbnail'] as String?,
externalUri: json['externalUri'] as String,
);
Map<String, dynamic> _$$SpotubeAudioSourceMatchObjectImplToJson(
_$SpotubeAudioSourceMatchObjectImpl instance) =>
<String, dynamic>{
'id': instance.id,
'title': instance.title,
'artists': instance.artists,
'duration': instance.duration.inMicroseconds,
'thumbnail': instance.thumbnail,
'externalUri': instance.externalUri,
};
_$SpotubeAudioSourceStreamObjectImpl
_$$SpotubeAudioSourceStreamObjectImplFromJson(Map json) =>
_$SpotubeAudioSourceStreamObjectImpl(
url: json['url'] as String,
container: json['container'] as String,
type: $enumDecode(_$SpotubeMediaCompressionTypeEnumMap, json['type']),
codec: json['codec'] as String?,
bitrate: (json['bitrate'] as num?)?.toDouble(),
bitDepth: (json['bitDepth'] as num?)?.toInt(),
sampleRate: (json['sampleRate'] as num?)?.toDouble(),
);
Map<String, dynamic> _$$SpotubeAudioSourceStreamObjectImplToJson(
_$SpotubeAudioSourceStreamObjectImpl instance) =>
<String, dynamic>{
'url': instance.url,
'container': instance.container,
'type': _$SpotubeMediaCompressionTypeEnumMap[instance.type]!,
'codec': instance.codec,
'bitrate': instance.bitrate,
'bitDepth': instance.bitDepth,
'sampleRate': instance.sampleRate,
};
_$SpotubeFullAlbumObjectImpl _$$SpotubeFullAlbumObjectImplFromJson(Map json) => _$SpotubeFullAlbumObjectImpl _$$SpotubeFullAlbumObjectImplFromJson(Map json) =>
_$SpotubeFullAlbumObjectImpl( _$SpotubeFullAlbumObjectImpl(
id: json['id'] as String, id: json['id'] as String,
@ -536,6 +419,7 @@ Map<String, dynamic> _$$SpotubeUserObjectImplToJson(
_$PluginConfigurationImpl _$$PluginConfigurationImplFromJson(Map json) => _$PluginConfigurationImpl _$$PluginConfigurationImplFromJson(Map json) =>
_$PluginConfigurationImpl( _$PluginConfigurationImpl(
type: $enumDecode(_$PluginTypeEnumMap, json['type']),
name: json['name'] as String, name: json['name'] as String,
description: json['description'] as String, description: json['description'] as String,
version: json['version'] as String, version: json['version'] as String,
@ -556,6 +440,7 @@ _$PluginConfigurationImpl _$$PluginConfigurationImplFromJson(Map json) =>
Map<String, dynamic> _$$PluginConfigurationImplToJson( Map<String, dynamic> _$$PluginConfigurationImplToJson(
_$PluginConfigurationImpl instance) => _$PluginConfigurationImpl instance) =>
<String, dynamic>{ <String, dynamic>{
'type': _$PluginTypeEnumMap[instance.type]!,
'name': instance.name, 'name': instance.name,
'description': instance.description, 'description': instance.description,
'version': instance.version, 'version': instance.version,
@ -568,6 +453,10 @@ Map<String, dynamic> _$$PluginConfigurationImplToJson(
'repository': instance.repository, 'repository': instance.repository,
}; };
const _$PluginTypeEnumMap = {
PluginType.metadata: 'metadata',
};
const _$PluginApisEnumMap = { const _$PluginApisEnumMap = {
PluginApis.webview: 'webview', PluginApis.webview: 'webview',
PluginApis.localstorage: 'localstorage', PluginApis.localstorage: 'localstorage',
@ -577,8 +466,6 @@ const _$PluginApisEnumMap = {
const _$PluginAbilitiesEnumMap = { const _$PluginAbilitiesEnumMap = {
PluginAbilities.authentication: 'authentication', PluginAbilities.authentication: 'authentication',
PluginAbilities.scrobbling: 'scrobbling', PluginAbilities.scrobbling: 'scrobbling',
PluginAbilities.metadata: 'metadata',
PluginAbilities.audioSource: 'audio-source',
}; };
_$PluginUpdateAvailableImpl _$$PluginUpdateAvailableImplFromJson(Map json) => _$PluginUpdateAvailableImpl _$$PluginUpdateAvailableImplFromJson(Map json) =>
@ -603,8 +490,6 @@ _$MetadataPluginRepositoryImpl _$$MetadataPluginRepositoryImplFromJson(
owner: json['owner'] as String, owner: json['owner'] as String,
description: json['description'] as String, description: json['description'] as String,
repoUrl: json['repoUrl'] as String, repoUrl: json['repoUrl'] as String,
topics:
(json['topics'] as List<dynamic>).map((e) => e as String).toList(),
); );
Map<String, dynamic> _$$MetadataPluginRepositoryImplToJson( Map<String, dynamic> _$$MetadataPluginRepositoryImplToJson(
@ -614,5 +499,4 @@ Map<String, dynamic> _$$MetadataPluginRepositoryImplToJson(
'owner': instance.owner, 'owner': instance.owner,
'description': instance.description, 'description': instance.description,
'repoUrl': instance.repoUrl, 'repoUrl': instance.repoUrl,
'topics': instance.topics,
}; };

View File

@ -1,20 +1,17 @@
part of 'metadata.dart'; part of 'metadata.dart';
enum PluginType { metadata }
enum PluginApis { webview, localstorage, timezone } enum PluginApis { webview, localstorage, timezone }
enum PluginAbilities { enum PluginAbilities { authentication, scrobbling }
authentication,
scrobbling,
metadata,
@JsonValue('audio-source')
audioSource,
}
@freezed @freezed
class PluginConfiguration with _$PluginConfiguration { class PluginConfiguration with _$PluginConfiguration {
const PluginConfiguration._(); const PluginConfiguration._();
factory PluginConfiguration({ factory PluginConfiguration({
required PluginType type,
required String name, required String name,
required String description, required String description,
required String version, required String version,

View File

@ -7,7 +7,6 @@ class MetadataPluginRepository with _$MetadataPluginRepository {
required String owner, required String owner,
required String description, required String description,
required String repoUrl, required String repoUrl,
required List<String> topics,
}) = _MetadataPluginRepository; }) = _MetadataPluginRepository;
factory MetadataPluginRepository.fromJson(Map<String, dynamic> json) => factory MetadataPluginRepository.fromJson(Map<String, dynamic> json) =>

Some files were not shown because too many files have changed in this diff Show More