Skip to content

Instantly share code, notes, and snippets.

@busches
Created July 20, 2021 01:59
Show Gist options
  • Save busches/b3717ac6e56ef0acb97376719399a7b8 to your computer and use it in GitHub Desktop.
Save busches/b3717ac6e56ef0acb97376719399a7b8 to your computer and use it in GitHub Desktop.
Check if a video will play in the Pacifica
import org.w3c.dom.Document
import org.xml.sax.InputSource
import java.io.File
import java.io.IOException
import java.io.StringReader
import java.math.BigInteger
import java.util.concurrent.TimeUnit
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.xpath.XPathConstants
import javax.xml.xpath.XPathFactory
fun main() {
val factory = XPathFactory.newInstance()
val xpath = factory.newXPath()
val gigaByte = (1024 * 1024 * 1024).toBigInteger()
val maxFileSize: BigInteger = BigInteger("4").times(gigaByte)
File("/media/movies")
.walkTopDown()
//.maxDepth(3)
.filter { arrayOf("mkv", "mp4", "m4v", "avi").contains(it.extension) }
.sorted()
.map {
println(it.absolutePath)
it
}
.mapNotNull {
val command = arrayListOf("mediainfo", it.absolutePath, "--Output=XML")
command.runCommand()
}
.map(::parseXML)
.forEach {
// println(xpath.compile("/MediaInfo/media/@ref").evaluate(it, XPathConstants.STRING))
val trackCount = xpath.compile("count(/MediaInfo/media/track)").evaluate(it, XPathConstants.NUMBER) as Double
for (track in 1..trackCount.toInt()) {
val type = xpath.compile("/MediaInfo/media/track[$track]/@type").evaluate(it, XPathConstants.STRING) as String
if (type == "Audio") {
val format = xpath.compile("/MediaInfo/media/track[$track]/Format").evaluate(it, XPathConstants.STRING) as String
val language = xpath.compile("/MediaInfo/media/track[$track]/Language").evaluate(it, XPathConstants.STRING) as String
if (!arrayOf("AAC", "MPEG Audio").contains(format)) {
println("INVALID AUDIO FORMAT - '$format'")
}
if (language.toUpperCase() != "EN") {
println("INVALID AUDIO LANGUAGE - '$language'")
}
} else if (type == "Video") {
val height = Integer.valueOf(xpath.compile("/MediaInfo/media/track[$track]/Height").evaluate(it, XPathConstants.STRING) as String)
val width = Integer.valueOf(xpath.compile("/MediaInfo/media/track[$track]/Width").evaluate(it, XPathConstants.STRING) as String)
if (width > 1280 || height > 720) {
println("INVALID VIDEO SIZE - ${width}x${height}")
}
} else if (type == "General") {
val fileSize = (xpath.compile("/MediaInfo/media/track[$track]/FileSize").evaluate(it, XPathConstants.STRING) as String).toBigInteger()
if (fileSize > maxFileSize) {
println("INVALID FILE SIZE - ${fileSize.divide(gigaByte)} GB")
}
}
}
}
}
/* 1280x800 is screen size
Smaller than 4GB
Audio codecs that work:
ACC
FLAC
MP3 (lame VBR)
16bit PCM (WAV format)
24bit PCM (WAV format)
No idea why you would want WAV, but it works. Note I did not try FLAC in a flac file, just in a MKV and AVI file. Both 96kHz and 24bit work as well. I did not have a HE-AAC encoder, so that is still unknown.
Audio codecs that do NOT work:
AC3
DTS/DCA
Enhanced AC3
Vorbis
MPEG1 layer 2 (mp2)
Opus
Speex
*/
fun List<String>.runCommand(): String? {
return try {
ProcessBuilder(this)
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectError(ProcessBuilder.Redirect.PIPE)
.start().apply {
waitFor(10, TimeUnit.SECONDS)
}
.inputStream.bufferedReader().readText()
} catch (e: IOException) {
e.printStackTrace()
null
}
}
fun parseXML(rawXML: String): Document {
val dbFactory = DocumentBuilderFactory.newInstance()
val dBuilder = dbFactory.newDocumentBuilder()
val xmlInput = InputSource(StringReader(rawXML))
return dBuilder.parse(xmlInput)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment