kaltura / playkit-ios Goto Github PK
View Code? Open in Web Editor NEWPlayKit: Kaltura Player SDK for iOS
Home Page: https://developer.kaltura.com/player/ios
License: GNU Affero General Public License v3.0
PlayKit: Kaltura Player SDK for iOS
Home Page: https://developer.kaltura.com/player/ios
License: GNU Affero General Public License v3.0
I've been trying to support ads for picture in picture using Kaltura SDK but it seems there's no way to support this via Playkit_IMA.
I've read some documentation about using Google IMA with picture in picture but it seems this documentation is not helping when trying to use Playkit_IMA with picture in picture.
Link for the documentation: https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture
My questions is, does Kaltura support ads via Playkit_IMA using picture in picture or is there other way in which this can be done?
We are in the process of updating our applications to Swift 4.0 and have identified the PlayKit library as a potential blocker to this. Are there current plans to update the codebase?
We've received an email stating the following:
Important: Upcoming changes to Google Cast SDK for iOS 13 needed for your app
We are asking all developers to update their iOS apps to the latest version of the Google Cast SDK (v4.4.4) released on August 12, 2019.
With the upcoming release of iOS 13, there are additional privacy controls which will cause new authorization dialogs to appear to users of apps that use the Cast iOS SDK.
We understand that triggering new dialogs may not be ideal for your app. To address this concern and to improve how the SDK works with iOS 13, the Google Cast team implemented changes in our new releases.
We are making two versions of the Cast iOS SDK available to developers,
- One which includes Guest Mode support
The SDK with Guest Mode will prompt a new Bluetooth®-related permission.
- One which excludes Guest Mode support
The SDK without Guest Mode will not prompt any new permissions for Bluetooth®.
In addition, some system-level APIs relating to device discovery will change behaviors in iOS 13, and we will update the Google Cast SDK accordingly. We strongly recommend that you update your apps to the new SDK to avoid a degraded experience on iOS 13.
Additional details can be found at: https://developers.google.com/cast/docs/ios_sender/ios13_changes
We don't use Google Cast SDK directly, but through your SDK, so we would make you know that you should update this component as soon as possible.
Is there any new version solving this problem to be released soon?
Thank you very much,
Oscar
I want to create a my own player using the playkit. unable to create dependency. please help me out of this.
I have tried this
.package(url: "https://github.com/kaltura/playkit-ios.git", from: "3.12.0")
when I try to generate xcode project, i got this issue
https://github.com/kaltura/playkit-ios.git @ 3.12.0: error: https://github.com/kaltura/playkit-ios.git has no manifest for version 3.12.0
Paste test code here
What you expected to happen
What actually happened
Paste the contents of the Xcode console here.
We are unable to AirPlay downloaded videos with the Kaltura iOS frameworks. The HLS(.m3u8) video files are downloaded using the DownloadToGo framework and are played using the PlayKit framework.
Steps to reproduce:
We are using the following framework versions managed by cocoapods in our project:
PlayKit: 3.25.0
PlayKit Providers: 1.10.0
PlayKitKava: 1.6.0
DownloadToGo: 3.15.0
KalturaClient: 14.1.0
Note: If the content is not downloaded and is being streamed then AirPlay works correctly
let url = try contentManager.itemPlaybackUrl(id: entryId)
let localAssetsManager = LocalAssetsManager.managerWithDefaultDataStore()
let mediaEntry = localAssetsManager.createLocalMediaEntry(for: entryId, localURL: url)
let mediaConfig = MediaConfig(mediaEntry: mediaEntry, startTime: startTime)
player.prepare(mediaConfig)
Video is played on the target AirPlay device
Video cannot be played on the target AirPlay device
2022-02-21 10:04:34.722355+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872c87c0>
2022-02-21 10:04:34.730 [Debug] [AVPlayerEngine.swift:294] play() > Play player
2022-02-21 10:04:34.731 [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 1.0
2022-02-21 10:04:34.751 [Debug] [KavaPlugin+AnalyticsPluginProtocol.swift:145] handlePlay() > play event
2022-02-21 10:04:34.817 [Debug] [KavaPlugin+AnalyticsPluginProtocol.swift:162] handlePlaying() > playing event
2022-02-21 10:04:34.818 [Debug] [KavaPlugin.swift:283] sendAnalyticsEvent(event:) > Action: resume
2022-02-21 10:04:34.818 [Debug] [KavaPlugin.swift:353] sendAnalyticsEvent(event:) > Sending Kava Event, resume (4): ["service": "analytics", "clientVer": "playkit/ios-3.25.0", "actualBitrate": "1922.881", "action": "trackEvent", "applicationVer": "505", "eventIndex": "9", "bufferTimeSum": "0.0", "referrer": "app://com.example.app1", "sessionId": "2A8071D2-8A1B-4493-8CFC-6996FF8ABF1C:0EBD01FF-D6C1-4CBA-ACC5-3DCF18B64AA8", "sessionStartTime": "1645391060.891", "eventType": "4", "bufferTime": "0.0", "deliveryType": "hls", "entryId": "1_q3eq1mi7", "position": "1.122", "playbackType": "vod", "application": "com.example.app1", "partnerId": "2066791"]
2022-02-21 10:04:34.823463+1300 Releases[2690:523443] 8.9.1 - [Firebase/Performance][I-PRF300005] URL length exceeds limits, truncating recorded URL - https://analytics.kaltura.com/api_v3/index.php.
2022-02-21 10:04:35.218882+1300 Releases[2690:524505] [tcp] tcp_input [C54.1.1.1:3] flags=[R] seq=1765588340, ack=0, win=0 state=LAST_ACK rcv_nxt=1765588340, snd_una=1153075
2022-02-21 10:04:35.221383+1300 Releases[2690:524505] [tcp] tcp_input [C54.1.1.1:3] flags=[R] seq=1765588340, ack=0, win=0 state=CLOSED rcv_nxt=1765588340, snd_una=1153075
2022-02-21 10:04:35.378564+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872ade80>
2022-02-21 10:04:35.420567+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872ad9c0>
2022-02-21 10:04:35.426470+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872ca640>
2022-02-21 10:04:35.768 [Debug] [KavaPlugin.swift:326] sendAnalyticsEvent(event:) > Response:
Status Code: 0
Error:
Data: {
time = "1645391075.631";
viewEventsEnabled = 1;
}
2022-02-21 10:04:35.776308+1300 Releases[2690:524505] 8.9.1 - [Firebase/Performance][I-PRF100009] Logging network request trace - https://analytics.kaltura.com/api_v3/index.php, Response code: 200, 947.5600ms
2022-02-21 10:04:35.778184+1300 Releases[2690:524505] 8.9.1 - [Firebase/Installations][I-FIS002000] -[FIRInstallationsIDController createGetInstallationItemPromise], appName: __FIRAPP_DEFAULT
2022-02-21 10:04:35.778425+1300 Releases[2690:524505] 8.9.1 - [Firebase/Installations][I-FIS002001] -[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:0], appName: __FIRAPP_DEFAULT
2022-02-21 10:04:37.005884+1300 Releases[2690:524518] [MediaRemote] No local output device available: (
"<MRAVConcreteOutputDevice:0x116e5d930 (local) \"Speaker\" uid=\"Speaker\" group_id=\"E667F8BA-E5FD-4194-BA70-B0088606ABA4\" bluetooth_id=(null) type=BuiltIn subtype=Speaker enc-prog-dl-assets fetch-sender-media-data opt-audio-ui>",
"<MRAVConcreteOutputDevice:0x116e5deb0 \"Ollie\U2019s MacBook Pro\" uid=\"ACE59E4D-A413-4399-BD46-699C7D06A8AC\" group_id=\"6D0EE75F-696A-43DA-B744-C0BA0F0EF18B\" bluetooth_id=(null) type=AirPlay subtype=Mac airplay2 airplay-receiving fetch-sender-media-data opt-audio-ui MacBookPro16,1>"
)
2022-02-21 10:04:37.009 [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2022-02-21 10:04:37.015 [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 3568.32
2022-02-21 10:04:43.823 [Debug] [KavaPlugin.swift:283] sendAnalyticsEvent(event:) > Action: view
2022-02-21 10:04:43.824 [Debug] [KavaPlugin.swift:353] sendAnalyticsEvent(event:) > Sending Kava Event, view (99): ["sessionStartTime": "1645391060.891", "averageBitrate": "1922.881", "deliveryType": "hls", "entryId": "1_q3eq1mi7", "service": "analytics", "eventType": "99", "application": "com.example.app1", "playbackType": "vod", "bufferTime": "0.0", "playTimeSum": "10.0", "eventIndex": "10", "captionsLanguage": "none", "partnerId": "2066791", "referrer": "app://com.example.app1", "bufferTimeSum": "0.0", "action": "trackEvent", "sessionId": "2A8071D2-8A1B-4493-8CFC-6996FF8ABF1C:0EBD01FF-D6C1-4CBA-ACC5-3DCF18B64AA8", "position": "3.252", "audioLanguage": "en", "clientVer": "playkit/ios-3.25.0", "applicationVer": "505", "actualBitrate": "1922.881"]
2022-02-21 10:04:43.828533+1300 Releases[2690:523443] 8.9.1 - [Firebase/Performance][I-PRF300005] URL length exceeds limits, truncating recorded URL - https://analytics.kaltura.com/api_v3/index.php.
2022-02-21 10:04:44.062 [Debug] [KavaPlugin.swift:326] sendAnalyticsEvent(event:) > Response:
Status Code: 0
Error:
Data: {
time = "1645391083.925";
viewEventsEnabled = 1;
}
2022-02-21 10:04:44.066275+1300 Releases[2690:524518] 8.9.1 - [Firebase/Performance][I-PRF100009] Logging network request trace - https://analytics.kaltura.com/api_v3/index.php, Response code: 200, 232.3020ms
2022-02-21 10:04:44.074071+1300 Releases[2690:524518] 8.9.1 - [Firebase/Installations][I-FIS002000] -[FIRInstallationsIDController createGetInstallationItemPromise], appName: __FIRAPP_DEFAULT
2022-02-21 10:04:44.074458+1300 Releases[2690:524518] 8.9.1 - [Firebase/Installations][I-FIS002001] -[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:0], appName: __FIRAPP_DEFAULT
2022-02-21 10:04:47.359100+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872a3880>
2022-02-21 10:04:47.424680+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2805ea3c0>
2022-02-21 10:04:47.429104+1300 Releases[2690:521657] Sentry - Debug:: Add breadcrumb: <SentryBreadcrumb: 0x2872b0640>
2022-02-21 10:04:48.804 [Debug] [AVPlayerEngine+Observation.swift:75] onAccessLogEntryNotification(notification:) > event log:
event log: averageAudioBitrate - 85728.0
event log: averageVideoBitrate - 2961376.0
event log: indicatedAverageBitrate - -1.0
event log: indicatedBitrate - 1969030.0
event log: observedBitrate - 36811172.0
event log: observedMaxBitrate - -1.0
event log: observedMinBitrate - -1.0
event log: switchBitrate - -1.0
event log: numberOfBytesTransferred - 761776
event log: numberOfStalls - 0
event log: URI - 'http://localhost:51856/1_q3eq1mi7/video/20b3cf06e10ac8f0ddac1e6c4c9a1fc4.m3u8'
event log: startupTime - -1.0
2022-02-21 10:04:48.821 [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 3568.32
2022-02-21 10:04:48.822 [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Ready
2022-02-21 10:04:48.823 [Debug] [KavaPlugin+AnalyticsPluginProtocol.swift:105] handleStateChanged(event:) > state changed event: PlayerEvent.StateChanged
2022-02-21 10:04:48.823 [Info] [KavaPlugin+AnalyticsPluginProtocol.swift:109] handleStateChanged(event:) > media ready
2022-02-21 10:04:48.849 [Warning] [AVPlayerEngine+Observation.swift:91] onErrorLogEntryNotification(notification:) > error description: Optional("Segment exceeds specified bandwidth for variant"), error domain: CoreMediaErrorDomain, error code: -12318
2022-02-21 10:04:49.175 [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2022-02-21 10:04:53.822 [Debug] [KavaPlugin.swift:283] sendAnalyticsEvent(event:) > Action: view
2022-02-21 10:04:53.824 [Debug] [KavaPlugin.swift:353] sendAnalyticsEvent(event:) > Sending Kava Event, view (99): ["actualBitrate": "1922.881", "audioLanguage": "en", "bufferTime": "0.0", "partnerId": "2066791", "sessionId": "2A8071D2-8A1B-4493-8CFC-6996FF8ABF1C:0EBD01FF-D6C1-4CBA-ACC5-3DCF18B64AA8", "position": "0.000", "averageBitrate": "1922.881", "application": "com.example.app1", "playTimeSum": "10.0", "applicationVer": "505", "clientVer": "playkit/ios-3.25.0", "entryId": "1_q3eq1mi7", "sessionStartTime": "1645391060.891", "eventIndex": "11", "service": "analytics", "referrer": "app://com.example.app1", "captionsLanguage": "none", "bufferTimeSum": "0.0", "playbackType": "vod", "eventType": "99", "deliveryType": "hls", "action": "trackEvent"]
2022-02-21 10:04:53.828872+1300 Releases[2690:524518] 8.9.1 - [Firebase/Performance][I-PRF300005] URL length exceeds limits, truncating recorded URL - https://analytics.kaltura.com/api_v3/index.php.
2022-02-21 10:04:54.197 [Debug] [KavaPlugin.swift:326] sendAnalyticsEvent(event:) > Response:
Status Code: 0
Error:
Data: {
time = "1645391093.92";
viewEventsEnabled = 1;
}
2022-02-21 10:04:54.197642+1300 Releases[2690:523443] 8.9.1 - [Firebase/Performance][I-PRF100009] Logging network request trace - https://analytics.kaltura.com/api_v3/index.php, Response code: 200, 367.3770ms
2022-02-21 10:04:54.199318+1300 Releases[2690:524504] 8.9.1 - [Firebase/Installations][I-FIS002000] -[FIRInstallationsIDController createGetInstallationItemPromise], appName: __FIRAPP_DEFAULT
2022-02-21 10:04:54.203900+1300 Releases[2690:524504] 8.9.1 - [Firebase/Installations][I-FIS002001] -[FIRInstallationsIDController installationWithValidAuthTokenForcingRefresh:0], appName: __FIRAPP_DEFAULT
I just need an example of how to stream a DRM content using kaltura with Fairplay on iOS.
Thanks
Hi Team,
Apple has announced to have privacy manifest file (PrivacyInfo.xcprivacy) for third party SDKs. For more details, please visit:
https://developer.apple.com/support/third-party-SDK-requirements/
Since Playkit Uses XCGLogger framework which internally uses "NSPrivacyAccessedAPICategoryFileTimestamp" APIs which they are planning to fix refering this issue :
https://github.com/DaveWoodCom/XCGLogger/issues/331
So, my query is, Do Playkit-ios team have plan to upgrade their repo, so we can get this change ?
When adding periodic time observers to a Player, depending on the intervals and order that they are added, it can cause a crash.
Then I'm adding two time observers:
This causes an immediate crash on adding the third observer:
2020-12-15 10:47:06.837 [Debug] [PlayerController+TimeMonitor.swift:16] addPeriodicObserver(interval:observeOn:using:) > add periodic observer with interval: 0.2, on queue: Optional(<OS_dispatch_queue_main: com.apple.main-thread[0x103a58c80] = { xref = -2147483648, ref = -2147483648, sref = 1, target = com.apple.root.default-qos.overcommit[0x103a59100], width = 0x1, state = 0x001ffe9000000300, dirty, in-flight = 0, thread = 0x303 }>)
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file PlayKit/TimeObserver.swift, line 171
However, if you reverse that, adding the shorter 0.2s observer before the 0.5s one, it works fine.
The culprit appears to be in addPeriodicObserver(...)
where it tries to find an existing observation to add the incoming block to - it's looking at an item from the periodicObservationsMap
rather than the full list of periodicObservations
.
} else if let periodicObservations = self.periodicObservationsMap[intervalMs] { // we already have this interval
// get the observation with same interval
var periodicObservation = periodicObservations.first(where: { $0.interval == intervalMs })!
From what I understand of the periodicObservationsMap
the keys are for the trigger times rather than the intervals - so the new interval may or may not be in the right place in the map (pseudocode):
a = Observer(100)
addObserver(a)
--- periodicObservations = [a]
--- periodicObservationsMap = [100:[a]]
b = Observer(500)
addObserver(b)
--- looks for periodicObservationsMap[500] – which doesn't exist yet – so it adds the observer to periodicObservations and regenerates the map
--- periodicObservations = [a,b]
--- periodicObservationsMap = [100:[a] , 200:[a], 300:[a], 400:[a], 500:[a,b]]
c = Observer(200)
addObserver(c)
--- looks for periodicObservationsMap[200] – which contains [a]
--- find first in [a] where interval == 200 – but the interval of a is 100 so zero results and crash
EXPECTED:
--- periodicObservationsMap = [100:[a] , 200:[a,c], 300:[a], 400:[a], 500:[a,b]]
Seems it should be looking for these existing observers in self.periodicObservations
rather than self.periodicObservationsMap
Will put a PR in for this shortly.
PlayKit by Kaltura is the only restraint for us to use Swift package manager in our project.
We've been waiting for SPM support for a very long time.
Please provide SPM support.
Currently, Volume is not exposed on the player - have made local repo changes to effect this - happy to submit PR if allowed (or git patch if preferred)
Kaltura Player Plugin's Pod File
PLAYKIT_GIT = 'https://github.com/kaltura/playkit-ios.git'
platform :ios, '9.0'
target 'kaltura_AkamaiMediaAnalytics' do
use_frameworks!
pod 'PlayKit', :git => PLAYKIT_GIT, :branch => "v3.16.1"
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
cflags = config.build_settings['OTHER_CFLAGS'] || ['$(inherited)']
cflags << '-fembed-bitcode'
config.build_settings['OTHER_CFLAGS'] = cflags
config.build_settings['SWIFT_VERSION'] = '5.0'
config.build_settings['BITCODE_GENERATION_MODE'] = 'bitcode'
config.build_settings['ENABLE_BITCODE'] = 'YES'
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end
end
end
Pod file of the sample application
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '9.0' # (define required version)
PLAYKIT_GIT='https://github.com/kaltura/playkit-ios.git'
PLAYKIT_IMA_GIT='https://github.com/kaltura/playkit-ios-ima.git'
PLAYKIT_PROVIDERS_GIT='https://github.com/kaltura/playkit-ios-providers.git'
PLAYKIT_BRANCH=ENV['PK_BRANCH'] || 'master'
target ‘AkamaiSamplePlayer' do
if defined? PLAYKIT_LOCAL
pod "PlayKit", :path => PLAYKIT_LOCAL
pod 'PlayKit_IMA', :path => PLAYKIT_IMA_LOCAL
else
pod 'PlayKit', :git => PLAYKIT_GIT, :branch => "v3.16.1"
pod 'PlayKit_IMA', :git => PLAYKIT_IMA_GIT, :branch => "v1.7.1"
pod 'PlayKitProviders', :git => PLAYKIT_PROVIDERS_GIT, :branch => "v1.5.0"
end
end
pre_install do |installer|
def installer.verify_no_static_framework_transitive_dependencies; end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = 'NO'
if target.name == 'PlayKit'
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
end
end
Kaltura Player Plugin must be loaded.
The sample application crashed
dyld: Symbol not found: _$s7PlayKit13PKPluginErrorO19missingPluginConfigyACSS_tcACmFWC
Referenced from: /Users/viskumar/Library/Developer/CoreSimulator/Devices/550155FE-A389-4E58-8034-93394178BE46/data/Containers/Bundle/Application/342A831D-7DC1-4534-A4DD-2B8E79B72DB1/AkamaiSamplePlayer.app/Frameworks/kaltura_AkamaiMediaAnalytics.framework/kaltura_AkamaiMediaAnalytics
Expected in: /Users/viskumar/Library/Developer/CoreSimulator/Devices/550155FE-A389-4E58-8034-93394178BE46/data/Containers/Bundle/Application/342A831D-7DC1-4534-A4DD-2B8E79B72DB1/AkamaiSamplePlayer.app/Frameworks/PlayKit.framework/PlayKit
in /Users/viskumar/Library/Developer/CoreSimulator/Devices/550155FE-A389-4E58-8034-93394178BE46/data/Containers/Bundle/Application/342A831D-7DC1-4534-A4DD-2B8E79B72DB1/AkamaiSamplePlayer.app/Frameworks/kaltura_AkamaiMediaAnalytics.framework/kaltura_AkamaiMediaAnalytics
default player controls
i am trying to use this player on tvOS and i can not find any default controls(play/pause/..) for the player, is this controls view implemented already or should i implement it from my side ?
Paste the contents of the Xcode console here.
I'm setting bitrate with: player.settings.network.preferredPeakBitRate = prefferedBitRate
and nothing happens ... can you provide example for bitrate in samples ?
In order to trigger the crash it is needed to enable Airplay and play a video content with Airplay while seeking back and forth from the player
Video should seek to the desired position selected (seeking more than 1 time is probably needed as this seems to happen at random)
Player tries to seek to position but crashes
Output in console ->
***** set current time to2: 1228.6467246747
2018-06-05 14:05:17.308375+0200 APPNAME[1165:317788] CMTimeMakeWithSeconds(1228.647 seconds, timescale 1): warning: error of -0.647 introduced due to very low timescale
[2018-06-05 14:05:17.309] AVPlayerEngine.swift:77 DEBUG: set currentPosition: nan
2018-06-05 14:05:17.309992+0200 APPNAME[1165:317788] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVPlayerItem seekToTime:toleranceBefore:toleranceAfter:completionHandler:] Seeking is not possible to time {INVALID}'
*** First throw call stack:
(0x183966d8c 0x182b205ec 0x1893ded54 0x1893c8fb0 0x105bdd1a8 0x105be15c4 0x104703728 0x1046f9330 0x18d7526e8 0x18dcbf3b4 0x18d8b4e38 0x18d751740 0x18dcb0bd4 0x18d74b4d8 0x18d74b010 0x18d74a874 0x18d7491d0 0x18df2ad1c 0x18df2d2c8 0x18df26368 0x18390f404 0x18390ec2c 0x18390c79c 0x18382cda8 0x185811020 0x18d849758 0x104620890 0x1832bdfc0)
libc++abi.dylib: terminating with uncaught exception of type NSException
Output in crash logs ->
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVPlayerItem seekToTime:toleranceBefore:toleranceAfter:completionHandler:] Seeking is not possible to time {INVALID}'
Last Exception Backtrace:
0 CoreFoundation 0x000000018393ed8c __exceptionPreprocess + 228
1 libobjc.A.dylib 0x0000000182af85ec objc_exception_throw + 52
2 AVFoundation 0x00000001893a2fa0 -[AVPlayerItem seekToTime:toleranceBefore:toleranceAfter:completionHandler:] + 1364
3 AVFoundation 0x000000018938d1fc -[AVPlayer seekToTime:toleranceBefore:toleranceAfter:completionHandler:] + 124
4 PlayKit 0x0000000105645338 0x105620000 + 152376
5 PlayKit 0x00000001056496a0 0x105620000 + 169632
6 AppName 0x000000010509c54c 0x104fb4000 + 951628
7 AppName 0x0000000105091c98 0x104fb4000 + 908440
8 UIKit 0x000000018d66e6c8 -[UIApplication sendAction:to:from:forEvent:] + 92
9 UIKit 0x000000018d78f8a4 -[UIControl sendAction:to:forEvent:] + 76
10 UIKit 0x000000018d67477c -[UIControl _sendActionsForEvents:withEvent:] + 436
11 UIKit 0x000000018da3b008 -[UISlider continueTrackingWithTouch:withEvent:] + 416
12 UIKit 0x000000018d850acc -[UIControl touchesMoved:withEvent:] + 140
13 UIKit 0x000000018d6f18c4 -[UIWindow _sendTouchesForEvent:] + 2036
14 UIKit 0x000000018d6e68f8 -[UIWindow sendEvent:] + 3156
15 UIKit 0x000000018d6e5238 -[UIApplication sendEvent:] + 336
16 UIKit 0x000000018dec6c0c __dispatchPreprocessedEventFromEventQueue + 2336
17 UIKit 0x000000018dec91b8 __handleEventQueueInternal + 4740
18 UIKit 0x000000018dec2258 __handleHIDEventFetcherDrain + 148
19 CoreFoundation 0x00000001838e7404 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 20
20 CoreFoundation 0x00000001838e6c2c __CFRunLoopDoSources0 + 272
21 CoreFoundation 0x00000001838e479c __CFRunLoopRun + 1200
22 CoreFoundation 0x0000000183804da8 CFRunLoopRunSpecific + 548
23 GraphicsServices 0x00000001857e7020 GSEventRunModal + 96
24 UIKit 0x000000018d7e578c UIApplicationMain + 232
25 AppName 0x0000000104fba0ac 0x104fb4000 + 24748
26 libdyld.dylib 0x0000000183295fc0 start + 0
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x00000001833c52ec __pthread_kill + 8
1 libsystem_pthread.dylib 0x000000018356a6a8 pthread_kill$VARIANT$armv81 + 356
2 libsystem_c.dylib 0x0000000183333d0c abort + 136
3 HockeySDK 0x0000000105821878 0x1057ac000 + 481400
4 CoreFoundation 0x000000018393f1c8 __handleUncaughtException + 824
5 libobjc.A.dylib 0x0000000182af88c8 _objc_terminate() + 108
6 HockeySDK 0x000000010580b24c 0x1057ac000 + 389708
7 libc++abi.dylib 0x0000000182ae937c std::__terminate(void (*)()) + 12
8 libc++abi.dylib 0x0000000182ae8f78 __cxa_rethrow + 140
9 libobjc.A.dylib 0x0000000182af87ac objc_exception_rethrow + 40
10 CoreFoundation 0x0000000183804e18 CFRunLoopRunSpecific + 660
11 GraphicsServices 0x00000001857e7020 GSEventRunModal + 96
12 UIKit 0x000000018d7e578c UIApplicationMain + 232
13 AppName 0x0000000104fba0ac 0x104fb4000 + 24748
14 libdyld.dylib 0x0000000183295fc0 start + 0
Thread 1:
0 libsystem_kernel.dylib 0x00000001833a3e08 mach_msg_trap + 8
1 CoreFoundation 0x00000001838e6e40 __CFRunLoopServiceMachPort + 192
2 CoreFoundation 0x00000001838e4908 __CFRunLoopRun + 1564
3 CoreFoundation 0x0000000183804da8 CFRunLoopRunSpecific + 548
4 Foundation 0x0000000184279674 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 300
5 Foundation 0x000000018427951c -[NSRunLoop(NSRunLoop) runUntilDate:] + 144
6 UIKit 0x000000018d4ca7e4 -[UIEventFetcher threadMain] + 132
7 Foundation 0x0000000184389efc __NSThread__start__ + 1036
8 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
9 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
10 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 2:
0 libsystem_kernel.dylib 0x00000001833a3e08 mach_msg_trap + 8
1 CoreFoundation 0x00000001838e6e40 __CFRunLoopServiceMachPort + 192
2 CoreFoundation 0x00000001838e4908 __CFRunLoopRun + 1564
3 CoreFoundation 0x0000000183804da8 CFRunLoopRunSpecific + 548
4 CFNetwork 0x00000001841124b0 -[__CoreSchedulingSetRunnable runForever] + 216
5 Foundation 0x0000000184389efc __NSThread__start__ + 1036
6 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
7 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
8 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 3:
0 libsystem_kernel.dylib 0x00000001833a3e08 mach_msg_trap + 8
1 CoreFoundation 0x00000001838e6e40 __CFRunLoopServiceMachPort + 192
2 CoreFoundation 0x00000001838e4908 __CFRunLoopRun + 1564
3 CoreFoundation 0x0000000183804da8 CFRunLoopRunSpecific + 548
4 AVFAudio 0x00000001892ea424 GenericRunLoopThread::Entry(void*) + 160
5 AVFAudio 0x0000000189314834 CAPThread::Entry(CAPThread*) + 84
6 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
7 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
8 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 4:
0 libsystem_kernel.dylib 0x00000001833c5538 __select + 8
1 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
2 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
3 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 5:
0 libsystem_pthread.dylib 0x0000000183563b04 start_wqthread + 0
Thread 6:
0 libsystem_kernel.dylib 0x00000001833c5d84 __workq_kernreturn + 8
1 libsystem_pthread.dylib 0x0000000183563b08 start_wqthread + 0
Thread 7:
0 libsystem_kernel.dylib 0x00000001833c50f4 __psynch_cvwait + 8
1 libc++.1.dylib 0x0000000182a7c25c std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 20
2 JavaScriptCore 0x000000018af5b1a4 void std::__1::condition_variable_any::wait<std::__1::unique_lock<bmalloc::Mutex> >(std::__1::unique_lock<bmalloc::Mutex>&) + 100
3 JavaScriptCore 0x000000018af5adb8 bmalloc::Scavenger::threadRunLoop() + 160
4 JavaScriptCore 0x000000018af5ab60 bmalloc::Scavenger::threadEntryPoint(bmalloc::Scavenger*) + 8
5 JavaScriptCore 0x000000018af5af7c void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (*)(bmalloc::Scavenger*), bmalloc::Scavenger*> >(void*) + 40
6 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
7 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
8 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 8:
0 libsystem_kernel.dylib 0x00000001833a3e08 mach_msg_trap + 8
1 CoreFoundation 0x00000001838e6e40 __CFRunLoopServiceMachPort + 192
2 CoreFoundation 0x00000001838e4908 __CFRunLoopRun + 1564
3 CoreFoundation 0x0000000183804da8 CFRunLoopRunSpecific + 548
4 WebCore 0x000000018ba91d9c RunWebThread(void*) + 588
5 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
6 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
7 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 9:
0 libsystem_kernel.dylib 0x00000001833a3e5c semaphore_timedwait_trap + 8
1 libdispatch.dylib 0x0000000183262a00 _dispatch_semaphore_wait_slow + 68
2 libdispatch.dylib 0x00000001832737e4 _dispatch_worker_thread + 244
3 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
4 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
5 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 10:
0 libsystem_kernel.dylib 0x00000001833a3e5c semaphore_timedwait_trap + 8
1 libdispatch.dylib 0x0000000183262a00 _dispatch_semaphore_wait_slow + 68
2 libdispatch.dylib 0x00000001832737e4 _dispatch_worker_thread + 244
3 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
4 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
5 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 11:
0 libsystem_kernel.dylib 0x00000001833a3e5c semaphore_timedwait_trap + 8
1 libdispatch.dylib 0x0000000183262a00 _dispatch_semaphore_wait_slow + 68
2 libdispatch.dylib 0x00000001832737e4 _dispatch_worker_thread + 244
3 libsystem_pthread.dylib 0x0000000183565220 _pthread_body + 268
4 libsystem_pthread.dylib 0x0000000183565110 _pthread_start + 288
5 libsystem_pthread.dylib 0x0000000183563b10 thread_start + 0
Thread 0 crashed with ARM-64 Thread State:
pc: 0x00000001833c52ec fp: 0x000000016ae4b2b0 sp: 0x000000016ae4b280 x0: 0x0000000000000000
x1: 0x0000000000000000 x2: 0x0000000000000000 x3: 0xffffffffffffffff x4: 0x0000000000000010
x5: 0x0000000000000a1d x6: 0x00000001c81a32c0 x7: 0x0000000000000a1e x8: 0x0000000008000000
x9: 0x0000000004000000 x10: 0x0000000183566110 x11: 0x00000001b80b5f04 x12: 0x00000001b80b5f04
x13: 0x0000000000000018 x14: 0x0000000000000001 x15: 0x0000000000000881 x16: 0x0000000000000148
x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000000000006 x20: 0x00000001b5d00b40
x21: 0x00000001ae253098 x22: 0x0000000000000303 x23: 0x00000001b5d00c20 x24: 0x000000010ae2b2e0
x25: 0x00000001b5d0e000 x26: 0x00000001b440a000 x27: 0x00000001cc10ccc0 x28: 0x00000001839d539f
lr: 0x000000018356a6a8 cpsr: 0x0000000000000000
Note that ***** set current time to2: 1228.6467246747
is printed before calling player.seek(to: player.duration * Double(slider.value))
additionally tried replacing the above call to player.currentTime = player.duration * Double(slider.value)
but crash still occurred
playKit.player?.addObserver(self, event: PlayerEvent.tracksAvailable) { [weak self] event in
dump(event.tracks)
}
Receiving videoTracks details as playkit-android does
Only textTracks and audioTracks will be returned
▿ Optional(<PlayKit.PKTracks: 0x6000002cb380>)
▿ some: <PlayKit.PKTracks: 0x6000002cb380> #0
- super: NSObject
▿ audioTracks: Optional([<PlayKit.Track: 0x6000017baa80>])
▿ some: 1 element
▿ <PlayKit.Track: 0x6000017baa80> #1
- super: NSObject
- id: "AVMediaType(_rawValue: soun):0"
- title: "Unknown"
- language: nil
- type: PlayKit.TrackType.audio
▿ textTracks: Optional([<PlayKit.Track: 0x6000017ba6c0>, <PlayKit.Track: 0x6000017ba780>])
▿ some: 2 elements
▿ <PlayKit.Track: 0x6000017ba6c0> #2
- super: NSObject
- id: "sbtl:-1"
- title: "Off"
- language: nil
- type: PlayKit.TrackType.text
▿ <PlayKit.Track: 0x6000017ba780> #3
- super: NSObject
- id: "sbtl:0"
- title: "English"
▿ language: Optional("en")
- some: "en"
- type: PlayKit.TrackType.text
Is there a way to know the width and height size of the current video track without having the videoTracks from PlayerEvent.tracksAvailable?
Is it possible to implement the same behaviour of Android's PlayerEvent.tracksAvailable observer/listener?
Thanks
I created a sample project with PlayKit
as a dependency. When I try to run the xcworkspace after pod install
I get compile errors in PlayKit
.
I'm using the latest release 3.16.1 with Xcode 11.3.1 (11C504) for iOS 13.
I can use PlayKit as a dependency on an iOS 13 project with Xcode 11.3.1 and Swift 5.1.
PlayKit does not compile as a dependency on an iOS 13 project with Xcode 11.3.1 and Swift 5.1.
Steps:
Basically, when trying to create multiple players by destroying older players, the app is crashing.
This issue was not happening till v3.14.0
iOS version: 10 and 11(till 11.2)
Playkit version: v3.16.0
I am getting the below crash log:
2020-01-02 08:21:56.162 [Debug] [AVPlayerEngine.swift:276] play() > Play player
2020-01-02 08:21:56.163 [Debug] [AVPlayerEngine.swift:244] deinit > AVPlayerEngine, was deinitialized
2020-01-02 13:51:56.170 CompanyName[25724:171183] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x60000024b820 of class PlayKit.PKAsset was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x600000432040> (
<NSKeyValueObservance 0x600000445520: Observer: 0x60000044b9a0, Key path: status, Options: <New: NO, Old: NO, Prior: NO> Context: 0x0, Property: 0x60000044c840>
)'
*** First throw call stack:
(
0 CoreFoundation 0x000000011ca0eb0b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x000000011bd04141 objc_exception_throw + 48
2 CoreFoundation 0x000000011ca77625 +[NSException raise:format:] + 197
3 Foundation 0x0000000111eecb53 NSKVODeallocate + 294
4 libobjc.A.dylib 0x000000011bd18b8e _ZN11objc_object17sidetable_releaseEb + 202
5 PlayKit 0x00000001141820a1 $s7PlayKit7PKAssetCSgWOh + 17
6 libobjc.A.dylib 0x000000011bd029bc _ZL27object_cxxDestructFromClassP11objc_objectP10objc_class + 127
7 libobjc.A.dylib 0x000000011bd0ed34 objc_destructInstance + 129
8 libobjc.A.dylib 0x000000011bd0ed66 object_dispose + 22
9 AVFoundation 0x000000011c221a2f -[AVPlayer dealloc] + 1171
10 PlayKit 0x0000000114195d79 $s7PlayKit14AVPlayerEngineCfD + 313
11 PlayKit 0x0000000114195f6b $s7PlayKit14AVPlayerEngineCfDTo + 43
12 Foundation 0x0000000111eeca8d NSKVODeallocate + 96
13 libobjc.A.dylib 0x000000011bd18b8e _ZN11objc_object17sidetable_releaseEb + 202
14 libobjc.A.dylib 0x000000011bd192fa _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 866
15 CoreFoundation 0x000000011c95de96 _CFAutoreleasePoolPop + 22
16 CoreFoundation 0x000000011c999aec __CFRunLoopRun + 2172
17 CoreFoundation 0x000000011c999016 CFRunLoopRunSpecific + 406
18 GraphicsServices 0x000000011fc95a24 GSEventRunModal + 62
19 UIKit 0x0000000117260134 UIApplicationMain + 159
20 ComapanyName 0x000000010baff092 main + 306
21 libdyld.dylib 0x000000011df9f65d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
Steps to reproduce:
In our app we have a simple Kaltura Playkit player with a pause/play button, a slider and a MPVolumeView
to airplay when available.
Result: The pause, seeking and seeked events are never emitted. When the player is paused on the Apple TV, the controllers on the device (iPhone) still look as if it is playing because it's not on paused state.
Expected result: Pause, play, seeking and seeked events are emitted even when interacting with the Apple TV remote controller in airplay mode. The controllers in the device always match the state in the Apple TV
import UIKit
import PlayKit
import MUXSDKKaltura
import MuxCore
import MediaPlayer
class PlayerViewController: UIViewController {
var kalturaPlayer: Player?
let kalturaPlayerContainer = PlayerView()
let playButton = UIButton()
let closeButton = UIButton()
let playheadSlider = UISlider()
let positionLabel = UILabel()
let durationLabel = UILabel()
let airplayButton = MPVolumeView(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
// MUX
let playerName = "iOS KalturaPlayer"
private var playerState: PlayerState = .idle {
didSet {
// Update player button icon depending on the state
switch playerState {
case .idle:
self.playButton.setImage(UIImage(systemName: "play"), for: .normal)
case .playing:
self.playButton.setImage(UIImage(systemName: "pause"), for: .normal)
case .paused:
self.playButton.setImage(UIImage(systemName: "play"), for: .normal)
case .ended:
self.playButton.setImage(UIImage(systemName: "arrow.clockwise"), for: .normal)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.setupLayout()
// Load PlayKit player
self.kalturaPlayer = PlayKitManager.shared.loadPlayer(pluginConfig: nil)
self.setupKalturaPlayer()
// Setup MUX
self.setupMUX()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
MUXSDKStats.destroyPlayer(name: self.playerName)
self.kalturaPlayer?.destroy()
}
func setupKalturaPlayer() {
// Set PlayerView as the container for PlayKit Player variable
self.kalturaPlayer?.view = self.kalturaPlayerContainer
self.loadMediaKalturaPlayer()
// Handle PlayKit events
self.playerState = .idle
let events = [
PlayerEvent.pause,
PlayerEvent.playing,
PlayerEvent.ended,
PlayerEvent.durationChanged
]
// Update player state depending on the Playkit events
self.kalturaPlayer?.addObserver(self, events: events) { [weak self] (event) in
guard let self = self else { return }
switch event {
case is PlayerEvent.Playing:
self.playerState = .playing
case is PlayerEvent.Pause:
self.playerState = .paused
case is PlayerEvent.Ended:
self.playerState = .ended
// Test video change
self.changeMediaKalturaPlayer()
case is PlayerEvent.DurationChanged:
// Observe PlayKit event durationChanged to update the maximum duration of the slider and duration label
guard let duration = event.duration as? TimeInterval else {
return
}
self.playheadSlider.maximumValue = Float(duration)
self.durationLabel.text = duration.formattedTimeDisplay
default:
break
}
}
// Checks media progress to update the player slider and the current position label
_ = self.kalturaPlayer?.addPeriodicObserver(
interval: 0.2,
observeOn: DispatchQueue.main,
using: { [weak self] currentPosition in
self?.playheadSlider.value = Float(currentPosition)
self?.positionLabel.text = currentPosition.formattedTimeDisplay
}
)
}
func loadMediaKalturaPlayer() {
let mediaConfig = createKalturaMediaConfig(
contentURL: "https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8",
entryId: "sintel"
)
// Prepare PlayKit player
self.kalturaPlayer?.prepare(mediaConfig)
}
func changeMediaKalturaPlayer() {
let mediaConfig = createKalturaMediaConfig(
contentURL: "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8",
entryId: "bipbop_16x9"
)
// Call MUX videoChange before stop, because playkit stop will replace current item for nil
self.MUXVideoChange()
// Resets The Player And Prepares for Change Media
self.kalturaPlayer?.stop()
// Prepare PlayKit player
self.kalturaPlayer?.prepare(mediaConfig)
// Wait for `canPlay` event to play
self.kalturaPlayer?.addObserver(self, events: [PlayerEvent.canPlay]) { event in
self.kalturaPlayer?.play()
}
}
func createKalturaMediaConfig(contentURL: String, entryId: String) -> MediaConfig {
// Create PlayKit media source
let source = PKMediaSource(entryId, contentUrl: URL(string: contentURL), drmData: nil, mediaFormat: .hls)
// Setup PlayKit media entry
let mediaEntry = PKMediaEntry(entryId, sources: [source])
// Create PlayKit media config
return MediaConfig(mediaEntry: mediaEntry)
}
func setupMUX() {
let playerData = MUXSDKCustomerPlayerData(environmentKey: "YOUR_ENV_KEY_HERE")
playerData?.playerName = self.playerName
let videoData = MUXSDKCustomerVideoData()
videoData.videoTitle = "Title Video Kaltura"
videoData.videoId = "sintel"
videoData.videoSeries = "animation"
let viewData = MUXSDKCustomerViewData()
viewData.viewSessionId = "my session id"
let customData = MUXSDKCustomData()
customData.customData1 = "Kaltura test"
customData.customData2 = "Custom Data 2"
let viewerData = MUXSDKCustomerViewerData()
viewerData.viewerApplicationName = "MUX Kaltura DemoApp"
let customerData = MUXSDKCustomerData(
customerPlayerData: playerData,
videoData: videoData,
viewData: viewData,
customData: customData,
viewerData: viewerData
)
guard let player = self.kalturaPlayer, let data = customerData else {
return
}
MUXSDKStats.monitorPlayer(
player: player,
playerName: self.playerName,
customerData: data
)
}
func MUXVideoChange() {
let playerData = MUXSDKCustomerPlayerData(environmentKey: "shqcbkagevf0r4jh9joir48kp")
playerData?.playerName = self.playerName
let videoData = MUXSDKCustomerVideoData()
videoData.videoTitle = "Apple Video Kaltura"
videoData.videoId = "apple"
videoData.videoSeries = "conference"
let viewData = MUXSDKCustomerViewData()
viewData.viewSessionId = "my second session id"
let customData = MUXSDKCustomData()
customData.customData1 = "Kaltura test video change"
let viewerData = MUXSDKCustomerViewerData()
viewerData.viewerApplicationName = "MUX Kaltura DemoApp"
guard let customerData = MUXSDKCustomerData(
customerPlayerData: playerData,
videoData: videoData,
viewData: viewData,
customData: customData,
viewerData: viewerData
) else {
return
}
MUXSDKStats.videoChangeForPlayer(name: self.playerName, customerData: customerData)
}
@objc func playButtonPressed() {
guard let player = self.kalturaPlayer else {
return
}
// Handle PlayKit events
switch playerState {
case .playing:
player.pause()
case .idle:
player.play()
case .paused:
player.play()
case .ended:
player.seek(to: 0)
player.play()
}
}
@objc func closeButtonPressed() {
self.navigationController?.popToRootViewController(animated: true)
}
@objc func playheadValueChanged() {
guard let player = self.kalturaPlayer else {
return
}
if self.playerState == .ended && self.playheadSlider.value < self.playheadSlider.maximumValue {
self.playerState = .paused
}
player.currentTime = TimeInterval(self.playheadSlider.value)
}
}
extension PlayerViewController {
enum PlayerState {
case idle
case playing
case paused
case ended
}
}
extension PlayerViewController {
func setupLayout() {
self.view.backgroundColor = .black
self.view.addSubview(self.kalturaPlayerContainer)
// Constraint PlayKit player container to safe area layout guide
self.kalturaPlayerContainer.translatesAutoresizingMaskIntoConstraints = false
let guide = self.view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
self.kalturaPlayerContainer.topAnchor.constraint(equalTo: guide.topAnchor),
self.kalturaPlayerContainer.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
self.kalturaPlayerContainer.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
self.kalturaPlayerContainer.trailingAnchor.constraint(equalTo: guide.trailingAnchor)
])
let actionsContainer = UIStackView()
actionsContainer.axis = .vertical
actionsContainer.isLayoutMarginsRelativeArrangement = true
actionsContainer.layoutMargins = UIEdgeInsets(top: 0, left: 8.0, bottom: 0, right: 8.0)
actionsContainer.translatesAutoresizingMaskIntoConstraints = false
self.kalturaPlayerContainer.addSubview(actionsContainer)
NSLayoutConstraint.activate([
actionsContainer.bottomAnchor.constraint(equalTo: self.kalturaPlayerContainer.bottomAnchor),
actionsContainer.leadingAnchor.constraint(equalTo: self.kalturaPlayerContainer.leadingAnchor),
actionsContainer.trailingAnchor.constraint(equalTo: self.kalturaPlayerContainer.trailingAnchor)
])
// Add airplay button
self.airplayButton.showsVolumeSlider = false
NSLayoutConstraint.activate([
self.airplayButton.widthAnchor.constraint(equalToConstant: 44.0),
self.airplayButton.heightAnchor.constraint(equalToConstant: 44.0)
])
let airplayRowStack = UIStackView()
airplayRowStack.axis = .horizontal
airplayRowStack.addArrangedSubview(UIView())
airplayRowStack.addArrangedSubview(airplayButton)
actionsContainer.addArrangedSubview(airplayRowStack)
let actionsRowStack = UIStackView()
actionsRowStack.axis = .horizontal
actionsRowStack.spacing = 6.0
actionsContainer.addArrangedSubview(actionsRowStack)
NSLayoutConstraint.activate([
actionsRowStack.heightAnchor.constraint(equalToConstant: 44.0)
])
// Add play/pause button
self.playButton.addTarget(self, action: #selector(self.playButtonPressed), for: .touchUpInside)
self.playButton.contentEdgeInsets = UIEdgeInsets(top: 10, left: 4, bottom: 10, right: 4)
self.playButton.contentHorizontalAlignment = .fill
self.playButton.contentVerticalAlignment = .fill
actionsRowStack.addArrangedSubview(self.playButton)
NSLayoutConstraint.activate([
self.playButton.widthAnchor.constraint(equalToConstant: 28.0)
])
self.positionLabel.textColor = .lightText
self.positionLabel.text = TimeInterval.zero.formattedTimeDisplay
actionsRowStack.addArrangedSubview(self.positionLabel)
self.playheadSlider.addTarget(self, action: #selector(self.playheadValueChanged), for: .valueChanged)
actionsRowStack.addArrangedSubview(self.playheadSlider)
self.durationLabel.textColor = .lightText
self.durationLabel.text = TimeInterval.zero.formattedTimeDisplay
actionsRowStack.addArrangedSubview(self.durationLabel)
// Add close button
self.closeButton.translatesAutoresizingMaskIntoConstraints = false
self.closeButton.addTarget(self, action: #selector(self.closeButtonPressed), for: .touchUpInside)
self.closeButton.setImage(UIImage(systemName: "xmark.square"), for: .normal)
self.closeButton.contentVerticalAlignment = .fill
self.closeButton.contentHorizontalAlignment = .fill
self.kalturaPlayerContainer.addSubview(self.closeButton)
NSLayoutConstraint.activate([
self.closeButton.heightAnchor.constraint(equalToConstant: 32.0),
self.closeButton.widthAnchor.constraint(equalToConstant: 32.0),
self.closeButton.trailingAnchor.constraint(equalTo: self.kalturaPlayerContainer.trailingAnchor, constant: -24.0),
self.closeButton.topAnchor.constraint(equalTo: self.kalturaPlayerContainer.topAnchor, constant: 24.0)
])
}
}
It's a simple kaltura playkit player with the button to airplay. I reproduce in airplay mode, when I pause or seek with the apple tv remote, I get kaltura PlayEvents for Pause, Seeking and Seeked. The UI in the device is in sync with the apple tv player, for example:if it is pause it shows the play button and viceversa.
I reproduce in airplay mode, when I pause or seek with the apple tv remote, I don't get any of the following kaltura PlayEvents: Pause, Seeking and Seeked. The UI in the device is not in sync with the apple tv player, for example: if it is paused in apple tv it still shows the pause button on the device, even though it should be showing the play button instead.
2021-11-05 2:06:04.139 PM [Debug] [DefaultAssetHandler.swift:88] build(from:readyCallback:) > Creating clear AVURLAsset
2021-11-05 2:06:04.178 PM [Debug] [AVPlayerEngine.swift:147] startPosition > set startPosition: nan
2021-11-05 2:06:04.179 PM [Debug] [AVPlayerEngine.swift:76] asset > The asset status changed to: preparing
2021-11-05 2:06:04.179 PM [Debug] [NetworkUtils.swift:57] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Sending Kava Event type: 1
2021-11-05 2:06:04.180 PM [Debug] [NetworkUtils.swift:57] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Sending Kava Event type: 2
2021-11-05 2:06:04.181 PM [Debug] [PlayerController+TimeMonitor.swift:16] addPeriodicObserver(interval:observeOn:using:) > add periodic observer with interval: 0.2, on queue: Optional(<OS_dispatch_queue_main: com.apple.main-thread[0x105668c80] = { xref = -2147483648, ref = -2147483648, sref = 1, target = com.apple.root.default-qos.overcommit[0x105669100], width = 0x1, state = 0x001ffe9000000300, dirty, in-flight = 0, thread = 0x303 }>)
2021-11-05 2:06:04.181 PM [Debug] [PlayerController+TimeMonitor.swift:18] addPeriodicObserver(interval:observeOn:using:) > periodic observer added with token: 6503F1FF-68E4-4E8C-9011-DAD6B36BDE6E
2021-11-05 2:06:04.184 PM [Debug] [PlayerController+TimeMonitor.swift:16] addPeriodicObserver(interval:observeOn:using:) > add periodic observer with interval: 0.1, on queue: nil
2021-11-05 2:06:04.184 PM [Debug] [PlayerController+TimeMonitor.swift:18] addPeriodicObserver(interval:observeOn:using:) > periodic observer added with token: 1AE02AF5-F7F5-484C-A19A-1A94BF991B47
2021-11-05 2:06:04.287 PM [Debug] [AVPlayerEngine.swift:76] asset > The asset status changed to: prepared
2021-11-05 2:06:04.288 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:06:04.288 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Idle old:Idle
2021-11-05 2:06:04.288 PM [Error] [AVPlayerEngine+Observation.swift:176] observeValue(forKeyPath:of:change:context:) > unknown player item status
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 888.0
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Buffering old:Idle
2021-11-05 2:06:04.289 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Idle old:Buffering
2021-11-05 2:06:04.303 PM [Debug] [AVPlayerEngine+Observation.swift:236] handle(status:) > player is ready to play player items
2021-11-05 2:06:04.303 PM [Debug] [AVPlayerEngine+Observation.swift:239] handle(status:) > duration in seconds: 888.0
2021-11-05 2:06:04.402 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:06:04.430 PM [Debug] [AVPlayerEngine+Observation.swift:75] onAccessLogEntryNotification(notification:) > event log:
event log: averageAudioBitrate - 378256.0
event log: averageVideoBitrate - 0.0
event log: indicatedAverageBitrate - -1.0
event log: indicatedBitrate - 6214307.0
event log: observedBitrate - nan
event log: observedMaxBitrate - 0.0
event log: observedMinBitrate - -1.0
event log: switchBitrate - -1.0
event log: numberOfBytesTransferred - 94564
event log: numberOfStalls - 0
event log: URI - 'https://bitdash-a.akamaihd.net/content/sintel/hls/video/6000kbit.m3u8'
event log: startupTime - -1.0
2021-11-05 2:06:04.543 PM [Warning] [AVPlayerEngine+Observation.swift:91] onErrorLogEntryNotification(notification:) > error description: Optional("Segment exceeds specified bandwidth for variant"), error domain: CoreMediaErrorDomain, error code: -12318
2021-11-05 2:06:04.555 PM [Debug] [AVPlayerEngine+Observation.swift:365] handleDurationChanged() > Duration in seconds: 888.0
2021-11-05 2:06:04.556 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Idle
2021-11-05 2:06:04.562 PM [Debug] [TracksManager.swift:38] handleTracks(item:cea608CaptionsEnabled:block:) > audio tracks:: Optional([<PlayKit.Track: 0x28057a540>, <PlayKit.Track: 0x28057a600>]), text tracks:: Optional([<PlayKit.Track: 0x28057aa80>, <PlayKit.Track: 0x28057a7c0>, <PlayKit.Track: 0x28057a840>, <PlayKit.Track: 0x28057a900>, <PlayKit.Track: 0x28057aa00>])
2021-11-05 2:06:04.562 PM [Debug] [AVPlayerEngine+Observation.swift:274] handle(playerItemStatus:) > duration in seconds: 888.0
2021-11-05 2:06:04.562 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Ready
2021-11-05 2:06:04.954 PM [Debug] [NetworkUtils.swift:55] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Response:
Status Code: 0
Error:
Data: {
time = "1636142765.009";
viewEventsEnabled = 1;
}
2021-11-05 2:06:05.371 PM [Debug] [NetworkUtils.swift:55] sendKavaAnalytics(forPartnerId:entryId:eventType:sessionId:) > Response:
Status Code: 0
Error:
Data: {
time = "1636142765.427";
viewEventsEnabled = 1;
}
2021-11-05 2:06:07.092 PM [Debug] [AVPlayerEngine.swift:294] play() > Play player
2021-11-05 2:06:07.092 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 1.0
2021-11-05 2:06:08.000 PM [Debug] [AVPlayerEngine+Observation.swift:75] onAccessLogEntryNotification(notification:) > event log:
event log: averageAudioBitrate - 0.0
event log: averageVideoBitrate - 41360.0
event log: indicatedAverageBitrate - -1.0
event log: indicatedBitrate - 1558322.0
event log: observedBitrate - 32336999.91437678
event log: observedMaxBitrate - 94714957.2420789
event log: observedMinBitrate - 2296042.501051438
event log: switchBitrate - -1.0
event log: numberOfBytesTransferred - 10340
event log: numberOfStalls - 0
event log: URI - 'https://bitdash-a.akamaihd.net/content/sintel/hls/video/1500kbit.m3u8'
event log: startupTime - 0.0
MUXSDK-INFO - Switch advertised bitrate from: 6214307.0 to: 1558322.0
2021-11-05 2:06:08.018 PM [Warning] [AVPlayerEngine+Observation.swift:91] onErrorLogEntryNotification(notification:) > error description: Optional("Segment exceeds specified bandwidth for variant"), error domain: CoreMediaErrorDomain, error code: -12318
2021-11-05 2:06:11.296 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Ready
2021-11-05 2:06:24.329 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:06:33.309 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:03.311 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:05.396 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:07.314 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:09.319 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:11.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:13.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:17.036 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:07:17.312 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:07:34.309 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Buffering old:Ready
2021-11-05 2:07:34.646 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 8.0
2021-11-05 2:07:35.607 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 24.0
2021-11-05 2:07:40.318 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
2021-11-05 2:07:42.236 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 1.0
2021-11-05 2:07:42.236 PM [Debug] [AVPlayerEngine.swift:387] postStateChange(newState:oldState:) > stateChanged:: new:Ready old:Buffering
2021-11-05 2:07:55.237 PM [Debug] [AVPlayerEngine+Observation.swift:157] observeValue(forKeyPath:of:change:context:) > Buffer Full
2021-11-05 2:08:01.814 PM [Debug] [AVPlayerEngine+Observation.swift:224] handleRate() > player rate was changed, now: 0.0
I'm getting memory leak on Kaltura live ( it may exist on offline too you can see leaks on EventsRegistration example this is stack trace log:
` 0 libsystem_malloc.dylib malloc_zone_malloc
--- 18 frames omitted ---
19 libswiftCore.dylib String.init<A>(stringInterpolationSegment:)
20 PlayKit closure #1 in MessageBus.post(_:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/MessageBus.swift:66
21 PlayKit partial apply for closure #1 in MessageBus.post(_:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/MessageBus.swift:0
22 PlayKit thunk for @callee_guaranteed () -> () /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/MessageBus.swift:0
23 libdispatch.dylib _dispatch_client_callout
24 libdispatch.dylib _dispatch_queue_barrier_sync_invoke_and_complete
25 PlayKit MessageBus.post(_:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/MessageBus.swift:64
26 PlayKit closure #1 in PlayerLoader.load(pluginConfig:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/PlayerLoader.swift:33
27 PlayKit partial apply for closure #1 in PlayerLoader.load(pluginConfig:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/PlayerLoader.swift:0
28 PlayKit closure #1 in PlayerController.init() /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/PlayerController.swift:119
29 PlayKit partial apply for closure #1 in PlayerController.init() /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/PlayerController.swift:0
--- 15 frames omitted ---
45 PlayKit @objc AVPlayerEngine.observeValue(forKeyPath:of:change:context:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/AVPlayerEngine/AVPlayerEngine+Observation.swift:0
46 Foundation NSKeyValueNotifyObserver
--- 4 frames omitted ---
51 AVFoundation -[AVPlayer replaceCurrentItemWithPlayerItem:]
52 PlayKit AVPlayerEngine.replaceCurrentItem(with:) /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/AVPlayerEngine/AVPlayerEngine+AssetLoading.swift:22
--- 3 frames omitted ---
56 PlayKit _T0Ieg_IeyB_TR /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/Pods/PlayKit/Classes/Player/AVPlayerEngine/AVPlayerEngine+AssetLoading.swift:0
57 libdispatch.dylib _dispatch_call_block_and_release
--- 6 frames omitted ---
64 UIKit UIApplicationMain
65 EventsRegistration-Swift main /Users/mohammadmac/Downloads/playkit-ios-samples-master 2/EventsRegistration/EventsRegistration-Swift/AppDelegate.swift:12
66 libdyld.dylib start
`
Paste test code here
What you expected to happen
What actually happened
Paste the contents of the Xcode console here.
How to get different resolutions of video by using entityId?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.