代码之家  ›  专栏  ›  技术社区  ›  aman

即使播放视图已暂停,外部播放器仍在播放音频

  •  1
  • aman  · 技术社区  · 7 年前

    我正在创建一个 Exoplayer 播放 mp4 包含来自URL的视频和音频的文件。视频和音频播放正常,但当视频播放器暂停时,音频仍在播放。我不知道该怎么解决这个问题。我假设问题是由于我的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 回复  |  直到 7 年前
        1
  •  2
  •   seyed Jafari    7 年前

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

    但是也可以看到播放器和视频的任何问题

    代码如下:

    @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>
    

    最后一个构建渐变文件:

    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'
    }
    

    更新日期:2018年17月18日 实际上,你面临的问题是 this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 线。

    当你运行你的活动时,它以纵向模式启动,一切都很好(没有 this.setRequestedOrientation(活动信息、屏幕方向、景观); )创建一个exoplayer并开始播放。

    但当您在活动启动期间更改方向时。Android试图破坏活动并创建另一个活动,这就是您的问题: 第一个活动不会被破坏,因为你忘记了真正放松外显玩家 onDestroy() 当新的活动被创建时,一个新的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 :