Unverified Commit 70e4e7bc authored by Sebastian Schüpbach's avatar Sebastian Schüpbach
Browse files

transform images into jp2


Signed-off-by: Sebastian Schüpbach's avatarSebastian Schüpbach <sebastian.schuepbach@unibas.ch>
parent daca005c
Pipeline #11936 failed with stages
in 2 minutes and 26 seconds
.idea/
target/
src/test/resources/test.*
src/test/resources/test*.*
\ No newline at end of file
......@@ -23,7 +23,11 @@ test:
stage: test
tags: [mbr]
before_script:
- apt-get update && apt-get install -y ffmpeg
- apt-get update && apt-get install -y ffmpeg imagemagick
- wget https://kakadusoftware.com/wp-content/uploads/2020/06/KDU805_Demo_Apps_for_Linux-x86-64_200602.zip
- unzip KDU805_Demo_Apps_for_Linux-x86-64_200602.zip && cd KDU805_Demo_Apps_for_Linux-x86-64_200602/ && mv kdu_compress libkdu_v80R.so ../ && cd ..
- export PATH=$PATH:`pwd`
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`
script:
- sbt test
......
......@@ -69,15 +69,13 @@ class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, vid
* @param destId Filename of dissemination copy without extension
* @return
*/
def createAudioCopy(data: ByteArrayOutputStream, destId: String): Try[Path] = {
Try {
val tempFilePath = Files.createTempFile("media-", null)
val destFile = Paths.get(audioDestPath, destId + ".mp4")
writeData(data, tempFilePath)
Transformations.mp3ToMp4(tempFilePath.toString, destFile.toString).get
Files.delete(tempFilePath)
destFile
}
def createAudioCopy(data: ByteArrayOutputStream, destId: String): Try[Path] = Try {
val tempFilePath = Files.createTempFile("media-", null)
val destFile = Paths.get(audioDestPath, destId + ".mp4")
writeData(data, tempFilePath)
Transformations.audioToMp4(tempFilePath.toString, destFile.toString).get
Files.delete(tempFilePath)
destFile
}
/**
......@@ -87,10 +85,12 @@ class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, vid
* @param destId Filename of dissemination copy without extension
* @return
*/
def createImageCopy(data: ByteArrayOutputStream, destId: String): Try[Path] = {
// TODO: Implement transcoding
def createImageCopy(data: ByteArrayOutputStream, destId: String): Try[Path] = Try {
val tempFilePath = Files.createTempFile("media-", null)
val destFile = Paths.get(imageDestPath, destId + ".jp2")
writeData(data, destFile)
Transformations.imageToJp2(tempFilePath.toString, destFile.toString).get
Files.delete(tempFilePath)
destFile
}
/**
......
......@@ -19,6 +19,7 @@
package ch.memobase
import java.io.IOException
import java.nio.file.Files
import org.apache.logging.log4j.scala.Logging
......@@ -31,7 +32,7 @@ object Transformations extends Logging {
import sys.process._
private def wrapCommand(command: String): Try[Int] = Try {
private def executeCommand(command: String): Try[Int] = Try {
val stderr = StringBuilder.newBuilder
val errorCode = command ! ProcessLogger(logger.debug(_), stderr append _)
if (errorCode > 0) {
......@@ -42,18 +43,38 @@ object Transformations extends Logging {
}
/**
* Repacks MP3 files in a MP4 container and adds a moov atom at the beginning of the file
* Repacks audio files in a MP4 container and adds a moov atom at the beginning of the file
*
* @param sourceFilePath Path to the temporary file
* @param sourceFilePath Path to the source file
* @param destFilePath Path to the final file
* @return
*/
def mp3ToMp4(sourceFilePath: String, destFilePath: String): Try[String] = {
def audioToMp4(sourceFilePath: String, destFilePath: String): Try[String] = {
val externalCommand = s"ffmpeg -i $sourceFilePath -acodec copy -loglevel warning -hide_banner -y -movflags faststart $destFilePath"
Try {
wrapCommand(externalCommand).get
executeCommand(externalCommand).get
destFilePath
}
}
/**
* Converts image file to jpeg2000
*
* @param sourceFilePath Path to the source file
* @param destFilePath Path to the final file
* @return
*/
def imageToJp2(sourceFilePath: String, destFilePath: String): Try[String] = Try {
val intermediaryFile = Files.createTempFile("image-", ".tif")
val imagemagickCommand = s"convert -format tif -compress none $sourceFilePath ${intermediaryFile.toString}"
val kduCompressCommand = s"kdu_compress -i ${intermediaryFile.toString} -o $destFilePath -rate 3 -flush_period 1024 -quiet Creversible=no Clevels=6 Clayers=6 Cprecincts={256,256},{256,256},{128,128} Corder=RPCL Cuse_sop=yes Cuse_eph=yes Cblk={64,64} ORGgen_plt=yes ORGtparts=R Stiles={512,512}"
try {
executeCommand(imagemagickCommand).get
executeCommand(kduCompressCommand).get
} finally {
Files.delete(intermediaryFile)
}
destFilePath
}
}
......@@ -24,18 +24,43 @@ import org.scalatest.funsuite.AnyFunSuite
class TransformationsTest extends AnyFunSuite {
private def appExists(name: String): Boolean = {
import sys.process._
(name !) == 0
}
test("Sample mp3 should be transformed correctly") {
val outFile = Files.createTempFile(Paths.get("src/test/resources"), "test-", ".mp4")
val res = Transformations.mp3ToMp4("src/test/resources/sample.mp3", outFile.toString)
outFile.toFile.delete()
assert(res.get == outFile.toString)
if (appExists("ffmpeg -version")) {
val outFile = Files.createTempFile(Paths.get("src/test/resources"), "test-", ".mp4")
val res = Transformations.audioToMp4("src/test/resources/sample.mp3", outFile.toString)
outFile.toFile.delete()
assert(res.get == outFile.toString)
} else {
println("No ffmpeg binary found in $PATH")
}
}
test("Conversion of nonexistent mp3 should abort with error") {
val outFile = Files.createTempFile(Paths.get("src/test/resources"), "test-", ".mp4")
val res = Transformations.mp3ToMp4("src/test/resources/null.mp3", outFile.toString)
outFile.toFile.delete()
assert(res.isFailure)
if (appExists("ffmpeg -version")) {
val outFile = Files.createTempFile(Paths.get("src/test/resources"), "test-", ".mp4")
val res = Transformations.audioToMp4("src/test/resources/null.mp3", outFile.toString)
outFile.toFile.delete()
assert(res.isFailure)
} else {
println("No ffmpeg binary found in $PATH")
}
}
test("Sample jpeg should be transformed into jp2") {
if (appExists("kdu_compress -v") && appExists("convert -version")) {
val outFile = Files.createTempFile(Paths.get("src/test/resources"), "test-", ".jp2")
val res = Transformations.imageToJp2("src/test/resources/sample.jpg", outFile.toString)
outFile.toFile.delete()
assert(res.isSuccess, res)
} else if (!appExists("kdu_compress -v"))
println("No kdu_compress binary found in $PATH")
else if (!appExists("convert -version"))
println("No convert binary found in $PATH")
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment