├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ └── metrics.yml ├── .gitignore ├── .travis.yml ├── Basic-Video-Chat ├── Basic-Video-Chat.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Basic-Video-Chat.xcscheme ├── Basic-Video-Chat │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── README.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CallKit ├── CallKitDemo.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── CallKitDemo.xcscheme ├── CallKitDemo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── IconMask.imageset │ │ │ ├── Contents.json │ │ │ ├── IconMask-120.png │ │ │ ├── IconMask-40.png │ │ │ └── IconMask-80.png │ │ └── baseHeroMount.imageset │ │ │ ├── Contents.json │ │ │ ├── baseHeroMount.png │ │ │ ├── baseHeroMount@2x.png │ │ │ └── baseHeroMount@3x.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── CallKitDemo-Bridging-Header.h │ ├── CallKitDemo.entitlements │ ├── Info.plist │ ├── OTDefaultAudioDevice.h │ ├── OTDefaultAudioDevice.m │ ├── ProviderDelegate.swift │ ├── Ringtone.caf │ ├── SpeakerboxCall.swift │ ├── SpeakerboxCallManager.swift │ └── ViewController.swift ├── LICENSE ├── Podfile ├── README.md ├── call.jpeg ├── demo.png ├── lock1.png ├── lock2.png ├── tokbox-logo.png ├── unlock1.png └── unlock2.png ├── Custom-Audio-Driver ├── Custom-Audio-Driver.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Custom-Audio-Driver.xcscheme ├── Custom-Audio-Driver │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── DefaultAudioDevice.swift │ ├── Info.plist │ └── ViewController.swift ├── Default-568h@2x.png ├── Podfile └── README.md ├── Custom-Video-Driver ├── Custom-Video-Driver.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Custom-Video-Driver.xcscheme ├── Lets-Build-OTPublisher │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── EAGLVideoRenderer.swift │ ├── ExampleVideoCapture.swift │ ├── ExampleVideoRender.swift │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── README.md ├── E2EE-Video-Chat ├── Basic-Video-Chat.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Basic-Video-Chat.xcscheme ├── Basic-Video-Chat │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── README.md ├── FrameMetadata ├── FrameMetadata.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── FrameMetadata.xcscheme ├── FrameMetadata │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── README.md ├── LICENSE ├── Live-Photo-Capture ├── Live-Photo-Capture.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Live-Photo-Capture.xcscheme ├── Live-Photo-Capture │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ExamplePhotoVideoCapture.swift │ ├── Info.plist │ └── ViewController.swift ├── Podfile └── README.md ├── Media-Transformers ├── CHANGELOG.md ├── Media-Transformers.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Video-Transformers.xcscheme ├── Media-Transformers │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.swift │ └── Vonage_Logo.png ├── Podfile └── README.md ├── Multiparty-UICollectionView ├── Multiparty-UICollectionView.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Multiparty-UICollectionView.xcscheme ├── Multiparty-UICollectionView │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ChatViewController.swift │ ├── Info.plist │ └── MultipartyLayout.swift ├── Podfile └── README.md ├── OpenTokSDKVersion.rb ├── Picture-In-Picture ├── Lets-Build-OTPublisher │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── ExampleVideoRender.swift │ ├── Info.plist │ ├── SampleBufferVideoCallView.swift │ └── ViewController.swift ├── Picture-In-Picture.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Picture-In-Picture.xcscheme ├── Podfile └── README.md ├── README.md ├── Screen-Sharing ├── Podfile ├── README.md ├── Screen-Sharing.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Screen-Sharing.xcscheme └── Screen-Sharing │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── ScreenCapturer.swift │ ├── ViewController.swift │ └── logo_opentok_registered.png ├── Signals ├── Podfile ├── README.md ├── Signals.xcodeproj │ └── project.pbxproj └── Signals │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json │ ├── ContentView.swift │ ├── FormView.swift │ ├── MessagesView.swift │ ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json │ ├── SignalsApp.swift │ └── VonageVideoSDK.swift ├── Simple-Multiparty ├── Podfile ├── README.md ├── Simple-Multiparty.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── Simple-Multiparty.xcscheme └── Simple-Multiparty │ ├── AppDelegate.swift │ ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Subscriber-Speaker-35.imageset │ │ ├── Contents.json │ │ ├── Subscriber-Speaker-35.png │ │ └── Subscriber-Speaker-35@2x.png │ ├── Subscriber-Speaker-Mute-35.imageset │ │ ├── Contents.json │ │ ├── Subscriber-Speaker-Mute-35.png │ │ └── Subscriber-Speaker-Mute-35@2x.png │ ├── TB Bug-30.imageset │ │ ├── Contents.json │ │ ├── TB Bug-30.png │ │ └── TB Bug-30@2x.png │ ├── camera-switch_black-33.imageset │ │ ├── Contents.json │ │ ├── camera-switch_black-33.png │ │ └── camera-switch_black-33@2x.png │ ├── camera_switch-33.imageset │ │ ├── Contents.json │ │ ├── camera_switch-33.png │ │ └── camera_switch-33@2x.png │ ├── icon_arrowLeft_disabled-28.imageset │ │ ├── Contents.json │ │ ├── icon_arrowLeft_disabled-28.png │ │ └── icon_arrowLeft_disabled-28@2x.png │ ├── icon_arrowLeft_enabled-28.imageset │ │ ├── Contents.json │ │ ├── icon_arrowLeft_enabled-28.png │ │ └── icon_arrowLeft_enabled-28@2x.png │ ├── icon_arrowRight_disabled-28.imageset │ │ ├── Contents.json │ │ ├── icon_arrowRight_disabled-28.png │ │ └── icon_arrowRight_disabled-28@2x.png │ ├── icon_arrowRight_enabled-28.imageset │ │ ├── Contents.json │ │ ├── icon_arrowRight_enabled-28.png │ │ └── icon_arrowRight_enabled-28@2x.png │ ├── mic-24.imageset │ │ ├── Contents.json │ │ ├── mic-24.png │ │ └── mic-24@2x.png │ ├── mic_muted-24.imageset │ │ ├── Contents.json │ │ ├── mic_muted-24.png │ │ └── mic_muted-24@2x.png │ └── mic_receiving_data-35.imageset │ │ ├── Contents.json │ │ ├── mic_receiving_data-35.png │ │ └── mic_receiving_data-35@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ └── ViewController.swift └── travis_build.sh /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Device (please compete the following information):** 23 | - sessionId, if applicable: 24 | - iOS SDK version: 25 | - OS and version: 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/workflows/metrics.yml: -------------------------------------------------------------------------------- 1 | name: Aggregit 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | recordMetrics: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: michaeljolley/aggregit@v1 12 | with: 13 | githubToken: ${{ secrets.GITHUB_TOKEN }} 14 | project_id: ${{ secrets.project_id }} 15 | private_key: ${{ secrets.private_key }} 16 | client_email: ${{ secrets.client_email }} 17 | firebaseDbUrl: ${{ secrets.firebaseDbUrl }} 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | OpenTok.framework/ 2 | OpenTok.framework 3 | 4 | # Xcode 5 | .DS_Store 6 | */build/* 7 | *.pbxuser 8 | !default.pbxuser 9 | *.mode1v3 10 | !default.mode1v3 11 | *.mode2v3 12 | !default.mode2v3 13 | *.perspectivev3 14 | !default.perspectivev3 15 | xcuserdata 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | .idea/ 20 | *.hmap 21 | *.xccheckout 22 | 23 | #CocoaPods 24 | Pods 25 | Podfile.lock 26 | *.xcworkspacedata 27 | *.xcworkspace 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode11.7 3 | before_install: 4 | - pod repo update > /dev/null 5 | script: ./travis_build.sh 6 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat.xcodeproj/xcshareddata/xcschemes/Basic-Video-Chat.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Hello-World 4 | // 5 | // Created by Roberto Perez Cubero on 11/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Basic-Video-Chat/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSCameraUsageDescription 40 | 41 | NSMicrophoneUsageDescription 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Basic-Video-Chat/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Basic-Video-Chat' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Basic-Video-Chat/README.md: -------------------------------------------------------------------------------- 1 | Basic Video Chat Sample App 2 | =============================== 3 | 4 | The Basic-Video-Chat app is a very simple application meant to get a new developer 5 | started using the OpenTok iOS SDK. 6 | 7 | Quick Start 8 | ----------- 9 | 10 | To use this application: 11 | 12 | 1. Follow the instructions in the [Quick Start](../README.md#quick-start) 13 | section of the main README file for this repository. 14 | 15 | Among other things, you need to set values for the `kApiKey`, `kSessionId`, 16 | and `kToken` constants. See [Obtaining OpenTok 17 | Credentials](../README.md#obtaining-opentok-credentials) 18 | in the main README file for the repository. 19 | 20 | 2. When you run the application, it connects to an OpenTok session and 21 | publishes an audio-video stream from your device to the session. 22 | 23 | 3. Run the app on a second client. You can do this by deploying the app to an 24 | iOS device and testing it in the simulator at the same time. Or you can use 25 | the browser_demo.html file to connect in a browser (see the following 26 | section). 27 | 28 | When the second client connects, it also publishes a stream to the session, 29 | and both clients subscribe to (view) each other’s stream. 30 | 31 | Application Notes 32 | ----------------- 33 | 34 | * Follow the code from the `ViewController.viewDidLoad(_:)` method through 35 | to the OpenTok callbacks to see how streams are created and handled in 36 | the OpenTok iOS SDK. 37 | 38 | * By default, all delegate methods from classes in the OpenTok iOS SDK are 39 | invoked on the main queue. This means that you can directly modify the view 40 | hierarchy from inside the callback, without any asynchronous callouts. 41 | 42 | * When the main view loads, the ViewController calls the 43 | `OTSession.initWithApiKey(_:, sessionId:,delegate:)` method to initialize 44 | a Session object. The app then calls the 45 | `OTSession.connectWithToken(_:, error:)` to connect to the session. The 46 | `OTSessionDelegate.sessionDidConnect(_:)` message is sent when the app 47 | connects to the OpenTok session. 48 | 49 | * The `doPublish()` method of the app initializes a publisher and passes it 50 | into the `OTSession.publish(_:,error:)` method. This publishes an 51 | audio-video stream to the session. 52 | 53 | * The `OTSessionDelegate.session(_:,streamCreated:)` message is sent when 54 | a new stream is created in the session. In response, the 55 | method calls `OTSubscriber(stream:,delegate:)`, 56 | passing in the OTStream object. This causes the app to subscribe to the 57 | stream. 58 | 59 | To add a second publisher (which will display as a subscriber in your emulator), either run the app a second time in an iOS device or use the OpenTok Playground to connect to the session in a supported web browser (Chrome, Firefox, or Internet Explorer 10-11) by following the steps below: 60 | 61 | 1. Go to [OpenTok Playground](https://tokbox.com/developer/tools/playground) (must be logged into your [Account](https://tokbox.com/account)) 62 | 2. Select the **Join existing session** tab 63 | 3. Copy the session ID you used in your project file and paste it in the **Session ID** input field 64 | 4. Click **Join Session** 65 | 5. On the next screen, click **Connect**, then click **Publish Stream** 66 | 6. You can adjust the Publisher options (not required), then click **Continue** to connect and begin publishing and subscribing 67 | 68 | 69 | Configuration Notes 70 | ------------------- 71 | 72 | * You can test in the iOS Simulator or on a supported iOS device. However, the 73 | XCode iOS Simulator does not provide access to the camera. When running in 74 | the iOS Simulator, an OTPublisher object uses a demo video instead of the 75 | camera. 76 | 77 | [1]: https://tokbox.com/account/#/ 78 | [2]: https://tokbox.com/developer/sdks/server/ 79 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | For anyone looking to get involved to this project, we are glad to hear from you. Here are a few types of contributions 4 | that we would be interested in hearing about. 5 | 6 | * Bug fixes 7 | - If you find a bug, please first report it using Github Issues. 8 | - Issues that have already been identified as a bug will be labelled `bug`. 9 | - If you'd like to submit a fix for a bug, send a Pull Request from your own fork and mention the Issue number. 10 | * New Features 11 | - If you'd like to accomplish something in the library that it doesn't already do, describe the problem in a new 12 | Github Issue. 13 | - Issues that have been identified as a feature request will be labelled `enhancement`. 14 | - If you'd like to implement the new feature, please wait for feedback from the project maintainers before spending 15 | too much time writing the code. In some cases, `enhancement`s may not align well with the project objectives at 16 | the time. 17 | * Documentation and Miscellaneous 18 | - If you think the documentation could be clearer, you've got an alternative 19 | implementation of something that may have more advantages, or any other change we would still be glad hear about 20 | it. 21 | - If its a trivial change, go ahead and send a Pull Request with the changes you have in mind 22 | - If not, open a Github Issue to discuss the idea first. 23 | 24 | ## Requirements 25 | 26 | For a contribution to be accepted: 27 | 28 | * Code must follow existing styling conventions 29 | * Commit messages must be descriptive. Related issues should be mentioned by number. 30 | 31 | If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still 32 | continue to add more commits to the branch you have sent the Pull Request from. 33 | 34 | ## How To 35 | 36 | 1. Fork this repository on GitHub. 37 | 1. Clone/fetch your fork to your local development machine. 38 | 1. Create a new branch (e.g. `issue-12`, `feat.add_foo`, etc) and check it out. 39 | 1. Make your changes and commit them. 40 | 1. Push your new branch to your fork. (e.g. `git push myname issue-12`) 41 | 1. Open a Pull Request from your new branch to the original fork's `master` branch. -------------------------------------------------------------------------------- /CallKit/CallKitDemo.xcodeproj/xcshareddata/xcschemes/CallKitDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // CallKitDemo 4 | // 5 | // Created by Xi Huang on 6/5/17. 6 | // Copyright © 2017 Tokbox, Inc. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PushKit 11 | import CallKit 12 | import OpenTok 13 | 14 | let apiKey = "" 15 | let sessionId = "" 16 | let token = "" 17 | 18 | @UIApplicationMain 19 | class AppDelegate: UIResponder, UIApplicationDelegate { 20 | 21 | var window: UIWindow? 22 | 23 | let pushRegistry = PKPushRegistry(queue: DispatchQueue.main) 24 | let callManager = SpeakerboxCallManager() 25 | var providerDelegate: ProviderDelegate? 26 | 27 | // Trigger VoIP registration on launch 28 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { 29 | 30 | 31 | providerDelegate = ProviderDelegate(callManager: callManager) 32 | 33 | pushRegistry.delegate = self 34 | pushRegistry.desiredPushTypes = [.voIP] 35 | 36 | return true 37 | } 38 | } 39 | 40 | extension AppDelegate: PKPushRegistryDelegate { 41 | 42 | func pushRegistry(_ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) { 43 | print("\(#function) voip token: \(credentials.token)") 44 | 45 | let deviceToken = credentials.token.reduce("", {$0 + String(format: "%02X", $1) }) 46 | print("\(#function) token is: \(deviceToken)") 47 | } 48 | 49 | func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) { 50 | 51 | print("\(#function) incoming voip notfication: \(payload.dictionaryPayload)") 52 | if let uuidString = payload.dictionaryPayload["UUID"] as? String, 53 | let handle = payload.dictionaryPayload["handle"] as? String, 54 | let uuid = UUID(uuidString: uuidString) { 55 | 56 | OTAudioDeviceManager.setAudioDevice(OTDefaultAudioDevice.sharedInstance()) 57 | 58 | // display incoming call UI when receiving incoming voip notification 59 | let backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: nil) 60 | self.displayIncomingCall(uuid: uuid, handle: handle, hasVideo: false) { _ in 61 | UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier) 62 | } 63 | } 64 | } 65 | 66 | func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) { 67 | print("\(#function) token invalidated") 68 | } 69 | 70 | /// Display the incoming call to the user 71 | func displayIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)? = nil) { 72 | providerDelegate?.reportIncomingCall(uuid: uuid, handle: handle, hasVideo: hasVideo, completion: completion) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "IconMask-40.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "IconMask-80.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "IconMask-120.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-120.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-40.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/IconMask.imageset/IconMask-80.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "baseHeroMount.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x", 11 | "filename" : "baseHeroMount@2x.png" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x", 16 | "filename" : "baseHeroMount@3x.png" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "zeplin", 21 | "version" : "1" 22 | } 23 | } -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount@2x.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Assets.xcassets/baseHeroMount.imageset/baseHeroMount@3x.png -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/CallKitDemo-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "OTDefaultAudioDevice.h" 6 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/CallKitDemo.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | 9 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleURLTypes 20 | 21 | 22 | CFBundleTypeRole 23 | Editor 24 | CFBundleURLName 25 | $(PRODUCT_BUNDLE_IDENTIFIER).url-scheme.dial 26 | CFBundleURLSchemes 27 | 28 | callkitdemo 29 | 30 | 31 | 32 | CFBundleVersion 33 | 1 34 | LSRequiresIPhoneOS 35 | 36 | NSCameraUsageDescription 37 | $(PRODUCT_NAME) uses camera 38 | NSMicrophoneUsageDescription 39 | $(PRODUCT_NAME) uses microphone 40 | UIBackgroundModes 41 | 42 | audio 43 | fetch 44 | remote-notification 45 | voip 46 | 47 | UILaunchStoryboardName 48 | LaunchScreen 49 | UIMainStoryboardFile 50 | Main 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/OTDefaultAudioDevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // OTAudioDeviceIOSDefault.h 3 | // 4 | // Copyright (c) 2014 TokBox, Inc. All rights reserved. 5 | // 6 | 7 | #import 8 | #import 9 | 10 | #define kMixerInputBusCount 2 11 | #define kOutputBus 0 12 | #define kInputBus 1 13 | 14 | #define AUDIO_DEVICE_HEADSET @"AudioSessionManagerDevice_Headset" 15 | #define AUDIO_DEVICE_BLUETOOTH @"AudioSessionManagerDevice_Bluetooth" 16 | #define AUDIO_DEVICE_SPEAKER @"AudioSessionManagerDevice_Speaker" 17 | 18 | 19 | @interface OTDefaultAudioDevice : NSObject 20 | { 21 | AudioStreamBasicDescription stream_format; 22 | } 23 | 24 | /** 25 | Returns YES if a wired headset is available. 26 | */ 27 | @property (nonatomic, readonly) BOOL headsetDeviceAvailable; 28 | 29 | /** 30 | Returns YES if a bluetooth device is available. 31 | */ 32 | @property (nonatomic, readonly) BOOL bluetoothDeviceAvailable; 33 | 34 | - (BOOL)setAudioBus:(id)audioBus; 35 | 36 | /** 37 | * Audio device lifecycle should live for the duration of the process, and 38 | * needs to be set before OTSession is initialized. 39 | * 40 | * It is not recommended to initialize unique audio device instances. 41 | */ 42 | + (instancetype)sharedInstance; 43 | + (instancetype)sharedInstanceWithAudioSession:(AVAudioSession *)audioSession; 44 | 45 | - (OTAudioFormat*)captureFormat; 46 | - (OTAudioFormat*)renderFormat; 47 | 48 | - (BOOL)renderingIsAvailable; 49 | - (BOOL)initializeRendering; 50 | - (BOOL)renderingIsInitialized; 51 | - (BOOL)captureIsAvailable; 52 | - (BOOL)initializeCapture; 53 | - (BOOL)captureIsInitialized; 54 | 55 | - (BOOL)startRendering; 56 | - (BOOL)stopRendering; 57 | - (BOOL)isRendering; 58 | - (BOOL)startCapture; 59 | - (BOOL)stopCapture; 60 | - (BOOL)isCapturing; 61 | 62 | - (uint16_t)estimatedRenderDelay; 63 | - (uint16_t)estimatedCaptureDelay; 64 | 65 | //desired Audio Route can be bluetooth and headset. 66 | //bluetooth has higher priority of all, next headset, next speaker 67 | - (BOOL)configureAudioSessionWithDesiredAudioRoute:(NSString*)desiredAudioRoute; 68 | - (BOOL)detectCurrentRoute; 69 | 70 | - (BOOL)setPlayOutRenderCallback:(AudioUnit)unit; 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /CallKit/CallKitDemo/Ringtone.caf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/CallKitDemo/Ringtone.caf -------------------------------------------------------------------------------- /CallKit/CallKitDemo/SpeakerboxCallManager.swift: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2016 Apple Inc. All Rights Reserved. 3 | See LICENSE.txt for this sample’s licensing information 4 | 5 | Abstract: 6 | Manager of SpeakerboxCalls, which demonstrates using a CallKit CXCallController to request actions on calls 7 | */ 8 | 9 | import UIKit 10 | import CallKit 11 | import OpenTok 12 | 13 | final class SpeakerboxCallManager: NSObject { 14 | 15 | enum Call: String { 16 | case start = "startCall" 17 | case end = "endCall" 18 | case hold = "holdCall" 19 | } 20 | 21 | let callController = CXCallController() 22 | 23 | // MARK: Actions 24 | 25 | func startCall(handle: String, video: Bool = false) { 26 | let handle = CXHandle(type: .phoneNumber, value: handle) 27 | let startCallAction = CXStartCallAction(call: UUID(), handle: handle) 28 | 29 | startCallAction.isVideo = video 30 | 31 | let transaction = CXTransaction() 32 | transaction.addAction(startCallAction) 33 | 34 | requestTransaction(transaction, action: Call.start.rawValue) 35 | } 36 | 37 | func end(call: SpeakerboxCall) { 38 | let endCallAction = CXEndCallAction(call: call.uuid) 39 | let transaction = CXTransaction() 40 | transaction.addAction(endCallAction) 41 | 42 | requestTransaction(transaction, action: Call.end.rawValue) 43 | } 44 | 45 | func setHeld(call: SpeakerboxCall, onHold: Bool) { 46 | let setHeldCallAction = CXSetHeldCallAction(call: call.uuid, onHold: onHold) 47 | let transaction = CXTransaction() 48 | transaction.addAction(setHeldCallAction) 49 | 50 | requestTransaction(transaction, action: Call.hold.rawValue) 51 | } 52 | 53 | private func requestTransaction(_ transaction: CXTransaction, action: String = "") { 54 | callController.request(transaction) { error in 55 | if let error = error { 56 | print("Error requesting transaction: \(error)") 57 | } else { 58 | print("Requested transaction \(action) successfully") 59 | } 60 | } 61 | } 62 | 63 | // MARK: Call Management 64 | 65 | static let CallsChangedNotification = Notification.Name("CallManagerCallsChangedNotification") 66 | 67 | private(set) var calls = [SpeakerboxCall]() 68 | 69 | func callWithUUID(uuid: UUID) -> SpeakerboxCall? { 70 | guard let index = calls.index(where: { $0.uuid == uuid }) else { 71 | return nil 72 | } 73 | return calls[index] 74 | } 75 | 76 | func addCall(_ call: SpeakerboxCall) { 77 | calls.append(call) 78 | 79 | call.stateDidChange = { [weak self] in 80 | self?.postCallsChangedNotification() 81 | } 82 | 83 | postCallsChangedNotification(userInfo: ["action": Call.start.rawValue]) 84 | } 85 | 86 | func removeCall(_ call: SpeakerboxCall) { 87 | calls = calls.filter {$0 === call} 88 | postCallsChangedNotification(userInfo: ["action": Call.end.rawValue]) 89 | } 90 | 91 | func removeAllCalls() { 92 | calls.removeAll() 93 | postCallsChangedNotification(userInfo: ["action": Call.end.rawValue]) 94 | } 95 | 96 | private func postCallsChangedNotification(userInfo: [String: Any]? = nil) { 97 | NotificationCenter.default.post(name: type(of: self).CallsChangedNotification, object: self, userInfo: userInfo) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /CallKit/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 OpenTok 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CallKit/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'CallKitDemo' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /CallKit/call.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/call.jpeg -------------------------------------------------------------------------------- /CallKit/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/demo.png -------------------------------------------------------------------------------- /CallKit/lock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/lock1.png -------------------------------------------------------------------------------- /CallKit/lock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/lock2.png -------------------------------------------------------------------------------- /CallKit/tokbox-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/tokbox-logo.png -------------------------------------------------------------------------------- /CallKit/unlock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/unlock1.png -------------------------------------------------------------------------------- /CallKit/unlock2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/CallKit/unlock2.png -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver.xcodeproj/xcshareddata/xcschemes/Custom-Audio-Driver.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 4.Custom-Audio-Driver 4 | // 5 | // Created by Roberto Perez Cubero on 21/09/2016. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | func applicationWillResignActive(_ application: UIApplication) { 21 | } 22 | 23 | func applicationDidEnterBackground(_ application: UIApplication) { 24 | } 25 | 26 | func applicationWillEnterForeground(_ application: UIApplication) { 27 | } 28 | 29 | func applicationDidBecomeActive(_ application: UIApplication) { 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/Custom-Audio-Driver/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | NSCameraUsageDescription 38 | 39 | NSMicrophoneUsageDescription 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Custom-Audio-Driver/Default-568h@2x.png -------------------------------------------------------------------------------- /Custom-Audio-Driver/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Custom-Audio-Driver' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Custom-Audio-Driver/README.md: -------------------------------------------------------------------------------- 1 | Custom Audio Driver Sample App 2 | ================================ 3 | 4 | This project implements a controller nearly identical to the hello world sample. 5 | The entry point of new content is during the controllers `viewDidLoad()` 6 | callback, where we set up an audio device before initializing our first OpenTok 7 | object. It is important to note that audio device setup *must* occur before any 8 | instance of OTSession or OTPublisher is initialized: 9 | 10 | ```swift 11 | let customAudioDevice = DefaultAudioDevice.sharedInstance 12 | OTAudioDeviceManager.setAudioDevice(customAudioDevice) 13 | ``` 14 | 15 | `DefaultAudioDevice` is a copy of the default device driver used in 16 | the OpenTok iOS SDK. If no audio device is set prior to the first instantiation 17 | of OTSession, the default driver will be used. A common reason for a developer 18 | to look at this sample is to debug audio issues in their application. This is 19 | also a good entry point for managing more complicated audio routing and 20 | customization of handling audio events on the device during the lifecycle of 21 | your app. 22 | 23 | *Important:* To use this application, follow the instructions in the 24 | [Quick Start](../README.md#quick-start) section of the main README file 25 | for this repository. 26 | 27 | Application Notes 28 | ----------------- 29 | 30 | * `recording_cb` and `playout_cb` are the two main operator functions in the 31 | audio graph once initialization has occurred and the session is active. 32 | Setting breakpoints on these functions can be useful to verify that the audio 33 | graph is indeed running and producing/consuming audio. 34 | 35 | * The callbacks `onRouteChangeEvent:` and `onInteruptionEvent:` are hooked into 36 | the system events and listen for important audio events that developers may 37 | wish to handle properly in different contexts of their app. 38 | 39 | * There are known constraints to sample rates and formats inherited from both 40 | the WebRTC runtime and iOS. The rates chosen in the sample audio device are 41 | known working configurations, but not everything will work. The simulator 42 | needs to run at 44.1 kHz. Devices should stick between 8-32 kHz. This example 43 | sticks to using unsigned 16-bit integers as the sample format. Your mileage 44 | may vary with adjusting any of these. 45 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Custom-Video-Driver.xcodeproj/xcshareddata/xcschemes/Custom-Video-Driver.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Lets-Build-OTPublisher/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Lets-Build-OTPublisher 4 | // 5 | // Created by Roberto Perez Cubero on 11/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | } 24 | 25 | func applicationDidEnterBackground(_ application: UIApplication) { 26 | } 27 | 28 | func applicationWillEnterForeground(_ application: UIApplication) { 29 | } 30 | 31 | func applicationDidBecomeActive(_ application: UIApplication) { 32 | } 33 | 34 | func applicationWillTerminate(_ application: UIApplication) { 35 | } 36 | 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Lets-Build-OTPublisher/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Custom-Video-Driver/Lets-Build-OTPublisher/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Lets-Build-OTPublisher/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Lets-Build-OTPublisher/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSCameraUsageDescription 40 | 41 | NSMicrophoneUsageDescription 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Custom-Video-Driver/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Custom-Video-Driver' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Custom-Video-Driver/README.md: -------------------------------------------------------------------------------- 1 | Custom Video Driver Sample App 2 | ================================== 3 | 4 | This project uses the custom video driver features in the OpenTok iOS SDK. 5 | By the end of a code review, you should have a basic understanding of the 6 | internals of the video capture and render API, as well as how to start 7 | building your own extensions to the core OTPublisherKit and OTSubscriberKit 8 | classes. 9 | 10 | Note that this sample application is not supported in the XCode iOS Simulator 11 | because the custom video capturer needs to acquire video from an iOS device 12 | camera. 13 | 14 | *Important:* To use this application, follow the instructions in the 15 | [Quick Start](../README.md#quick-start) section of the main README file 16 | for this repository. 17 | 18 | ### ExampleVideoRender 19 | 20 | Both OTSubscriber and OTPublisher need an instance supporting the 21 | `OTVideoRender` protocol to display video contents. In short, the instance 22 | ID that is set to the `videoRender` property will receive YUV frames (I420) as 23 | they are captured (publisher) or as they are received (subscriber). Note that, 24 | although the publisher's `OTVideoCapture` interface can process multiple pixel 25 | formats, the images passed through the rendering callback will always be in the 26 | I420 YUV format. 27 | 28 | ExampleVideoRender is a simplified swift version of the default video renderer 29 | for the OpenTok iOS SDK. It is borrowed and modified from a series of classes in 30 | Google's [WebRTC][1] project. 31 | 32 | In this example we wire a video renderer to the publisher's rendering 33 | callback. An alternative approach for developers using video from the camera 34 | with AVFoundation is to wire [AVCaptureVideoPreviewLayer][2] directly to the 35 | capture class and leave the `OTPublisherKit.videoRender` property nil. 36 | 37 | To see ExampleVideoRender in action, put a breakpoint on `renderVideoFrame:`. 38 | You will see this method called for every video frame that is presented to the 39 | rendering endpoint by the OpenTok iOS SDK. 40 | 41 | ### ExampleVideoCapture 42 | 43 | This class interfaces with AVFoundation to provide video capture support from 44 | the device's camera hardware. By implementing the OTVideoCapture interface, it 45 | can be used as a video capture endpoint OTPublisher to provide video for 46 | publishing. 47 | 48 | To see ExampleVideoCapture in action, put a breakpoint on 49 | `captureOutput:didOutputSampleBuffer:fromConnection:`. This method is invoked by 50 | AVFoundation for every frame that is output from the camera capture session. 51 | After some processing, the video capture invokes its own 52 | `OTVideoCaptureConsumer` with the captured frame. Note the consumer is set by 53 | the OpenTok iOS SDK during instantiation of the publisher. 54 | 55 | 56 | Putting it all together 57 | ----------------------- 58 | 59 | The [ViewController](Lets-Build-OTPublisher/ViewController.m) for this 60 | application is a near-identical clone of the previous, with text substitutions 61 | for our newly-minted example publisher and subscriber classes. Notice how a 62 | majority of the calls made into the OpenTok iOS SDK classes are declared 63 | on the core classes, OTPublisherKit and OTSubscriberKit. Extending those core 64 | classes as is done in this example is as simple as defining a few simple 65 | interfaces and plugging everything in at runtime. We hope that this new 66 | class hierarchy will give you some ideas for how to extend the core 67 | functionality of the OpenTok iOS SDK to meet your application needs. 68 | 69 | 70 | [1]: https://chromium.googlesource.com/external/webrtc/+/master/talk/app/webrtc/objc/ 71 | [2]: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureVideoPreviewLayer_Class/Reference/Reference.html 72 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat.xcodeproj/xcshareddata/xcschemes/Basic-Video-Chat.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Hello-World 4 | // 5 | // Created by Roberto Perez Cubero on 11/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Basic-Video-Chat/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSCameraUsageDescription 40 | 41 | NSMicrophoneUsageDescription 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Basic-Video-Chat' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /E2EE-Video-Chat/README.md: -------------------------------------------------------------------------------- 1 | E2EE Basic Video Chat Sample App 2 | =============================== 3 | 4 | The E2EE Basic-Video-Chat app is a very simple application meant to get a new developer 5 | started using the OpenTok iOS SDK and end to end encryption. 6 | 7 | Quick Start 8 | ----------- 9 | 10 | To use this application: 11 | 12 | 1. Follow the instructions in the [Quick Start](../README.md#quick-start) 13 | section of the main README file for this repository. 14 | 15 | Among other things, you need to set values for the `kApiKey`, `kSessionId`, 16 | `kToken`, and `kEncryptionSecret` constants. See [Obtaining OpenTok 17 | Credentials](../README.md#obtaining-opentok-credentials) 18 | in the main README file for the repository. 19 | 20 | 2. To create an E2EE connection you must first enable this functionality server side. 21 | You enable end-to-end encryption when you create a session using the REST API. 22 | Set the e2ee property to true. See the [E2EE](https://tokbox.com/developer/guides/end-to-end-encryption/#server_side) guide. 23 | 24 | 3. When you run the application, it connects to an OpenTok session and 25 | publishes an audio-video stream from your device to the session. 26 | 27 | 4. Run the app on a second client. You can do this by deploying the app to an 28 | iOS device and testing it in the simulator at the same time. Or you can use 29 | the browser_demo.html file to connect in a browser (see the following 30 | section). 31 | 32 | When the second client connects, it also publishes a stream to the session, 33 | and both clients subscribe to (view) each other’s stream. 34 | 35 | Application Notes 36 | ----------------- 37 | 38 | * Follow the code from the `ViewController.viewDidLoad(_:)` method through 39 | to the OpenTok callbacks to see how streams are created and handled in 40 | the OpenTok iOS SDK. 41 | 42 | * By default, all delegate methods from classes in the OpenTok iOS SDK are 43 | invoked on the main queue. This means that you can directly modify the view 44 | hierarchy from inside the callback, without any asynchronous callouts. 45 | 46 | * When the main view loads, the ViewController calls the `OTSession.setEncryptionSecret(_:, error:)` 47 | method to set the encryption secret. Then the 48 | `OTSession.initWithApiKey(_:, sessionId:,delegate:)` method to initialize 49 | a Session object. The app then calls the 50 | `OTSession.connectWithToken(_:, error:)` to connect to the session. The 51 | `OTSessionDelegate.sessionDidConnect(_:)` message is sent when the app 52 | connects to the OpenTok session. 53 | 54 | * The `doPublish()` method of the app initializes a publisher and passes it 55 | into the `OTSession.publish(_:,error:)` method. This publishes an 56 | audio-video stream to the session. 57 | 58 | * The `OTSessionDelegate.session(_:,streamCreated:)` message is sent when 59 | a new stream is created in the session. In response, the 60 | method calls `OTSubscriber(stream:,delegate:)`, 61 | passing in the OTStream object. This causes the app to subscribe to the 62 | stream. 63 | 64 | 65 | Configuration Notes 66 | ------------------- 67 | 68 | * You can test in the iOS Simulator or on a supported iOS device. However, the 69 | XCode iOS Simulator does not provide access to the camera. When running in 70 | the iOS Simulator, an OTPublisher object uses a demo video instead of the 71 | camera. 72 | 73 | [1]: https://tokbox.com/account/#/ 74 | [2]: https://tokbox.com/developer/sdks/server/ 75 | -------------------------------------------------------------------------------- /FrameMetadata/FrameMetadata.xcodeproj/xcshareddata/xcschemes/FrameMetadata.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /FrameMetadata/FrameMetadata/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Lets-Build-OTPublisher 4 | // 5 | // Created by Roberto Perez Cubero on 11/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | } 24 | 25 | func applicationDidEnterBackground(_ application: UIApplication) { 26 | } 27 | 28 | func applicationWillEnterForeground(_ application: UIApplication) { 29 | } 30 | 31 | func applicationDidBecomeActive(_ application: UIApplication) { 32 | } 33 | 34 | func applicationWillTerminate(_ application: UIApplication) { 35 | } 36 | 37 | 38 | } 39 | 40 | -------------------------------------------------------------------------------- /FrameMetadata/FrameMetadata/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /FrameMetadata/FrameMetadata/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FrameMetadata/FrameMetadata/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | FrameMetadata 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSCameraUsageDescription 28 | 29 | NSMicrophoneUsageDescription 30 | 31 | UILaunchStoryboardName 32 | LaunchScreen 33 | UIMainStoryboardFile 34 | Main 35 | UIRequiredDeviceCapabilities 36 | 37 | armv7 38 | 39 | UISupportedInterfaceOrientations 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationLandscapeLeft 43 | UIInterfaceOrientationLandscapeRight 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /FrameMetadata/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'FrameMetadata' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /FrameMetadata/README.md: -------------------------------------------------------------------------------- 1 | Frame Metadata 2 | ================================== 3 | 4 | This project shows how to set metadata (limited to 32 bytes) to a video frame, as well as how to read metadata from a video frame. It basically extends project 2, "Let's build OTPublisher." By the end of a code review, you should learn how to set and get your desired metedata from a video frame of publisher and subscriber. 5 | 6 | Note that this sample application is not supported in the XCode iOS Simulator 7 | because the custom video capturer needs to acquire video from an iOS device 8 | camera. 9 | 10 | *Important:* To use this application, follow the instructions in the 11 | [Quick Start](../README.md#quick-start) section of the main README file 12 | for this repository. 13 | 14 | TBExampleVideoRender and TBExampleVideoCapture 15 | ------------------------------------------ 16 | 17 | In this example we will include our implementations of OTVideoRender and OTVideoCapture that will allow us to capture and render video by ourselves. 18 | 19 | The purpose of including a custom renderer and capturer is to access the underlying video frame (`OTVideoFrame`) which is not directly visible at `OTPublisher` or `OTSubscriber` class. Once each farme is ready to transmit to the OpenTok platform, we can now attach metadata by invoking the `[setMetadata:error:]` method. In the sample app, we show how to attach an ISO standard timestamp to a video frame: 20 | ``` 21 | func finishPreparingFrame(_ videoFrame: OTVideoFrame?) { 22 | guard let videoFrame = videoFrame else { 23 | return 24 | } 25 | setTimestampToVideoFrame(videoFrame) 26 | } 27 | 28 | fileprivate func setTimestampToVideoFrame(_ videoFrame: OTVideoFrame?) { 29 | guard let videoFrame = videoFrame else { 30 | return 31 | } 32 | 33 | let timestamp = self.dateFormatter.string(from: Date()) 34 | 35 | let metdata = Data(timestamp.utf8) 36 | var error: OTError? 37 | videoFrame.setMetadata(metdata, error: &error) 38 | if let error = error { 39 | print(error) 40 | } 41 | } 42 | ``` 43 | By conforming the `FrameCapturerMetadataDelegate` protocol and implementing the `[finishPreparingFrame:]` method, you will receive a ready video frame to attach your metadata. 44 | 45 | To read the data, the approarch is similar. We simply need to access the underlying video frame and read the `metadata` property. 46 | ``` 47 | func renderer(_ renderer: ExampleVideoRender, didReceiveFrame videoFrame: OTVideoFrame) { 48 | guard let metadata = videoFrame.metadata, let timestampe = String(data: metadata, encoding: .utf8) else { 49 | print("Receiving video frame without metadata attached") 50 | return 51 | } 52 | 53 | DispatchQueue.main.async { 54 | self.metadataLabel.text = timestampe 55 | print("Receiving video frame metadata", timestampe) 56 | } 57 | } 58 | ``` 59 | In the sample app, we conform `ExampleVideoRenderDelegate` and implement `[renderer:didReceiveFrame:]` method to pass back each video frame. 60 | 61 | *Note: you can always directly access a video frame from a custom captuere or renderer. We follow the classic delegate design pattern to enforce better abstraction and reusability.* 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2016 TokBox, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture.xcodeproj/xcshareddata/xcschemes/Live-Photo-Capture.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Live-Photo-Capture 4 | // 5 | // Created by Roberto Perez Cubero on 23/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | } 24 | 25 | func applicationDidEnterBackground(_ application: UIApplication) { 26 | } 27 | 28 | func applicationWillEnterForeground(_ application: UIApplication) { 29 | } 30 | 31 | func applicationDidBecomeActive(_ application: UIApplication) { 32 | } 33 | 34 | func applicationWillTerminate(_ application: UIApplication) { 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/ExamplePhotoVideoCapture.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExamplePhotoVideoCapture.swift 3 | // Live-Photo-Capture 4 | // 5 | // Created by Roberto Perez Cubero on 23/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import AVFoundation 11 | 12 | class ExamplePhotoVideoCapture: ExampleVideoCapture { 13 | var stillImageOutput: AVCaptureStillImageOutput? 14 | var oldPreset: AVCaptureSession.Preset? 15 | 16 | private func waitForSensor() { 17 | let now = CACurrentMediaTime() 18 | let timeout = 1.0 19 | 20 | while (timeout > (CACurrentMediaTime() - now)) 21 | && (videoInput!.device.isAdjustingExposure || videoInput!.device.isAdjustingFocus) {} 22 | return 23 | } 24 | 25 | private func pauseVideoCaptureForPhoto() { 26 | captureSession?.beginConfiguration() 27 | oldPreset = captureSession?.sessionPreset 28 | captureSession?.sessionPreset = AVCaptureSession.Preset.photo 29 | stillImageOutput = AVCaptureStillImageOutput() 30 | stillImageOutput?.outputSettings = [AVVideoCodecKey: AVVideoCodecType.jpeg] 31 | guard let stillImageOutput = self.stillImageOutput else { 32 | print("Error setting stillImageOutput") 33 | return 34 | } 35 | captureSession?.addOutput(stillImageOutput) 36 | captureSession?.commitConfiguration() 37 | 38 | waitForSensor() 39 | } 40 | 41 | private func resumeVideoCapture() { 42 | captureSession?.beginConfiguration() 43 | guard let oldPreset = oldPreset else { 44 | print("Error get oldPreset") 45 | return 46 | } 47 | captureSession?.sessionPreset = oldPreset 48 | guard let stillImageOutput = self.stillImageOutput else { 49 | print("Error setting stillImageOutput") 50 | return 51 | } 52 | captureSession?.removeOutput(stillImageOutput) 53 | captureSession?.commitConfiguration() 54 | } 55 | 56 | private func doPhotoCapture(completionHandler handler: @escaping (_ photo: UIImage?) -> ()) { 57 | guard let connection:AVCaptureConnection = stillImageOutput?.connections.filter({ conn -> Bool in 58 | (conn ).inputPorts.contains( where: { 59 | return ($0 ).mediaType == AVMediaType.video 60 | }) 61 | }).first 62 | else { 63 | handler(nil) 64 | return 65 | } 66 | 67 | stillImageOutput?.captureStillImageAsynchronously(from: connection, completionHandler: { (buffer, error) in 68 | guard let buffer = buffer else { 69 | print("Error gettinb buffer") 70 | return 71 | } 72 | let data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer) 73 | let resultImage = UIImage(data: data!) 74 | handler(resultImage) 75 | }) 76 | } 77 | 78 | func takePhoto(completionHandler handler: @escaping (_ photo: UIImage?) -> ()) { 79 | captureQueue.async { 80 | self.pauseVideoCaptureForPhoto() 81 | self.doPhotoCapture(completionHandler: { img in 82 | DispatchQueue.main.async { 83 | handler(img) 84 | } 85 | }) 86 | self.resumeVideoCapture() 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Live-Photo-Capture/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSCameraUsageDescription 40 | 41 | NSMicrophoneUsageDescription 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Live-Photo-Capture/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Live-Photo-Capture' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Live-Photo-Capture/README.md: -------------------------------------------------------------------------------- 1 | Live Photo Capture Sample App 2 | ================================ 3 | 4 | This project extends some of the material we presented in [Project 2][1], by 5 | demonstrating how a simple capture implementation can be extended to provide 6 | interesting features. By the end of a code review of this project, you should 7 | understand how to use the AVFoundation API to temporarily halt your video 8 | capture module, adjust capture settings to use photo-quality resolution, 9 | capture a picture, then resume video capture. 10 | 11 | *Important:* To use this application, follow the instructions in the 12 | [Quick Start](../README.md#quick-start) section of the main README file 13 | for this repository. 14 | 15 | Configuration Notes 16 | ------------------- 17 | 18 | Since we are importing a number of classes implemented in project 2, the 19 | header search paths in the project build settings must be extended to look 20 | in the project 2 directory. 21 | 22 | Application Notes 23 | ----------------- 24 | 25 | * The only new implementation in this project is the 26 | TBExamplePhotoVideoCapture class. By subclassing the video capture module 27 | implemented in project 2, we save some time setting up standard video 28 | capture and focus only on manipulating AVFoundation to give us a picture 29 | in the middle of a (video) capture session. 30 | 31 | * In testing, we noticed that the image sensor takes a moment to adjust white 32 | balance and exposure after switching to the capture session preset for photo 33 | quality (see `pauseVideoCaptureForPhoto` in TBExamplePhotoVideoCapture). 34 | The example implementation stalls the photo capture with a busy loop, but 35 | a more sophisticated approach might be considered to ensure the best 36 | experience for the end user. 37 | 38 | * This implementation briefly pauses the video feed during image capture. Note 39 | that a prolonged delay to the video capture consumer might result in other 40 | subscribers timing out the stream. If you wait for too long to send 41 | consecutive video frames, you might lose the publisher altogether! Consider 42 | sending a freeze frame or even a blank image buffer to the video capture 43 | endpoint if you need to pause video for a long (>2 second) period. 44 | 45 | * An alternative approach to this problem might be to continuously pipe photo- 46 | quality video into the video capture consumer. This might not work on some 47 | devices, based on processing capability and the fidelity of the image 48 | sensor. Feel free to experiment and let us know how it goes for you! 49 | 50 | * Note that this sample application is not supported in the XCode iOS 51 | Simulator because the custom video capturer needs to acquire video from an 52 | iOS device camera. 53 | 54 | [1]: ../2.Lets-Build-OTPublisher 55 | -------------------------------------------------------------------------------- /Media-Transformers/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Video Transformers Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | ## 2.27.2 6 | 7 | ### Added 8 | 9 | - Support Vonage Media Processor library as a opt-in library. 10 | - Supports Noise Suppression 11 | 12 | ### Fixed 13 | 14 | - Decoupled Media Processor library 15 | 16 | ## 2.26.0 17 | 18 | ### Added 19 | 20 | - Support pre-built transformers in the Vonage Media Processor library or create your own custom video transformer to apply to published video. 21 | 22 | ### Known issues 23 | 24 | - When using the simulator, video transformers are not visible on the publisher side. 25 | 26 | ### Fixed 27 | 28 | - NA 29 | 30 | ### Enhancements 31 | 32 | - NA 33 | 34 | ### Changed 35 | 36 | - NA 37 | 38 | ### Deprecated 39 | 40 | - NA 41 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers.xcodeproj/xcshareddata/xcschemes/Video-Transformers.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Hello-World 4 | // 5 | // Created by Roberto Perez Cubero on 11/08/16. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | NSCameraUsageDescription 40 | 41 | NSMicrophoneUsageDescription 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /Media-Transformers/Media-Transformers/Vonage_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Media-Transformers/Media-Transformers/Vonage_Logo.png -------------------------------------------------------------------------------- /Media-Transformers/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Media-Transformers' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | pod 'VonageClientSDKVideoTransformers' , OpenTokSDKVersion 9 | end 10 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView.xcodeproj/xcshareddata/xcschemes/Multiparty-UICollectionView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 7.Multiparty-UICollectionView 4 | // 5 | // Created by Roberto Perez Cubero on 17/04/2017. 6 | // Copyright © 2017 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | return true 19 | } 20 | 21 | func applicationWillResignActive(_ application: UIApplication) { 22 | } 23 | 24 | func applicationDidEnterBackground(_ application: UIApplication) { 25 | } 26 | 27 | func applicationWillEnterForeground(_ application: UIApplication) { 28 | } 29 | 30 | func applicationDidBecomeActive(_ application: UIApplication) { 31 | } 32 | 33 | func applicationWillTerminate(_ application: UIApplication) { 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Multiparty-UICollectionView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | NSCameraUsageDescription 24 | 25 | NSMicrophoneUsageDescription 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Multiparty-UICollectionView' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Multiparty-UICollectionView/README.md: -------------------------------------------------------------------------------- 1 | Multiparty UICollectionView Sample App 2 | ======================================== 3 | 4 | If you plan to build a multiparty app, you may want to use `UICollectionView` to dynamically 5 | adapt to the screen size and display the video views of all participants in an OpenTok session. 6 | 7 | *Important:* To use this application, follow the instructions in the 8 | [Quick Start](../README.md#quick-start) section of the main README file 9 | for this repository. 10 | 11 | Use `UICollectionView` to easily specify the way views are displayed. 12 | 13 | ## Creating a custom layout for UICollectionView 14 | 15 | When building custom layouts, you need to subclass `UICollectionViewLayout` and override two 16 | methods (`prepare()` and `layoutAttributesForElements(in:)`) and a computed property 17 | (`collectionViewContentSize`). 18 | 19 | First, you need to return the size of the entire `UICollectionView`. In our case, since we want 20 | to fill the entire screen without scrolling, we simply return the size of the `UICollectionView` 21 | container by overriding `collectionViewContentSize()`: 22 | 23 | ```swift 24 | override var collectionViewContentSize: CGSize { 25 | return collectionView?.superview?.bounds.size ?? CGSize() 26 | } 27 | ``` 28 | 29 | When the view is going to be laid out, `UIKit` calls the implementation of the 30 | `MultipartyLayout.prepare()` method. This method prepares values used when the views are drawn. 31 | It populates a cache, which is a `UICollectionViewLayoutAttributes` object that specifies the size 32 | and position of each item: 33 | 34 | ```swift 35 | override func prepare() { 36 | guard let views = collectionView?.numberOfItems(inSection: 0) 37 | else { 38 | cache.removeAll() 39 | return 40 | } 41 | 42 | if views != cachedNumberOfViews { 43 | cache.removeAll() 44 | } 45 | 46 | if cache.isEmpty { 47 | cachedNumberOfViews = views 48 | let attribs: [UICollectionViewLayoutAttributes] = { 49 | switch views { 50 | case 1: 51 | return attributesForPublisherFullScreen() 52 | case 2: 53 | return attributesForPublisherAndOneSubscriber() 54 | case let x where x > 2 && x.isEven: 55 | return attributesForAllViewsTwoByTwo(withNumberOfViews: x) 56 | case let x where x > 2 && !x.isEven: 57 | return attributesForPublisherOnTopAndSubscribersTwoByTwo(withNumberOfViews: x) 58 | default: 59 | return [] 60 | } 61 | }() 62 | 63 | cache.append(contentsOf: attribs) 64 | } 65 | } 66 | ``` 67 | 68 | The implementation of the `UICollectionViewLayout.layoutAttributesForElements(in:)` method is 69 | called when the views are laid out. It returns the cache containing the actual view sizes: 70 | 71 | ```swift 72 | override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { 73 | return cache 74 | } 75 | ``` 76 | -------------------------------------------------------------------------------- /OpenTokSDKVersion.rb: -------------------------------------------------------------------------------- 1 | OpenTokSDKVersion = '2.30.1' 2 | MinIosSdkVersion = '15.0' 3 | -------------------------------------------------------------------------------- /Picture-In-Picture/Lets-Build-OTPublisher/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | @UIApplicationMain 4 | class AppDelegate: UIResponder, UIApplicationDelegate { 5 | 6 | var window: UIWindow? 7 | 8 | 9 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 10 | // Override point for customization after application launch. 11 | return true 12 | } 13 | 14 | func applicationWillResignActive(_ application: UIApplication) { 15 | } 16 | 17 | func applicationDidEnterBackground(_ application: UIApplication) { 18 | } 19 | 20 | func applicationWillEnterForeground(_ application: UIApplication) { 21 | } 22 | 23 | func applicationDidBecomeActive(_ application: UIApplication) { 24 | } 25 | 26 | func applicationWillTerminate(_ application: UIApplication) { 27 | } 28 | 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /Picture-In-Picture/Lets-Build-OTPublisher/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Picture-In-Picture/Lets-Build-OTPublisher/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Picture-In-Picture/Lets-Build-OTPublisher/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSCameraUsageDescription 26 | 27 | NSMicrophoneUsageDescription 28 | 29 | UIBackgroundModes 30 | 31 | audio 32 | fetch 33 | processing 34 | 35 | UILaunchStoryboardName 36 | LaunchScreen 37 | UIMainStoryboardFile 38 | Main 39 | UIRequiredDeviceCapabilities 40 | 41 | armv7 42 | 43 | UISupportedInterfaceOrientations 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Picture-In-Picture/Lets-Build-OTPublisher/SampleBufferVideoCallView.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import AVKit 3 | 4 | class SampleBufferVideoCallView: UIView { 5 | override class var layerClass: AnyClass { 6 | AVSampleBufferDisplayLayer.self 7 | } 8 | 9 | var sampleBufferDisplayLayer: AVSampleBufferDisplayLayer { 10 | layer as! AVSampleBufferDisplayLayer 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /Picture-In-Picture/Picture-In-Picture.xcodeproj/xcshareddata/xcschemes/Picture-In-Picture.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Picture-In-Picture/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Picture-In-Picture' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Picture-In-Picture/README.md: -------------------------------------------------------------------------------- 1 | Picture In Picture Sample App 2 | ================================== 3 | 4 | This project uses the custom video render features in the OpenTok iOS SDK. 5 | By the end of a code review, you should have a basic understanding how to implement 6 | Picture-In-Picture for the subscribed stream. 7 | 8 | Note that this sample application is not supported in the XCode iOS Simulator 9 | because the Picture-In-Picture only works on real device. 10 | 11 | *Important:* To use this application, follow the instructions in the 12 | [Quick Start](../README.md#quick-start) section of the main README file 13 | for this repository. 14 | 15 | 16 | ### ExampleVideoRender 17 | 18 | OTSubscriber needs an instance supporting the 19 | `OTVideoRender` protocol to display video contents. In short, the instance 20 | ID that is set to the `videoRender` property will receive YUV frames (I420) 21 | as they are received (subscriber). 22 | 23 | In this example we get the YUV frames from `videoRender`, 24 | and convert the frames to CMSampleBuffer. 25 | Refer to function `createSampleBufferWithVideoFrame` for YUV frames to CMSampeBuffer conversion. 26 | 27 | Then, draw the video stream on the PIP by adding the CMSampleBuffer into PIP 28 | `sampleBufferDisplayLayer` 29 | 30 | 31 | ### ViewController 32 | 33 | Setup a PIP controller is well documented in [apple doc][1]. 34 | 35 | To see sample in action, you need to add a publisher (which will display as a subscriber), either run the app a second time in an iOS device or use the OpenTok Playground to connect to the session in a supported web browser (Chrome, Firefox, or Internet Explorer 10-11). 36 | 37 | 38 | [1]: https://developer.apple.com/documentation/avkit/adopting-picture-in-picture-for-video-calls 39 | -------------------------------------------------------------------------------- /Screen-Sharing/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Screen-Sharing' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing.xcodeproj/xcshareddata/xcschemes/Screen-Sharing.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 5.Screen-Sharing 4 | // 5 | // Created by Roberto Perez Cubero on 23/09/2016. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | func applicationWillResignActive(_ application: UIApplication) { 21 | } 22 | 23 | func applicationDidEnterBackground(_ application: UIApplication) { 24 | } 25 | 26 | func applicationWillEnterForeground(_ application: UIApplication) { 27 | } 28 | 29 | func applicationDidBecomeActive(_ application: UIApplication) { 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | NSCameraUsageDescription 38 | 39 | NSMicrophoneUsageDescription 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Screen-Sharing/Screen-Sharing/logo_opentok_registered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Screen-Sharing/Screen-Sharing/logo_opentok_registered.png -------------------------------------------------------------------------------- /Signals/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Signals' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Signals/README.md: -------------------------------------------------------------------------------- 1 | Signaling Sample App 2 | =============================== 3 | 4 | The Signaling app is a very simple application meant to get a new developer 5 | started using the signaling features of OpenTok iOS SDK. 6 | 7 | Quick Start 8 | ----------- 9 | 10 | To use this application: 11 | 12 | 1. Follow the instructions in the [Quick Start](../README.md#quick-start) 13 | section of the main README file for this repository. 14 | 15 | Among other things, you need to set values for the `kApiKey`, `kSessionId`, 16 | and `kToken` constants. See [Obtaining OpenTok 17 | Credentials](../README.md#obtaining-opentok-credentials) 18 | in the main README file for the repository. 19 | 20 | 2. When you run the application, an OpenTok session is created . Signaling only needs 21 | OTConnection(s). 22 | 23 | 3. Run the app on a second client. You can do this by deploying the app to an 24 | iOS device and testing it in the simulator at the same time. 25 | 26 | 27 | Application Notes 28 | ----------------- 29 | 30 | * Signals are meant to transmit basic text data between participants in a session. 31 | * Signals don't have extensive chat like features (like emoji's etc). 32 | 33 | * Sending an signal using an session object as follows: 34 | ```swift 35 | session.signal(withType: type , string: data, connection:c.getOTConnection(), error: nil) 36 | ``` 37 | or 38 | ```swift 39 | session.signal(withType: type , string: data, connection:c.getOTConnection(), retryAfterReconnect: retryAfterConnect, error: nil) 40 | ``` 41 | `retryAfterReconnect` default value is `true` in the first call. The error case fails silently. 42 | 43 | * Receiving a signal is done using OTSessionDelegate callback as follows: 44 | ```swift 45 | func session(_ session: OTSession, receivedSignalType type: String?, from connection: OTConnection?, with string: String?) { 46 | .. 47 | } 48 | ``` 49 | You just need to implement the above calls in your app. 50 | 51 | * Valid Characters in a signal data is limited to `[^a-zA-Z0-9-_~\\s]`. If a non valid character is used , signal is not send. To get around this you can encode signal data with `base64` and decode it on other side. This way you can send emoji's for example. A sample code which extends `String` is provided below for reference: 52 | ```swift 53 | extension String { 54 | func fromBase64() -> String? { 55 | guard let data = Data(base64Encoded: self) else { 56 | return nil 57 | } 58 | 59 | return String(data: data, encoding: .ascii) 60 | } 61 | 62 | func toBase64() -> String { 63 | return Data(self.utf8).base64EncodedString() 64 | } 65 | func isValidSignal() -> Bool { 66 | return self.count <= 128 && self.range(of: "[^a-zA-Z0-9-_~\\s]", options: .regularExpression) == nil 67 | } 68 | ... 69 | } 70 | ``` 71 | 72 | Screen shot (SwiftUI based) 73 | ----------------- 74 | 75 | ## Starting screen: 76 | 77 | 1) Tap on "Hello !!" sends a "Hello World" message to all connections. 78 | 2) Tap on the Pen image leads to Form View (as shown below) 79 | 80 | image 81 | 82 | 83 | 84 | ## Starting screen with Scrollable Messages: 85 | 86 | image 87 | 88 | 89 | ## Signal Form view: 90 | 91 | image 92 | 93 | image 94 | 95 | 96 | -------------------------------------------------------------------------------- /Signals/Signals/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Signals/Signals/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | } 8 | ], 9 | "info" : { 10 | "author" : "xcode", 11 | "version" : 1 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Signals/Signals/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Signals/Signals/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // Signals 4 | // 5 | // Created by Jaideep Shah on 2/9/23. 6 | // 7 | 8 | import SwiftUI 9 | struct ContentView { 10 | @State var oneClick = true 11 | @StateObject private var sdk = VonageVideoSDK() 12 | @State private var signalType = "Greetings" 13 | @State private var signalData = "Hello World" 14 | @State private var isRetryOnReconnect = true 15 | 16 | } 17 | extension ContentView: View { 18 | var body: some View { 19 | ZStack { 20 | VStack(alignment: .center, spacing: 25) { 21 | if (sdk.isSessionConnected == false) { 22 | Text("Connecting ...") 23 | .font(.title) 24 | } else { 25 | if oneClick == true { 26 | Button("Hello !!") { 27 | sdk.sendSignalToAll(type: "Greetings", data: "Hello World") 28 | } 29 | .font(.title) 30 | 31 | //OneClickView(oneClick: $oneClick) 32 | Button { 33 | oneClick = false 34 | // print("Edit button was tapped") 35 | } label: { 36 | Image(systemName: "square.and.pencil") 37 | } 38 | ScrollView { 39 | MessagesView() 40 | 41 | } 42 | } 43 | else { 44 | VStack { 45 | FormView(signalType: $signalType, signalData: $signalData, retryAfterConnect: $isRetryOnReconnect, oneClick: $oneClick) 46 | } 47 | } 48 | } 49 | 50 | 51 | } 52 | .padding(30) 53 | .environmentObject(sdk) 54 | .onDisappear { 55 | sdk.closeAll() 56 | } 57 | } 58 | } 59 | } 60 | struct ContentView_Previews: PreviewProvider { 61 | static var previews: some View { 62 | ContentView() 63 | } 64 | } 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Signals/Signals/MessagesView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MessagesView.swift 3 | // 4 | // 5 | // Created by Jaideep Shah on 2/9/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | 11 | 12 | struct MessagesView { 13 | @EnvironmentObject private var sdk: VonageVideoSDK 14 | } 15 | 16 | extension MessagesView: View { 17 | var body: some View { 18 | LazyVStack(alignment: .leading) { 19 | 20 | ForEach(sdk.messages) { m in 21 | Spacer() 22 | VStack(alignment: .leading) { 23 | HStack { 24 | if m.outgoing { 25 | Image(systemName: "arrow.up.forward.square.fill") 26 | .foregroundColor(.yellow) 27 | } else { 28 | Image(systemName: "arrow.down.left.square.fill") 29 | .foregroundColor(.green) 30 | } 31 | Text(m.displayConnId) 32 | .padding(.horizontal) 33 | .multilineTextAlignment(.leading) 34 | .font(.system(size: 12)) 35 | Spacer() 36 | Text(m.type) 37 | .multilineTextAlignment(.trailing) 38 | .font(.system(size: 12)) 39 | 40 | 41 | } 42 | Spacer() 43 | HStack { 44 | Image(systemName: "arrow.up.forward.square.fill") 45 | .foregroundColor(.green) 46 | .hidden() 47 | Text(m.content) 48 | .padding(.horizontal) 49 | .multilineTextAlignment(.leading) 50 | .font(.system(size: 14)) 51 | 52 | .allowsTightening(true) 53 | .lineLimit(3) 54 | } 55 | 56 | } 57 | .padding(5) 58 | .overlay( 59 | RoundedRectangle(cornerRadius: 10, style: .circular).stroke(Color(uiColor: .tertiaryLabel), lineWidth: 1) 60 | .shadow(radius: 5) 61 | 62 | 63 | ) 64 | 65 | } 66 | 67 | 68 | 69 | } 70 | .padding() 71 | 72 | } 73 | 74 | } 75 | 76 | struct MessagesView_Previews: PreviewProvider { 77 | static var previews: some View { 78 | MessagesView() 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Signals/Signals/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Signals/Signals/SignalsApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SignalsApp.swift 3 | // Signals 4 | // 5 | // Created by Jaideep Shah on 2/9/23. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct SignalsApp: App { 12 | var body: some Scene { 13 | WindowGroup { 14 | ContentView() 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Simple-Multiparty/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../OpenTokSDKVersion' 2 | 3 | platform :ios, MinIosSdkVersion 4 | use_frameworks! 5 | 6 | target 'Simple-Multiparty' do 7 | pod 'OTXCFramework', OpenTokSDKVersion 8 | end 9 | -------------------------------------------------------------------------------- /Simple-Multiparty/README.md: -------------------------------------------------------------------------------- 1 | Simple Multiparty Sample App 2 | ============================== 3 | 4 | Previous samples subscribe to only one stream. In a multiparty video audio call 5 | there should be multiple parties. 6 | 7 | *Important:* To use this application, follow the instructions in the 8 | [Quick Start](../README.md#quick-start) section of the main README file 9 | for this repository. 10 | 11 | This simple multiparty app is able to handle only four subscriber parties. On a 12 | new stream received the ViewController class creates a new Subscriber object and 13 | subscribes the Session object to it. The Subscriber stream is rendered in the 14 | screen as we did it before. 15 | 16 | This sample uses a UICollectionView to show each subscriber view. We use a custom 17 | UICollectionViewCell that will hold the subscriber view and will also control some 18 | basic user interface to mute the audio of that subscriber. 19 | 20 | ```swift 21 | class SubscriberCollectionCell: UICollectionViewCell { 22 | @IBOutlet var muteButton: UIButton! 23 | 24 | var subscriber: OTSubscriber? 25 | 26 | @IBAction func muteSubscriberAction(_ sender: AnyObject) { 27 | subscriber?.subscribeToAudio = !(subscriber?.subscribeToAudio ?? true) 28 | 29 | let buttonImage: UIImage = { 30 | if !(subscriber?.subscribeToAudio ?? true) { 31 | return #imageLiteral(resourceName: "Subscriber-Speaker-Mute-35") 32 | } else { 33 | return #imageLiteral(resourceName: "Subscriber-Speaker-35") 34 | } 35 | }() 36 | 37 | muteButton.setImage(buttonImage, for: .normal) 38 | } 39 | 40 | override func layoutSubviews() { 41 | if let sub = subscriber { 42 | sub.view.frame = bounds 43 | contentView.insertSubview(sub.view, belowSubview: muteButton) 44 | 45 | muteButton.isEnabled = true 46 | muteButton.isHidden = false 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | ## Adding user interface controls 53 | 54 | The ViewController class shows how you can add user interface controls for the following: 55 | 56 | * Turning a publisher's audio stream on and off 57 | * Swapping the publisher's camera 58 | 59 | When the user taps the mute button for the publisher, the following method of the ViewController 60 | class is invoked: 61 | 62 | ```swift 63 | @IBAction func muteMicAction(_ sender: AnyObject) { 64 | publisher.publishAudio = !publisher.publishAudio 65 | let buttonImage: UIImage = { 66 | if !publisher.publishAudio { 67 | return #imageLiteral(resourceName: "mic_muted-24") 68 | } else { 69 | return #imageLiteral(resourceName: "mic-24") 70 | } 71 | }() 72 | 73 | muteMicButton.setImage(buttonImage, for: .normal) 74 | } 75 | ``` 76 | 77 | ## Next steps 78 | 79 | For details on the full OpenTok Android API, see the [reference 80 | documentation](https://tokbox.com/developer/sdks/ios/reference/index.html). 81 | -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty.xcodeproj/xcshareddata/xcschemes/Simple-Multiparty.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 6.Multi-Party 4 | // 5 | // Created by Roberto Perez Cubero on 27/09/2016. 6 | // Copyright © 2016 tokbox. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | return true 18 | } 19 | 20 | func applicationWillResignActive(_ application: UIApplication) { 21 | } 22 | 23 | func applicationDidEnterBackground(_ application: UIApplication) { 24 | } 25 | 26 | func applicationWillEnterForeground(_ application: UIApplication) { 27 | } 28 | 29 | func applicationDidBecomeActive(_ application: UIApplication) { 30 | } 31 | 32 | func applicationWillTerminate(_ application: UIApplication) { 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-35.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Subscriber-Speaker-35.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Subscriber-Speaker-35@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-35.imageset/Subscriber-Speaker-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-35.imageset/Subscriber-Speaker-35.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-35.imageset/Subscriber-Speaker-35@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-35.imageset/Subscriber-Speaker-35@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-Mute-35.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Subscriber-Speaker-Mute-35.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Subscriber-Speaker-Mute-35@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-Mute-35.imageset/Subscriber-Speaker-Mute-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-Mute-35.imageset/Subscriber-Speaker-Mute-35.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-Mute-35.imageset/Subscriber-Speaker-Mute-35@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/Subscriber-Speaker-Mute-35.imageset/Subscriber-Speaker-Mute-35@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/TB Bug-30.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "TB Bug-30.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "TB Bug-30@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/TB Bug-30.imageset/TB Bug-30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/TB Bug-30.imageset/TB Bug-30.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/TB Bug-30.imageset/TB Bug-30@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/TB Bug-30.imageset/TB Bug-30@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera-switch_black-33.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "camera-switch_black-33.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "camera-switch_black-33@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera-switch_black-33.imageset/camera-switch_black-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera-switch_black-33.imageset/camera-switch_black-33.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera-switch_black-33.imageset/camera-switch_black-33@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera-switch_black-33.imageset/camera-switch_black-33@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera_switch-33.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "camera_switch-33.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "camera_switch-33@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera_switch-33.imageset/camera_switch-33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera_switch-33.imageset/camera_switch-33.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera_switch-33.imageset/camera_switch-33@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/camera_switch-33.imageset/camera_switch-33@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_disabled-28.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icon_arrowLeft_disabled-28.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icon_arrowLeft_disabled-28@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_disabled-28.imageset/icon_arrowLeft_disabled-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_disabled-28.imageset/icon_arrowLeft_disabled-28.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_disabled-28.imageset/icon_arrowLeft_disabled-28@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_disabled-28.imageset/icon_arrowLeft_disabled-28@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_enabled-28.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icon_arrowLeft_enabled-28.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icon_arrowLeft_enabled-28@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_enabled-28.imageset/icon_arrowLeft_enabled-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_enabled-28.imageset/icon_arrowLeft_enabled-28.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_enabled-28.imageset/icon_arrowLeft_enabled-28@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowLeft_enabled-28.imageset/icon_arrowLeft_enabled-28@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_disabled-28.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icon_arrowRight_disabled-28.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icon_arrowRight_disabled-28@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_disabled-28.imageset/icon_arrowRight_disabled-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_disabled-28.imageset/icon_arrowRight_disabled-28.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_disabled-28.imageset/icon_arrowRight_disabled-28@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_disabled-28.imageset/icon_arrowRight_disabled-28@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_enabled-28.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "icon_arrowRight_enabled-28.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "icon_arrowRight_enabled-28@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_enabled-28.imageset/icon_arrowRight_enabled-28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_enabled-28.imageset/icon_arrowRight_enabled-28.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_enabled-28.imageset/icon_arrowRight_enabled-28@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/icon_arrowRight_enabled-28.imageset/icon_arrowRight_enabled-28@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic-24.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mic-24.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mic-24@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic-24.imageset/mic-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic-24.imageset/mic-24.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic-24.imageset/mic-24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic-24.imageset/mic-24@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_muted-24.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mic_muted-24.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mic_muted-24@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_muted-24.imageset/mic_muted-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_muted-24.imageset/mic_muted-24.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_muted-24.imageset/mic_muted-24@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_muted-24.imageset/mic_muted-24@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_receiving_data-35.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "mic_receiving_data-35.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "mic_receiving_data-35@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_receiving_data-35.imageset/mic_receiving_data-35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_receiving_data-35.imageset/mic_receiving_data-35.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_receiving_data-35.imageset/mic_receiving_data-35@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opentok/opentok-ios-sdk-samples-swift/78e834dbd6ce9192a425a7e4f1b352f324558caf/Simple-Multiparty/Simple-Multiparty/Assets.xcassets/mic_receiving_data-35.imageset/mic_receiving_data-35@2x.png -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Simple-Multiparty/Simple-Multiparty/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | NSCameraUsageDescription 38 | 39 | NSMicrophoneUsageDescription 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /travis_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | cd Basic-Video-Chat/ 6 | pod install 7 | xcodebuild -workspace Basic-Video-Chat.xcworkspace -scheme Basic-Video-Chat -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 8 | 9 | cd ../Custom-Video-Driver/ 10 | pod install 11 | xcodebuild -workspace Custom-Video-Driver.xcworkspace -scheme Custom-Video-Driver -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 12 | 13 | cd ../Custom-Audio-Driver/ 14 | pod install 15 | xcodebuild -workspace Custom-Audio-Driver.xcworkspace -scheme Custom-Audio-Driver -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 16 | 17 | cd ../Screen-Sharing/ 18 | pod install 19 | xcodebuild -workspace Screen-Sharing.xcworkspace -scheme Screen-Sharing -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 20 | 21 | cd ../Live-Photo-Capture/ 22 | pod install 23 | xcodebuild -workspace Live-Photo-Capture.xcworkspace -scheme Live-Photo-Capture -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 24 | 25 | cd ../Simple-Multiparty/ 26 | pod install 27 | xcodebuild -workspace Simple-Multiparty.xcworkspace -scheme Simple-Multiparty -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 28 | 29 | cd ../Multiparty-UICollectionView/ 30 | pod install 31 | xcodebuild -workspace Multiparty-UICollectionView.xcworkspace -scheme Multiparty-UICollectionView -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 32 | 33 | cd ../CallKit/ 34 | pod install 35 | xcodebuild -workspace CallKitDemo.xcworkspace -scheme CallKitDemo -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 36 | 37 | cd Video-Transformers/ 38 | pod install 39 | xcodebuild -workspace Video-Transformers.xcworkspace -scheme Video-Transformers -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO -UseModernBuildSystem=NO 40 | --------------------------------------------------------------------------------