Loading media/java/android/media/videoeditor/AudioTrack.java +173 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package android.media.videoeditor; import java.io.IOException; import android.util.Log; /** * This class allows to handle an audio track. This audio file is mixed with the * audio samples of the MediaItems. * {@hide} */ public class AudioTrack { // Logging private static final String TAG = "AudioTrack"; // Instance variables private final String mUniqueId; private final String mFilename; Loading @@ -47,6 +52,129 @@ public class AudioTrack { // The audio waveform filename private String mAudioWaveformFilename; private PlaybackThread mPlaybackThread; /** * This listener interface is used by the AudioTrack to emit playback * progress notifications. */ public interface PlaybackProgressListener { /** * This method notifies the listener of the current time position while * playing an audio track * * @param audioTrack The audio track * @param timeMs The current playback position (expressed in milliseconds * since the beginning of the audio track). * @param end true if the end of the audio track was reached */ public void onProgress(AudioTrack audioTrack, long timeMs, boolean end); } /** * The playback thread */ private class PlaybackThread extends Thread { // Instance variables private final PlaybackProgressListener mListener; private final long mFromMs, mToMs; private boolean mRun; private final boolean mLoop; private long mPositionMs; /** * Constructor * * @param fromMs The time (relative to the beginning of the audio track) * at which the playback will start * @param toMs The time (relative to the beginning of the audio track) at * which the playback will stop. Use -1 to play to the end of * the audio track * @param loop true if the playback should be looped once it reaches the * end * @param listener The listener which will be notified of the playback * progress */ public PlaybackThread(long fromMs, long toMs, boolean loop, PlaybackProgressListener listener) { mPositionMs = mFromMs = fromMs; if (toMs < 0) { mToMs = mDurationMs; } else { mToMs = toMs; } mLoop = loop; mListener = listener; mRun = true; } /* * {@inheritDoc} */ @Override public void run() { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "===> PlaybackThread.run enter"); } while (mRun) { try { sleep(100); } catch (InterruptedException ex) { break; } mPositionMs += 100; if (mPositionMs >= mToMs) { if (!mLoop) { if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, true); } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "PlaybackThread.run playback complete"); } break; } else { // Fire a notification for the end of the clip if (mListener != null) { mListener.onProgress(AudioTrack.this, mToMs, false); } // Rewind mPositionMs = mFromMs; if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, false); } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "PlaybackThread.run playback complete"); } } } else { if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, false); } } } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "===> PlaybackThread.run exit"); } } /** * Stop the playback * * @return The stop position */ public long stopPlayback() { mRun = false; try { join(); } catch (InterruptedException ex) { } return mPositionMs; } }; /** * An object of this type cannot be instantiated by using the default Loading Loading @@ -99,7 +227,7 @@ public class AudioTrack { } /** * @return The id of the media item * @return The id of the audio track */ public String getId() { return mUniqueId; Loading Loading @@ -311,6 +439,50 @@ public class AudioTrack { return mDuckingLowVolume; } /** * Start the playback of this audio track. This method does not block (does * not wait for the playback to complete). * * @param fromMs The time (relative to the beginning of the audio track) at * which the playback will start * @param toMs The time (relative to the beginning of the audio track) at * which the playback will stop. Use -1 to play to the end of the * audio track * @param loop true if the playback should be looped once it reaches the end * @param listener The listener which will be notified of the playback * progress * @throws IllegalArgumentException if fromMs or toMs is beyond the playback * duration * @throws IllegalStateException if a playback, preview or an export is * already in progress */ public void startPlayback(long fromMs, long toMs, boolean loop, PlaybackProgressListener listener) { if (fromMs >= mDurationMs) { return; } mPlaybackThread = new PlaybackThread(fromMs, toMs, loop, listener); mPlaybackThread.start(); } /** * Stop the audio track playback. This method blocks until the ongoing * playback is stopped. * * @return The accurate current time when stop is effective expressed in * milliseconds */ public long stopPlayback() { final long stopTimeMs; if (mPlaybackThread != null) { stopTimeMs = mPlaybackThread.stopPlayback(); mPlaybackThread = null; } else { stopTimeMs = 0; } return stopTimeMs; } /** * This API allows to generate a file containing the sample volume levels of * this audio track object. This function may take significant time and is Loading media/java/android/media/videoeditor/VideoEditorTestImpl.java +5 −8 Original line number Diff line number Diff line Loading @@ -537,16 +537,13 @@ public class VideoEditorTestImpl implements VideoEditor { * {@inheritDoc} */ public AudioTrack getAudioTrack(String audioTrackId) { if (mPreviewThread != null) { throw new IllegalStateException("Previewing is in progress"); for (AudioTrack at : mAudioTracks) { if (at.getId().equals(audioTrackId)) { return at; } final AudioTrack audioTrack = getAudioTrack(audioTrackId); if (audioTrack != null) { mAudioTracks.remove(audioTrack); } return audioTrack; return null; } /* Loading Loading
media/java/android/media/videoeditor/AudioTrack.java +173 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package android.media.videoeditor; import java.io.IOException; import android.util.Log; /** * This class allows to handle an audio track. This audio file is mixed with the * audio samples of the MediaItems. * {@hide} */ public class AudioTrack { // Logging private static final String TAG = "AudioTrack"; // Instance variables private final String mUniqueId; private final String mFilename; Loading @@ -47,6 +52,129 @@ public class AudioTrack { // The audio waveform filename private String mAudioWaveformFilename; private PlaybackThread mPlaybackThread; /** * This listener interface is used by the AudioTrack to emit playback * progress notifications. */ public interface PlaybackProgressListener { /** * This method notifies the listener of the current time position while * playing an audio track * * @param audioTrack The audio track * @param timeMs The current playback position (expressed in milliseconds * since the beginning of the audio track). * @param end true if the end of the audio track was reached */ public void onProgress(AudioTrack audioTrack, long timeMs, boolean end); } /** * The playback thread */ private class PlaybackThread extends Thread { // Instance variables private final PlaybackProgressListener mListener; private final long mFromMs, mToMs; private boolean mRun; private final boolean mLoop; private long mPositionMs; /** * Constructor * * @param fromMs The time (relative to the beginning of the audio track) * at which the playback will start * @param toMs The time (relative to the beginning of the audio track) at * which the playback will stop. Use -1 to play to the end of * the audio track * @param loop true if the playback should be looped once it reaches the * end * @param listener The listener which will be notified of the playback * progress */ public PlaybackThread(long fromMs, long toMs, boolean loop, PlaybackProgressListener listener) { mPositionMs = mFromMs = fromMs; if (toMs < 0) { mToMs = mDurationMs; } else { mToMs = toMs; } mLoop = loop; mListener = listener; mRun = true; } /* * {@inheritDoc} */ @Override public void run() { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "===> PlaybackThread.run enter"); } while (mRun) { try { sleep(100); } catch (InterruptedException ex) { break; } mPositionMs += 100; if (mPositionMs >= mToMs) { if (!mLoop) { if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, true); } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "PlaybackThread.run playback complete"); } break; } else { // Fire a notification for the end of the clip if (mListener != null) { mListener.onProgress(AudioTrack.this, mToMs, false); } // Rewind mPositionMs = mFromMs; if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, false); } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "PlaybackThread.run playback complete"); } } } else { if (mListener != null) { mListener.onProgress(AudioTrack.this, mPositionMs, false); } } } if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "===> PlaybackThread.run exit"); } } /** * Stop the playback * * @return The stop position */ public long stopPlayback() { mRun = false; try { join(); } catch (InterruptedException ex) { } return mPositionMs; } }; /** * An object of this type cannot be instantiated by using the default Loading Loading @@ -99,7 +227,7 @@ public class AudioTrack { } /** * @return The id of the media item * @return The id of the audio track */ public String getId() { return mUniqueId; Loading Loading @@ -311,6 +439,50 @@ public class AudioTrack { return mDuckingLowVolume; } /** * Start the playback of this audio track. This method does not block (does * not wait for the playback to complete). * * @param fromMs The time (relative to the beginning of the audio track) at * which the playback will start * @param toMs The time (relative to the beginning of the audio track) at * which the playback will stop. Use -1 to play to the end of the * audio track * @param loop true if the playback should be looped once it reaches the end * @param listener The listener which will be notified of the playback * progress * @throws IllegalArgumentException if fromMs or toMs is beyond the playback * duration * @throws IllegalStateException if a playback, preview or an export is * already in progress */ public void startPlayback(long fromMs, long toMs, boolean loop, PlaybackProgressListener listener) { if (fromMs >= mDurationMs) { return; } mPlaybackThread = new PlaybackThread(fromMs, toMs, loop, listener); mPlaybackThread.start(); } /** * Stop the audio track playback. This method blocks until the ongoing * playback is stopped. * * @return The accurate current time when stop is effective expressed in * milliseconds */ public long stopPlayback() { final long stopTimeMs; if (mPlaybackThread != null) { stopTimeMs = mPlaybackThread.stopPlayback(); mPlaybackThread = null; } else { stopTimeMs = 0; } return stopTimeMs; } /** * This API allows to generate a file containing the sample volume levels of * this audio track object. This function may take significant time and is Loading
media/java/android/media/videoeditor/VideoEditorTestImpl.java +5 −8 Original line number Diff line number Diff line Loading @@ -537,16 +537,13 @@ public class VideoEditorTestImpl implements VideoEditor { * {@inheritDoc} */ public AudioTrack getAudioTrack(String audioTrackId) { if (mPreviewThread != null) { throw new IllegalStateException("Previewing is in progress"); for (AudioTrack at : mAudioTracks) { if (at.getId().equals(audioTrackId)) { return at; } final AudioTrack audioTrack = getAudioTrack(audioTrackId); if (audioTrack != null) { mAudioTracks.remove(audioTrack); } return audioTrack; return null; } /* Loading