Skip to content

Commit

Permalink
'playback_speed_by_adjusting_audio_or_standaloneMediaClock_speed'
Browse files Browse the repository at this point in the history
  • Loading branch information
WeiChungChang committed Feb 19, 2017
1 parent c3d7eec commit 3f05ef6
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 4 deletions.
10 changes: 10 additions & 0 deletions library/src/main/java/com/google/android/exoplayer2/ExoPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -463,4 +463,14 @@ public ExoPlayerMessage(ExoPlayerComponent target, int messageType, Object messa
*/
boolean isCurrentWindowSeekable();

/**
* @return the speed factor: speed_of_playback / speed_of_real_clock
*/
float getPlaybackSpeed();

/**
* @param speed the speed factor: speed_of_playback / speed_of_real_clock
*/
void setPlaybackSpeed(float speed);

}
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,16 @@ public Timeline getCurrentTimeline() {
return timeline;
}

@Override
public float getPlaybackSpeed() {
return internalPlayer.getPlaybackSpeed();
}

@Override
public void setPlaybackSpeed(float speed) {
internalPlayer.setPlaybackSpeed(speed);
}

@Override
public Object getCurrentManifest() {
return manifest;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import com.google.android.exoplayer2.util.TraceUtil;
import java.io.IOException;

import android.os.Build;
import android.media.PlaybackParams;
/**
* Implements the internal behavior of {@link ExoPlayerImpl}.
*/
Expand Down Expand Up @@ -165,6 +167,7 @@ public SourceInfo(Timeline timeline, Object manifest, PlaybackInfo playbackInfo,
private MediaPeriodHolder playingPeriodHolder;

private Timeline timeline;
private float speed;

public ExoPlayerImplInternal(Renderer[] renderers, TrackSelector trackSelector,
LoadControl loadControl, boolean playWhenReady, Handler eventHandler,
Expand Down Expand Up @@ -222,6 +225,10 @@ public void sendMessages(ExoPlayerMessage... messages) {
}
customMessagesSent++;
handler.obtainMessage(MSG_CUSTOM, messages).sendToTarget();

for (ExoPlayerMessage message : messages) {
maybeUpdatePlaybackSpeed(message);
}
}

public synchronized void blockingSendMessages(ExoPlayerMessage... messages) {
Expand All @@ -238,6 +245,9 @@ public synchronized void blockingSendMessages(ExoPlayerMessage... messages) {
Thread.currentThread().interrupt();
}
}
for (ExoPlayerMessage message : messages) {
maybeUpdatePlaybackSpeed(message);
}
}

public synchronized void release() {
Expand Down Expand Up @@ -430,6 +440,9 @@ private void updatePlaybackPositions() throws ExoPlaybackException {
rendererPositionUs = standaloneMediaClock.getPositionUs();
}
periodPositionUs = playingPeriodHolder.toPeriodTime(rendererPositionUs);
rendererPositionUs = rendererMediaClock.getPositionUs();
standaloneMediaClock.setPositionUs(rendererPositionUs);
periodPositionUs = rendererPositionUs - playingPeriodHolder.rendererPositionOffsetUs;
}
playbackInfo.positionUs = periodPositionUs;
elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
Expand Down Expand Up @@ -1377,6 +1390,7 @@ private void enableRenderers(boolean[] rendererWasEnabledFlags, int enabledRende
new IllegalStateException("Multiple renderer media clocks enabled."));
}
rendererMediaClock = mediaClock;
rendererMediaClock.setPlaybackSpeed(speed);
rendererMediaClockSource = renderer;
}
// Start the renderer if playing.
Expand All @@ -1388,6 +1402,40 @@ private void enableRenderers(boolean[] rendererWasEnabledFlags, int enabledRende
}
}

public float getPlaybackSpeed() {
return standaloneMediaClock.getPlaybackSpeed();
}

public void setPlaybackSpeed(float speed) {
this.speed = speed;

if ((Build.VERSION.SDK_INT >= 23) && (rendererMediaClockSource != null)) {
PlaybackParams params = new PlaybackParams();
params.setSpeed(speed);
ExoPlayerMessage[] messages = new ExoPlayerMessage[renderers.length];
for (int i = 0; i < renderers.length; i++) {
messages[i] = new ExoPlayerMessage(renderers[i], C.MSG_SET_PLAYBACK_PARAMS, params);
}
try {
sendMessagesInternal(messages);
} catch (ExoPlaybackException e) {
e.printStackTrace();
}
} else {
this.speed = speed;
standaloneMediaClock.setPlaybackSpeed(speed);
if (rendererMediaClock != null) {
rendererMediaClock.setPlaybackSpeed(speed);
}
}
}

