From d97dc031df10693c9b38f22b2819de485d93515b Mon Sep 17 00:00:00 2001 From: tateisu Date: Fri, 19 Jul 2019 17:58:05 +0900 Subject: [PATCH] add aac,3gp,m4a audio format in media attachment --- .idea/dictionaries/tateisu.xml | 2 + app/src/main/AndroidManifest.xml | 12 + .../jp/juggler/subwaytooter/ActCallback.kt | 2 +- .../java/jp/juggler/subwaytooter/ActPost.kt | 230 ++++++++++++------ app/src/main/res/values-he/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 3 +- app/src/main/res/values/strings.xml | 3 +- 7 files changed, 181 insertions(+), 72 deletions(-) diff --git a/.idea/dictionaries/tateisu.xml b/.idea/dictionaries/tateisu.xml index 1d92e17f..74ebdd44 100644 --- a/.idea/dictionaries/tateisu.xml +++ b/.idea/dictionaries/tateisu.xml @@ -34,6 +34,7 @@ flac flexbox foregrounder + ftyp gifv github gmail @@ -45,6 +46,7 @@ idat idempotency ihdr + kddi kenglxn kotlinx mailto diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fed64a39..c7097f5d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -135,6 +135,18 @@ + + + + + + + + + + + + = header.size && data.startWith(header)) return type } - // scan mp3 frame header - loop@ for(i in 0 until nRead - 4) { + + // scan frame header + for(i in 0 until nRead - 8) { + + if(! matchSig(data, i, sigFtyp)) continue + + // 3gpp check + for(s in sig3gp) { + if(matchSig(data, i + 4, s)) return "audio/3gpp" + } + + // m4a check + for(s in sigM4a) { + if(matchSig(data, i + 4, s)) return "audio/m4a" + } + + } + + // scan frame header + loop@ for(i in 0 until nRead - 2) { + + // mpeg frame header val b0 = data[i].toInt() and 255 if(b0 != 255) continue val b1 = data[i + 1].toInt() and 255 if((b1 and 0b11100000) != 0b11100000) continue - // mpegVersionId - when(((b1 shr 3) and 3)) { - 1 -> continue@loop - } + val mpegVersionId = ((b1 shr 3) and 3) + // 00 mpeg 2.5 + // 01 not used + // 10 (mp3) mpeg 2 / (AAC) mpeg-4 + // 11 (mp3) mpeg 1 / (AAC) mpeg-2 - // mpegLayerId - when(((b1 shr 1) and 3)) { - 1 -> { + @Suppress("MoveVariableDeclarationIntoWhen") + val mpegLayerId = ((b1 shr 1) and 3) + // 00 (mp3)not used / (AAC) always 0 + // 01 (mp3)layer III + // 10 (mp3)layer II + // 11 (mp3)layer I + + when(mpegLayerId) { + 0 -> when(mpegVersionId) { + 2, 3 -> return "audio/aac" + + else -> { + } + } + 1 -> when(mpegVersionId) { + 0, 2, 3 -> return "audio/mp3" + + else -> { + } } - - else -> continue@loop } - - return "audio/mp3" } } } catch(ex : Throwable) { @@ -193,16 +270,6 @@ class ActPost : AppCompatActivity(), } return null } - // private void performCameraVideo(){ - // - // try{ - // Intent takeVideoIntent = new Intent( MediaStore.ACTION_VIDEO_CAPTURE ); - // startActivityForResult( takeVideoIntent, REQUEST_CODE_VIDEO ); - // }catch( Throwable ex ){ - // warning.trace( ex ); - // Utils.showToast( this, ex, "opening video app failed." ); - // } - // } ///////////////////////////////////////////////// @@ -422,36 +489,48 @@ class ActPost : AppCompatActivity(), } override fun onActivityResult(requestCode : Int, resultCode : Int, data : Intent?) { - - if(requestCode == REQUEST_CODE_ATTACHMENT_OLD && resultCode == Activity.RESULT_OK) { - checkAttachments(data?.handleGetContentResult(contentResolver)) - - } else if(requestCode == REQUEST_CODE_ATTACHMENT && resultCode == Activity.RESULT_OK) { - checkAttachments(data?.handleGetContentResult(contentResolver)) - } else if(requestCode == REQUEST_CODE_CAMERA) { - - if(resultCode != Activity.RESULT_OK) { - // 失敗したら DBからデータを削除 - val uriCameraImage = this.uriCameraImage - if(uriCameraImage != null) { - contentResolver.delete(uriCameraImage, null, null) - this@ActPost.uriCameraImage = null - } - } else { - // 画像のURL - val uri = data?.data ?: uriCameraImage - if(uri != null) { - addAttachment(uri) - } else { - showToast(this@ActPost, false, "missing image uri") + if(resultCode != RESULT_OK) { + when(requestCode) { + REQUEST_CODE_CAMERA -> { + // 失敗したら DBからデータを削除 + val uriCameraImage = this.uriCameraImage + if(uriCameraImage != null) { + contentResolver.delete(uriCameraImage, null, null) + this@ActPost.uriCameraImage = null + } + } + } + } else { + when(requestCode) { + REQUEST_CODE_ATTACHMENT_OLD -> checkAttachments( + data?.handleGetContentResult( + contentResolver + ) + ) + REQUEST_CODE_ATTACHMENT -> checkAttachments( + data?.handleGetContentResult( + contentResolver + ) + ) + + REQUEST_CODE_CAMERA -> { + // 画像のURL + val uri = data?.data ?: uriCameraImage + if(uri != null) { + addAttachment(uri) + } else { + showToast(this@ActPost, false, "missing image uri") + } + } + + REQUEST_CODE_VIDEO, REQUEST_CODE_SOUND -> data?.data?.let { addAttachment(it) } + + REQUEST_CODE_MUSHROOM -> { + data?.getStringExtra("replace_key")?.let { applyMushroomResult(it) } } } - } else if(requestCode == REQUEST_CODE_VIDEO && resultCode == Activity.RESULT_OK) { - data?.data?.let { addAttachment(it) } - - } else if(requestCode == REQUEST_CODE_MUSHROOM && resultCode == Activity.RESULT_OK) { - data?.getStringExtra("replace_key")?.let { applyMushroomResult(it) } } + super.onActivityResult(requestCode, resultCode, data) } @@ -1460,16 +1539,16 @@ class ActPost : AppCompatActivity(), iv.setImageUrl(pref, Styler.calcIconRound(iv.layoutParams.width), null) } - else ->{ + else -> { val defaultIconId = when(a.type) { TootAttachmentType.Image -> R.drawable.ic_image TootAttachmentType.Video, - TootAttachmentType.GIFV ->R.drawable.ic_videocam - TootAttachmentType.Audio ->R.drawable.ic_music_note + TootAttachmentType.GIFV -> R.drawable.ic_videocam + TootAttachmentType.Audio -> R.drawable.ic_music_note else -> R.drawable.ic_clip } - iv.setDefaultImage(defaultColorIcon(this,defaultIconId)) - iv.setErrorImage(defaultColorIcon(this,defaultIconId)) + iv.setDefaultImage(defaultColorIcon(this, defaultIconId)) + iv.setErrorImage(defaultColorIcon(this, defaultIconId)) iv.setImageUrl(pref, Styler.calcIconRound(iv.layoutParams.width), a.preview_url) } } @@ -1654,9 +1733,6 @@ class ActPost : AppCompatActivity(), // } val a = ActionsDialog() - a.addAction(getString(R.string.image_capture)) { - performCamera() - } a.addAction(getString(R.string.pick_images)) { openAttachmentChooser(R.string.pick_images, "image/*", "video/*") } @@ -1666,12 +1742,24 @@ class ActPost : AppCompatActivity(), a.addAction(getString(R.string.pick_audios)) { openAttachmentChooser(R.string.pick_audios, "audio/*") } + a.addAction(getString(R.string.image_capture)) { + performCamera() + } + a.addAction(getString(R.string.video_capture)) { + performCapture( + REQUEST_CODE_VIDEO, + MediaStore.ACTION_VIDEO_CAPTURE, + "can't open video capture app." + ) + } + a.addAction(getString(R.string.voice_capture)) { + performCapture( + REQUEST_CODE_SOUND, + MediaStore.Audio.Media.RECORD_SOUND_ACTION, + "can't open voice capture app." + ) + } - // a.addAction( getString( R.string.video_capture ), new Runnable() { - // @Override public void run(){ - // performCameraVideo(); - // } - // } ); a.show(this, null) } @@ -2144,9 +2232,7 @@ class ActPost : AppCompatActivity(), } private fun performCamera() { - try { - // カメラで撮影 val filename = System.currentTimeMillis().toString() + ".jpg" val values = ContentValues() values.put(MediaStore.Images.Media.TITLE, filename) @@ -2165,14 +2251,20 @@ class ActPost : AppCompatActivity(), } + private fun performCapture(requestCode : Int, action : String, errorCaption : String) { + try { + startActivityForResult(Intent(action), requestCode) + } catch(ex : Throwable) { + log.trace(ex); + showToast(this, ex, errorCaption) + } + } + private fun preparePermission() { if(Build.VERSION.SDK_INT >= 23) { - // No explanation needed, we can request the permission. - ActivityCompat.requestPermissions( this, - arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE) // Manifest.permission.CAMERA, - , + arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), PERMISSION_REQUEST_CODE ) } else { diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 7ea8548f..0f9601aa 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -31,3 +31,4 @@ עוד סגור את העמודה + diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index aa269dd4..817cb86c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -349,6 +349,8 @@ 画像 画像の不透明度 カメラで撮影 + 動画を記録 + 音声を記録 アカウント切り替えできません。in_reply_toのID変換に失敗しました。 アクセストークン 通常のユーザ認証の代わりにアクセストークンを指定します。(上級者向け) @@ -737,7 +739,6 @@ バージョン %1$s 振動 バッファ中… - 動画の撮影 動画の選択 公開範囲 ダイレクト diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 91e7812e..12706b03 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -232,6 +232,8 @@ Don\'t resize Resize to %1$d pixels Take a picture + Capture a video + Capture a voice Missing app permission to access media. Uploading media attachment… Media attachment was uploaded. @@ -492,7 +494,6 @@ Quote all hashtags \"%1$s\" Parsing response… Pick video - Capture video Already followed. Can\'t get visibility setting in web app. Mastodon 1.6 or later