Skip to content

Commit 2b4a7f0

Browse files
author
xianing
committed
fix 37200 issues
1 parent 1f4c21e commit 2b4a7f0

16 files changed

Lines changed: 163 additions & 534 deletions

File tree

Android/APIExample/app/src/main/AndroidManifest.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,6 @@
3232
</intent-filter>
3333
</activity>
3434

35-
<service android:name=".examples.advanced.customaudio.MicrophoneRecordService"
36-
android:exported="false"/>
37-
38-
<service android:name=".examples.advanced.customaudio.PCMRecordService"
39-
android:exported="false"/>
40-
4135
<service android:name=".examples.advanced.SwitchCameraScreenShare$MediaProjectFgService"
4236
android:enabled="true"
4337
android:exported="false"

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

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public class MediaPlayer extends BaseFragment implements View.OnClickListener, I
5555

5656
private static final String TAG = MediaPlayer.class.getSimpleName();
5757

58-
private Button join, open, play, stop, pause, publish, publishOnlyAudio;
58+
private Button join, open, play, stop, pause, publish;
5959
private EditText et_channel, et_url;
6060
private RtcEngine engine;
6161
private IMediaPlayer mediaPlayer;
@@ -124,7 +124,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
124124
stop = view.findViewById(R.id.stop);
125125
pause = view.findViewById(R.id.pause);
126126
publish = view.findViewById(R.id.publish);
127-
publishOnlyAudio = view.findViewById(R.id.publish_only_audio);
128127

