NAV Navbar
swift obj-c android JS cURL

Welcome

Welcome to Firekast! The best developer tools to bring live video streaming into your app without being a video expert.

Firekast is a Video as a Service platform, we provide iOS and Android SDKs to wrap camera usage, streaming, video encoding and player into something sweet and easy to use. Yes, you are 5 minutes away to make the next Periscope ๐Ÿ˜Ž

We are obsessed over developer experience and want this documentation to be as clear as possible. If you have any question, suggestion, feature request, feel free to contact us, we would love to hear from you.

Firekast Basics

Before we start, let's introduce some Firekast basics concepts. You may already be familiar with since we designed our service with well known SaaS platforms in mind.

Nothing in life is to be feared, it is only to be understood. Now is the time to understand more, so that we may fear less. -- Marie Curie

Apps

On your dashboard, you can create as many applications as you like.

A Firekast application has:

Each of these information are editable later.

An application can be deleted if you decide so.

API Keys

API keys allow to initialize SDKs so they can request our REST API. Firekast provides a set of two (renewable) API keys : one that must remain private and one that aims to be public.

Private key

Use this key to initialize mobile SDKs and make authorized HTTPS requests.

Public key

Use this key to initialize the web player.

ย SDK v1.5.x and before

Please refer to our sample app repository history for sample code using clientKey and applicationId.

We recommend that you upgrade regularly to the latest SDK version, as we keep adding new features based on your feedback.

Simultaneous Streamers

As soon as a streamer creates a live stream, it starts counting a new simultaneous streamer until the live session is done.

A stream with state waiting and live stream states increases by 1 the simultaneous streamer counter.

A stream with state timeout or vod stream states decreases by 1 the simultaneous streamer counter.

Active Users

In the current month, each new device (mobile or web) that reaches our server is counted as a new Active User.

Free Trial Terms

We recommand to upgrade your app to a paid plan before going to production.

Check out our pricing plans.

Free trial comes with the following limitations:

Sample Apps

We provide sample apps in both Swift and Objective-C.

Visit firekast-demo-ios.

We provide sample apps in both Kotlin and Java.

Visit firekast-demo-android.

To help you get started quickly and demonstrate how easy Firekast is, we provide sample applications available in our github page.

These apps are minimalist, 2 screens:

Getting Started

Installation

1. Edit your podfile

use_frameworks!

# Set the same version name X.Y.Z. for both Firekast and VideoCore pod.
pod 'Firekast', :podspec => 'https://firekast.io/sdk/ios/vX.Y.Z/Firekast.podspec'
pod 'VideoCore', :git => 'https://github.com/Firekast-io/VideoCore.git', :tag => 'fk-X.Y.Z'

# Please note, first `pod install` may be long, please be patient :)
use_frameworks!

# Set the same version name X.Y.Z. for both Firekast and VideoCore pod.
pod 'Firekast', :podspec => 'https://firekast.io/sdk/ios/vX.Y.Z/Firekast.podspec'
pod 'VideoCore', :git => 'https://github.com/Firekast-io/VideoCore.git', :tag => 'fk-X.Y.Z'

# Please note, first `pod install` may be long, please be patient :)

2. Run

> pod install
> pod install

3. Specify camera and microphone usage description in your info.pList

<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone usage description</string>
<key>NSCameraUsageDescription</key>
<string>Camera usage description</string>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone usage description</string>

4. Initialize the SDK

import Firekast

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    Firekast.initialize(privateKey: "YOUR_APP_PRIVATE_KEY")
    return true
  }

  //...
}
#import "Firekast/Firekast-Swift.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [Firekast initializeWithPrivateKey:@"YOUR_APP_PRIVATE_KEY"];
    return YES;
}

//...

@end

5. Edit your project Build Settings

Set Always Embed Swift Standard Libraries to Yes in your project Build Settings. Otherwise you will encounter a dyld: Library not loaded error.

1. Edit your project root build.gradle

allprojects {
    repositories {
        [...]
        maven { url 'https://dl.bintray.com/firekast/android' }
    }
}

2. Edit your app build.gradle

dependencies {
  implementation('io.firekast:firekast:X.Y.Z') // {
  //   exclude group: "com.android.support"
  // }
  // โ˜๏ธ Uncomment above lines if targeting API 26 and below
}

3. Add camera, record audio and internet permission in your AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

4. Initialize the SDK

Firekast.initialize(this, "YOUR_APP_PRIVATE_KEY");

1a. Import with script tag

<script src="https://firekast.io/sdk/js/latest/firekast.min.js"></script>

1b. Import with Webpack, Browserify...

const Firekast = require('firekast');

1c. Import with AMD module syntax

define(["firekast"], function(Firekast) { 
  //... 
});

