Skip to content
This repository has been archived by the owner on Mar 9, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20 from sean-perkins/release-1.5.0
Browse files Browse the repository at this point in the history
Release 1.5.0
  • Loading branch information
Sean Perkins committed Sep 6, 2016
2 parents 8811160 + 0130698 commit b234538
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 74 deletions.
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,42 @@ Node Package Manager (NPM)
##### View
You will first need to import the custom element into the {N} xml view. This can be accomplished by adding this snippet: `xmlns:OT="nativescript-opentok"` to your existing `Page` element tag.

The basic integration example would include the following declarations for publisher and subscriber. Notice subscriber is any element with `id="subscriber"`. You will need to provide a valid sessionId, api (key) and token to the publisher element.
The basic integration example would include the following declarations for publisher and subscriber. Notice subscriber is any element with `id="subscriber"`.
```
<StackLayout id="subscriber" width="100%" height="100%"></StackLayout>
<OT:TNSOTPublisher id="publisher" sessionId="{{ sessionId }}" api="{{ api }}" token="{{ publisherToken }}" verticalAlignment="top" horizontalAlignment="right" margin="10" width="100" height="100"></OT:TNSOTPublisher>
<OT:TNSOTPublisher id="publisher" verticalAlignment="top" horizontalAlignment="right" margin="10" width="100" height="100"></OT:TNSOTPublisher>
```

Next in your page's binding context (a controller, view model, etc.), you will need to import and hook to the OpenTok implementation.

```
import {TNSOTPublisher, TNSOTSession} from 'nativescript-opentok';
public _apiKey:string = 'API_KEY';
public sessionId: string = 'SESSION_ID';
public publisherToken: string = 'TOKEN';
private publisher: TNSOTPublisher;
private session:TNSOTSession;
constructor(private page: Page) {
super();
this.session = TNSOTSession.initWithApiKeySessionId(this._apiKey, this.sessionId);
this.publisher = <TNSOTPublisher> this.page.getViewById('publisher');
this.initPublisher();
}
initPublisher() {
this.session.connect(this.publisherToken);
this.publisher.publish(this.session);
}
```


