ATS-812: PoC FFmpeg skeleton - experiments

- add PoC option to convert from mp4 to either image/png or image/png
- single frame based on timeOffset param (example format "00:00:00.5")
- transform option names & support mimetypes subject to change
- requires detailed design + (unit) regression tests

- see also MM-156
This commit is contained in:
Jan Vonka
2021-03-30 16:36:01 +01:00
parent d0d1fd8cdb
commit b8c1463b35
6 changed files with 61 additions and 8 deletions

View File

@@ -10,6 +10,8 @@
<tr><td><div style="text-align:right">timeout</div></td><td><input type="text" name="timeout" value="" /></td></tr>
<tr><td><div style="text-align:right">testDelay</div></td><td><input type="text" name="testDelay" value="" /></td></tr>
<tr><td><div style="text-align:right">timeOffset</div></td><td><input type="text" name="timeOffset" value="" /></td></tr>
<tr><td></td><td><input type="submit" value="Transform" /></td></tr>
</table>
</form>

View File

@@ -1,12 +1,20 @@
{
"transformOptions": {
"ffmpegOptions": [
{"value": {"name": "timeOffset"}}
]
},
"transformers": [
{
"transformerName": "ffmpeg",
"supportedSourceAndTargetList": [
{"sourceMediaType": "video/mp4", "targetMediaType": "video/avi" },
{"sourceMediaType": "video/mp4", "targetMediaType": "audio/mpeg" }
{"sourceMediaType": "video/mp4", "targetMediaType": "audio/mpeg" },
{"sourceMediaType": "video/mp4", "targetMediaType": "image/png" },
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" }
],
"transformOptions": [
"ffmpegOptions"
]
}
]

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
@@ -36,13 +36,38 @@ import java.util.StringJoiner;
// TODO PoC for FFmpeg
public final class FFmpegOptionsBuilder
{
private String timeOffset;
private Integer framesNum;
// TODO PoC - add FFmpeg options ...
private FFmpegOptionsBuilder() {}
public FFmpegOptionsBuilder withTimeOffset(final String timeOffset)
{
this.timeOffset = timeOffset;
return this;
}
public FFmpegOptionsBuilder withFramesNum(final Integer framesNum)
{
this.framesNum = framesNum;
return this;
}
public String build()
{
StringJoiner args = new StringJoiner(" ");
if (timeOffset != null)
{
args.add("-ss "+timeOffset);
}
if (framesNum != null)
{
args.add("-frames:v "+framesNum);
}
return args.toString();
}

View File

@@ -2,7 +2,7 @@
* #%L
* Alfresco Transform Core
* %%
* Copyright (C) 2005 - 2020 Alfresco Software Limited
* Copyright (C) 2005 - 2021 Alfresco Software Limited
* %%
* This file is part of the Alfresco software.
* -
@@ -33,7 +33,9 @@ import java.io.File;
import java.util.HashMap;
import java.util.Map;
import static org.alfresco.transformer.util.RequestParamMap.START_PAGE;
import static org.alfresco.transformer.util.RequestParamMap.TIMEOUT;
import static org.alfresco.transformer.util.RequestParamMap.TIME_OFFSET;
import static org.alfresco.transformer.util.Util.stringToLong;
/**
@@ -50,6 +52,8 @@ public class FFmpegCommandExecutor extends AbstractCommandExecutor
private final String EXE;
private final int FRAMES_NUM_1 = 1;
public FFmpegCommandExecutor(String exe)
{
if (exe == null || exe.isEmpty())
@@ -75,7 +79,7 @@ public class FFmpegCommandExecutor extends AbstractCommandExecutor
// TODO PoC for FFmpeg - check against Gytheio: -y SPLIT:${sourceOptions} -i ${source} SPLIT:${targetOptions} ${target}
commandsAndArguments.put(".*",
new String[]{EXE, "-y", "-i", "SPLIT:${options}", "${source}", "${target}"});
new String[]{EXE, "-y", "-i", "${source}", "SPLIT:${options}", "${target}"});
runtimeExec.setCommandsAndArguments(commandsAndArguments);
@@ -103,9 +107,17 @@ public class FFmpegCommandExecutor extends AbstractCommandExecutor
Map<String, String> transformOptions,
File sourceFile, File targetFile) throws TransformException
{
final String options = FFmpegOptionsBuilder
.builder()
.build();
FFmpegOptionsBuilder optionsBuilder = FFmpegOptionsBuilder.builder();
String timeOffset = transformOptions.get(TIME_OFFSET);
if (timeOffset != null)
{
// TODO check target mimetype (to be supported image formats) for "single frame" option
optionsBuilder.withTimeOffset(transformOptions.get(TIME_OFFSET));
optionsBuilder.withFramesNum(FRAMES_NUM_1);
}
final String options = optionsBuilder.build();
Long timeout = stringToLong(transformOptions.get(TIMEOUT));

View File

@@ -1,6 +1,7 @@
{
"transformOptions": {
"ffmpegOptions": [
{"value": {"name": "timeOffset"}}
]
},
"transformers": [
@@ -8,7 +9,9 @@
"transformerName": "ffmpeg",
"supportedSourceAndTargetList": [
{"sourceMediaType": "video/mp4", "targetMediaType": "video/avi" },
{"sourceMediaType": "video/mp4", "targetMediaType": "audio/mpeg" }
{"sourceMediaType": "video/mp4", "targetMediaType": "audio/mpeg" },
{"sourceMediaType": "video/mp4", "targetMediaType": "image/png" },
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" }
],
"transformOptions": [
"ffmpegOptions"

View File

@@ -72,4 +72,7 @@ public interface RequestParamMap
String INCLUDE_CONTENTS = "includeContents";
String NOT_EXTRACT_BOOKMARK_TEXT = "notExtractBookmarksText";
String PAGE_LIMIT = "pageLimit";
// TODO PoC for FFmpeg
String TIME_OFFSET = "timeOffset";
}