mirror of
https://github.com/Alfresco/alfresco-transform-core.git
synced 2025-08-14 17:58:27 +00:00
ATS-812: PoC for FFmpeg T-Engine (WIP) - initial folder skeleton
- note: PoC only - limited functionality & no tests yet - see also ATS-793 epic
This commit is contained in:
@@ -0,0 +1,49 @@
|
|||||||
|
# Image provides a container in which to run FFmpeg transformations for Alfresco Content Services.
|
||||||
|
|
||||||
|
# TODO PoC for FFmpeg
|
||||||
|
# The FFmpeg transformer uses FFmpeg. See license: https://github.com/FFmpeg/FFmpeg/blob/master/LICENSE.md
|
||||||
|
|
||||||
|
FROM alfresco/alfresco-base-java:11.0.7-openjdk-centos-7-9448dd21de19
|
||||||
|
|
||||||
|
ARG FFMPEG_VERSION=3.4.8-1
|
||||||
|
|
||||||
|
# TODO PoC for FFmpeg - update & download from Nexus
|
||||||
|
ENV FFMPEG_RPM_URL=https://download1.rpmfusion.org/free/el/updates/7/x86_64/f/ffmpeg-${FFMPEG_VERSION}.el7.x86_64.rpm
|
||||||
|
#ENV FFMPEG_LICENSE_FILE=https://github.com/Alfresco/acs-community-packaging/blob/master/distribution/src/main/resources/licenses/3rd-party/TODO-license.txt
|
||||||
|
ENV JAVA_OPTS=""
|
||||||
|
|
||||||
|
# Set default user information
|
||||||
|
ARG GROUPNAME=Alfresco
|
||||||
|
ARG GROUPID=1000
|
||||||
|
|
||||||
|
# TODO PoC for FFmpeg - update w3 page with a specific allocated id in sequence (may not be 33099)
|
||||||
|
ARG FFMPEGUSERNAME=ffmpeg
|
||||||
|
ARG USERID=33099
|
||||||
|
|
||||||
|
COPY target/${env.project_artifactId}-${env.project_version}.jar /usr/bin
|
||||||
|
|
||||||
|
RUN ln /usr/bin/${env.project_artifactId}-${env.project_version}.jar /usr/bin/${env.project_artifactId}.jar && \
|
||||||
|
# TODO PoC for FFmpeg - see above
|
||||||
|
# curl -s -S $FFMPEG_RPM_URL -o ffmpeg-distribution-linux.rpm && \
|
||||||
|
# curl -s -S $FFMPEG_LICENSE_FILE -o FFmpeg-license.txt && \
|
||||||
|
yum install -y epel-release && \
|
||||||
|
# yum localinstall -y ffmpeg-distribution-*linux.rpm && \
|
||||||
|
yum localinstall -y --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm && \
|
||||||
|
yum install -y ffmpeg && \
|
||||||
|
# rm -f ffmpeg-distribution-*.rpm && \
|
||||||
|
yum clean all
|
||||||
|
|
||||||
|
ADD target/generated-resources/licenses /licenses
|
||||||
|
ADD target/generated-resources/licenses.xml /licenses/
|
||||||
|
ADD target/generated-sources/license/THIRD-PARTY.txt /licenses/
|
||||||
|
|
||||||
|
RUN groupadd -g ${GROUPID} ${GROUPNAME} && \
|
||||||
|
useradd -u ${USERID} -G ${GROUPNAME} ${FFMPEGUSERNAME} && \
|
||||||
|
chgrp -R ${GROUPNAME} /usr/bin/${env.project_artifactId}.jar
|
||||||
|
|
||||||
|
EXPOSE 8090
|
||||||
|
|
||||||
|
USER ${PDFUSERNAME}
|
||||||
|
|
||||||
|
ENTRYPOINT java $JAVA_OPTS -jar /usr/bin/${env.project_artifactId}.jar
|
||||||
|
|
@@ -0,0 +1,3 @@
|
|||||||
|
### Licenses
|
||||||
|
|
||||||
|
* TODO - The FFmpeg transformer uses FFmpeg. See license: https://github.com/FFmpeg/FFmpeg/blob/master/LICENSE.md
|
302
alfresco-transform-ffmpeg/alfresco-transform-ffmpeg-boot/pom.xml
Normal file
302
alfresco-transform-ffmpeg/alfresco-transform-ffmpeg-boot/pom.xml
Normal file
@@ -0,0 +1,302 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>alfresco-transform-ffmpeg-boot</artifactId>
|
||||||
|
<name>Alfresco Ffmoeg Spring Boot</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transform-core</artifactId>
|
||||||
|
<version>2.3.3-SNAPSHOT</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<image.name>alfresco/alfresco-ffmpeg</image.name>
|
||||||
|
<image.registry>quay.io</image.registry>
|
||||||
|
<env.project_artifactId>${project.artifactId}</env.project_artifactId>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transformer-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transformer-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<classifier>tests</classifier>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transform-ffmpeg</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>com.vaadin.external.google</groupId>
|
||||||
|
<artifactId>android-json</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dom4j</groupId>
|
||||||
|
<artifactId>dom4j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>docker-it-setup</id>
|
||||||
|
<!-- raises an ActiveMq container for the Integration Tests -->
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>docker-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<alias>activemq</alias>
|
||||||
|
<name>alfresco/alfresco-activemq:5.15.8</name>
|
||||||
|
<run>
|
||||||
|
<hostname>activemq</hostname>
|
||||||
|
<ports>
|
||||||
|
<port>8161:8161</port>
|
||||||
|
<port>5672:5672</port>
|
||||||
|
<port>61616:61616</port>
|
||||||
|
</ports>
|
||||||
|
<wait>
|
||||||
|
<log>Apache ActiveMQ 5.15.8 .* started</log>
|
||||||
|
<time>20000</time>
|
||||||
|
<kill>500</kill>
|
||||||
|
<shutdown>100</shutdown>
|
||||||
|
<exec>
|
||||||
|
<preStop>kill 1</preStop>
|
||||||
|
<preStop>kill -9 1</preStop>
|
||||||
|
</exec>
|
||||||
|
</wait>
|
||||||
|
</run>
|
||||||
|
</image>
|
||||||
|
|
||||||
|
<image>
|
||||||
|
<alias>alfresco-ffmpeg</alias>
|
||||||
|
<name>${image.name}:${image.tag}</name>
|
||||||
|
<run>
|
||||||
|
<ports>
|
||||||
|
<port>8090:8090</port>
|
||||||
|
</ports>
|
||||||
|
<wait>
|
||||||
|
<http>
|
||||||
|
<url>http://localhost:8090/transform/config</url>
|
||||||
|
<method>GET</method>
|
||||||
|
<status>200...299</status>
|
||||||
|
</http>
|
||||||
|
<time>300000</time>
|
||||||
|
<kill>500</kill>
|
||||||
|
<shutdown>100</shutdown>
|
||||||
|
<exec>
|
||||||
|
<preStop>kill 1</preStop>
|
||||||
|
<preStop>kill -9 1</preStop>
|
||||||
|
</exec>
|
||||||
|
</wait>
|
||||||
|
</run>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>local</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>fabric8-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<image>
|
||||||
|
<name>${image.name}:${image.tag}</name>
|
||||||
|
<build>
|
||||||
|
<dockerFileDir>${project.basedir}/</dockerFileDir>
|
||||||
|
<buildOptions>
|
||||||
|
<squash>true</squash>
|
||||||
|
</buildOptions>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>build-image</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>build</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>internal</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>fabric8-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<images>
|
||||||
|
<!-- QuayIO image -->
|
||||||
|
<image>
|
||||||
|
<name>${image.name}:${image.tag}</name>
|
||||||
|
<registry>${image.registry}</registry>
|
||||||
|
<build>
|
||||||
|
<dockerFileDir>${project.basedir}/</dockerFileDir>
|
||||||
|
<buildOptions>
|
||||||
|
<squash>true</squash>
|
||||||
|
</buildOptions>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
<!-- DockerHub image -->
|
||||||
|
<image>
|
||||||
|
<name>${image.name}:${image.tag}</name>
|
||||||
|
<build>
|
||||||
|
<dockerFileDir>${project.basedir}/</dockerFileDir>
|
||||||
|
<buildOptions>
|
||||||
|
<squash>true</squash>
|
||||||
|
</buildOptions>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>build-image</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>build</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>push-image</id>
|
||||||
|
<phase>install</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>push</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
|
||||||
|
<profile>
|
||||||
|
<id>release</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.fabric8</groupId>
|
||||||
|
<artifactId>fabric8-maven-plugin</artifactId>
|
||||||
|
<configuration combine.self="override">
|
||||||
|
<images>
|
||||||
|
<!-- QuayIO image -->
|
||||||
|
<image>
|
||||||
|
<name>${image.name}:${project.version}</name>
|
||||||
|
<registry>${image.registry}</registry>
|
||||||
|
<build>
|
||||||
|
<dockerFileDir>${project.basedir}/</dockerFileDir>
|
||||||
|
<buildOptions>
|
||||||
|
<squash>true</squash>
|
||||||
|
</buildOptions>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
<!-- DockerHub image -->
|
||||||
|
<image>
|
||||||
|
<name>${image.name}:${project.version}</name>
|
||||||
|
<build>
|
||||||
|
<dockerFileDir>${project.basedir}/</dockerFileDir>
|
||||||
|
<buildOptions>
|
||||||
|
<squash>true</squash>
|
||||||
|
</buildOptions>
|
||||||
|
</build>
|
||||||
|
</image>
|
||||||
|
</images>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>build-push-image</id>
|
||||||
|
<phase>deploy</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>build</goal>
|
||||||
|
<goal>push</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transformer;
|
||||||
|
|
||||||
|
import io.micrometer.core.instrument.MeterRegistry;
|
||||||
|
import org.alfresco.transformer.executors.FFmpegCommandExecutor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static org.alfresco.transformer.logging.StandardMessages.LICENCE;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
|
||||||
|
public class Application
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Application.class);
|
||||||
|
|
||||||
|
@Value("${container.name}")
|
||||||
|
private String containerName;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags()
|
||||||
|
{
|
||||||
|
return registry -> registry.config().commonTags("containerName", containerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void startup()
|
||||||
|
{
|
||||||
|
logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||||
|
Arrays.stream(LICENCE.split("\\n")).forEach(logger::info);
|
||||||
|
logger.info(FFmpegCommandExecutor.LICENCE);
|
||||||
|
logger.info("-----------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||||
|
|
||||||
|
logger.info("Starting application components... Done");
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,120 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transformer;
|
||||||
|
|
||||||
|
import org.alfresco.transformer.executors.FFmpegCommandExecutor;
|
||||||
|
import org.alfresco.transformer.probes.ProbeTestTransform;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for the Docker based FFmpeg transformer.
|
||||||
|
*
|
||||||
|
* Status Codes:
|
||||||
|
*
|
||||||
|
* 200 Success
|
||||||
|
* 400 Bad Request: Request parameter <name> is missing (missing mandatory parameter)
|
||||||
|
* 400 Bad Request: Request parameter <name> is of the wrong type
|
||||||
|
* 400 Bad Request: Transformer exit code was not 0 (possible problem with the source file)
|
||||||
|
* 400 Bad Request: The source filename was not supplied
|
||||||
|
* 500 Internal Server Error: (no message with low level IO problems)
|
||||||
|
* 500 Internal Server Error: The target filename was not supplied (should not happen as targetExtension is checked)
|
||||||
|
* 500 Internal Server Error: Transformer version check exit code was not 0
|
||||||
|
* 500 Internal Server Error: Transformer version check failed to create any output
|
||||||
|
* 500 Internal Server Error: Could not read the target file
|
||||||
|
* 500 Internal Server Error: The target filename was malformed (should not happen because of other checks)
|
||||||
|
* 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
|
||||||
|
* 507 Insufficient Storage: Failed to store the source file
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
public class FFmpegController extends AbstractTransformerController
|
||||||
|
{
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(
|
||||||
|
FFmpegController
|
||||||
|
.class);
|
||||||
|
|
||||||
|
@Value("${transform.core.ffmpeg.exe}")
|
||||||
|
private String execPath;
|
||||||
|
|
||||||
|
FFmpegCommandExecutor commandExecutor;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
private void init()
|
||||||
|
{
|
||||||
|
commandExecutor = new FFmpegCommandExecutor(execPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTransformerName()
|
||||||
|
{
|
||||||
|
return "FFmpeg";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String version()
|
||||||
|
{
|
||||||
|
return commandExecutor.version();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProbeTestTransform getProbeTestTransform()
|
||||||
|
{
|
||||||
|
// See the Javadoc on this method and Probes.md for the choice of these values.
|
||||||
|
// TODO PoC for FFmpeg
|
||||||
|
return new ProbeTestTransform(this, "quick.mp4", "quick.mp3",
|
||||||
|
7455, 1024, 150, 10240, 60 * 20 + 1, 60 * 15 - 15)
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void executeTransformCommand(File sourceFile, File targetFile)
|
||||||
|
{
|
||||||
|
transformImpl(null, null, null, Collections.emptyMap(), sourceFile, targetFile);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTransformerName(final File sourceFile, final String sourceMimetype,
|
||||||
|
final String targetMimetype, final Map<String, String> transformOptions)
|
||||||
|
{
|
||||||
|
return null; // does not matter what value is returned, as it is not used because there is only one.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transformImpl(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
|
Map<String, String> transformOptions, File sourceFile, File targetFile)
|
||||||
|
{
|
||||||
|
commandExecutor.transform(sourceMimetype, targetMimetype, transformOptions, sourceFile, targetFile);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,8 @@
|
|||||||
|
queue:
|
||||||
|
engineRequestQueue: ${TRANSFORM_ENGINE_REQUEST_QUEUE:org.alfresco.transform.engine.ffmpeg.acs}
|
||||||
|
transform:
|
||||||
|
core:
|
||||||
|
config:
|
||||||
|
location: classpath:ffmpeg_engine_config.json
|
||||||
|
ffmpeg:
|
||||||
|
exe: ${FFMPEG_EXE:/usr/bin/ffmpeg}
|
@@ -0,0 +1,23 @@
|
|||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h2>Alfresco FFmpeg Test Transformation</h2>
|
||||||
|
<form method="POST" enctype="multipart/form-data" action="/transform">
|
||||||
|
<table>
|
||||||
|
<tr><td><div style="text-align:right">file *</div></td><td><input type="file" name="file" /></td></tr>
|
||||||
|
<tr><td><div style="text-align:right">targetExtension *</div></td><td><input type="text" name="targetExtension" value="" /></td></tr>
|
||||||
|
<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></td><td><input type="submit" value="Transform" /></td></tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a href="/log">Log entries</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@@ -0,0 +1,3 @@
|
|||||||
|
### Licenses
|
||||||
|
|
||||||
|
* TODO - The FFmpeg transformer uses FFmpeg. See license: https://github.com/FFmpeg/FFmpeg/blob/master/LICENSE.md
|
38
alfresco-transform-ffmpeg/alfresco-transform-ffmpeg/pom.xml
Normal file
38
alfresco-transform-ffmpeg/alfresco-transform-ffmpeg/pom.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>alfresco-transform-ffmpeg</artifactId>
|
||||||
|
<name>Alfresco FFmpeg Transformer</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transform-core</artifactId>
|
||||||
|
<version>2.3.3-SNAPSHOT</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.alfresco</groupId>
|
||||||
|
<artifactId>alfresco-transformer-base</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>license-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-failsafe-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transformer;
|
||||||
|
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FFmpeg options builder.
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
|
*/
|
||||||
|
// TODO PoC for FFmpeg
|
||||||
|
public final class FFmpegOptionsBuilder
|
||||||
|
{
|
||||||
|
// TODO PoC - add FFmpeg options ...
|
||||||
|
private FFmpegOptionsBuilder() {}
|
||||||
|
|
||||||
|
public String build()
|
||||||
|
{
|
||||||
|
StringJoiner args = new StringJoiner(" ");
|
||||||
|
|
||||||
|
return args.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FFmpegOptionsBuilder builder()
|
||||||
|
{
|
||||||
|
return new FFmpegOptionsBuilder();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Transform Core
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2005 - 2020 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* -
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
* -
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
* -
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
* -
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.transformer.executors;
|
||||||
|
|
||||||
|
import org.alfresco.transform.exceptions.TransformException;
|
||||||
|
import org.alfresco.transformer.FFmpegOptionsBuilder;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.alfresco.transformer.util.RequestParamMap.TIMEOUT;
|
||||||
|
import static org.alfresco.transformer.util.Util.stringToLong;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandExecutor implementation for running FFmpeg transformations. It runs the
|
||||||
|
* transformation logic as a separate Shell process.
|
||||||
|
*/
|
||||||
|
// TODO PoC for FFmpeg
|
||||||
|
public class FFmpegCommandExecutor extends AbstractCommandExecutor
|
||||||
|
{
|
||||||
|
private static String ID = "ffmpeg";
|
||||||
|
|
||||||
|
// TODO PoC for FFmpeg
|
||||||
|
public static final String LICENCE = "TODO: This transformer uses Ffmpeg. See the license at ...";
|
||||||
|
|
||||||
|
private final String EXE;
|
||||||
|
|
||||||
|
public FFmpegCommandExecutor(String exe)
|
||||||
|
{
|
||||||
|
if (exe == null || exe.isEmpty())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("FfmpegCommandExecutor EXE variable cannot be null or empty");
|
||||||
|
}
|
||||||
|
this.EXE = exe;
|
||||||
|
super.transformCommand = createTransformCommand();
|
||||||
|
super.checkCommand = createCheckCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTransformerId()
|
||||||
|
{
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RuntimeExec createTransformCommand()
|
||||||
|
{
|
||||||
|
RuntimeExec runtimeExec = new RuntimeExec();
|
||||||
|
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||||
|
|
||||||
|
// 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}"});
|
||||||
|
|
||||||
|
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||||
|
|
||||||
|
Map<String, String> defaultProperties = new HashMap<>();
|
||||||
|
defaultProperties.put("key", null);
|
||||||
|
runtimeExec.setDefaultProperties(defaultProperties);
|
||||||
|
|
||||||
|
runtimeExec.setErrorCodes("1");
|
||||||
|
|
||||||
|
return runtimeExec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected RuntimeExec createCheckCommand()
|
||||||
|
{
|
||||||
|
RuntimeExec runtimeExec = new RuntimeExec();
|
||||||
|
Map<String, String[]> commandsAndArguments = new HashMap<>();
|
||||||
|
commandsAndArguments.put(".*", new String[]{EXE, "--version"});
|
||||||
|
runtimeExec.setCommandsAndArguments(commandsAndArguments);
|
||||||
|
return runtimeExec;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void transform(String transformName, String sourceMimetype, String targetMimetype,
|
||||||
|
Map<String, String> transformOptions,
|
||||||
|
File sourceFile, File targetFile) throws TransformException
|
||||||
|
{
|
||||||
|
final String options = FFmpegOptionsBuilder
|
||||||
|
.builder()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Long timeout = stringToLong(transformOptions.get(TIMEOUT));
|
||||||
|
|
||||||
|
run(options, sourceFile, targetFile, timeout);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"transformOptions": {
|
||||||
|
"ffmpegOptions": [
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"transformers": [
|
||||||
|
{
|
||||||
|
"transformerName": "ffmpeg",
|
||||||
|
"supportedSourceAndTargetList": [
|
||||||
|
{"sourceMediaType": "video/mp4", "targetMediaType": "video/avi" },
|
||||||
|
{"sourceMediaType": "video/mp4", "targetMediaType": "audio/mp3" }
|
||||||
|
],
|
||||||
|
"transformOptions": [
|
||||||
|
"ffmpegOptions"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
10
pom.xml
10
pom.xml
@@ -45,6 +45,8 @@
|
|||||||
<module>alfresco-transformer-base</module>
|
<module>alfresco-transformer-base</module>
|
||||||
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick</module>
|
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick</module>
|
||||||
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick-boot</module>
|
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick-boot</module>
|
||||||
|
<module>alfresco-transform-ffmpeg/alfresco-transform-ffmpeg</module>
|
||||||
|
<module>alfresco-transform-ffmpeg/alfresco-transform-ffmpeg-boot</module>
|
||||||
<module>alfresco-transform-libreoffice/alfresco-transform-libreoffice</module>
|
<module>alfresco-transform-libreoffice/alfresco-transform-libreoffice</module>
|
||||||
<module>alfresco-transform-libreoffice/alfresco-transform-libreoffice-boot</module>
|
<module>alfresco-transform-libreoffice/alfresco-transform-libreoffice-boot</module>
|
||||||
<module>alfresco-transform-misc/alfresco-transform-misc</module>
|
<module>alfresco-transform-misc/alfresco-transform-misc</module>
|
||||||
@@ -71,6 +73,14 @@
|
|||||||
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick-boot</module>
|
<module>alfresco-transform-imagemagick/alfresco-transform-imagemagick-boot</module>
|
||||||
</modules>
|
</modules>
|
||||||
</profile>
|
</profile>
|
||||||
|
<profile>
|
||||||
|
<id>ffmpeg</id>
|
||||||
|
<modules>
|
||||||
|
<module>alfresco-transformer-base</module>
|
||||||
|
<module>alfresco-transform-ffmpeg/alfresco-transform-ffmpeg</module>
|
||||||
|
<module>alfresco-transform-ffmpeg/alfresco-transform-ffmpeg-boot</module>
|
||||||
|
</modules>
|
||||||
|
</profile>
|
||||||
<profile>
|
<profile>
|
||||||
<id>libreoffice</id>
|
<id>libreoffice</id>
|
||||||
<modules>
|
<modules>
|
||||||
|
Reference in New Issue
Block a user