2. Initialize the SDK

Firekast.init({
  public_key: 'YOUR_APP_PUBLIC_KEY'
});

Firekast iOS SDK is distributed via Cocoapods.

Firekast Android SDK is distributed via Gradle.

Several options are available to import Firekast Javascript SDK in your project.

Note that the JS SDK is not yet available on the public npm registry. Please, let us know if you would love so.

Live stream

// 1. Initializes the streamer
let streamer = FKStreamer(usecase: .portrait)

// 2. Open camera inside a view
let camera = streamer.showCamera(.front, in: aView) 

// 3. Create a stream and start streaming when ready
streamer.createStream { (stream, error) in 
  guard error == nil else { return } // Something went wrong, like you have reached your plan limit for example.
  streamer.startStreaming(on: stream, delegate: self)
}
// 1. Initializes the streamer
_streamer = [[FKStreamer alloc] initWithUsecase:FKStreamerOrientationPortrait];

// 2. Open camera inside a view
_camera = [_streamer showCamera:Front in:_aView];

// 3. Create a stream and start streaming when ready
[_streamer createStreamWithOutputs:nil completion:^(FKStream * stream, NSError *error) {
    if (error != nil) { return; } // Something went wrong, like you have reached your plan limit for example.
    [self->_streamer startStreamingOn:stream delegate:self];
}];
// 1. Load FKCameraFragment in your FrameLayout with id `camera_fragment`

@Override
protected void onCreate(Bundle savedInstanceState) {
  [...]
  FKCameraFragment cameraFragment = new FKCameraFragment();
  cameraFragment.getCameraAsync(this);
  getSupportFragmentManager().beginTransaction()
          .replace(R.id.camera_container, cameraFragment)
          .commit();
  [...]
} 

// 2. Get camera as soon as it's available

@Override
public void onCameraReady(@Nullable FKCamera camera, @Nullable FKStreamer streamer, @Nullable FKError error) {
  if (error != null) return; // Something went wrong, like device has no camera for example.  
  mCamera = camera;
  mStreamer = streamer;
}

// 3. Create a stream and start streaming when ready

public void handleClick(View view) {
  mStreamer.createStream(new FKStreamer.CreateStreamCallback() { 
    @Override
    public void done(@Nullable FKStream stream, @Nullable FKError error) {
      if (error != null) return; // Something went wrong, like you have reached your plan limit for example.
      mStreamer.startStreaming(stream, new FKStreamer.StreamingCallback() { ... });
    }
  });
}

Streams can be created using our mobile streaming SDKs.

The javascript SDK currently only supports live and vod content playback, not publishing.

This is all you need to do to live stream the device camera.

First, you must request for a stream and then, call start streaming method whenever your User is ready.

Restream simultaneously to multiple platforms

// 1. Checkout desired platforms API to create a RTMP link ready to receive a live stream.
let facebookRtmpLink = "rtmp://live-api-a.facebook.com:80/rtmp/143521800?ds=1&a=PEtMa1Ul0W3Rpa"
let youtubeRtmpLink = "rtmp://a.rtmp.youtube.com/live/hello_webcast"

// 2. Create a stream specifying restream outputs and start streaming when ready
streamer.createStream(outputs: [facebookRtmpLink, youtubeRtmpLink]) { (stream, error) in
  guard error == nil else { return } // Something went wrong, like you have reached your plan limit for example.
  streamer.startStreaming(on: stream, delegate: self)
}
// 1. Checkout desired platforms API to create a RTMP link ready to receive a live stream.
NSString* facebookRtmpLink = @"rtmp://live-api-a.facebook.com:80/rtmp/143521800?ds=1&a=PEtMa1Ul0W3Rpa";
NSString* youtubeRtmpLink = @"rtmp://a.rtmp.youtube.com/live/hello_webcast";
NSArray* outputs = [NSArray arrayWithObjects: facebookRtmpLink, youtubeRtmpLink, nil];

// 2. Create a stream specifying restream outputs and start streaming when ready
[_streamer createStreamWithOutputs:restream completion:^(FKStream * stream, NSError *error) {
    if (error != nil) { return; } // Something went wrong, like you have reached your plan limit for example.
    [self->_streamer startStreamingOn:stream delegate:self];
}];
// 1. Checkout desired platforms API to create a RTMP link ready to receive a live stream.
String facebookRtmpLink = "rtmp://live-api-a.facebook.com:80/rtmp/143521800?ds=1&a=PEtMa1Ul0W3Rpa";
String youtubeRtmpLink = "rtmp://a.rtmp.youtube.com/live/hello_webcast";

