@mustafaj/capacitor-plugin-playlist 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CapacitorPluginPlaylist.podspec +17 -0
  2. package/README.md +248 -0
  3. package/android/.project +34 -0
  4. package/android/build.gradle +69 -0
  5. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  6. package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  7. package/android/gradle.properties +22 -0
  8. package/android/gradlew +251 -0
  9. package/android/gradlew.bat +94 -0
  10. package/android/proguard-rules.pro +21 -0
  11. package/android/settings.gradle +2 -0
  12. package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +26 -0
  13. package/android/src/main/AndroidManifest.xml +4 -0
  14. package/android/src/main/java/org/dwbn/plugins/playlist/App.kt +19 -0
  15. package/android/src/main/java/org/dwbn/plugins/playlist/FakeR.kt +39 -0
  16. package/android/src/main/java/org/dwbn/plugins/playlist/OnStatusCallback.kt +34 -0
  17. package/android/src/main/java/org/dwbn/plugins/playlist/OnStatusReportListener.java +7 -0
  18. package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistItemOptions.java +52 -0
  19. package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +447 -0
  20. package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioErrorType.java +13 -0
  21. package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.java +487 -0
  22. package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioStatusMessage.java +35 -0
  23. package/android/src/main/java/org/dwbn/plugins/playlist/RmxConstants.java +42 -0
  24. package/android/src/main/java/org/dwbn/plugins/playlist/TrackRemovalItem.java +12 -0
  25. package/android/src/main/java/org/dwbn/plugins/playlist/data/AudioTrack.kt +94 -0
  26. package/android/src/main/java/org/dwbn/plugins/playlist/manager/MediaControlsListener.kt +13 -0
  27. package/android/src/main/java/org/dwbn/plugins/playlist/manager/Options.kt +77 -0
  28. package/android/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +308 -0
  29. package/android/src/main/java/org/dwbn/plugins/playlist/notification/PlaylistNotificationProvider.kt +26 -0
  30. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioApi.kt +114 -0
  31. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.java +146 -0
  32. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/BaseMediaApi.kt +36 -0
  33. package/android/src/main/java/org/dwbn/plugins/playlist/service/MediaImageProvider.kt +83 -0
  34. package/android/src/main/java/org/dwbn/plugins/playlist/service/MediaService.kt +98 -0
  35. package/android/src/main/res/.gitkeep +0 -0
  36. package/android/src/main/res/drawable/ic_closed_caption_white_24dp.xml +9 -0
  37. package/android/src/main/res/drawable/ic_demo_icon_adaptive.xml +15 -0
  38. package/android/src/main/res/drawable/ic_launcher_background.xml +48 -0
  39. package/android/src/main/res/drawable/ic_launcher_foreground.xml +22 -0
  40. package/android/src/main/res/drawable/ic_notification_icon.png +0 -0
  41. package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
  42. package/android/src/main/res/values/colors.xml +3 -0
  43. package/android/src/main/res/values/strings.xml +3 -0
  44. package/android/src/main/res/values/styles.xml +3 -0
  45. package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +18 -0
  46. package/dist/docs.json +2071 -0
  47. package/dist/esm/Constants.d.ts +164 -0
  48. package/dist/esm/Constants.js +175 -0
  49. package/dist/esm/Constants.js.map +1 -0
  50. package/dist/esm/RmxAudioPlayer.d.ts +181 -0
  51. package/dist/esm/RmxAudioPlayer.js +344 -0
  52. package/dist/esm/RmxAudioPlayer.js.map +1 -0
  53. package/dist/esm/definitions.d.ts +78 -0
  54. package/dist/esm/definitions.js +2 -0
  55. package/dist/esm/definitions.js.map +1 -0
  56. package/dist/esm/index.d.ts +5 -0
  57. package/dist/esm/index.js +6 -0
  58. package/dist/esm/index.js.map +1 -0
  59. package/dist/esm/interfaces.d.ts +246 -0
  60. package/dist/esm/interfaces.js +2 -0
  61. package/dist/esm/interfaces.js.map +1 -0
  62. package/dist/esm/plugin.d.ts +3 -0
  63. package/dist/esm/plugin.js +13 -0
  64. package/dist/esm/plugin.js.map +1 -0
  65. package/dist/esm/utils.d.ts +15 -0
  66. package/dist/esm/utils.js +48 -0
  67. package/dist/esm/utils.js.map +1 -0
  68. package/dist/esm/web.d.ts +54 -0
  69. package/dist/esm/web.js +409 -0
  70. package/dist/esm/web.js.map +1 -0
  71. package/dist/plugin.cjs.js +993 -0
  72. package/dist/plugin.cjs.js.map +1 -0
  73. package/dist/plugin.js +996 -0
  74. package/dist/plugin.js.map +1 -0
  75. package/ios/Plugin/AVBidirectionalQueuePlayer.swift +269 -0
  76. package/ios/Plugin/AudioTrack.swift +63 -0
  77. package/ios/Plugin/Constants.swift +39 -0
  78. package/ios/Plugin/DispatchQueue.swift +47 -0
  79. package/ios/Plugin/Info.plist +24 -0
  80. package/ios/Plugin/Plugin.h +10 -0
  81. package/ios/Plugin/Plugin.m +30 -0
  82. package/ios/Plugin/Plugin.swift +208 -0
  83. package/ios/Plugin/RmxAudioPlayer.swift +1150 -0
  84. package/ios/Plugin.xcodeproj/project.pbxproj +574 -0
  85. package/ios/Plugin.xcworkspace/contents.xcworkspacedata +10 -0
  86. package/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  87. package/ios/PluginTests/Info.plist +22 -0
  88. package/ios/PluginTests/PluginTests.swift +35 -0
  89. package/ios/Podfile +16 -0
  90. package/package.json +89 -0
