Merge pull request #3167 from team-spotube/dev

Update URLs, add iOS build process, and prepare for beta release
This commit is contained in:
Kingkor Roy Tirtho 2026-10-26 19:13:40 +06:00 committed by GitHub
commit 0d5b5b094e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 262 additions and 30 deletions

View File

@ -76,7 +76,7 @@ body:
description: Where did you install Spotube from?
multiple: true
options:
- "Website (spotube.org)"
- "Website (spotube.cc)"
- "GitHub Releases (Binary)"
- "GitHub Actions (Nightly Binary)"
- "Play Store (Android)"

View File

@ -10,6 +10,7 @@ on:
default: 'stable'
options:
- stable
- beta
- nightly
dry_run:
description: 'Dry run (build & upload artifacts only, skip creating release)'
@ -26,7 +27,7 @@ on:
permissions:
contents: read
# Never cancel a running release when another is dispatched, and let stable and nightly run side by side
# Never cancel a running release when another is dispatched, and let stable, beta and nightly run side by side
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.release_type }}
cancel-in-progress: false
@ -215,7 +216,7 @@ jobs:
fi
# Desktop entry + metainfo, with the release history from git-cliff
./gradlew :composeApp:renderPackagingLinux -Pnightly=${{ inputs.release_type == 'nightly' }} -PbuildNumber=${{ github.run_number }}
packaging/package-linux-tarball.sh "$VERSION" "${{ inputs.release_type }}" .
packaging/package-linux-tarball.sh "$VERSION" "${{ inputs.release_type == 'nightly' && 'nightly' || 'stable' }}" .
- name: Upload tarball
uses: actions/upload-artifact@v7
@ -335,7 +336,7 @@ jobs:
fi
# Desktop entry + metainfo, with the release history from git-cliff
./gradlew :composeApp:renderPackagingLinux -Pnightly=${{ inputs.release_type == 'nightly' }} -PbuildNumber=${{ github.run_number }}
packaging/package-linux-tarball.sh "$VERSION" "${{ inputs.release_type }}" .
packaging/package-linux-tarball.sh "$VERSION" "${{ inputs.release_type == 'nightly' && 'nightly' || 'stable' }}" .
- name: Upload tarball
uses: actions/upload-artifact@v7
@ -485,7 +486,16 @@ jobs:
env:
# Nucleus lists GraalVM CE releases via the GitHub API; unauthenticated calls hit the 60/hour limit
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: ./gradlew :composeApp:packageGraalvmDmg -Pnightly=${{ inputs.release_type == 'nightly' }} -PbuildNumber=${{ github.run_number }}
# The free macOS runner has 3 cores / 7 GB. With the default 4g Gradle + 3g Kotlin daemons idling,
# native-image only gets ~3 GB and spends ~40% of its time in GC (47 min build vs ~15 on Linux).
# A single-use daemon with a smaller heap and in-process Kotlin compilation leaves the RAM to it.
run: >
./gradlew :composeApp:packageGraalvmDmg
--no-daemon
-Dorg.gradle.jvmargs="-Xmx3g -XX:MaxMetaspaceSize=1g"
-Pkotlin.compiler.execution.strategy=in-process
-Pnightly=${{ inputs.release_type == 'nightly' }}
-PbuildNumber=${{ github.run_number }}
- name: Rename macOS artifact
run: |
@ -504,6 +514,75 @@ jobs:
with:
limit-access-to-actor: true
build-ios:
name: iOS
needs: prepare-deps
timeout-minutes: 120
runs-on: macos-latest
steps:
- uses: actions/checkout@v7
- name: Download maven local
uses: actions/download-artifact@v8
with:
name: maven-local
path: ~/.m2/repository/
- name: Set up JDK 21
uses: actions/setup-java@v6
with:
distribution: temurin
java-version: 21
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v6
- name: Make gradlew executable
run: chmod +x gradlew
# Unsigned on purpose: there is no Apple developer account in CI. The IPA is meant for sideloading
# (AltStore, Sideloadly, ...), which re-signs it with the user's own certificate.
# The Gradle build phase inside Xcode reads these as project properties.
- name: Build unsigned app
env:
ORG_GRADLE_PROJECT_nightly: ${{ inputs.release_type == 'nightly' }}
ORG_GRADLE_PROJECT_buildNumber: ${{ github.run_number }}
run: >
xcodebuild
-project iosApp/iosApp.xcodeproj
-scheme iosApp
-configuration Release
-sdk iphoneos
-destination 'generic/platform=iOS'
-derivedDataPath build/ios
CODE_SIGNING_ALLOWED=NO
CODE_SIGNING_REQUIRED=NO
CODE_SIGN_IDENTITY=""
DEVELOPMENT_TEAM=""
build
- name: Package IPA
run: |
APP=$(find build/ios/Build/Products/Release-iphoneos -maxdepth 1 -name "*.app" -type d | head -1)
mkdir Payload
cp -R "$APP" Payload/
zip -qry Spotube-ios.ipa Payload
- name: Upload IPA
uses: actions/upload-artifact@v7
with:
name: ios-ipa
path: Spotube-ios.ipa
- name: Setup tmate session on failure
if: ${{ inputs.debug_ssh && failure() }}
uses: mxschmitt/action-tmate@v3
with:
limit-access-to-actor: true
create-release:
name: Create GitHub Release
if: ${{ !inputs.dry_run }}
@ -513,6 +592,7 @@ jobs:
- build-linux-arm64
- build-windows
- build-macos
- build-ios
runs-on: ubuntu-latest
permissions:
contents: write
@ -538,8 +618,9 @@ jobs:
- name: Set release variables
id: vars
run: |
if [ "${{ inputs.release_type }}" = "stable" ]; then
if [ "${{ inputs.release_type }}" != "nightly" ]; then
chmod +x gradlew
# printVersion includes the -beta.N suffix when betaNumber is set in build.gradle.kts
VERSION=$(./gradlew -q :composeApp:printVersion)
TAG="v${VERSION}"
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
@ -561,7 +642,7 @@ jobs:
run: |
echo "## Downloads" > release-notes.md
echo "" >> release-notes.md
for dir in android-apk linux-deb linux-rpm linux-appimage linux-tarball linux-deb-arm64 linux-rpm-arm64 linux-appimage-arm64 linux-tarball-arm64 windows-exe macos-dmg; do
for dir in android-apk linux-deb linux-rpm linux-appimage linux-tarball linux-deb-arm64 linux-rpm-arm64 linux-appimage-arm64 linux-tarball-arm64 windows-exe macos-dmg ios-ipa; do
if [ -d "$dir" ]; then
echo "### $dir" >> release-notes.md
for f in "$dir"/*; do
@ -571,13 +652,6 @@ jobs:
fi
done
# The rolling nightly tag already exists, and the release action never moves an existing tag
- name: Move nightly tag to this commit
if: ${{ inputs.release_type == 'nightly' }}
run: |
git tag -f nightly "$GITHUB_SHA"
git push -f origin refs/tags/nightly
- name: Create Release
uses: softprops/action-gh-release@v3
with:
@ -601,3 +675,4 @@ jobs:
linux-tarball-arm64/*.tar.xz
windows-exe/*.exe
macos-dmg/*.dmg
ios-ipa/*.ipa

View File

@ -1,5 +1,156 @@
# Changelog
## [6.0.0-beta.0](https://github.com/team-spotube/spotube/compare/v5.1.2...v6.0.0-beta.0) (2026-10-26)
### Features
- Migration to Compose Multiplatform
- Add ChipTab component and refactor SearchScreen to use it
- Add AutocompleteTextField component and integrate it into SearchScreen
- Enhance AutocompleteTextField with focus management and dropdown behavior
- Enhance AppSidebar with improved button interactions and visual feedback
- Implement endless playback recommendations in DeviceAudioPlayerQueue
- Add GhostIconButton component and enhance button interactions in TrackList
- Replace IconButton with GhostIconButton in AppExpandedPlayer and AppLargePlayer for improved visual consistency
- Replace IconButton with GhostIconButton in PlayerQueueContent and PlayableCard for visual consistency
- Enhance UI components with LocalBaseUITheme for consistent styling and improved interactions
- Enhance button styles and interactions in Buttons and Theme components for improved UI consistency
- Simplify highlight implementation in UI components for improved readability and maintainability
- Add genre selection and tabs to HomeScreen for improved content navigation
- Implement artist overview screen with loading, error handling, and pagination for albums, related artists, and featured playlists
- Add genre and featured browsing capabilities to MediaBrowseHelper
- Implement playlist creation and editing functionality with UI components
- Add 'Add to Playlist' functionality with UI components and dialogs
- Add Toggle component and update UI to use it in place of Switch
- Implement settings section cards for updates, desktop, language, caching, and plugins
- Update icons in settings sections to use Iconsax library for improved UI consistency
- Replace FeatherIcons with Iconsax in PluginCard and PluginPermissionsDialog for improved UI consistency
- Refactor PluginPermissionsDialog to use custom UI components for improved consistency and readability
- Enhance UI with shared element transitions and improve state management in album and playlist screens
- Integrate Uniffi for audio metadata reading and writing with Lofty library
- Replace FeatherIcons with Iconsax in window controls and update sidebar with better design
- Implement haze effect and UI enhancements in AppLargePlayer and AppShell
- Enhance haze effect integration in AppShell and AppSidebar for improved UI experience
- Add adaptive dialog bottom sheet component and enhance plugin installation UI
- Enhance AdaptiveDialogBottomSheet with dismiss icon and improve plugin screen layout
- Implement CollectionView component and refactor Album, Playlist, SavedTracks screens for improved UI consistency
- Add current time management in AudioPlayer for improved playback control
- Simplify playback control logic in AudioPlayer by removing redundant state checks
- Introduce AudioPlayerInterface and refactor AudioPlayer implementations for better abstraction
- Update skipToNext and skipToPrevious methods in AudioPlayer for improved media item management
- Refactor LyricsViewModel to use AudioPlayerInterface for improved abstraction
- Add Discord Rich Presence integration for enhanced media playback visibility
- Implement System Tray integration for window management and media controls
- Add hover effect to menu items in System Tray for improved user experience
- Add SSH debug session setup on failure for improved troubleshooting
- Implement blacklist functionality for tracks and artists with UI updates
- **systemtray**: Self-manage tray lifecycle via Koin DI
- **plugin_interfaces**: Update Maven publishing configuration and add GitHub Actions workflow
- **plugin_discovery**: Implement GitHub plugin discovery and add logo support in UI
- **plugin_discovery**: Implement GitHub plugin discovery and add logo support and information dialog in UI
- **plugin_install**: Add plugin installation dialog and release fetching functionality
- Update dependencies and configure compose hot reload settings
- Improve NewPipe video rank matching
- Integrate Nucleus framework for enhanced window management and webview support
- Implement system tray functionality with Compose Native Tray integration
- **mediacontrol**: Implement SystemMediaControlService for OS media integration
- **devices**: Add device discovery and remote control features
- **deeplinks**: Implement deep link handling for jam sessions
- **remote-control**: Implement remote playback functionality and UI components
- **remote-control**: Enhance queue management and player state synchronization
- **remote-control**: Enhance remote playback functionality with new commands and UI integration
- **webrtc**: Update ICE server configuration and enhance logging for peer connection events
- **jam-session**: Add connection state management and update UI feedback for session status
- **jam-session**: Enhance jam session functionality with improved playback synchronization and error handling
- **remote-control**: Refactor service registration and cleanup logic for improved reliability
- **jam-session**: Integrate MQTT broker configuration and enhance jam session settings
- **jam-session**: Implement track addition to jam session and enhance UI feedback for jam state
- **jam-session**: Enhance guest functionality with track addition and participant moderation options
- **release**: Add support for Linux ARM64 builds and artifact uploads
- **player-options**: Add PlayerOptionsViewModel and enhance player UI with options menu
- **player-options**: Enhance options menu with localized strings and icons
- **jam-settings**: Implement JamSettings screen and view model for broker configuration
- Refactor track source management to support plugin-specific caching and retrieval
- Implement shuffle play functionality for albums, playlists, and saved tracks
- **navigation**: Refactor sidebar and bottombar navigation structure with new tab and group models
- **search**: Enhance LazyRow with drag scrolling functionality
- **autocomplete**: Simplify focus management and remove unused key event handling
- **update**: Implement update checker with dialog for available updates
- **update**: Refactor update checking mechanism and implement new dialog for app and plugin updates
- **scrobble**: Implement ScrobbleManager to handle track scrobbling and integrate with audio player
- **welcome**: Implement onboarding flow with multiple pages and donation options
- **previews**: Add comprehensive previews for UI components including sliders, toggles, checkboxes, and text fields
- **settings**: Add 'About' section and improve header visibility in settings sections
- **surface**: Implement Frutiger-Aero themed surfaces with glass and acrylic styles
- **ui**: Replace Scaffold with BaseScaffold for consistent surface theming across screens
- **ui**: New custom surface integration on all components
- **onboarding**: Enhance welcome screen with structured guide steps and improved layout
- **player**: Add content descriptions for play, pause, and add to queue actions
- **support**: Implement support reminder dialog and donation options
- **player**: Refactor artist display and improve search field labels
- **search**: Enhance search functionality with recent search suggestions and improved UI components
- **sidebar**: Adjust spacing in sidebar and setting cards for improved layout
- **jam**: Implement group jam functionality with UI components and state management
- **library**: Enhance library UI with new tab titles, filtering options, and improved state management
- **library**: Add Library screen list mode beside grid mode, Local Track, Download screen, Local Library folders dialog visual improvement
- **ui**: Integrate LocalTextStyle for dynamic tinting in player controls and UI components
- **navigation**: Add custom navigation transition specifications for push and pop actions
- **i18n**: Replace hardcoded strings with localized resources across multiple components
- **plugin**: Implement MetadataPluginGuard to manage plugin dependencies and user prompts
- **ui**: Replace IndeterminateProgress with new loading components and enhance dialog structures
- **ui**: Update MillenniumModalBottomSheet with compact padding and spacing adjustments
- **plugin**: Add login prompt for metadata plugin access and implement authentication view model
- **user-agents**: Implement dynamic user agent fetching and caching mechanism
- **lyrics**: Implement SyncedLyricsList component and enhance LyricsViewModel for better state management
- **server**: Implement port fallback mechanism for playback proxy server
- **window**: Implement window state persistence and restoration
- Enhance Android build configuration with stable/nightly flavors and update launcher icons
- **graalvm**: Enable GraalVM native image support and update packaging configurations
- **local-tracks**: Implement LocalFolder screen and view model for folder navigation
- **navigation**: Implement fade-through and stack transition animations for navigation
- **remote**: Redesign remote control and devices screens, fix connection issues
- Download diagnostics, live connect status, remote settings on devices screen
- Enhance loading states for various UI components and update dependencies
- **packaging**: Flathub, AUR, WinGet and Chocolatey publishing
- **plugin**: Implement automatic plugin updates and enhance JSON parsing
### Bug Fixes
- **newpipe**: Fallback to muxed streams if no audio stream is available
- Dismiss search dropdown and keyboard on submission
- Custom image helper null exception
- **plugin**: Reload Zipline service on same-version replace
- Convert buildCurrentMediaItemList to a suspend function for coroutine support
- Enhance Discord RPC connection management with cooldown and error handling
- Cached track audio not being invalidated causing alternative track source to not being played
- Play next not working
- Update pendingNextIndex when playing a track from the playlist
- **webview**: Linux webview crashing the app
- Add mavenLocal() to plugin and dependency resolution management
- **plugin**: Handle service closure exception during authentication check
- **sidebar**: Add spacer to AppSidebar for improved layout
- **remote-control**: Update connection handling and improve logging for remote control events
- Add window insets to top bar and bottom navigation bar, queue sheet
- **stream-proxy**: Stream upstream audio instead of buffering the whole track
- **newpipe**: Fall back through multiple searches when ISRC search misses
- **audio-api**: Enhance fallback mechanism for text search results in YouTube
- **audio-player**: Android shuffle wasnt working
- **stream-proxy**: Improve logging for cache timeout and handle disconnection scenarios
- **macos**: Add GraalVM runtime dependency and initialize GraalVm in main function
- **android**: Create intermediate directories for Rust targets to prevent runtime errors
- **android**: Update sharing functionality to use chooser intent with new task flag
- **android**: Simplify service start logic for PlaybackService to avoid crashes on background playback
- **android**: Update playback state management to ensure guests follow host's play state
- **android**: App stuck on splash screen from main-thread string loading
- **downloads**: Respect download format/quality and never save manifests or video
- **ios**: Run Zipline on an 8 MiB stack thread
- **server**: Don't crash when the proxy port is still in use
- **ios**: Stream formats AVPlayer can play
- **gradle**: Restore VFS watch setting and clean up properties
- **build**: Restore version catalog lost in dev merge
- **ios**: Make the login WebView identify as Mobile Safari
- Update website URLs from spotube.org to spotube.cc
## [5.1.2](https://github.com/team-spotube/spotube/compare/v5.1.1...v5.1.2) (2026-06-05)
### Bug Fixes

View File

@ -4,7 +4,7 @@
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!
<a href="https://spotube.org"><img alt="Visit the website" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/website_vector.svg"></a>
<a href="https://spotube.cc"><img alt="Visit the website" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/documentation/website_vector.svg"></a>
<a href="https://discord.gg/uJ94vxB6vg"><img alt="Discord Server" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/social/discord-plural_vector.svg"></a>
<a href="https://patreon.com/krtirtho"><img alt="Support me on Patron" height="56" src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/cozy/donate/patreon-singular_vector.svg"></a>
@ -37,11 +37,11 @@ Bring your own music metadata/playlist/audio-source with plugins created by comm
### ⬇️ Download
Download Spotube from the Official Website: https://spotube.org
Download Spotube from the Official Website: https://spotube.cc
### 🔄 Nightly Builds
Grab the latest nightly builds of Spotube [from the Offical Website](https://spotube.org/downloads/nightly).
Grab the latest nightly builds of Spotube [from the Offical Website](https://spotube.cc/downloads/nightly).
## 🕳️ Building from source
@ -166,7 +166,7 @@ Android picks the Rust profile from its build type (`debug` or `release`) on its
### Releases
Releases are built by [`spotube-release-binary.yml`](.github/workflows/spotube-release-binary.yml), run manually (`workflow_dispatch`) as `stable` or `nightly`. Each desktop platform (Linux x86_64 and aarch64, Windows, macOS) builds its native installers on its own runner. Android builds a signed APK.
Releases are built by [`spotube-release-binary.yml`](.github/workflows/spotube-release-binary.yml), run manually (`workflow_dispatch`) as `stable`, `beta` or `nightly`. A beta is the stable build released like a stable release (draft, not a pre-release), tagged `v<version>-beta.N` (set `betaNumber` in `composeApp/build.gradle.kts` to N, and back to `null` for stable). Each desktop platform (Linux x86_64 and aarch64, Windows, macOS) builds its native installers on its own runner. Android builds a signed APK.
## 👥 The Spotube team

View File

@ -48,6 +48,10 @@ plugins {
val bundleId = "org.spotube.spotube"
val version = "6.0.0"
// Set to N to release <version>-beta.N (same app id, icons and name as stable); null for a plain stable release.
// Installer metadata (packageVersion) must stay numeric, so it keeps using plain `version`.
val betaNumber: Int? = 0
// Betas share the stable app id, so bump this for every beta: Android only updates to a higher versionCode.
val buildNumber = 46
// Desktop icon channel; Android picks its icons via the stable/nightly product flavor. Use -Pnightly=true.
val isNightly = providers.gradleProperty("nightly").map { it.toBoolean() }.getOrElse(false)
@ -68,9 +72,9 @@ val isProductionBuild = providers.gradleProperty("production").map { it.toBoolea
}
)
val targetName = "Spotube"
val homePageUrl = "https://spotube.org"
val homePageUrl = "https://spotube.cc"
val repositoryUrl = "https://github.com/team-spotube/spotube"
val appVersionName = version
val appVersionName = if (betaNumber != null) "$version-beta.$betaNumber" else version
val appBuildNumber = if (isNightly) nightlyBuildNumber else buildNumber
val appRepositoryUrl = repositoryUrl
// CI reads the release version from here instead of scraping this file.
@ -375,8 +379,8 @@ android {
applicationId = bundleId
minSdk = libs.versions.android.minSdk.get().toInt()
targetSdk = libs.versions.android.targetSdk.get().toInt()
versionCode = buildNumber
versionName = version
versionCode = appBuildNumber
versionName = appVersionName
}
// stable = production channel, nightly = beta channel (own icon, name and installable side by side)
flavorDimensions += "channel"

View File

@ -253,7 +253,7 @@ fun App(
onDismiss = appUpdateService::dismissUpdate,
onIgnore = appUpdateService::ignoreUpdate,
onUpdate = {
runCatching { openUrlInBrowser("https://spotube.org/downloads/") }
runCatching { openUrlInBrowser("https://spotube.cc/downloads/") }
appUpdateService.dismissUpdate()
})
}

View File

@ -20,9 +20,11 @@ kotlin.code.style=official
kotlin.daemon.jvmargs=-Xmx3072M
kotlin.mpp.stability.nowarn=true
kotlin.incremental=true
kotlin.native.jvmArgs=-Xmx6g
#Gradle
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
# The Kotlin/Native release framework link (iOS) runs in the Gradle daemon and OOMs below ~6g
org.gradle.jvmargs=-Xmx6g -XX:MaxMetaspaceSize=1g
org.gradle.configuration-cache=true
org.gradle.caching=true

View File

@ -4,7 +4,7 @@ pkgver={{version}}
pkgrel={{pkgrel}}
pkgdesc="Open source, plugin powered music streaming client"
arch=(x86_64 aarch64)
url="https://spotube.org"
url="https://spotube.cc"
license=('AGPL-3.0-or-later')
# libvlc + plugins for playback (FFmpeg demux/decode, GnuTLS for HTTPS streams, PulseAudio/PipeWire output),
# WebKitGTK 4.1 for the webview, and the X11/GL/ALSA libraries the AWT/Skiko natives link

View File

@ -13,7 +13,7 @@ enclosed in quotation marks, you should use an editor that supports UTF-8, not t
<!-- == SOFTWARE SPECIFIC SECTION == -->
<title>spotube (Install)</title>
<authors>Team Spotube</authors>
<projectUrl>https://spotube.org</projectUrl>
<projectUrl>https://spotube.cc</projectUrl>
<iconUrl>
https://rawcdn.githack.com/team-spotube/spotube/69a310c78f5ceaf4eab7dfee98f187d38211c9ba/assets/branding/spotube-logo.png</iconUrl>
<copyright>2026 Kingkor Roy Tirtho and Spotube Contributors</copyright>
@ -21,7 +21,7 @@ enclosed in quotation marks, you should use an editor that supports UTF-8, not t
<licenseUrl>https://github.com/team-spotube/spotube/blob/master/LICENSE</licenseUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<projectSourceUrl>https://github.com/team-spotube/spotube</projectSourceUrl>
<docsUrl>https://spotube.org</docsUrl>
<docsUrl>https://spotube.cc</docsUrl>
<bugTrackerUrl>https://github.com/team-spotube/spotube/issues/new</bugTrackerUrl>
<tags>spotube music audio music-player streaming lyrics plugins foss</tags>
<summary>Open source, plugin powered music streaming client</summary>

View File

@ -47,7 +47,7 @@
<keyword>lyrics</keyword>
</keywords>
<url type="homepage">https://spotube.org</url>
<url type="homepage">https://spotube.cc</url>
<url type="bugtracker">https://github.com/team-spotube/spotube/issues</url>
<url type="vcs-browser">https://github.com/team-spotube/spotube</url>
<url type="donation">https://opencollective.com/spotube</url>

View File

@ -6,10 +6,10 @@ PackageLocale: en-US
Publisher: Team Spotube
PublisherUrl: https://github.com/team-spotube
PublisherSupportUrl: https://github.com/team-spotube/spotube/issues
PrivacyUrl: https://spotube.org/p/privacy
PrivacyUrl: https://spotube.cc/p/privacy
Author: Team Spotube
PackageName: Spotube
PackageUrl: https://spotube.org
PackageUrl: https://spotube.cc
License: AGPL-3.0-or-later
LicenseUrl: https://github.com/team-spotube/spotube/blob/master/LICENSE
Copyright: Copyright (c) 2022-2026 Kingkor Roy Tirtho and Spotube Contributors