@capgo/capacitor-jw-player 0.0.1 → 0.0.5

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.
@@ -13,6 +13,8 @@ Pod::Spec.new do |s|
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
14
  s.ios.deployment_target = '14.0'
15
15
  s.dependency 'Capacitor'
16
- s.dependency 'JWPlayerKit'
16
+ s.dependency 'JWPlayerKit', '>= 4.0.0'
17
+ s.dependency 'google-cast-sdk', '>= 4.8.1'
18
+ s.dependency 'Protobuf', '>= 3.13'
17
19
  s.swift_version = '5.1'
18
20
  end
package/Package.swift CHANGED
@@ -1,6 +1,11 @@
1
1
  // swift-tools-version: 5.9
2
2
  import PackageDescription
3
3
 
4
+ struct GoogleCastMetadata {
5
+ static let version: String = "4.8.3"
6
+ static let checksum: String = "bc2c3c2434ef2895a0388ac3f16932242d3d3ac11805f810dbe7d7bce3bb27f6"
7
+ }
8
+
4
9
  let package = Package(
5
10
  name: "CapgoCapacitorJwPlayer",
6
11
  platforms: [.iOS(.v14)],
@@ -10,8 +15,8 @@ let package = Package(
10
15
  targets: ["JwPlayerPlugin"])
11
16
  ],
12
17
  dependencies: [
13
- .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
14
- .package(url: "https://github.com/jwplayer/JWPlayerKit-package.git", .upToNextMajor(from: "4.21.3"))
18
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "7.2.0"),
19
+ .package(url: "https://github.com/jwplayer/JWPlayerKit-package.git", .upToNextMajor(from: "4.22.0"))
15
20
  ],
