Skip to content

Commit

Permalink
Expose a single chapter reader file and make all other components of the
Browse files Browse the repository at this point in the history
chapter-reader module internal.
  • Loading branch information
PaulWoitaschek committed Jul 30, 2017
1 parent a07ddba commit c4ba714
Show file tree
Hide file tree
Showing 29 changed files with 85 additions and 64 deletions.
18 changes: 3 additions & 15 deletions app/src/main/java/de/ph1b/audiobook/features/BookAdder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import android.support.v4.content.ContextCompat
import d
import de.ph1b.audiobook.Book
import de.ph1b.audiobook.Chapter
import de.ph1b.audiobook.chapterreader.id3.ID3ChapterReader
import de.ph1b.audiobook.chapterreader.matroska.MatroskaChapterReader
import de.ph1b.audiobook.chapterreader.mp4.Mp4ChapterReader
import de.ph1b.audiobook.chapterreader.ogg.OggChapterReader
import de.ph1b.audiobook.chapterreader.ChapterReader
import de.ph1b.audiobook.misc.*
import de.ph1b.audiobook.persistence.BookRepository
import de.ph1b.audiobook.persistence.PrefsManager
Expand All @@ -38,10 +35,7 @@ import javax.inject.Singleton
private val repo: BookRepository,
private val coverCollector: CoverFromDiscCollector,
private val mediaAnalyzer: MediaAnalyzer,
private val mp4ChapterReader: Mp4ChapterReader,
private val matroskaChapterReader: MatroskaChapterReader,
private val iD3ChapterReader: ID3ChapterReader,
private val oggChapterReader: OggChapterReader
private val chapterReader: ChapterReader
) {

private val executor = Executors.newSingleThreadExecutor()
Expand Down Expand Up @@ -319,13 +313,7 @@ import javax.inject.Singleton
val result = mediaAnalyzer.analyze(f)
.blockingGet()
if (result is MediaAnalyzer.Result.Success) {
val marks = when (f.extension) {
"mp3" -> iD3ChapterReader.read(f)
"mp4", "m4a", "m4b", "aac" -> mp4ChapterReader.readChapters(f)
"opus", "ogg", "oga" -> oggChapterReader.read(f)
"mka", "mkv", "webm" -> matroskaChapterReader.read(f)
else -> emptyMap()
}.toSparseArray()
val marks = chapterReader.read(f).toSparseArray()
containingMedia.add(Chapter(f, result.chapterName, result.duration, lastModified, marks))
}
throwIfStopRequested()
Expand Down
8 changes: 3 additions & 5 deletions app/src/main/java/de/ph1b/audiobook/misc/androidExtensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,14 @@ fun <T> SparseArray<T>.equalsTo(other: SparseArray<T>): Boolean {
}

fun <T> Map<Int, T>.toSparseArray(): SparseArray<T> {
if (isEmpty())
return emptySparseArray()

val array = SparseArray<T>(size)
forEach { (key, value) ->
array.put(key, value)
}
return array
}

val <T> SparseArray<T>.values
get() = (0..size() - 1).map { valueAt(it) }

fun SparseArray<*>.keyAtOrNull(index: Int) = if (index >= size()) null else keyAt(index)

fun SparseArray<*>.isNotEmpty() = size() > 0
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package de.ph1b.audiobook.chapterreader

import dagger.Reusable
import de.ph1b.audiobook.chapterreader.id3.ID3ChapterReader
import de.ph1b.audiobook.chapterreader.matroska.MatroskaChapterReader
import de.ph1b.audiobook.chapterreader.mp4.Mp4ChapterReader
import de.ph1b.audiobook.chapterreader.ogg.OggChapterReader
import java.io.File
import javax.inject.Inject


@Reusable class ChapterReader @Inject internal constructor(
private val oggReader: OggChapterReader,
private val mp4Reader: Mp4ChapterReader,
private val matroskaReader: MatroskaChapterReader,
private val id3Reader: ID3ChapterReader
) {

fun read(file: File): Map<Int, String> = when (file.extension) {
"mp3" -> id3Reader.read(file)
"mp4", "m4a", "m4b", "aac" -> mp4Reader.readChapters(file)
"opus", "ogg", "oga" -> oggReader.read(file)
"mka", "mkv", "webm" -> matroskaReader.read(file)
else -> emptyMap()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package de.ph1b.audiobook.chapterreader.id3

internal data class ChapterMetaData(
var id3ID: String,
var start: Int,
var title: String? = null
)
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.ph1b.audiobook.chapterreader.id3


sealed class Header {
internal sealed class Header {

abstract val id: String
abstract val size: Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ private const val FRAME_ID_TITLE = "TIT2"
* Original source from [AntennaPod](https://github.com/AntennaPod/AntennaPod/tree/develop/core/src/main/java/de/danoeh/antennapod/core/util/id3reader)
* Licensed under Apache 2.0
*/
@Reusable class ID3ChapterReader @Inject constructor(private val logger: Logger) {
@Reusable internal class ID3ChapterReader @Inject constructor(private val logger: Logger) {

private val chapters = ArrayList<ChapterMetaData>()
private var readerPosition: Int = 0
Expand Down Expand Up @@ -268,5 +268,4 @@ private const val FRAME_ID_TITLE = "TIT2"
}
}

data class ChapterMetaData(var id3ID: String, var start: Int, var title: String? = null)
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package de.ph1b.audiobook.chapterreader.id3

class ID3ReaderException(message: String) : Exception(message)
internal class ID3ReaderException(message: String) : Exception(message)

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.ph1b.audiobook.chapterreader.matroska

data class MatroskaChapter(
internal data class MatroskaChapter(
val startTime: Long,
val names: List<MatroskaChapterName>,
val children: List<MatroskaChapter>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package de.ph1b.audiobook.chapterreader.matroska


object MatroskaChapterFlattener {
internal object MatroskaChapterFlattener {

private lateinit var target: MutableMap<Int, String>
private lateinit var preferredLanguages: List<String>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package de.ph1b.audiobook.chapterreader.matroska

data class MatroskaChapterName(val name: String, val languages: Set<String>)
internal data class MatroskaChapterName(val name: String, val languages: Set<String>)
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import dagger.Reusable
import de.ph1b.audiobook.common.Logger
import java.io.File
import java.lang.RuntimeException
import java.util.Locale
import java.util.*
import javax.inject.Inject

@Reusable class MatroskaChapterReader @Inject constructor(
@Reusable internal class MatroskaChapterReader @Inject constructor(
private val logger: Logger,
private val readAsMatroskaChapters: ReadAsMatroskaChapters
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package de.ph1b.audiobook.chapterreader.matroska

import java.lang.RuntimeException

class MatroskaParseException(message: String) : RuntimeException(message)
internal class MatroskaParseException(message: String) : RuntimeException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@ package de.ph1b.audiobook.chapterreader.matroska

import dagger.Reusable
import de.ph1b.audiobook.common.Logger
import org.ebml.EBMLReader
import org.ebml.Element
import org.ebml.MasterElement
import org.ebml.ProtoType
import org.ebml.StringElement
import org.ebml.UnsignedIntegerElement
import org.ebml.*
import org.ebml.io.FileDataSource
import org.ebml.matroska.MatroskaDocTypes
import java.io.File
import javax.inject.Inject


@Reusable class ReadAsMatroskaChapters @Inject constructor(private val logger: Logger) {
@Reusable internal class ReadAsMatroskaChapters @Inject constructor(private val logger: Logger) {

private lateinit var dataSource: FileDataSource
private lateinit var reader: EBMLReader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,22 @@ package de.ph1b.audiobook.chapterreader.mp4
import java.io.File
import java.io.RandomAccessFile
import java.util.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.List
import kotlin.collections.Map
import kotlin.collections.emptyList
import kotlin.collections.emptyMap
import kotlin.collections.filter
import kotlin.collections.firstOrNull
import kotlin.collections.forEachIndexed
import kotlin.collections.getOrNull
import kotlin.collections.listOf
import kotlin.collections.map

/**
* Reads the chap atom to find associated chapters
*/
object ChapReader {
internal object ChapReader {

fun read(file: File): Map<Int, String> {
val raf = RandomAccessFile(file, "r")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.io.RandomAccessFile
/**
* Reads chapters from the chpl atom
*/
object ChplReader {
internal object ChplReader {

fun read(file: File): Map<Int, String> {
val raf = RandomAccessFile(file, "r")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import javax.inject.Inject
/**
* Reads mp4 chapters
*/
@Reusable class Mp4ChapterReader @Inject constructor(private val errorReporter: ErrorReporter) {
@Reusable internal class Mp4ChapterReader @Inject constructor(private val errorReporter: ErrorReporter) {

fun readChapters(file: File): Map<Int, String> {
val fromChap: Map<Int, String> = try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ package de.ph1b.audiobook.chapterreader.mp4

import java.io.EOFException
import java.io.RandomAccessFile
import java.util.ArrayList
import java.util.*


data class Mp4Atom(val name: String, val position: Long, val length: Long, val children: List<Mp4Atom>)
internal data class Mp4Atom(val name: String, val position: Long, val length: Long, val children: List<Mp4Atom>)

fun RandomAccessFile.atoms(toVisit: List<String>, endOfAtom: Long? = null): List<Mp4Atom> {
internal fun RandomAccessFile.atoms(toVisit: List<String>, endOfAtom: Long? = null): List<Mp4Atom> {
val atoms = ArrayList<Mp4Atom>()
while (true) {
if (filePointer >= length()) break
Expand All @@ -33,7 +33,7 @@ fun RandomAccessFile.atoms(toVisit: List<String>, endOfAtom: Long? = null): List
return atoms
}

fun List<Mp4Atom>.findAtom(vararg path: String): Mp4Atom? {
internal fun List<Mp4Atom>.findAtom(vararg path: String): Mp4Atom? {
if (path.isEmpty()) return null

forEach { root ->
Expand All @@ -52,7 +52,7 @@ fun List<Mp4Atom>.findAtom(vararg path: String): Mp4Atom? {
return firstOrNull { it.name == path.first() }
}

fun RandomAccessFile.readUnsignedInt(): Long =
internal fun RandomAccessFile.readUnsignedInt(): Long =
(read().toLong() and 0xFFL shl 24) or
(read().toLong() and 0xFFL shl 16) or
(read().toLong() and 0xFFL shl 8) or
Expand All @@ -61,10 +61,10 @@ fun RandomAccessFile.readUnsignedInt(): Long =
private val boxHeaderBuffer = ByteArray(4)

@Synchronized
fun RandomAccessFile.readBoxHeader(): String {
internal fun RandomAccessFile.readBoxHeader(): String {
val result = read(boxHeaderBuffer)
if (result == -1) throw EOFException("Can't read box header")
return String(boxHeaderBuffer)
}

fun RandomAccessFile.readUInt64(): Long = (readUnsignedInt() shl 32) + readUnsignedInt()
internal fun RandomAccessFile.readUInt64(): Long = (readUnsignedInt() shl 32) + readUnsignedInt()
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.io.*
import javax.inject.Inject


@Reusable class OggChapterReader @Inject constructor(
@Reusable internal class OggChapterReader @Inject constructor(
private val logger: Logger
) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.ph1b.audiobook.chapterreader.ogg.oggReading

data class OggPage(
internal data class OggPage(
val continuedPacket: Boolean,
val finishedPacket: Boolean,
val firstPageOfStream: Boolean,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package de.ph1b.audiobook.chapterreader.ogg.oggReading

class OggPageParseException(message: String) : Exception(message)
internal class OggPageParseException(message: String) : Exception(message)
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package de.ph1b.audiobook.chapterreader.ogg.oggReading

import java.util.ArrayDeque
import kotlin.Boolean
import kotlin.ByteArray
import kotlin.NoSuchElementException
import kotlin.Unit

class OggStream(private val pullPage: OggStream.() -> Unit) : Iterator<ByteArray> {
internal class OggStream(private val pullPage: OggStream.() -> Unit) : Iterator<ByteArray> {
private val packetsQue = ArrayDeque<ByteArray>()
private val packetBuffer = mutableListOf<ByteArray>()
private var isDone = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package de.ph1b.audiobook.chapterreader.ogg.oggReading
import de.ph1b.audiobook.common.toUInt


object PackageSizeParser {
internal object PackageSizeParser {

fun fromSegmentTable(segmentTable: ByteArray): List<Int> = segmentTable
.map { it.toUInt() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import java.io.InputStream

private val OGG_PAGE_MAGIC = "OggS".toByteArray()

fun readOggPages(stream: InputStream): Sequence<OggPage> {
internal fun readOggPages(stream: InputStream): Sequence<OggPage> {
return generateSequence gen@ {
// https://www.ietf.org/rfc/rfc3533.txt
val capturePattern = try {
Expand Down Expand Up @@ -46,7 +46,7 @@ fun readOggPages(stream: InputStream): Sequence<OggPage> {
}
}

fun Iterable<ByteArray>.concat(): ByteArray {
internal fun Iterable<ByteArray>.concat(): ByteArray {
val res = ByteArray(this.sumBy { it.size })
var idx = 0
for (part in this) {
Expand All @@ -56,7 +56,7 @@ fun Iterable<ByteArray>.concat(): ByteArray {
return res
}

fun demuxOggStreams(oggPages: Sequence<OggPage>): Map<Int, OggStream> {
internal fun demuxOggStreams(oggPages: Sequence<OggPage>): Map<Int, OggStream> {
val it = oggPages.iterator()
val streamMap = HashMap<Int, OggStream>()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package de.ph1b.audiobook.chapterreader.ogg.vorbisComment

class OpusStreamParseException(message: String) : Exception(message)
internal class OpusStreamParseException(message: String) : Exception(message)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package de.ph1b.audiobook.chapterreader.ogg.vorbisComment

data class VorbisComment(val vendor: String, val comments: Map<String, String>) {
internal data class VorbisComment(val vendor: String, val comments: Map<String, String>) {
/**
* Chapters extracted according to https://wiki.xiph.org/Chapter_Extension
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package de.ph1b.audiobook.chapterreader.ogg.vorbisComment

class VorbisCommentParseException(message: String) : Exception(message)
internal class VorbisCommentParseException(message: String) : Exception(message)
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import de.ph1b.audiobook.common.readAmountOfBytes
import de.ph1b.audiobook.common.readLeUInt32
import java.io.InputStream

object VorbisCommentReader {
internal object VorbisCommentReader {

private val VORBIS_COMMENT_CHAPTER_TIME_REGEX = Regex("""(\d+):(\d+):(\d+).(\d+)""")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package de.ph1b.audiobook.chapterreader.ogg.vorbisComment

class VorbisStreamParseException(message: String) : Exception(message)
internal class VorbisStreamParseException(message: String) : Exception(message)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object MatroskaTestFileProvider {

val file = javaClass.classLoader.getResource("matroska/simple.mka").file
val testFile = File(file)
val testFileMatroskaChapters = listOf(
internal val testFileMatroskaChapters = listOf(
MatroskaChapter(0, listOf(
MatroskaChapterName("Part 1", setOf("eng"))
), listOf()),
Expand Down

0 comments on commit c4ba714

Please sign in to comment.