Unverified Commit 8e392aa6 authored by Sebastian Schüpbach's avatar Sebastian Schüpbach
Browse files

create audio snippet along with audo dissemination file


Signed-off-by: Sebastian Schüpbach's avatarSebastian Schüpbach <sebastian.schuepbach@unibas.ch>
parent 2d2de825
Pipeline #13778 passed with stages
in 11 minutes and 57 seconds
......@@ -32,6 +32,8 @@ spec:
value: /data
- name: VIDEO_SINK_DIR
value: /data
- name: AUDIO_SNIPPET_DURATION
value: "30"
- name: INTERNAL_BASE_URL
value: "http://mb-fd1.memobase.unibas.ch:8080/fcrepo/rest/"
- name: EXTERNAL_BASE_URL
......
......@@ -2,6 +2,7 @@ app:
audioSinkDir: ${AUDIO_SINK_DIR:?system}
imageSinkDir: ${IMAGE_SINK_DIR:?system}
videoSinkDir: ${VIDEO_SINK_DIR:?system}
audioSnippetDuration: ${AUDIO_SNIPPET_DURATION:?system}
internalBaseUrl: ${INTERNAL_BASE_URL:?system}
externalBaseUrl: ${EXTERNAL_BASE_URL:?system}
fedoraUser: ${FEDORA_USER:?system}
......
......@@ -47,7 +47,8 @@ object App extends scala.App with Logging {
val fileHandler = new DisseminationCopyHandler(
settings.getAppSettings.getProperty("audioSinkDir"),
settings.getAppSettings.getProperty("imageSinkDir"),
settings.getAppSettings.getProperty("videoSinkDir"))
settings.getAppSettings.getProperty("videoSinkDir"),
settings.getAppSettings.getProperty("audioSnippetDuration").toInt)
val fCWrapper = FedoraClientWrapper(
settings.getAppSettings.getProperty("internalBaseUrl"),
settings.getAppSettings.getProperty("externalBaseUrl"),
......
......@@ -33,7 +33,7 @@ import scala.util.{Failure, Success, Try}
* @param imageDestPath Path to folder containing image dissemination copies
* @param videoDestPath Path to folder containing video dissemination copies
*/
class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, videoDestPath: String) {
class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, videoDestPath: String, audioSnippetDuration: Int) {
private def writeData(data: ByteArrayOutputStream, destFile: Path): Try[Path] = {
Try(new FileOutputStream(destFile.toFile)) match {
......@@ -63,8 +63,10 @@ class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, vid
def createAudioCopy(data: ByteArrayOutputStream, destId: String, sourceFileType: MediaFileType): Try[Path] = Try {
val tempFilePath = Files.createTempFile("media-", "." + Conversions.getFileTypeExtension(sourceFileType).get)
val destFile = Paths.get(audioDestPath, destId + ".mp4")
val snippetFile = Paths.get(audioDestPath, destId + "-intro." + Conversions.getFileTypeExtension(sourceFileType).get)
writeData(data, tempFilePath)
Transformations.audioToMp4(tempFilePath.toString, destFile.toString).get
Transformations.createAudioSnippet(tempFilePath.toString, snippetFile.toString, audioSnippetDuration)
Files.delete(tempFilePath)
destFile
}
......@@ -108,6 +110,7 @@ class DisseminationCopyHandler(audioDestPath: String, imageDestPath: String, vid
def deleteAudioCopy(destId: String): Try[Boolean] =
Try {
Paths.get(audioDestPath, destId + ".mp4").toFile.delete()
Paths.get(audioDestPath, destId + "-intro.mp3").toFile.delete()
}
/**
......
......@@ -58,6 +58,26 @@ object Transformations extends Logging {
}
}
/**
* Creates an audio snippet used as a base for producing sonograms
*
* @param sourceFilePath Path to the source file
* @param destFilePath Path to the final file
* @param duration Duration of snippet (counts from beginning of track)
* @return
*/
def createAudioSnippet(sourceFilePath: String, destFilePath: String, duration: Int): Try[String] = {
val minutes = (duration / 60) % 60
val hours = (duration / 60 / 60) % 24
val time = "%02d:%02d:%02d".format(hours, minutes, duration % 60)
val copyStream = sourceFilePath.endsWith(".mp3")
val externalCommand = s"ffmpeg -i $sourceFilePath ${if (copyStream) "-acodec copy"} -loglevel warning -hide_banner -y -t $time $destFilePath"
Try {
executeCommand(externalCommand)
destFilePath
}
}
/**
* Converts image file to jpeg2000
*
......
......@@ -33,21 +33,23 @@ class DisseminationCopyHandlerTest extends AnyFunSuite with BeforeAndAfter {
private def fixture = {
new {
val resPath = "src/test/resources"
val fileHandler = new DisseminationCopyHandler(resPath, resPath, resPath)
val fileHandler = new DisseminationCopyHandler(resPath, resPath, resPath, 30)
}
}
after {
val paths = List(
new File("src/test/resources/test.jp2").toPath,
new File("src/test/resources/test.mp4").toPath,
)
for (p <- paths) {
private def deleteFiles(files: String*): Unit = {
for (file <- files) {
val p = new File(file).toPath
Files.deleteIfExists(p)
}
}
private def testCopy(pathToTmpDir: String, sourceFileName: String, destFileName: String, fileType: MediaFileType, copyFun: (ByteArrayOutputStream, String, MediaFileType) => Try[Path]): Assertion = {
private def testCopy(pathToTmpDir: String,
sourceFileName: String,
destFileName: String,
fileType: MediaFileType,
copyFun: (ByteArrayOutputStream, String, MediaFileType)
=> Try[Path]): Assertion = {
val file = Paths.get(pathToTmpDir, sourceFileName).toFile
val data = new ByteArrayOutputStream(file.length().toInt)
val buffer = new Array[Byte](1024)
......@@ -65,23 +67,36 @@ class DisseminationCopyHandlerTest extends AnyFunSuite with BeforeAndAfter {
test("calling the deleteAudio function should delete temporary audio file") {
val f = fixture
val testFile = Files.createFile(Paths.get(f.resPath, "test.mp4"))
val testSnippetFile = Files.createFile(Paths.get(f.resPath, "test-intro.mp3"))
f.fileHandler.deleteAudioCopy("test")
assert(!testFile.toFile.exists())
}
/**
* ATTENTION: Requires that ffmpeg is properly installed!
*/
test("calling the copyAudio function should create temporary file") {
val f = fixture
testCopy(f.resPath, "sample.mp3", "test.mp4", Mp3File, f.fileHandler.createAudioCopy)
deleteFiles("src/test/resources/test.mp4", "src/test/resources/test-intro.mp3")
}
/**
* ATTENTION: Requires that Kakadu and imagemagick are properly installed!
*/
test("calling the copyImage function should create temporary file") {
val f = fixture
testCopy(f.resPath, "sample.jpg", "test.jp2", JpegFile, f.fileHandler.createImageCopy)
deleteFiles("src/test/resources/test.jp2")
}
/**
* ATTENTION: Requires that ffmpeg is properly installed!
*/
test("calling the copyVideo function should create temporary file") {
val f = fixture
testCopy(f.resPath, "sample.mp4", "test.mp4", VideoMpeg4File, f.fileHandler.createVideoCopy)
deleteFiles("src/test/resources/test.mp4")
}
}
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