gpt4 book ai didi

java - AudioPlaybackCapture(Android 10)无法正常工作并录制空声音

转载 作者:行者123 更新时间:2023-11-30 05:03:06 45 4
gpt4 key购买 nike

我尝试使用新的 AudioPlaybackCapture 方法在 android 10 设备中录制一些媒体。但不幸的是,我使用此 API 的代码似乎运行不佳。

在这里,我使用了一个 Activity 来启动单独的媒体录制服务。该服务已注册到广播接收器以开始和停止录制。广播 Intent 是通过单击按钮(开始、停止)使用我的主要 Activity 触发的

没有打印异常。该文件也会在所需位置创建。但没有内容(0 字节)。已提供所有必需的 list 和运行时权限。我在这里做错了什么。

这是我的服务

public class MediaCaptureService extends Service {
public static final String ACTION_ALL = "ALL";
public static final String ACTION_START = "ACTION_START";
public static final String ACTION_STOP = "ACTION_STOP";
public static final String EXTRA_RESULT_CODE = "EXTRA_RESULT_CODE";
public static final String EXTRA_ACTION_NAME = "ACTION_NAME";

private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

NotificationCompat.Builder _notificationBuilder;
NotificationManager _notificationManager;
private String NOTIFICATION_CHANNEL_ID = "ChannelId";
private String NOTIFICATION_CHANNEL_NAME = "Channel";
private String NOTIFICATION_CHANNEL_DESC = "ChannelDescription";
private int NOTIFICATION_ID = 1000;
private static final String ONGING_NOTIFICATION_TICKER = "RecorderApp";

int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format

AudioRecord _recorder;
private boolean isRecording = false;

private MediaProjectionManager _mediaProjectionManager;
private MediaProjection _mediaProjection;

Intent _callingIntent;

public MediaCaptureService() {
}

@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Call Start foreground with notification
Intent notificationIntent = new Intent(this, MediaCaptureService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
_notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_foreground))
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Starting Service")
.setContentText("Starting monitoring service")
.setTicker(ONGING_NOTIFICATION_TICKER)
.setContentIntent(pendingIntent);
Notification notification = _notificationBuilder.build();
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(NOTIFICATION_CHANNEL_DESC);
_notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
_notificationManager.createNotificationChannel(channel);
startForeground(NOTIFICATION_ID, notification);
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
_mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
}

}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
_callingIntent = intent;

IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_ALL);
registerReceiver(_actionReceiver, filter);

return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void startRecording(Intent intent) {
//final int resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, 0);
_mediaProjection = _mediaProjectionManager.getMediaProjection(-1, intent);
startRecording(_mediaProjection);
}

@TargetApi(29)
private void startRecording(MediaProjection mediaProjection ) {
AudioPlaybackCaptureConfiguration config =
new AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
.addMatchingUsage(AudioAttributes.USAGE_MEDIA)
.build();
AudioFormat audioFormat = new AudioFormat.Builder()
.setEncoding(RECORDER_AUDIO_ENCODING)
.setSampleRate(RECORDER_SAMPLERATE)
.setChannelMask(RECORDER_CHANNELS)
.build();
_recorder = new AudioRecord.Builder()
// .setAudioSource(MediaRecorder.AudioSource.MIC)
.setAudioFormat(audioFormat)
.setBufferSizeInBytes(BufferElements2Rec * BytesPerElement)
.setAudioPlaybackCaptureConfig(config)
.build();

_recorder.startRecording();
writeAudioDataToFile();
}

private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;

}

private void writeAudioDataToFile() {
// Write the output audio in byte
Log.i(MainActivity.LOG_PREFIX, "Recording started. Computing output file name");
File sampleDir = new File(getExternalFilesDir(null), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String fileName = "Record-" + new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss").format(new Date()) + ".pcm";
String filePath = sampleDir.getAbsolutePath() + "/" + fileName;
//String filePath = "/sdcard/voice8K16bitmono.pcm";
short sData[] = new short[BufferElements2Rec];

FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}

while (isRecording) {
// gets the voice output from microphone to byte format
_recorder.read(sData, 0, BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData, 0, BufferElements2Rec * BytesPerElement);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}

Log.i(MainActivity.LOG_PREFIX, String.format("Recording finished. File saved to '%s'", filePath));
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopRecording() {
// stops the recording activity
if (null != _recorder) {
isRecording = false;
_recorder.stop();
_recorder.release();
_recorder = null;
}

_mediaProjection.stop();

stopSelf();
}

@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(_actionReceiver);
}

BroadcastReceiver _actionReceiver = new BroadcastReceiver() {
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase(ACTION_ALL)) {
String actionName = intent.getStringExtra(EXTRA_ACTION_NAME);
if (actionName != null && !actionName.isEmpty()) {
if (actionName.equalsIgnoreCase(ACTION_START)) {
startRecording(_callingIntent);
} else if (actionName.equalsIgnoreCase(ACTION_STOP)){
stopRecording();
}
}

}
}
};



这是主要 Activity 的摘录,其中启动了服务和启动/停止操作。



public class MainActivity extends AppCompatActivity {
public static final String LOG_PREFIX = "CALL_FUNCTION_TEST";

private static final int ALL_PERMISSIONS_PERMISSION_CODE = 1000;
private static final int CREATE_SCREEN_CAPTURE = 1001;

Button _btnInitCapture;
Button _btnStartCapture;
Button _btnStopCapture;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

_btnGetOkPermissions = findViewById(R.id.btnGetOkPermissions);
_btnGetOkPermissions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
checkOkPermissions();
}
});

_btnInitCapture = findViewById(R.id.btnInitCapture);
_btnInitCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
initAudioCapture();
}
});

_btnStartCapture = findViewById(R.id.btnStartCapture);
_btnStartCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startRecording();
}
});

_btnStopCapture = findViewById(R.id.btnStopAudioCapture);
_btnStopCapture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
stopRecording();
}
});
}

...

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void initAudioCapture() {
_manager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
Intent intent = _manager.createScreenCaptureIntent();
startActivityForResult(intent, CREATE_SCREEN_CAPTURE);
}

private void stopRecording() {
Intent broadCastIntent = new Intent();
broadCastIntent.setAction(MediaCaptureService.ACTION_ALL);
broadCastIntent.putExtra(MediaCaptureService.EXTRA_ACTION_NAME, MediaCaptureService.ACTION_STOP);
this.sendBroadcast(broadCastIntent);
}

private void startRecording() {
Intent broadCastIntent = new Intent();
broadCastIntent.setAction(MediaCaptureService.ACTION_ALL);
broadCastIntent.putExtra(MediaCaptureService.EXTRA_ACTION_NAME, MediaCaptureService.ACTION_START);
this.sendBroadcast(broadCastIntent);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (CREATE_SCREEN_CAPTURE == requestCode) {
if (resultCode == RESULT_OK) {
Intent i = new Intent(this, MediaCaptureService.class);
i.setAction(MediaCaptureService.ACTION_START);
i.putExtra(MediaCaptureService.EXTRA_RESULT_CODE, resultCode);
i.putExtras(intent);
this.startService(i);
} else {
// user did not grant permissions
}
}
}
}


最佳答案

好吧,没有什么设置 isRecording 为真。此外,您正在以阻塞方法进行录制,但您在 UI 线程上,这应该会导致您的界面在您开始录制后立即卡住。

关于java - AudioPlaybackCapture(Android 10)无法正常工作并录制空声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57870287/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com