129128
progressBar = view.findViewById(R.id.ctrl_progress_bar);
130129
progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@@ -154,7 +153,6 @@ public void onStopTrackingTouch(SeekBar seekBar) {
154153
view.findViewById(R.id.stop).setOnClickListener(this);
155154
view.findViewById(R.id.pause).setOnClickListener(this);
156155
view.findViewById(R.id.publish).setOnClickListener(this);
157-
view.findViewById(R.id.publish_only_audio).setOnClickListener(this);
158156
fl_local = view.findViewById(R.id.fl_local);
159157
fl_remote = view.findViewById(R.id.fl_remote);
160158
}
@@ -222,12 +220,9 @@ public void onClick(View v) {
222220
} else if (v.getId() == R.id.pause) {
223221
mediaPlayer.pause();
224222
} else if (v.getId() == R.id.publish) {
225-
options.publishAudioTrack = false;
226223
options.publishMediaPlayerVideoTrack = true;
227-
engine.updateChannelMediaOptions(options);
228-
} else if (v.getId() == R.id.publish_only_audio) {
229-
options.publishAudioTrack = true;
230-
options.publishMediaPlayerVideoTrack = false;
224+
options.publishMediaPlayerAudioTrack = true;
225+
options.publishMediaPlayerId = mediaPlayer.getMediaPlayerId();
231226
engine.updateChannelMediaOptions(options);
232227
}
233228
}
@@ -275,11 +270,6 @@ private void joinChannel(String channelId) {
275270
options.publishAudioTrack = false;
276271
options.enableAudioRecordingOrPlayout = true;
277272

278-
// media player
279-
options.publishMediaPlayerId = mediaPlayer.getMediaPlayerId();
280-
options.publishMediaPlayerAudioTrack = true;
281-
options.publishMediaPlayerVideoTrack = true;
282-
283273
/**Please configure accessToken in the string_config file.
284274
* A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see
285275
* https://docs.agora.io/en/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token
@@ -517,7 +507,6 @@ public void run() {
517507
stop.setEnabled(enable);
518508
pause.setEnabled(enable);
519509
publish.setEnabled(enable);
520-
publishOnlyAudio.setEnabled(enable);
521510
}
522511
});
523512
}

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,7 @@ public class ProcessAudioRawData extends BaseFragment implements View.OnClickLis
6262
private boolean joined = false;
6363
private boolean isWriteBackAudio = false;
6464
private static final Integer SAMPLE_RATE = 44100;
65-
private static final Integer SAMPLE_NUM_OF_CHANNEL = 2;
66-
private static final Integer BIT_PER_SAMPLE = 8;
65+
private static final Integer SAMPLE_NUM_OF_CHANNEL = 1;
6766
private static final Integer SAMPLES = 1024;
6867
private static final String AUDIO_FILE = "output.raw";
6968
private InputStream inputStream;
@@ -106,7 +105,7 @@ private void closeAudioFile(){
106105
}
107106

108107
private byte[] readBuffer(){
109-
int byteSize = SAMPLES * BIT_PER_SAMPLE / 8 * SAMPLE_NUM_OF_CHANNEL;
108+
int byteSize = SAMPLES * SAMPLE_NUM_OF_CHANNEL * 2;
110109
byte[] buffer = new byte[byteSize];
111110
try {
112111
if(inputStream.read(buffer) < 0){
@@ -183,6 +182,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
183182
engine = RtcEngine.create(config);
184183
engine.registerAudioFrameObserver(iAudioFrameObserver);
185184
engine.setRecordingAudioFrameParameters(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_WRITE, SAMPLES);
185+
engine.setPlaybackAudioFrameParameters(SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, Constants.RAW_AUDIO_FRAME_OP_MODE_READ_WRITE, SAMPLES);
186186
openAudioFile();
187187
}
188188
catch (Exception e) {
@@ -192,9 +192,12 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
192192
}
193193

194194
private byte[] audioAggregate(byte[] origin, byte[] buffer) {
195-
byte[] output = new byte[origin.length];
195+
byte[] output = new byte[buffer.length];
196196
for (int i = 0; i < origin.length; i++) {
197-
output[i] = (byte) ((int) origin[i] + (int) buffer[i] / 2);
197+
output[i] = (byte) ((long) origin[i] / 2 + (long) buffer[i]);
198+
if(i == 2){
199+
Log.i(TAG, "origin :" + (int) origin[i] + " audio: " + (int) buffer[i]);
200+
}
198201
}
199202
return output;
200203
}
@@ -289,7 +292,6 @@ private void joinChannel(String channelId) {
289292
if (TextUtils.equals(accessToken, "") || TextUtils.equals(accessToken, "<#YOUR ACCESS TOKEN#>")) {
290293
accessToken = null;
291294
}
292-
engine.enableAudioVolumeIndication(1000, 3, false);
293295
ChannelMediaOptions option = new ChannelMediaOptions();
294296
option.autoSubscribeAudio = true;
295297
option.autoSubscribeVideo = true;
@@ -313,29 +315,29 @@ private void joinChannel(String channelId) {
313315

314316
@Override
315317
public boolean onRecordAudioFrame(int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, ByteBuffer byteBuffer, long renderTimeMs, int bufferLength) {
316-
// Log.i(TAG, "onRecordAudioFrame " + isWriteBackAudio);
317318
if(isWriteBackAudio){
319+
byteBuffer.flip();
318320
byte[] buffer = readBuffer();
319321
byte[] origin = new byte[byteBuffer.remaining()];
320322
byteBuffer.get(origin);
321323
byteBuffer.flip();
322324
byteBuffer.put(audioAggregate(origin, buffer), 0, byteBuffer.remaining());
323325
}
324-
return false;
326+
return true;
325327
}
326328

327329
@Override
328-
public boolean onPlaybackAudioFrame(int i, int i1, int i2, int i3, int i4, ByteBuffer byteBuffer, long l, int i5) {
330+
public boolean onPlaybackAudioFrame(int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, ByteBuffer byteBuffer, long renderTimeMs, int bufferLength) {
329331
return false;
330332
}
331333

332334
@Override
333-
public boolean onMixedAudioFrame(int i, int i1, int i2, int i3, int i4, ByteBuffer byteBuffer, long l, int i5) {
335+
public boolean onMixedAudioFrame(int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, ByteBuffer byteBuffer, long renderTimeMs, int bufferLength) {
334336
return false;
335337
}
336338

337339
@Override
338-
public boolean onPlaybackAudioFrameBeforeMixing(int i, int i1, int i2, int i3, int i4, int i5, ByteBuffer byteBuffer, long l, int i6) {
340+
public boolean onPlaybackAudioFrameBeforeMixing(int uid, int audioFrameType, int samples, int bytesPerSample, int channels, int samplesPerSec, ByteBuffer byteBuffer, long renderTimeMs, int bufferLength) {
339341
return false;
340342
}
341343
};

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

Lines changed: 55 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
package io.agora.api.example.examples.advanced.customaudio;
22

33
import android.content.Context;
4-
import android.content.Intent;
5-
import android.media.AudioFormat;
6-
import android.media.AudioManager;
74
import android.os.Bundle;
8-
import android.os.Environment;
95
import android.os.Handler;
106
import android.text.TextUtils;
117
import android.util.Log;
@@ -23,8 +19,8 @@
2319
import com.yanzhenjie.permission.AndPermission;
2420
import com.yanzhenjie.permission.runtime.Permission;
2521

26-
import java.io.File;
27-
import java.util.Random;
22+
import java.io.IOException;
23+
import java.io.InputStream;
2824

2925
import io.agora.api.example.R;
3026
import io.agora.api.example.annotation.Example;
@@ -33,14 +29,11 @@
3329
import io.agora.rtc2.ChannelMediaOptions;
3430
import io.agora.rtc2.Constants;
3531
import io.agora.rtc2.IRtcEngineEventHandler;
36-
import io.agora.rtc2.RtcConnection;
3732
import io.agora.rtc2.RtcEngine;
3833
import io.agora.rtc2.RtcEngineConfig;
3934
import io.agora.rtc2.RtcEngineEx;
4035

4136
import static io.agora.api.example.common.model.Examples.ADVANCED;
42-
import static io.agora.api.example.examples.advanced.customaudio.MicrophoneRecordService.RecordThread.DEFAULT_CHANNEL_COUNT;
43-
import static io.agora.api.example.examples.advanced.customaudio.MicrophoneRecordService.RecordThread.DEFAULT_SAMPLE_RATE;
4437

4538
/**This demo demonstrates how to make a one-to-one voice call*/
4639
@Example(
@@ -60,6 +53,13 @@ public class CustomAudioSource extends BaseFragment implements View.OnClickListe
6053
public static RtcEngineEx engine;
6154
private Switch mic, pcm;
6255
private ChannelMediaOptions option = new ChannelMediaOptions();
56+
private static final String AUDIO_FILE = "output.raw";
57+
private static final Integer SAMPLE_RATE = 44100;
58+
private static final Integer SAMPLE_NUM_OF_CHANNEL = 1;
59+
private static final Integer SAMPLES = 1024;
60+
private static final Integer BUFFER_SIZE = SAMPLES * SAMPLE_NUM_OF_CHANNEL * 2;
61+
62+
private InputStream inputStream;
6363

6464
@Override
6565
public void onCreate(@Nullable Bundle savedInstanceState)
@@ -76,6 +76,36 @@ private void initMediaOption() {
7676
option.publishCustomAudioTrack = false;
7777
}
7878

79+
private void openAudioFile(){
80+
try {
81+
inputStream = this.getResources().getAssets().open(AUDIO_FILE);
82+
} catch (IOException e) {
83+
e.printStackTrace();
84+
}
85+
}
86+
87+
private void closeAudioFile(){
88+
try {
89+
inputStream.close();
90+
} catch (IOException e) {
91+
e.printStackTrace();
92+
}
93+
}
94+
95+
private byte[] readBuffer(){
96+
int byteSize = BUFFER_SIZE;
97+
byte[] buffer = new byte[byteSize];
98+
try {
99+
if(inputStream.read(buffer) < 0){
100+
inputStream.reset();
101+
return readBuffer();
102+
}
103+
} catch (IOException e) {
104+
e.printStackTrace();
105+
}
106+
return buffer;
107+
}
108+
79109
@Nullable
80110
@Override
81111
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
@@ -95,15 +125,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
95125
pcm = view.findViewById(R.id.localAudio);
96126
mic.setOnCheckedChangeListener(this);
97127
pcm.setOnCheckedChangeListener(this);
98-
checkLocalAudio();
99-
}
100-
101-
private void checkLocalAudio() {
102-
File dir = getContext().getExternalFilesDir(Environment.DIRECTORY_MUSIC);
103-
File audioFile = new File(dir, PCMRecordService.FILE_NAME);
104-
if (!audioFile.exists()) {
105-
showAlert(String.format(getString(R.string.alert_no_local_audio_message), dir.getAbsolutePath()));
106-
}
107128
}
108129

109130
@Override
@@ -141,6 +162,7 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState)
141162
config.mEventHandler = iRtcEngineEventHandler;
142163
config.mAudioScenario = Constants.AudioScenario.getValue(Constants.AudioScenario.HIGH_DEFINITION);
143164
engine = (RtcEngineEx) RtcEngine.create(config);
165+
openAudioFile();
144166
}
145167
catch (Exception e)
146168
{
@@ -153,14 +175,14 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState)
153175
public void onDestroy()
154176
{
155177
super.onDestroy();
156-
stopPCMRecord();
157178
/**leaveChannel and Destroy the RtcEngine instance*/
158179
if(engine != null)
159180
{
160181
engine.leaveChannel();
161182
}
162183
handler.post(RtcEngine::destroy);
163184
engine = null;
185+
closeAudioFile();
164186
}
165187

