-
Notifications
You must be signed in to change notification settings - Fork 891
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] share ayah as audio #2011
Changes from 10 commits
b2809b6
4a53d7f
435ab83
34b6fd2
bdfa882
aa873a1
4162f19
4fdceae
2880ebf
47727e5
cf84a95
168a044
e85760c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -102,9 +102,11 @@ | |
android:authorities="@string/file_authority" | ||
android:grantUriPermissions="true" | ||
android:exported="false"> | ||
tools:replace="android:authorities"> | ||
<meta-data | ||
android:name="android.support.FILE_PROVIDER_PATHS" | ||
android:resource="@xml/file_paths"/> | ||
android:resource="@xml/file_paths" | ||
tools:replace="android:resource" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and this |
||
</provider> | ||
|
||
<receiver android:name="androidx.media.session.MediaButtonReceiver"> | ||
|
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,25 @@ package com.quran.labs.androidquran.util | |
|
||
import android.content.Context | ||
import android.content.Intent | ||
import android.media.MediaMetadataRetriever | ||
import android.net.Uri | ||
import androidx.annotation.VisibleForTesting | ||
import androidx.core.content.ContextCompat.startActivity | ||
import androidx.core.content.FileProvider | ||
import com.quran.data.core.QuranInfo | ||
import com.quran.data.model.SuraAyah | ||
import com.quran.labs.androidquran.common.audio.model.AudioConfiguration | ||
import com.quran.labs.androidquran.common.audio.model.QariItem | ||
import com.quran.labs.androidquran.common.audio.util.QariUtil | ||
import com.quran.labs.androidquran.dao.audio.AudioPathInfo | ||
import com.quran.labs.androidquran.service.AudioService | ||
import com.quran.labs.androidquran.ui.PagerActivity | ||
import com.quran.labs.androidquran.util.audioConversionUtils.CheapSoundFile | ||
import timber.log.Timber | ||
import java.io.File | ||
import java.util.Locale | ||
import java.io.* | ||
import java.util.* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please let's not use star imports There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have fixed this in the latest commit |
||
import javax.inject.Inject | ||
import kotlin.math.roundToInt | ||
|
||
class AudioUtils @Inject constructor( | ||
private val quranInfo: QuranInfo, | ||
|
@@ -283,6 +291,101 @@ class AudioUtils @Inject constructor( | |
} | ||
} | ||
|
||
fun getLocalAudioPathInfo(qari: QariItem): AudioPathInfo? { | ||
val localPath = getLocalQariUrl(qari) | ||
if (localPath != null) { | ||
val databasePath = getQariDatabasePathIfGapless(qari) | ||
val urlFormat = if (databasePath.isNullOrEmpty()) { | ||
localPath + File.separator + "%d" + File.separator + | ||
"%d" + AUDIO_EXTENSION | ||
} else { | ||
localPath + File.separator + "%03d" + AUDIO_EXTENSION | ||
} | ||
return AudioPathInfo(urlFormat, localPath, databasePath) | ||
} | ||
return null | ||
} | ||
|
||
fun getMergedAudioFromSegments(segments: ArrayList<String>): String { | ||
var mergedAudioPath = segments[0] | ||
if (segments.size > 1) { | ||
for (i in 1 until segments.size) { | ||
mergedAudioPath = mergeAudios(mergedAudioPath, segments[i])!! | ||
} | ||
} | ||
return mergedAudioPath | ||
} | ||
|
||
private fun mergeAudios(path1: String, path2: String): String? { | ||
val tempAudioName = UUID.randomUUID().toString() + ".mp3" | ||
val destFile = File(PagerActivity.audioCacheDirectory.path + File.separator + tempAudioName) | ||
try { | ||
val fileInputStream = FileInputStream(path1) | ||
val bArr = ByteArray(1048576) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. constant - also what's relevant about this number here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is 1 MB (1024*1024 bytes), but I have removed this in favor of "Okio" |
||
val fileOutputStream = FileOutputStream(destFile) | ||
while (true) { | ||
val read = fileInputStream.read(bArr) | ||
if (read == -1) { | ||
break | ||
} | ||
fileOutputStream.write(bArr, 0, read) | ||
fileOutputStream.flush() | ||
} | ||
fileInputStream.close() | ||
val fileInputStream2 = FileInputStream(path2) | ||
while (true) { | ||
val read2 = fileInputStream2.read(bArr) | ||
if (read2 == -1) { | ||
break | ||
} | ||
fileOutputStream.write(bArr, 0, read2) | ||
fileOutputStream.flush() | ||
} | ||
fileInputStream2.close() | ||
fileOutputStream.close() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have okio in the code that might simplify this logic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
return destFile.path | ||
} catch (e2: FileNotFoundException) { | ||
e2.printStackTrace() | ||
} catch (e: IOException) { | ||
e.printStackTrace() | ||
} | ||
return null | ||
} | ||
|
||
fun getSurahSegment(path: String, lowerCut: Int, upperCut: Int): String? { | ||
if (lowerCut == 0 && upperCut == 0) { | ||
return null | ||
} | ||
val tempAudioName = UUID.randomUUID().toString() + ".mp3" | ||
val destFile = File(PagerActivity.audioCacheDirectory.path + File.separator + tempAudioName) | ||
val mSoundFile = arrayOfNulls<CheapSoundFile>(1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit - please avoid m prefix on variables There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
try { | ||
mSoundFile[0] = CheapSoundFile.create(path, null) | ||
val startTime = lowerCut.toFloat() / 1000 | ||
val endTime = upperCut.toFloat() / 1000 | ||
val samplesPerFrame = mSoundFile[0]?.samplesPerFrame | ||
val sampleRate = mSoundFile[0]?.sampleRate | ||
val avg = sampleRate?.div(samplesPerFrame!!) | ||
val startFrames = (startTime * avg!!).roundToInt() | ||
val endFrames = (endTime * avg).roundToInt() | ||
mSoundFile[0]?.WriteFile(destFile, startFrames, endFrames - startFrames) | ||
} catch (e: IOException) { | ||
e.printStackTrace() | ||
} | ||
return destFile.absolutePath | ||
} | ||
|
||
fun getSurahDuration(context: Context,path: String): Int { | ||
val mmr = MediaMetadataRetriever() | ||
mmr.setDataSource(context, Uri.parse(path)) | ||
val durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION) | ||
return durationStr!!.toInt() | ||
} | ||
|
||
fun getSurahAudioPath(audioPathInfo: AudioPathInfo, surah: Int): String? { | ||
return String.format(Locale.US, audioPathInfo.urlFormat, surah) | ||
} | ||
|
||
companion object { | ||
const val ZIP_EXTENSION = ".zip" | ||
const val AUDIO_EXTENSION = ".mp3" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did we need to add this?