55import android .content .Context ;
66import android .os .Bundle ;
77import android .os .Handler ;
8- import android .os .Process ;
98import android .util .Log ;
109import android .view .LayoutInflater ;
1110import android .view .View ;
2120import com .yanzhenjie .permission .AndPermission ;
2221import com .yanzhenjie .permission .runtime .Permission ;
2322
24- import java .io .IOException ;
25- import java .io .InputStream ;
26-
2723import io .agora .api .example .MainApplication ;
2824import io .agora .api .example .R ;
2925import io .agora .api .example .annotation .Example ;
3026import io .agora .api .example .common .BaseFragment ;
3127import io .agora .api .example .common .widget .AudioSeatManager ;
28+ import io .agora .api .example .utils .AudioFileReader ;
3229import io .agora .api .example .utils .CommonUtil ;
3330import io .agora .api .example .utils .TokenUtils ;
3431import io .agora .rtc2 .ChannelMediaOptions ;
@@ -57,19 +54,9 @@ public class CustomAudioSource extends BaseFragment implements View.OnClickListe
5754 public static RtcEngineEx engine ;
5855 private Switch mic , pcm ;
5956 private ChannelMediaOptions option = new ChannelMediaOptions ();
60- private static final String AUDIO_FILE = "output.raw" ;
61- private static final Integer SAMPLE_RATE = 44100 ;
62- private static final Integer SAMPLE_NUM_OF_CHANNEL = 2 ;
63- private static final Integer BITS_PER_SAMPLE = 16 ;
64- private static final Integer SAMPLES = 441 ;
65- private static final Integer BUFFER_SIZE = SAMPLES * BITS_PER_SAMPLE / 8 * SAMPLE_NUM_OF_CHANNEL ;
66- private static final Integer PUSH_INTERVAL = SAMPLES * 1000 / SAMPLE_RATE ;
67-
68- private InputStream inputStream ;
69- private Thread pushingTask ;
70- private boolean pushing = false ;
7157
7258 private AudioSeatManager audioSeatManager ;
59+ private AudioFileReader audioPushingHelper ;
7360
7461 @ Override
7562 public void onCreate (@ Nullable Bundle savedInstanceState ) {
@@ -87,36 +74,6 @@ private void initMediaOption() {
8774 option .enableAudioRecordingOrPlayout = true ;
8875 }
8976
90- private void openAudioFile () {
91- try {
92- inputStream = this .getResources ().getAssets ().open (AUDIO_FILE );
93- } catch (IOException e ) {
94- e .printStackTrace ();
95- }
96- }
97-
98- private void closeAudioFile () {
99- try {
100- inputStream .close ();
101- } catch (IOException e ) {
102- e .printStackTrace ();
103- }
104- }
105-
106- private byte [] readBuffer () {
107- int byteSize = BUFFER_SIZE ;
108- byte [] buffer = new byte [byteSize ];
109- try {
110- if (inputStream .read (buffer ) < 0 ) {
111- inputStream .reset ();
112- return readBuffer ();
113- }
114- } catch (IOException e ) {
115- e .printStackTrace ();
116- }
117- return buffer ;
118- }
119-
12077 @ Nullable
12178 @ Override
12279 public View onCreateView (@ NonNull LayoutInflater inflater , @ Nullable ViewGroup container , @ Nullable Bundle savedInstanceState ) {
@@ -193,7 +150,12 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
193150 + "\" appVersion\" :\" " + RtcEngine .getSdkVersion () + "\" "
194151 + "}"
195152 + "}" );
196- openAudioFile ();
153+
154+ audioPushingHelper = new AudioFileReader (requireContext (), (buffer , timestamp ) -> {
155+ if (joined && engine != null ){
156+ engine .pushExternalAudioFrame (buffer , timestamp );
157+ }
158+ });
197159 } catch (Exception e ) {
198160 e .printStackTrace ();
199161 getActivity ().onBackPressed ();
@@ -203,34 +165,27 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
203165 @ Override
204166 public void onDestroy () {
205167 super .onDestroy ();
206- pushing = false ;
168+ if (audioPushingHelper != null ){
169+ audioPushingHelper .stop ();
170+ }
207171 /**leaveChannel and Destroy the RtcEngine instance*/
208172 if (engine != null ) {
209173 engine .leaveChannel ();
210174 }
211175 handler .post (RtcEngine ::destroy );
212176 engine = null ;
213- closeAudioFile ();
214177 }
215178
216179
217180 @ Override
218- public void onCheckedChanged (CompoundButton compoundButton , boolean b ) {
181+ public void onCheckedChanged (CompoundButton compoundButton , boolean checked ) {
219182 if (compoundButton .getId () == R .id .microphone ) {
220- if (b ) {
221- option .publishMicrophoneTrack = true ;
222- } else {
223- option .publishMicrophoneTrack = false ;
224- }
183+ option .publishMicrophoneTrack = checked ;
225184 engine .updateChannelMediaOptions (option );
226185 } else if (compoundButton .getId () == R .id .localAudio ) {
227- if (b ) {
228- option .publishCustomAudioTrack = true ;
229- } else {
230- option .publishCustomAudioTrack = false ;
231- }
186+ option .publishCustomAudioTrack = checked ;
232187 engine .updateChannelMediaOptions (option );
233- engine .enableCustomAudioLocalPlayback (0 , true );
188+ engine .enableCustomAudioLocalPlayback (0 , checked );
234189 }
235190 }
236191
@@ -276,17 +231,11 @@ public void onClick(View v) {
276231 * 2:If you call the leaveChannel method during CDN live streaming, the SDK
277232 * triggers the removeInjectStreamUrl method.*/
278233 engine .leaveChannel ();
279- pushing = false ;
280234 join .setText (getString (R .string .join ));
281235 mic .setEnabled (false );
282236 pcm .setEnabled (false );
283- if (pushingTask != null ){
284- try {
285- pushingTask .join ();
286- pushingTask = null ;
287- } catch (InterruptedException e ) {
288- // do nothing
289- }
237+ if (audioPushingHelper != null ){
238+ audioPushingHelper .stop ();
290239 }
291240 audioSeatManager .downAllSeats ();
292241 }
@@ -313,8 +262,9 @@ private void joinChannel(String channelId) {
313262 * 0: Success.
314263 * < 0: Failure.
315264 * PS: Ensure that you call this method before the joinChannel method.*/
316- engine .setExternalAudioSource (true , SAMPLE_RATE , SAMPLE_NUM_OF_CHANNEL , 2 , false , true );
317-
265+ engine .setExternalAudioSource (true ,
266+ AudioFileReader .SAMPLE_RATE , AudioFileReader .SAMPLE_NUM_OF_CHANNEL , AudioFileReader .SAMPLE_NUM_OF_CHANNEL ,
267+ false , true );
318268
319269
320270 /**Please configure accessToken in the string_config file.
@@ -379,10 +329,8 @@ public void run() {
379329 pcm .setEnabled (true );
380330 join .setEnabled (true );
381331 join .setText (getString (R .string .leave ));
382- pushing = true ;
383- if (pushingTask == null ){
384- pushingTask = new Thread (new PushingTask ());
385- pushingTask .start ();
332+ if (audioPushingHelper != null ){
333+ audioPushingHelper .start ();
386334 }
387335 audioSeatManager .upLocalSeat (uid );
388336 }
@@ -403,26 +351,4 @@ public void onUserOffline(int uid, int reason) {
403351 }
404352 };
405353
406- class PushingTask implements Runnable {
407- long number = 0 ;
408-
409- @ Override
410- public void run () {
411- Process .setThreadPriority (Process .THREAD_PRIORITY_URGENT_AUDIO );
412- while (pushing ) {
413- Log .i (TAG , "pushExternalAudioFrame times:" + number ++);
414- long before = System .currentTimeMillis ();
415- engine .pushExternalAudioFrame (readBuffer (), 0 );
416- long now = System .currentTimeMillis ();
417- long consuming = now - before ;
418- if (consuming < PUSH_INTERVAL ){
419- try {
420- Thread .sleep (PUSH_INTERVAL - consuming );
421- } catch (InterruptedException e ) {
422- Log .e (TAG , "PushingTask Interrupted" );
423- }
424- }
425- }
426- }
427- }
428354}
0 commit comments