Skip to content Skip to sidebar Skip to footer

Using Exoplayer Without Surfaceview

I want to use Exoplayer in a service the way Spotify does but i can see that most of the implementations use a SurfaceView and a VideoController. Can the Exoplyer be used without t

Solution 1:

I have created a service that can play your audio it is similar to the demo of official exoplayer. exoplayer github

I have created a PlayerService just similar to PlayerActivity of the official demo. I have tested only with the option Google play (MP3 Audio) in MISC section. Please do not comment on the code style it is done to try this out.

publicclassPlayServiceextendsServiceimplementsDemoPlayer.Listener, AudioCapabilitiesReceiver.Listener,
    DemoPlayer.CaptionListener, DemoPlayer.Id3MetadataListener {



// For use within demo app code.publicstaticfinalStringCONTENT_ID_EXTRA="content_id";
publicstaticfinalStringCONTENT_TYPE_EXTRA="content_type";
publicstaticfinalStringPROVIDER_EXTRA="provider";


private DemoPlayer player;


// For use when launching the demo app using adb.privatestaticfinalStringCONTENT_EXT_EXTRA="type";
privatestaticfinalStringTAG="PlayerService";
privatestaticfinalintMENU_GROUP_TRACKS=1;
privatestaticfinalintID_OFFSET=2;


private EventLogger eventLogger;
private MediaController mediaController;
privatelong playerPosition;
privateboolean enableBackgroundAudio;

private Uri contentUri;
privateint contentType;
private String contentId;
private String provider;

private AudioCapabilitiesReceiver audioCapabilitiesReceiver;
privateboolean playerNeedsPrepare;

publicPlayService() {
}

@Overridepublic IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.thrownewUnsupportedOperationException("Not yet implemented");
}

@OverridepublicintonStartCommand(Intent intent, int flags, int startId) {

    audioCapabilitiesReceiver = newAudioCapabilitiesReceiver(this, this);
    audioCapabilitiesReceiver.register();

    contentUri = intent.getData();
    contentType = intent.getIntExtra(CONTENT_TYPE_EXTRA,
            inferContentType(contentUri, intent.getStringExtra(CONTENT_EXT_EXTRA)));
    contentId = intent.getStringExtra(CONTENT_ID_EXTRA);
    provider = intent.getStringExtra(PROVIDER_EXTRA);

    preparePlayer(true);


    return START_STICKY;
}


privatestaticintinferContentType(Uri uri, String fileExtension) {
    StringlastPathSegment= !TextUtils.isEmpty(fileExtension) ? "." + fileExtension
            : uri.getLastPathSegment();
    return Util.inferContentType(lastPathSegment);
}

@OverridepublicvoidonStateChanged(boolean playWhenReady, int playbackState) {

}

@OverridepublicvoidonError(Exception e) {

}

@OverridepublicvoidonVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {

}


privatevoidreleasePlayer() {
    if (player != null) {
        playerPosition = player.getCurrentPosition();
        player.release();
        player = null;
        eventLogger.endSession();
        eventLogger = null;
    }
}

private DemoPlayer.RendererBuilder getRendererBuilder() {
    StringuserAgent= Util.getUserAgent(this, "ExoPlayerDemo");
    switch (contentType) {
        case Util.TYPE_SS:
            returnnewSmoothStreamingRendererBuilder(this, userAgent, contentUri.toString(),
                    newSmoothStreamingTestMediaDrmCallback());
        case Util.TYPE_DASH:
            returnnewDashRendererBuilder(this, userAgent, contentUri.toString(),
                    newWidevineTestMediaDrmCallback(contentId, provider));
        case Util.TYPE_HLS:
            returnnewHlsRendererBuilder(this, userAgent, contentUri.toString());
        case Util.TYPE_OTHER:
            returnnewExtractorRendererBuilder(this, userAgent, contentUri);
        default:
            thrownewIllegalStateException("Unsupported type: " + contentType);
    }
}

privatevoidpreparePlayer(boolean playWhenReady) {
    if (player == null) {
        player = newDemoPlayer(getRendererBuilder());
        player.setBackgrounded(true);
        player.addListener(this);
        player.setCaptionListener(this);
        player.setMetadataListener(this);
        player.seekTo(playerPosition);
        playerNeedsPrepare = true;
        //mediaController.setMediaPlayer(player.getPlayerControl());//mediaController.setEnabled(true);
        eventLogger = newEventLogger();
        eventLogger.startSession();
        player.addListener(eventLogger);
        player.setInfoListener(eventLogger);
        player.setInternalErrorListener(eventLogger);
    }
    player.setBackgrounded(true);
    if (playerNeedsPrepare) {
        player.prepare();
        playerNeedsPrepare = false;
    }
    player.setBackgrounded(true);
    player.setPlayWhenReady(playWhenReady);
}

@OverridepublicvoidonAudioCapabilitiesChanged(AudioCapabilities audioCapabilities) {
    if (player == null) {
        return;
    }
    booleanbackgrounded= player.getBackgrounded();
    booleanplayWhenReady= player.getPlayWhenReady();
    releasePlayer();
    preparePlayer(playWhenReady);
    player.setBackgrounded(backgrounded);
}

@OverridepublicvoidonCues(List<Cue> cues) {

}

@OverridepublicvoidonId3Metadata(List<Id3Frame> id3Frames) {
    for (Id3Frame id3Frame : id3Frames) {
        if (id3Frame instanceof TxxxFrame) {
            TxxxFrametxxxFrame= (TxxxFrame) id3Frame;
            Log.i(TAG, String.format("ID3 TimedMetadata %s: description=%s, value=%s", txxxFrame.id,
                    txxxFrame.description, txxxFrame.value));
        } elseif (id3Frame instanceof PrivFrame) {
            PrivFrameprivFrame= (PrivFrame) id3Frame;
            Log.i(TAG, String.format("ID3 TimedMetadata %s: owner=%s", privFrame.id, privFrame.owner));
        } elseif (id3Frame instanceof GeobFrame) {
            GeobFramegeobFrame= (GeobFrame) id3Frame;
            Log.i(TAG, String.format("ID3 TimedMetadata %s: mimeType=%s, filename=%s, description=%s",
                    geobFrame.id, geobFrame.mimeType, geobFrame.filename, geobFrame.description));
        } else {
            Log.i(TAG, String.format("ID3 TimedMetadata %s", id3Frame.id));
        }
    }
}

}

Post a Comment for "Using Exoplayer Without Surfaceview"