### Special Articles
- [Overlay UI on the Video Stream](https://github.com/sean-perkins/nativescript-opentok/wiki/Overlay-UI-on-Video-Stream)
- [Angular 2 Integration Guide](https://github.com/sean-perkins/nativescript-opentok/wiki/Angular-2-Integration-Guide)
- [Controlling Resolution and FPS](https://github.com/sean-perkins/nativescript-opentok/wiki/Controlling-Frame-Rate-and-Resolution)

### Images
|iPhone|iPad|
Expand Down
2 changes: 1 addition & 1 deletion demo/app/main-page.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<GridLayout rows="*,auto,auto">
<GridLayout>
<StackLayout id="subscriber" width="100%" height="100%"></StackLayout>
<OT:TNSOTPublisher id="publisher" sessionId="{{ sessionId }}" api="{{ api }}" token="{{ publisherToken }}" verticalAlignment="top" horizontalAlignment="right" margin="10" width="100" height="100"></OT:TNSOTPublisher>
<OT:TNSOTPublisher id="publisher" verticalAlignment="top" horizontalAlignment="right" margin="10" width="200" height="200"></OT:TNSOTPublisher>
</GridLayout>

<StackLayout verticalAlignment="bottom" marginBottom="50">
Expand Down
25 changes: 17 additions & 8 deletions demo/app/main-view-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,30 @@ import {Observable, EventData} from 'data/observable';
import {isAndroid, isIOS} from 'platform';
import {Page} from 'ui/page';

import {TNSOTPublisher} from 'nativescript-opentok';
import {TNSOTSession, TNSOTPublisher} from 'nativescript-opentok';

export class Demo extends Observable {

public api:string = '45644202';
public _apiKey:string = '45644202';
public sessionId: string = '1_MX40NTY0NDIwMn5-MTQ3MjIyNzU3NTAwM35FczFWMHdVekNxeXNabWRSTUdIUkpjRmR-fg';
public publisherToken: string = 'T1==cGFydG5lcl9pZD00NTY0NDIwMiZzaWc9NTkwNmVhZWZjNDMzNWRlNDY5ZTZmZTkwMjg0Yjk0ODJlZmE4NjFjODpzZXNzaW9uX2lkPTFfTVg0ME5UWTBOREl3TW41LU1UUTNNakl5TnpVM05UQXdNMzVGY3pGV01IZFZla054ZVhOYWJXUlNUVWRJVWtwalJtUi1mZyZjcmVhdGVfdGltZT0xNDcyMjI3NTg4Jm5vbmNlPTAuNzY3MTczMTA0Njg2NjYyNiZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNDc0ODE5NTg3';
public publisherToken2: string = 'T1==cGFydG5lcl9pZD00NTY0NDIwMiZzaWc9YTM5NTVmODVmYWU0NjkwNThiN2YzMjU3YzM0ZmI4YTYwNTg2YjU0MjpzZXNzaW9uX2lkPTFfTVg0ME5UWTBOREl3TW41LU1UUTNNakl5TnpVM05UQXdNMzVGY3pGV01IZFZla054ZVhOYWJXUlNUVWRJVWtwalJtUi1mZyZjcmVhdGVfdGltZT0xNDcyMjQyNDgwJm5vbmNlPTAuMjU5ODA5NDU5MzI2Nzg4OCZyb2xlPXB1Ymxpc2hlciZleHBpcmVfdGltZT0xNDc0ODM0NDgw';
public publisherToken: string = 'T1==cGFydG5lcl9pZD00NTY0NDIwMiZzaWc9ODMwYzUyMTEwMjk5ODQ1OGQ3YmJlOWY1MDFhOGU2MGQwZGQyMmQyYjpzZXNzaW9uX2lkPTFfTVg0ME5UWTBOREl3TW41LU1UUTNNakl5TnpVM05UQXdNMzVGY3pGV01IZFZla054ZVhOYWJXUlNUVWRJVWtwalJtUi1mZyZjcmVhdGVfdGltZT0xNDcyODQ4NDk1Jm5vbmNlPTAuNjYyMzAzOTA2MTY2OTI2JnJvbGU9cHVibGlzaGVyJmV4cGlyZV90aW1lPTE0NzU0NDA0OTU=';

private publisher: any;
private publisher: TNSOTPublisher;
private session:TNSOTSession;

constructor(private page: Page) {
super();
this.publisher = this.page.getViewById('publisher');
this.session = TNSOTSession.initWithApiKeySessionId(this._apiKey, this.sessionId);
this.publisher = <TNSOTPublisher> this.page.getViewById('publisher');
this.initPublisher();
}

initPublisher() {
this.session.connect(this.publisherToken);
this.publisher.publish(this.session, '', 'HIGH', '30');
this.publisher.events.on('streamDestroyed', (result) => {
console.log('publisher stream destroyed');
});
}

switchCamera() {
Expand All @@ -32,8 +42,7 @@ export class Demo extends Observable {
}

unpublish() {
this.publisher.session.unpublish();
console.log('unpublish');
this.publisher.unpublish(this.session);
}

}
112 changes: 73 additions & 39 deletions src/ios/publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,63 @@ import {ContentView} from 'ui/content-view'
import {TNSOTSession} from './session';

declare var OTPublisher: any,
CGRectMake: any,
interop: any,
OTPublisherKitDelegate: any,
OTCameraCaptureResolution: any,
OTCameraCaptureFrameRate: any,
AVCaptureDevicePositionBack: any,
AVCaptureDevicePositionFront: any;

export class TNSOTPublisher extends ContentView {

private _ios: any;
private _ios: any = {};
private _view: UIView;
private _publisherKitDelegate: any;
private _session: TNSOTSession;

private _sessionId: any;
private _apiKey: string;
private _token: string;

constructor() {
super();
this._publisherKitDelegate = TNSPublisherKitDelegateImpl.initWithOwner(new WeakRef(this));
this._ios = new OTPublisher(this._publisherKitDelegate);
}

private connect(): void {
if(this._apiKey && this._sessionId && this._token) {
this._session = TNSOTSession.initWithApiKeySessionIdToken(this._apiKey, this._sessionId, this._token);
this._session.events.on('sessionDidConnect', (result) => {
this.publishStream(result.object);
});
}
onLoaded() {
super.onLoaded();
UIView.alloc().initWithFrame(CGRectMake(0, 0, this.width, this.height));
}

publish(session: TNSOTSession, name?:string, cameraResolution?: string, cameraFrameRate?: string): void {
this._ios = OTPublisher.alloc().initWithDelegateNameCameraResolutionCameraFrameRate(
this._publisherKitDelegate,
name ? name : '',
this.getCameraResolution(cameraResolution),
this.getCameraFrameRate(cameraFrameRate)
);
this._ios.view.frame = CGRectMake(0, 0, this.width, this.height);
this._view.addSubview(this._ios.view);

session.events.on('sessionDidConnect', (result) => {
this._ios.publishAudio = true;
try {
let stream: any = result.object;
this.setIdleTimer(true);
stream.publish(this._ios);
} catch(error) {
console.log(error);
}
});
}

private publishStream(session: any): void {
this._ios.publishAudio = true;
unpublish(session: TNSOTSession): void {
try {
session.publish(this._ios);
} catch (error) {
if(session) {
let errorRef = new interop.Reference();
this.setIdleTimer(false);
session._ios.unpublishError(this._ios, errorRef);
if(errorRef.value) {
console.log(errorRef.value);
}
}
}
catch(error) {
console.log(error);
}
}
Expand All @@ -49,22 +71,42 @@ export class TNSOTPublisher extends ContentView {
}

get _nativeView(): any {
return this._ios.view;
}

set sessionId(sessionId: string) {
this._sessionId = sessionId;
this.connect();
return this._view;
}

set api(apiKey: string) {
this._apiKey = apiKey;
this.connect();
private setIdleTimer(idleTimerDisabled: boolean) {
let app = UIApplication.sharedApplication();
app.idleTimerDisabled = idleTimerDisabled;
}

set token(token: string) {
this._token = token;
this.connect();
private getCameraResolution(cameraResolution: string): any {
if(cameraResolution) {
switch(cameraResolution.toString().toUpperCase()) {
case 'LOW':
return OTCameraCaptureResolution.OTCameraCaptureResolutionLow;
case 'MEDIUM':
return OTCameraCaptureResolution.OTCameraCaptureResolutionMedium;
case 'HIGH':
return OTCameraCaptureResolution.OTCameraCaptureResolutionHigh;
}
}
return OTCameraCaptureResolution.OTCameraCaptureResolutionMedium;
}

private getCameraFrameRate(cameraFrameRate: string): any {
if(cameraFrameRate) {
switch(Number(cameraFrameRate)) {
case 30:
return OTCameraCaptureFrameRate.OTCameraCaptureFrameRate30FPS;
case 15:
return OTCameraCaptureFrameRate.OTCameraCaptureFrameRate15FPS;
case 7:
return OTCameraCaptureFrameRate.OTCameraCaptureFrameRate7FPS;
case 1:
return OTCameraCaptureFrameRate.OTCameraCaptureFrameRate1FPS;
}
}
return OTCameraCaptureFrameRate.OTCameraCaptureFrameRate30FPS;
}

cycleCamera(): void {
Expand All @@ -90,13 +132,6 @@ export class TNSOTPublisher extends ContentView {
}
}

get session(): TNSOTSession {
if(this._session) {
this._session.publisher = this._ios;
}
return this._session;
}

get events(): Observable {
return this._publisherKitDelegate.events;
}
Expand Down Expand Up @@ -139,7 +174,6 @@ class TNSPublisherKitDelegateImpl extends NSObject {
})
});
}
topmost().currentPage.ios.view.removeFromSuperview(publisher.view);
}

public publisherDidFailWithError(publisher: any, error: any) {
Expand Down
40 changes: 16 additions & 24 deletions src/ios/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,49 @@ export class TNSOTSession extends NSObject {
public static ObjCProtocols = [OTSessionDelegate];

public subscriber: TNSOTSubscriber;
public events: Observable;
public session: any;
public _ios: any;

private _events: Observable;
private _publisher: TNSOTPublisher;

public static initWithApiKeySessionIdToken(apiKey: string, sessionId: string, token:string): TNSOTSession {
public static initWithApiKeySessionId(apiKey: string, sessionId: string): TNSOTSession {
let instance = <TNSOTSession>TNSOTSession.new();
instance.events = new Observable();
instance.session = OTSession.alloc().initWithApiKeySessionIdDelegate(apiKey.toString(), sessionId.toString(), instance);
instance._events = new Observable();
instance._ios = OTSession.alloc().initWithApiKeySessionIdDelegate(apiKey.toString(), sessionId.toString(), instance);
return instance;
}

connect(token: string): void {
let errorRef = new interop.Reference();
instance.session.connectWithTokenError(token, errorRef);
this._ios.connectWithTokenError(token, errorRef);
if(errorRef.value) {
console.log(errorRef.value);
}
return instance;
}

disconnect(): void {
if(this.session) {
if(this._ios) {
try {
this.session.disconnect();
this._ios.disconnect();
} catch(error) {
console.log(error);
}
}
}

unpublish(): void {
try {
if(this.session) {
this.session.unpublish(this._publisher);
}
}
catch(error) {
console.log(error);
}
}

unsubscribe(): void {
try {
if(this.session) {
this.session.unsubscribe();
if(this._ios) {
this._ios.unsubscribe();
}
}
catch(error) {
console.log(error);
}
}

set publisher(publisher) {
this._publisher = publisher;
get events(): Observable {
return this._events;
}

public sessionDidConnect(session: any) {
Expand Down

0 comments on commit b234538

Please sign in to comment.