expo-realtime-ivs-broadcast 0.1.10 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/README.md +261 -4
  2. package/android/build/.transforms/10a4d332fad050fdaf4ee2d7badc1ee4/transformed/classes/classes_dex/classes.dex +0 -0
  3. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoIVSRemoteStreamView.dex +0 -0
  4. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView$attachStreamWithRetry$4.dex +0 -0
  5. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView.dex +0 -0
  6. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$16$1.dex +0 -0
  7. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$10$2.dex → ExpoRealtimeIvsBroadcastModule$definition$1$16$2.dex} +0 -0
  8. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$11$1.dex → ExpoRealtimeIvsBroadcastModule$definition$1$17$1.dex} +0 -0
  9. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$2.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$1.dex} +0 -0
  10. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$10.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$10.dex} +0 -0
  11. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$14.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$11.dex} +0 -0
  12. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$12.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$12.dex} +0 -0
  13. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$13.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$13.dex} +0 -0
  14. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$11.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$14.dex} +0 -0
  15. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$15.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$15.dex} +0 -0
  16. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$16.dex +0 -0
  17. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$17.dex +0 -0
  18. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$18.dex +0 -0
  19. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$4.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$2.dex} +0 -0
  20. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$3.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$3.dex} +0 -0
  21. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$5.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$4.dex} +0 -0
  22. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$1.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$5.dex} +0 -0
  23. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$6.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$6.dex} +0 -0
  24. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$7.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$7.dex} +0 -0
  25. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$8.dex +0 -0
  26. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$9.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$9.dex} +0 -0
  27. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$1.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$1.dex} +0 -0
  28. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$2.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$2.dex} +0 -0
  29. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$3.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$3.dex} +0 -0
  30. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$4.dex +0 -0
  31. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$5.dex +0 -0
  32. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$6.dex +0 -0
  33. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$7.dex +0 -0
  34. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$8.dex +0 -0
  35. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$OnCreate$1.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$OnCreate$1.dex} +0 -0
  36. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$1.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$1.dex} +0 -0
  37. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$2.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$2.dex} +0 -0
  38. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$1.dex +0 -0
  39. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$10$$inlined$Prop$1.dex → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$2.dex} +0 -0
  40. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$23$$inlined$Prop$1.dex +0 -0
  41. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule.dex +0 -0
  42. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/IVSStageManager.dex +0 -0
  43. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PiPOptions$PiPSourceView.dex +0 -0
  44. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PiPOptions.dex +0 -0
  45. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PiPStateListener.dex +0 -0
  46. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PictureInPictureDelegate.dex +0 -0
  47. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PictureInPictureManager$Companion.dex +0 -0
  48. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/PictureInPictureManager.dex +0 -0
  49. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +5 -0
  50. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  51. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +12 -1
  52. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +5 -0
  53. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoIVSRemoteStreamView.class +0 -0
  54. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView$attachStreamWithRetry$4.class +0 -0
  55. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView.class +0 -0
  56. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$10$1.class → ExpoRealtimeIvsBroadcastModule$definition$1$16$1.class} +0 -0
  57. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$10$2.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$16$2.class} +0 -0
  58. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$11$1.class → ExpoRealtimeIvsBroadcastModule$definition$1$17$1.class} +0 -0
  59. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$4.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$1.class} +0 -0
  60. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$10.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$10.class} +0 -0
  61. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$14.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$11.class} +0 -0
  62. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$12.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$12.class} +0 -0
  63. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$13.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$13.class} +0 -0
  64. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$11.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$14.class} +0 -0
  65. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$15.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$15.class} +0 -0
  66. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$16.class +0 -0
  67. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$17.class +0 -0
  68. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$18.class +0 -0
  69. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$5.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$2.class} +0 -0
  70. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$3.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$3.class} +0 -0
  71. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$2.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$4.class} +0 -0
  72. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$5.class} +0 -0
  73. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$6.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$6.class} +0 -0
  74. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$7.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$7.class} +0 -0
  75. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$8.class +0 -0
  76. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$9.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$9.class} +0 -0
  77. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$1.class} +0 -0
  78. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$2.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$2.class} +0 -0
  79. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$3.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$3.class} +0 -0
  80. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$4.class +0 -0
  81. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$5.class +0 -0
  82. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$6.class +0 -0
  83. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$7.class +0 -0
  84. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$8.class +0 -0
  85. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$OnCreate$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$OnCreate$1.class} +0 -0
  86. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$1.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$1.class} +0 -0
  87. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$2.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$2.class} +0 -0
  88. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$1.class +0 -0
  89. package/android/build/{tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$10$$inlined$Prop$1.class → intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$2.class} +0 -0
  90. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$10$$inlined$Prop$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$23$$inlined$Prop$1.class} +0 -0
  91. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule.class +0 -0
  92. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/IVSStageManager.class +0 -0
  93. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PiPOptions$PiPSourceView.class +0 -0
  94. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PiPOptions.class +0 -0
  95. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PiPStateListener.class +0 -0
  96. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PictureInPictureDelegate.class +0 -0
  97. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PictureInPictureManager$Companion.class +0 -0
  98. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/PictureInPictureManager.class +0 -0
  99. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  100. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
  101. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
  102. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
  103. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
  104. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values +0 -0
  105. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
  106. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.s +1 -0
  107. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
  108. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
  109. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
  110. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
  111. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
  112. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
  113. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
  114. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
  115. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
  116. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
  117. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
  118. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
  119. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
  120. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
  121. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
  122. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
  123. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
  124. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
  125. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
  126. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  127. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
  128. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
  129. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
  130. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values +0 -0
  131. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  132. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.s +1 -0
  133. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
  134. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
  135. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
  136. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
  137. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
  138. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
  139. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
  140. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
  141. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
  142. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
  143. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
  144. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
  145. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
  146. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
  147. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
  148. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
  149. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
  150. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
  151. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
  152. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
  153. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
  154. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
  155. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
  156. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
  157. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
  158. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
  159. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
  160. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
  161. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
  162. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
  163. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
  164. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
  165. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  166. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  167. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  168. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  169. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values +0 -0
  170. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  171. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.s +1 -0
  172. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  173. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  174. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  175. package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
  176. package/android/build/outputs/logs/manifest-merger-debug-report.txt +14 -2
  177. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoIVSRemoteStreamView.class +0 -0
  178. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView$attachStreamWithRetry$4.class +0 -0
  179. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView.class +0 -0
  180. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$10$1.class → ExpoRealtimeIvsBroadcastModule$definition$1$16$1.class} +0 -0
  181. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$10$2.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$16$2.class} +0 -0
  182. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$1$11$1.class → ExpoRealtimeIvsBroadcastModule$definition$1$17$1.class} +0 -0
  183. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$1.class +0 -0
  184. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$10.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$10.class} +0 -0
  185. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$14.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$11.class} +0 -0
  186. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$12.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$12.class} +0 -0
  187. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$13.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$13.class} +0 -0
  188. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$11.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$14.class} +0 -0
  189. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$15.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$15.class} +0 -0
  190. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$16.class +0 -0
  191. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$17.class +0 -0
  192. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$18.class +0 -0
  193. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$2.class +0 -0
  194. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$3.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$3.class} +0 -0
  195. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$4.class +0 -0
  196. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$5.class +0 -0
  197. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$6.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$6.class} +0 -0
  198. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$7.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$7.class} +0 -0
  199. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$8.class +0 -0
  200. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$9.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunction$9.class} +0 -0
  201. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$1.class} +0 -0
  202. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$2.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$2.class} +0 -0
  203. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunctionWithoutArgs$3.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$3.class} +0 -0
  204. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$4.class +0 -0
  205. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$5.class +0 -0
  206. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$6.class +0 -0
  207. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$7.class +0 -0
  208. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$AsyncFunctionWithoutArgs$8.class +0 -0
  209. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$OnCreate$1.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$OnCreate$1.class} +0 -0
  210. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$1.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$1.class} +0 -0
  211. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$View$2.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$$inlined$View$2.class} +0 -0
  212. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$1.class +0 -0
  213. package/android/build/{intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$2.class → tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$22$$inlined$Prop$2.class} +0 -0
  214. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/{ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$2.class → ExpoRealtimeIvsBroadcastModule$definition$lambda$24$lambda$23$$inlined$Prop$1.class} +0 -0
  215. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule.class +0 -0
  216. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/IVSStageManager.class +0 -0
  217. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PiPOptions$PiPSourceView.class +0 -0
  218. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PiPOptions.class +0 -0
  219. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PiPStateListener.class +0 -0
  220. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PictureInPictureDelegate.class +0 -0
  221. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PictureInPictureManager$Companion.class +0 -0
  222. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/PictureInPictureManager.class +0 -0
  223. package/android/src/main/AndroidManifest.xml +5 -0
  224. package/android/src/main/java/expo/modules/realtimeivsbroadcast/ExpoIVSRemoteStreamView.kt +172 -23
  225. package/android/src/main/java/expo/modules/realtimeivsbroadcast/ExpoIVSStagePreviewView.kt +33 -0
  226. package/android/src/main/java/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule.kt +92 -2
  227. package/android/src/main/java/expo/modules/realtimeivsbroadcast/IVSStageManager.kt +5 -2
  228. package/android/src/main/java/expo/modules/realtimeivsbroadcast/PictureInPictureManager.kt +431 -0
  229. package/build/ExpoRealtimeIvsBroadcast.types.d.ts +45 -0
  230. package/build/ExpoRealtimeIvsBroadcast.types.d.ts.map +1 -1
  231. package/build/ExpoRealtimeIvsBroadcast.types.js.map +1 -1
  232. package/build/ExpoRealtimeIvsBroadcastModule.d.ts +7 -1
  233. package/build/ExpoRealtimeIvsBroadcastModule.d.ts.map +1 -1
  234. package/build/ExpoRealtimeIvsBroadcastModule.js.map +1 -1
  235. package/build/ExpoRealtimeIvsBroadcastModule.web.d.ts +7 -1
  236. package/build/ExpoRealtimeIvsBroadcastModule.web.d.ts.map +1 -1
  237. package/build/ExpoRealtimeIvsBroadcastModule.web.js +20 -0
  238. package/build/ExpoRealtimeIvsBroadcastModule.web.js.map +1 -1
  239. package/build/index.d.ts +60 -1
  240. package/build/index.d.ts.map +1 -1
  241. package/build/index.js +77 -0
  242. package/build/index.js.map +1 -1
  243. package/ios/ExpoIVSRemoteStreamView.swift +17 -0
  244. package/ios/ExpoIVSStagePreviewView.swift +18 -0
  245. package/ios/ExpoRealtimeIvsBroadcast.podspec +2 -1
  246. package/ios/ExpoRealtimeIvsBroadcastModule.swift +46 -1
  247. package/ios/IVSPictureInPictureController.swift +1070 -0
  248. package/ios/IVSStageManager.swift +419 -1
  249. package/package.json +1 -1
  250. package/src/ExpoRealtimeIvsBroadcast.types.ts +53 -0
  251. package/src/ExpoRealtimeIvsBroadcastModule.ts +9 -1
  252. package/src/ExpoRealtimeIvsBroadcastModule.web.ts +26 -8
  253. package/src/index.ts +94 -0
  254. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$1$10$1.dex +0 -0
  255. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$8.dex +0 -0
  256. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$1.dex +0 -0
  257. package/android/build/.transforms/9f2f591934de19590757f5a4b0b59398/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$2.dex +0 -0
  258. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$8.class +0 -0
  259. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$1.class +0 -0
  260. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$1.class +0 -0
  261. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$2.class +0 -0
  262. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$4.class +0 -0
  263. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$5.class +0 -0
  264. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$$inlined$AsyncFunction$8.class +0 -0
  265. package/android/build/tmp/kotlin-classes/debug/expo/modules/realtimeivsbroadcast/ExpoRealtimeIvsBroadcastModule$definition$lambda$11$lambda$9$$inlined$Prop$1.class +0 -0
