Split UI components into separate module
Issue: #2139 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=150623215
@ -27,6 +27,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
compile project(':library-core')
|
||||
compile project(':library-ui')
|
||||
}
|
||||
|
||||
android.libraryVariants.all { variant ->
|
||||
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.google.android.exoplayer2.core.R;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
/**
|
||||
* A {@link FrameLayout} that resizes itself to match a specified aspect ratio.
|
||||
*/
|
||||
public final class AspectRatioFrameLayout extends FrameLayout {
|
||||
|
||||
/**
|
||||
* Resize modes for {@link AspectRatioFrameLayout}.
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({RESIZE_MODE_FIT, RESIZE_MODE_FIXED_WIDTH, RESIZE_MODE_FIXED_HEIGHT, RESIZE_MODE_FILL})
|
||||
public @interface ResizeMode {}
|
||||
|
||||
/**
|
||||
* Either the width or height is decreased to obtain the desired aspect ratio.
|
||||
*/
|
||||
public static final int RESIZE_MODE_FIT = 0;
|
||||
/**
|
||||
* The width is fixed and the height is increased or decreased to obtain the desired aspect ratio.
|
||||
*/
|
||||
public static final int RESIZE_MODE_FIXED_WIDTH = 1;
|
||||
/**
|
||||
* The height is fixed and the width is increased or decreased to obtain the desired aspect ratio.
|
||||
*/
|
||||
public static final int RESIZE_MODE_FIXED_HEIGHT = 2;
|
||||
/**
|
||||
* The specified aspect ratio is ignored.
|
||||
*/
|
||||
public static final int RESIZE_MODE_FILL = 3;
|
||||
|
||||
/**
|
||||
* The {@link FrameLayout} will not resize itself if the fractional difference between its natural
|
||||
* aspect ratio and the requested aspect ratio falls below this threshold.
|
||||
* <p>
|
||||
* This tolerance allows the view to occupy the whole of the screen when the requested aspect
|
||||
* ratio is very close, but not exactly equal to, the aspect ratio of the screen. This may reduce
|
||||
* the number of view layers that need to be composited by the underlying system, which can help
|
||||
* to reduce power consumption.
|
||||
*/
|
||||
private static final float MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f;
|
||||
|
||||
private float videoAspectRatio;
|
||||
private int resizeMode;
|
||||
|
||||
public AspectRatioFrameLayout(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AspectRatioFrameLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
resizeMode = RESIZE_MODE_FIT;
|
||||
if (attrs != null) {
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.AspectRatioFrameLayout, 0, 0);
|
||||
try {
|
||||
resizeMode = a.getInt(R.styleable.AspectRatioFrameLayout_resize_mode, RESIZE_MODE_FIT);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the aspect ratio that this view should satisfy.
|
||||
*
|
||||
* @param widthHeightRatio The width to height ratio.
|
||||
*/
|
||||
public void setAspectRatio(float widthHeightRatio) {
|
||||
if (this.videoAspectRatio != widthHeightRatio) {
|
||||
this.videoAspectRatio = widthHeightRatio;
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resize mode.
|
||||
*
|
||||
* @param resizeMode The resize mode.
|
||||
*/
|
||||
public void setResizeMode(@ResizeMode int resizeMode) {
|
||||
if (this.resizeMode != resizeMode) {
|
||||
this.resizeMode = resizeMode;
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (resizeMode == RESIZE_MODE_FILL || videoAspectRatio <= 0) {
|
||||
// Aspect ratio not set.
|
||||
return;
|
||||
}
|
||||
|
||||
int width = getMeasuredWidth();
|
||||
int height = getMeasuredHeight();
|
||||
float viewAspectRatio = (float) width / height;
|
||||
float aspectDeformation = videoAspectRatio / viewAspectRatio - 1;
|
||||
if (Math.abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) {
|
||||
// We're within the allowed tolerance.
|
||||
return;
|
||||
}
|
||||
|
||||
switch (resizeMode) {
|
||||
case RESIZE_MODE_FIXED_WIDTH:
|
||||
height = (int) (width / videoAspectRatio);
|
||||
break;
|
||||
case RESIZE_MODE_FIXED_HEIGHT:
|
||||
width = (int) (height * videoAspectRatio);
|
||||
break;
|
||||
default:
|
||||
if (aspectDeformation > 0) {
|
||||
height = (int) (width / videoAspectRatio);
|
||||
} else {
|
||||
width = (int) (height * videoAspectRatio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
|
||||
}
|
||||
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.widget.TextView;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.decoder.DecoderCounters;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
|
||||
/**
|
||||
* A helper class for periodically updating a {@link TextView} with debug information obtained from
|
||||
* a {@link SimpleExoPlayer}.
|
||||
*/
|
||||
public final class DebugTextViewHelper implements Runnable, ExoPlayer.EventListener {
|
||||
|
||||
private static final int REFRESH_INTERVAL_MS = 1000;
|
||||
|
||||
private final SimpleExoPlayer player;
|
||||
private final TextView textView;
|
||||
|
||||
private boolean started;
|
||||
|
||||
/**
|
||||
* @param player The {@link SimpleExoPlayer} from which debug information should be obtained.
|
||||
* @param textView The {@link TextView} that should be updated to display the information.
|
||||
*/
|
||||
public DebugTextViewHelper(SimpleExoPlayer player, TextView textView) {
|
||||
this.player = player;
|
||||
this.textView = textView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts periodic updates of the {@link TextView}. Must be called from the application's main
|
||||
* thread.
|
||||
*/
|
||||
public void start() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
started = true;
|
||||
player.addListener(this);
|
||||
updateAndPost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops periodic updates of the {@link TextView}. Must be called from the application's main
|
||||
* thread.
|
||||
*/
|
||||
public void stop() {
|
||||
if (!started) {
|
||||
return;
|
||||
}
|
||||
started = false;
|
||||
player.removeListener(this);
|
||||
textView.removeCallbacks(this);
|
||||
}
|
||||
|
||||
// ExoPlayer.EventListener implementation.
|
||||
|
||||
@Override
|
||||
public void onLoadingChanged(boolean isLoading) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
updateAndPost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {
|
||||
updateAndPost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException error) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
// Runnable implementation.
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
updateAndPost();
|
||||
}
|
||||
|
||||
// Private methods.
|
||||
|
||||
private void updateAndPost() {
|
||||
textView.setText(getPlayerStateString() + getPlayerWindowIndexString() + getVideoString()
|
||||
+ getAudioString());
|
||||
textView.removeCallbacks(this);
|
||||
textView.postDelayed(this, REFRESH_INTERVAL_MS);
|
||||
}
|
||||
|
||||
private String getPlayerStateString() {
|
||||
String text = "playWhenReady:" + player.getPlayWhenReady() + " playbackState:";
|
||||
switch (player.getPlaybackState()) {
|
||||
case ExoPlayer.STATE_BUFFERING:
|
||||
text += "buffering";
|
||||
break;
|
||||
case ExoPlayer.STATE_ENDED:
|
||||
text += "ended";
|
||||
break;
|
||||
case ExoPlayer.STATE_IDLE:
|
||||
text += "idle";
|
||||
break;
|
||||
case ExoPlayer.STATE_READY:
|
||||
text += "ready";
|
||||
break;
|
||||
default:
|
||||
text += "unknown";
|
||||
break;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private String getPlayerWindowIndexString() {
|
||||
return " window:" + player.getCurrentWindowIndex();
|
||||
}
|
||||
|
||||
private String getVideoString() {
|
||||
Format format = player.getVideoFormat();
|
||||
if (format == null) {
|
||||
return "";
|
||||
}
|
||||
return "\n" + format.sampleMimeType + "(id:" + format.id + " r:" + format.width + "x"
|
||||
+ format.height + getDecoderCountersBufferCountString(player.getVideoDecoderCounters())
|
||||
+ ")";
|
||||
}
|
||||
|
||||
private String getAudioString() {
|
||||
Format format = player.getAudioFormat();
|
||||
if (format == null) {
|
||||
return "";
|
||||
}
|
||||
return "\n" + format.sampleMimeType + "(id:" + format.id + " hz:" + format.sampleRate + " ch:"
|
||||
+ format.channelCount
|
||||
+ getDecoderCountersBufferCountString(player.getAudioDecoderCounters()) + ")";
|
||||
}
|
||||
|
||||
private static String getDecoderCountersBufferCountString(DecoderCounters counters) {
|
||||
if (counters == null) {
|
||||
return "";
|
||||
}
|
||||
counters.ensureUpdated();
|
||||
return " rb:" + counters.renderedOutputBufferCount
|
||||
+ " sb:" + counters.skippedOutputBufferCount
|
||||
+ " db:" + counters.droppedOutputBufferCount
|
||||
+ " mcdb:" + counters.maxConsecutiveDroppedOutputBufferCount;
|
||||
}
|
||||
|
||||
}
|
@ -1,813 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.SystemClock;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.core.R;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A view for controlling {@link ExoPlayer} instances.
|
||||
* <p>
|
||||
* A PlaybackControlView can be customized by setting attributes (or calling corresponding methods),
|
||||
* overriding the view's layout file or by specifying a custom view layout file, as outlined below.
|
||||
*
|
||||
* <h3>Attributes</h3>
|
||||
* The following attributes can be set on a PlaybackControlView when used in a layout XML file:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li><b>{@code show_timeout}</b> - The time between the last user interaction and the controls
|
||||
* being automatically hidden, in milliseconds. Use zero if the controls should not
|
||||
* automatically timeout.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setShowTimeoutMs(int)}</li>
|
||||
* <li>Default: {@link #DEFAULT_SHOW_TIMEOUT_MS}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code rewind_increment}</b> - The duration of the rewind applied when the user taps the
|
||||
* rewind button, in milliseconds. Use zero to disable the rewind button.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setRewindIncrementMs(int)}</li>
|
||||
* <li>Default: {@link #DEFAULT_REWIND_MS}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code fastforward_increment}</b> - Like {@code rewind_increment}, but for fast forward.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setFastForwardIncrementMs(int)}</li>
|
||||
* <li>Default: {@link #DEFAULT_FAST_FORWARD_MS}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code controller_layout_id}</b> - Specifies the id of the layout to be inflated. See
|
||||
* below for more details.
|
||||
* <ul>
|
||||
* <li>Corresponding method: None</li>
|
||||
* <li>Default: {@code R.id.exo_playback_control_view}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Overriding the layout file</h3>
|
||||
* To customize the layout of PlaybackControlView throughout your app, or just for certain
|
||||
* configurations, you can define {@code exo_playback_control_view.xml} layout files in your
|
||||
* application {@code res/layout*} directories. These layouts will override the one provided by the
|
||||
* ExoPlayer library, and will be inflated for use by PlaybackControlView. The view identifies and
|
||||
* binds its children by looking for the following ids:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li><b>{@code exo_play}</b> - The play button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_pause}</b> - The pause button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_ffwd}</b> - The fast forward button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_rew}</b> - The rewind button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_prev}</b> - The previous track button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_next}</b> - The next track button.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_position}</b> - Text view displaying the current playback position.
|
||||
* <ul>
|
||||
* <li>Type: {@link TextView}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_duration}</b> - Text view displaying the current media duration.
|
||||
* <ul>
|
||||
* <li>Type: {@link TextView}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_progress}</b> - Seek bar that's updated during playback and allows seeking.
|
||||
* <ul>
|
||||
* <li>Type: {@link SeekBar}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* All child views are optional and so can be omitted if not required, however where defined they
|
||||
* must be of the expected type.
|
||||
*
|
||||
* <h3>Specifying a custom layout file</h3>
|
||||
* Defining your own {@code exo_playback_control_view.xml} is useful to customize the layout of
|
||||
* PlaybackControlView throughout your application. It's also possible to customize the layout for a
|
||||
* single instance in a layout file. This is achieved by setting the {@code controller_layout_id}
|
||||
* attribute on a PlaybackControlView. This will cause the specified layout to be inflated instead
|
||||
* of {@code exo_playback_control_view.xml} for only the instance on which the attribute is set.
|
||||
*/
|
||||
public class PlaybackControlView extends FrameLayout {
|
||||
|
||||
/**
|
||||
* Listener to be notified about changes of the visibility of the UI control.
|
||||
*/
|
||||
public interface VisibilityListener {
|
||||
|
||||
/**
|
||||
* Called when the visibility changes.
|
||||
*
|
||||
* @param visibility The new visibility. Either {@link View#VISIBLE} or {@link View#GONE}.
|
||||
*/
|
||||
void onVisibilityChange(int visibility);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches seek operations to the player.
|
||||
*/
|
||||
public interface SeekDispatcher {
|
||||
|
||||
/**
|
||||
* @param player The player to seek.
|
||||
* @param windowIndex The index of the window.
|
||||
* @param positionMs The seek position in the specified window, or {@link C#TIME_UNSET} to seek
|
||||
* to the window's default position.
|
||||
* @return True if the seek was dispatched. False otherwise.
|
||||
*/
|
||||
boolean dispatchSeek(ExoPlayer player, int windowIndex, long positionMs);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Default {@link SeekDispatcher} that dispatches seeks to the player without modification.
|
||||
*/
|
||||
public static final SeekDispatcher DEFAULT_SEEK_DISPATCHER = new SeekDispatcher() {
|
||||
|
||||
@Override
|
||||
public boolean dispatchSeek(ExoPlayer player, int windowIndex, long positionMs) {
|
||||
player.seekTo(windowIndex, positionMs);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final int DEFAULT_FAST_FORWARD_MS = 15000;
|
||||
public static final int DEFAULT_REWIND_MS = 5000;
|
||||
public static final int DEFAULT_SHOW_TIMEOUT_MS = 5000;
|
||||
|
||||
private static final int PROGRESS_BAR_MAX = 1000;
|
||||
private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000;
|
||||
|
||||
private final ComponentListener componentListener;
|
||||
private final View previousButton;
|
||||
private final View nextButton;
|
||||
private final View playButton;
|
||||
private final View pauseButton;
|
||||
private final View fastForwardButton;
|
||||
private final View rewindButton;
|
||||
private final TextView durationView;
|
||||
private final TextView positionView;
|
||||
private final SeekBar progressBar;
|
||||
private final StringBuilder formatBuilder;
|
||||
private final Formatter formatter;
|
||||
private final Timeline.Window currentWindow;
|
||||
|
||||
private ExoPlayer player;
|
||||
private SeekDispatcher seekDispatcher;
|
||||
private VisibilityListener visibilityListener;
|
||||
|
||||
private boolean isAttachedToWindow;
|
||||
private boolean dragging;
|
||||
private int rewindMs;
|
||||
private int fastForwardMs;
|
||||
private int showTimeoutMs;
|
||||
private long hideAtMs;
|
||||
|
||||
private final Runnable updateProgressAction = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateProgress();
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable hideAction = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
|
||||
public PlaybackControlView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public PlaybackControlView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public PlaybackControlView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
int controllerLayoutId = R.layout.exo_playback_control_view;
|
||||
rewindMs = DEFAULT_REWIND_MS;
|
||||
fastForwardMs = DEFAULT_FAST_FORWARD_MS;
|
||||
showTimeoutMs = DEFAULT_SHOW_TIMEOUT_MS;
|
||||
if (attrs != null) {
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.PlaybackControlView, 0, 0);
|
||||
try {
|
||||
rewindMs = a.getInt(R.styleable.PlaybackControlView_rewind_increment, rewindMs);
|
||||
fastForwardMs = a.getInt(R.styleable.PlaybackControlView_fastforward_increment,
|
||||
fastForwardMs);
|
||||
showTimeoutMs = a.getInt(R.styleable.PlaybackControlView_show_timeout, showTimeoutMs);
|
||||
controllerLayoutId = a.getResourceId(R.styleable.PlaybackControlView_controller_layout_id,
|
||||
controllerLayoutId);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
currentWindow = new Timeline.Window();
|
||||
formatBuilder = new StringBuilder();
|
||||
formatter = new Formatter(formatBuilder, Locale.getDefault());
|
||||
componentListener = new ComponentListener();
|
||||
seekDispatcher = DEFAULT_SEEK_DISPATCHER;
|
||||
|
||||
LayoutInflater.from(context).inflate(controllerLayoutId, this);
|
||||
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
|
||||
|
||||
durationView = (TextView) findViewById(R.id.exo_duration);
|
||||
positionView = (TextView) findViewById(R.id.exo_position);
|
||||
progressBar = (SeekBar) findViewById(R.id.exo_progress);
|
||||
if (progressBar != null) {
|
||||
progressBar.setOnSeekBarChangeListener(componentListener);
|
||||
progressBar.setMax(PROGRESS_BAR_MAX);
|
||||
}
|
||||
playButton = findViewById(R.id.exo_play);
|
||||
if (playButton != null) {
|
||||
playButton.setOnClickListener(componentListener);
|
||||
}
|
||||
pauseButton = findViewById(R.id.exo_pause);
|
||||
if (pauseButton != null) {
|
||||
pauseButton.setOnClickListener(componentListener);
|
||||
}
|
||||
previousButton = findViewById(R.id.exo_prev);
|
||||
if (previousButton != null) {
|
||||
previousButton.setOnClickListener(componentListener);
|
||||
}
|
||||
nextButton = findViewById(R.id.exo_next);
|
||||
if (nextButton != null) {
|
||||
nextButton.setOnClickListener(componentListener);
|
||||
}
|
||||
rewindButton = findViewById(R.id.exo_rew);
|
||||
if (rewindButton != null) {
|
||||
rewindButton.setOnClickListener(componentListener);
|
||||
}
|
||||
fastForwardButton = findViewById(R.id.exo_ffwd);
|
||||
if (fastForwardButton != null) {
|
||||
fastForwardButton.setOnClickListener(componentListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player currently being controlled by this view, or null if no player is set.
|
||||
*/
|
||||
public ExoPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link ExoPlayer} to control.
|
||||
*
|
||||
* @param player the {@code ExoPlayer} to control.
|
||||
*/
|
||||
public void setPlayer(ExoPlayer player) {
|
||||
if (this.player == player) {
|
||||
return;
|
||||
}
|
||||
if (this.player != null) {
|
||||
this.player.removeListener(componentListener);
|
||||
}
|
||||
this.player = player;
|
||||
if (player != null) {
|
||||
player.addListener(componentListener);
|
||||
}
|
||||
updateAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link VisibilityListener}.
|
||||
*
|
||||
* @param listener The listener to be notified about visibility changes.
|
||||
*/
|
||||
public void setVisibilityListener(VisibilityListener listener) {
|
||||
this.visibilityListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link SeekDispatcher}.
|
||||
*
|
||||
* @param seekDispatcher The {@link SeekDispatcher}, or null to use
|
||||
* {@link #DEFAULT_SEEK_DISPATCHER}.
|
||||
*/
|
||||
public void setSeekDispatcher(SeekDispatcher seekDispatcher) {
|
||||
this.seekDispatcher = seekDispatcher == null ? DEFAULT_SEEK_DISPATCHER : seekDispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rewind increment in milliseconds.
|
||||
*
|
||||
* @param rewindMs The rewind increment in milliseconds. A non-positive value will cause the
|
||||
* rewind button to be disabled.
|
||||
*/
|
||||
public void setRewindIncrementMs(int rewindMs) {
|
||||
this.rewindMs = rewindMs;
|
||||
updateNavigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fast forward increment in milliseconds.
|
||||
*
|
||||
* @param fastForwardMs The fast forward increment in milliseconds. A non-positive value will
|
||||
* cause the fast forward button to be disabled.
|
||||
*/
|
||||
public void setFastForwardIncrementMs(int fastForwardMs) {
|
||||
this.fastForwardMs = fastForwardMs;
|
||||
updateNavigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the playback controls timeout. The playback controls are automatically hidden after
|
||||
* this duration of time has elapsed without user input.
|
||||
*
|
||||
* @return The duration in milliseconds. A non-positive value indicates that the controls will
|
||||
* remain visible indefinitely.
|
||||
*/
|
||||
public int getShowTimeoutMs() {
|
||||
return showTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the playback controls timeout. The playback controls are automatically hidden after this
|
||||
* duration of time has elapsed without user input.
|
||||
*
|
||||
* @param showTimeoutMs The duration in milliseconds. A non-positive value will cause the controls
|
||||
* to remain visible indefinitely.
|
||||
*/
|
||||
public void setShowTimeoutMs(int showTimeoutMs) {
|
||||
this.showTimeoutMs = showTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the playback controls. If {@link #getShowTimeoutMs()} is positive then the controls will
|
||||
* be automatically hidden after this duration of time has elapsed without user input.
|
||||
*/
|
||||
public void show() {
|
||||
if (!isVisible()) {
|
||||
setVisibility(VISIBLE);
|
||||
if (visibilityListener != null) {
|
||||
visibilityListener.onVisibilityChange(getVisibility());
|
||||
}
|
||||
updateAll();
|
||||
requestPlayPauseFocus();
|
||||
}
|
||||
// Call hideAfterTimeout even if already visible to reset the timeout.
|
||||
hideAfterTimeout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the controller.
|
||||
*/
|
||||
public void hide() {
|
||||
if (isVisible()) {
|
||||
setVisibility(GONE);
|
||||
if (visibilityListener != null) {
|
||||
visibilityListener.onVisibilityChange(getVisibility());
|
||||
}
|
||||
removeCallbacks(updateProgressAction);
|
||||
removeCallbacks(hideAction);
|
||||
hideAtMs = C.TIME_UNSET;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the controller is currently visible.
|
||||
*/
|
||||
public boolean isVisible() {
|
||||
return getVisibility() == VISIBLE;
|
||||
}
|
||||
|
||||
private void hideAfterTimeout() {
|
||||
removeCallbacks(hideAction);
|
||||
if (showTimeoutMs > 0) {
|
||||
hideAtMs = SystemClock.uptimeMillis() + showTimeoutMs;
|
||||
if (isAttachedToWindow) {
|
||||
postDelayed(hideAction, showTimeoutMs);
|
||||
}
|
||||
} else {
|
||||
hideAtMs = C.TIME_UNSET;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAll() {
|
||||
updatePlayPauseButton();
|
||||
updateNavigation();
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
private void updatePlayPauseButton() {
|
||||
if (!isVisible() || !isAttachedToWindow) {
|
||||
return;
|
||||
}
|
||||
boolean requestPlayPauseFocus = false;
|
||||
boolean playing = player != null && player.getPlayWhenReady();
|
||||
if (playButton != null) {
|
||||
requestPlayPauseFocus |= playing && playButton.isFocused();
|
||||
playButton.setVisibility(playing ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
if (pauseButton != null) {
|
||||
requestPlayPauseFocus |= !playing && pauseButton.isFocused();
|
||||
pauseButton.setVisibility(!playing ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
if (requestPlayPauseFocus) {
|
||||
requestPlayPauseFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateNavigation() {
|
||||
if (!isVisible() || !isAttachedToWindow) {
|
||||
return;
|
||||
}
|
||||
Timeline currentTimeline = player != null ? player.getCurrentTimeline() : null;
|
||||
boolean haveNonEmptyTimeline = currentTimeline != null && !currentTimeline.isEmpty();
|
||||
boolean isSeekable = false;
|
||||
boolean enablePrevious = false;
|
||||
boolean enableNext = false;
|
||||
if (haveNonEmptyTimeline) {
|
||||
int currentWindowIndex = player.getCurrentWindowIndex();
|
||||
currentTimeline.getWindow(currentWindowIndex, currentWindow);
|
||||
isSeekable = currentWindow.isSeekable;
|
||||
enablePrevious = currentWindowIndex > 0 || isSeekable || !currentWindow.isDynamic;
|
||||
enableNext = (currentWindowIndex < currentTimeline.getWindowCount() - 1)
|
||||
|| currentWindow.isDynamic;
|
||||
}
|
||||
setButtonEnabled(enablePrevious , previousButton);
|
||||
setButtonEnabled(enableNext, nextButton);
|
||||
setButtonEnabled(fastForwardMs > 0 && isSeekable, fastForwardButton);
|
||||
setButtonEnabled(rewindMs > 0 && isSeekable, rewindButton);
|
||||
if (progressBar != null) {
|
||||
progressBar.setEnabled(isSeekable);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateProgress() {
|
||||
if (!isVisible() || !isAttachedToWindow) {
|
||||
return;
|
||||
}
|
||||
long duration = player == null ? 0 : player.getDuration();
|
||||
long position = player == null ? 0 : player.getCurrentPosition();
|
||||
if (durationView != null) {
|
||||
durationView.setText(stringForTime(duration));
|
||||
}
|
||||
if (positionView != null && !dragging) {
|
||||
positionView.setText(stringForTime(position));
|
||||
}
|
||||
|
||||
if (progressBar != null) {
|
||||
if (!dragging) {
|
||||
progressBar.setProgress(progressBarValue(position));
|
||||
}
|
||||
long bufferedPosition = player == null ? 0 : player.getBufferedPosition();
|
||||
progressBar.setSecondaryProgress(progressBarValue(bufferedPosition));
|
||||
// Remove scheduled updates.
|
||||
}
|
||||
removeCallbacks(updateProgressAction);
|
||||
// Schedule an update if necessary.
|
||||
int playbackState = player == null ? ExoPlayer.STATE_IDLE : player.getPlaybackState();
|
||||
if (playbackState != ExoPlayer.STATE_IDLE && playbackState != ExoPlayer.STATE_ENDED) {
|
||||
long delayMs;
|
||||
if (player.getPlayWhenReady() && playbackState == ExoPlayer.STATE_READY) {
|
||||
delayMs = 1000 - (position % 1000);
|
||||
if (delayMs < 200) {
|
||||
delayMs += 1000;
|
||||
}
|
||||
} else {
|
||||
delayMs = 1000;
|
||||
}
|
||||
postDelayed(updateProgressAction, delayMs);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestPlayPauseFocus() {
|
||||
boolean playing = player != null && player.getPlayWhenReady();
|
||||
if (!playing && playButton != null) {
|
||||
playButton.requestFocus();
|
||||
} else if (playing && pauseButton != null) {
|
||||
pauseButton.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void setButtonEnabled(boolean enabled, View view) {
|
||||
if (view == null) {
|
||||
return;
|
||||
}
|
||||
view.setEnabled(enabled);
|
||||
if (Util.SDK_INT >= 11) {
|
||||
setViewAlphaV11(view, enabled ? 1f : 0.3f);
|
||||
view.setVisibility(VISIBLE);
|
||||
} else {
|
||||
view.setVisibility(enabled ? VISIBLE : INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(11)
|
||||
private void setViewAlphaV11(View view, float alpha) {
|
||||
view.setAlpha(alpha);
|
||||
}
|
||||
|
||||
private String stringForTime(long timeMs) {
|
||||
if (timeMs == C.TIME_UNSET) {
|
||||
timeMs = 0;
|
||||
}
|
||||
long totalSeconds = (timeMs + 500) / 1000;
|
||||
long seconds = totalSeconds % 60;
|
||||
long minutes = (totalSeconds / 60) % 60;
|
||||
long hours = totalSeconds / 3600;
|
||||
formatBuilder.setLength(0);
|
||||
return hours > 0 ? formatter.format("%d:%02d:%02d", hours, minutes, seconds).toString()
|
||||
: formatter.format("%02d:%02d", minutes, seconds).toString();
|
||||
}
|
||||
|
||||
private int progressBarValue(long position) {
|
||||
long duration = player == null ? C.TIME_UNSET : player.getDuration();
|
||||
return duration == C.TIME_UNSET || duration == 0 ? 0
|
||||
: (int) ((position * PROGRESS_BAR_MAX) / duration);
|
||||
}
|
||||
|
||||
private long positionValue(int progress) {
|
||||
long duration = player == null ? C.TIME_UNSET : player.getDuration();
|
||||
return duration == C.TIME_UNSET ? 0 : ((duration * progress) / PROGRESS_BAR_MAX);
|
||||
}
|
||||
|
||||
private void previous() {
|
||||
Timeline currentTimeline = player.getCurrentTimeline();
|
||||
if (currentTimeline.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int currentWindowIndex = player.getCurrentWindowIndex();
|
||||
currentTimeline.getWindow(currentWindowIndex, currentWindow);
|
||||
if (currentWindowIndex > 0 && (player.getCurrentPosition() <= MAX_POSITION_FOR_SEEK_TO_PREVIOUS
|
||||
|| (currentWindow.isDynamic && !currentWindow.isSeekable))) {
|
||||
seekTo(currentWindowIndex - 1, C.TIME_UNSET);
|
||||
} else {
|
||||
seekTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void next() {
|
||||
Timeline currentTimeline = player.getCurrentTimeline();
|
||||
if (currentTimeline.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int currentWindowIndex = player.getCurrentWindowIndex();
|
||||
if (currentWindowIndex < currentTimeline.getWindowCount() - 1) {
|
||||
seekTo(currentWindowIndex + 1, C.TIME_UNSET);
|
||||
} else if (currentTimeline.getWindow(currentWindowIndex, currentWindow, false).isDynamic) {
|
||||
seekTo(currentWindowIndex, C.TIME_UNSET);
|
||||
}
|
||||
}
|
||||
|
||||
private void rewind() {
|
||||
if (rewindMs <= 0) {
|
||||
return;
|
||||
}
|
||||
seekTo(Math.max(player.getCurrentPosition() - rewindMs, 0));
|
||||
}
|
||||
|
||||
private void fastForward() {
|
||||
if (fastForwardMs <= 0) {
|
||||
return;
|
||||
}
|
||||
seekTo(Math.min(player.getCurrentPosition() + fastForwardMs, player.getDuration()));
|
||||
}
|
||||
|
||||
private void seekTo(long positionMs) {
|
||||
seekTo(player.getCurrentWindowIndex(), positionMs);
|
||||
}
|
||||
|
||||
private void seekTo(int windowIndex, long positionMs) {
|
||||
boolean dispatched = seekDispatcher.dispatchSeek(player, windowIndex, positionMs);
|
||||
if (!dispatched) {
|
||||
// The seek wasn't dispatched. If the progress bar was dragged by the user to perform the
|
||||
// seek then it'll now be in the wrong position. Trigger a progress update to snap it back.
|
||||
updateProgress();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
isAttachedToWindow = true;
|
||||
if (hideAtMs != C.TIME_UNSET) {
|
||||
long delayMs = hideAtMs - SystemClock.uptimeMillis();
|
||||
if (delayMs <= 0) {
|
||||
hide();
|
||||
} else {
|
||||
postDelayed(hideAction, delayMs);
|
||||
}
|
||||
}
|
||||
updateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
isAttachedToWindow = false;
|
||||
removeCallbacks(updateProgressAction);
|
||||
removeCallbacks(hideAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
boolean handled = dispatchMediaKeyEvent(event) || super.dispatchKeyEvent(event);
|
||||
if (handled) {
|
||||
show();
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to process media key events. Any {@link KeyEvent} can be passed but only media key
|
||||
* events will be handled.
|
||||
*
|
||||
* @param event A key event.
|
||||
* @return Whether the key event was handled.
|
||||
*/
|
||||
public boolean dispatchMediaKeyEvent(KeyEvent event) {
|
||||
int keyCode = event.getKeyCode();
|
||||
if (player == null || !isHandledMediaKey(keyCode)) {
|
||||
return false;
|
||||
}
|
||||
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
|
||||
fastForward();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_REWIND:
|
||||
rewind();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
|
||||
player.setPlayWhenReady(!player.getPlayWhenReady());
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_PLAY:
|
||||
player.setPlayWhenReady(true);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_PAUSE:
|
||||
player.setPlayWhenReady(false);
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_NEXT:
|
||||
next();
|
||||
break;
|
||||
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
|
||||
previous();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
show();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isHandledMediaKey(int keyCode) {
|
||||
return keyCode == KeyEvent.KEYCODE_MEDIA_FAST_FORWARD
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_REWIND
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_PAUSE
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_NEXT
|
||||
|| keyCode == KeyEvent.KEYCODE_MEDIA_PREVIOUS;
|
||||
}
|
||||
|
||||
private final class ComponentListener implements ExoPlayer.EventListener,
|
||||
SeekBar.OnSeekBarChangeListener, OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
removeCallbacks(hideAction);
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (fromUser) {
|
||||
long position = positionValue(progress);
|
||||
if (positionView != null) {
|
||||
positionView.setText(stringForTime(position));
|
||||
}
|
||||
if (player != null && !dragging) {
|
||||
seekTo(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
dragging = false;
|
||||
if (player != null) {
|
||||
seekTo(positionValue(seekBar.getProgress()));
|
||||
}
|
||||
hideAfterTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
updatePlayPauseButton();
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {
|
||||
updateNavigation();
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
updateNavigation();
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadingChanged(boolean isLoading) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException error) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (player != null) {
|
||||
if (nextButton == view) {
|
||||
next();
|
||||
} else if (previousButton == view) {
|
||||
previous();
|
||||
} else if (fastForwardButton == view) {
|
||||
fastForward();
|
||||
} else if (rewindButton == view) {
|
||||
rewind();
|
||||
} else if (playButton == view) {
|
||||
player.setPlayWhenReady(true);
|
||||
} else if (pauseButton == view) {
|
||||
player.setPlayWhenReady(false);
|
||||
}
|
||||
}
|
||||
hideAfterTimeout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,718 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||
import com.google.android.exoplayer2.ExoPlayer;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.Timeline;
|
||||
import com.google.android.exoplayer2.core.R;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.ApicFrame;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextRenderer;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout.ResizeMode;
|
||||
import com.google.android.exoplayer2.ui.PlaybackControlView.SeekDispatcher;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A high level view for {@link SimpleExoPlayer} media playbacks. It displays video, subtitles and
|
||||
* album art during playback, and displays playback controls using a {@link PlaybackControlView}.
|
||||
* <p>
|
||||
* A SimpleExoPlayerView can be customized by setting attributes (or calling corresponding methods),
|
||||
* overriding the view's layout file or by specifying a custom view layout file, as outlined below.
|
||||
*
|
||||
* <h3>Attributes</h3>
|
||||
* The following attributes can be set on a SimpleExoPlayerView when used in a layout XML file:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li><b>{@code use_artwork}</b> - Whether artwork is used if available in audio streams.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setUseArtwork(boolean)}</li>
|
||||
* <li>Default: {@code true}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code default_artwork}</b> - Default artwork to use if no artwork available in audio
|
||||
* streams.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setDefaultArtwork(Bitmap)}</li>
|
||||
* <li>Default: {@code null}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code use_controller}</b> - Whether playback controls are displayed.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setUseController(boolean)}</li>
|
||||
* <li>Default: {@code true}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code resize_mode}</b> - Controls how video and album art is resized within the view.
|
||||
* Valid values are {@code fit}, {@code fixed_width}, {@code fixed_height} and {@code fill}.
|
||||
* <ul>
|
||||
* <li>Corresponding method: {@link #setResizeMode(int)}</li>
|
||||
* <li>Default: {@code fit}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code surface_type}</b> - The type of surface view used for video playbacks. Valid
|
||||
* values are {@code surface_view}, {@code texture_view} and {@code none}. Using {@code none}
|
||||
* is recommended for audio only applications, since creating the surface can be expensive.
|
||||
* Using {@code surface_view} is recommended for video applications.
|
||||
* <ul>
|
||||
* <li>Corresponding method: None</li>
|
||||
* <li>Default: {@code surface_view}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code player_layout_id}</b> - Specifies the id of the layout to be inflated. See below
|
||||
* for more details.
|
||||
* <ul>
|
||||
* <li>Corresponding method: None</li>
|
||||
* <li>Default: {@code R.id.exo_simple_player_view}</li>
|
||||
* </ul>
|
||||
* <li><b>{@code controller_layout_id}</b> - Specifies the id of the layout resource to be
|
||||
* inflated by the child {@link PlaybackControlView}. See below for more details.
|
||||
* <ul>
|
||||
* <li>Corresponding method: None</li>
|
||||
* <li>Default: {@code R.id.exo_playback_control_view}</li>
|
||||
* </ul>
|
||||
* <li>All attributes that can be set on a {@link PlaybackControlView} can also be set on a
|
||||
* SimpleExoPlayerView, and will be propagated to the inflated {@link PlaybackControlView}.
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* <h3>Overriding the layout file</h3>
|
||||
* To customize the layout of SimpleExoPlayerView throughout your app, or just for certain
|
||||
* configurations, you can define {@code exo_simple_player_view.xml} layout files in your
|
||||
* application {@code res/layout*} directories. These layouts will override the one provided by the
|
||||
* ExoPlayer library, and will be inflated for use by SimpleExoPlayerView. The view identifies and
|
||||
* binds its children by looking for the following ids:
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li><b>{@code exo_content_frame}</b> - A frame whose aspect ratio is resized based on the video
|
||||
* or album art of the media being played, and the configured {@code resize_mode}. The video
|
||||
* surface view is inflated into this frame as its first child.
|
||||
* <ul>
|
||||
* <li>Type: {@link AspectRatioFrameLayout}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_shutter}</b> - A view that's made visible when video should be hidden. This
|
||||
* view is typically an opaque view that covers the video surface view, thereby obscuring it
|
||||
* when visible.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_subtitles}</b> - Displays subtitles.
|
||||
* <ul>
|
||||
* <li>Type: {@link SubtitleView}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_artwork}</b> - Displays album art.
|
||||
* <ul>
|
||||
* <li>Type: {@link ImageView}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_controller_placeholder}</b> - A placeholder that's replaced with the inflated
|
||||
* {@link PlaybackControlView}.
|
||||
* <ul>
|
||||
* <li>Type: {@link View}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>{@code exo_overlay}</b> - A {@link FrameLayout} positioned on top of the player which
|
||||
* the app can access via {@link #getOverlayFrameLayout()}, provided for convenience.
|
||||
* <ul>
|
||||
* <li>Type: {@link FrameLayout}</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* All child views are optional and so can be omitted if not required, however where defined they
|
||||
* must be of the expected type.
|
||||
*
|
||||
* <h3>Specifying a custom layout file</h3>
|
||||
* Defining your own {@code exo_simple_player_view.xml} is useful to customize the layout of
|
||||
* SimpleExoPlayerView throughout your application. It's also possible to customize the layout for a
|
||||
* single instance in a layout file. This is achieved by setting the {@code player_layout_id}
|
||||
* attribute on a SimpleExoPlayerView. This will cause the specified layout to be inflated instead
|
||||
* of {@code exo_simple_player_view.xml} for only the instance on which the attribute is set.
|
||||
*/
|
||||
@TargetApi(16)
|
||||
public final class SimpleExoPlayerView extends FrameLayout {
|
||||
|
||||
private static final int SURFACE_TYPE_NONE = 0;
|
||||
private static final int SURFACE_TYPE_SURFACE_VIEW = 1;
|
||||
private static final int SURFACE_TYPE_TEXTURE_VIEW = 2;
|
||||
|
||||
private final AspectRatioFrameLayout contentFrame;
|
||||
private final View shutterView;
|
||||
private final View surfaceView;
|
||||
private final ImageView artworkView;
|
||||
private final SubtitleView subtitleView;
|
||||
private final PlaybackControlView controller;
|
||||
private final ComponentListener componentListener;
|
||||
private final FrameLayout overlayFrameLayout;
|
||||
|
||||
private SimpleExoPlayer player;
|
||||
private boolean useController;
|
||||
private boolean useArtwork;
|
||||
private Bitmap defaultArtwork;
|
||||
private int controllerShowTimeoutMs;
|
||||
|
||||
public SimpleExoPlayerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SimpleExoPlayerView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SimpleExoPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
|
||||
int playerLayoutId = R.layout.exo_simple_player_view;
|
||||
boolean useArtwork = true;
|
||||
int defaultArtworkId = 0;
|
||||
boolean useController = true;
|
||||
int surfaceType = SURFACE_TYPE_SURFACE_VIEW;
|
||||
int resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT;
|
||||
int controllerShowTimeoutMs = PlaybackControlView.DEFAULT_SHOW_TIMEOUT_MS;
|
||||
if (attrs != null) {
|
||||
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
|
||||
R.styleable.SimpleExoPlayerView, 0, 0);
|
||||
try {
|
||||
playerLayoutId = a.getResourceId(R.styleable.SimpleExoPlayerView_player_layout_id,
|
||||
playerLayoutId);
|
||||
useArtwork = a.getBoolean(R.styleable.SimpleExoPlayerView_use_artwork, useArtwork);
|
||||
defaultArtworkId = a.getResourceId(R.styleable.SimpleExoPlayerView_default_artwork,
|
||||
defaultArtworkId);
|
||||
useController = a.getBoolean(R.styleable.SimpleExoPlayerView_use_controller, useController);
|
||||
surfaceType = a.getInt(R.styleable.SimpleExoPlayerView_surface_type, surfaceType);
|
||||
resizeMode = a.getInt(R.styleable.SimpleExoPlayerView_resize_mode, resizeMode);
|
||||
controllerShowTimeoutMs = a.getInt(R.styleable.SimpleExoPlayerView_show_timeout,
|
||||
controllerShowTimeoutMs);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
LayoutInflater.from(context).inflate(playerLayoutId, this);
|
||||
componentListener = new ComponentListener();
|
||||
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
|
||||
|
||||
// Content frame.
|
||||
contentFrame = (AspectRatioFrameLayout) findViewById(R.id.exo_content_frame);
|
||||
if (contentFrame != null) {
|
||||
setResizeModeRaw(contentFrame, resizeMode);
|
||||
}
|
||||
|
||||
// Shutter view.
|
||||
shutterView = findViewById(R.id.exo_shutter);
|
||||
|
||||
// Create a surface view and insert it into the content frame, if there is one.
|
||||
if (contentFrame != null && surfaceType != SURFACE_TYPE_NONE) {
|
||||
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
||||
surfaceView = surfaceType == SURFACE_TYPE_TEXTURE_VIEW ? new TextureView(context)
|
||||
: new SurfaceView(context);
|
||||
surfaceView.setLayoutParams(params);
|
||||
contentFrame.addView(surfaceView, 0);
|
||||
} else {
|
||||
surfaceView = null;
|
||||
}
|
||||
|
||||
// Overlay frame layout.
|
||||
overlayFrameLayout = (FrameLayout) findViewById(R.id.exo_overlay);
|
||||
|
||||
// Artwork view.
|
||||
artworkView = (ImageView) findViewById(R.id.exo_artwork);
|
||||
this.useArtwork = useArtwork && artworkView != null;
|
||||
if (defaultArtworkId != 0) {
|
||||
defaultArtwork = BitmapFactory.decodeResource(context.getResources(), defaultArtworkId);
|
||||
}
|
||||
|
||||
// Subtitle view.
|
||||
subtitleView = (SubtitleView) findViewById(R.id.exo_subtitles);
|
||||
if (subtitleView != null) {
|
||||
subtitleView.setUserDefaultStyle();
|
||||
subtitleView.setUserDefaultTextSize();
|
||||
}
|
||||
|
||||
// Playback control view.
|
||||
View controllerPlaceholder = findViewById(R.id.exo_controller_placeholder);
|
||||
if (controllerPlaceholder != null) {
|
||||
// Note: rewindMs and fastForwardMs are passed via attrs, so we don't need to make explicit
|
||||
// calls to set them.
|
||||
this.controller = new PlaybackControlView(context, attrs);
|
||||
controller.setLayoutParams(controllerPlaceholder.getLayoutParams());
|
||||
ViewGroup parent = ((ViewGroup) controllerPlaceholder.getParent());
|
||||
int controllerIndex = parent.indexOfChild(controllerPlaceholder);
|
||||
parent.removeView(controllerPlaceholder);
|
||||
parent.addView(controller, controllerIndex);
|
||||
} else {
|
||||
this.controller = null;
|
||||
}
|
||||
this.controllerShowTimeoutMs = controller != null ? controllerShowTimeoutMs : 0;
|
||||
this.useController = useController && controller != null;
|
||||
hideController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the player currently set on this view, or null if no player is set.
|
||||
*/
|
||||
public SimpleExoPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link SimpleExoPlayer} to use. The {@link SimpleExoPlayer#setTextOutput} and
|
||||
* {@link SimpleExoPlayer#setVideoListener} method of the player will be called and previous
|
||||
* assignments are overridden.
|
||||
*
|
||||
* @param player The {@link SimpleExoPlayer} to use.
|
||||
*/
|
||||
public void setPlayer(SimpleExoPlayer player) {
|
||||
if (this.player == player) {
|
||||
return;
|
||||
}
|
||||
if (this.player != null) {
|
||||
this.player.setTextOutput(null);
|
||||
this.player.setVideoListener(null);
|
||||
this.player.removeListener(componentListener);
|
||||
this.player.setVideoSurface(null);
|
||||
}
|
||||
this.player = player;
|
||||
if (useController) {
|
||||
controller.setPlayer(player);
|
||||
}
|
||||
if (shutterView != null) {
|
||||
shutterView.setVisibility(VISIBLE);
|
||||
}
|
||||
if (player != null) {
|
||||
if (surfaceView instanceof TextureView) {
|
||||
player.setVideoTextureView((TextureView) surfaceView);
|
||||
} else if (surfaceView instanceof SurfaceView) {
|
||||
player.setVideoSurfaceView((SurfaceView) surfaceView);
|
||||
}
|
||||
player.setVideoListener(componentListener);
|
||||
player.addListener(componentListener);
|
||||
player.setTextOutput(componentListener);
|
||||
maybeShowController(false);
|
||||
updateForCurrentTrackSelections();
|
||||
} else {
|
||||
hideController();
|
||||
hideArtwork();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the resize mode.
|
||||
*
|
||||
* @param resizeMode The resize mode.
|
||||
*/
|
||||
public void setResizeMode(@ResizeMode int resizeMode) {
|
||||
Assertions.checkState(contentFrame != null);
|
||||
contentFrame.setResizeMode(resizeMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether artwork is displayed if present in the media.
|
||||
*/
|
||||
public boolean getUseArtwork() {
|
||||
return useArtwork;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether artwork is displayed if present in the media.
|
||||
*
|
||||
* @param useArtwork Whether artwork is displayed.
|
||||
*/
|
||||
public void setUseArtwork(boolean useArtwork) {
|
||||
Assertions.checkState(!useArtwork || artworkView != null);
|
||||
if (this.useArtwork != useArtwork) {
|
||||
this.useArtwork = useArtwork;
|
||||
updateForCurrentTrackSelections();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default artwork to display.
|
||||
*/
|
||||
public Bitmap getDefaultArtwork() {
|
||||
return defaultArtwork;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default artwork to display if {@code useArtwork} is {@code true} and no artwork is
|
||||
* present in the media.
|
||||
*
|
||||
* @param defaultArtwork the default artwork to display.
|
||||
*/
|
||||
public void setDefaultArtwork(Bitmap defaultArtwork) {
|
||||
if (this.defaultArtwork != defaultArtwork) {
|
||||
this.defaultArtwork = defaultArtwork;
|
||||
updateForCurrentTrackSelections();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the playback controls are enabled.
|
||||
*/
|
||||
public boolean getUseController() {
|
||||
return useController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether playback controls are enabled. If set to {@code false} the playback controls are
|
||||
* never visible and are disconnected from the player.
|
||||
*
|
||||
* @param useController Whether playback controls should be enabled.
|
||||
*/
|
||||
public void setUseController(boolean useController) {
|
||||
Assertions.checkState(!useController || controller != null);
|
||||
if (this.useController == useController) {
|
||||
return;
|
||||
}
|
||||
this.useController = useController;
|
||||
if (useController) {
|
||||
controller.setPlayer(player);
|
||||
} else if (controller != null) {
|
||||
controller.hide();
|
||||
controller.setPlayer(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to process media key events. Any {@link KeyEvent} can be passed but only media key
|
||||
* events will be handled. Does nothing if playback controls are disabled.
|
||||
*
|
||||
* @param event A key event.
|
||||
* @return Whether the key event was handled.
|
||||
*/
|
||||
public boolean dispatchMediaKeyEvent(KeyEvent event) {
|
||||
return useController && controller.dispatchMediaKeyEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the playback controls. Does nothing if playback controls are disabled.
|
||||
*/
|
||||
public void showController() {
|
||||
if (useController) {
|
||||
maybeShowController(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the playback controls. Does nothing if playback controls are disabled.
|
||||
*/
|
||||
public void hideController() {
|
||||
if (controller != null) {
|
||||
controller.hide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the playback controls timeout. The playback controls are automatically hidden after
|
||||
* this duration of time has elapsed without user input and with playback or buffering in
|
||||
* progress.
|
||||
*
|
||||
* @return The timeout in milliseconds. A non-positive value will cause the controller to remain
|
||||
* visible indefinitely.
|
||||
*/
|
||||
public int getControllerShowTimeoutMs() {
|
||||
return controllerShowTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the playback controls timeout. The playback controls are automatically hidden after this
|
||||
* duration of time has elapsed without user input and with playback or buffering in progress.
|
||||
*
|
||||
* @param controllerShowTimeoutMs The timeout in milliseconds. A non-positive value will cause
|
||||
* the controller to remain visible indefinitely.
|
||||
*/
|
||||
public void setControllerShowTimeoutMs(int controllerShowTimeoutMs) {
|
||||
Assertions.checkState(controller != null);
|
||||
this.controllerShowTimeoutMs = controllerShowTimeoutMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link PlaybackControlView.VisibilityListener}.
|
||||
*
|
||||
* @param listener The listener to be notified about visibility changes.
|
||||
*/
|
||||
public void setControllerVisibilityListener(PlaybackControlView.VisibilityListener listener) {
|
||||
Assertions.checkState(controller != null);
|
||||
controller.setVisibilityListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link SeekDispatcher}.
|
||||
*
|
||||
* @param seekDispatcher The {@link SeekDispatcher}, or null to use
|
||||
* {@link PlaybackControlView#DEFAULT_SEEK_DISPATCHER}.
|
||||
*/
|
||||
public void setSeekDispatcher(SeekDispatcher seekDispatcher) {
|
||||
Assertions.checkState(controller != null);
|
||||
controller.setSeekDispatcher(seekDispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the rewind increment in milliseconds.
|
||||
*
|
||||
* @param rewindMs The rewind increment in milliseconds.
|
||||
*/
|
||||
public void setRewindIncrementMs(int rewindMs) {
|
||||
Assertions.checkState(controller != null);
|
||||
controller.setRewindIncrementMs(rewindMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fast forward increment in milliseconds.
|
||||
*
|
||||
* @param fastForwardMs The fast forward increment in milliseconds.
|
||||
*/
|
||||
public void setFastForwardIncrementMs(int fastForwardMs) {
|
||||
Assertions.checkState(controller != null);
|
||||
controller.setFastForwardIncrementMs(fastForwardMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the view onto which video is rendered. This is either a {@link SurfaceView} (default)
|
||||
* or a {@link TextureView} if the {@code use_texture_view} view attribute has been set to true.
|
||||
*
|
||||
* @return Either a {@link SurfaceView} or a {@link TextureView}.
|
||||
*/
|
||||
public View getVideoSurfaceView() {
|
||||
return surfaceView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the overlay {@link FrameLayout}, which can be populated with UI elements to show on top of
|
||||
* the player.
|
||||
*
|
||||
* @return The overlay {@link FrameLayout}, or {@code null} if the layout has been customized and
|
||||
* the overlay is not present.
|
||||
*/
|
||||
public FrameLayout getOverlayFrameLayout() {
|
||||
return overlayFrameLayout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link SubtitleView}.
|
||||
*
|
||||
* @return The {@link SubtitleView}, or {@code null} if the layout has been customized and the
|
||||
* subtitle view is not present.
|
||||
*/
|
||||
public SubtitleView getSubtitleView() {
|
||||
return subtitleView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (!useController || player == null || ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
if (controller.isVisible()) {
|
||||
controller.hide();
|
||||
} else {
|
||||
maybeShowController(true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTrackballEvent(MotionEvent ev) {
|
||||
if (!useController || player == null) {
|
||||
return false;
|
||||
}
|
||||
maybeShowController(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void maybeShowController(boolean isForced) {
|
||||
if (!useController || player == null) {
|
||||
return;
|
||||
}
|
||||
int playbackState = player.getPlaybackState();
|
||||
boolean showIndefinitely = playbackState == ExoPlayer.STATE_IDLE
|
||||
|| playbackState == ExoPlayer.STATE_ENDED || !player.getPlayWhenReady();
|
||||
boolean wasShowingIndefinitely = controller.isVisible() && controller.getShowTimeoutMs() <= 0;
|
||||
controller.setShowTimeoutMs(showIndefinitely ? 0 : controllerShowTimeoutMs);
|
||||
if (isForced || showIndefinitely || wasShowingIndefinitely) {
|
||||
controller.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateForCurrentTrackSelections() {
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
TrackSelectionArray selections = player.getCurrentTrackSelections();
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
if (player.getRendererType(i) == C.TRACK_TYPE_VIDEO && selections.get(i) != null) {
|
||||
// Video enabled so artwork must be hidden. If the shutter is closed, it will be opened in
|
||||
// onRenderedFirstFrame().
|
||||
hideArtwork();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Video disabled so the shutter must be closed.
|
||||
if (shutterView != null) {
|
||||
shutterView.setVisibility(VISIBLE);
|
||||
}
|
||||
// Display artwork if enabled and available, else hide it.
|
||||
if (useArtwork) {
|
||||
for (int i = 0; i < selections.length; i++) {
|
||||
TrackSelection selection = selections.get(i);
|
||||
if (selection != null) {
|
||||
for (int j = 0; j < selection.length(); j++) {
|
||||
Metadata metadata = selection.getFormat(j).metadata;
|
||||
if (metadata != null && setArtworkFromMetadata(metadata)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (setArtworkFromBitmap(defaultArtwork)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Artwork disabled or unavailable.
|
||||
hideArtwork();
|
||||
}
|
||||
|
||||
private boolean setArtworkFromMetadata(Metadata metadata) {
|
||||
for (int i = 0; i < metadata.length(); i++) {
|
||||
Metadata.Entry metadataEntry = metadata.get(i);
|
||||
if (metadataEntry instanceof ApicFrame) {
|
||||
byte[] bitmapData = ((ApicFrame) metadataEntry).pictureData;
|
||||
Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length);
|
||||
return setArtworkFromBitmap(bitmap);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean setArtworkFromBitmap(Bitmap bitmap) {
|
||||
if (bitmap != null) {
|
||||
int bitmapWidth = bitmap.getWidth();
|
||||
int bitmapHeight = bitmap.getHeight();
|
||||
if (bitmapWidth > 0 && bitmapHeight > 0) {
|
||||
if (contentFrame != null) {
|
||||
contentFrame.setAspectRatio((float) bitmapWidth / bitmapHeight);
|
||||
}
|
||||
artworkView.setImageBitmap(bitmap);
|
||||
artworkView.setVisibility(VISIBLE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void hideArtwork() {
|
||||
if (artworkView != null) {
|
||||
artworkView.setImageResource(android.R.color.transparent); // Clears any bitmap reference.
|
||||
artworkView.setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ResourceType")
|
||||
private static void setResizeModeRaw(AspectRatioFrameLayout aspectRatioFrame, int resizeMode) {
|
||||
aspectRatioFrame.setResizeMode(resizeMode);
|
||||
}
|
||||
|
||||
private final class ComponentListener implements SimpleExoPlayer.VideoListener,
|
||||
TextRenderer.Output, ExoPlayer.EventListener {
|
||||
|
||||
// TextRenderer.Output implementation
|
||||
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
if (subtitleView != null) {
|
||||
subtitleView.onCues(cues);
|
||||
}
|
||||
}
|
||||
|
||||
// SimpleExoPlayer.VideoListener implementation
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees,
|
||||
float pixelWidthHeightRatio) {
|
||||
if (contentFrame != null) {
|
||||
float aspectRatio = height == 0 ? 1 : (width * pixelWidthHeightRatio) / height;
|
||||
contentFrame.setAspectRatio(aspectRatio);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRenderedFirstFrame() {
|
||||
if (shutterView != null) {
|
||||
shutterView.setVisibility(INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackGroupArray tracks, TrackSelectionArray selections) {
|
||||
updateForCurrentTrackSelections();
|
||||
}
|
||||
|
||||
// ExoPlayer.EventListener implementation
|
||||
|
||||
@Override
|
||||
public void onLoadingChanged(boolean isLoading) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
maybeShowController(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerError(ExoPlaybackException e) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,405 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Join;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.text.Layout.Alignment;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/**
|
||||
* Paints subtitle {@link Cue}s.
|
||||
*/
|
||||
/* package */ final class SubtitlePainter {
|
||||
|
||||
private static final String TAG = "SubtitlePainter";
|
||||
|
||||
/**
|
||||
* Ratio of inner padding to font size.
|
||||
*/
|
||||
private static final float INNER_PADDING_RATIO = 0.125f;
|
||||
|
||||
/**
|
||||
* Temporary rectangle used for computing line bounds.
|
||||
*/
|
||||
private final RectF lineBounds = new RectF();
|
||||
|
||||
// Styled dimensions.
|
||||
private final float cornerRadius;
|
||||
private final float outlineWidth;
|
||||
private final float shadowRadius;
|
||||
private final float shadowOffset;
|
||||
private final float spacingMult;
|
||||
private final float spacingAdd;
|
||||
|
||||
private final TextPaint textPaint;
|
||||
private final Paint paint;
|
||||
|
||||
// Previous input variables.
|
||||
private CharSequence cueText;
|
||||
private Alignment cueTextAlignment;
|
||||
private Bitmap cueBitmap;
|
||||
private float cueLine;
|
||||
@Cue.LineType
|
||||
private int cueLineType;
|
||||
@Cue.AnchorType
|
||||
private int cueLineAnchor;
|
||||
private float cuePosition;
|
||||
@Cue.AnchorType
|
||||
private int cuePositionAnchor;
|
||||
private float cueSize;
|
||||
private boolean applyEmbeddedStyles;
|
||||
private int foregroundColor;
|
||||
private int backgroundColor;
|
||||
private int windowColor;
|
||||
private int edgeColor;
|
||||
@CaptionStyleCompat.EdgeType
|
||||
private int edgeType;
|
||||
private float textSizePx;
|
||||
private float bottomPaddingFraction;
|
||||
private int parentLeft;
|
||||
private int parentTop;
|
||||
private int parentRight;
|
||||
private int parentBottom;
|
||||
|
||||
// Derived drawing variables.
|
||||
private StaticLayout textLayout;
|
||||
private int textLeft;
|
||||
private int textTop;
|
||||
private int textPaddingX;
|
||||
private Rect bitmapRect;
|
||||
|
||||
@SuppressWarnings("ResourceType")
|
||||
public SubtitlePainter(Context context) {
|
||||
int[] viewAttr = {android.R.attr.lineSpacingExtra, android.R.attr.lineSpacingMultiplier};
|
||||
TypedArray styledAttributes = context.obtainStyledAttributes(null, viewAttr, 0, 0);
|
||||
spacingAdd = styledAttributes.getDimensionPixelSize(0, 0);
|
||||
spacingMult = styledAttributes.getFloat(1, 1);
|
||||
styledAttributes.recycle();
|
||||
|
||||
Resources resources = context.getResources();
|
||||
DisplayMetrics displayMetrics = resources.getDisplayMetrics();
|
||||
int twoDpInPx = Math.round((2f * displayMetrics.densityDpi) / DisplayMetrics.DENSITY_DEFAULT);
|
||||
cornerRadius = twoDpInPx;
|
||||
outlineWidth = twoDpInPx;
|
||||
shadowRadius = twoDpInPx;
|
||||
shadowOffset = twoDpInPx;
|
||||
|
||||
textPaint = new TextPaint();
|
||||
textPaint.setAntiAlias(true);
|
||||
textPaint.setSubpixelText(true);
|
||||
|
||||
paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Style.FILL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the provided {@link Cue} into a canvas with the specified styling.
|
||||
* <p>
|
||||
* A call to this method is able to use cached results of calculations made during the previous
|
||||
* call, and so an instance of this class is able to optimize repeated calls to this method in
|
||||
* which the same parameters are passed.
|
||||
*
|
||||
* @param cue The cue to draw.
|
||||
* @param applyEmbeddedStyles Whether styling embedded within the cue should be applied.
|
||||
* @param style The style to use when drawing the cue text.
|
||||
* @param textSizePx The text size to use when drawing the cue text, in pixels.
|
||||
* @param bottomPaddingFraction The bottom padding fraction to apply when {@link Cue#line} is
|
||||
* {@link Cue#DIMEN_UNSET}, as a fraction of the viewport height
|
||||
* @param canvas The canvas into which to draw.
|
||||
* @param cueBoxLeft The left position of the enclosing cue box.
|
||||
* @param cueBoxTop The top position of the enclosing cue box.
|
||||
* @param cueBoxRight The right position of the enclosing cue box.
|
||||
* @param cueBoxBottom The bottom position of the enclosing cue box.
|
||||
*/
|
||||
public void draw(Cue cue, boolean applyEmbeddedStyles, CaptionStyleCompat style, float textSizePx,
|
||||
float bottomPaddingFraction, Canvas canvas, int cueBoxLeft, int cueBoxTop, int cueBoxRight,
|
||||
int cueBoxBottom) {
|
||||
boolean isTextCue = cue.bitmap == null;
|
||||
CharSequence cueText = null;
|
||||
Bitmap cueBitmap = null;
|
||||
int windowColor = Color.BLACK;
|
||||
if (isTextCue) {
|
||||
cueText = cue.text;
|
||||
if (TextUtils.isEmpty(cueText)) {
|
||||
// Nothing to draw.
|
||||
return;
|
||||
}
|
||||
windowColor = cue.windowColorSet ? cue.windowColor : style.windowColor;
|
||||
if (!applyEmbeddedStyles) {
|
||||
// Strip out any embedded styling.
|
||||
cueText = cueText.toString();
|
||||
windowColor = style.windowColor;
|
||||
}
|
||||
} else {
|
||||
cueBitmap = cue.bitmap;
|
||||
}
|
||||
if (areCharSequencesEqual(this.cueText, cueText)
|
||||
&& Util.areEqual(this.cueTextAlignment, cue.textAlignment)
|
||||
&& this.cueBitmap == cueBitmap
|
||||
&& this.cueLine == cue.line
|
||||
&& this.cueLineType == cue.lineType
|
||||
&& Util.areEqual(this.cueLineAnchor, cue.lineAnchor)
|
||||
&& this.cuePosition == cue.position
|
||||
&& Util.areEqual(this.cuePositionAnchor, cue.positionAnchor)
|
||||
&& this.cueSize == cue.size
|
||||
&& this.applyEmbeddedStyles == applyEmbeddedStyles
|
||||
&& this.foregroundColor == style.foregroundColor
|
||||
&& this.backgroundColor == style.backgroundColor
|
||||
&& this.windowColor == windowColor
|
||||
&& this.edgeType == style.edgeType
|
||||
&& this.edgeColor == style.edgeColor
|
||||
&& Util.areEqual(this.textPaint.getTypeface(), style.typeface)
|
||||
&& this.textSizePx == textSizePx
|
||||
&& this.bottomPaddingFraction == bottomPaddingFraction
|
||||
&& this.parentLeft == cueBoxLeft
|
||||
&& this.parentTop == cueBoxTop
|
||||
&& this.parentRight == cueBoxRight
|
||||
&& this.parentBottom == cueBoxBottom) {
|
||||
// We can use the cached layout.
|
||||
drawLayout(canvas, isTextCue);
|
||||
return;
|
||||
}
|
||||
|
||||
this.cueText = cueText;
|
||||
this.cueTextAlignment = cue.textAlignment;
|
||||
this.cueBitmap = cueBitmap;
|
||||
this.cueLine = cue.line;
|
||||
this.cueLineType = cue.lineType;
|
||||
this.cueLineAnchor = cue.lineAnchor;
|
||||
this.cuePosition = cue.position;
|
||||
this.cuePositionAnchor = cue.positionAnchor;
|
||||
this.cueSize = cue.size;
|
||||
this.applyEmbeddedStyles = applyEmbeddedStyles;
|
||||
this.foregroundColor = style.foregroundColor;
|
||||
this.backgroundColor = style.backgroundColor;
|
||||
this.windowColor = windowColor;
|
||||
this.edgeType = style.edgeType;
|
||||
this.edgeColor = style.edgeColor;
|
||||
this.textPaint.setTypeface(style.typeface);
|
||||
this.textSizePx = textSizePx;
|
||||
this.bottomPaddingFraction = bottomPaddingFraction;
|
||||
this.parentLeft = cueBoxLeft;
|
||||
this.parentTop = cueBoxTop;
|
||||
this.parentRight = cueBoxRight;
|
||||
this.parentBottom = cueBoxBottom;
|
||||
|
||||
if (isTextCue) {
|
||||
setupTextLayout();
|
||||
} else {
|
||||
setupBitmapLayout();
|
||||
}
|
||||
drawLayout(canvas, isTextCue);
|
||||
}
|
||||
|
||||
private void setupTextLayout() {
|
||||
int parentWidth = parentRight - parentLeft;
|
||||
int parentHeight = parentBottom - parentTop;
|
||||
|
||||
textPaint.setTextSize(textSizePx);
|
||||
int textPaddingX = (int) (textSizePx * INNER_PADDING_RATIO + 0.5f);
|
||||
|
||||
int availableWidth = parentWidth - textPaddingX * 2;
|
||||
if (cueSize != Cue.DIMEN_UNSET) {
|
||||
availableWidth = (int) (availableWidth * cueSize);
|
||||
}
|
||||
if (availableWidth <= 0) {
|
||||
Log.w(TAG, "Skipped drawing subtitle cue (insufficient space)");
|
||||
return;
|
||||
}
|
||||
|
||||
Alignment textAlignment = cueTextAlignment == null ? Alignment.ALIGN_CENTER : cueTextAlignment;
|
||||
textLayout = new StaticLayout(cueText, textPaint, availableWidth, textAlignment, spacingMult,
|
||||
spacingAdd, true);
|
||||
int textHeight = textLayout.getHeight();
|
||||
int textWidth = 0;
|
||||
int lineCount = textLayout.getLineCount();
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
textWidth = Math.max((int) Math.ceil(textLayout.getLineWidth(i)), textWidth);
|
||||
}
|
||||
if (cueSize != Cue.DIMEN_UNSET && textWidth < availableWidth) {
|
||||
textWidth = availableWidth;
|
||||
}
|
||||
textWidth += textPaddingX * 2;
|
||||
|
||||
int textLeft;
|
||||
int textRight;
|
||||
if (cuePosition != Cue.DIMEN_UNSET) {
|
||||
int anchorPosition = Math.round(parentWidth * cuePosition) + parentLeft;
|
||||
textLeft = cuePositionAnchor == Cue.ANCHOR_TYPE_END ? anchorPosition - textWidth
|
||||
: cuePositionAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorPosition * 2 - textWidth) / 2
|
||||
: anchorPosition;
|
||||
textLeft = Math.max(textLeft, parentLeft);
|
||||
textRight = Math.min(textLeft + textWidth, parentRight);
|
||||
} else {
|
||||
textLeft = (parentWidth - textWidth) / 2;
|
||||
textRight = textLeft + textWidth;
|
||||
}
|
||||
|
||||
textWidth = textRight - textLeft;
|
||||
if (textWidth <= 0) {
|
||||
Log.w(TAG, "Skipped drawing subtitle cue (invalid horizontal positioning)");
|
||||
return;
|
||||
}
|
||||
|
||||
int textTop;
|
||||
if (cueLine != Cue.DIMEN_UNSET) {
|
||||
int anchorPosition;
|
||||
if (cueLineType == Cue.LINE_TYPE_FRACTION) {
|
||||
anchorPosition = Math.round(parentHeight * cueLine) + parentTop;
|
||||
} else {
|
||||
// cueLineType == Cue.LINE_TYPE_NUMBER
|
||||
int firstLineHeight = textLayout.getLineBottom(0) - textLayout.getLineTop(0);
|
||||
if (cueLine >= 0) {
|
||||
anchorPosition = Math.round(cueLine * firstLineHeight) + parentTop;
|
||||
} else {
|
||||
anchorPosition = Math.round((cueLine + 1) * firstLineHeight) + parentBottom;
|
||||
}
|
||||
}
|
||||
textTop = cueLineAnchor == Cue.ANCHOR_TYPE_END ? anchorPosition - textHeight
|
||||
: cueLineAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorPosition * 2 - textHeight) / 2
|
||||
: anchorPosition;
|
||||
if (textTop + textHeight > parentBottom) {
|
||||
textTop = parentBottom - textHeight;
|
||||
} else if (textTop < parentTop) {
|
||||
textTop = parentTop;
|
||||
}
|
||||
} else {
|
||||
textTop = parentBottom - textHeight - (int) (parentHeight * bottomPaddingFraction);
|
||||
}
|
||||
|
||||
// Update the derived drawing variables.
|
||||
this.textLayout = new StaticLayout(cueText, textPaint, textWidth, textAlignment, spacingMult,
|
||||
spacingAdd, true);
|
||||
this.textLeft = textLeft;
|
||||
this.textTop = textTop;
|
||||
this.textPaddingX = textPaddingX;
|
||||
}
|
||||
|
||||
private void setupBitmapLayout() {
|
||||
int parentWidth = parentRight - parentLeft;
|
||||
int parentHeight = parentBottom - parentTop;
|
||||
float anchorX = parentLeft + (parentWidth * cuePosition);
|
||||
float anchorY = parentTop + (parentHeight * cueLine);
|
||||
int width = Math.round(parentWidth * cueSize);
|
||||
int height = Math.round(width * ((float) cueBitmap.getHeight() / cueBitmap.getWidth()));
|
||||
int x = Math.round(cueLineAnchor == Cue.ANCHOR_TYPE_END ? (anchorX - width)
|
||||
: cueLineAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorX - (width / 2)) : anchorX);
|
||||
int y = Math.round(cuePositionAnchor == Cue.ANCHOR_TYPE_END ? (anchorY - height)
|
||||
: cuePositionAnchor == Cue.ANCHOR_TYPE_MIDDLE ? (anchorY - (height / 2)) : anchorY);
|
||||
bitmapRect = new Rect(x, y, x + width, y + height);
|
||||
}
|
||||
|
||||
private void drawLayout(Canvas canvas, boolean isTextCue) {
|
||||
if (isTextCue) {
|
||||
drawTextLayout(canvas);
|
||||
} else {
|
||||
drawBitmapLayout(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawTextLayout(Canvas canvas) {
|
||||
StaticLayout layout = textLayout;
|
||||
if (layout == null) {
|
||||
// Nothing to draw.
|
||||
return;
|
||||
}
|
||||
|
||||
int saveCount = canvas.save();
|
||||
canvas.translate(textLeft, textTop);
|
||||
|
||||
if (Color.alpha(windowColor) > 0) {
|
||||
paint.setColor(windowColor);
|
||||
canvas.drawRect(-textPaddingX, 0, layout.getWidth() + textPaddingX, layout.getHeight(),
|
||||
paint);
|
||||
}
|
||||
|
||||
if (Color.alpha(backgroundColor) > 0) {
|
||||
paint.setColor(backgroundColor);
|
||||
float previousBottom = layout.getLineTop(0);
|
||||
int lineCount = layout.getLineCount();
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
lineBounds.left = layout.getLineLeft(i) - textPaddingX;
|
||||
lineBounds.right = layout.getLineRight(i) + textPaddingX;
|
||||
lineBounds.top = previousBottom;
|
||||
lineBounds.bottom = layout.getLineBottom(i);
|
||||
previousBottom = lineBounds.bottom;
|
||||
canvas.drawRoundRect(lineBounds, cornerRadius, cornerRadius, paint);
|
||||
}
|
||||
}
|
||||
|
||||
if (edgeType == CaptionStyleCompat.EDGE_TYPE_OUTLINE) {
|
||||
textPaint.setStrokeJoin(Join.ROUND);
|
||||
textPaint.setStrokeWidth(outlineWidth);
|
||||
textPaint.setColor(edgeColor);
|
||||
textPaint.setStyle(Style.FILL_AND_STROKE);
|
||||
layout.draw(canvas);
|
||||
} else if (edgeType == CaptionStyleCompat.EDGE_TYPE_DROP_SHADOW) {
|
||||
textPaint.setShadowLayer(shadowRadius, shadowOffset, shadowOffset, edgeColor);
|
||||
} else if (edgeType == CaptionStyleCompat.EDGE_TYPE_RAISED
|
||||
|| edgeType == CaptionStyleCompat.EDGE_TYPE_DEPRESSED) {
|
||||
boolean raised = edgeType == CaptionStyleCompat.EDGE_TYPE_RAISED;
|
||||
int colorUp = raised ? Color.WHITE : edgeColor;
|
||||
int colorDown = raised ? edgeColor : Color.WHITE;
|
||||
float offset = shadowRadius / 2f;
|
||||
textPaint.setColor(foregroundColor);
|
||||
textPaint.setStyle(Style.FILL);
|
||||
textPaint.setShadowLayer(shadowRadius, -offset, -offset, colorUp);
|
||||
layout.draw(canvas);
|
||||
textPaint.setShadowLayer(shadowRadius, offset, offset, colorDown);
|
||||
}
|
||||
|
||||
textPaint.setColor(foregroundColor);
|
||||
textPaint.setStyle(Style.FILL);
|
||||
layout.draw(canvas);
|
||||
textPaint.setShadowLayer(0, 0, 0, 0);
|
||||
|
||||
canvas.restoreToCount(saveCount);
|
||||
}
|
||||
|
||||
private void drawBitmapLayout(Canvas canvas) {
|
||||
canvas.drawBitmap(cueBitmap, null, bitmapRect, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used instead of {@link TextUtils#equals(CharSequence, CharSequence)} because the
|
||||
* latter only checks the text of each sequence, and does not check for equality of styling that
|
||||
* may be embedded within the {@link CharSequence}s.
|
||||
*/
|
||||
private static boolean areCharSequencesEqual(CharSequence first, CharSequence second) {
|
||||
// Some CharSequence implementations don't perform a cheap referential equality check in their
|
||||
// equals methods, so we perform one explicitly here.
|
||||
return first == second || (first != null && first.equals(second));
|
||||
}
|
||||
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ui;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.CaptioningManager;
|
||||
import com.google.android.exoplayer2.text.CaptionStyleCompat;
|
||||
import com.google.android.exoplayer2.text.Cue;
|
||||
import com.google.android.exoplayer2.text.TextRenderer;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A view for displaying subtitle {@link Cue}s.
|
||||
*/
|
||||
public final class SubtitleView extends View implements TextRenderer.Output {
|
||||
|
||||
/**
|
||||
* The default fractional text size.
|
||||
*
|
||||
* @see #setFractionalTextSize(float, boolean)
|
||||
*/
|
||||
public static final float DEFAULT_TEXT_SIZE_FRACTION = 0.0533f;
|
||||
|
||||
/**
|
||||
* The default bottom padding to apply when {@link Cue#line} is {@link Cue#DIMEN_UNSET}, as a
|
||||
* fraction of the viewport height.
|
||||
*
|
||||
* @see #setBottomPaddingFraction(float)
|
||||
*/
|
||||
public static final float DEFAULT_BOTTOM_PADDING_FRACTION = 0.08f;
|
||||
|
||||
private static final int FRACTIONAL = 0;
|
||||
private static final int FRACTIONAL_IGNORE_PADDING = 1;
|
||||
private static final int ABSOLUTE = 2;
|
||||
|
||||
private final List<SubtitlePainter> painters;
|
||||
|
||||
private List<Cue> cues;
|
||||
private int textSizeType;
|
||||
private float textSize;
|
||||
private boolean applyEmbeddedStyles;
|
||||
private CaptionStyleCompat style;
|
||||
private float bottomPaddingFraction;
|
||||
|
||||
public SubtitleView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SubtitleView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
painters = new ArrayList<>();
|
||||
textSizeType = FRACTIONAL;
|
||||
textSize = DEFAULT_TEXT_SIZE_FRACTION;
|
||||
applyEmbeddedStyles = true;
|
||||
style = CaptionStyleCompat.DEFAULT;
|
||||
bottomPaddingFraction = DEFAULT_BOTTOM_PADDING_FRACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCues(List<Cue> cues) {
|
||||
setCues(cues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cues to be displayed by the view.
|
||||
*
|
||||
* @param cues The cues to display.
|
||||
*/
|
||||
public void setCues(List<Cue> cues) {
|
||||
if (this.cues == cues) {
|
||||
return;
|
||||
}
|
||||
this.cues = cues;
|
||||
// Ensure we have sufficient painters.
|
||||
int cueCount = (cues == null) ? 0 : cues.size();
|
||||
while (painters.size() < cueCount) {
|
||||
painters.add(new SubtitlePainter(getContext()));
|
||||
}
|
||||
// Invalidate to trigger drawing.
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the text size to a given unit and value.
|
||||
* <p>
|
||||
* See {@link TypedValue} for the possible dimension units.
|
||||
*
|
||||
* @param unit The desired dimension unit.
|
||||
* @param size The desired size in the given units.
|
||||
*/
|
||||
public void setFixedTextSize(int unit, float size) {
|
||||
Context context = getContext();
|
||||
Resources resources;
|
||||
if (context == null) {
|
||||
resources = Resources.getSystem();
|
||||
} else {
|
||||
resources = context.getResources();
|
||||
}
|
||||
setTextSize(ABSOLUTE, TypedValue.applyDimension(unit, size, resources.getDisplayMetrics()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text size to one derived from {@link CaptioningManager#getFontScale()}, or to a
|
||||
* default size before API level 19.
|
||||
*/
|
||||
public void setUserDefaultTextSize() {
|
||||
float fontScale = Util.SDK_INT >= 19 && !isInEditMode() ? getUserCaptionFontScaleV19() : 1f;
|
||||
setFractionalTextSize(DEFAULT_TEXT_SIZE_FRACTION * fontScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text size to be a fraction of the view's remaining height after its top and bottom
|
||||
* padding have been subtracted.
|
||||
* <p>
|
||||
* Equivalent to {@code #setFractionalTextSize(fractionOfHeight, false)}.
|
||||
*
|
||||
* @param fractionOfHeight A fraction between 0 and 1.
|
||||
*/
|
||||
public void setFractionalTextSize(float fractionOfHeight) {
|
||||
setFractionalTextSize(fractionOfHeight, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text size to be a fraction of the height of this view.
|
||||
*
|
||||
* @param fractionOfHeight A fraction between 0 and 1.
|
||||
* @param ignorePadding Set to true if {@code fractionOfHeight} should be interpreted as a
|
||||
* fraction of this view's height ignoring any top and bottom padding. Set to false if
|
||||
* {@code fractionOfHeight} should be interpreted as a fraction of this view's remaining
|
||||
* height after the top and bottom padding has been subtracted.
|
||||
*/
|
||||
public void setFractionalTextSize(float fractionOfHeight, boolean ignorePadding) {
|
||||
setTextSize(ignorePadding ? FRACTIONAL_IGNORE_PADDING : FRACTIONAL, fractionOfHeight);
|
||||
}
|
||||
|
||||
private void setTextSize(int textSizeType, float textSize) {
|
||||
if (this.textSizeType == textSizeType && this.textSize == textSize) {
|
||||
return;
|
||||
}
|
||||
this.textSizeType = textSizeType;
|
||||
this.textSize = textSize;
|
||||
// Invalidate to trigger drawing.
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether styling embedded within the cues should be applied. Enabled by default.
|
||||
*
|
||||
* @param applyEmbeddedStyles Whether styling embedded within the cues should be applied.
|
||||
*/
|
||||
public void setApplyEmbeddedStyles(boolean applyEmbeddedStyles) {
|
||||
if (this.applyEmbeddedStyles == applyEmbeddedStyles) {
|
||||
return;
|
||||
}
|
||||
this.applyEmbeddedStyles = applyEmbeddedStyles;
|
||||
// Invalidate to trigger drawing.
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the caption style to be equivalent to the one returned by
|
||||
* {@link CaptioningManager#getUserStyle()}, or to a default style before API level 19.
|
||||
*/
|
||||
public void setUserDefaultStyle() {
|
||||
setStyle(Util.SDK_INT >= 19 && !isInEditMode()
|
||||
? getUserCaptionStyleV19() : CaptionStyleCompat.DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the caption style.
|
||||
*
|
||||
* @param style A style for the view.
|
||||
*/
|
||||
public void setStyle(CaptionStyleCompat style) {
|
||||
if (this.style == style) {
|
||||
return;
|
||||
}
|
||||
this.style = style;
|
||||
// Invalidate to trigger drawing.
|
||||
invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bottom padding fraction to apply when {@link Cue#line} is {@link Cue#DIMEN_UNSET},
|
||||
* as a fraction of the view's remaining height after its top and bottom padding have been
|
||||
* subtracted.
|
||||
* <p>
|
||||
* Note that this padding is applied in addition to any standard view padding.
|
||||
*
|
||||
* @param bottomPaddingFraction The bottom padding fraction.
|
||||
*/
|
||||
public void setBottomPaddingFraction(float bottomPaddingFraction) {
|
||||
if (this.bottomPaddingFraction == bottomPaddingFraction) {
|
||||
return;
|
||||
}
|
||||
this.bottomPaddingFraction = bottomPaddingFraction;
|
||||
// Invalidate to trigger drawing.
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchDraw(Canvas canvas) {
|
||||
int cueCount = (cues == null) ? 0 : cues.size();
|
||||
int rawTop = getTop();
|
||||
int rawBottom = getBottom();
|
||||
|
||||
// Calculate the bounds after padding is taken into account.
|
||||
int left = getLeft() + getPaddingLeft();
|
||||
int top = rawTop + getPaddingTop();
|
||||
int right = getRight() + getPaddingRight();
|
||||
int bottom = rawBottom - getPaddingBottom();
|
||||
if (bottom <= top || right <= left) {
|
||||
// No space to draw subtitles.
|
||||
return;
|
||||
}
|
||||
|
||||
float textSizePx = textSizeType == ABSOLUTE ? textSize
|
||||
: textSize * (textSizeType == FRACTIONAL ? (bottom - top) : (rawBottom - rawTop));
|
||||
if (textSizePx <= 0) {
|
||||
// Text has no height.
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < cueCount; i++) {
|
||||
painters.get(i).draw(cues.get(i), applyEmbeddedStyles, style, textSizePx,
|
||||
bottomPaddingFraction, canvas, left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
private float getUserCaptionFontScaleV19() {
|
||||
CaptioningManager captioningManager =
|
||||
(CaptioningManager) getContext().getSystemService(Context.CAPTIONING_SERVICE);
|
||||
return captioningManager.getFontScale();
|
||||
}
|
||||
|
||||
@TargetApi(19)
|
||||
private CaptionStyleCompat getUserCaptionStyleV19() {
|
||||
CaptioningManager captioningManager =
|
||||
(CaptioningManager) getContext().getSystemService(Context.CAPTIONING_SERVICE);
|
||||
return CaptionStyleCompat.createFromCaptionStyle(captioningManager.getUserStyle());
|
||||
}
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M4,18l8.5,-6L4,6v12zM13,6v12l8.5,-6L13,6z"/>
|
||||
|
||||
</vector>
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"/>
|
||||
|
||||
</vector>
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
|
||||
|
||||
</vector>
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M8,5v14l11,-7z"/>
|
||||
|
||||
</vector>
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z"/>
|
||||
|
||||
</vector>
|
@ -1,25 +0,0 @@
|
||||
<!-- Copyright (C) 2017 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="32dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M11,18L11,6l-8.5,6 8.5,6zM11.5,12l8.5,6L20,6l-8.5,6z"/>
|
||||
|
||||
</vector>
|
Before Width: | Height: | Size: 354 B |
Before Width: | Height: | Size: 323 B |
Before Width: | Height: | Size: 108 B |
Before Width: | Height: | Size: 286 B |
Before Width: | Height: | Size: 292 B |
Before Width: | Height: | Size: 347 B |
Before Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 91 B |
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 187 B |
Before Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 276 B |
Before Width: | Height: | Size: 153 B |
Before Width: | Height: | Size: 228 B |
Before Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 273 B |
Before Width: | Height: | Size: 392 B |
Before Width: | Height: | Size: 334 B |
Before Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 339 B |
Before Width: | Height: | Size: 400 B |
Before Width: | Height: | Size: 584 B |
Before Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 113 B |
Before Width: | Height: | Size: 384 B |
Before Width: | Height: | Size: 464 B |
Before Width: | Height: | Size: 571 B |
@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:layoutDirection="ltr"
|
||||
android:background="#CC000000"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:paddingTop="4dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageButton android:id="@id/exo_prev"
|
||||
style="@style/ExoMediaButton.Previous"/>
|
||||
|
||||
<ImageButton android:id="@id/exo_rew"
|
||||
style="@style/ExoMediaButton.Rewind"/>
|
||||
|
||||
<ImageButton android:id="@id/exo_play"
|
||||
style="@style/ExoMediaButton.Play"/>
|
||||
|
||||
<ImageButton android:id="@id/exo_pause"
|
||||
style="@style/ExoMediaButton.Pause"/>
|
||||
|
||||
<ImageButton android:id="@id/exo_ffwd"
|
||||
style="@style/ExoMediaButton.FastForward"/>
|
||||
|
||||
<ImageButton android:id="@id/exo_next"
|
||||
style="@style/ExoMediaButton.Next"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView android:id="@id/exo_position"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#FFBEBEBE"/>
|
||||
|
||||
<SeekBar android:id="@id/exo_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="32dp"
|
||||
android:focusable="false"
|
||||
style="?android:attr/progressBarStyleHorizontal"/>
|
||||
|
||||
<TextView android:id="@id/exo_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:paddingLeft="4dp"
|
||||
android:paddingRight="4dp"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#FFBEBEBE"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<com.google.android.exoplayer2.ui.AspectRatioFrameLayout android:id="@id/exo_content_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<!-- Video surface will be inserted as the first child of the content frame. -->
|
||||
|
||||
<View android:id="@id/exo_shutter"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black"/>
|
||||
|
||||
<ImageView android:id="@id/exo_artwork"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitXY"/>
|
||||
|
||||
<com.google.android.exoplayer2.ui.SubtitleView android:id="@id/exo_subtitles"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</com.google.android.exoplayer2.ui.AspectRatioFrameLayout>
|
||||
|
||||
<View android:id="@id/exo_controller_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<FrameLayout android:id="@id/exo_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</merge>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Vorige snit"</string>
|
||||
<string name="exo_controls_next_description">"Volgende snit"</string>
|
||||
<string name="exo_controls_pause_description">"Wag"</string>
|
||||
<string name="exo_controls_play_description">"Speel"</string>
|
||||
<string name="exo_controls_stop_description">"Stop"</string>
|
||||
<string name="exo_controls_rewind_description">"Spoel terug"</string>
|
||||
<string name="exo_controls_fastforward_description">"Vinnig vorentoe"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"ቀዳሚ ትራክ"</string>
|
||||
<string name="exo_controls_next_description">"ቀጣይ ትራክ"</string>
|
||||
<string name="exo_controls_pause_description">"ለአፍታ አቁም"</string>
|
||||
<string name="exo_controls_play_description">"አጫውት"</string>
|
||||
<string name="exo_controls_stop_description">"አቁም"</string>
|
||||
<string name="exo_controls_rewind_description">"ወደኋላ አጠንጥን"</string>
|
||||
<string name="exo_controls_fastforward_description">"በፍጥነት አሳልፍ"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"المقطع الصوتي السابق"</string>
|
||||
<string name="exo_controls_next_description">"المقطع الصوتي التالي"</string>
|
||||
<string name="exo_controls_pause_description">"إيقاف مؤقت"</string>
|
||||
<string name="exo_controls_play_description">"تشغيل"</string>
|
||||
<string name="exo_controls_stop_description">"إيقاف"</string>
|
||||
<string name="exo_controls_rewind_description">"إرجاع"</string>
|
||||
<string name="exo_controls_fastforward_description">"تقديم سريع"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Öncəki trek"</string>
|
||||
<string name="exo_controls_next_description">"Növbəti trek"</string>
|
||||
<string name="exo_controls_pause_description">"Pauza"</string>
|
||||
<string name="exo_controls_play_description">"Oyun"</string>
|
||||
<string name="exo_controls_stop_description">"Dayandır"</string>
|
||||
<string name="exo_controls_rewind_description">"Geri sarıma"</string>
|
||||
<string name="exo_controls_fastforward_description">"Sürətlə irəli"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Prethodna pesma"</string>
|
||||
<string name="exo_controls_next_description">"Sledeća pesma"</string>
|
||||
<string name="exo_controls_pause_description">"Pauza"</string>
|
||||
<string name="exo_controls_play_description">"Pusti"</string>
|
||||
<string name="exo_controls_stop_description">"Zaustavi"</string>
|
||||
<string name="exo_controls_rewind_description">"Premotaj unazad"</string>
|
||||
<string name="exo_controls_fastforward_description">"Premotaj unapred"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Папярэдні трэк"</string>
|
||||
<string name="exo_controls_next_description">"Наступны трэк"</string>
|
||||
<string name="exo_controls_pause_description">"Прыпыніць"</string>
|
||||
<string name="exo_controls_play_description">"Прайграць"</string>
|
||||
<string name="exo_controls_stop_description">"Спыніць"</string>
|
||||
<string name="exo_controls_rewind_description">"Перамотка назад"</string>
|
||||
<string name="exo_controls_fastforward_description">"Перамотка ўперад"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Предишен запис"</string>
|
||||
<string name="exo_controls_next_description">"Следващ запис"</string>
|
||||
<string name="exo_controls_pause_description">"Пауза"</string>
|
||||
<string name="exo_controls_play_description">"Пускане"</string>
|
||||
<string name="exo_controls_stop_description">"Спиране"</string>
|
||||
<string name="exo_controls_rewind_description">"Превъртане назад"</string>
|
||||
<string name="exo_controls_fastforward_description">"Превъртане напред"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"পূর্ববর্তী ট্র্যাক"</string>
|
||||
<string name="exo_controls_next_description">"পরবর্তী ট্র্যাক"</string>
|
||||
<string name="exo_controls_pause_description">"বিরাম দিন"</string>
|
||||
<string name="exo_controls_play_description">"প্লে করুন"</string>
|
||||
<string name="exo_controls_stop_description">"থামান"</string>
|
||||
<string name="exo_controls_rewind_description">"গুটিয়ে নিন"</string>
|
||||
<string name="exo_controls_fastforward_description">"দ্রুত সামনে এগোন"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Prethodna numera"</string>
|
||||
<string name="exo_controls_next_description">"Sljedeća numera"</string>
|
||||
<string name="exo_controls_pause_description">"Pauziraj"</string>
|
||||
<string name="exo_controls_play_description">"Reproduciraj"</string>
|
||||
<string name="exo_controls_stop_description">"Zaustavi"</string>
|
||||
<string name="exo_controls_rewind_description">"Premotaj"</string>
|
||||
<string name="exo_controls_fastforward_description">"Ubrzaj"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Ruta anterior"</string>
|
||||
<string name="exo_controls_next_description">"Ruta següent"</string>
|
||||
<string name="exo_controls_pause_description">"Posa en pausa"</string>
|
||||
<string name="exo_controls_play_description">"Reprodueix"</string>
|
||||
<string name="exo_controls_stop_description">"Atura"</string>
|
||||
<string name="exo_controls_rewind_description">"Rebobina"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avança ràpidament"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Předchozí skladba"</string>
|
||||
<string name="exo_controls_next_description">"Další skladba"</string>
|
||||
<string name="exo_controls_pause_description">"Pozastavit"</string>
|
||||
<string name="exo_controls_play_description">"Přehrát"</string>
|
||||
<string name="exo_controls_stop_description">"Zastavit"</string>
|
||||
<string name="exo_controls_rewind_description">"Přetočit zpět"</string>
|
||||
<string name="exo_controls_fastforward_description">"Přetočit vpřed"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Forrige nummer"</string>
|
||||
<string name="exo_controls_next_description">"Næste nummer"</string>
|
||||
<string name="exo_controls_pause_description">"Pause"</string>
|
||||
<string name="exo_controls_play_description">"Afspil"</string>
|
||||
<string name="exo_controls_stop_description">"Stop"</string>
|
||||
<string name="exo_controls_rewind_description">"Spol tilbage"</string>
|
||||
<string name="exo_controls_fastforward_description">"Spol frem"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Vorheriger Titel"</string>
|
||||
<string name="exo_controls_next_description">"Nächster Titel"</string>
|
||||
<string name="exo_controls_pause_description">"Pausieren"</string>
|
||||
<string name="exo_controls_play_description">"Wiedergabe"</string>
|
||||
<string name="exo_controls_stop_description">"Beenden"</string>
|
||||
<string name="exo_controls_rewind_description">"Zurückspulen"</string>
|
||||
<string name="exo_controls_fastforward_description">"Vorspulen"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Προηγούμενο κομμάτι"</string>
|
||||
<string name="exo_controls_next_description">"Επόμενο κομμάτι"</string>
|
||||
<string name="exo_controls_pause_description">"Παύση"</string>
|
||||
<string name="exo_controls_play_description">"Αναπαραγωγή"</string>
|
||||
<string name="exo_controls_stop_description">"Διακοπή"</string>
|
||||
<string name="exo_controls_rewind_description">"Επαναφορά"</string>
|
||||
<string name="exo_controls_fastforward_description">"Γρήγορη προώθηση"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Previous track"</string>
|
||||
<string name="exo_controls_next_description">"Next track"</string>
|
||||
<string name="exo_controls_pause_description">"Pause"</string>
|
||||
<string name="exo_controls_play_description">"Play"</string>
|
||||
<string name="exo_controls_stop_description">"Stop"</string>
|
||||
<string name="exo_controls_rewind_description">"Rewind"</string>
|
||||
<string name="exo_controls_fastforward_description">"Fast-forward"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Previous track"</string>
|
||||
<string name="exo_controls_next_description">"Next track"</string>
|
||||
<string name="exo_controls_pause_description">"Pause"</string>
|
||||
<string name="exo_controls_play_description">"Play"</string>
|
||||
<string name="exo_controls_stop_description">"Stop"</string>
|
||||
<string name="exo_controls_rewind_description">"Rewind"</string>
|
||||
<string name="exo_controls_fastforward_description">"Fast-forward"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Previous track"</string>
|
||||
<string name="exo_controls_next_description">"Next track"</string>
|
||||
<string name="exo_controls_pause_description">"Pause"</string>
|
||||
<string name="exo_controls_play_description">"Play"</string>
|
||||
<string name="exo_controls_stop_description">"Stop"</string>
|
||||
<string name="exo_controls_rewind_description">"Rewind"</string>
|
||||
<string name="exo_controls_fastforward_description">"Fast-forward"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Pista anterior"</string>
|
||||
<string name="exo_controls_next_description">"Siguiente pista"</string>
|
||||
<string name="exo_controls_pause_description">"Pausar"</string>
|
||||
<string name="exo_controls_play_description">"Reproducir"</string>
|
||||
<string name="exo_controls_stop_description">"Detener"</string>
|
||||
<string name="exo_controls_rewind_description">"Retroceder"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avanzar"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Canción anterior"</string>
|
||||
<string name="exo_controls_next_description">"Siguiente canción"</string>
|
||||
<string name="exo_controls_pause_description">"Pausar"</string>
|
||||
<string name="exo_controls_play_description">"Reproducir"</string>
|
||||
<string name="exo_controls_stop_description">"Detener"</string>
|
||||
<string name="exo_controls_rewind_description">"Rebobinar"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avance rápido"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Eelmine lugu"</string>
|
||||
<string name="exo_controls_next_description">"Järgmine lugu"</string>
|
||||
<string name="exo_controls_pause_description">"Peata"</string>
|
||||
<string name="exo_controls_play_description">"Esita"</string>
|
||||
<string name="exo_controls_stop_description">"Peata"</string>
|
||||
<string name="exo_controls_rewind_description">"Keri tagasi"</string>
|
||||
<string name="exo_controls_fastforward_description">"Keri edasi"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Aurreko pista"</string>
|
||||
<string name="exo_controls_next_description">"Hurrengo pista"</string>
|
||||
<string name="exo_controls_pause_description">"Pausatu"</string>
|
||||
<string name="exo_controls_play_description">"Erreproduzitu"</string>
|
||||
<string name="exo_controls_stop_description">"Gelditu"</string>
|
||||
<string name="exo_controls_rewind_description">"Atzeratu"</string>
|
||||
<string name="exo_controls_fastforward_description">"Aurreratu"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"آهنگ قبلی"</string>
|
||||
<string name="exo_controls_next_description">"آهنگ بعدی"</string>
|
||||
<string name="exo_controls_pause_description">"مکث"</string>
|
||||
<string name="exo_controls_play_description">"پخش"</string>
|
||||
<string name="exo_controls_stop_description">"توقف"</string>
|
||||
<string name="exo_controls_rewind_description">"عقب بردن"</string>
|
||||
<string name="exo_controls_fastforward_description">"جلو بردن سریع"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Edellinen raita"</string>
|
||||
<string name="exo_controls_next_description">"Seuraava raita"</string>
|
||||
<string name="exo_controls_pause_description">"Tauko"</string>
|
||||
<string name="exo_controls_play_description">"Toista"</string>
|
||||
<string name="exo_controls_stop_description">"Seis"</string>
|
||||
<string name="exo_controls_rewind_description">"Kelaa taakse"</string>
|
||||
<string name="exo_controls_fastforward_description">"Kelaa eteen"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Chanson précédente"</string>
|
||||
<string name="exo_controls_next_description">"Chanson suivante"</string>
|
||||
<string name="exo_controls_pause_description">"Pause"</string>
|
||||
<string name="exo_controls_play_description">"Lecture"</string>
|
||||
<string name="exo_controls_stop_description">"Arrêter"</string>
|
||||
<string name="exo_controls_rewind_description">"Reculer"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avance rapide"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Piste précédente"</string>
|
||||
<string name="exo_controls_next_description">"Piste suivante"</string>
|
||||
<string name="exo_controls_pause_description">"Interrompre"</string>
|
||||
<string name="exo_controls_play_description">"Lire"</string>
|
||||
<string name="exo_controls_stop_description">"Arrêter"</string>
|
||||
<string name="exo_controls_rewind_description">"Retour arrière"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avance rapide"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Pista anterior"</string>
|
||||
<string name="exo_controls_next_description">"Seguinte pista"</string>
|
||||
<string name="exo_controls_pause_description">"Pausar"</string>
|
||||
<string name="exo_controls_play_description">"Reproducir"</string>
|
||||
<string name="exo_controls_stop_description">"Deter"</string>
|
||||
<string name="exo_controls_rewind_description">"Rebobinar"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avance rápido"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"પહેલાનો ટ્રૅક"</string>
|
||||
<string name="exo_controls_next_description">"આગલો ટ્રૅક"</string>
|
||||
<string name="exo_controls_pause_description">"થોભો"</string>
|
||||
<string name="exo_controls_play_description">"ચલાવો"</string>
|
||||
<string name="exo_controls_stop_description">"રોકો"</string>
|
||||
<string name="exo_controls_rewind_description">"રીવાઇન્ડ કરો"</string>
|
||||
<string name="exo_controls_fastforward_description">"ઝડપી ફોરવર્ડ કરો"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"पिछला ट्रैक"</string>
|
||||
<string name="exo_controls_next_description">"अगला ट्रैक"</string>
|
||||
<string name="exo_controls_pause_description">"रोकें"</string>
|
||||
<string name="exo_controls_play_description">"चलाएं"</string>
|
||||
<string name="exo_controls_stop_description">"बंद करें"</string>
|
||||
<string name="exo_controls_rewind_description">"रिवाइंड करें"</string>
|
||||
<string name="exo_controls_fastforward_description">"फ़ास्ट फ़ॉरवर्ड"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Prethodna pjesma"</string>
|
||||
<string name="exo_controls_next_description">"Sljedeća pjesma"</string>
|
||||
<string name="exo_controls_pause_description">"Pauziraj"</string>
|
||||
<string name="exo_controls_play_description">"Reproduciraj"</string>
|
||||
<string name="exo_controls_stop_description">"Zaustavi"</string>
|
||||
<string name="exo_controls_rewind_description">"Unatrag"</string>
|
||||
<string name="exo_controls_fastforward_description">"Brzo unaprijed"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Előző szám"</string>
|
||||
<string name="exo_controls_next_description">"Következő szám"</string>
|
||||
<string name="exo_controls_pause_description">"Szünet"</string>
|
||||
<string name="exo_controls_play_description">"Lejátszás"</string>
|
||||
<string name="exo_controls_stop_description">"Leállítás"</string>
|
||||
<string name="exo_controls_rewind_description">"Visszatekerés"</string>
|
||||
<string name="exo_controls_fastforward_description">"Előretekerés"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Նախորդը"</string>
|
||||
<string name="exo_controls_next_description">"Հաջորդը"</string>
|
||||
<string name="exo_controls_pause_description">"Դադարեցնել"</string>
|
||||
<string name="exo_controls_play_description">"Նվագարկել"</string>
|
||||
<string name="exo_controls_stop_description">"Դադարեցնել"</string>
|
||||
<string name="exo_controls_rewind_description">"Հետ փաթաթել"</string>
|
||||
<string name="exo_controls_fastforward_description">"Արագ առաջ անցնել"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Lagu sebelumnya"</string>
|
||||
<string name="exo_controls_next_description">"Lagu berikutnya"</string>
|
||||
<string name="exo_controls_pause_description">"Jeda"</string>
|
||||
<string name="exo_controls_play_description">"Putar"</string>
|
||||
<string name="exo_controls_stop_description">"Berhenti"</string>
|
||||
<string name="exo_controls_rewind_description">"Putar Ulang"</string>
|
||||
<string name="exo_controls_fastforward_description">"Maju cepat"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Fyrra lag"</string>
|
||||
<string name="exo_controls_next_description">"Næsta lag"</string>
|
||||
<string name="exo_controls_pause_description">"Hlé"</string>
|
||||
<string name="exo_controls_play_description">"Spila"</string>
|
||||
<string name="exo_controls_stop_description">"Stöðva"</string>
|
||||
<string name="exo_controls_rewind_description">"Spóla til baka"</string>
|
||||
<string name="exo_controls_fastforward_description">"Spóla áfram"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Traccia precedente"</string>
|
||||
<string name="exo_controls_next_description">"Traccia successiva"</string>
|
||||
<string name="exo_controls_pause_description">"Metti in pausa"</string>
|
||||
<string name="exo_controls_play_description">"Riproduci"</string>
|
||||
<string name="exo_controls_stop_description">"Interrompi"</string>
|
||||
<string name="exo_controls_rewind_description">"Riavvolgi"</string>
|
||||
<string name="exo_controls_fastforward_description">"Avanti veloce"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"הרצועה הקודמת"</string>
|
||||
<string name="exo_controls_next_description">"הרצועה הבאה"</string>
|
||||
<string name="exo_controls_pause_description">"השהה"</string>
|
||||
<string name="exo_controls_play_description">"הפעל"</string>
|
||||
<string name="exo_controls_stop_description">"הפסק"</string>
|
||||
<string name="exo_controls_rewind_description">"הרץ אחורה"</string>
|
||||
<string name="exo_controls_fastforward_description">"הרץ קדימה"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"前のトラック"</string>
|
||||
<string name="exo_controls_next_description">"次のトラック"</string>
|
||||
<string name="exo_controls_pause_description">"一時停止"</string>
|
||||
<string name="exo_controls_play_description">"再生"</string>
|
||||
<string name="exo_controls_stop_description">"停止"</string>
|
||||
<string name="exo_controls_rewind_description">"巻き戻し"</string>
|
||||
<string name="exo_controls_fastforward_description">"早送り"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"წინა ჩანაწერი"</string>
|
||||
<string name="exo_controls_next_description">"შემდეგი ჩანაწერი"</string>
|
||||
<string name="exo_controls_pause_description">"პაუზა"</string>
|
||||
<string name="exo_controls_play_description">"დაკვრა"</string>
|
||||
<string name="exo_controls_stop_description">"შეწყვეტა"</string>
|
||||
<string name="exo_controls_rewind_description">"უკან გადახვევა"</string>
|
||||
<string name="exo_controls_fastforward_description">"წინ გადახვევა"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Алдыңғы трек"</string>
|
||||
<string name="exo_controls_next_description">"Келесі трек"</string>
|
||||
<string name="exo_controls_pause_description">"Кідірту"</string>
|
||||
<string name="exo_controls_play_description">"Ойнату"</string>
|
||||
<string name="exo_controls_stop_description">"Тоқтату"</string>
|
||||
<string name="exo_controls_rewind_description">"Кері айналдыру"</string>
|
||||
<string name="exo_controls_fastforward_description">"Жылдам алға айналдыру"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"បទមុន"</string>
|
||||
<string name="exo_controls_next_description">"បទបន្ទាប់"</string>
|
||||
<string name="exo_controls_pause_description">"ផ្អាក"</string>
|
||||
<string name="exo_controls_play_description">"ចាក់"</string>
|
||||
<string name="exo_controls_stop_description">"បញ្ឈប់"</string>
|
||||
<string name="exo_controls_rewind_description">"ខាថយក្រោយ"</string>
|
||||
<string name="exo_controls_fastforward_description">"ទៅមុខរហ័ស"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"ಹಿಂದಿನ ಟ್ರ್ಯಾಕ್"</string>
|
||||
<string name="exo_controls_next_description">"ಮುಂದಿನ ಟ್ರ್ಯಾಕ್"</string>
|
||||
<string name="exo_controls_pause_description">"ವಿರಾಮಗೊಳಿಸು"</string>
|
||||
<string name="exo_controls_play_description">"ಪ್ಲೇ ಮಾಡು"</string>
|
||||
<string name="exo_controls_stop_description">"ನಿಲ್ಲಿಸು"</string>
|
||||
<string name="exo_controls_rewind_description">"ರಿವೈಂಡ್ ಮಾಡು"</string>
|
||||
<string name="exo_controls_fastforward_description">"ವೇಗವಾಗಿ ಮುಂದಕ್ಕೆ"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"이전 트랙"</string>
|
||||
<string name="exo_controls_next_description">"다음 트랙"</string>
|
||||
<string name="exo_controls_pause_description">"일시중지"</string>
|
||||
<string name="exo_controls_play_description">"재생"</string>
|
||||
<string name="exo_controls_stop_description">"중지"</string>
|
||||
<string name="exo_controls_rewind_description">"되감기"</string>
|
||||
<string name="exo_controls_fastforward_description">"빨리 감기"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Мурунку трек"</string>
|
||||
<string name="exo_controls_next_description">"Кийинки трек"</string>
|
||||
<string name="exo_controls_pause_description">"Тындыруу"</string>
|
||||
<string name="exo_controls_play_description">"Ойнотуу"</string>
|
||||
<string name="exo_controls_stop_description">"Токтотуу"</string>
|
||||
<string name="exo_controls_rewind_description">"Артка түрүү"</string>
|
||||
<string name="exo_controls_fastforward_description">"Алдыга түрүү"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"ເພງກ່ອນໜ້າ"</string>
|
||||
<string name="exo_controls_next_description">"ເພງຕໍ່ໄປ"</string>
|
||||
<string name="exo_controls_pause_description">"ຢຸດຊົ່ວຄາວ"</string>
|
||||
<string name="exo_controls_play_description">"ຫຼິ້ນ"</string>
|
||||
<string name="exo_controls_stop_description">"ຢຸດ"</string>
|
||||
<string name="exo_controls_rewind_description">"ຣີວາຍກັບ"</string>
|
||||
<string name="exo_controls_fastforward_description">"ເລື່ອນໄປໜ້າ"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Ankstesnis takelis"</string>
|
||||
<string name="exo_controls_next_description">"Kitas takelis"</string>
|
||||
<string name="exo_controls_pause_description">"Pristabdyti"</string>
|
||||
<string name="exo_controls_play_description">"Leisti"</string>
|
||||
<string name="exo_controls_stop_description">"Stabdyti"</string>
|
||||
<string name="exo_controls_rewind_description">"Sukti atgal"</string>
|
||||
<string name="exo_controls_fastforward_description">"Sukti pirmyn"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Iepriekšējais ieraksts"</string>
|
||||
<string name="exo_controls_next_description">"Nākamais ieraksts"</string>
|
||||
<string name="exo_controls_pause_description">"Pārtraukt"</string>
|
||||
<string name="exo_controls_play_description">"Atskaņot"</string>
|
||||
<string name="exo_controls_stop_description">"Apturēt"</string>
|
||||
<string name="exo_controls_rewind_description">"Attīt atpakaļ"</string>
|
||||
<string name="exo_controls_fastforward_description">"Ātri patīt"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Претходна песна"</string>
|
||||
<string name="exo_controls_next_description">"Следна песна"</string>
|
||||
<string name="exo_controls_pause_description">"Пауза"</string>
|
||||
<string name="exo_controls_play_description">"Пушти"</string>
|
||||
<string name="exo_controls_stop_description">"Запри"</string>
|
||||
<string name="exo_controls_rewind_description">"Премотај назад"</string>
|
||||
<string name="exo_controls_fastforward_description">"Брзо премотај напред"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"മുമ്പത്തെ ട്രാക്ക്"</string>
|
||||
<string name="exo_controls_next_description">"അടുത്ത ട്രാക്ക്"</string>
|
||||
<string name="exo_controls_pause_description">"താൽക്കാലികമായി നിർത്തുക"</string>
|
||||
<string name="exo_controls_play_description">"പ്ലേ ചെയ്യുക"</string>
|
||||
<string name="exo_controls_stop_description">"നിര്ത്തുക"</string>
|
||||
<string name="exo_controls_rewind_description">"റിവൈൻഡുചെയ്യുക"</string>
|
||||
<string name="exo_controls_fastforward_description">"വേഗത്തിലുള്ള കൈമാറൽ"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Өмнөх трек"</string>
|
||||
<string name="exo_controls_next_description">"Дараагийн трек"</string>
|
||||
<string name="exo_controls_pause_description">"Түр зогсоох"</string>
|
||||
<string name="exo_controls_play_description">"Тоглуулах"</string>
|
||||
<string name="exo_controls_stop_description">"Зогсоох"</string>
|
||||
<string name="exo_controls_rewind_description">"Буцааж хураах"</string>
|
||||
<string name="exo_controls_fastforward_description">"Хурдан урагшлуулах"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"मागील ट्रॅक"</string>
|
||||
<string name="exo_controls_next_description">"पुढील ट्रॅक"</string>
|
||||
<string name="exo_controls_pause_description">"विराम द्या"</string>
|
||||
<string name="exo_controls_play_description">"प्ले करा"</string>
|
||||
<string name="exo_controls_stop_description">"थांबा"</string>
|
||||
<string name="exo_controls_rewind_description">"रिवाईँड करा"</string>
|
||||
<string name="exo_controls_fastforward_description">"फास्ट फॉरवर्ड करा"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Lagu sebelumnya"</string>
|
||||
<string name="exo_controls_next_description">"Lagu seterusnya"</string>
|
||||
<string name="exo_controls_pause_description">"Jeda"</string>
|
||||
<string name="exo_controls_play_description">"Main"</string>
|
||||
<string name="exo_controls_stop_description">"Berhenti"</string>
|
||||
<string name="exo_controls_rewind_description">"Gulung semula"</string>
|
||||
<string name="exo_controls_fastforward_description">"Mara laju"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"ယခင် တစ်ပုဒ်"</string>
|
||||
<string name="exo_controls_next_description">"နောက် တစ်ပုဒ်"</string>
|
||||
<string name="exo_controls_pause_description">"ခဏရပ်ရန်"</string>
|
||||
<string name="exo_controls_play_description">"ဖွင့်ရန်"</string>
|
||||
<string name="exo_controls_stop_description">"ရပ်ရန်"</string>
|
||||
<string name="exo_controls_rewind_description">"ပြန်ရစ်ရန်"</string>
|
||||
<string name="exo_controls_fastforward_description">"ရှေ့သို့ သွားရန်"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Forrige spor"</string>
|
||||
<string name="exo_controls_next_description">"Neste spor"</string>
|
||||
<string name="exo_controls_pause_description">"Sett på pause"</string>
|
||||
<string name="exo_controls_play_description">"Spill av"</string>
|
||||
<string name="exo_controls_stop_description">"Stopp"</string>
|
||||
<string name="exo_controls_rewind_description">"Tilbakespoling"</string>
|
||||
<string name="exo_controls_fastforward_description">"Fremoverspoling"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"अघिल्लो ट्रयाक"</string>
|
||||
<string name="exo_controls_next_description">"अर्को ट्रयाक"</string>
|
||||
<string name="exo_controls_pause_description">"रोक्नुहोस्"</string>
|
||||
<string name="exo_controls_play_description">"चलाउनुहोस्"</string>
|
||||
<string name="exo_controls_stop_description">"रोक्नुहोस्"</string>
|
||||
<string name="exo_controls_rewind_description">"दोहोर्याउनुहोस्"</string>
|
||||
<string name="exo_controls_fastforward_description">"फास्ट फर्वार्ड"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"Vorig nummer"</string>
|
||||
<string name="exo_controls_next_description">"Volgend nummer"</string>
|
||||
<string name="exo_controls_pause_description">"Onderbreken"</string>
|
||||
<string name="exo_controls_play_description">"Afspelen"</string>
|
||||
<string name="exo_controls_stop_description">"Stoppen"</string>
|
||||
<string name="exo_controls_rewind_description">"Terugspoelen"</string>
|
||||
<string name="exo_controls_fastforward_description">"Vooruitspoelen"</string>
|
||||
</resources>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="exo_controls_previous_description">"ਪਿਛਲਾ ਟਰੈਕ"</string>
|
||||
<string name="exo_controls_next_description">"ਅਗਲਾ ਟਰੈਕ"</string>
|
||||
<string name="exo_controls_pause_description">"ਰੋਕੋ"</string>
|
||||
<string name="exo_controls_play_description">"ਪਲੇ ਕਰੋ"</string>
|
||||
<string name="exo_controls_stop_description">"ਰੋਕੋ"</string>
|
||||
<string name="exo_controls_rewind_description">"ਰੀਵਾਈਂਡ ਕਰੋ"</string>
|
||||
<string name="exo_controls_fastforward_description">"ਅੱਗੇ ਭੇਜੋ"</string>
|
||||
</resources>
|