Android Open Source - kickflip-android-sdk Kickflip






From Project

Back to project page kickflip-android-sdk.

License

The source code is released under:

Apache License

If you think the Android project kickflip-android-sdk listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package io.kickflip.sdk;
/*from ww w .j a v a 2s  . co m*/
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import com.google.common.eventbus.EventBus;

import java.io.File;
import java.io.IOException;

import io.kickflip.sdk.activity.BroadcastActivity;
import io.kickflip.sdk.activity.GlassBroadcastActivity;
import io.kickflip.sdk.activity.MediaPlayerActivity;
import io.kickflip.sdk.api.KickflipApiClient;
import io.kickflip.sdk.api.KickflipCallback;
import io.kickflip.sdk.api.json.Stream;
import io.kickflip.sdk.av.BroadcastListener;
import io.kickflip.sdk.av.SessionConfig;
import io.kickflip.sdk.event.StreamLocationAddedEvent;
import io.kickflip.sdk.location.DeviceLocation;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * This is a top-level manager class for all the fundamental SDK actions. Herer you can register
 * your Kickflip account credentials, start a live broadcast or play one back.
 * <p/>
 * <h2>Setup</h2>
 * Before use Kickflip must be setup with your Kickflip Client ID and Client Secret with
 * {@link #setup(android.content.Context, String, String)}. These tokens are available in your kickflip
 * account dashboard.
 * <h2>Example Usage</h2>
 * <b>Starting a single live broadcast</b>
 * <p/>
 * <ol>
 * <li>{@link #setup(android.content.Context, String, String)}</li>
 * <li>(Optional) {@link #setSessionConfig(io.kickflip.sdk.av.SessionConfig)}</li>
 * <li>{@link #startBroadcastActivity(android.app.Activity, io.kickflip.sdk.av.BroadcastListener)}</li>
 * </ol>
 * The {@link io.kickflip.sdk.activity.BroadcastActivity} will present a standard camera UI with controls
 * for starting and stopping the broadcast. When the broadcast is stopped, BroadcastActivity will finish
 * after notifying {@link io.kickflip.sdk.av.BroadcastListener#onBroadcastStop()}.
 * <p/>
 * <br/>
 * <b>Customizing broadcast parameters</b>
 * <p/>
 * As noted above, you can optionally call {@link #setSessionConfig(io.kickflip.sdk.av.SessionConfig)} before
 * each call to {@link #startBroadcastActivity(android.app.Activity, io.kickflip.sdk.av.BroadcastListener)}.
 * Here's an example of how to build a {@link io.kickflip.sdk.av.SessionConfig} with {@link io.kickflip.sdk.av.SessionConfig.Builder}:
 * <p/>
 * <code>
 *   SessionConfig config = new SessionConfig.Builder(mRecordingOutputPath)
 *     <br/>&nbsp.withTitle(Util.getHumanDateString())
 *     <br/>&nbsp.withDescription("Example Description")
 *     <br/>&nbsp.withVideoResolution(1280, 720)
 *     <br/>&nbsp.withVideoBitrate(2 * 1000 * 1000)
 *     <br/>&nbsp.withAudioBitrate(192 * 1000)
 *     <br/>&nbsp.withAdaptiveStreaming(true)
 *     <br/>&nbsp.withVerticalVideoCorrection(true)
 *     <br/>&nbsp.withExtraInfo(extraDataMap)
 *     <br/>&nbsp.withPrivateVisibility(false)
 *     <br/>&nbsp.withLocation(true)
 *
 *     <br/>&nbsp.build();
 *    <br/>Kickflip.setSessionConfig(config);
 *
 * </code>
 * <br/>
 * Note that SessionConfig is initialized with sane defaults for a 720p broadcast. Every parameter is optional.
 */
public class Kickflip {
    public static final String TAG = "Kickflip";
    private static Context sContext;
    private static String sClientKey;
    private static String sClientSecret;

    private static KickflipApiClient sKickflip;

    // Per-Stream settings
    private static SessionConfig sSessionConfig;          // Absolute path to root storage location
    private static BroadcastListener sBroadcastListener;

    /**
     * Register with Kickflip, creating a new user identity per app installation.
     *
     * @param context the host application's {@link android.content.Context}
     * @param key     your Kickflip Client Key
     * @param secret  your Kickflip Client Secret
     * @return a {@link io.kickflip.sdk.api.KickflipApiClient} used to perform actions on behalf of a
     * {@link io.kickflip.sdk.api.json.User}.
     */
    public static KickflipApiClient setup(Context context, String key, String secret) {
        return setup(context, key, secret, null);
    }

    /**
     * Register with Kickflip, creating a new user identity per app installation.
     *
     * @param context the host application's {@link android.content.Context}
     * @param key     your Kickflip Client Key
     * @param secret  your Kickflip Client Secret
     * @param cb      A callback to be invoked when Kickflip user credentials are available.
     * @return a {@link io.kickflip.sdk.api.KickflipApiClient} used to perform actions on behalf of
     * a {@link io.kickflip.sdk.api.json.User}.
     */
    public static KickflipApiClient setup(Context context, String key, String secret, KickflipCallback cb) {
        sContext = context;
        setApiCredentials(key, secret);
        return getApiClient(context, cb);
    }

    private static void setApiCredentials(String key, String secret) {
        sClientKey = key;
        sClientSecret = secret;
    }

    /**
     * Start {@link io.kickflip.sdk.activity.BroadcastActivity}. This Activity
     * facilitates control over a single live broadcast.
     * <p/>
     * <b>Must be called after {@link Kickflip#setup(android.content.Context, String, String)} or
     * {@link Kickflip#setup(android.content.Context, String, String, io.kickflip.sdk.api.KickflipCallback)}.</b>
     *
     * @param host     the host {@link android.app.Activity} initiating this action
     * @param listener an optional {@link io.kickflip.sdk.av.BroadcastListener} to be notified on
     *                 broadcast events
     */
    public static void startBroadcastActivity(Activity host, BroadcastListener listener) {
        checkNotNull(listener, host.getString(R.string.error_no_broadcastlistener));
        if (sSessionConfig == null) {
            setupDefaultSessionConfig();
        }
        checkNotNull(sClientKey);
        checkNotNull(sClientSecret);
        sBroadcastListener = listener;
        Intent broadcastIntent = new Intent(host, BroadcastActivity.class);
        broadcastIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        host.startActivity(broadcastIntent);
    }

    public static void startGlassBroadcastActivity(Activity host, BroadcastListener listener) {
        checkNotNull(listener, host.getString(R.string.error_no_broadcastlistener));
        if (sSessionConfig == null) {
            setupDefaultSessionConfig();
        }
        checkNotNull(sClientKey);
        checkNotNull(sClientSecret);
        sBroadcastListener = listener;
        Log.i(TAG, "startGlassBA ready? " + readyToBroadcast());
        Intent broadcastIntent = new Intent(host, GlassBroadcastActivity.class);
        broadcastIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        host.startActivity(broadcastIntent);
    }

    /**
     * Start {@link io.kickflip.sdk.activity.MediaPlayerActivity}. This Activity
     * facilitates playing back a Kickflip broadcast.
     * <p/>
     * <b>Must be called after {@link Kickflip#setup(android.content.Context, String, String)} or
     * {@link Kickflip#setup(android.content.Context, String, String, io.kickflip.sdk.api.KickflipCallback)}.</b>
     *
     * @param host      the host {@link android.app.Activity} initiating this action
     * @param streamUrl a path of format https://kickflip.io/<stream_id> or https://xxx.xxx/xxx.m3u8
     * @param newTask   Whether this Activity should be started as part of a new task. If so, when this Activity finishes
     *                  the host application will be concluded.
     */
    public static void startMediaPlayerActivity(Activity host, String streamUrl, boolean newTask) {
        Intent playbackIntent = new Intent(host, MediaPlayerActivity.class);
        playbackIntent.putExtra("mediaUrl", streamUrl);
        if (newTask) {
            playbackIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        }
        host.startActivity(playbackIntent);
    }

    /**
     * Convenience method for attaching the current reverse geocoded device location to a given
     * {@link io.kickflip.sdk.api.json.Stream}
     *
     * @param context  the host application {@link android.content.Context}
     * @param stream   the {@link io.kickflip.sdk.api.json.Stream} to attach location to
     * @param eventBus an {@link com.google.common.eventbus.EventBus} to be notified of the complete action
     */
    public static void addLocationToStream(final Context context, final Stream stream, final EventBus eventBus) {
        DeviceLocation.getLastKnownLocation(context, false, new DeviceLocation.LocationResult() {
            @Override
            public void gotLocation(Location location) {
                stream.setLatitude(location.getLatitude());
                stream.setLongitude(location.getLongitude());

                try {
                    Geocoder geocoder = new Geocoder(context);
                    Address address = geocoder.getFromLocation(location.getLatitude(),
                            location.getLongitude(), 1).get(0);
                    stream.setCity(address.getLocality());
                    stream.setCountry(address.getCountryName());
                    stream.setState(address.getAdminArea());
                    if (eventBus != null) {
                        eventBus.post(new StreamLocationAddedEvent());
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

    }

    /**
     * Get the {@link io.kickflip.sdk.av.BroadcastListener} to be notified on broadcast events.
     */
    public static BroadcastListener getBroadcastListener() {
        return sBroadcastListener;
    }

    /**
     * Set a {@link io.kickflip.sdk.av.BroadcastListener} to be notified on broadcast events.
     *
     * @param listener a {@link io.kickflip.sdk.av.BroadcastListener}
     */
    public static void setBroadcastListener(BroadcastListener listener) {
        sBroadcastListener = listener;
    }

    /**
     * Get the provided Kickflip Client Key
     *
     * @return the provided Kickflip Client Key
     */
    public static String getApiKey() {
        return sClientKey;
    }

    /**
     * Get the provided Kickflip Client Secret
     *
     * @return the provided Kickflip Client Secret
     */
    public static String getApiSecret() {
        return sClientSecret;
    }

    /**
     * Return the {@link io.kickflip.sdk.av.SessionConfig} responsible for configuring this broadcast.
     *
     * @return the {@link io.kickflip.sdk.av.SessionConfig} responsible for configuring this broadcast.
     * @hide
     */
    public static SessionConfig getSessionConfig() {
        return sSessionConfig;
    }

    /**
     * Clear the current SessionConfig, marking it as in use by a Broadcaster.
     * This is typically safe to do after constructing a Broadcaster, as it will
     * hold reference.
     *
     * @hide
     */
    public static void clearSessionConfig() {
        Log.i(TAG, "Clearing SessionConfig");
        sSessionConfig = null;
    }

    /**
     * Set the {@link io.kickflip.sdk.av.SessionConfig} responsible for configuring this broadcast.
     *
     * @param config the {@link io.kickflip.sdk.av.SessionConfig} responsible for configuring this broadcast.
     */
    public static void setSessionConfig(SessionConfig config) {
        sSessionConfig = config;
    }

    /**
     * Check whether credentials required for broadcast are provided
     *
     * @return true if credentials required for broadcast are provided. false otherwise
     */
    public static boolean readyToBroadcast() {
        return sClientKey != null && sClientSecret != null && sSessionConfig != null;
    }

    /**
     * Return whether the given Uri belongs to the kickflip.io authority.
     *
     * @param uri uri to test
     * @return true if the uri is of the kickflip.io authority.
     */
    public static boolean isKickflipUrl(Uri uri) {
        return uri != null && uri.getAuthority().contains("kickflip.io");
    }

    /**
     * Given a Kickflip.io url, return the stream id.
     * <p/>
     * e.g: https://kickflip.io/39df392c-4afe-4bf5-9583-acccd8212277/ returns
     * "39df392c-4afe-4bf5-9583-acccd8212277"
     *
     * @param uri the uri to test
     * @return the last path segment of the given uri, corresponding to the Kickflip {@link Stream#mStreamId}
     */
    public static String getStreamIdFromKickflipUrl(Uri uri) {
        if (uri == null) throw new IllegalArgumentException("uri cannot be null");
        return uri.getLastPathSegment().toString();
    }

    /**
     * Create a new instance of the KickflipApiClient if one hasn't
     * yet been created, or the provided API keys don't match
     * the existing client.
     *
     * @param context the context of the host application
     * @return
     */
    public static KickflipApiClient getApiClient(Context context) {
        return getApiClient(context, null);
    }

    /**
     * Create a new instance of the KickflipApiClient if one hasn't
     * yet been created, or the provided API keys don't match
     * the existing client.
     *
     * @param context  the context of the host application
     * @param callback an optional callback to be notified with the Kickflip user
     *                 corresponding to the provided API keys.
     * @return
     */
    public static KickflipApiClient getApiClient(Context context, KickflipCallback callback) {
        checkNotNull(sClientKey);
        checkNotNull(sClientSecret);
        if (sKickflip == null || !sKickflip.getConfig().getClientId().equals(sClientKey)) {
            sKickflip = new KickflipApiClient(context, sClientKey, sClientSecret, callback);
        } else if (callback != null) {
            callback.onSuccess(sKickflip.getActiveUser());
        }
        return sKickflip;
    }

    private static void setupDefaultSessionConfig() {
        Log.i(TAG, "Setting default SessonConfig");
        checkNotNull(sContext);
        String outputLocation = new File(sContext.getFilesDir(), "index.m3u8").getAbsolutePath();
        Kickflip.setSessionConfig(new SessionConfig.Builder(outputLocation)
                .withVideoBitrate(100 * 1000)
                .withPrivateVisibility(false)
                .withLocation(true)
                .withVideoResolution(720, 480)
                .build());
    }

    /**
     * Returns whether the current device is running Android 4.4, KitKat, or newer
     *
     * KitKat is required for certain Kickflip features like Adaptive bitrate streaming
     */
    public static boolean isKitKat() {
        return Build.VERSION.SDK_INT >= 19;
    }

}




Java Source Code List

io.kickflip.sdk.FileUtils.java
io.kickflip.sdk.Kickflip.java
io.kickflip.sdk.Share.java
io.kickflip.sdk.Util.java
io.kickflip.sdk.activity.BroadcastActivity.java
io.kickflip.sdk.activity.GlassBroadcastActivity.java
io.kickflip.sdk.activity.ImmersiveActivity.java
io.kickflip.sdk.activity.MediaPlayerActivity.java
io.kickflip.sdk.api.KickflipApiClient.java
io.kickflip.sdk.api.KickflipCallback.java
io.kickflip.sdk.api.OAuthCallback.java
io.kickflip.sdk.api.OAuthClient.java
io.kickflip.sdk.api.OAuthConfig.java
io.kickflip.sdk.api.json.HlsStream.java
io.kickflip.sdk.api.json.Response.java
io.kickflip.sdk.api.json.StreamList.java
io.kickflip.sdk.api.json.Stream.java
io.kickflip.sdk.api.json.User.java
io.kickflip.sdk.api.s3.S3BroadcastManager.java
io.kickflip.sdk.api.s3.package-info.java
io.kickflip.sdk.av.AVRecorder.java
io.kickflip.sdk.av.AndroidEncoder.java
io.kickflip.sdk.av.AndroidMuxer.java
io.kickflip.sdk.av.AudioEncoderConfig.java
io.kickflip.sdk.av.AudioEncoderCore.java
io.kickflip.sdk.av.BroadcastListener.java
io.kickflip.sdk.av.Broadcaster.java
io.kickflip.sdk.av.CameraEncoder.java
io.kickflip.sdk.av.CameraSurfaceRenderer.java
io.kickflip.sdk.av.Drawable2d.java
io.kickflip.sdk.av.EglCore.java
io.kickflip.sdk.av.EglStateSaver.java
io.kickflip.sdk.av.EglSurfaceBase.java
io.kickflip.sdk.av.FFmpegMuxer.java
io.kickflip.sdk.av.Filters.java
io.kickflip.sdk.av.FullFrameRect.java
io.kickflip.sdk.av.GlUtil.java
io.kickflip.sdk.av.HlsFileObserver.java
io.kickflip.sdk.av.M3u8Parser.java
io.kickflip.sdk.av.MicrophoneEncoder.java
io.kickflip.sdk.av.Muxer.java
io.kickflip.sdk.av.SessionConfig.java
io.kickflip.sdk.av.SizeableFrameRect.java
io.kickflip.sdk.av.Texture2dProgram.java
io.kickflip.sdk.av.VideoEncoderConfig.java
io.kickflip.sdk.av.VideoEncoderCore.java
io.kickflip.sdk.av.WindowSurface.java
io.kickflip.sdk.event.BroadcastEvent.java
io.kickflip.sdk.event.BroadcastIsBufferingEvent.java
io.kickflip.sdk.event.BroadcastIsLiveEvent.java
io.kickflip.sdk.event.CameraOpenedEvent.java
io.kickflip.sdk.event.HlsManifestUploadedEvent.java
io.kickflip.sdk.event.HlsManifestWrittenEvent.java
io.kickflip.sdk.event.HlsSegmentUploadedEvent.java
io.kickflip.sdk.event.HlsSegmentWrittenEvent.java
io.kickflip.sdk.event.MuxerFinishedEvent.java
io.kickflip.sdk.event.S3FailedUploadEvent.java
io.kickflip.sdk.event.S3UploadEvent.java
io.kickflip.sdk.event.StreamLocationAddedEvent.java
io.kickflip.sdk.event.ThumbnailWrittenEvent.java
io.kickflip.sdk.event.UploadEvent.java
io.kickflip.sdk.event.package-info.java
io.kickflip.sdk.exception.KickflipException.java
io.kickflip.sdk.fragment.BroadcastFragment.java
io.kickflip.sdk.fragment.GlassBroadcastFragment.java
io.kickflip.sdk.fragment.MediaPlayerFragment.java
io.kickflip.sdk.fragment.package-info.java
io.kickflip.sdk.location.DeviceLocation.java
io.kickflip.sdk.location.package-info.java
io.kickflip.sdk.view.GLCameraEncoderView.java
io.kickflip.sdk.view.GLCameraView.java
io.kickflip.sdk.view.package-info.java
pro.dbro.ffmpegwrapper.FFmpegWrapper.java
pro.dbro.ffmpegwrapper.package-info.java