// 2. Create a stream specifying restream outputs and start streaming when ready
List outputs = new ArrayList<>();
outputs.add(facebookRtmpLink);
outputs.add(youtubeRtmpLink);
mStreamer.createStream(outputs, new FKStreamer.CreateStreamCallback() { ... });

Firekast allows to push your live stream simultaneously to other live streaming platforms and social medias, such as Facebook, Youtube, Twitch, Periscope etc...

Camera Features

camera.position = .back // opens back camera

camera.isAudioCaptureEnabled = false // mutes the microphone
camera.isImageCaptureEnabled = false // turns camera off and streams a black screen

if camera.isFlashAvailable {
    camera.isFlashEnabled = true // turns flash on
}

camera.capture() // cheeeese!
[_camera setPosition:Back]; // opens back camera

[_camera setIsAudioCaptureEnabled:NO]; // mutes the microphone
[_camera setIsImageCaptureEnabled:NO]; // turns camera off and streams a black screen

if ([_camera isFlashAvailable]) {
  [_camera setIsFlashEnabled:YES]; // turns flash on
}

[_camera capture]; // cheeeese!
mCamera.switchToPosition(Position.BACK); // opens back camera

mCamera.setAudioCaptureEnabled(false); // mutes microphone
mCamera.setVideoCaptureEnabled(false); // turns camera off and streams a black screen

if (mCamera.isFlashAvailable()) {
    mCamera.setFlashEnabled(true); // turn flash on
}

mCamera.capturePreview(this) // cheeeese!

Adding camera often leads to boilerplate codes, especially on Android where you must pay attention on your Activity or Fragment lifecycle to release the Camera.

Our SDK manages everything for you and provides a simple interface to interact with commonly used features.

Watch live or replay as VOD

let player = FKPlayer() // 1. initialize player
player.show(in: aView) // 2. display player in myView
player.delegate = self

let stream = FKStream(withoutDataExceptStreamId: "STREAM_ID")
player.play(stream) // 3. play the video starting - in that example - from the beginning.
#import "CoreMedia/CoreMedia.h"

_player = [[FKPlayer alloc] init]; // 1. initialize player
[_player showIn:_aView]; // 2. display player in myView
[_player setDelegate:self];

FKStream* stream = [[FKStream alloc] initWithWithoutDataExceptStreamId:@"STREAM_ID"];
[_player play:stream at:kCMTimeZero]; // 3. play the video starting - in that example - from the beginning.
// 1. add the player view in your layout
<io.firekast.FKPlayerView
    android:id="@+id/playerView"
    android:layout_width="200dp"
    android:layout_height="110dp" />

// 2. get the player from the view
mPlayer = mPlayerView.getPlayer();
mPlayer.setCallback(new FKPlayer.Callback() { ... });

// 3. play the stream starting - in that example - from the beginning.
FKStream stream = FKStream.newEmptyInstance("STREAM_ID")
mPlayer.play(stream);

The player wraps around clappr.

<div id="player"></div>
<script>
  Firekast.API.init({
    public_key: 'YOUR_APP_PUBLIC_KEY'
  });
  const player = new Firekast.Player({
    parent_id:   '#player',
    stream_id:   'STREAM_ID'
  });
</script>

The player figures out whether the stream is live or VOD. Its UI gets updated accord accordingly.

Making HTTP requests

Authorization header using your app's api key.

curl https://api.firekast.io/v2/apps/myapp/streams \
    -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%'

switch language tab to 'cURL' to view sample HTTP requests

You can use your private key to make authorized http requests to out API.

Check out our full REST API documentation

SDK - Stream

A stream describes one video content. A stream is unique and is associated to an application.

id

Fetch a stream from our API using its ID:

curl https://api.firekast.io/v2/streams/%YOUR-STREAM-ID% -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%'

Delete a stream:

# This operation is not recoverable.
curl -X DELETE \
    https://api.firekast.io/v2/streams/%YOUR-STREAM-ID% \
    -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%' 

The unique identifier for a stream, assigned once at the stream creation time (createStream). It is available though mobile SDKs, visible in the dashboard, and looks like d17j39tg4noar25g3.

state

During its life time, a stream goes though predefined states:

The typical live stream lifecycle is waiting โ†’ live โ†’ vod.

If a stream has been waiting but never received video data from the streamer, it transitions to timeout.

If a stream is live and stops receiving video data, it transitions to vod.

timeout

let timeout: Date = stream.ingestTimeout // available only when stream's state is .waiting.
NSDate* timeout = [stream ingestTimeout]; // available only when stream's state is .waiting.
Date timeout = stream.getIngestTimeout() // available only when stream's state is WAITING.

The stream timeout deadline (ingestTimeout) is a date available while a stream state is waiting. After that date, if a streamer hasn't started streaming, the stream's state transitions to timeout. It can no longer serve a live broadcast, and doesn't yield any content for playback.

