aman
aman

Reputation: 391

Exoplayer playing audio even when the PlayerView has been paused

I'm creating an Exoplayer video player which plays a mp4 file containing video and audio from a url. The video and audio plays properly but when the video player is paused, the audio is still being played. I don't know how I can fix this. I'm assuming that the problem occurs due to my android device. I'm leaving my code, app's info, android device info below and a video clip of my problem. If someone can use my code and tell me if they are experiencing the same problem, it will be thankful. Please Help Me.

The app's detail:

Using API 21: Android 5.0 (Lollipop). Contains Internet Permission. Importing implementation 'com.google.android.exoplayer:exoplayer:2.8.1'.

Device detail:

Type: Android Tablet. Android Version : 5.1.1

The 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);
    }
}

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

Video Clip of the problem (The video has been uploaded on OpenLoad server):

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

Upvotes: 2

Views: 5449

Answers (1)

seyed Jafari
seyed Jafari

Reputation: 1265

I made a very easy sample app to reproduce the issue

but yet too see any problem neither with the player or video

here is the code:

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

}

here is the layout:

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

manifest:

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

and lastly the build gradle file:

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

Update 17/18/2018 Actually the problem you are facing is because of this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); line.

when you run your activity it starts in portrait mode and everything is fine (without this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);) and one exoplayer is created and starts the playback.

but when you change the orientation during startup of the activity. android trys to destroy the activity and create another one here comes your problem: first activity does not get destroyed because you forget to realease the ExoPlayer in onDestroy() and when the new activity is created a new exoplayer is also created and both of them keep the playback going. when you pause the playback you actually pausing the second one not the first one. this behavior is called memory leak.

first of all make sure you call .release() in onDestroy() of the activity.

and then for orientation you have couple of options:

1.specify the orientation of the activity in the manifest so android apply it before the creation of the activity

 <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.prevent android from killing the activity on config changes:

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

hope it helps you

you can also chek out this sample (with a small and minor difference) on github:

Upvotes: 4

Related Questions