From abacbf2b41b0c45fa46039b61deef3a954fe9e13 Mon Sep 17 00:00:00 2001
From: NoCrypt <57245077+NoCrypt@users.noreply.github.com>
Date: Sat, 10 Aug 2024 20:49:19 +0700
Subject: [PATCH] feat: controls in pip on android
by correctly implementing Media Session using external plugin
---
capacitor/android/app/capacitor.build.gradle | 1 +
.../android/app/src/main/AndroidManifest.xml | 1 +
capacitor/android/capacitor.settings.gradle | 3 ++
capacitor/package.json | 1 +
common/views/Player/MediaHandler.svelte | 32 ++++++++++---------
common/views/Player/Player.svelte | 28 ++++++++++++----
pnpm-lock.yaml | 12 +++++++
7 files changed, 56 insertions(+), 22 deletions(-)
diff --git a/capacitor/android/app/capacitor.build.gradle b/capacitor/android/app/capacitor.build.gradle
index e868c8b..bb255f4 100644
--- a/capacitor/android/app/capacitor.build.gradle
+++ b/capacitor/android/app/capacitor.build.gradle
@@ -16,6 +16,7 @@ dependencies {
implementation project(':capacitor-filesystem')
implementation project(':capacitor-local-notifications')
implementation project(':capacitor-status-bar')
+ implementation project(':jofr-capacitor-media-session')
implementation project(':capacitor-nodejs')
implementation project(':capacitor-plugin-safe-area')
implementation project(':capacitor-volume-control')
diff --git a/capacitor/android/app/src/main/AndroidManifest.xml b/capacitor/android/app/src/main/AndroidManifest.xml
index b539c6f..843f525 100644
--- a/capacitor/android/app/src/main/AndroidManifest.xml
+++ b/capacitor/android/app/src/main/AndroidManifest.xml
@@ -54,6 +54,7 @@
+
diff --git a/capacitor/android/capacitor.settings.gradle b/capacitor/android/capacitor.settings.gradle
index 85780dc..bd07bcc 100644
--- a/capacitor/android/capacitor.settings.gradle
+++ b/capacitor/android/capacitor.settings.gradle
@@ -23,6 +23,9 @@ project(':capacitor-local-notifications').projectDir = new File('../../node_modu
include ':capacitor-status-bar'
project(':capacitor-status-bar').projectDir = new File('../../node_modules/@capacitor/status-bar/android')
+include ':jofr-capacitor-media-session'
+project(':jofr-capacitor-media-session').projectDir = new File('../../node_modules/@jofr/capacitor-media-session/android')
+
include ':capacitor-nodejs'
project(':capacitor-nodejs').projectDir = new File('../../node_modules/capacitor-nodejs/android')
diff --git a/capacitor/package.json b/capacitor/package.json
index 2c98c1f..5a178ae 100644
--- a/capacitor/package.json
+++ b/capacitor/package.json
@@ -37,6 +37,7 @@
"@capacitor/ios": "^6.1.1",
"@capacitor/local-notifications": "^6.0.0",
"@capacitor/status-bar": "^6.0.0",
+ "@jofr/capacitor-media-session": "^4.0.0",
"capacitor-nodejs": "https://github.com/hampoelz/Capacitor-NodeJS/releases/download/v1.0.0-beta.7/capacitor-nodejs.tgz",
"capacitor-plugin-safe-area": "^3.0.3",
"capacitor-volume-control": "^0.0.1",
diff --git a/common/views/Player/MediaHandler.svelte b/common/views/Player/MediaHandler.svelte
index 6b29e46..1d1e3b1 100644
--- a/common/views/Player/MediaHandler.svelte
+++ b/common/views/Player/MediaHandler.svelte
@@ -5,6 +5,7 @@
import { tick } from 'svelte'
import { state } from '../WatchTogether/WatchTogether.svelte'
import IPC from '@/modules/ipc.js'
+ import { SUPPORTS } from '@/modules/support.js';
const episodeRx = /Episode (\d+) - (.*)/
@@ -183,23 +184,24 @@
})
function setMediaSession (nowPlaying) {
- if (typeof MediaMetadata === 'undefined') return
const name = [nowPlaying.title, nowPlaying.episode, nowPlaying.episodeTitle, 'Migu'].filter(i => i).join(' - ')
-
- const metadata =
- nowPlaying.thumbnail
- ? new MediaMetadata({
- title: name,
- artwork: [
- {
- src: nowPlaying.thumbnail,
- sizes: '256x256',
- type: 'image/jpg'
- }
+
+ const metadata = {
+ title: nowPlaying.title,
+ album: nowPlaying.episodeTitle,
+ artist: 'Migu',
+ artwork: [
+ {
+ src: nowPlaying.thumbnail ? nowPlaying.thumbnail : './logo_filled.png',
+ sizes: '256x256',
+ type: 'image/jpg'
+ }
]
- })
- : new MediaMetadata({ title: name })
- navigator.mediaSession.metadata = metadata
+ }
+
+ if (SUPPORTS.isAndroid) window.Capacitor.Plugins.MediaSession.setMetadata(metadata)
+ if (typeof MediaMetadata === 'undefined') return
+ navigator.mediaSession.metadata = new MediaMetadata(metadata)
}
function setDiscordRPC (np = nowPlaying.value) {
diff --git a/common/views/Player/Player.svelte b/common/views/Player/Player.svelte
index 0e692c9..ea9bf40 100644
--- a/common/views/Player/Player.svelte
+++ b/common/views/Player/Player.svelte
@@ -42,6 +42,7 @@
}
function updatew2g () {
+ if (SUPPORTS.isAndroid) window.Capacitor.Plugins.MediaSession.setPlaybackState( {playbackState: paused ? 'paused' : 'playing'} )
w2gEmitter.emit('player', { time: Math.floor(currentTime), paused })
}
@@ -282,6 +283,8 @@
}
function playPause () {
paused = !paused
+ if (SUPPORTS.isAndroid) window.Capacitor.Plugins.MediaSession.setPlaybackState( {playbackState: paused ? 'paused' : 'playing'} )
+
resetImmerse()
}
function toggleMute () {
@@ -735,20 +738,31 @@
resetImmerse()
}, 150)
}
- $: navigator.mediaSession?.setPositionState({
+
+ const mediaSession = navigator.mediaSession ? navigator.mediaSession : window.Capacitor.Plugins.MediaSession
+ $: mediaSession?.setPositionState({
duration: Math.max(0, safeduration || 0),
playbackRate: 1,
position: Math.max(0, Math.min(safeduration || 0, currentTime || 0))
})
if ('mediaSession' in navigator) {
- navigator.mediaSession.setActionHandler('play', playPause)
- navigator.mediaSession.setActionHandler('pause', playPause)
- navigator.mediaSession.setActionHandler('nexttrack', playNext)
- navigator.mediaSession.setActionHandler('previoustrack', playLast)
- navigator.mediaSession.setActionHandler('seekforward', forward)
- navigator.mediaSession.setActionHandler('seekbackward', rewind)
+ mediaSession.setActionHandler('play', playPause)
+ mediaSession.setActionHandler('pause', playPause)
+ mediaSession.setActionHandler('nexttrack', playNext)
+ mediaSession.setActionHandler('previoustrack', playLast)
+ mediaSession.setActionHandler('seekforward', forward)
+ mediaSession.setActionHandler('seekbackward', rewind)
+ } else {
+ mediaSession.setActionHandler({action: 'play'}, playPause)
+ mediaSession.setActionHandler({action: 'pause'}, playPause)
+ mediaSession.setActionHandler({action: 'nexttrack'}, playNext)
+ mediaSession.setActionHandler({action: 'previoustrack'}, playLast)
+ mediaSession.setActionHandler({action: 'seekforward'}, forward)
+ mediaSession.setActionHandler({action: 'seekbackward'}, rewind)
}
+
+
let stats = null
let requestCallback = null
function toggleStats () {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d88dcaf..00fe22d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -96,6 +96,9 @@ importers:
'@capacitor/status-bar':
specifier: ^6.0.0
version: 6.0.0(@capacitor/core@6.1.1)
+ '@jofr/capacitor-media-session':
+ specifier: ^4.0.0
+ version: 4.0.0(@capacitor/core@6.1.1)
capacitor-nodejs:
specifier: https://github.com/hampoelz/Capacitor-NodeJS/releases/download/v1.0.0-beta.7/capacitor-nodejs.tgz
version: https://github.com/hampoelz/Capacitor-NodeJS/releases/download/v1.0.0-beta.7/capacitor-nodejs.tgz(@capacitor/core@6.1.1)
@@ -674,6 +677,11 @@ packages:
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
engines: {node: '>=12'}
+ '@jofr/capacitor-media-session@4.0.0':
+ resolution: {integrity: sha512-IGfc6BUzeeR0sJkk+0/jij3l0h78NdTqPMwBc9LXZrojtiqNtg4tw3CnIkYGccwZ/0glV3hPl8HVNTElOPVCyg==}
+ peerDependencies:
+ '@capacitor/core': ^6.0.0
+
'@jridgewell/gen-mapping@0.3.5':
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'}
@@ -6173,6 +6181,10 @@ snapshots:
wrap-ansi: 8.1.0
wrap-ansi-cjs: wrap-ansi@7.0.0
+ '@jofr/capacitor-media-session@4.0.0(@capacitor/core@6.1.1)':
+ dependencies:
+ '@capacitor/core': 6.1.1
+
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1