If your application no longer uses a stream, you should stop it explicitely to ensure it frees ressources allocated and immediately stops counting against your simultanous streamers quota.

metadata

Update stream's metadata:

let metadata = ["title":"Awesome title", "description": "An awesome video with awesome people."]
guard FKStream.isMetadataValid(metadata) else { return }
stream.updateMetadata(with: metadata) { (error) in
  //...
}
NSDictionary *metadata = @{
                  @"title" : @"Awesome title",
                  @"description" : @"An awesome video with awesome people."
                };
if ([FKStream isMetadataValid:metadata]) {
  [stream updateMetadataWith:metadata completion:^(NSError * error) {
    //...
  }];
}
Map<String, String> metadata = new HashMap<>();
metadata.put("title", "Awesome title");
metadata.put("description", "An awesome video with awesome people.");
if (FKStream.isMetadataValid(metadata)) {
    mStream.updateMetadata(metadata, new FKStream.Callback() { ... });
}
# The metadata string must be a valid json string.
curl -X PUT \
    https://api.firekast.io/v2/streams/%STREAM-ID% \
    -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%' \
    -d 'metadata={"field":"value","field2":"value2","field3":"value3"}'

metadata is a useful stream's property, which you can use to store structured information, by providing a map of key / pair string values.

It can be updated as soon as the stream is created and can be retrieved by fetching the stream.

Query

Fetch your app's streams, starting with the most recent.

#ย with states: all, live, timeout, waiting, vod, processing 
curl https://api.firekast.io/v2/apps/myapp/streams \
    -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%' \
    -F state=all \
    -F pageNumber=1 \
    -F pageSize=20
FKStream.findAll() { (numOfPages: Int, pageNumber: Int, pageSize: Int, count: Int, streams, error) in
  //...
}
[FKStream findAllWithWhere:FKStreamStateUnknown pageNumber: 0 pageSize: 100 completion:^(NSInteger numOfPages, NSInteger pageNumber, NSInteger pageSize, NSInteger count, NSArray<FKStream *> *streams, NSError * error) {
  //...
}];
FKStream.findAll(0, 100, null, new FKStream.FindAllCallback() { ... });

Add a where clause to filter by state.

FKStream.findAll(where: .vod) { (numOfPages: Int, pageNumber: Int, pageSize: Int, count: Int, streams, error) in
  //...
}
[FKStream findAllWithWhere:FKStreamStateVod pageNumber: 0 pageSize: 100 completion:^(NSInteger numOfPages, NSInteger pageNumber, NSInteger pageSize, NSInteger count, NSArray<FKStream *> *streams, NSError * error) {
  //...
}];
FKStream.findAll(0, 100, FKStream.State.VOD, new FKStream.FindAllCallback() { ... });

We provide an easy way to fetch your app's streams.

However, we recommend that you manage the streamIDs in your own backend.

Force Close

stream.forceClose { (error) in
  //...
}
[stream forceCloseWithCompletion:^(NSError * error) {
  //...
}];
mStream.forceClose(new FKStream.Callback() { ... });

Call this function when your user has created a stream but abandoned the idea of going live. That way, the stream moves from state waiting to timeout instantaneously and your plan's simultaneous streamer counter decreases by 1.

SDK - Streamer

Streams can be created using mobile SDKs.

The javascript SDK currently only supports live and vod content playback, not publishing.

The streamer is responsible for creating streams and actually sends frames and audio for live streaming.

Create Streams

streamer.createStream { (stream, error) in
  //...
}
[_streamer createStreamWithOutputs:nil completion:^(FKStream * stream, NSError * error) {
  //...     
}];
mStreamer.createStream(new FKStreamer.CreateStreamCallback() { ... });

First step to do live broadcasting is to create a stream.

This call provisions server resources to handle live streaming, create and returns a stream with state waiting. Waiting for frames and audio to be sent.

This newly created stream is immediatly visible in your dashboard.

Go Live

Start streaming:

streamer.startStreaming(on: stream, delegate: self)
[_streamer startStreamingOn:stream delegate:self];
mStreamer.startStreaming(stream, new FKStreamer.StreamingCallback() { ... });

Start streaming

Once you have created a stream, you can start streaming whenever your User is ready.

Stop streaming:

curl -X POST \
    https://api.firekast.io/v2/streams/%STREAM-ID%/stop \
    -H 'Authorization: SDK %YOUR-APP-PRIVATE-KEY%' 
streamer.stopStreaming()
[_streamer stopStreaming];
mStreamer.stopStreaming()

Stop streaming

Then, stop streaming whenever your User is done.

Streamer Events

