NAV Navbar
iOS android javascript 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 obsesses 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 app in both Swift and Objective-C.

Visit firekast-demo-ios.

We provide sample app 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 :)

2. Run in terminal

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>

4. Initialize the SDK

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

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({
  api_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.

For Objective-C projects:

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

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. 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 AppStreamingCallback());
    }
  });
}

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.
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 AppCreateStreamCallback());

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.isVideoCaptureEnabled = false // turns camera off and streams a black screen

if camera.isFlashAvailable {
    camera.isFlashEnabled = true // 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.
// 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 AppPlayerCallback());

// 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.
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 metadata.isValidFirekastMetadata() else { return }
stream.updateMetadata(with: metadata) { (error) in
  //...
}
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 AppStreamCallback());
}
# 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.findAll(0, 100, null, new AppFindAllCallback());

Add a where clause to filter by state.

FKStream.findAll(where: .vod) { (numOfPages: Int, pageNumber: Int, pageSize: Int, count: Int, streams, error) in
  // ...
}
FKStream.findAll(0, 100, FKStream.State.VOD, new AppFindAllCallback());

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

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

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()
mStreamer.createStream(new AppCreateStreamCallback());

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)
mStreamer.startStreaming(stream, new AppStreamingCallback());

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()
mStreamer.stopStreaming()

Stop streaming

Then, stop streaming whenever your User is done.

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) {}
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 
  // ...
}
mStreamer.createStream(mListOfRtmpLink, new AppCreateStreamCallback());

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()
}
long durationMs = 15000;
mStreamer.startStreaming(FKStream.bandwidthTest, new AppStreamingCallback());
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.
}
@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
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)
}

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.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.

Events

func player(_ player: FKPlayer, stateDidChanged state: FKPlayer.State) {}
func player(_ player: FKPlayer, videoDurationIsAvailable duration: TimeInterval) {}
func player(_ player: FKPlayer, willPlay stream: FKStream, unless error: NSError?) {}
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
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.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.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.

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.