Overview
The example shows how to publish a WebRTC stream to a server and play multiple streams from the server (one-to-mant videochat). It may be also used as memory consumption test while decoding multiple high resolution streams.
On the screenshot below the 1280x720 stream is publishing and playing. The published stream from the device camera is displayed above, and four playing streams are displayed below
Analyzing the code
To analyze the code let's take MultiPlayerSwift example, which can be downloaded from GitHub.
The class for main view of the application: MultiPlayerController (implementation file MultiPlayerController.swift).
1. Import of API
import FPWCSApi2Swift
2. Session creation and connection to server
WCSSession, WCSSession.connect code
The session options include:
- URL of WCS server
- appKey of server-side REST hook application (defaultApp)
@IBAction func startPressed(_ sender: Any) { ... if (startButton.title(for: .normal) == "PUBLISH AND PLAY") { if (session == nil) { let options = FPWCSApi2SessionOptions() options.urlServer = urlField.text options.appKey = "defaultApp" do { try session = WCSSession(options) } catch { print(error) } } ... session?.connect() } else { ... } }
3. Stream publishing
WCSSession.createStream, WCSStream.publish code
The following stream options are passed to createStream method:
- stream name
- view to display video
- width and height publishing constraint
func publish() { let options = FPWCSApi2StreamOptions() options.name = streamName.text options.display = localDisplay.videoView let ret = FPWCSApi2MediaConstraints() let video = FPWCSApi2VideoConstraints() video.minWidth = Int(widthField.text ?? "0") ?? 0 video.maxWidth = video.minWidth video.minHeight = Int(heightField.text ?? "0") ?? 0 video.maxHeight = video.minHeight ret.video = video options.constraints = ret do { publishStream = try session!.createStream(options) } catch { print(error); } ... do { try publishStream?.publish() } catch { print(error); } }
4. Start four stream instances playback after successful publishing
fileprivate func onPublishing(_ stream:FPWCSApi2Stream) { playStreamLT = self.play(display: remoteDisplayLT); playStreamRT = self.play(display: remoteDisplayRT); playStreamLB = self.play(display: remoteDisplayLB); playStreamRB = self.play(display: remoteDisplayRB); startButton.setTitle("STOP", for:.normal) changeViewState(startButton, true); changeViewState(switchCameraButton, true); }
5. Stream playback
WCSSession.createStream, WCSStream.play code
The following stream options are passed to createStream method:
- stream name
- view to display video
func play(display: WebRTCView) -> WCSStream? { let options = FPWCSApi2StreamOptions() options.name = streamName.text; options.display = display.videoView; do { let playStream = try session!.createStream(options) ... try playStream.play() return playStream; } catch { print(error); } return nil; }
6. Camera switching
WCSStream.switchCamera code
@IBAction func switchCameraPressed(_ sender: Any) { publishStream?.switchCamera() }
7. Playback stop when publishing is stopped
WCSStream.stop code
fileprivate func onUnpublished() { do { try playStreamLT?.stop(); } catch { print(error); } do { try playStreamRT?.stop(); } catch { print(error); } do { try playStreamLB?.stop(); } catch { print(error); } do { try playStreamRB?.stop(); } catch { print(error); } }
8. Closing the connection
WCSSession.disconnect code
@IBAction func startPressed(_ sender: Any) { changeViewState(startButton, false) changeViewState(urlField, false) changeViewState(streamName, false) if (startButton.title(for: .normal) == "PUBLISH AND PLAY") { ... session?.connect() } else { session?.disconnect() } }