func streamer(_ streamer: FKStreamer, willStart stream: FKStream, unless error: NSError?) {}
func streamer(_ streamer: FKStreamer, didBecomeLive stream: FKStream) {}
func streamer(_ streamer: FKStreamer, didStop stream: FKStream, error: NSError?) {}
func streamer(_ streamer: FKStreamer, didUpdateStreamHealth health: Float) {}
- (void)streamer:(FKStreamer *)streamer willStart:(FKStream *)stream unless:(NSError *)error {}
- (void)streamer:(FKStreamer *)streamer didBecomeLive:(FKStream *)stream {}
- (void)streamer:(FKStreamer *)streamer didStop:(FKStream *)stream error:(NSError *)error {}
- (void)streamer:(FKStreamer *)streamer didUpdateStreamHealth:(float)health {}
private class AppStreamingCallback implements FKStreamer.StreamingCallback {
  @Override
  public void onSteamWillStartUnless(@NonNullable FKStream stream, @Nullable FKError error) {}

  @Override
  public void onStreamDidBecomeLive(@NonNullable FKStream stream) {}

  @Override
  public void onStreamDidStop(@NonNullable FKStream stream, FKError error) {}

  @Override
  public void onStreamingUpdateAvailable(boolean lag) {}
}

Your app can rely on the streamer events to adapt its UI. Events notify whether the live streaming has started properly or failed, stopped normally or prematurely, and how the live stream is performing.

Restream

streamer.createStream(outputs: listOfRtmpLink) { (stream, error) in 
  // ...
}
[_streamer createStreamWithOutputs:listOfRtmpLink completion:^(FKStream * stream, NSError * error) {
  // 
}];
mStreamer.createStream(mListOfRtmpLink, new FKStreamer.CreateStreamCallback() { ... });

Firekast allows to push your live stream simultaneously to other live streaming platforms and social medias, such as Facebook, Youtube, Twitch, Periscope etc...

Refer to the targeted platform API docs to find out how to generate a live stream and get its RTMP link.

Test Bandwidth

Testing bandwidth for 15 seconds

let testDuration: TimeInterval = 15
streamer.startStreaming(on: FKStream.bandwidthTest, delegate: self)
DispatchQueue.main.asyncAfter(deadline: .now() + testDuration) { [weak self] in
  guard let this = self else { return }
  this.streamer.stopStreaming()
}
double testDuration = 15.0;
[_streamer startStreamingOn:[FKStream bandwidthTest] delegate:self];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(testDuration * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
  [self->_streamer stopStreaming];
});
long durationMs = 15000;
mStreamer.startStreaming(FKStream.bandwidthTest, new FKStreamer.StreamingCallback() {ย ... });
mHandler.sendEmptyMessageDelayed(MSG_TEST_BANDWIDTH_STOP_STREAMING, durationMs)

Observe stream health

func streamer(_ streamer: FKStreamer, didUpdateStreamHealth health: Float) {
  // stream health between 70-100% is good.
}
- (void)streamer:(FKStreamer *)streamer didUpdateStreamHealth:(float)health {
  // stream health between 70-100% is good.
}
@Override
public void onStreamHealthDidUpdate(boolean congestion, float health) {
    // congestion means frames and audio is waiting for network to be sent. Note that, while congested, the camera preview stucks on the frame and will resume as soon as data is sent.
    // stream health between 70-100% is good.
}

Run a test bandwidth to know whether the network is good enough to provide a healthy live stream.

Running a test bandwidth consists of streaming on a dummy stream FKStream.testBandwidth, that our server recognizes and whose frames and audio are not recorded. Then, while streaming, observe onStreamDidUpdate's streamer callback to estimate the global streaming performance of the test.

The stream health indicates how the live stream is performing. A stream health around 70-100% indicates that the live stream is good.

If the stream health falls below this range for a consistent period, it suggests the network may not be capable of providing a healthy live stream.

Quality

streamer.quality = .standard
[_streamer setQuality:FKQualityStandard];
mStreamer.setQuality(FKQuality.STANDARD);

Mobile SDKs stream at the highest possible resolution allowed by your plan.

In case your internet connection does not provide sufficient bandwidth, SDK will degrade encoding quality to keep up with available bandwidth at the target resolution.

However, we still encourage to run a test bandwidth before creating a stream. Depending on the outcome of that test, you may decide to start streaming at a lower resolution in order to provide your Users a smooth streaming experience and consistent image quality.

SDK - Player

The player lets you play any stream of your current application. Whether the stream is live or VOD, the player will figure it out and adapt its UI.

Initialization

The player is based on AVPlayerViewController.

override func viewDidLoad() {
  super.viewDidLoad()
  player = FKPlayer()
  player.delegate = self
  player.show(in: playerContainerView)
}
- (void)viewDidLoad {
  [super viewDidLoad];
  _player = [[FKPlayer alloc] init];
  [_player setDelegate:self];
  [_player showIn:_ibPlayerView];
}

