Skip to content

Commit ab8bc86

Browse files
authored
Merge pull request #184 from AgoraIO/dev/3.5.0
Dev/3.5.0
2 parents 9332c72 + 356da44 commit ab8bc86

File tree

17 files changed

+124
-60
lines changed

17 files changed

+124
-60
lines changed

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/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/ProcessAudioRawData.java

Lines changed: 74 additions & 27 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,15 +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-
mAudioPlayer = new AudioPlayer(AudioManager.STREAM_VOICE_CALL, SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, AudioFormat.CHANNEL_OUT_MONO);
113+
openAudioFile();
119114
}
120115
catch (Exception e) {
121116
e.printStackTrace();
@@ -132,7 +127,45 @@ public void onDestroy() {
132127
}
133128
handler.post(RtcEngine::destroy);
134129
engine = null;
135-
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;
136169
}
137170

138171
@Override
@@ -237,8 +270,14 @@ private void joinChannel(String channelId) {
237270
}
238271
// Prevent repeated entry
239272
join.setEnabled(false);
240-
241-
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);
242281
}
243282

244283
/**
@@ -282,7 +321,6 @@ public void onLeaveChannel(RtcStats stats) {
282321
public void onJoinChannelSuccess(String channel, int uid, int elapsed) {
283322
Log.i(TAG, String.format("onJoinChannelSuccess channel %s uid %d", channel, uid));
284323
showLongToast(String.format("onJoinChannelSuccess channel %s uid %d", channel, uid));
285-
mAudioPlayer.startPlayer();
286324
myUid = uid;
287325
joined = true;
288326
handler.post(new Runnable() {
@@ -292,7 +330,7 @@ public void run() {
292330
mute.setEnabled(true);
293331
join.setEnabled(true);
294332
join.setText(getString(R.string.leave));
295-
loopback.setEnabled(true);
333+
writeBackAudio.setEnabled(true);
296334
}
297335
});
298336
}
@@ -372,7 +410,16 @@ public void onActiveSpeaker(int uid) {
372410
private final IAudioFrameObserver audioFrameObserver = new IAudioFrameObserver() {
373411
@Override
374412
public boolean onRecordFrame(AudioFrame audioFrame) {
375-
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;
376423
}
377424

378425
@Override
@@ -402,12 +449,12 @@ public boolean onPlaybackFrameBeforeMixingEx(AudioFrame audioFrame, int uid, Str
402449

403450
@Override
404451
public int getObservedAudioFramePosition() {
405-
return 0;
452+
return IAudioFrameObserver.POSITION_RECORD | IAudioFrameObserver.POSITION_MIXED;
406453
}
407454

408455
@Override
409456
public AudioParams getRecordAudioParams() {
410-
return new AudioParams(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_ONLY, SAMPLES_PER_CALL);
457+
return new AudioParams(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_WRITE, SAMPLES_PER_CALL);
411458
}
412459

413460
@Override
@@ -423,6 +470,6 @@ public AudioParams getMixedAudioParams() {
423470

424471
@Override
425472
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
426-
isEnableLoopBack = b;
473+
isWriteBackAudio = b;
427474
}
428475
}

Android/APIExample/app/src/main/res/layout/fragment_raw_audio.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
tools:context=".examples.basic.JoinChannelAudio">
88

99
<Switch
10-
android:id="@+id/loopback"
10+
android:id="@+id/audioWriteBack"
1111
android:layout_width="wrap_content"
1212
android:layout_height="wrap_content"
1313
android:layout_alignParentEnd="true"
1414
android:layout_alignParentBottom="true"
1515
android:layout_marginEnd="16dp"
1616
android:layout_marginBottom="200dp"
1717
android:enabled="false"
18-
android:text="@string/loopback" />
18+
android:text="@string/mixing_audio" />
1919

2020
<androidx.appcompat.widget.AppCompatButton
2121
android:id="@+id/btn_mute"

Android/APIExample/app/src/main/res/values-zh/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,4 +139,5 @@
139139
<string name="mixing_playout_vol">混音播放音量</string>
140140
<string name="effect_control">音效控制</string>
141141
<string name="audio_effects_vol">音效音量</string>
142+
<string name="mixing_audio">混音</string>
142143
</resources>

Android/APIExample/app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,5 @@
143143
<string name="mixing_playout_vol">Mixing Playout Vol</string>
144144
<string name="effect_control">Effect Control</string>
145145
<string name="audio_effects_vol">Audio Effects Vol</string>
146+
<string name="mixing_audio">Audio Mixing</string>
146147
</resources>

Android/APIExample/build.gradle

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
buildscript {
44
repositories {
55
google()
6-
jcenter()
7-
maven { url 'https://www.jitpack.io' }
6+
mavenCentral()
87

98
}
109
dependencies {
@@ -20,8 +19,8 @@ buildscript {
2019
allprojects {
2120
repositories {
2221
google()
23-
jcenter()
24-
maven { url 'https://www.jitpack.io' }
22+
mavenCentral()
23+
maven { url 'https://jitpack.io' }
2524
}
2625
}
2726

Android/APIExample/lib-component/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ dependencies {
3030
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
3131
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
3232

33-
api 'com.github.agorabuilder:native-full-sdk:3.4.5'
34-
api 'io.agora:agoraplayer:1.2.4'
33+
api 'io.agora.rtc:full-sdk:3.5.0'
34+
api 'io.agora:player:1.3.0'
3535

3636
}

Android/APIExample/lib-screensharing/src/main/java/io/agora/rtc/ss/gles/GLRender.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public class GLRender {
5454
private LinkedList<Runnable> mGLDrawTaskList;
5555
private final Object mDrawLock = new Object();
5656

57+
private final static int frameRate = 30;
58+
private long mLastFrameTime;
59+
60+
5761
private Runnable runnableDrawFrame = new Runnable() {
5862
public void run() {
5963
doDrawFrame();
@@ -196,6 +200,14 @@ public void onResume() {
196200
}
197201

198202
public void requestRender() {
203+
long tm = System.currentTimeMillis();
204+
long tmDiff = tm - mLastFrameTime;
205+
if (tmDiff < (1000 / frameRate)) {
206+
Log.v(TAG, "drawing too often, drop this frame... ");
207+
return;
208+
}
209+
mLastFrameTime = tm;
210+
199211
if (mGLSurfaceView != null) {
200212
mGLSurfaceView.requestRender();
201213
}

0 commit comments

Comments
 (0)