Lumen help

Legacy Integration for Brightcove Player on Android

Project setup

                repositories {
    maven {
        url 'https://sdk.streamroot.io/android'
    }
}
            
                implementation 'io.streamroot.dna:dna-core:3.23.0'
            
                android {
// Configure only for each module that uses Java 8
// language features (either in its source code or
// through dependencies).
compileOptions {
      sourceCompatibility JavaVersion.VERSION_1_8
      targetCompatibility JavaVersion.VERSION_1_8
  }
}

            

Integrate Lumen SDK

                <meta-data
        android:name="io.streamroot.dna.StreamrootKey"
        android:value="streamrootKey"/>

            
                dnaClient = DnaClient.newBuilder()
        .context(<Context>)
        .playerInteractor(BrightcoveInteractor(<Player>))
        .latency(latency)
        .start(Uri.parse(firstHlsSource.getUrl()));
            
                LoadControlConfig loadControlConfig = new LoadControlConfig.Builder()
        .setAllocatorConfig(allocatorConfig)
        .setMinBufferMs(10000)
        .setMaxBufferMs((DnaClient.generateBufferTarget(10000, 30000, 30000)))
        .build();
            
                dnaClient.manifestUrl : <Uri>
            
                import android.os.Looper;
import com.brightcove.player.display.ExoPlayerVideoDisplayComponent;
import com.brightcove.player.display.VideoDisplayComponent;
import com.brightcove.player.event.Event;
import com.brightcove.player.event.EventListener;
import com.brightcove.player.event.EventType;
import com.brightcove.player.view.BrightcoveExoPlayerVideoView;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.List;
import io.streamroot.dna.core.PlayerInteractor;
import io.streamroot.dna.core.TimeRange;

final class BrightcoveInteractor implements PlayerInteractor {
    private ExoPlayer mPlayer;
    private BrightcoveExoPlayerVideoView brightcoveVideoView;
    BrightcoveInteractor(BrightcoveExoPlayerVideoView brightcoveVideoView) {
        this.brightcoveVideoView = brightcoveVideoView;
        setExoWhenAvailable(brightcoveVideoView);
    }

    private void setExoWhenAvailable(BrightcoveExoPlayerVideoView brightcoveVideoView) {
        this.brightcoveVideoView.addListener(EventType.DID_SET_VIDEO,new EventListener()  {
            @Override
            public void processEvent(Event event) {
                VideoDisplayComponent videoDisplayComponent = brightcoveVideoView.getVideoDisplay();
                if (videoDisplayComponent instanceof ExoPlayerVideoDisplayComponent) {
                    // Get ExoPlayer
                    ExoPlayer exoPlayer = ((ExoPlayerVideoDisplayComponent) videoDisplayComponent).getExoPlayer();
                    if (exoPlayer instanceof SimpleExoPlayer) {
                        // Get SimpleExoPlayer
                        mPlayer = (SimpleExoPlayer) exoPlayer;
                    }
                }
            }
        });
    }

    @NotNull
    @Override
    public List<TimeRange> loadedTimeRanges() {
        if (mPlayer == null) {  return Collections.emptyList(); }
        long shift = getCurrentWindowShift();
        long rangeDurationMs = mPlayer.getBufferedPosition() - mPlayer.getCurrentPosition();
        return (rangeDurationMs > 0) ?
                Collections.singletonList(new TimeRange(shift +
                        mPlayer.getCurrentPosition(), rangeDurationMs))
                : Collections.emptyList();
    }

    @Nullable
    @Override
    public Looper looper() {
        return (mPlayer == null) ? null : mPlayer.getPlaybackLooper();
    }

    @Override
    public long playbackTime() {
        return (mPlayer == null)
                ? brightcoveVideoView.getCurrentPosition()
                : getCurrentWindowShift() + mPlayer.getCurrentPosition();
    }

    private long getCurrentWindowShift() {
        Timeline current = mPlayer.getCurrentTimeline();
        Timeline.Window timeLimeWindow = new Timeline.Window();
        long shift = 0;
        if (mPlayer.getCurrentWindowIndex() < current.getWindowCount()) {
            mPlayer.getCurrentTimeline().getWindow(mPlayer.getCurrentWindowIndex(), timeLimeWindow);
            shift = timeLimeWindow.getPositionInFirstPeriodMs();
        }
        return shift;
    }