The player is based on ExoPlayer and is wrapped into a simple view.

// In your layout:

<io.firekast.FKPlayerView
  android:id="@+id/playerView"
  android:layout_width="match parent" 
  android:layout_height="110dp" />

// Then in your code:

mPlayerView = (FKPlayerView) findViewById(R.id.playerView);
mPlayer = mPlayerView.getPlayer();

The player wraps around clappr.

<div id="player"></div>
<script>
  Firekast.API.init({
    public_key: 'YOUR_APP_PUBLIC_KEY'
  });
  const player = new Firekast.Player({
    parent_id:   '#player',
    stream_id:   'STREAM_ID'
  });
</script>

For each platform, we wrapped the most common player and its methods to make it simpler and expose what's count.

Play and Stop

let stream = FKStream(withoutDataExceptStreamId: "STREAM_ID")
player.play(stream)
player.pause()
player.resume()
import CoreMedia

player.seek(to: CMTime(seconds: 30, preferredTimescale: 1))
FKStream* stream = [[FKStream alloc] initWithWithoutDataExceptStreamId:"STREAM_ID"];
[_player play:stream at:kCMTimeZero];
[_player resume];
[_player pause];
#import "CoreMedia/CoreMedia.h"

[_player play:stream at:CMTimeMake(30, 1)];
FKStream stream = FKStream.newEmptyInstance("STREAM_ID")
mPlayer.play(stream);
mPlayer.pause();
mPlayer.resume();
mPlayer.seek(TimeUnit.SECONDS.toMillis(30));
player.on('ready', () => {
  player.play();
});
player.stop();

The following methods are also available.

player.pause()
player.seek(seconds:Number)
player.mute()
player.setVolume(percent:Number)
player.getCurrentTime():Number
player.getDuration():Number
player.isPlaying():Boolean
player.destroy()

The player aims to be very simple.

Call play to start playing the stream right away, whether the stream is live or VOD.

The playback controller UI adapts automatically depending on the state of the stream.

Once playing, video can be paused and resumed programmatically if needed.

Use seek to set the current playback time to a specified time.

When playing a live that finally reaches its ends, the playback stops at the end of the live and allows to replay the stream as a VOD.

Player Events

func player(_ player: FKPlayer, willPlay stream: FKStream, unless error: Error?) {}    
func player(_ player: FKPlayer, stateDidChanged state: FKPlayer.State) {}
- (void)player:(FKPlayer *)player willPlay:(FKStream *)stream unless:(NSError *)error {}
- (void)player:(FKPlayer *)player stateDidChanged:(enum FKPlayerState)state {}
mPlayer.setCallback(new FKPlayer.Callback() {
  @Override
  public void onPlayerWillPlay(@NonNull FKStream stream, @Nullable FKError error) {}
  @Override
  public void onPlayerStateChanged(@NonNull FKPlayer.State state) {}
});
const events = [
  'ready',
  'play',
  'stop',
  'ended',
  'error',
  'timeupdate',
  'volumechange',
  'seek',
  'resize'
];

events.forEach( event => {
  player.on('ready', () => console.log(`Player emitted ${event}`));
});

player.on('ready', () => player.play());

You may want to listen for player callback so you can update your UI accordingly.

Note that the stream may need to be fetched (automatically by the SDK) first before it can be played. For some reason it is possible that the request fails. You should definitely notify your User about that failure so User can retry eventually.

UI Customization

player.videoGravity = .resizeAspectFill
player.showPlaybackControls = false
[_player setVideoGravity:FKPlayerVideoGravityResizeAspectFill];
[_player setShowPlaybackControls:NO];
mPlayer.setShowPlaybackControls(true); // default is true
mPlayer.setPlaybackControlsMargins(...); // default is 8dp
mPlayer.setPlaybackControlsBackground(R.drawable.my_player_controls_background); // default is a 8dp rounded semi-transparent black rectangle
const player = new Firekast.Player({
  [...]
  clappr_config: {
    mediacontrol: { seekbar: "#E113D3", buttons: "#66B2FF" }
  }
});

We provide basic customization of the playback controls UI.

Note that AVPlayerViewController provides very little control over the UI. We only wrapped what we found useful.

Please let us know if you need more control over the player UI.

Release Notes

Follow what's new in Firekast SDK releases.

v1.7.12019-06-01

Built with Swift 5.0.1 (Xcode 10.2.1).
* Streaming stopped before stream becomes LIVE causes the stream to be force closed. This helps us to release server's resources and free up spaces on your plan as soon as possible.
* Fixes the Firekast framework so it compiles and runs on simulators.