@@ -0,0 +1,36 @@
1
+ package org.dwbn.plugins.playlist.playlist
2
+
3
+ import com.devbrackets.android.exomedia.listener.*
4
+ import com.devbrackets.android.playlistcore.api.MediaPlayerApi
5
+ import com.devbrackets.android.playlistcore.listener.MediaStatusListener
6
+ import org.dwbn.plugins.playlist.data.AudioTrack
7
+
8
+ abstract class BaseMediaApi : MediaPlayerApi<AudioTrack>, OnPreparedListener, OnCompletionListener,
9
+ OnErrorListener, OnSeekCompletionListener, OnBufferUpdateListener {
10
+ protected var prepared: Boolean = false
11
+ protected var bufferPercent: Int = 0
12
+
13
+ protected var statusListener: MediaStatusListener<AudioTrack>? = null
14
+ override fun setMediaStatusListener(listener: MediaStatusListener<AudioTrack>) {
15
+ statusListener = listener
16
+ }
17
+ override fun onCompletion() {
18
+ statusListener?.onCompletion(this)
19
+ }
20
+ override fun onPrepared() {
21
+ prepared = true
22
+ statusListener?.onPrepared(this)
23
+ }
24
+ override fun onSeekComplete() {
25
+ statusListener?.onSeekComplete(this)
26
+ }
27
+
28
+ override fun onError(e: Exception?): Boolean {
29
+ return statusListener?.onError(this) == true
30
+ }
31
+
32
+ override fun onBufferingUpdate(percent: Int) {
33
+ bufferPercent = percent
34
+ statusListener?.onBufferingUpdate(this, percent)
35
+ }
36
+ }
@@ -0,0 +1,83 @@
1
+ package org.dwbn.plugins.playlist.service
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.graphics.BitmapFactory
6
+ import com.bumptech.glide.Glide
7
+ import com.bumptech.glide.RequestManager
8
+ import com.bumptech.glide.request.target.CustomTarget
9
+ import com.bumptech.glide.request.transition.Transition
10
+ import com.devbrackets.android.playlistcore.components.image.ImageProvider
11
+ import org.dwbn.plugins.playlist.FakeR
12
+ import org.dwbn.plugins.playlist.data.AudioTrack
13
+ import org.dwbn.plugins.playlist.manager.Options
14
+
15
+
16
+ class MediaImageProvider(
17
+ context: Context,
18
+ val onImageUpdatedListener: OnImageUpdatedListener,
19
+ options: Options
20
+ ) : ImageProvider<AudioTrack> {
21
+
22
+ interface OnImageUpdatedListener {
23
+ fun onImageUpdated()
24
+ }
25
+
26
+ private var options: Options? = null
27
+ private val glide: RequestManager = Glide.with(context.applicationContext)
28
+ private val fakeR: FakeR = FakeR(context.applicationContext)
29
+ private val remoteViewImageTarget = RemoteViewImageTarget()
30
+ private var defaultArtworkImage: Bitmap? = null
31
+ private var artworkImage: Bitmap? = null
32
+ private var notificationIconId = 0
33
+ override val notificationIconRes: Int
34
+ get() = mipmapIcon
35
+
36
+ override val remoteViewIconRes: Int
37
+ get() = mipmapIcon
38
+
39
+ override val largeNotificationImage: Bitmap?
40
+ get() = remoteViewArtwork
41
+
42
+ override var remoteViewArtwork: Bitmap? = null
43
+ get() = if (artworkImage != null) artworkImage else defaultArtworkImage
44
+ private set
45
+
46
+ override fun updateImages(playlistItem: AudioTrack) {
47
+ glide.asBitmap().load(playlistItem.artworkUrl).into(remoteViewImageTarget)
48
+ }
49
+
50
+ // return R.mipmap.icon; // this comes from cordova itself.
51
+ private val mipmapIcon: Int
52
+ get() {
53
+ // return R.mipmap.icon; // this comes from cordova itself.
54
+ if (notificationIconId <= 0) {
55
+ notificationIconId = fakeR.getId("drawable", options?.icon)
56
+ }
57
+ return notificationIconId
58
+ }
59
+
60
+ /**
61
+ * A class used to listen to the loading of the large lock screen images and perform
62
+ * the correct functionality to update the artwork once it is loaded.
63
+ *
64
+ * **NOTE:** This is a Glide Image loader class
65
+ */
66
+ private inner class RemoteViewImageTarget : CustomTarget<Bitmap>() {
67
+ override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
68
+ artworkImage = resource
69
+ }
70
+
71
+ override fun onLoadCleared(placeholder: android.graphics.drawable.Drawable?) {
72
+ // No cleanup needed
73
+ }
74
+ }
75
+
76
+ init {
77
+ this.options = options
78
+ defaultArtworkImage = BitmapFactory.decodeResource(
79
+ context.resources,
80
+ fakeR.getId("drawable", options.icon)
81
+ )
82
+ }
83
+ }
@@ -0,0 +1,98 @@
1
+ package org.dwbn.plugins.playlist.service
2
+
3
+ import android.app.Notification
4
+ import android.app.Service
5
+ import android.content.Intent
6
+ import android.content.pm.ServiceInfo
7
+ import android.os.Build
8
+ import android.util.Log
9
+ import com.devbrackets.android.playlistcore.components.playlisthandler.PlaylistHandler
10
+ import com.devbrackets.android.playlistcore.service.BasePlaylistService
11
+ import org.dwbn.plugins.playlist.App
12
+ import org.dwbn.plugins.playlist.data.AudioTrack
13
+ import org.dwbn.plugins.playlist.manager.PlaylistManager
14
+ import org.dwbn.plugins.playlist.playlist.AudioApi
15
+ import org.dwbn.plugins.playlist.playlist.AudioPlaylistHandler
16
+ import org.dwbn.plugins.playlist.service.MediaImageProvider.OnImageUpdatedListener
17
+
18
+ /**
19
+ * A simple service that extends [BasePlaylistService] in order to provide
20
+ * the application specific information required.
21
+ */
22
+ class MediaService : BasePlaylistService<AudioTrack, PlaylistManager>() {
23
+ companion object {
24
+ private const val TAG = "MediaService"
25
+ }
26
+
27
+ override fun onCreate() {
28
+ super.onCreate()
29
+ // Adds the audio player implementation, otherwise there's nothing to play media with
30
+ val newAudio = AudioApi(applicationContext)
31
+ newAudio.addErrorListener(playlistManager)
32
+ playlistManager.mediaPlayers.add(newAudio)
33
+ }
34
+
35
+ override fun onDestroy() {
36
+ super.onDestroy()
37
+
38
+ // Releases and clears all the MediaPlayersMediaImageProvider
39
+ for (player in playlistManager.mediaPlayers) {
40
+ player.release()
41
+ }
42
+ playlistManager.mediaPlayers.clear()
43
+ }
44
+
45
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
46
+ return try {
47
+ super.onStartCommand(intent, flags, startId)
48
+ } catch (e: android.app.ForegroundServiceStartNotAllowedException) {
49
+ // Android 12+ blocks foreground service start from background
50
+ // Log the error but don't crash - service can still function without foreground status
51
+ Log.w(TAG, "Cannot start foreground service: app is in background", e)
52
+ // Return START_NOT_STICKY so service won't be restarted if killed
53
+ // The service will continue as a regular service (may be killed by system)
54
+ Service.START_NOT_STICKY
55
+ }
56
+ }
57
+
58
+ override fun runAsForeground(notificationId: Int, notification: Notification) {
59
+ if (inForeground) {
60
+ return
61
+ }
62
+
63
+ inForeground = true
64
+ try {
65
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
66
+ startForeground(notificationId, notification)
67
+ } else {
68
+ startForeground(notificationId, notification,
69
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
70
+ }
71
+ } catch (e: android.app.ForegroundServiceStartNotAllowedException) {
72
+ // Android 12+ blocks foreground service start from background
73
+ // Log the error but don't crash - service can still function without foreground status
74
+ Log.w(TAG, "Cannot start foreground service: app is in background", e)
75
+ inForeground = false
76
+ // Service will continue as a regular service (may be killed by system)
77
+ }
78
+ }
79
+
80
+ override val playlistManager: PlaylistManager
81
+ get() = (applicationContext as App).playlistManager
82
+
83
+ override fun newPlaylistHandler(): PlaylistHandler<AudioTrack> {
84
+ val imageProvider = MediaImageProvider(applicationContext, object : OnImageUpdatedListener {
85
+ override fun onImageUpdated() {
86
+ playlistHandler.updateMediaControls()
87
+ }
88
+ }, playlistManager.options)
89
+
90
+ return AudioPlaylistHandler.Builder(
91
+ applicationContext,
92
+ javaClass,
93
+ playlistManager,
94
+ imageProvider,
95
+ null
96
+ ).build()
97
+ }
98
+ }
File without changes
@@ -0,0 +1,9 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="24dp"
3
+ android:height="24dp"
4
+ android:viewportWidth="24.0"
5
+ android:viewportHeight="24.0">
6
+ <path
7
+ android:fillColor="#FFFFFFFF"
8
+ android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,11L9.5,11v-0.5h-2v3h2L9.5,13L11,13v1c0,0.55 -0.45,1 -1,1L7,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v1zM18,11h-1.5v-0.5h-2v3h2L16.5,13L18,13v1c0,0.55 -0.45,1 -1,1h-3c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v1z"/>
9
+ </vector>
@@ -0,0 +1,15 @@
1
+ <vector android:height="24dp" android:viewportHeight="50.8"
2
+ android:viewportWidth="50.8" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <path android:fillAlpha="1" android:fillColor="#4db6ac"
4
+ android:pathData="m13.76,23.11l0,16.89l3.57,-2.06l0,-14.83z"
5
+ android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.47587052"/>
6
+ <path android:fillAlpha="1" android:fillColor="#aed581"
7
+ android:pathData="m13.76,10.8l0,11.78l15.35,0l0,-3.05L13.98,10.8Z"
8
+ android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.52379054"/>
9
+ <path android:fillAlpha="1" android:fillColor="#f29312"
10
+ android:pathData="m17.85,23.11l0,14.53l12.93,-7.46l-1.66,0l0,-7.07z"
11
+ android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.40285373"/>
12
+ <path android:fillAlpha="1" android:fillColor="#ffee58"
13
+ android:pathData="m29.64,19.84l0,9.81l2.05,0L39.16,25.34Z"
14
+ android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.35085261"/>
15
+ </vector>
@@ -0,0 +1,48 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="108dp"
3
+ android:height="108dp"
4
+ android:viewportWidth="50.8"
5
+ android:viewportHeight="50.8">
6
+ <path
7
+ android:pathData="M-10.85,-0h72.57v50.8h-72.57z"
8
+ android:fillAlpha="1"
9
+ android:strokeColor="#00000000"
10
+ android:fillColor="#00796b"
11
+ android:strokeWidth="10.03837585"
12
+ android:strokeAlpha="1"/>
13
+ <path
14
+ android:pathData="M0,22.49l19.05,0l0,20.64l-19.05,0z"
15
+ android:fillAlpha="1"
16
+ android:strokeColor="#00000000"
17
+ android:fillColor="#64ffda"
18
+ android:strokeWidth="0.41645226"
19
+ android:strokeAlpha="1"/>
20
+ <path
21
+ android:pathData="M0,7.57l33.34,0l0,14.29l-33.34,0z"
22
+ android:fillAlpha="1"
23
+ android:strokeColor="#00000000"
24
+ android:fillColor="#aed581"
25
+ android:strokeWidth="0.45838892"
26
+ android:strokeAlpha="1"/>
27
+ <path
28
+ android:pathData="M33.97,7.57l16.83,0l0,9.53l-16.83,0z"
29
+ android:fillAlpha="1"
30
+ android:strokeColor="#00000000"
31
+ android:fillColor="#4db6ac"
32
+ android:strokeWidth="0.26590821"
33
+ android:strokeAlpha="1"/>
34
+ <path
35
+ android:pathData="m19.68,22.49l0,20.64l13.65,0 17.46,0L50.8,31.06L33.34,31.06L33.34,22.49Z"
36
+ android:fillAlpha="1"
37
+ android:strokeColor="#00000000"
38
+ android:fillColor="#f29312"
39
+ android:strokeWidth="0.77728117"
40
+ android:strokeAlpha="1"/>
41
+ <path
42
+ android:pathData="M33.97,17.73l16.83,0l0,12.7l-16.83,0z"
43
+ android:fillAlpha="1"
44
+ android:strokeColor="#00000000"
45
+ android:fillColor="#ffee58"
46
+ android:strokeWidth="0.30704439"
47
+ android:strokeAlpha="1"/>
48
+ </vector>
@@ -0,0 +1,22 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="108dp"
3
+ android:height="108dp"
4
+ android:viewportHeight="28.575"
5
+ android:viewportWidth="28.575">
6
+ <path
7
+ android:fillAlpha="1"
8
+ android:fillColor="#4db6ac"
9
+ android:pathData="m9.6242,13.3524l0,6.8882l1.5616,-0.8401l0,-6.0481z"/>
10
+ <path
11
+ android:fillAlpha="1"
12
+ android:fillColor="#aed581"
13
+ android:pathData="m9.6242,8.3344l0,4.8044l6.717,0l0,-1.242L9.7201,8.3344Z"/>
14
+ <path
15
+ android:fillAlpha="1"
16
+ android:fillColor="#f29312"
17
+ android:pathData="m11.4146,13.3524l0,5.925l5.6549,-3.0425l-0.7283,0l0,-2.8824z"/>
18
+ <path
19
+ android:fillAlpha="1"
20
+ android:fillColor="#ffee58"
21
+ android:pathData="m16.5704,12.0203l0,4.0013l0.8954,0L20.7367,14.2617Z"/>
22
+ </vector>
@@ -0,0 +1,15 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+ xmlns:app="http://schemas.android.com/apk/res-auto"
4
+ xmlns:tools="http://schemas.android.com/tools"
5
+ android:layout_width="match_parent"
6
+ android:layout_height="match_parent"
7
+ tools:context="com.getcapacitor.BridgeActivity"
8
+ >
9
+
10
+ <WebView
11
+ android:id="@+id/webview"
12
+ android:layout_width="fill_parent"
13
+ android:layout_height="fill_parent" />
14
+
15
+ </androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <resources>
3
+ </resources>
@@ -0,0 +1,3 @@
1
+ <resources>
2
+ <string name="my_string">Just a simple string</string>
3
+ </resources>
@@ -0,0 +1,3 @@
1
+ <resources>
2
+
3
+ </resources>
@@ -0,0 +1,18 @@
1
+ package com.getcapacitor;
2
+
3
+ import static org.junit.Assert.*;
4
+
5
+ import org.junit.Test;
6
+
7
+ /**
8
+ * Example local unit test, which will execute on the development machine (host).
9
+ *
10
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
11
+ */
12
+ public class ExampleUnitTest {
13
+
14
+ @Test
15
+ public void addition_isCorrect() throws Exception {
16
+ assertEquals(4, 2 + 2);
17
+ }
18
+ }