16
21
  targets: [
17
22
  .target(
@@ -22,6 +27,11 @@ let package = Package(
22
27
  .product(name: "JWPlayerKit", package: "JWPlayerKit-package")
23
28
  ],
24
29
  path: "ios/Sources/JwPlayerPlugin"),
30
+ .binaryTarget(
31
+ name: "GoogleCast",
32
+ url: "https://dl.google.com/dl/chromecast/sdk/ios/GoogleCastSDK-ios-\(GoogleCastMetadata.version)_dynamic.xcframework.zip",
33
+ checksum: GoogleCastMetadata.checksum
34
+ ),
25
35
  .testTarget(
26
36
  name: "JwPlayerPluginTests",
27
37
  dependencies: ["JwPlayerPlugin"],
@@ -62,6 +62,7 @@ dependencies {
62
62
 
63
63
  implementation "com.jwplayer:jwplayer-core:$jwPlayerVersion"
64
64
  implementation "com.jwplayer:jwplayer-common:$jwPlayerVersion"
65
+ implementation "com.jwplayer:jwplayer-chromecast:$jwPlayerVersion"
65
66
 
66
67
  implementation "androidx.media3:media3-common:$media3ExoVersion"
67
68
  implementation "androidx.media3:media3-exoplayer:$media3ExoVersion"
@@ -14,6 +14,11 @@
14
14
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
15
15
 
16
16
  <application>
17
+
18
+ <meta-data
19
+ android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
20
+ android:value="ee.forgr.capacitor_jw_player.CastOptionsProvider" />
21
+
17
22
  <activity
18
23
  android:name=".PlayerActivity"
19
24
  android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
@@ -0,0 +1,35 @@
1
+ package ee.forgr.capacitor_jw_player;
2
+
3
+ import android.content.Context;
4
+
5
+ import androidx.annotation.NonNull;
6
+
7
+ import com.google.android.gms.cast.CastMediaControlIntent;
8
+ import com.google.android.gms.cast.LaunchOptions;
9
+ import com.google.android.gms.cast.framework.CastOptions;
10
+ import com.google.android.gms.cast.framework.OptionsProvider;
11
+ import com.google.android.gms.cast.framework.SessionProvider;
12
+
13
+ import java.util.List;
14
+ import java.util.Locale;
15
+
16
+ public class CastOptionsProvider implements OptionsProvider {
17
+
18
+ @NonNull
19
+ @Override
20
+ public CastOptions getCastOptions(@NonNull Context context) {
21
+ LaunchOptions launchOptions = new LaunchOptions.Builder()
22
+ .setLocale(Locale.US)
23
+ .build();
24
+
25
+ return new CastOptions.Builder()
26
+ .setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
27
+ .setLaunchOptions(launchOptions)
28
+ .build();
29
+ }
30
+
31
+ @Override
32
+ public List<SessionProvider> getAdditionalSessionProviders(Context context) {
33
+ return null;
34
+ }
35
+ }
@@ -9,6 +9,7 @@ import com.getcapacitor.Plugin;
9
9
  import com.getcapacitor.PluginCall;
10
10
  import com.getcapacitor.PluginMethod;
11
11
  import com.getcapacitor.annotation.CapacitorPlugin;
12
+ import com.google.android.gms.cast.framework.CastContext;
12
13
  import com.jwplayer.pub.api.JWPlayer;
13
14
  import com.jwplayer.pub.api.configuration.PlayerConfig;
14
15
  import com.jwplayer.pub.api.license.LicenseUtil;
@@ -1,6 +1,7 @@
1
1
  package ee.forgr.capacitor_jw_player;
2
2
 
3
3
  import android.app.Activity;
4
+ import android.content.Context;
4
5
  import android.content.Intent;
5
6
  import android.content.res.Configuration;
6
7
  import android.graphics.Rect;
@@ -18,6 +19,11 @@ import android.widget.ImageView;
18
19
 
19
20
  import androidx.appcompat.app.AppCompatActivity;
20
21
 
22
+ import com.google.android.gms.cast.CastMediaControlIntent;
23
+ import com.google.android.gms.cast.LaunchOptions;
24
+ import com.google.android.gms.cast.framework.CastOptions;
25
+ import com.google.android.gms.cast.framework.OptionsProvider;
26
+ import com.google.android.gms.cast.framework.SessionProvider;
21
27
  import com.jwplayer.pub.api.JWPlayer;
22
28
  import com.jwplayer.pub.api.PlayerState;
23
29
  import com.jwplayer.pub.api.UiGroup;
@@ -38,6 +44,7 @@ import com.jwplayer.ui.views.ControlbarView;
38
44
 
39
45
  import java.util.ArrayList;
40
46
  import java.util.List;
47
+ import java.util.Locale;
41
48
 
42
49
  public class PlayerActivity extends AppCompatActivity implements
43
50
  VideoPlayerEvents.OnFullscreenListener,
@@ -89,6 +96,7 @@ public class PlayerActivity extends AppCompatActivity implements
89
96
  mPlayer = mPlayerView.getPlayer();
90
97
  mPlayer.registerActivityForPip(this, getSupportActionBar());
91
98
 
99
+
92
100
  // Delte fullscreen button
93
101
  ControlbarView customControlBar = mPlayerView.getControlsContainer().getControlbarView();
94
102
  ImageView enterFullScreenButton = customControlBar.findViewById(com.longtailvideo.jwplayer.R.id.controlbar_enter_fullscreen_btn);
@@ -466,4 +474,4 @@ public class PlayerActivity extends AppCompatActivity implements
466
474
  }
467
475
  }
468
476
  }
469
- }
477
+ }
@@ -2,7 +2,7 @@ import Foundation
2
2
  import Capacitor
3
3
  import JWPlayerKit
4
4
  import AVKit // Import AVKit for AVAudioSession
