• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media.cujcommon.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 
21 import android.net.Uri;
22 import android.os.Bundle;
23 import android.view.WindowManager;
24 
25 import androidx.appcompat.app.AppCompatActivity;
26 import androidx.media3.common.MediaItem;
27 import androidx.media3.common.TrackSelectionParameters;
28 import androidx.media3.common.TrackSelectionParameters.AudioOffloadPreferences;
29 import androidx.media3.exoplayer.ExoPlayer;
30 import androidx.media3.exoplayer.ExoPlayer.AudioOffloadListener;
31 import androidx.media3.ui.PlayerView;
32 
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.List;
36 
37 public class AudioOffloadTestActivity extends AppCompatActivity {
38 
39   protected PlayerView mExoplayerView;
40   protected ExoPlayer mPlayer;
41   protected static List<String> sVideoUrls = new ArrayList<>();
42   protected PlayerListener mPlayerListener;
43   protected boolean mIsSleepingForAudioOffloadEnabled;
44   protected boolean mIsAudioOffloadEnabled;
45 
46   @Override
onCreate(Bundle savedInstanceState)47   protected void onCreate(Bundle savedInstanceState) {
48     super.onCreate(savedInstanceState);
49     setContentView(R.layout.activity_main_audio_offload);
50     getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
51     buildPlayer();
52   }
53 
54   /**
55    * Get audio offload listener
56    */
getAudioOffloadListener()57   private AudioOffloadListener getAudioOffloadListener() {
58     return new AudioOffloadListener() {
59       @Override
60       public void onSleepingForOffloadChanged(boolean isSleepingForOffload) {
61         mIsSleepingForAudioOffloadEnabled = true;
62       }
63 
64       @Override
65       public void onOffloadedPlayback(boolean isOffloadedPlayback) {
66         if (!mIsAudioOffloadEnabled && isOffloadedPlayback) {
67           mIsAudioOffloadEnabled = true;
68         }
69         if (mIsAudioOffloadEnabled && !isOffloadedPlayback) {
70           assertEquals("Audio offload is disabled before the playback is finished. "
71                   + "ClipDuration= " + mPlayer.getDuration() + " currentPosition= "
72                   + mPlayer.getCurrentPosition(), (float) mPlayer.getDuration(),
73               (float) mPlayer.getCurrentPosition(), 5000);
74         }
75       }
76     };
77   }
78 
79   /**
80    * Build the player
81    */
82   protected void buildPlayer() {
83     AudioOffloadListener listener = getAudioOffloadListener();
84     CustomRenderersFactory customRenderersFactory = new CustomRenderersFactory(this, listener);
85     mPlayer = new ExoPlayer.Builder(this, customRenderersFactory).build();
86     mPlayer.addAudioOffloadListener(listener);
87     // Enable audio offloading
88     AudioOffloadPreferences audioOffloadPreferences = new AudioOffloadPreferences.Builder()
89         .setAudioOffloadMode(AudioOffloadPreferences.AUDIO_OFFLOAD_MODE_ENABLED)
90         .build();
91     TrackSelectionParameters currentParameters = mPlayer.getTrackSelectionParameters();
92     TrackSelectionParameters newParameters = currentParameters.buildUpon()
93         .setAudioOffloadPreferences(audioOffloadPreferences).build();
94     mPlayer.setTrackSelectionParameters(newParameters);
95     mExoplayerView = findViewById(R.id.audioOffloadExoplayer);
96     mExoplayerView.setPlayer(mPlayer);
97   }
98 
99   /**
100    * Prepare input list and add it to player's playlist.
101    */
102   public void prepareMediaItems(List<String> urls) {
103     sVideoUrls = urls != null ? Collections.unmodifiableList(urls) : null;
104     if (sVideoUrls == null) {
105       return;
106     }
107     for (String videoUrl : sVideoUrls) {
108       MediaItem mediaItem = MediaItem.fromUri(Uri.parse(videoUrl));
109       mPlayer.addMediaItem(mediaItem);
110     }
111   }
112 
113   /**
114    * Prepare and play the player.
115    */
116   @Override
117   protected void onStart() {
118     super.onStart();
119     mPlayer.prepare();
120     mPlayer.play();
121   }
122 
123   /**
124    * Stop the player.
125    */
126   @Override
127   protected void onStop() {
128     mPlayer.stop();
129     super.onStop();
130   }
131 
132   /**
133    * Release the player and destroy the activity
134    */
135   @Override
136   protected void onDestroy() {
137     super.onDestroy();
138     mPlayer.release();
139     getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
140   }
141 
142   /**
143    * Register a listener to receive events from the player.
144    *
145    * <p>This method can be called from any thread.
146    *
147    * @param listener The listener to register.
148    */
149   public void addPlayerListener(PlayerListener listener) {
150     mPlayer.addListener(listener);
151     this.mPlayerListener = listener;
152   }
153 
154   /**
155    * Unregister a listener registered through addPlayerListener(Listener). The listener will no
156    * longer receive events.
157    */
158   public void removePlayerListener() {
159     mPlayer.removeListener(this.mPlayerListener);
160   }
161 }
162