Skip to content

Commit b16d2dc

Browse files
Merge pull request #492 from TakayukiHoshi1984/bugfix_android10_mediaplayer
録音処理の修正
2 parents cc26c0e + a40a396 commit b16d2dc

6 files changed

Lines changed: 108 additions & 39 deletions

File tree

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/mediaplayer/HostMediaPlayerManager.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public class HostMediaPlayerManager {
110110
* サポートしているaudioのタイプ一覧.
111111
*/
112112
private static final List<String> AUDIO_TYPE_LIST = Arrays.asList("audio/mpeg", "audio/x-wav", "application/ogg",
113-
"audio/x-ms-wma", "audio/mp3", "audio/ogg", "audio/mp4");
113+
"audio/x-ms-wma", "audio/mp3", "audio/ogg", "audio/mp4", "audio/aac");
114114

115115
/**
116116
* サポートしているvideoのタイプ一覧.
@@ -250,6 +250,9 @@ public void putMediaId(final Intent response, final String mediaId) {
250250
String mMineType = getMIMEType(filePath);
251251
FileDescriptor fd = getDescriptorFromUri(uri);
252252

253+
mLogger.info("putMediaId: mimeType: " + mMineType);
254+
mLogger.info("putMediaId: fd: " + fd);
255+
253256
// パス指定の場合
254257
if (AUDIO_TYPE_LIST.contains(mMineType)) {
255258
if (mMediaPlayer != null) {

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/profile/HostMediaStreamingRecordingProfile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public void onReceive(final Context context, final Intent intent) {
8787
Uri uri = intent.getParcelableExtra(VideoConst.EXTRA_URI);
8888
String path = intent.getStringExtra(VideoConst.EXTRA_FILE_NAME);
8989
String u = uri != null ? uri.toString() : null;
90-
mRecorderMgr.sendEventForRecordingChange(serviceId, state, u, path, "audio/3gp", "");
90+
mRecorderMgr.sendEventForRecordingChange(serviceId, state, u, path, "audio/aac", "");
9191
}
9292
}
9393
};

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/recorder/audio/AudioConst.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,5 @@ private AudioConst() {
6969
public static final String EXTRA_CALLBACK_ERROR_MESSAGE = "callback_error_message";
7070

7171
/** フォーマット名. */
72-
public static final String FORMAT_TYPE = ".3gp";
72+
public static final String FORMAT_TYPE = ".m4a";
7373
}

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/recorder/audio/HostDeviceAudioRecorder.java

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,22 @@
88

99

1010
import android.Manifest;
11-
import android.content.ContentResolver;
12-
import android.content.ContentValues;
1311
import android.content.Context;
1412
import android.content.Intent;
1513
import android.media.MediaRecorder;
14+
import android.net.Uri;
1615
import android.os.Build;
1716
import android.os.Handler;
1817
import android.os.Looper;
19-
import android.provider.MediaStore;
18+
import android.util.Log;
19+
2020
import androidx.annotation.NonNull;
2121

2222
import org.deviceconnect.android.activity.PermissionUtility;
2323
import org.deviceconnect.android.deviceplugin.host.file.HostFileProvider;
2424
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceRecorder;
2525
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceStreamRecorder;
26+
import org.deviceconnect.android.deviceplugin.host.recorder.util.MediaSharing;
2627
import org.deviceconnect.android.provider.FileManager;
2728

2829
import java.io.File;
@@ -33,18 +34,25 @@
3334
import java.util.List;
3435
import java.util.Locale;
3536