5
-
5
+ import GoogleCast
6
6
  /**
7
7
  * Please read the Capacitor iOS Plugin Development Guide
8
8
  * here: https://capacitorjs.com/docs/plugins/ios
@@ -17,7 +17,7 @@ protocol CallbackHandler {
17
17
 
18
18
 
19
19
  @objc(JwPlayerPlugin)
20
- public class JwPlayerPlugin: CAPPlugin, CAPBridgedPlugin {
20
+ public class JwPlayerPlugin: CAPPlugin, CAPBridgedPlugin, GCKLoggerDelegate {
21
21
  public let identifier = "JwPlayerPlugin"
22
22
  public let jsName = "JwPlayer"
23
23
  public let pluginMethods: [CAPPluginMethod] = [
@@ -48,6 +48,8 @@ public class JwPlayerPlugin: CAPPlugin, CAPBridgedPlugin {
48
48
  override public func load() {
49
49
  // Configure the audio session when the plugin loads
50
50
  setupAudioSession()
51
+ print("[JWPlayer] Plugin loaded. Note: Chromecast is initialized in AppDelegate.")
52
+ initializeChromecast()
51
53
  super.load()
52
54
  }
53
55
 
@@ -63,6 +65,32 @@ public class JwPlayerPlugin: CAPPlugin, CAPBridgedPlugin {
63
65
  }
64
66
  }
65
67
 
68
+ private func initializeChromecast() {
69
+ print("[ChromecastDebug] Starting Chromecast initialization")
70
+ let kReceiverAppID = "CC1AD845" // Custom App ID for Chromecast
71
+ let discoveryCriteria = GCKDiscoveryCriteria(applicationID: kReceiverAppID)
72
+ let options = GCKCastOptions(discoveryCriteria: discoveryCriteria)
73
+ options.physicalVolumeButtonsWillControlDeviceVolume = true
74
+ options.disableDiscoveryAutostart = false
75
+ print("[ChromecastDebug] Setting custom options for Chromecast")
76
+ do {
77
+ GCKCastContext.setSharedInstanceWith(options)
78
+ print("[ChromecastDebug] Chromecast context initialized with App ID: \(kReceiverAppID)")
79
+ } catch {
80
+ print("[ChromecastDebug] Error initializing Chromecast context: \(error.localizedDescription)")
81
+ }
82
+
83
+ let filter = GCKLoggerFilter.init()
84
+ filter.minimumLevel = .verbose
85
+ GCKLogger.sharedInstance().filter = filter
86
+ GCKLogger.sharedInstance().delegate = self
87
+ print("[ChromecastDebug] Logger initialized")
88
+ }
89
+
90
+ public func logMessage(_ message: String, at level: GCKLoggerLevel, fromFunction function: String, location: String) {
91
+ print(function + " - " + message)
92
+ }
93
+
66
94
  @objc func initialize(_ call: CAPPluginCall) {
67
95
  print("[JWPlayer] initialize called")
68
96
  guard let licenseKey = call.getString("licenseKey") else {
@@ -612,7 +640,6 @@ class CustomPlayerViewController: JWPlayerViewController, JWPlayerViewController
612
640
  print("[JWPlayer] Configuring player from init config")
613
641
  player.configurePlayer(with: config)
614
642
  print("[JWPlayer] Player configured successfully from init config")
615
-
616
643
  } else {
617
644
  print("[JWPlayer] Error: Player configuration is missing in viewDidLoad")
618
645
  self.callbackHandler?.notifyEventListener("error", data: ["message": "Player configuration missing"])
@@ -746,4 +773,79 @@ class CustomPlayerViewController: JWPlayerViewController, JWPlayerViewController
746
773
  callbackHandler?.onPlayerDismissed(isPiPDismissal: false)
747
774
  }
748
775
  }
776
+
777
+ // MARK: - JWCastDelegate
778
+ // Optionally, override the following methods to receive and respond to events when casting.
779
+ // Always call the superclass's method when overriding these methods.
780
+
781
+
782
+ // Called when a new casting device comes online.
783
+ override func castController(_ controller: JWCastController, devicesAvailable devices: [JWCastingDevice]) {
784
+ super.castController(controller, devicesAvailable: devices)
785
+ print("[JWCastDelegate]: \(devices.count) became available: \(devices)")
786
+ }
787
+
788
+ // Called when a successful connection to a casting device is made.
789
+ override func castController(_ controller: JWCastController, connectedTo device: JWCastingDevice) {
790
+ super.castController(controller, connectedTo: device)
791
+ print("[JWCastDelegate]: Connected to device: \(device.identifier)")
792
+ }
793
+
794
+
795
+ // Called when the casting device disconnects.
796
+ override func castController(_ controller: JWCastController, disconnectedWithError error: Error?) {
797
+ super.castController(controller, disconnectedWithError: error)
798
+
799
+ if let error {
800
+ print("[JWCastDelegate]: Casting disconnected from device with error: \"\(error.localizedDescription)\"")
801
+ }
802
+ else {
803
+ print("[JWCastDelegate]: Casting disconnected from device successfully.")
804
+ }
805
+ }
806
+
807
+
808
+ // Called when the connected casting device is temporarily disconnected. Video resumes on the mobile device until connection resumes.
809
+ override func castController(_ controller: JWCastController, connectionSuspendedWithDevice device: JWCastingDevice) {
810
+ super.castController(controller, connectionSuspendedWithDevice: device)
811
+ print("[JWCastDelegate]: Connection suspended with device: \(device.identifier)")
812
+ }
813
+
814
+
815
+ // Called after connection is reestablished following a temporary disconnection. Video resumes on the casting device.
816
+ override func castController(_ controller: JWCastController, connectionRecoveredWithDevice device: JWCastingDevice) {
817
+ super.castController(controller, connectionRecoveredWithDevice: device)
818
+ print("[JWCastDelegate]: Connection recovered with device: \(device.identifier)")
819
+ }
820
+
821
+ // Called when an attempt to connect to a casting device is unsuccessful.
822
+ override func castController(_ controller: JWCastController, connectionFailedWithError error: Error) {
823
+ super.castController(controller, connectionFailedWithError: error)
824
+ print("[JWCastDelegate]: Connection failed with error: \(error.localizedDescription)")
825
+ }
826
+
827
+ // Called when casting session begins.
828
+ override func castController(_ controller: JWCastController, castingBeganWithDevice device: JWCastingDevice) {
829
+ super.castController(controller, castingBeganWithDevice: device)
830
+ print("[JWCastDelegate]: Casting began with device: \(device.identifier)")
831
+ }
832
+
833
+ // Called when an attempt to cast to a casting device is unsuccessful.
834
+ override func castController(_ controller: JWCastController, castingFailedWithError error: Error) {
835
+ super.castController(controller, castingFailedWithError: error)
836
+ print("[JWCastDelegate]: Casting failed with error: \(error.localizedDescription)")
837
+ }
838
+
839
+ // Called when a casting session ends.
840
+ override func castController(_ controller: JWCastController, castingEndedWithError error: Error?) {
841
+ super.castController(controller, castingEndedWithError: error)
842
+
843
+ if let error {
844
+ print("[JWCastDelegate]: Casting ended with error: \"\(error.localizedDescription)\"")
845
+ }
846
+ else {
847
+ print("[JWCastDelegate]: Casting ended successfully.")
848
+ }
849
+ }
850
+
749
851
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-jw-player",
3
- "version": "0.0.1",
3
+ "version": "0.0.5",
4
4
  "description": "Playes videos from jwplayer.com",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -46,10 +46,10 @@
46
46
  "prepublishOnly": "npm run build"
47
47
  },
48
48
  "devDependencies": {
49
- "@capacitor/android": "^7.0.0",
50
- "@capacitor/core": "^7.0.0",
49
+ "@capacitor/android": "^7.2.0",
50
+ "@capacitor/core": "^7.2.0",
51
51
  "@capacitor/docgen": "^0.3.0",
52
- "@capacitor/ios": "^7.0.0",
52
+ "@capacitor/ios": "^7.2.0",
53
53
  "@ionic/eslint-config": "^0.4.0",
54
54
  "@ionic/prettier-config": "^4.0.0",
55
55
  "@ionic/swiftlint-config": "^2.0.0",
@@ -62,7 +62,7 @@
62
62
  "typescript": "~4.1.5"
63
63
  },
64
64
  "peerDependencies": {
65
- "@capacitor/core": ">=7.0.0"
65
+ "@capacitor/core": ">=7.2.0"
66
66
  },
67
67
  "prettier": "@ionic/prettier-config",
68
68
  "swiftlint": "@ionic/swiftlint-config",