mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-08-14 17:58:27 +00:00
ATS-812: PoC FFmpeg (experimental)
- remove extra isTransformable check (& related isSupported src/tgt) for now - add mov to mp4 to supported src/tgt config - update lic headers to 2022
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
@@ -44,6 +44,9 @@ import java.util.Arrays;
|
|||||||
|
|
||||||
import static org.alfresco.transformer.logging.StandardMessages.LICENCE;
|
import static org.alfresco.transformer.logging.StandardMessages.LICENCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author janv
|
||||||
|
*/
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||||
public class Application
|
public class Application
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
@@ -39,7 +39,7 @@ import java.util.Collections;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for the Docker based FFmpeg transformer.
|
* Controller for the FFmpeg transformer.
|
||||||
*
|
*
|
||||||
* Status Codes:
|
* Status Codes:
|
||||||
*
|
*
|
||||||
@@ -57,6 +57,8 @@ import java.util.Map;
|
|||||||
* 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
|
* 500 Internal Server Error: Transformer failed to create an output file (the exit code was 0, so there should be some content)
|
||||||
* 500 Internal Server Error: Filename encoding error
|
* 500 Internal Server Error: Filename encoding error
|
||||||
* 507 Insufficient Storage: Failed to store the source file
|
* 507 Insufficient Storage: Failed to store the source file
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
@Controller
|
@Controller
|
||||||
public class FFmpegController extends AbstractTransformerController
|
public class FFmpegController extends AbstractTransformerController
|
||||||
@@ -65,16 +67,6 @@ public class FFmpegController extends AbstractTransformerController
|
|||||||
FFmpegController
|
FFmpegController
|
||||||
.class);
|
.class);
|
||||||
|
|
||||||
// note: subset from Gytheio
|
|
||||||
|
|
||||||
public static final String PREFIX_AUDIO = "audio/";
|
|
||||||
public static final String PREFIX_IMAGE = "image/";
|
|
||||||
public static final String PREFIX_VIDEO = "video/";
|
|
||||||
|
|
||||||
public static final String MEDIATYPE_IMAGE_SVG = "image/svg+xml";
|
|
||||||
public static final String MEDIATYPE_APPLICATION_PHOTOSHOP = "image/vnd.adobe.photoshop";
|
|
||||||
public static final String MEDIATYPE_IMG_DWG = "image/vnd.dwg";
|
|
||||||
|
|
||||||
@Value("${transform.core.ffmpeg.exe}")
|
@Value("${transform.core.ffmpeg.exe}")
|
||||||
private String execPath;
|
private String execPath;
|
||||||
|
|
||||||
@@ -125,67 +117,6 @@ public class FFmpegController extends AbstractTransformerController
|
|||||||
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
||||||
{
|
{
|
||||||
// note: actual supported transforms are defined by FFmpeg engine config - this is an extra sanity check
|
|
||||||
if (! isTransformable(sourceMimetype, targetMimetype))
|
|
||||||
{
|
|
||||||
throw new UnsupportedOperationException("Unsupported combinations of source/target media types: "+sourceMimetype+","+targetMimetype);
|
|
||||||
}
|
|
||||||
|
|
||||||
commandExecutor.transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
commandExecutor.transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if the source mimetype is supported by ffmpeg
|
|
||||||
*
|
|
||||||
* @param mediaType the mimetype to check
|
|
||||||
* @return Returns true if ffmpeg can handle the given mimetype format
|
|
||||||
*/
|
|
||||||
private static boolean isSupportedSource(String mediaType)
|
|
||||||
{
|
|
||||||
return ((mediaType.startsWith(PREFIX_VIDEO) && !(
|
|
||||||
mediaType.equals("video/x-rad-screenplay") ||
|
|
||||||
mediaType.equals("video/x-sgi-movie") ||
|
|
||||||
mediaType.equals("video/mpeg2"))) ||
|
|
||||||
(mediaType.startsWith(PREFIX_AUDIO) && !(
|
|
||||||
mediaType.equals("audio/vnd.adobe.soundbooth"))) ||
|
|
||||||
mediaType.equals("application/mxf"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines if FFmpeg can be made to support the given target mimetype.
|
|
||||||
*
|
|
||||||
* @param mimetype the mimetype to check
|
|
||||||
* @return Returns true if ffmpeg can handle the given mimetype format
|
|
||||||
*/
|
|
||||||
private static boolean isSupportedTarget(String mimetype)
|
|
||||||
{
|
|
||||||
return ((mimetype.startsWith(PREFIX_VIDEO) && !(
|
|
||||||
mimetype.equals("video/x-rad-screenplay") ||
|
|
||||||
mimetype.equals("video/x-sgi-movie") ||
|
|
||||||
mimetype.equals("video/mpeg2"))) ||
|
|
||||||
(mimetype.startsWith(PREFIX_IMAGE) && !(
|
|
||||||
mimetype.equals(MEDIATYPE_IMAGE_SVG) ||
|
|
||||||
mimetype.equals(MEDIATYPE_APPLICATION_PHOTOSHOP) ||
|
|
||||||
mimetype.equals(MEDIATYPE_IMG_DWG) ||
|
|
||||||
mimetype.equals("image/vnd.adobe.premiere") ||
|
|
||||||
mimetype.equals("image/x-portable-anymap") ||
|
|
||||||
mimetype.equals("image/x-xpixmap") ||
|
|
||||||
mimetype.equals("image/x-dwt") ||
|
|
||||||
mimetype.equals("image/cgm") ||
|
|
||||||
mimetype.equals("image/ief"))) ||
|
|
||||||
(mimetype.startsWith(PREFIX_AUDIO) && !(
|
|
||||||
mimetype.equals("audio/vnd.adobe.soundbooth"))));
|
|
||||||
}
|
|
||||||
|
|
||||||
// note: based on Gytheio
|
|
||||||
private boolean isTransformable(String sourceMediaType, String targetMediaType)
|
|
||||||
{
|
|
||||||
if (sourceMediaType.startsWith(PREFIX_AUDIO) &&
|
|
||||||
targetMediaType.startsWith(PREFIX_IMAGE))
|
|
||||||
{
|
|
||||||
// Might be able to support audio to waveform image in the future, but for now...
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return (isSupportedSource(sourceMediaType) && isSupportedTarget(targetMediaType));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
@@ -79,6 +79,8 @@ import javax.annotation.PostConstruct;
|
|||||||
/**
|
/**
|
||||||
* Test the FFmpegController without a server.
|
* Test the FFmpegController without a server.
|
||||||
* Super class includes tests for the AbstractTransformerController.
|
* Super class includes tests for the AbstractTransformerController.
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
@WebMvcTest(FFmpegController.class)
|
@WebMvcTest(FFmpegController.class)
|
||||||
public class FFmpegControllerTest extends AbstractTransformerControllerTest
|
public class FFmpegControllerTest extends AbstractTransformerControllerTest
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
@@ -31,6 +31,8 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests FFmpegController with a server test harness.
|
* Tests FFmpegController with a server test harness.
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||||
public class FFmpegHttpRequestTest extends AbstractHttpRequestTest
|
public class FFmpegHttpRequestTest extends AbstractHttpRequestTest
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
|
@@ -11,7 +11,8 @@
|
|||||||
{"sourceMediaType": "video/mp4", "targetMediaType": "video/avi" },
|
{"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/png" },
|
||||||
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" }
|
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" },
|
||||||
|
{"sourceMediaType": "video/quicktime", "targetMediaType": "video/mp4" }
|
||||||
],
|
],
|
||||||
"transformOptions": [
|
"transformOptions": [
|
||||||
"ffmpegOptions"
|
"ffmpegOptions"
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Transform Core
|
* Alfresco Transform Core
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2021 Alfresco Software Limited
|
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* -
|
* -
|
||||||
@@ -33,7 +33,6 @@ import java.io.File;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
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.TIMEOUT;
|
||||||
import static org.alfresco.transformer.util.RequestParamMap.TIME_OFFSET;
|
import static org.alfresco.transformer.util.RequestParamMap.TIME_OFFSET;
|
||||||
import static org.alfresco.transformer.util.Util.stringToLong;
|
import static org.alfresco.transformer.util.Util.stringToLong;
|
||||||
@@ -41,6 +40,8 @@ import static org.alfresco.transformer.util.Util.stringToLong;
|
|||||||
/**
|
/**
|
||||||
* CommandExecutor implementation for running FFmpeg transformations. It runs the
|
* CommandExecutor implementation for running FFmpeg transformations. It runs the
|
||||||
* transformation logic as a separate Shell process.
|
* transformation logic as a separate Shell process.
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
// TODO PoC for FFmpeg
|
// TODO PoC for FFmpeg
|
||||||
public class FFmpegCommandExecutor extends AbstractCommandExecutor
|
public class FFmpegCommandExecutor extends AbstractCommandExecutor
|
||||||
|
@@ -11,7 +11,8 @@
|
|||||||
{"sourceMediaType": "video/mp4", "targetMediaType": "video/avi" },
|
{"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/png" },
|
||||||
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" }
|
{"sourceMediaType": "video/mp4", "targetMediaType": "image/jpeg" },
|
||||||
|
{"sourceMediaType": "video/quicktime", "targetMediaType": "video/mp4" }
|
||||||
],
|
],
|
||||||
"transformOptions": [
|
"transformOptions": [
|
||||||
"ffmpegOptions"
|
"ffmpegOptions"
|
||||||
|
Reference in New Issue
Block a user