PlayKit: Kaltura Player SDK for iOS

Overview

Swift 3.0+ Codacy Badge CI Status Version License Platform

Kaltura Player SDK

Demo: Demo repo.

If you are a Kaltura customer, please contact your Kaltura Customer Success Manager to help facilitate use of this component.

Overview

The Kaltura Player SDK is fully native and introduces significant performance improvements. The SDK is intended to be integrated in any iOS application and includes the following features:

  • Online and Offline Playback
  • Live
  • Multi audio tracks
  • Multiple captions
  • Kaltura’s uDRM support (FairPlay, Widevine Classic)
  • VAST Support (IMA)
  • Kaltura analytics
  • Youbora
  • Chromecast and AirPlay support

Usage Guides

Please see our VPaaS Documentation site.

License and Copyright Information

All code in this project is released under the AGPLv3 license unless a different license for a particular library is specified in the applicable library path.

Copyright © Kaltura Inc. All rights reserved.
Authors and contributors: See GitHub contributors list.

Comments
  • Exposed uri in PKPlaybackInfo

    Exposed uri in PKPlaybackInfo

    Description of the Changes

    This is an enhancement to add playback item URI to the standard PlayKit Playback Info.

    CheckLists

    • [x] changes have been done against master branch, and PR does not conflict
    • [x] new unit / functional tests have been added (whenever applicable)
    • [x] test are passing in local environment
    • [x] Travis tests are passing (or test results are not worse than on master branch :))
    • [x] Docs have been updated
    opened by naveen-c 16
  • Making player optional and cleaning up player instance

    Making player optional and cleaning up player instance

    Intermittently the player instance doesn't clean up and leads to error loading subsequent videos. Setting the current item to nil in destroy() function of AVPlayerEngine.swift fixes this issue.

    The app crashes as IMA plugin is trying to access the removed player when the player instance is removed as the ad is loading. So, the player should be made optional.

    bug 
    opened by SachinAhujaGit 13
  • Seeking while session is connected to Airplay crashes the SDK and the app

    Seeking while session is connected to Airplay crashes the SDK and the app

    Prerequisites
    • [x] Which Player version are you using: issue first encountered on version 3.3.5 and after updating to 3.4.1 issue still persists
    • [x] Can you reproduce the issue with our latest release version: Can be reproduced with 3.4.1 (latest version at the current time)
    • [x] Can you reproduce the issue with the latest code from master: Issue can be reproduce with code from master
    • [x] What devices and OS versions are you using:
      • iPhone X running iOS 11.3.4
      • iPhone X running iOS 11.4
      • iPhone 6S running iOS 10.3.1
      • iPhone 8 Plus
      • iPhone 7 running iOS 11

    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

    Expected behavior

    Video should seek to the desired position selected (seeking more than 1 time is probably needed as this seems to happen at random)

    Actual behavior

    Player tries to seek to position but crashes

    Console output

    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

    opened by kjoneandrei 10
  • expose public player

    expose public player

    Description of the Changes

    Expose the player as public in PlayerView.swift, keeping as internal doesn't allow to use it.

    CheckLists

    • [ ] changes have been done against master branch, and PR does not conflict
    • [ ] new unit / functional tests have been added (whenever applicable)
    • [ ] test are passing in local environment
    • [ ] Travis tests are passing (or test results are not worse than on master branch :))
    • [ ] Docs have been updated
    opened by matteocrippa 8
  • Fem 1728 separate repos

    Fem 1728 separate repos

    Description of the Changes

    moving google cast addon, youbora plugin and ott classes to separated repos

    CheckLists

    • [x] changes have been done against master branch, and PR does not conflict
    • [x] new unit / functional tests have been added (whenever applicable)
    • [x] test are passing in local environment
    • [x] Travis tests are passing (or test results are not worse than on master branch :))
    • [ ] Docs have been updated
    opened by vadimkononov 5
  • Swift 4

    Swift 4

    Description of the Changes

    Updated to support Swift 4 and Xcode 9.

    Did not update pod version - i'll leave this to the Kaltura team

    CheckLists

    • [X] changes have been done against master branch, and PR does not conflict
    • [NA] new unit / functional tests have been added (whenever applicable)
    • [X] test are passing in local environment
    • [ ] Travis tests are passing (or test results are not worse than on master branch :))
    • [NA] Docs have been updated
    enhancement 
    opened by pdupris 5
  • getting memory leak on Kaltura

    getting memory leak on Kaltura

    Prerequisites
    • [x] Which Player version are you using: It exist on version 3.5 as it was in 3.4
    • [x] Can you reproduce the issue with our latest release version: yes
    • [x] Can you reproduce the issue with the latest code from master:yes
    • [x] What devices and OS versions are you using: iOS 11.4
    • [x] If applicable, add test code or test page to reproduce:

    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
    `
    
    opened by mohammadZ74 4
  • FEM-1688: playkit swift 4 support

    FEM-1688: playkit swift 4 support

    Description of the Changes

    Please add a detailed description of the change, weather it's an enhancement or a bugfix. If the PR is related to an open issue please link to it.

    CheckLists

    • [x] changes have been done against master branch, and PR does not conflict
    • [ ] new unit / functional tests have been added (whenever applicable)
    • [x] test are passing in local environment
    • [x] Travis tests are passing (or test results are not worse than on master branch :))
    • [ ] Docs have been updated
    enhancement 
    opened by vadimkononov 4
  • Crash while loading Kaltura Player Plugin

    Crash while loading Kaltura Player Plugin

    Prerequisites
    • [x] Have you checked for duplicate issues: Yes
    • [x] Which Player version are you using: 3.16.2
    • [x] Can you reproduce the issue with our latest release version: Yes
    • [x] Can you reproduce the issue with the latest code from master: Yes
    • [x] What devices and OS versions are you using: iOS 13
    • [x] If applicable, add test code or test page to reproduce:
    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
    
    
    Expected behavior

    Kaltura Player Plugin must be loaded.

    Actual behavior

    The sample application crashed

    Console output
    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
    
    opened by El-Vishy 3
  • Cannot build PlayKit on iOS 13 with Xcode 11.3.1

    Cannot build PlayKit on iOS 13 with Xcode 11.3.1

    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.

    Prerequisites
    • [x] Have you checked for duplicate issues: yes
    • [x] Which Player version are you using: 3.16.1
    • [x] Can you reproduce the issue with our latest release version: yes
    • [ ] Can you reproduce the issue with the latest code from master: didn't check, master is behind release 3.16.1
    • [x] What devices and OS versions are you using: iOS 13, tried to build it on a simulator
    • [x] If applicable, add test code or test page to reproduce: see example project KalturaTest.zip
    Expected behavior

    I can use PlayKit as a dependency on an iOS 13 project with Xcode 11.3.1 and Swift 5.1.

    Actual behavior

    PlayKit does not compile as a dependency on an iOS 13 project with Xcode 11.3.1 and Swift 5.1.

    image ...

    opened by bensLine 3
  • App crashing when trying to use instantiate and use second instance of Player in iOS 10 and iOS 11.

    App crashing when trying to use instantiate and use second instance of Player in iOS 10 and iOS 11.

    Steps:

    1. Play a video
    2. Play another video using another instance of Player
    3. The app crashes

    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
    
    opened by nishu-priya 3
  • Playkit_IMA support for Picture in Picture

    Playkit_IMA support for Picture in Picture

    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?

    opened by audrarodriguez 4
  • AirPlay not working for downloaded videos

    AirPlay not working for downloaded videos

    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:

    1. Download HLS video file from remote
    2. AirPlay video to an external device (i.e. Macbook Pro)
    3. Play video.

    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

    Prerequisites
    • [ ] Have you checked for duplicate issues: Y
    • [ ] Which Player version are you using: 3.25.0
    • [ ] Can you reproduce the issue with our latest release version: Y
    • [ ] Can you reproduce the issue with the latest code from master:
    • [ ] What devices and OS versions are you using: iPhone 15.3.1 and MacOS 12.1
    • [ ] If applicable, add test code or test page to reproduce:
                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)
    
    Expected behavior

    Video is played on the target AirPlay device

    Actual behavior

    Video cannot be played on the target AirPlay device

    Console output
    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
    
    
    opened by olliestringfield-accedo 1
  • Swift package manager support

    Swift package manager support

    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.

    opened by JaiDeves 6
  • Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote

    Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote

    Pause, Seeking and Seeked events are not emitted when using Airplay mode with the Apple TV remote

    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.

    1. Choose airplay to apple tv
    2. Start playing the video
    3. Pause and play again with the apple tv remote controller
    4. Seek with the apple tv remote controller

    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

    Prerequisites
    • [x] Have you checked for duplicate issues: Yes, there are no duplicates for this issue.
    • [x] Which Player version are you using: 3.21
    • [x] Can you reproduce the issue with our latest release version: Yes
    • [x] Can you reproduce the issue with the latest code from master: Yes
    • [x] What devices and OS versions are you using: iPhone Xs iOS 14.4.2
    • [x] If applicable, add test code or test page to reproduce:
    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)
            ])
        }
    }
    
    Expected behavior

    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.

    Actual behavior

    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.

    Console output
    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
    
    opened by nidhik 0
  • Expose framerate in pk playback info

    Expose framerate in pk playback info

    Description of the Changes

    Please add a detailed description of the change, wether it's an enhancement or a bugfix. If the PR is related to an open issue please link to it.

    This is an enhancement to add frame rate reporting to the standard PlayKit Playback Info.

    CheckLists

    • [*] changes have been done against master branch, and PR does not conflict
    • [*] new unit / functional tests have been added (whenever applicable)
    • [*] test are passing in local environment

    I don't believe tests are relevant for this additional item

    • [*] Travis tests are passing (or test results are not worse than on master branch :))
    • [*] Docs have been updated

    I add a comment referencing the new frames per second property

    opened by TheoBendixson 0
Releases(v3.27.0)
  • v3.27.0(Nov 16, 2022)

    New in this version:

    • Fixed TimedMetadata handling with updated logic (#468)
    • codecDescription added to PlayerEvent.VideoTrackChanged (#466)

    Cocoapods install

    pod 'PlayKit', '~> 3.27.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.26.1(Sep 29, 2022)

    New in this version:

    • Added init() function to AnalyticsConfig class (#464)
    • Added missing clickThroughUrl exposure in PKEvent. (#467)

    Cocoapods install

    pod 'PlayKit', '~> 3.26.1'

    Source code(tar.gz)
    Source code(zip)
  • v3.26.0(Jul 5, 2022)

    Changes from v3.25.1

    • Playing Audio from a Video Asset in the Background (#459)
    • Seek to live edge API added. seekToLiveEdge() (#456 )
    • AVPlayer preventsDisplaySleepDuringVideo settings parameter added (#458, #460) kalturaPlayer.settings.preventsDisplaySleepDuringVideoPlayback = false
    • Minor code fixes (#457)

    Cocoapods install

    pod 'PlayKit', '~> 3.26.0

    Source code(tar.gz)
    Source code(zip)
  • v3.25.0(Feb 15, 2022)

    Changes from v3.24.0

    • PKMediaEntry and PKMediaSource extended with NSCopying (#449)
    • Added Vertical and horizontal captions positioning. (#453) Example:
      // Bottom right corner
      kalturaPlayer.settings.textTrackStyling.setOrthogonalLinePositionPercentage(95)
      kalturaPlayer.settings.textTrackStyling.setTextPositionPercentage(95)
      
      // Top left corner
      kalturaPlayer.settings.textTrackStyling.setOrthogonalLinePositionPercentage(5)
      kalturaPlayer.settings.textTrackStyling.setTextPositionPercentage(5)
      

    Cocoapods install

    pod 'PlayKit', '~> 3.25.0

    Source code(tar.gz)
    Source code(zip)
  • v3.24.0(Jan 4, 2022)

  • v3.23.0(Nov 15, 2021)

    Changes from v3.22.0

    • Fix for renewing the key for a DRM media (#443)
    • Primary + Redirect token reports event - For BP (#444) & (#445)

    Cocoapods install

    pod 'PlayKit', '~> 3.23.0

    Source code(tar.gz)
    Source code(zip)
  • v3.22.0(Sep 23, 2021)

    Changes from v3.21.0

    • Udrm calls now have extra data: player type, session and referrer information (#433)
    • AdEvent now has new properties (#432):
        @objc public var skipTimeOffset: TimeInterval
        @objc public var creativeAdId: String?
        @objc public var dealId: String?
        @objc public var surveyUrl: String?
        @objc public var traffickingParams: String?
        @objc public var adIndexInPod: Int
        @objc public var podCount: Int
        @objc public var adPodTimeOffset: TimeInterval```
      
      
    • Low-Latency HLS support (#431). Now you can specify AVPlayerItem.automaticallyPreservesTimeOffsetFromLive and AVPlayerItem.configuredTimeOffsetFromLive via PKLowLatencySettings
    • Kava analytics report now sending for all non Kaltura partners Accounts in PlayKit (#434)
    • Added integration with Youbora Smart Switch events (#429)

    Cocoapods install

    pod 'PlayKit', '~> 3.22.0

    Source code(tar.gz)
    Source code(zip)
  • v3.21.0(Jul 13, 2021)

    Changes from v3.20.1

    1. Exposed interface and methods to enable customisation of HTTP request headers for playback request. (#426) Applies for playlist/manifest URL and for .ts segments URLs

    How to use :

    • KalturaPlayer
    let playbackAdaptor = CustomPlaybackRequestAdapter()
    playbackAdaptor.httpHeaders = ["Authorization": "Bearer 12345689"]
    kalturaOTTPlayer.settings.contentRequestAdapter = playbackAdaptor
    
    // Load media
    kalturaOTTPlayer.loadMedia(options: mediaOptions) {}
    
    • PlayKit
    let playbackAdaptor = CustomPlaybackRequestAdapter()
    playbackAdaptor.httpHeaders = ["Authorization": "Bearer 12345689"]
    self.player.settings.contentRequestAdapter = playbackAdaptor
            
    // Prepare the player
    self.player.prepare(mediaConfig)
    

    1. Returning error in case a source could not be selected. (#427)

    1. PlaybackRateChanged event added (#424)
    PlayerEvent.playbackRate
    

    Cocoapods install

    pod 'PlayKit', '~> 3.21.0

    Source code(tar.gz)
    Source code(zip)
  • v3.20.1(Mar 11, 2021)

  • v3.20.0(Dec 28, 2020)

    Changes from v3.19.0

    • Expose loaded plugins by type (#414)
    • Trimming the tag from whitespaces before checking for 360. (#419)
    • Exposed userAgent to objc. (#411)

    Cocoapods install

    pod 'PlayKit', '~> 3.20.0

    Source code(tar.gz)
    Source code(zip)
  • v3.19.0(Nov 23, 2020)

    Changes from v3.18.0

    • Added bufferedTime to the BasicPlayer protocol. (#413)
    • Fixed - The currentItem seekableTimeRanges last object can not be casted to CMTimeRange, need to use the timeRangeValue of that object which is a CMTimeRange. (#412)

    Cocoapods install

    pod 'PlayKit', '~> 3.19.0

    Source code(tar.gz)
    Source code(zip)
  • v3.18.0(Sep 15, 2020)

    Changes from v3.17.1

    • Support iOS 14 Xcode 12 (#409)

      • Fixed deprecated code accordingly.
        • In the Tracks, selectedMediaOption on the AVPlayerItem is deprecated from iOS 11, it is called on the item's currentMediaSelection property available from iOS 9.0.
        • From iOS 11.2, 'respondByRequestingPersistableContentKeyRequest' changed to 'respondByRequestingPersistableContentKeyRequestAndReturnError'.
      • Updated SwiftyJSON to v5.0.0 from 4.3.0
      • Workaround for iOS 14 issue upon seeking to the duration when the seek is done with zero tolerance. Bug reported to Apple (FB8602469).
      • Updated dependency to the latest KalturaNetKit (v1.4.0) and PlayKitUtils (0.5.0).
    • Fixed issue where the durationChanged event was not fired upon change media. (#408)

    Cocoapods install

    pod 'PlayKit', '~> 3.18.0

    Source code(tar.gz)
    Source code(zip)
  • v3.17.1(Jun 10, 2020)

    Changes from v3.17.0

    • KVO crash fix, added the validation for the tvOS version in addition to the iOS version, where the observer wasn't removed automatically. (#406)

    Cocoapods install

    pod 'PlayKit', '~> 3.17.1'

    Source code(tar.gz)
    Source code(zip)
  • v3.17.0(Jun 2, 2020)

    Changes from v3.16.2

    • Live with DVR - Resume playback out of window time frame should seek to live edge. (#399)

    Bug Fixes:

    • Call seek to live edge only when the current item is set and if triggered. (#398)
    • Fixed, Change Media always starts from the beginning and ignores the startTime field. (#400)
    • Fixed, Creating a VR Data only when a tag is exactly 360, from the available tags that are returned. (#403)

    Cocoapods install

    pod 'PlayKit', '~> 3.17.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.16.2(Apr 1, 2020)

    Changes from v3.16.1

    • Fixed, not to set the current position and not to seek if the newValue is the same as the current one. (#395)
    • Send a PlayerEvent Pause upon rate changed to 0 only if it was caused by the stalling situation. (#396)

    Cocoapods install

    pod 'PlayKit', '~> 3.16.2'

    Source code(tar.gz)
    Source code(zip)
  • v3.16.1(Jan 7, 2020)

  • v3.16.0(Dec 23, 2019)

    Changes from v3.15.1

    • Loading optimizations, added autoBuffer boolean to the player network settings and startBuffering function to the player. (#385)
    • Fixed the PlayerEvent.Pause to be reported when the player is automatically paused because of a stall caused by setting the shouldPlayImmediately too true and automaticallyWaitsToMinimizeStalling too false. (#386)
    • Changed the userAgent in PlayKitManager to public. (#387)

    Cocoapods install

    pod 'PlayKit', '~> 3.16.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.15.1(Dec 19, 2019)

  • v3.15.0(Dec 2, 2019)

    Changes from v3.14.0

    • Fairplay using AVAssetDownloading was broken, added missing delegate. (#378)
    • Fixed upon calling play straight after prepare for a live media to start playing once ready. (#379)
    • Added support for play Immediately with rate. (from iOS 10, tvOS 10) (#380)
    • Added support for automaticallyWaitsToMinimizeStalling. (from iOS 10, tvOS 10) (#382)
    • Extracting FairPlay assetId in chunklists if not found in the master playlist. (#381)

    Cocoapods install

    pod 'PlayKit', '~> 3.15.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.14.0(Nov 4, 2019)

    Changes from v3.13.0

    • Setting startTime 0 for media Live with DVR doesn't start from 0 (#374)
    • Expose AV preferredForwardBufferDuration (#354)
    • Fixed the case there are no text tracks, to enable the code to continue to the audio tracks. (#376)

    Cocoapods install

    pod 'PlayKit', '~> 3.14.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.13.0(Sep 15, 2019)

    Changes from v3.12.1

    • Added the option to add External (out-of-band) WebVTT captions (#371)
    • Added to the PlayerSetting a boolean that indicates if FairPlay can be played on external screens. (#372)

    For the External Subtitles guide click here.

    Cocoapods install

    pod 'PlayKit', '~> 3.13.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.12.1(Aug 25, 2019)

  • v3.12.0(Aug 12, 2019)

    Changes from v3.11.1

    • Set the video gravity through the playerView contentMode. (#363)
    • Exposed PKPlaybackInfo To Objective-C (#328) (Thanks Theodore Bendixson)

    Cocoapods install

    pod 'PlayKit', '~> 3.12.0'

    Source code(tar.gz)
    Source code(zip)
  • v3.11.1(Aug 6, 2019)

  • v3.11.0(Jul 11, 2019)

    Changes from v3.10.1

    • Allowing the usage of external FairPlay DRM servers. ( #344 )
    • Use a user agent header that looks like a browser. ( #346 )
    • Add support for subtitles styling/CVAA. ( #345 )
    • Added an init to FairPlayDRMParams that doesn't need scheme parameter. ( #347 )
    • Made FPSExpirationInfo compatible with objective-c. ( #348 )
    • Added stop to the player inside the destroy function, so that the client won't need to call stop before calling destroy. ( #350 )
    • DFP DAI - IMA SDK integration. ( #349 )
    • Added "alwaysStartWithPreroll" boolean. ( #353 )
    • FairPlay, report error if offline duration is <= 0. ( #355 )
    • Fixed FairPlay response error handling. ( #357 )
    • Added user agent to uDRM call. ( #356 )

    Braking Changes

    • Removed the PlayerDelegate and the function 'playerShouldPlayAd'. ( #351 )
    Source code(tar.gz)
    Source code(zip)
  • v3.10.1(Apr 24, 2019)

  • v3.9.2(Apr 24, 2019)

  • v3.10.0(Apr 21, 2019)

  • v3.9.0(Apr 3, 2019)

    Changes from v3.8.0

    • Swift 4.2
    • Supports iOS 9 and above.
    • Fixed all blocks using weak or unowned self.
    • Player doesn't start playing once ready, reverting back, so that calling play will start the player once it is ready. (#332)
    • Cap seek target, not allowing to seek bellow or above duration. (#333)
    • Expose player volume. (#336)
    • Expose Creative ID and Advertiser Name. (#330)
    • Fixed audio track crash, the mediaType returned from the option of audible tracks has changed. (#339)
    • Updated KalturaNetKit to 1.1.0
    • Updated PlayKitUtils to 0.2.0

    Additional Info

    • PlayKit_IMA - Please update to the latest release v1.4.0
    Source code(tar.gz)
    Source code(zip)
  • v3.8.0(Jan 17, 2019)

    Changes from v3.7.0

    • Added PlayheadUpdate to the PlayerEvent. (#310)
    • Upgraded the API version used by the PhoenixMediaProvider to "5.0.3.18074" (#311)
    • Added currentProgramTime to BasicPlayer (#314)
    • Added mediaBitrate to the PKAdInfo. (#317)
    • Removed crash, the player will be created even if a plugin was not registered. (#318)
    • Removed crash if the media was set up as 360 but the VRPlayer plugin was not added, AVPlayer will be created. (#318)
    • Added name to PKMediaEntry, to be set by the providers. (#319)
    • Added PlaybackStalled to the PlayerEvent. (#320)
    • Added the option to send the clickThroughUrl to the AdClicked event. (#312)
    • Fixed leak in AVPlayerWrapper when calling the PKEvent namespace. (#315)
    • Perform seek to live edge automatically upon Live media. Added MediaType dvrLive. (#316, #321)
    • The subtitle 'NAME' in the metadata will be taken for the text track title if exists. (#322)
    • Added CustomStringConvertible to all enums. (#323)
    • Added cea608CaptionsEnabled to the PlayerSettings, to enable/disable the CLOSED-CAPTIONS in the text tracks. (#324)

    Additional Info

    • PlayKitYoubora - Please update to the latest release v1.1.0
    • PlayKitProviders - Please update to the latest release v1.1.0
    • PlayKit_IMA - Please update to the latest release v1.3.0
    Source code(tar.gz)
    Source code(zip)
Owner
Kaltura
Kaltura’s mission is to power any video experience. Recognized leader in OTT TV, OVP, Education Video and Enterprise Video Platform markets
Kaltura
Alter SDK is a cross-platform SDK consisting of a real-time 3D avatar system, facial motion capture, and an Avatar Designer component built from scratch for web3 interoperability and the open metaverse.

Alter SDK is a cross-platform SDK consisting of a real-time 3D avatar system, facial motion capture, and an Avatar Designer component built from scratch for web3 interoperability and the open metaverse.

Alter 45 Nov 29, 2022
Native iOS implementation of RadarCOVID tracing client using DP3T iOS SDK

RadarCOVID iOS App Introduction Native iOS implementation of RadarCOVID tracing client using DP3T iOS SDK Prerequisites These are the tools used to bu

Radar COVID 146 Nov 24, 2022
TelegramStickersImport — Telegram stickers importing SDK for iOS

TelegramStickersImport — Telegram stickers importing SDK for iOS TelegramStickersImport helps your users import third-party programaticaly created sti

null 35 Oct 26, 2022
Muxer used on top of Feed iOS SDK for airplay

FeedAirplayMuxer Muxer used on top of Feed iOS SDK for airplay purposes. Demo Project --> https://github.com/feedfm/AirplayDemo Feed Airplay Muxer is

Feed Media 0 May 6, 2022
Basispay IOS SDK Version 2

BasisPay-IOS-KIT BasisPay IOS Payment Gateway kit for developers INTRODUCTION This document describes the steps for integrating Basispay online paymen

null 0 Oct 21, 2021
Release repo for Gini Bank SDK for iOS

Gini Bank SDK for iOS The Gini Bank SDK provides components for capturing, reviewing and analyzing photos of invoices and remittance slips. By integra

Gini GmbH 1 Dec 6, 2022
Da Xue Zhang Platform Lvb iOS SDK

Cloud_Lvb_SDK iOS API Reference Dxz Meeting iOS SDK是为 iOS 平台用户音视频服务的开源 SDK。通过大学长开放平台自研RTC,RTM系统,为客户提供质量可靠的音视频服务。 类 类名 描述 CLS_PlatformManager SDK的音视频主要

null 8 Jan 10, 2022
PayPal iOS SDK

PayPal iOS SDK Welcome to PayPal's iOS SDK. This library will help you accept card, PayPal, Venmo, and alternative payment methods in your iOS app. Su

PayPal 25 Dec 14, 2022
Unofficial Notion API SDK for iOS & macOS

NotionSwift Unofficial Notion SDK for iOS & macOS. This is still work in progress version, the module interface might change. API Documentation This l

Wojciech Chojnacki 59 Jan 8, 2023
150,000+ stickers API & SDK for iOS Apps.

English | 한국어 Stipop UI SDK for iOS Stipop SDK provides over 150,000 .png and .gif stickers that can be easily integrated into mobile app chats, comme

Stipop, Inc. 19 Dec 20, 2022
Spotify SDK for iOS

Spotify iOS SDK Overview The Spotify iOS framework allows your application to interact with the Spotify app running in the background on a user's devi

Spotify 522 Jan 6, 2023
Headless iOS/Mac SDK for saving stuff to Pocket.

This SDK is deprecated Howdy all! ?? Thanks for checking out this repo. Your ?? mean a lot to us. ?? Unfortunately, this project is deprecated, and th

Pocket 230 Mar 18, 2022
Evernote Cloud SDK for iOS

Evernote Cloud SDK 3.0 for iOS This is the official Evernote SDK for iOS. To get started, follow the instructions bellow. Additional information can b

Evernote 256 Oct 6, 2022
iOS SDK for the Box Content API

Box iOS SDK Getting Started Docs: https://developer.box.com/guides/mobile/ios/quick-start/ NOTE: The Box iOS SDK in Objective-C (prior to v3.0.0) has

Box 112 Dec 19, 2022
OneDrive SDK for iOS

Get started with the OneDrive SDK for iOS Integrate the OneDrive API into your iOS app! 1. Installation Install via Cocoapods Install Cocoapods - Foll

OneDrive 101 Dec 19, 2022
Stripe iOS SDK

Stripe iOS SDK The Stripe iOS SDK makes it quick and easy to build an excellent payment experience in your iOS app. We provide powerful and customizab

Stripe 1.8k Jan 5, 2023
AWS SDK for iOS. For more information, see our web site:

AWS SDK for iOS The AWS SDK for iOS provides a library and documentation for developers to build connected mobile applications using AWS. Features / A

AWS Amplify 1.6k Dec 26, 2022
Zendesk Mobile SDK for iOS

⚠️ This Repository has been deprecated, please go to here for the Zendesk Support SDK ⚠️ Zendesk Mobile SDK for iOS Zendesk SDK for mobile is a quick,

Zendesk 113 Dec 24, 2022
Uber Rides iOS SDK (beta)

Uber Rides iOS SDK This Swift library allows you to integrate the Uber Rides API into your iOS app. Requirements iOS 8.0+ Xcode 10.0+ Swift 4.2+ Insta

Uber Open Source 343 Jan 4, 2023