Skip to content

Commit 33e017d

Browse files
committed
Merge branch 'master' of github.com:AgoraIO/API-Examples into master
2 parents e6b5ae8 + ab8bc86 commit 33e017d

23 files changed

Lines changed: 132 additions & 677 deletions

File tree

Android/APIExample/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ dependencies {
5050
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
5151
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
5252

53-
implementation 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.2.0'
54-
implementation 'com.yanzhenjie:permission:2.0.3'
53+
implementation 'com.github.luizgrp:SectionedRecyclerViewAdapter:v3.2.0'
54+
implementation 'com.yanzhenjie:permission:2.0.2'
5555
implementation 'de.javagl:obj:0.2.1'
5656
implementation 'com.google.ar:core:1.0.0'
5757

1.39 MB
Binary file not shown.

Android/APIExample/app/src/main/java/io/agora/api/example/ExampleActivity.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import io.agora.api.example.examples.advanced.VideoQuickSwitch;
3737
import io.agora.api.example.examples.advanced.RTMPStreaming;
3838
import io.agora.api.example.examples.advanced.StreamEncrypt;
39-
import io.agora.api.example.examples.advanced.SwitchCameraScreenShare;
4039
import io.agora.api.example.examples.advanced.VideoMetadata;
4140
import io.agora.api.example.examples.advanced.VoiceEffects;
4241
import io.agora.api.example.examples.advanced.customaudio.CustomAudioSource;
@@ -120,9 +119,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
120119
case R.id.action_mainFragment_to_SwitchExternalVideo:
121120
fragment = new SwitchExternalVideo();
122121
break;
123-
case R.id.action_mainFragment_to_SwitchCameraScreenShare:
124-
fragment = new SwitchCameraScreenShare();
125-
break;
126122
case R.id.action_mainFragment_to_VideoMetadata:
127123
fragment = new VideoMetadata();
128124
break;

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MediaPlayerKit.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,11 @@ public void onPlayBufferUpdated(long l) {
202202

203203
}
204204

205+
@Override
206+
public void onPreloadEvent(String s, Constants.MediaPlayerPreloadEvent mediaPlayerPreloadEvent) {
207+
208+
}
209+
205210
@Override
206211
public void onPlayerEvent(Constants.MediaPlayerEvent eventCode) {
207212
LogUtil.i("agoraMediaPlayerKit1 onEvent:" + eventCode);

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/MultiProcess.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
/**This demo demonstrates how to make a one-to-one video call*/
4343
@Example(
44-
index = 23,
44+
index = 6,
4545
group = ADVANCED,
4646
name = R.string.item_twoProcessScreenShare,
4747
actionId = R.id.action_mainFragment_to_two_process_screen_share,

Android/APIExample/app/src/main/java/io/agora/api/example/examples/advanced/ProcessAudioRawData.java

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package io.agora.api.example.examples.advanced;
22

33
import android.content.Context;
4-
import android.media.AudioFormat;
5-
import android.media.AudioManager;
64
import android.os.Bundle;
75
import android.os.Handler;
86
import android.text.TextUtils;
@@ -21,10 +19,13 @@
2119
import com.yanzhenjie.permission.AndPermission;
2220
import com.yanzhenjie.permission.runtime.Permission;
2321

22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.nio.ByteBuffer;
25+
2426
import io.agora.api.example.R;
2527
import io.agora.api.example.annotation.Example;
2628
import io.agora.api.example.common.BaseFragment;
27-
import io.agora.api.example.examples.advanced.customaudio.AudioPlayer;
2829
import io.agora.api.example.utils.CommonUtil;
2930
import io.agora.rtc.AudioFrame;
3031
import io.agora.rtc.Constants;
@@ -53,15 +54,17 @@ public class ProcessAudioRawData extends BaseFragment implements View.OnClickLis
5354
private static final String TAG = ProcessAudioRawData.class.getSimpleName();
5455
private EditText et_channel;
5556
private Button mute, join, speaker;
56-
private Switch loopback;
57+
private Switch writeBackAudio;
5758
private RtcEngine engine;
5859
private int myUid;
5960
private boolean joined = false;
60-
private boolean isEnableLoopBack = false;
61-
private AudioPlayer mAudioPlayer;
61+
private boolean isWriteBackAudio = false;
6262
private static final Integer SAMPLE_RATE = 44100;
63+
private static final Integer SAMPLE_NUM_OF_CHANNEL = 2;
64+
private static final Integer BIT_PER_SAMPLE = 16;
6365
private static final Integer SAMPLES_PER_CALL = 4410;
64-
private static final Integer SAMPLE_NUM_OF_CHANNEL = 1;
66+
private static final String AUDIO_FILE = "output.raw";
67+
private InputStream inputStream;
6568

6669
@Override
6770
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -86,8 +89,8 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
8689
mute.setOnClickListener(this);
8790
speaker = view.findViewById(R.id.btn_speaker);
8891
speaker.setOnClickListener(this);
89-
loopback = view.findViewById(R.id.loopback);
90-
loopback.setOnCheckedChangeListener(this);
92+
writeBackAudio = view.findViewById(R.id.audioWriteBack);
93+
writeBackAudio.setOnCheckedChangeListener(this);
9194
}
9295

9396
@Override
@@ -107,18 +110,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
107110
* The SDK uses this class to report to the app on SDK runtime events.*/
108111
String appId = getString(R.string.agora_app_id);
109112
engine = RtcEngine.create(getContext().getApplicationContext(), appId, iRtcEngineEventHandler);
110-
/** Registers the audio observer object.
111-
*
112-
* @param observer Audio observer object to be registered. See {@link IAudioFrameObserver IAudioFrameObserver}. Set the value as @p null to cancel registering, if necessary.
113-
* @return
114-
* - 0: Success.
115-
* - < 0: Failure.
116-
*/
117-
engine.registerAudioFrameObserver(audioFrameObserver);
118-
engine.setRecordingAudioFrameParameters(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_ONLY, SAMPLES_PER_CALL);
119-
engine.setMixedAudioFrameParameters(SAMPLE_RATE, SAMPLES_PER_CALL);
120-
engine.setPlaybackAudioFrameParameters(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_ONLY, SAMPLES_PER_CALL);
121-
mAudioPlayer = new AudioPlayer(AudioManager.STREAM_VOICE_CALL, SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, AudioFormat.CHANNEL_OUT_MONO);
113+
openAudioFile();
122114
}
123115
catch (Exception e) {
124116
e.printStackTrace();
@@ -135,7 +127,45 @@ public void onDestroy() {
135127
}
136128
handler.post(RtcEngine::destroy);
137129
engine = null;
138-
mAudioPlayer.stopPlayer();
130+
closeAudioFile();
131+
}
132+
133+
private void openAudioFile(){
134+
try {
135+
inputStream = this.getResources().getAssets().open(AUDIO_FILE);
136+
} catch (IOException e) {
137+
e.printStackTrace();
138+
}
139+
}
140+
141+
private void closeAudioFile(){
142+
try {
143+
inputStream.close();
144+
} catch (IOException e) {
145+
e.printStackTrace();
146+
}
147+
}
148+
149+
private byte[] readBuffer(){
150+
int byteSize = SAMPLES_PER_CALL * BIT_PER_SAMPLE / 8;
151+
byte[] buffer = new byte[byteSize];
152+
try {
153+
if(inputStream.read(buffer) < 0){
154+
inputStream.reset();
155+
return readBuffer();
156+
}
157+
} catch (IOException e) {
158+
e.printStackTrace();
159+
}
160+
return buffer;
161+
}
162+
163+
private byte[] audioAggregate(byte[] origin, byte[] buffer) {
164+
byte[] output = new byte[origin.length];
165+
for (int i = 0; i < origin.length; i++) {
166+
output[i] = (byte) ((int) origin[i] + (int) buffer[i] / 2);
167+
}
168+
return output;
139169
}
140170

141171
@Override
@@ -240,8 +270,14 @@ private void joinChannel(String channelId) {
240270
}
241271
// Prevent repeated entry
242272
join.setEnabled(false);
243-
244-
273+
/** Registers the audio observer object.
274+
*
275+
* @param observer Audio observer object to be registered. See {@link IAudioFrameObserver IAudioFrameObserver}. Set the value as @p null to cancel registering, if necessary.
276+
* @return
277+
* - 0: Success.
278+
* - < 0: Failure.
279+
*/
280+
engine.registerAudioFrameObserver(audioFrameObserver);
245281
}
246282