166188

@@ -170,23 +192,21 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
170192
{
171193
if(b){
172194
option.publishAudioTrack = true;
173-
engine.updateChannelMediaOptions(option);
174195
}
175196
else{
176197
option.publishAudioTrack = false;
177-
engine.updateChannelMediaOptions(option);
178198
}
199+
engine.updateChannelMediaOptions(option);
179200
}
180201
else if(compoundButton.getId() == R.id.localAudio)
181202
{
182203
if(b){
183204
option.publishCustomAudioTrack = true;
184-
engine.updateChannelMediaOptions(option);
185205
}
186206
else{
187207
option.publishCustomAudioTrack = false;
188-
engine.updateChannelMediaOptions(option);
189208
}
209+
engine.updateChannelMediaOptions(option);
190210
}
191211
}
192212

@@ -220,7 +240,6 @@ public void onClick(View v)
220240
else
221241
{
222242
joined = false;
223-
stopPCMRecord();
224243
/**After joining a channel, the user must call the leaveChannel method to end the
225244
* call before joining another channel. This method returns 0 if the user leaves the
226245
* channel and releases all resources related to the call. This method call is
@@ -266,7 +285,7 @@ private void joinChannel(String channelId)
266285
* 0: Success.
267286
* < 0: Failure.
268287
* PS: Ensure that you call this method before the joinChannel method.*/
269-
engine.setExternalAudioSource(true, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, 1, true, true);
288+
engine.setExternalAudioSource(true, SAMPLE_RATE, SAMPLE_NUM_OF_CHANNEL, 2, true, true);
270289
/**Please configure accessToken in the string_config file.
271290
* A temporary token generated in Console. A temporary token is valid for 24 hours. For details, see
272291
* https://docs.agora.io/en/Agora%20Platform/token?platform=All%20Platforms#get-a-temporary-token
@@ -294,20 +313,6 @@ private void joinChannel(String channelId)
294313
join.setEnabled(false);
295314
}
296315

297-
private void startPCMRecord()
298-
{
299-
Intent intent = new Intent(getContext(), PCMRecordService.class);
300-
getActivity().startService(intent);
301-
}
302-
303-
private void stopPCMRecord()
304-
{
305-
Intent intent = new Intent(getContext(), PCMRecordService.class);
306-
getActivity().stopService(intent);
307-
option.publishCustomAudioTrack = false;
308-
engine.updateChannelMediaOptions(option);
309-
}
310-
311316
/**IRtcEngineEventHandler is an abstract class providing default implementation.
312317
* The SDK uses this class to report to the app on SDK runtime events.*/
313318
private final IRtcEngineEventHandler iRtcEngineEventHandler = new IRtcEngineEventHandler()
@@ -342,7 +347,6 @@ public void onJoinChannelSuccess(String channel, int uid, int elapsed)
342347
showLongToast(String.format("onJoinChannelSuccess channel %s uid %d", channel, uid));
343348
myUid = uid;
344349
joined = true;
345-
startPCMRecord();
346350
handler.post(new Runnable()
347351
{
348352
@Override
@@ -352,9 +356,20 @@ public void run()
352356
pcm.setEnabled(true);
353357
join.setEnabled(true);
354358
join.setText(getString(R.string.leave));
359+
new Thread(new PushingTask()).start();
355360
}
356361
});
357362
}
358363

359364
};
365+
366+
class PushingTask implements Runnable {
367+
368+
@Override
369+
public void run() {
370+
while (true){
371+
engine.pushExternalAudioFrame(readBuffer(), BUFFER_SIZE);
372+
}
373+
}
374+
}
360375
}

0 commit comments

Comments
 (0)