@@ -0,0 +1,1070 @@
1
+ // IVSPictureInPictureController.swift
2
+ // Picture-in-Picture support for IVS Stages
3
+
4
+ import AVKit
5
+ import AVFoundation
6
+ import UIKit
7
+ import AmazonIVSBroadcast
8
+
9
+ // MARK: - PiP Types (Available to all iOS versions for type compatibility)
10
+
11
+ /// Options for configuring PiP behavior
12
+ public struct PiPOptions {
13
+ public var autoEnterOnBackground: Bool = true
14
+ public var sourceView: PiPSourceView = .remote
15
+ public var preferredAspectRatio: CGSize = CGSize(width: 9, height: 16)
16
+
17
+ public enum PiPSourceView: String {
18
+ case local
19
+ case remote
20
+ }
21
+
22
+ public init() {}
23
+ }
24
+
25
+ /// Delegate protocol for PiP state changes
26
+ public protocol IVSPictureInPictureControllerDelegate: AnyObject {
27
+ func pictureInPictureDidStart()
28
+ func pictureInPictureDidStop()
29
+ func pictureInPictureWillRestore()
30
+ func pictureInPictureDidFail(with error: String)
31
+ }
32
+
33
+ // MARK: - View Frame Capture
34
+ /// Captures frames from any UIView using CADisplayLink for PiP
35
+ /// This is the workaround for IVS SDK not exposing frame callbacks
36
+ /// ALL operations happen on the main thread to avoid threading issues
37
+
38
+ public class ViewFrameCapture {
39
+ private var displayLink: CADisplayLink?
40
+ private weak var targetView: UIView?
41
+ private var frameCallback: ((CVPixelBuffer) -> Void)?
42
+
43
+ // Throttle frame capture to 30fps
44
+ private var lastCaptureTime: CFTimeInterval = 0
45
+ private let targetFrameInterval: CFTimeInterval = 1.0 / 30.0
46
+
47
+ // Fixed output size to prevent jittering - 9:16 portrait
48
+ private let fixedOutputWidth: Int = 540
49
+ private let fixedOutputHeight: Int = 960
50
+
51
+ // Reusable pixel buffer pool for efficiency
52
+ private var pixelBufferPool: CVPixelBufferPool?
53
+ private var lastWidth: Int = 0
54
+ private var lastHeight: Int = 0
55
+
56
+ private var isCapturing: Bool = false
57
+
58
+ public init() {}
59
+
60
+ deinit {
61
+ stop()
62
+ }
63
+
64
+ /// Start capturing frames from the target view
65
+ public func start(view: UIView, callback: @escaping (CVPixelBuffer) -> Void) {
66
+ // Ensure we're on main thread
67
+ guard Thread.isMainThread else {
68
+ DispatchQueue.main.async { [weak self] in
69
+ self?.start(view: view, callback: callback)
70
+ }
71
+ return
72
+ }
73
+
74
+ stop() // Clean up any existing capture
75
+
76
+ self.targetView = view
77
+ self.frameCallback = callback
78
+ self.isCapturing = true
79
+
80
+ let displayLink = CADisplayLink(target: self, selector: #selector(self.captureFrame))
81
+ displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: 24, maximum: 30, preferred: 30)
82
+ displayLink.add(to: .main, forMode: .common)
83
+ self.displayLink = displayLink
84
+
85
+ print("🖼️ [ViewCapture] Started capturing frames from view")
86
+ }
87
+
88
+ /// Stop capturing frames
89
+ public func stop() {
90
+ // Ensure we're on main thread
91
+ guard Thread.isMainThread else {
92
+ DispatchQueue.main.async { [weak self] in
93
+ self?.stop()
94
+ }
95
+ return
96
+ }
97
+
98
+ isCapturing = false
99
+ displayLink?.invalidate()
100
+ displayLink = nil
101
+ targetView = nil
102
+ frameCallback = nil
103
+ pixelBufferPool = nil
104
+ lastWidth = 0
105
+ lastHeight = 0
106
+ frameCount = 0
107
+ print("🖼️ [ViewCapture] Stopped capturing frames")
108
+ }
109
+
110
+ @objc private func captureFrame(_ displayLink: CADisplayLink) {
111
+ // All of this runs on main thread (CADisplayLink callback)
112
+ guard isCapturing else { return }
113
+
114
+ // Throttle to target frame rate
115
+ let currentTime = displayLink.timestamp
116
+ guard currentTime - lastCaptureTime >= targetFrameInterval else { return }
117
+ lastCaptureTime = currentTime
118
+
119
+ guard let view = targetView, let callback = frameCallback else { return }
120
+
121
+ let bounds = view.bounds
122
+ guard bounds.width > 0 && bounds.height > 0 else { return }
123
+
124
+ // Check if view has a window - if not, try to get superview bounds
125
+ // IVS preview might not have window when app is in background
126
+ let captureView: UIView
127
+ let captureBounds: CGRect
128
+
129
+ if view.window != nil {
130
+ captureView = view
131
+ captureBounds = bounds
132
+ } else if let superview = view.superview, superview.window != nil {
133
+ // Try capturing from superview instead
134
+ captureView = superview
135
+ captureBounds = superview.bounds
136
+ } else {
137
+ // Last resort: capture the view anyway with afterScreenUpdates
138
+ captureView = view
139
+ captureBounds = bounds
140
+ }
141
+
142
+ // Use UIGraphicsImageRenderer with drawHierarchy for Metal/OpenGL views
143
+ // This is the only reliable way to capture IVS preview views
144
+ // NOTE: afterScreenUpdates must be true when view is not in visible window (e.g., during PiP)
145
+ let renderer = UIGraphicsImageRenderer(size: captureBounds.size)
146
+ let image = renderer.image { rendererContext in
147
+ // drawHierarchy captures Metal/OpenGL content unlike layer.render
148
+ // afterScreenUpdates: true is required when view may not be visible
149
+ captureView.drawHierarchy(in: captureBounds, afterScreenUpdates: true)
150
+ }
151
+
152
+ guard let cgImage = image.cgImage else { return }
153
+
154
+ // Use FIXED output size to prevent jittering
155
+ let width = fixedOutputWidth
156
+ let height = fixedOutputHeight
157
+
158
+ // Get pixel buffer from pool with fixed size
159
+ guard let pixelBuffer = getPixelBuffer(width: width, height: height) else {
160
+ return
161
+ }
162
+
163
+ CVPixelBufferLockBaseAddress(pixelBuffer, [])
164
+ defer { CVPixelBufferUnlockBaseAddress(pixelBuffer, []) }
165
+
166
+ guard let context = CGContext(
167
+ data: CVPixelBufferGetBaseAddress(pixelBuffer),
168
+ width: width,
169
+ height: height,
170
+ bitsPerComponent: 8,
171
+ bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
172
+ space: CGColorSpaceCreateDeviceRGB(),
173
+ bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
174
+ ) else {
175
+ return
176
+ }
177
+
178
+ // Calculate scaling to fit the captured image into fixed output size
179
+ // while maintaining aspect ratio (aspect fill)
180
+ let sourceWidth = CGFloat(cgImage.width)
181
+ let sourceHeight = CGFloat(cgImage.height)
182
+ let targetWidth = CGFloat(width)
183
+ let targetHeight = CGFloat(height)
184
+
185
+ let sourceAspect = sourceWidth / sourceHeight
186
+ let targetAspect = targetWidth / targetHeight
187
+
188
+ var drawRect: CGRect
189
+ if sourceAspect > targetAspect {
190
+ // Source is wider - fit to height, crop sides
191
+ let scaledWidth = targetHeight * sourceAspect
192
+ let xOffset = (scaledWidth - targetWidth) / 2
193
+ drawRect = CGRect(x: -xOffset, y: 0, width: scaledWidth, height: targetHeight)
194
+ } else {
195
+ // Source is taller - fit to width, crop top/bottom
196
+ let scaledHeight = targetWidth / sourceAspect
197
+ let yOffset = (scaledHeight - targetHeight) / 2
198
+ drawRect = CGRect(x: 0, y: -yOffset, width: targetWidth, height: scaledHeight)
199
+ }
200
+
201
+ // CGContext has origin at bottom-left, so we need to flip
202
+ context.translateBy(x: 0, y: CGFloat(height))
203
+ context.scaleBy(x: 1, y: -1)
204
+
205
+ // Draw the image scaled to fit the fixed output size (aspect fill)
206
+ context.draw(cgImage, in: drawRect)
207
+
208
+ // Log first frame capture for debugging
209
+ if frameCount == 0 {
210
+ print("🖼️ [ViewCapture] First frame captured: \(width)x\(height)")
211
+ }
212
+ frameCount += 1
213
+
214
+ // Call the callback with the captured frame
215
+ callback(pixelBuffer)
216
+ }
217
+
218
+ private var frameCount: Int = 0
219
+
220
+ private func getPixelBuffer(width: Int, height: Int) -> CVPixelBuffer? {
221
+ // Create new pool if size changed
222
+ if width != lastWidth || height != lastHeight || pixelBufferPool == nil {
223
+ lastWidth = width
224
+ lastHeight = height
225
+
226
+ let attributes: [String: Any] = [
227
+ kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA,
228
+ kCVPixelBufferWidthKey as String: width,
229
+ kCVPixelBufferHeightKey as String: height,
230
+ kCVPixelBufferIOSurfacePropertiesKey as String: [:],
231
+ kCVPixelBufferCGImageCompatibilityKey as String: true,
232
+ kCVPixelBufferCGBitmapContextCompatibilityKey as String: true
233
+ ]
234
+
235
+ var pool: CVPixelBufferPool?
236
+ CVPixelBufferPoolCreate(kCFAllocatorDefault, nil, attributes as CFDictionary, &pool)
237
+ pixelBufferPool = pool
238
+ }
239
+
240
+ guard let pool = pixelBufferPool else { return nil }
241
+
242
+ var pixelBuffer: CVPixelBuffer?
243
+ CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pool, &pixelBuffer)
244
+ return pixelBuffer
245
+ }
246
+ }
247
+
248
+ // MARK: - SampleBufferVideoCallView
249
+ /// A UIView that uses AVSampleBufferDisplayLayer as its layer class
250
+ /// This is required for Video Call PiP
251
+
252
+ @available(iOS 15.0, *)
253
+ class SampleBufferVideoCallView: UIView {
254
+ override class var layerClass: AnyClass {
255
+ return AVSampleBufferDisplayLayer.self
256
+ }
257
+
258
+ var sampleBufferDisplayLayer: AVSampleBufferDisplayLayer {
259
+ return layer as! AVSampleBufferDisplayLayer
260
+ }
261
+ }
262
+
263
+ // MARK: - IVSPictureInPictureController
264
+
265
+ /// Controller for managing Picture-in-Picture functionality with IVS streams
266
+ /// Uses the Video Call PiP API for real-time video
267
+ @available(iOS 15.0, *)
268
+ public class IVSPictureInPictureController: NSObject {
269
+
270
+ // MARK: - Properties
271
+
272
+ private var pipController: AVPictureInPictureController?
273
+ private var sampleBufferDisplayLayer: AVSampleBufferDisplayLayer?
274
+ private var pipContentSource: AVPictureInPictureController.ContentSource?
275
+
276
+ // Video Call PiP components
277
+ private var pipVideoCallViewController: AVPictureInPictureVideoCallViewController?
278
+ private var sampleBufferVideoCallView: SampleBufferVideoCallView?
279
+
280
+ // Container/source view for PiP - this should be the ACTUAL visible view showing video
281
+ private var pipContainerView: UIView?
282
+ private weak var activeSourceView: UIView?
283
+
284
+ // Configuration
285
+ private var options: PiPOptions = PiPOptions()
286
+
287
+ // State
288
+ public private(set) var isActive: Bool = false
289
+ public private(set) var isEnabled: Bool = false
290
+
291
+ // Delegate
292
+ public weak var delegate: IVSPictureInPictureControllerDelegate?
293
+
294
+ // Frame timing for sample buffer creation
295
+ private var frameCount: Int64 = 0
296
+ private let timeScale: Int32 = 600
297
+
298
+ // Queue for sample buffer operations
299
+ private let sampleBufferQueue = DispatchQueue(label: "com.ivs.pip.sampleBuffer")
300
+
301
+ // View frame capture for remote streams
302
+ private var viewFrameCapture: ViewFrameCapture?
303
+ private weak var captureTargetView: UIView?
304
+
305
+ // Placeholder frame generator for broadcaster PiP (when camera is unavailable in background)
306
+ private var placeholderTimer: Timer?
307
+ private var placeholderPixelBuffer: CVPixelBuffer?
308
+ private var isUsingPlaceholder: Bool = false
309
+ private var lastRealFrameTime: CFAbsoluteTime = 0
310
+ private let placeholderTimeout: CFTimeInterval = 0.5 // Switch to placeholder after 0.5s without frames
311
+
312
+ // MARK: - Initialization
313
+
314
+ public override init() {
315
+ super.init()
316
+ setupNotifications()
317
+ createPlaceholderPixelBuffer()
318
+ }
319
+
320
+ deinit {
321
+ NotificationCenter.default.removeObserver(self)
322
+ cleanup()
323
+ }
324
+
325
+ // MARK: - Setup
326
+
327
+ private func setupNotifications() {
328
+ NotificationCenter.default.addObserver(
329
+ self,
330
+ selector: #selector(applicationWillResignActive),
331
+ name: UIApplication.willResignActiveNotification,
332
+ object: nil
333
+ )
334
+
335
+ NotificationCenter.default.addObserver(
336
+ self,
337
+ selector: #selector(applicationDidBecomeActive),
338
+ name: UIApplication.didBecomeActiveNotification,
339
+ object: nil
340
+ )
341
+ }
342
+
343
+ /// Enable PiP with the given options
344
+ /// Uses the Video Call PiP API which is designed for real-time video
345
+ public func enable(options: PiPOptions) -> Bool {
346
+ guard AVPictureInPictureController.isPictureInPictureSupported() else {
347
+ print("🖼️ [PiP] Picture-in-Picture is not supported on this device (simulator?)")
348
+ delegate?.pictureInPictureDidFail(with: "PiP not supported on this device")
349
+ return false
350
+ }
351
+
352
+ // Ensure we're on the main thread for all UI operations
353
+ guard Thread.isMainThread else {
354
+ var result = false
355
+ DispatchQueue.main.sync {
356
+ result = self.enable(options: options)
357
+ }
358
+ return result
359
+ }
360
+
361
+ // If already enabled, clean up first to allow re-enabling
362
+ if isEnabled {
363
+ print("🖼️ [PiP] Already enabled, resetting state for re-enable")
364
+ cleanupForReEnable()
365
+ }
366
+
367
+ self.options = options
368
+
369
+ // Use fixed frame size matching our capture output (9:16 portrait)
370
+ let frameWidth: CGFloat = 540
371
+ let frameHeight: CGFloat = 960
372
+
373
+ // Create SampleBufferVideoCallView - a UIView with AVSampleBufferDisplayLayer as its layer
374
+ let sampleBufferView = SampleBufferVideoCallView(frame: CGRect(x: 0, y: 0, width: frameWidth, height: frameHeight))
375
+ sampleBufferView.sampleBufferDisplayLayer.videoGravity = .resizeAspectFill
376
+ self.sampleBufferDisplayLayer = sampleBufferView.sampleBufferDisplayLayer
377
+ self.sampleBufferVideoCallView = sampleBufferView
378
+
379
+ // Create the PiP Video Call View Controller
380
+ let pipVideoCallVC = AVPictureInPictureVideoCallViewController()
381
+ pipVideoCallVC.preferredContentSize = CGSize(width: frameWidth, height: frameHeight)
382
+ pipVideoCallVC.view.addSubview(sampleBufferView)
383
+ self.pipVideoCallViewController = pipVideoCallVC
384
+
385
+ // Set up constraints for the sample buffer view
386
+ sampleBufferView.translatesAutoresizingMaskIntoConstraints = false
387
+ NSLayoutConstraint.activate([
388
+ sampleBufferView.leadingAnchor.constraint(equalTo: pipVideoCallVC.view.leadingAnchor),
389
+ sampleBufferView.trailingAnchor.constraint(equalTo: pipVideoCallVC.view.trailingAnchor),
390
+ sampleBufferView.topAnchor.constraint(equalTo: pipVideoCallVC.view.topAnchor),
391
+ sampleBufferView.bottomAnchor.constraint(equalTo: pipVideoCallVC.view.bottomAnchor)
392
+ ])
393
+
394
+ // NOTE: We'll set the activeSourceView later when setupWithSourceView is called
395
+ // The activeVideoCallSourceView MUST be the actual visible view showing video
396
+ self.isEnabled = true
397
+
398
+ print("🖼️ [PiP] Enabled with Video Call API: autoEnter=\(options.autoEnterOnBackground), source=\(options.sourceView.rawValue)")
399
+ print("🖼️ [PiP] Call setupWithSourceView() with the actual video view to complete setup")
400
+
401
+ return true
402
+ }
403
+
404
+ /// Clean up state for re-enabling (without fully disabling)
405
+ private func cleanupForReEnable() {
406
+ // Stop any active PiP
407
+ pipController?.stopPictureInPicture()
408
+ pipController = nil
409
+ pipContentSource = nil
410
+
411
+ // Clean up Video Call components
412
+ sampleBufferVideoCallView?.removeFromSuperview()
413
+ sampleBufferVideoCallView = nil
414
+ pipVideoCallViewController = nil
415
+
416
+ sampleBufferDisplayLayer?.flush()
417
+ sampleBufferDisplayLayer = nil
418
+
419
+ // Reset state but keep isEnabled true (will be set again)
420
+ frameCount = 0
421
+ enqueuedFrameCount = 0
422
+ startTime = nil
423
+ isActive = false
424
+
425
+ // Don't nil out activeSourceView - it might still be valid
426
+ print("🖼️ [PiP] Cleaned up for re-enable")
427
+ }
428
+
429
+ /// Complete PiP setup with the actual source view
430
+ /// This MUST be called with the visible view showing video content
431
+ public func setupWithSourceView(_ sourceView: UIView) {
432
+ guard Thread.isMainThread else {
433
+ DispatchQueue.main.async { [weak self] in
434
+ self?.setupWithSourceView(sourceView)
435
+ }
436
+ return
437
+ }
438
+
439
+ guard let pipVideoCallVC = pipVideoCallViewController else {
440
+ print("🖼️ [PiP] Error: Must call enable() before setupWithSourceView()")
441
+ return
442
+ }
443
+
444
+ self.activeSourceView = sourceView
445
+ self.pipContainerView = sourceView
446
+
447
+ // Create PiP content source using Video Call API
448
+ // The activeVideoCallSourceView is the ACTUAL view showing video in the app
449
+ let contentSource = AVPictureInPictureController.ContentSource(
450
+ activeVideoCallSourceView: sourceView,
451
+ contentViewController: pipVideoCallVC
452
+ )
453
+ self.pipContentSource = contentSource
454
+
455
+ // Create PiP controller
456
+ let controller = AVPictureInPictureController(contentSource: contentSource)
457
+ controller.delegate = self
458
+ controller.canStartPictureInPictureAutomaticallyFromInline = options.autoEnterOnBackground
459
+
460
+ self.pipController = controller
461
+
462
+ // Pre-warm with placeholder frames so PiP is possible immediately
463
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { [weak self] in
464
+ for _ in 0..<3 {
465
+ self?.enqueuePlaceholderFrame()
466
+ }
467
+ }
468
+
469
+ print("🖼️ [PiP] Setup complete with source view: \(sourceView)")
470
+ print("🖼️ [PiP] isPictureInPicturePossible: \(controller.isPictureInPicturePossible)")
471
+ }
472
+
473
+ /// Disable PiP
474
+ public func disable() {
475
+ // Ensure we're on the main thread
476
+ guard Thread.isMainThread else {
477
+ DispatchQueue.main.async { [weak self] in
478
+ self?.disable()
479
+ }
480
+ return
481
+ }
482
+
483
+ if isActive {
484
+ stop()
485
+ }
486
+
487
+ stopViewCapture()
488
+ cleanup()
489
+ isEnabled = false
490
+
491
+ print("🖼️ [PiP] Disabled")
492
+ }
493
+
494
+ /// Start PiP manually
495
+ public func start() {
496
+ // Ensure we're on the main thread
497
+ guard Thread.isMainThread else {
498
+ DispatchQueue.main.async { [weak self] in
499
+ self?.start()
500
+ }
501
+ return
502
+ }
503
+
504
+ guard isEnabled else {
505
+ print("🖼️ [PiP] Cannot start - PiP is not enabled")
506
+ delegate?.pictureInPictureDidFail(with: "PiP is not enabled")
507
+ return
508
+ }
509
+
510
+ guard let controller = pipController else {
511
+ print("🖼️ [PiP] Cannot start - no PiP controller")
512
+ delegate?.pictureInPictureDidFail(with: "PiP controller not initialized")
513
+ return
514
+ }
515
+
516
+ // If PiP is not possible, try pre-warming with placeholder frames
517
+ if !controller.isPictureInPicturePossible {
518
+ print("🖼️ [PiP] PiP not possible, pre-warming with placeholder frames...")
519
+ preWarmWithPlaceholder { [weak self, weak controller] success in
520
+ guard let self = self, let controller = controller else { return }
521
+
522
+ if success && controller.isPictureInPicturePossible {
523
+ controller.startPictureInPicture()
524
+ print("🖼️ [PiP] Start requested after pre-warming")
525
+ } else {
526
+ print("🖼️ [PiP] Cannot start - PiP still not possible after pre-warming")
527
+ self.delegate?.pictureInPictureDidFail(with: "PiP is not possible at this time. Make sure video frames are being fed.")
528
+ }
529
+ }
530
+ return
531
+ }
532
+
533
+ controller.startPictureInPicture()
534
+ print("🖼️ [PiP] Start requested")
535
+ }
536
+
537
+ /// Pre-warm the display layer with placeholder frames to make PiP possible
538
+ private func preWarmWithPlaceholder(completion: @escaping (Bool) -> Void) {
539
+ guard let pixelBuffer = placeholderPixelBuffer else {
540
+ completion(false)
541
+ return
542
+ }
543
+
544
+ // Enqueue several placeholder frames to prime the display layer
545
+ for _ in 0..<5 {
546
+ enqueuePlaceholderFrame()
547
+ }
548
+
549
+ // Wait a moment for frames to be processed, then check if PiP is possible
550
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
551
+ let isPossible = self?.pipController?.isPictureInPicturePossible ?? false
552
+ print("🖼️ [PiP] Pre-warm complete, isPictureInPicturePossible: \(isPossible)")
553
+ completion(isPossible)
554
+ }
555
+ }
556
+
557
+ /// Stop PiP manually
558
+ public func stop() {
559
+ // Ensure we're on the main thread
560
+ guard Thread.isMainThread else {
561
+ DispatchQueue.main.async { [weak self] in
562
+ self?.stop()
563
+ }
564
+ return
565
+ }
566
+
567
+ guard let controller = pipController, isActive else {
568
+ print("🖼️ [PiP] Cannot stop - PiP is not active")
569
+ return
570
+ }
571
+
572
+ controller.stopPictureInPicture()
573
+ print("🖼️ [PiP] Stop requested")
574
+ }
575
+
576
+ // MARK: - View Capture for Remote Streams (Fallback Method)
577
+
578
+ /// Start capturing frames from a UIView (fallback method when IVSImageDevice is not available)
579
+ /// This also sets up the Video Call API with the source view
580
+ /// NOTE: For IVSImageDevice frame capture, the IVSStageManager handles the callback setup
581
+ /// and calls enqueueFrame() directly. This method is kept as a fallback.
582
+ public func startViewCapture(from view: UIView) {
583
+ // Ensure we're on the main thread
584
+ guard Thread.isMainThread else {
585
+ DispatchQueue.main.async { [weak self] in
586
+ self?.startViewCapture(from: view)
587
+ }
588
+ return
589
+ }
590
+
591
+ stopViewCapture()
592
+
593
+ // IMPORTANT: Set up the Video Call API with this view as the source
594
+ // This must be the actual visible view showing video content
595
+ if let parentView = view.superview {
596
+ // Use the parent container view (ExpoIVSRemoteStreamView) as the source
597
+ setupWithSourceView(parentView)
598
+ } else {
599
+ // Use the view directly
600
+ setupWithSourceView(view)
601
+ }
602
+
603
+ captureTargetView = view
604
+ viewFrameCapture = ViewFrameCapture()
605
+ viewFrameCapture?.start(view: view) { [weak self] pixelBuffer in
606
+ self?.enqueueFrame(pixelBuffer)
607
+ }
608
+
609
+ print("🖼️ [PiP] Started view capture for remote stream (fallback method)")
610
+ }
611
+
612
+ /// Stop capturing frames from view
613
+ public func stopViewCapture() {
614
+ // Ensure we're on the main thread
615
+ guard Thread.isMainThread else {
616
+ DispatchQueue.main.async { [weak self] in
617
+ self?.stopViewCapture()
618
+ }
619
+ return
620
+ }
621
+
622
+ viewFrameCapture?.stop()
623
+ viewFrameCapture = nil
624
+ captureTargetView = nil
625
+ }
626
+
627
+ // MARK: - Frame Handling
628
+
629
+ /// Feed a video frame (CVPixelBuffer) to the PiP display
630
+ public func enqueueFrame(_ pixelBuffer: CVPixelBuffer) {
631
+ guard isEnabled, let displayLayer = sampleBufferDisplayLayer else {
632
+ return
633
+ }
634
+
635
+ // Track that we received a real frame
636
+ lastRealFrameTime = CFAbsoluteTimeGetCurrent()
637
+
638
+ // If we were using placeholder, switch back to real frames
639
+ if isUsingPlaceholder {
640
+ print("🖼️ [PiP] Real frames resumed, stopping placeholder")
641
+ stopPlaceholderFrameGeneration()
642
+ }
643
+
644
+ // Log first few frames and periodically for debugging
645
+ let shouldLog = enqueuedFrameCount < 3 || (enqueuedFrameCount % 300 == 0) // Log every 10 seconds at 30fps
646
+ if shouldLog {
647
+ let width = CVPixelBufferGetWidth(pixelBuffer)
648
+ let height = CVPixelBufferGetHeight(pixelBuffer)
649
+ print("🖼️ [PiP] Frame #\(enqueuedFrameCount): \(width)x\(height), layer status: \(displayLayer.status.rawValue), isActive: \(isActive)")
650
+ }
651
+
652
+ // Create CMSampleBuffer from CVPixelBuffer - do this synchronously
653
+ // to ensure the pixel buffer is not released before we use it
654
+ guard let sampleBuffer = self.createSampleBuffer(from: pixelBuffer) else {
655
+ if enqueuedFrameCount < 3 {
656
+ print("🖼️ [PiP] Failed to create sample buffer")
657
+ }
658
+ return
659
+ }
660
+
661
+ enqueuedFrameCount += 1
662
+
663
+ // Enqueue on background queue for performance
664
+ sampleBufferQueue.async { [weak displayLayer, weak self] in
665
+ guard let displayLayer = displayLayer else { return }
666
+
667
+ // Handle failed display layer
668
+ if displayLayer.status == .failed {
669
+ print("🖼️ [PiP] Display layer failed, flushing...")
670
+ displayLayer.flush()
671
+ // Reset start time for fresh timing after flush
672
+ self?.startTime = nil
673
+ }
674
+
675
+ displayLayer.enqueue(sampleBuffer)
676
+ }
677
+
678
+ // Log first successful enqueue
679
+ if enqueuedFrameCount == 1 {
680
+ print("🖼️ [PiP] First frame enqueued successfully")
681
+ }
682
+ }
683
+
684
+ private var enqueuedFrameCount: Int = 0
685
+
686
+ /// Feed a CMSampleBuffer directly to the PiP display
687
+ /// This extracts the pixel buffer and re-creates with proper timing for AVSampleBufferDisplayLayer
688
+ public func enqueueSampleBuffer(_ sampleBuffer: CMSampleBuffer) {
689
+ guard isEnabled, let displayLayer = sampleBufferDisplayLayer else {
690
+ return
691
+ }
692
+
693
+ // Extract pixel buffer from sample buffer and use our timing
694
+ guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
695
+ return
696
+ }
697
+
698
+ // Use enqueueFrame which has proper timing handling
699
+ enqueueFrame(pixelBuffer)
700
+ }
701
+
702
+ // MARK: - Private Helpers
703
+
704
+ private var startTime: CMTime?
705
+
706
+ private func createSampleBuffer(from pixelBuffer: CVPixelBuffer) -> CMSampleBuffer? {
707
+ var formatDescription: CMVideoFormatDescription?
708
+ let status = CMVideoFormatDescriptionCreateForImageBuffer(
709
+ allocator: kCFAllocatorDefault,
710
+ imageBuffer: pixelBuffer,
711
+ formatDescriptionOut: &formatDescription
712
+ )
713
+
714
+ guard status == noErr, let format = formatDescription else {
715
+ print("🖼️ [PiP] Failed to create format description")
716
+ return nil
717
+ }
718
+
719
+ // Use host time for live streaming - this ensures proper synchronization
720
+ let currentTime = CMClockGetTime(CMClockGetHostTimeClock())
721
+
722
+ // Initialize start time on first frame
723
+ if startTime == nil {
724
+ startTime = currentTime
725
+ }
726
+
727
+ // Calculate presentation time relative to start
728
+ let presentationTime = CMTimeSubtract(currentTime, startTime!)
729
+
730
+ var timingInfo = CMSampleTimingInfo(
731
+ duration: CMTime(value: 1, timescale: 30), // 1/30th second duration
732
+ presentationTimeStamp: presentationTime,
733
+ decodeTimeStamp: .invalid
734
+ )
735
+
736
+ var sampleBuffer: CMSampleBuffer?
737
+ let createStatus = CMSampleBufferCreateForImageBuffer(
738
+ allocator: kCFAllocatorDefault,
739
+ imageBuffer: pixelBuffer,
740
+ dataReady: true,
741
+ makeDataReadyCallback: nil,
742
+ refcon: nil,
743
+ formatDescription: format,
744
+ sampleTiming: &timingInfo,
745
+ sampleBufferOut: &sampleBuffer
746
+ )
747
+
748
+ guard createStatus == noErr else {
749
+ print("🖼️ [PiP] Failed to create sample buffer: \(createStatus)")
750
+ return nil
751
+ }
752
+
753
+ // Increment frame count
754
+ frameCount += 1
755
+
756
+ return sampleBuffer
757
+ }
758
+
759
+ // MARK: - Placeholder Frame Generation
760
+
761
+ /// Create a placeholder pixel buffer with "Broadcasting" text
762
+ private func createPlaceholderPixelBuffer() {
763
+ let width = 540
764
+ let height = 960
765
+
766
+ let attributes: [String: Any] = [
767
+ kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA,
768
+ kCVPixelBufferWidthKey as String: width,
769
+ kCVPixelBufferHeightKey as String: height,
770
+ kCVPixelBufferIOSurfacePropertiesKey as String: [:],
771
+ kCVPixelBufferCGImageCompatibilityKey as String: true,
772
+ kCVPixelBufferCGBitmapContextCompatibilityKey as String: true
773
+ ]
774
+
775
+ var pixelBuffer: CVPixelBuffer?
776
+ CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA, attributes as CFDictionary, &pixelBuffer)
777
+
778
+ guard let buffer = pixelBuffer else {
779
+ print("🖼️ [PiP] Failed to create placeholder pixel buffer")
780
+ return
781
+ }
782
+
783
+ CVPixelBufferLockBaseAddress(buffer, [])
784
+ defer { CVPixelBufferUnlockBaseAddress(buffer, []) }
785
+
786
+ guard let context = CGContext(
787
+ data: CVPixelBufferGetBaseAddress(buffer),
788
+ width: width,
789
+ height: height,
790
+ bitsPerComponent: 8,
791
+ bytesPerRow: CVPixelBufferGetBytesPerRow(buffer),
792
+ space: CGColorSpaceCreateDeviceRGB(),
793
+ bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue
794
+ ) else {
795
+ return
796
+ }
797
+
798
+ // Fill with dark background
799
+ context.setFillColor(UIColor(red: 0.1, green: 0.1, blue: 0.15, alpha: 1.0).cgColor)
800
+ context.fill(CGRect(x: 0, y: 0, width: width, height: height))
801
+
802
+ // Draw "Broadcasting" text
803
+ UIGraphicsPushContext(context)
804
+
805
+ // Flip context for proper text rendering
806
+ context.translateBy(x: 0, y: CGFloat(height))
807
+ context.scaleBy(x: 1, y: -1)
808
+
809
+ let paragraphStyle = NSMutableParagraphStyle()
810
+ paragraphStyle.alignment = .center
811
+
812
+ // Draw large red recording dot
813
+ let circleSize: CGFloat = 50
814
+ let circleRect = CGRect(x: (CGFloat(width) - circleSize) / 2, y: CGFloat(height) / 2 - 120, width: circleSize, height: circleSize)
815
+ context.setFillColor(UIColor.red.cgColor)
816
+ context.fillEllipse(in: circleRect)
817
+
818
+ // Draw "LIVE" text - large and bold
819
+ let liveText = "LIVE"
820
+ let liveAttributes: [NSAttributedString.Key: Any] = [
821
+ .font: UIFont.boldSystemFont(ofSize: 72),
822
+ .foregroundColor: UIColor.white,
823
+ .paragraphStyle: paragraphStyle
824
+ ]
825
+ let liveRect = CGRect(x: 0, y: CGFloat(height) / 2 - 40, width: CGFloat(width), height: 90)
826
+ liveText.draw(in: liveRect, withAttributes: liveAttributes)
827
+
828
+ // Draw "Broadcasting in progress" text
829
+ let subText = "Broadcasting in progress"
830
+ let subAttributes: [NSAttributedString.Key: Any] = [
831
+ .font: UIFont.systemFont(ofSize: 28),
832
+ .foregroundColor: UIColor.lightGray,
833
+ .paragraphStyle: paragraphStyle
834
+ ]
835
+ let subRect = CGRect(x: 0, y: CGFloat(height) / 2 + 60, width: CGFloat(width), height: 40)
836
+ subText.draw(in: subRect, withAttributes: subAttributes)
837
+
838
+ UIGraphicsPopContext()
839
+
840
+ self.placeholderPixelBuffer = buffer
841
+ print("🖼️ [PiP] Placeholder pixel buffer created")
842
+ }
843
+
844
+ /// Start generating placeholder frames to keep PiP alive
845
+ private func startPlaceholderFrameGeneration() {
846
+ guard placeholderTimer == nil else { return }
847
+
848
+ isUsingPlaceholder = true
849
+ print("🖼️ [PiP] Starting placeholder frame generation")
850
+
851
+ // Generate placeholder frames at 10fps to keep PiP alive
852
+ placeholderTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in
853
+ self?.enqueuePlaceholderFrame()
854
+ }
855
+ RunLoop.main.add(placeholderTimer!, forMode: .common)
856
+ }
857
+
858
+ /// Stop generating placeholder frames
859
+ private func stopPlaceholderFrameGeneration() {
860
+ placeholderTimer?.invalidate()
861
+ placeholderTimer = nil
862
+ isUsingPlaceholder = false
863
+ print("🖼️ [PiP] Stopped placeholder frame generation")
864
+ }
865
+
866
+ /// Enqueue a placeholder frame
867
+ private func enqueuePlaceholderFrame() {
868
+ guard isEnabled, let pixelBuffer = placeholderPixelBuffer, let displayLayer = sampleBufferDisplayLayer else {
869
+ return
870
+ }
871
+
872
+ guard let sampleBuffer = createSampleBuffer(from: pixelBuffer) else {
873
+ return
874
+ }
875
+
876
+ sampleBufferQueue.async { [weak displayLayer] in
877
+ guard let displayLayer = displayLayer else { return }
878
+
879
+ if displayLayer.status == .failed {
880
+ displayLayer.flush()
881
+ }
882
+
883
+ displayLayer.enqueue(sampleBuffer)
884
+ }
885
+ }
886
+
887
+ /// Check if we should switch to placeholder (called when real frames stop coming)
888
+ private func checkForPlaceholderSwitch() {
889
+ let timeSinceLastFrame = CFAbsoluteTimeGetCurrent() - lastRealFrameTime
890
+
891
+ if timeSinceLastFrame > placeholderTimeout && !isUsingPlaceholder && isActive {
892
+ print("🖼️ [PiP] No real frames for \(timeSinceLastFrame)s, switching to placeholder")
893
+ startPlaceholderFrameGeneration()
894
+ }
895
+ }
896
+
897
+ private func cleanup() {
898
+ // Ensure we're on the main thread for UI operations
899
+ guard Thread.isMainThread else {
900
+ DispatchQueue.main.sync { [weak self] in
901
+ self?.cleanup()
902
+ }
903
+ return
904
+ }
905
+
906
+ // Stop placeholder frame generation
907
+ stopPlaceholderFrameGeneration()
908
+
909
+ pipController?.stopPictureInPicture()
910
+ pipController = nil
911
+ pipContentSource = nil
912
+
913
+ // Clean up Video Call components
914
+ sampleBufferVideoCallView?.removeFromSuperview()
915
+ sampleBufferVideoCallView = nil
916
+ pipVideoCallViewController = nil
917
+
918
+ sampleBufferDisplayLayer?.flush()
919
+ sampleBufferDisplayLayer = nil
920
+
921
+ // Don't remove pipContainerView if it's the actual source view (not owned by us)
922
+ if pipContainerView != activeSourceView {
923
+ pipContainerView?.removeFromSuperview()
924
+ }
925
+ pipContainerView = nil
926
+ activeSourceView = nil
927
+
928
+ frameCount = 0
929
+ enqueuedFrameCount = 0
930
+ startTime = nil
931
+ isActive = false
932
+ }
933
+
934
+ // MARK: - App Lifecycle
935
+
936
+ @objc private func applicationWillResignActive() {
937
+ // NOTE: We no longer manually trigger PiP here because
938
+ // AVPictureInPictureController.canStartPictureInPictureAutomaticallyFromInline = true
939
+ // handles auto-entering PiP automatically when the app goes to background.
940
+ // Manual triggering was causing "Failed to start" errors due to race conditions
941
+ // with the system's built-in auto-enter mechanism.
942
+ print("🖼️ [PiP] App going to background (system handles auto-enter)")
943
+ }
944
+
945
+ @objc private func applicationDidBecomeActive() {
946
+ // Could be used for cleanup or state updates when app returns
947
+ print("🖼️ [PiP] App became active")
948
+ }
949
+
950
+ // MARK: - Public Getters
951
+
952
+ public var isPictureInPicturePossible: Bool {
953
+ return pipController?.isPictureInPicturePossible ?? false
954
+ }
955
+
956
+ public var currentSourceView: PiPOptions.PiPSourceView {
957
+ return options.sourceView
958
+ }
959
+ }
960
+
961
+ // MARK: - AVPictureInPictureControllerDelegate
962
+
963
+ @available(iOS 15.0, *)
964
+ extension IVSPictureInPictureController: AVPictureInPictureControllerDelegate {
965
+
966
+ public func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
967
+ print("🖼️ [PiP] Will start")
968
+ }
969
+
970
+ public func pictureInPictureControllerDidStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
971
+ isActive = true
972
+ lastRealFrameTime = CFAbsoluteTimeGetCurrent() // Reset timer
973
+
974
+ // Start monitoring for frame timeout to switch to placeholder
975
+ startFrameMonitoring()
976
+
977
+ print("🖼️ [PiP] Did start")
978
+ delegate?.pictureInPictureDidStart()
979
+ }
980
+
981
+ /// Start monitoring for frame timeout
982
+ private func startFrameMonitoring() {
983
+ // Check every 0.5 seconds if we should switch to placeholder
984
+ Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { [weak self] timer in
985
+ guard let self = self else {
986
+ timer.invalidate()
987
+ return
988
+ }
989
+
990
+ // Stop monitoring if PiP is no longer active
991
+ if !self.isActive {
992
+ timer.invalidate()
993
+ return
994
+ }
995
+
996
+ self.checkForPlaceholderSwitch()
997
+ }
998
+ }
999
+
1000
+ public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1001
+ print("🖼️ [PiP] Will stop")
1002
+ }
1003
+
1004
+ public func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
1005
+ isActive = false
1006
+
1007
+ // Stop placeholder frame generation
1008
+ stopPlaceholderFrameGeneration()
1009
+
1010
+ // Reset timing for next PiP session - this is crucial for re-enabling PiP
1011
+ startTime = nil
1012
+ frameCount = 0
1013
+ enqueuedFrameCount = 0
1014
+
1015
+ // Flush the display layer to prepare for fresh frames
1016
+ sampleBufferDisplayLayer?.flush()
1017
+
1018
+ // Pre-warm with a few placeholder frames so PiP can start again immediately
1019
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
1020
+ self?.enqueuePlaceholderFrame()
1021
+ self?.enqueuePlaceholderFrame()
1022
+ self?.enqueuePlaceholderFrame()
1023
+ }
1024
+
1025
+ print("🖼️ [PiP] Did stop - state reset for next session")
1026
+ delegate?.pictureInPictureDidStop()
1027
+ }
1028
+
1029
+ public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) {
1030
+ isActive = false
1031
+ print("🖼️ [PiP] Failed to start: \(error.localizedDescription)")
1032
+ delegate?.pictureInPictureDidFail(with: error.localizedDescription)
1033
+ }
1034
+
1035
+ public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
1036
+ print("🖼️ [PiP] Restore user interface requested")
1037
+ delegate?.pictureInPictureWillRestore()
1038
+ completionHandler(true)
1039
+ }
1040
+ }
1041
+
1042
+ // MARK: - AVPictureInPictureSampleBufferPlaybackDelegate
1043
+
1044
+ @available(iOS 15.0, *)
1045
+ extension IVSPictureInPictureController: AVPictureInPictureSampleBufferPlaybackDelegate {
1046
+
1047
+ public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, setPlaying playing: Bool) {
1048
+ // For live streaming, we ignore play/pause requests - always playing
1049
+ print("🖼️ [PiP] setPlaying: \(playing) (ignored - live stream)")
1050
+ }
1051
+
1052
+ public func pictureInPictureControllerTimeRangeForPlayback(_ pictureInPictureController: AVPictureInPictureController) -> CMTimeRange {
1053
+ // Return .invalid to indicate live streaming (no seek bar, no time display)
1054
+ // This tells the system there's no seekable content
1055
+ return .invalid
1056
+ }
1057
+
1058
+ public func pictureInPictureControllerIsPlaybackPaused(_ pictureInPictureController: AVPictureInPictureController) -> Bool {
1059
+ // Live streaming is never paused - always return false
1060
+ return false
1061
+ }
1062
+
1063
+ public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, didTransitionToRenderSize newRenderSize: CMVideoDimensions) {
1064
+ print("🖼️ [PiP] Transitioned to render size: \(newRenderSize.width)x\(newRenderSize.height)")
1065
+ }
1066
+
1067
+ public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, skipByInterval skipInterval: CMTime) async {
1068
+ // No seeking in live streams - this is a no-op for live content
1069
+ }
1070
+ }