247283
/**
@@ -285,7 +321,6 @@ public void onLeaveChannel(RtcStats stats) {
285321
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
286322
Log.i(TAG, String.format("onJoinChannelSuccess channel %s uid %d", channel, uid));
287323
showLongToast(String.format("onJoinChannelSuccess channel %s uid %d", channel, uid));
288-
mAudioPlayer.startPlayer();
289324
myUid = uid;
290325
joined = true;
291326
handler.post(new Runnable() {
@@ -295,7 +330,7 @@ public void run() {
295330
mute.setEnabled(true);
296331
join.setEnabled(true);
297332
join.setText(getString(R.string.leave));
298-
loopback.setEnabled(true);
333+
writeBackAudio.setEnabled(true);
299334
}
300335
});
301336
}
@@ -375,7 +410,16 @@ public void onActiveSpeaker(int uid) {
375410
private final IAudioFrameObserver audioFrameObserver = new IAudioFrameObserver() {
376411
@Override
377412
public boolean onRecordFrame(AudioFrame audioFrame) {
378-
return false;
413+
Log.i(TAG, "onRecordAudioFrame " + isWriteBackAudio);
414+
if(isWriteBackAudio){
415+
ByteBuffer byteBuffer = audioFrame.samples;
416+
byte[] buffer = readBuffer();
417+
byte[] origin = new byte[byteBuffer.remaining()];
418+
byteBuffer.get(origin);
419+
byteBuffer.flip();
420+
byteBuffer.put(audioAggregate(origin, buffer), 0, byteBuffer.remaining());
421+
}
422+
return true;
379423
}
380424

381425
@Override
@@ -405,27 +449,27 @@ public boolean onPlaybackFrameBeforeMixingEx(AudioFrame audioFrame, int uid, Str
405449

406450
@Override
407451
public int getObservedAudioFramePosition() {
408-
return 0;
452+
return IAudioFrameObserver.POSITION_RECORD | IAudioFrameObserver.POSITION_MIXED;
409453
}
410454

411455
@Override
412456
public AudioParams getRecordAudioParams() {
413-
return null;
457+
return new AudioParams(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_WRITE, SAMPLES_PER_CALL);
414458
}
415459

416460
@Override
417461
public AudioParams getPlaybackAudioParams() {
418-
return null;
462+
return new AudioParams(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_ONLY, SAMPLES_PER_CALL);
419463
}
420464

421465
@Override
422466
public AudioParams getMixedAudioParams() {
423-
return null;
467+
return new AudioParams(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_ONLY, SAMPLES_PER_CALL);
424468
}
425469
};
426470

427471
@Override
428472
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
429-
isEnableLoopBack = b;
473+
isWriteBackAudio = b;
430474
}
431475
}

0 commit comments

Comments
 (0)