private void maybeUpdatePlaybackSpeed(ExoPlayerMessage msg) {
if (Build.VERSION.SDK_INT >= 23 && msg.messageType == C.MSG_SET_PLAYBACK_PARAMS) {
standaloneMediaClock.setPlaybackSpeed(((PlaybackParams)msg.message).allowDefaults().getSpeed());
}
}

/**
* Holds a {@link MediaPeriod} with information required to play it as part of a timeline.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1036,4 +1036,14 @@ public PlaybackParamsHolder(PlaybackParams params) {

}

@Override
public float getPlaybackSpeed() {
return player.getPlaybackSpeed();
}

@Override
public void setPlaybackSpeed(float speed) {
player.setPlaybackSpeed(speed);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
*/
public final class AudioTrack {

public void setPlaybackSpeed(float speed) {
audioTrackUtil.setPlaybackSpeed(speed);
}

/**
* Listener for audio track events.
*/
Expand Down Expand Up @@ -1256,6 +1260,7 @@ private static class AudioTrackUtil {
private long stopTimestampUs;
private long stopPlaybackHeadPosition;
private long endPlaybackHeadPosition;
private float speed = 1.0f;

/**
* Reconfigures the audio track utility helper to use the specified {@code audioTrack}.
Expand Down Expand Up @@ -1410,9 +1415,12 @@ public void setPlaybackParams(PlaybackParams playbackParams) {
* @return The speed factor used by the underlying {@link android.media.AudioTrack}.
*/
public float getPlaybackSpeed() {
return 1.0f;
return speed;
}

public void setPlaybackSpeed(float speed) {
this.speed = speed;
}
}

@TargetApi(19)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ protected void onOutputStreamEnded() {
audioTrack.handleEndOfStream();
}

@Override
public void setPlaybackSpeed(float speed) {
audioTrack.setPlaybackSpeed(speed);
}

@Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
switch (messageType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,11 @@ private void onInputFormatChanged(Format newFormat) throws ExoPlaybackException
eventDispatcher.inputFormatChanged(newFormat);
}

@Override
public void setPlaybackSpeed(float speed) {
audioTrack.setPlaybackSpeed(speed);
}

@Override
public void handleMessage(int messageType, Object message) throws ExoPlaybackException {
switch (messageType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public interface MediaClock {
*/
long getPositionUs();

/**
* Set the playback speed
*/
void setPlaybackSpeed(float speed);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,21 @@ public final class StandaloneMediaClock implements MediaClock {
*/
private long deltaUs;

/**
* The media time(ms) on last sync.
*/
private double lastMediaTime;

/**
* The {@link SystemClock#elapsedRealtime()} (ms) on last sync.
*/
private long lastRealTime;

/*
* speed ratio between media time and real time
*/
private float speed = 1.0f;

/**
* Starts the clock. Does nothing if the clock is already started.
*/
Expand All @@ -60,17 +75,34 @@ public void stop() {
* @param timeUs The position to set in microseconds.
*/
public void setPositionUs(long timeUs) {
this.positionUs = timeUs;
deltaUs = elapsedRealtimeMinus(timeUs);
lastRealTime = SystemClock.elapsedRealtime();
lastMediaTime = timeUs / 1000.0;
}

@Override
public long getPositionUs() {
return started ? elapsedRealtimeMinus(deltaUs) : positionUs;
updateMediaTime();
return (long)(lastMediaTime * 1000);
}

private long elapsedRealtimeMinus(long toSubtractUs) {
return SystemClock.elapsedRealtime() * 1000 - toSubtractUs;
}

public float getPlaybackSpeed() {
return speed;
}

public void setPlaybackSpeed(float newSpeed) {
updateMediaTime();
speed = newSpeed;
}

private void updateMediaTime() {
if (!started)
return;
long realTime = SystemClock.elapsedRealtime();
lastMediaTime = lastMediaTime + (realTime - lastRealTime) * speed;
lastRealTime = realTime;
}
}

0 comments on commit 3f05ef6

Please sign in to comment.