- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 ExoPlayer 从 URL 播放一些 mp4。当用户单击主页按钮或任何导致应用程序从用户 View 中删除然后返回到我的应用程序(和视频 Activity )时,我希望视频从它停止的地方继续播放。我尝试通过在 onStop()
中保存视频位置然后重建播放器并在 onStart()
中使用 seekTo()
来实现这一点。我在 onStart()
中检查我当前的 exoplayer 是否为 null,但是此检查从未通过,所以我认为这就是问题所在。现在它是如何编码的我的视频永远不会恢复。如果我通过按下主页按钮离开应用程序 onStop()
被调用,然后当我返回我的应用程序时 onStart()
将被调用,但是视频播放器仍然存在黑色,从不播放视频。如果我删除空检查,每当我从主要 Activity 开始播放视频时,我都会播放两个视频实例,因为它在 onCreate()
和 onStart()
中都被调用.有没有更好的方法来获得我想要的功能?感谢您的帮助!
public class VideoActivity extends AppCompatActivity {
private SimpleExoPlayer exoPlayer;
private SimpleExoPlayerView simpleExoPlayerView;
private long playerPosition;
private String mp4Url;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.player_activity);
// Get the Intent that started this activity and extract the video url
Intent intent = getIntent();
mp4Url = intent.getStringExtra(MainActivity.VIDEO_URL);
// Create an exoplayer instance and start playing video
buildPlayer(mp4Url);
}
private void buildPlayer(String mp4Url) {
// Create a default TrackSelector
Handler mainHandler = new Handler();
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
// Create the player
exoPlayer = ExoPlayerFactory.newSimpleInstance(this, trackSelector); // no LoadControl?
simpleExoPlayerView = new SimpleExoPlayerView(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
// Set media controller
simpleExoPlayerView.setUseController(true);
simpleExoPlayerView.requestFocus();
// Bind player to the view
simpleExoPlayerView.setPlayer(exoPlayer);
// Create Uri from video location
// TODO: should this be in some network class? Should I be appending APIKEY here?
Uri mp4Uri = Uri.parse(mp4Url + "?api_key=" + BuildConfig.GIANTBOMB_API_KEY);
Timber.v("Video url with api key: " + mp4Uri.toString());
// Create another bandwidth meter for bandwidth during playback (not strictly necessary)
DefaultBandwidthMeter playbackBandwidthMeter = new DefaultBandwidthMeter();
// DataSourceFactory to produce DataSource instances through which media data is loaded
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this,
Util.getUserAgent(this, "GiantBombForAndroid"),
playbackBandwidthMeter);
// Produces Extractor instances for parsing the media data
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
ExtractorMediaSource.EventListener eventListener = new ExtractorMediaSource.EventListener() {
@Override
public void onLoadError(IOException error) {
Timber.e("Error loading video from source");
}
};
final MediaSource videoSource = new ExtractorMediaSource(mp4Uri,
dataSourceFactory,
extractorsFactory,
mainHandler,
eventListener);
exoPlayer.prepare(videoSource);
exoPlayer.addListener(new ExoPlayer.EventListener() {
@Override
public void onLoadingChanged(boolean isLoading) {
Timber.v("Listener-onLoadingChanged...");
}
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
Timber.v("Listener-onPlayerStateChanged...");
}
@Override
public void onTimelineChanged(Timeline timeline, Object manifest) {
Timber.v("Listener-onTimelineChanged...");
}
@Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
// TODO: Do I need anything here?
}
@Override
public void onPlayerError(ExoPlaybackException error) {
Timber.v("Listener-onPlayerError...");
exoPlayer.stop();
exoPlayer.prepare(videoSource);
exoPlayer.setPlayWhenReady(true);
}
@Override
public void onPositionDiscontinuity() {
Timber.v("Listener-onPositionDiscontinuity...");
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
// TODO: Do I need anything here?
}
});
exoPlayer.setPlayWhenReady(true);
}
@Override
protected void onStart() {
super.onStart();
Timber.v("onStart()...");
if (exoPlayer == null) {
Timber.v("No exoplayer instance, recreating...");
buildPlayer(mp4Url);
exoPlayer.seekTo(playerPosition);
}
}
@Override
protected void onStop(){
super.onStop();
Timber.v("onStop()...");
//TODO: pull player creation code into it's own method so it can be called here as well
playerPosition = exoPlayer.getCurrentPosition();
exoPlayer.release();
}
@Override
protected void onDestroy() {
super.onDestroy();
Timber.v("onDestroy()...");
exoPlayer.release();
}
}
最佳答案
目前您正在 onStop()
中调用 release,这将清空播放器的所有重要部分,但不会清空 exoPlayer
字段(并销毁任何状态你没有跟踪自己)。
有几种不同的方法。但无论您做什么,您都可能希望自己跟踪某些状态。下面我将它们用作字段,但它们也可以放在 onSavedInstanceState()
中。在 onStop()
中,我们保存了两条信息,然后在 onStart()
中将它们提取出来。 1) 我们的玩家在暂停时所处的最后位置,以及 2) 我们是否应该在恢复时播放。您可以将 seekTo
调用移出 if == null
block ,因为您可能总是希望从中断的地方继续。:
@Override
public void onStart() {
// ...
if (exoPlayer == null) {
// init player
}
// Seek to the last position of the player.
exoPlayer.seekTo(mLastPosition);
// Put the player into the last state we were in.
exoPlayer.setPlayWhenReady(mPlayVideoWhenForegrounded);
// ...
}
@Override
public void onStop() {
// ...
// Store off if we were playing so we know if we should start when we're foregrounded again.
mPlayVideoWhenForegrounded = exoPlayer.getPlayWhenReady();
// Store off the last position our player was in before we paused it.
mLastPosition = exoPlayer.getCurrentPosition();
// Pause the player
exoPlayer.setPlayWhenReady(false);
// ...
}
现在我在您的代码示例中看到的另一个问题是 exoPlayer.release()
不会清空 exoPlayer
字段。因此,您可以在 exoPlayer.release()
之后添加 exoPlayer = null
行,这有望解决您的多个 exoPlayer 问题。您还可以将 release()
调用移动到 onDestroy()
,但前提是您知道自己正在正确地重新实例化所有内容。
关于android - 我如何让 ExoPlayer 在我的 Activity 的 onStart() 方法中恢复视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43959176/
我对 Android 很陌生,如果问题重复,请避免并发送链接。有三个 Activity A、B 和 C。 Activity A 获取一个用户名,我想在 Activity C 中显示该用户名,但我想先运
我正在尝试制作记事本应用程序,因此每次打开新笔记时,布局都会相同。另外, Activity 的数量(新注释)不应定义得尽可能多 最佳答案 如果 Activity 始终相同,您可能应该创建一个适配器,允
我有 3 个 Activity 。 主窗口 5 个按钮 在按钮的主窗口中按下此窗口打开(将其称为父窗口) 在父窗口按钮上按下此窗口打开调用它作为结束子窗口。 现在从子窗口我从父窗口获取值如下:
我遇到了一个 Activity backstack 问题。假设我的后台有 5 个 Activity :比如 Activity A、 Activity B、 Activity C、 Activity D
我正在寻找必须具有以下附加特征的 JMS 提供程序: 采用多代理,所有代理都必须处于事件状态(无单点故障) 仅在两台机器上进行扩展就足以满足我们的需求 能够保证订购(如果 1 个生产者 + 1 个消费
假设,我有一个由 TabHost 组成的选项卡 Activity 。 TabHost 包含 2 个选项卡,每两个选项卡都有一个 Activity 组。每个 Activity 组包含一项 Activit
我正在开发一个应用程序,我需要根据某些操作导航到特定 Activity 。这是一张图片 我的第一个 Activity 是 ReadingActivity。基于某些操作,用户将被带到 NewProjec
我创建了一个与服务器异步通信的应用程序。当应用程序发出服务器请求时,将创建一个带有“正在加载”通知的新对话框( Activity )。主要 Activity 实现了处理服务器响应的方法,我想在主要 A
我想在我的所有应用程序 Activity 中显示相同的选项菜单。我创建了一个实现菜单的通用 Activity ,并且我所有的进一步 Activity 都扩展了它。 问题:当我需要扩展其他特定 Acti
我有四个 Activity ,即 java 文件 - Activity1.java、activity2.java、activity3.java、activity4.java 和 xml 文件 - Ac
我有两个 Activity 。我想将数据从第二个 Activity 发送到上一个 Activity 。第一个 Activity 有自定义 ListView 和 bean 类。当我点击第二个 Activ
根 Activity 是堆栈中当前的第一个 Activity 还是 list 中指定为启动 Activity 的 Activity ? 支持应用程序 P 在启动时启动 Activity A。然后 A
你好 我想知道您在绘制 Activity 图选择“Activity ”时考虑了哪些关键点? 您如何从要建模的问题中选择 Activity ? 谢谢 最佳答案 Activity 图用于对正在开发的系统和
如何从主 Activity 启动 Activity 并在子 Activity 返回主 Activity 中退出操作后返回主 Activity ? 我已将子 Activity 作为启动器 Intent
我的工作流程如下: 登录 Activity -> ActivityB -> ActivityC -> ActivityD 我想将数据从LoginActivity传递到ActivityD,但不直接传递到
我之前曾尝试获得此问题的答案,但找不到可以解决我的问题的答案。我正在制作保存圆盘高尔夫球分数的应用程序。我的 MainActivity 有 4 个按钮。新比赛、恢复比赛、类(class)和球员。 At
我有一个 tts 非 UI 类和 Activity 类。现在在 Activity 类中,我有一个按钮,用户可以从中选择男声或女声,具体取决于我想要将字符串传递给 tts 类的选择,然后一次tts 类根
问题有点复杂,首先, Activity A 和 Activity B 的 list 中都有 android:noHistory = true 。我有一个自定义 serialized 类,假设 MyCl
在我的应用程序中,我有两个 Activity (AuthenticationActivity 和 MainActivity),每个 Activity 都有一个导航图和大量 fragment 。我创建了
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: How can i use compose email activity in tabView? 我想在选项
我是一名优秀的程序员,十分优秀!