v1.7.02019-04-24

Built with Swift 5.0 (Xcode 10.2).
* Player can be muted.
* By default, player starts to play immediately, otherwise call play(self.stream, playImmediately: false) to override this behavior.
* Fix player crash: 'Cannot remove an observer for the key path because it is not registered as an observer.'.

v1.6.12019-04-09

Built with Swift 5.0 (Xcode 10.2).
* Support Swift 5.0

v1.6.02019-03-20

Built with Swift 4.2.1 (Xcode 10.1).
* Security: new API auth keys available in your app settings. Use privateKey to initialize the SDK instead of deprecated clientKey and applicationID. This key must remain confidential.
* Errors: description readibility has been improved to help support.
* Restream: we decided to let you choose the platform to which you want to live stream. You are no longer dependent on our implementation, provide us with the RTMP link and that's it. So FKOutput has been abandonned.
* Delegate's methods in Swift code now support Error instead of NSError.
* Test Bandwidth: start streaming on FKStream.bandwidthTest stream and observe FKStreamerDelegate.didUpdateStreamHealth(...).
* FKStreamer:
  * requestStream becomes createStream.
  * stream in delegate's methods is no more optional since it is actually always known.
  * quality: ability to change the quality for the next created streams.
  * We have replaced the network quality measure with the notion of stream health. Method networkQualityDidUpdate becomes didUpdateStreamHealth. We consider that 70% is the minimum rate for a healthy live stream. Moreover, this value has become more reliable.
  * Objective-C streamer orientation constants are now prefixed with FKStreamerOrientation.
* FKStream: 
  * Query for your app's streams using findAll(...).
  * forceClose() allows to force close a stream in case your User created a stream and you know for sure that User will finally not go live.
  * Objective-C FKStream's streamId becomes id.

v1.5.02019-01-25

Built with Swift 4.2.1 (Xcode 10.1).
* Abality to disable video capture while streaming with isVideoCaptureEnabled.
* Renaming isMicrophoneEnabled into isAudioCaptureEnabled.

v1.4.02019-01-16

Built with Swift 4.2.1 (Xcode 10.1).
New:
* Replace internal use of MPMoviePlayerController (deprecated) with AVPlayerViewController. Implementation changes slightly: 
  * FKPlayerDelegate is now set to FKPlayer and no more passed through FKPlayer.play(_:at:).  
  * Show or hide native playback controls using FKPlayer.showPlaybackControls().
  * While playing, control programmatically the playback with FKPlayer.pause(), FKPlayer.resume() or FKPlayer.seek(to:).
  * Get the current playback position with FKPlayer.currentTime.
  * ScalingMode becomes FKPlayer.VideoGravity.

v1.3.32018-11-29

Build with Swift 4.2 (Xcode 10).
New:
* AppStore distribution bug fix.
* Framework includes bitcode.

v1.3.12018-11-20

Build with Swift 4.2 (Xcode 10).
New:
* Add FKStreamerDelegate.streamer(_:didBecomeLive:) that notifies as soon as the stream is LIVE on Firekast Servers, meaning the stream is broadcast and VOD is getting recorded.

v1.3.02018-10-11

Build with Swift 4.2 (Xcode 10).
New:
* Support Swift 4.2
* FKPlayer supports controlStyle and scaleMode options

v1.2.22018-09-27

Build with Swift 4.1.2 (Xcode 9.4.1).
New:
* Call capture() on camera to get a snapshot of the camera preview

v1.2.12018-09-20

Build with Swift 4.1.2 (Xcode 9.4.1).
Fixes:
* Optimizes streaming for portrait or orientation 

v1.2.02018-09-20

Build with Swift 4.1.2 (Xcode 9.4.1).
What's new:
* Objective-C retro-compatible
* FKError replaced by NSError for Objective-C retro-compatibility
* NSError extension method: fk() to convert NSError into FKError 

v1.1.12018-04-20

Built with Swift 4.1 (Xcode 9.3).
What's new:
* Minor fixes

v1.1.02018-01-08

Built with Swift 4.0.3 (Xcode 9.2).
What's new:
* 100% documented.
* Refactoring, Streamer and Player, functions and parameters should be more straight forward.
* Live stream on **Facebook** and/or **Youtube** and Firekast simultaneous. See LiveStreamingPlatform.
* Use **camera features** by enabling torch, microphone, choosing your device's camera. See Camera.

v1.0.02017-05-24

Built with Swift 3.1
First release of FirekastStreamer and FirekastPlayer to stream and play video with its streamId.

v1.7.32019-09-02

* Set the camera view scale type: CENTER_CROP or CENTER_INSIDE (cf. FKCameraFragment.Builder).

v1.7.22019-06-01

