Exoplayer即使在PlayerView已暂停的情况下也播放音频

时间:2018-07-10 01:34:30

标签: java android android-studio exoplayer

我正在创建一个Exoplayer视频播放器,该播放器将播放一个mp4文件,其中包含来自网址的视频和音频。视频和音频可以正常播放,但是当视频播放器暂停时,音频仍在播放。我不知道该如何解决。我假设问题是由于我的Android设备而引起的。我将在下面留下我的代码,应用程序信息,Android设备信息以及问题的视频剪辑。如果有人可以使用我的代码并告诉我他们是否遇到相同的问题,将非常感激。请帮助我。

该应用的详细信息:

使用API 21: Android 5.0 (Lollipop)。包含Internet权限。导入implementation 'com.google.android.exoplayer:exoplayer:2.8.1'

设备详细信息:

类型:Android平板电脑。 Android版本:5.1.1

MainActivity.java

import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MergingMediaSource;
import com.google.android.exoplayer2.source.SingleSampleMediaSource;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity
{
    SimpleExoPlayer video_player;
    PlayerView player_screen;
    DefaultTrackSelector track_selector;
    DefaultBandwidthMeter band_width_meter = new DefaultBandwidthMeter();
    MediaSource mediaSource_both;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        player_screen = findViewById (R.id.player_screen);
        player_screen.requestFocus();

        TrackSelection.Factory video_track_selection_factory = new AdaptiveTrackSelection.Factory(band_width_meter);
        track_selector = new DefaultTrackSelector(video_track_selection_factory);
        video_player = ExoPlayerFactory.newSimpleInstance(this, track_selector);

        player_screen.setPlayer(video_player);
        video_player.setPlayWhenReady(true);

        DataSource.Factory data_source_factory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "Application Name"), new DefaultBandwidthMeter());
        Uri url = Uri.parse("http://dash.akamaized.net/akamai/bbb/bbb_1280x720_60fps_6000k.mp4");
        mediaSource_both = new ExtractorMediaSource.Factory(data_source_factory).createMediaSource(url);

        video_player.prepare(mediaSource_both);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/player_screen"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:use_controller="true" />

</android.support.constraint.ConstraintLayout>

问题的视频剪辑(视频已上传到OpenLoad服务器上):

https://openload.co/embed/NrlMUxUP0C4/problem.mp4

1 个答案:

答案 0 :(得分:2)

我制作了一个非常简单的示例应用程序来重现该问题

但仍然看不到播放器或视频的任何问题

代码如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    SimpleExoPlayerView simpleExoPlayerView = findViewById(R.id.player_view);

    SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(this, new DefaultTrackSelector(new DefaultBandwidthMeter.Builder().build()));

    SimpleCache downloadCache = new SimpleCache(new File(getCacheDir(), "exoCache"), new NoOpCacheEvictor());

    String uri = "http://dash.akamaized.net/akamai/bbb/bbb_1280x720_60fps_6000k.mp4";

    DataSource.Factory dataSourceFactory = new CacheDataSourceFactory(downloadCache, new DefaultDataSourceFactory(this, "seyed"));

    MediaSource mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(uri));

    player.addListener(new Player.EventListener() {
        @Override
        public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
            Log.d("exo", "timeLine Changed");
        }

        @Override
        public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

        }

        @Override
        public void onLoadingChanged(boolean isLoading) {
            Log.d("exo", "loding changed= " + isLoading);
        }

        @Override
        public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
            Log.d("exo", "state changed");
        }

        @Override
        public void onRepeatModeChanged(int repeatMode) {

        }

        @Override
        public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

        }

        @Override
        public void onPlayerError(ExoPlaybackException error) {
            Log.e("exo", "exoplayer error", error);
        }

        @Override
        public void onPositionDiscontinuity(int reason) {

        }

        @Override
        public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

        }

        @Override
        public void onSeekProcessed() {
            Log.d("exo", "seek processed");
        }
    });
    player.prepare(mediaSource);

    simpleExoPlayerView.setPlayer(player);

    player.setPlayWhenReady(true);

}

这是布局:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />

</android.support.design.widget.AppBarLayout>

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <com.google.android.exoplayer2.ui.SimpleExoPlayerView
        android:id="@+id/player_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

清单:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".MyDownloadService"
        android:exported="false"/>
</application>

最后是构建gradle文件:

dependencies {
implementation 'com.android.support:appcompat-v7:27.0.2'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:design:27.0.2'
implementation 'com.google.android.exoplayer:exoplayer:2.8.2'
}

更新17/18/2018 实际上,您面临的问题是由于this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);行。

运行活动时,活动以纵向模式启动,并且一切正常(没有this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);),并且创建了一个exoplayer并开始播放。

,但是在活动启动期间更改方向时。 android尝试破坏活动并创建另一个活动,这是您遇到的问题: 第一个活动不会被销毁,因为您忘记了在onDestroy()中重新部署ExoPlayer,并且在创建新活动时,还会创建一个新的exoplayer,并且两者都可以继续播放。当您暂停播放时,实际上是暂停第二个而不是第一个。这种行为称为内存泄漏。

首先请确保您在活动的.release()中呼叫onDestroy()

然后,对于定向,您有几个选择:

1。在清单中指定活动的方向,以便android在创建活动之前将其应用

 <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar"
        android:screenOrientation="sensorLandscape">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

2。防止android杀死配置更改活动:

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar"
        android:configChanges="orientation">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

希望对您有帮助

您还可以在github上检出此样本(有微小的差别):