    @Override
    public double bufferTarget() { return 0; }

    @Override
    public void setBufferTarget(double target) {}
}
            
                import com.brightcove.player.display.ExoPlayerVideoDisplayComponent;
import com.google.android.exoplayer2.Player;
import io.streamroot.dna.core.BandwidthListener;

final class BrightcoveBandwidthListener implements BandwidthListener {
    private ExoPlayerVideoDisplayComponent displayComponent;

    BrightcoveBandwidthListener(ExoPlayerVideoDisplayComponent displayComponent) {
        this.displayComponent = displayComponent;
    }

    @Override
    public void onBandwidthChange(long estimatedBandwidth) {
        displayComponent.setPeakBitrate((int) estimatedBandwidth);
    }
}
            
                dnaClient = DnaClient.newBuilder()
     .context(<Context>)
     .playerInteractor(BrightcoveInteractor(<Player>))
     ...
     
     .bandwidthListener(<BandwidthListener>)
     
     ...
     .start(<String>);
            
                import com.brightcove.player.event.Default;
import com.brightcove.player.event.Event;
import com.brightcove.player.event.EventListener;
import com.brightcove.player.event.EventType;
import com.brightcove.player.view.BrightcoveExoPlayerVideoView;
import io.streamroot.dna.core.PlaybackState;
import io.streamroot.dna.core.QosModule;

final class BrightcoveQoSModule extends QosModule {
    private BrightcoveExoPlayerVideoView brightcoveVideoView;
    BrightcoveQoSModule(BrightcoveExoPlayerVideoView brightcoveVideoView) {
        super();
        this.brightcoveVideoView = brightcoveVideoView;
        initListeners();
    }

    void initListeners() {
        {
            this.brightcoveVideoView.addListener(EventType.SOURCE_NOT_PLAYABLE, new EventListener() {
                @Default
                public void processEvent(Event event) {
                    playbackErrorOccurred();
                }
            });
            this.brightcoveVideoView.addListener(EventType.COMPLETED, new EventListener() {
                public void processEvent(Event event) {
                    playbackStateChange(PlaybackState.ENDED);
                }
            });
            this.brightcoveVideoView.addListener(EventType.SEEK_TO, new EventListener() {
                public void processEvent(Event event) {
                    playbackStateChange(PlaybackState.SEEKING);
                }
            });
            this.brightcoveVideoView.addListener(EventType.DID_PLAY, new EventListener() {
                public void processEvent(Event event) {
                    playbackStateChange(PlaybackState.PLAYING);
                }
            });
            this.brightcoveVideoView.addListener(EventType.DID_STOP, new EventListener() {
                public void processEvent(Event event) {
                    playbackStateChange(PlaybackState.ENDED);
                }
            });
            this.brightcoveVideoView.addListener(EventType.DID_PAUSE, new EventListener() {
                public void processEvent(Event event) {
                    playbackStateChange(PlaybackState.PAUSING);
                }
            });
            this.brightcoveVideoView.addListener(EventType.WILL_INTERRUPT_CONTENT, new EventListener() {
                public void processEvent(Event event) {
                    playbackErrorOccurred();
                    playbackStateChange(PlaybackState.ENDED);
                }
            });
        }
    }
}
            
                dnaClient = DnaClient.newBuilder()
     .context(<Context>)
     .playerInteractor(BrightcoveInteractor((BrightcoveExoPlayerVideoView)brightcoveVideoView))
     ...
     
     .qosModule(BrightcoveQoSModule((BrightcoveExoPlayerVideoView)brightcoveVideoView))
     
     ...
     .start(<String>);
            
                dnaClient.close();
            
                <?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <application
        ...
        android:usesCleartextTraffic="true">
        ...
    </application>
</manifest>
            
                <?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>
            
                <?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <application
        ...
        android:networkSecurityConfig="@xml/network_security_config">
        ...
    </application>
</manifest>