* Streaming stopped before stream becomes LIVE causes the stream to be force closed. This helps us to release server's resources and free up spaces on your plan as soon as possible.
* Fixes camera opening bug on devices that do not support flash.

v1.7.12019-05-11

* Streamer internal optimizations.

v1.7.02019-04-24

* Player can be muted.
* By default, player starts to play immediately, otherwise call play(FKStream stream, long atTimeInMillis, boolean playImmediately) to override this behavior.
* Add FKPlayer reference in FKPlayer.Callback's methods.

v1.6.02019-03-20

* Min SDK version is now 19 (was 16).
* Security: new API auth keys available in your app settings. Use privateKey to initialize the SDK instead of deprecated clientKey and applicationID. This key must remain confidential.
* Errors: readibility has been improved to help support.
* Restream: we decided to let you choose the platform to which you want to live stream. You are no longer dependent on our implementation, provide us with the RTMP link and that's it. So FKOutput has been abandonned.
* Test Bandwidth: start streaming on FKStream.bandwidthTest stream and observe FKStreamer.StreamingCallback.onStreamHealthDidUpdate(...).
* FKStreamer:
  * requestStream becomes createStream.
  * RequestStreamCallback becomes CreateStreamCallback.
  * onStreamingUpdateAvailable becomes onStreamHealthDidUpdate indicating when camera is freezing on screen because of data congestion and providing a rate for 0 to 1 that indicates how the stream is performing. We consider that 70% is the minimum rate for a healthy live stream.
  * setQuality(FKQuality target) allows to change the quality for the next created streams.
* FKStream: 
  * Query for your app's streams using findAll(...).
  * forceClose() allows to force close a stream in case your User created a stream and you know for sure that User will finally not go live.

Bug fix:

- isStreaming() is now false in onStreamDidStop.
- getCameraAsync() indeed was not returning the camera in very rare corner case.
- switchCamera() is now synchoneous so your app can update its UI right after the call.
- Camera flash availability and turn on/off was not reliable.
  

v1.5.02019-01-28

* Abality to disable video capture while streaming with setVideoCaptureEnabled.
* Renaming setMicrophoneEnabled into setAudioCaptureEnabled.
* Fix FKPlayer.Callback#onPlayerWillPlay(FKStream, FKError) that used to be called with error null when reaching the end of a live stream.

v1.4.02019-01-16

* FKPlayer refactoring. What's changed:
   * Use play(FKStream stream, long at) to start playing the given stream at a specific time.
   * While playing, use pause() and resume().
   * Call getCurrentPosition() to get the current playback position in time.
   * Call getState() to retrieve the current player state and setCallback(FKPlayer.Callback callback) to track events.
   * Call setPlaybackConstrolsMargins and setPlaybackControlsBackground to customize the playback controls UI.
   * Finally, call release() when the player is no longer required.

v1.2.52019-01-03

* Returns the player's playback position, in milliseconds.
* Bug fixes

v1.2.42018-11-30

* Add FKPlayerView.Callback#onPlayerStateChanged(boolean playWhenReady, int playbackState) callback to notify of player's state changes.

v1.2.32018-11-20

* Add FKStreamer.StreamingCallback#onStreamDidBecomeLive(@NonNull FKStream stream) callback to notify as soon as flagged LIVE on Firekast Servers, meaning the stream is actually live.

v1.2.22018-11-09

* Add support for emulators (Android Virtual Devices) ๐ŸŽ‰. Apps embedding the SDK can run on AVD but note that streaming is only possible for AVD with API 23 and above.

v1.2.12018-09-27

* ExoPlayer`'s PlayerView accessor available in FKPlayerView`

v1.2.02018-09-17

* Specify ExoPlayer dependency is not required anymore in dependencies

v1.1.22018-06-21

* HTTP request bug fix.

v1.1.12018-05-11

What's new:
* Fix aspect ratio issue.
* Fix camera position issue in FKCameraFragment.Builder.
* Retrieve FKStreamer in FKCamera ready callback. 

v1.1.02018-03-29

What's new:
* 100% documented.
* Refactoring, FKStreamer and FKPlayerView, functions and parameters should be more straight forward.
* Introducing FKStream object with its stream id, state and more. 
* Live stream on **Facebook** and/or **Youtube** and Firekast simultaneous. See FKOutput.
* Use **camera features** by enabling torch, microphone, choosing your device's camera. See FKCamera.

v1.0.02017-05-25

First release.
The lastest player is available at https://firekast.io/sdk/js/latest/firekast.min.js

v1.1.02019-03-21

Support API v2 API key

v1.0.12018-11-22

Minor bugfix.
Update player engine.

v1.0.02018-04-19

Inital release.
Play Firekast.io live and VOD videos on your website.