37+
import static org.deviceconnect.android.deviceplugin.host.BuildConfig.DEBUG;
38+
3639
/**
3740
* Host Device Audio Recorder.
3841
*
3942
* @author NTT DOCOMO, INC.
4043
*/
4144
public class HostDeviceAudioRecorder implements HostDeviceRecorder, HostDeviceStreamRecorder {
4245

46+
/**
47+
* ログ出力用タグ.
48+
*/
49+
private static final String TAG = "host.dplugin";
50+
4351
private static final String ID = "audio";
4452

4553
private static final String NAME = "AndroidHost Audio Recorder";
4654

47-
private static final String MIME_TYPE = "audio/3gp";
55+
private static final String MIME_TYPE = "audio/aac";
4856

4957
private final SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyyMMdd_kkmmss", Locale.JAPAN);
5058

@@ -59,10 +67,14 @@ public class HostDeviceAudioRecorder implements HostDeviceRecorder, HostDeviceSt
5967
*/
6068
private List<String> mMimeTypes = new ArrayList<String>() {
6169
{
62-
add("audio/3gp");
70+
add("audio/aac");
6371
}
6472
};
73+
6574
private RecorderState mState;
75+
76+
private final MediaSharing mMediaSharing = MediaSharing.getInstance();
77+
6678
public HostDeviceAudioRecorder(final Context context) {
6779
mContext = context;
6880
mState = RecorderState.INACTTIVE;
@@ -209,7 +221,9 @@ public synchronized void stopRecording(final StoppingListener listener) {
209221
mState = RecorderState.INACTTIVE;
210222
if (listener != null) {
211223
if (mMediaRecorder != null) {
224+
mMediaRecorder.stop();
212225
releaseMediaRecorder();
226+
registerAudio(mFile);
213227
listener.onStopped(this, mFile.getName());
214228
} else {
215229
listener.onFailed(this, "Failed to Stop recording.");
@@ -283,8 +297,8 @@ private void initAudioContext(final String fileName, final RecordingListener lis
283297

284298
mMediaRecorder = new MediaRecorder();
285299
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
286-
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
287-
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
300+
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
301+
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
288302

289303
if (fileName != null) {
290304
mFile = new File(fileMgr.getBasePath(), fileName);
@@ -296,36 +310,27 @@ private void initAudioContext(final String fileName, final RecordingListener lis
296310
listener.onFailed(HostDeviceAudioRecorder.this, "File name must be specified.");
297311
}
298312
}
299-
/**
300-
* Check the existence of file.
301-
*
302-
* @return true is exist
303-
*/
304-
private boolean checkAudioFile() {
305-
return mFile != null && mFile.exists() && mFile.length() > 0;
306-
}
307313

308314
/**
309315
* MediaRecorderを解放.
310316
*/
311317
private void releaseMediaRecorder() {
312-
if (checkAudioFile()) {
313-
// Contents Providerに登録.
314-
ContentResolver resolver = mContext.getContentResolver();
315-
ContentValues values = new ContentValues();
316-
values.put(MediaStore.Video.Media.TITLE, mFile.getName());
317-
values.put(MediaStore.Video.Media.DISPLAY_NAME, mFile.getName());
318-
values.put(MediaStore.Video.Media.ARTIST, "DeviceConnect");
319-
values.put(MediaStore.Video.Media.MIME_TYPE, "audio/3gp");
320-
values.put(MediaStore.Video.Media.DATA, mFile.toString());
321-
resolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
322-
}
323-
324318
if (mMediaRecorder != null) {
325319
mMediaRecorder.reset();
326320
mMediaRecorder.release();
327321
mMediaRecorder = null;
328322
}
329323
}
330324

325+
private void registerAudio(final File audioFile) {
326+
Uri uri = mMediaSharing.shareAudio(mContext, audioFile);
327+
if (DEBUG) {
328+
String filePath = audioFile.getAbsolutePath();
329+
if (uri != null) {
330+
Log.d(TAG, "Registered audio: filePath=" + filePath + ", uri=" + uri.getPath());
331+
} else {
332+
Log.e(TAG, "Failed to register audio: file=" + filePath);
333+
}
334+
}
335+
}
331336
}

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/recorder/camera/Camera2Recorder.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
*/
77
package org.deviceconnect.android.deviceplugin.host.recorder.camera;
88

9-
import android.content.ContentResolver;
10-
import android.content.ContentValues;
119
import android.content.Context;
1210
import android.graphics.Bitmap;
1311
import android.graphics.BitmapFactory;
@@ -17,12 +15,11 @@
1715
import android.graphics.YuvImage;
1816
import android.media.Image;
1917
import android.media.ImageReader;
20-
import android.media.ThumbnailUtils;
2118
import android.net.Uri;
2219
import android.os.Handler;
2320
import android.os.HandlerThread;
2421
import android.os.Looper;
25-
import android.provider.MediaStore;
22+
2623
import androidx.annotation.NonNull;
2724

2825
import android.util.Log;
@@ -42,12 +39,12 @@
4239
import org.deviceconnect.android.deviceplugin.host.recorder.HostDeviceStreamRecorder;
4340
import org.deviceconnect.android.deviceplugin.host.recorder.PreviewServer;
4441
import org.deviceconnect.android.deviceplugin.host.recorder.util.CapabilityUtil;
42+
import org.deviceconnect.android.deviceplugin.host.recorder.util.MediaSharing;
4543
import org.deviceconnect.android.deviceplugin.host.recorder.util.RecorderSettingData;
4644
import org.deviceconnect.android.provider.FileManager;
4745

4846
import java.io.ByteArrayOutputStream;
4947
import java.io.File;
50-
import java.io.IOException;
5148
import java.nio.ByteBuffer;
5249
import java.text.SimpleDateFormat;
5350
import java.util.ArrayList;

dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/recorder/camera/MediaSharing.java renamed to dConnectDevicePlugin/dConnectDeviceHost/app/src/main/java/org/deviceconnect/android/deviceplugin/host/recorder/util/MediaSharing.java

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.deviceconnect.android.deviceplugin.host.recorder.camera;
1+
package org.deviceconnect.android.deviceplugin.host.recorder.util;
22

33
import android.annotation.TargetApi;
44
import android.content.ContentResolver;
@@ -30,7 +30,7 @@
3030
/**
3131
* メディア共有ロジック.
3232
*/
33-
abstract class MediaSharing {
33+
public abstract class MediaSharing {
3434

3535
/**
3636
* ログ出力用タグ.
@@ -59,6 +59,9 @@ public abstract Uri shareVideo(final @NonNull Context context,
5959
final @NonNull File videoFile,
6060
final @NonNull FileManager fileManager);
6161

62+
public abstract Uri shareAudio(final @NonNull Context context,
63+
final @NonNull File audioFile);
64+
6265
/**
6366
* 動作環境に合わせたメディア共有ロジックを取得する.
6467
* @return メディア共有ロジックのインスタンス
@@ -213,6 +216,22 @@ boolean updateThumbnailInfo(final @NonNull Context context,
213216
int result = resolver.update(uri, values, where, args);
214217
return result == 1;
215218
}
219+
220+
@Override
221+
public Uri shareAudio(@NonNull Context context, @NonNull File audioFile) {
222+
if (checkMediaFile(audioFile)) {
223+
// Contents Providerに登録.
224+
ContentResolver resolver = context.getContentResolver();
225+
ContentValues values = new ContentValues();
226+
values.put(MediaStore.Video.Media.TITLE, audioFile.getName());
227+
values.put(MediaStore.Video.Media.DISPLAY_NAME, audioFile.getName());
228+
values.put(MediaStore.Video.Media.ARTIST, "DeviceConnect");
229+
values.put(MediaStore.Video.Media.MIME_TYPE, "audio/mp3");
230+
values.put(MediaStore.Video.Media.DATA, audioFile.toString());
231+
resolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
232+
}
233+
return null;
234+
}
216235
}
217236

218237
@TargetApi(29)
@@ -276,7 +295,7 @@ public Uri shareVideo(final @NonNull Context context,
276295
values.put(MediaStore.Video.Media.DISPLAY_NAME, videoFile.getName());
277296
values.put(MediaStore.Video.Media.ARTIST, "DeviceConnect");
278297
values.put(MediaStore.Video.Media.MIME_TYPE, "video/avc");
279-
values.put(MediaStore.Images.Media.IS_PENDING, 1);
298+
values.put(MediaStore.Video.Media.IS_PENDING, 1);
280299
Uri uri = resolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values);
281300
if (uri == null) {
282301
return null;
@@ -301,7 +320,7 @@ public Uri shareVideo(final @NonNull Context context,
301320
}
302321

303322
values.clear();
304-
values.put(MediaStore.Images.Media.IS_PENDING, 0);
323+
values.put(MediaStore.Video.Media.IS_PENDING, 0);
305324
resolver.update(uri, values, null, null);
306325

307326
try {
@@ -325,5 +344,50 @@ public Uri shareVideo(final @NonNull Context context,
325344
}
326345
return null;
327346
}
347+
348+
@Override
349+
public Uri shareAudio(@NonNull Context context, @NonNull File audioFile) {
350+
if (checkMediaFile(audioFile)) {
351+
ContentResolver resolver = context.getContentResolver();
352+
ContentValues values = new ContentValues();
353+
values.put(MediaStore.Audio.Media.DISPLAY_NAME, audioFile.getName());
354+
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/aac");
355+
values.put(MediaStore.Audio.Media.IS_PENDING, 1);
356+
Uri collection = MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
357+
Uri uri = resolver.insert(collection, values);
358+
if (uri == null) {
359+
Log.e(TAG, "Failed to share audio: not inserted to media store: path = " + audioFile.getAbsolutePath());
360+
return null;
361+
}
362+
363+
try (InputStream in = new FileInputStream(audioFile);
364+
OutputStream out = resolver.openOutputStream(uri))
365+
{
366+
if (out == null) {
367+
Log.e(TAG, "Failed to share audio: no output stream: path = " + audioFile.getAbsolutePath());
368+
return null;
369+
}
370+
byte[] buf = new byte[1024];
371+
int len;
372+
while ((len = in.read(buf)) > 0) {
373+
out.write(buf, 0, len);
374+
}
375+
out.flush();
376+
} catch (FileNotFoundException e) {
377+
throw new IllegalStateException(e);
378+
} catch (IOException e) {
379+
Log.e(TAG, "Failed to share audio: I/O error: path = " + audioFile.getAbsolutePath(), e);
380+
return null;
381+
}
382+
383+
values.clear();
384+
values.put(MediaStore.Audio.Media.IS_PENDING, 0);
385+
resolver.update(uri, values, null, null);
386+
return uri;
387+
} else {
388+
Log.e(TAG, "Failed to share audio: file not found: path = " + audioFile.getAbsolutePath());
389+
}
390+
return null;
391+
}
328392
}
329393
}

0 commit comments

Comments
 (0)