Commit 44119e12 authored by Elias Englmeier's avatar Elias Englmeier
Browse files

added threaded video conversion

parent 9170f7cb
......@@ -13,6 +13,6 @@
##
build.namespace=ANALYSIS
build.number=79
build.date=1516699209154
build.number=80
build.date=1521122796310
build.auto.upgrade=true
\ No newline at end of file
......@@ -13,6 +13,6 @@
##
build.namespace=GB
build.number=100
build.date=1516699213602
build.number=101
build.date=1521122800720
build.auto.upgrade=true
\ No newline at end of file
......@@ -31,6 +31,7 @@ import com.liferay.portal.kernel.search.Indexable;
import com.liferay.portal.kernel.search.IndexableType;
import com.liferay.portal.kernel.service.BaseLocalService;
import com.liferay.portal.kernel.service.PersistedModelLocalService;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.transaction.Isolation;
import com.liferay.portal.kernel.transaction.Propagation;
import com.liferay.portal.kernel.transaction.Transactional;
......@@ -418,7 +419,7 @@ public interface IdeasLocalService extends BaseLocalService,
java.lang.String pictureRef);
public void addVideoToExistingIdea(long ideasId, long videoId,
java.lang.String videoRef);
java.lang.String videoRef, ThemeDisplay themedisplay);
/**
* persists the new Idea and performs some checks e.g. if the entry is a duplicate it won't be inserted.
......
......@@ -494,8 +494,10 @@ public class IdeasLocalServiceUtil {
}
public static void addVideoToExistingIdea(long ideasId, long videoId,
java.lang.String videoRef) {
getService().addVideoToExistingIdea(ideasId, videoId, videoRef);
java.lang.String videoRef,
com.liferay.portal.kernel.theme.ThemeDisplay themedisplay) {
getService()
.addVideoToExistingIdea(ideasId, videoId, videoRef, themedisplay);
}
/**
......
......@@ -525,8 +525,10 @@ public class IdeasLocalServiceWrapper implements IdeasLocalService,
@Override
public void addVideoToExistingIdea(long ideasId, long videoId,
java.lang.String videoRef) {
_ideasLocalService.addVideoToExistingIdea(ideasId, videoId, videoRef);
java.lang.String videoRef,
com.liferay.portal.kernel.theme.ThemeDisplay themedisplay) {
_ideasLocalService.addVideoToExistingIdea(ideasId, videoId, videoRef,
themedisplay);
}
/**
......
......@@ -5,4 +5,5 @@ Liferay-Require-SchemaVersion: 1.0.0
Liferay-Service: true
Export-Package: \
ideaService.ideas.search,\
ideaService.ideas.asset
ideaService.ideas.asset,\
ideaService.service.avconversion
package ideaService.service.avconversion;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Map;
import java.util.UUID;
import org.osgi.service.component.annotations.Component;
import com.liferay.document.library.kernel.model.DLFileEntry;
import com.liferay.document.library.kernel.service.DLAppLocalServiceUtil;
import com.liferay.document.library.kernel.service.DLFileEntryLocalServiceUtil;
import com.liferay.portal.kernel.backgroundtask.BackgroundTask;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskConstants;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskExecutor;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskResult;
import com.liferay.portal.kernel.backgroundtask.BaseBackgroundTaskExecutor;
import com.liferay.portal.kernel.backgroundtask.display.BackgroundTaskDisplay;
import com.liferay.portal.kernel.backgroundtask.display.BackgroundTaskDisplayFactoryUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.util.MimeTypesUtil;
import ideaService.model.Ideas;
import ideaService.service.persistence.IdeasUtil;
@Component(immediate = true, property = {"background.task.executor.class.name=ideaService.service.avconversion.VideoConverter"}, service = BackgroundTaskExecutor.class)
public class VideoConverter extends BaseBackgroundTaskExecutor {
private static Log logger = LogFactoryUtil.getLog( VideoConverter.class);
@Override
public BackgroundTaskResult execute(BackgroundTask backgroundTask) throws Exception {
logger.info("---------------------Executing background task started ---------------------");
Map<String, Serializable> taskContextMap = backgroundTask.getTaskContextMap();
long ideasId = (long) taskContextMap.get("ideasId");
long videoId = (long) taskContextMap.get("videoId");
String convertTo = (String) taskContextMap.get("convertTo");
String portalUrl = (String) taskContextMap.get("portalUrl");
String contextPath = (String) taskContextMap.get("contextPath");
long gId = (long) taskContextMap.get("gId");
//Get FileEntry from Liferay Docs-Library
DLFileEntry dlEntry = DLFileEntryLocalServiceUtil.getFileEntry(videoId);
//Get InputStream from File
InputStream videoInputStream = DLFileEntryLocalServiceUtil.getFileAsStream(videoId, dlEntry.getVersion());
//Create File From Inputstream. Even when converting to ogg and webm in parallel creating one source file is enough. Hence, the same name.
//However, filename still needs to be distinct in case of converting two files at the same time.
File tmpSourceFile = new File("tmpSourceFileOF" + dlEntry.getFileName() );
tmpSourceFile.deleteOnExit();
FileOutputStream out = new FileOutputStream(tmpSourceFile);
copyStream(videoInputStream,out);
out.close();
logger.info("-------------------------------- Created temp file at" + tmpSourceFile.getAbsolutePath() + " -----------------------------------");
String outputFileName = null;
Process p = null;
if(convertTo.equals("webm")){
logger.info("-------------------------- Started converting to WEBM ----------------------------------------");
outputFileName = dlEntry.getFileName().substring(0, dlEntry.getFileName().length()-4) + ".webm";
p = Runtime.getRuntime().exec("ffmpeg -i " + tmpSourceFile.getAbsolutePath() +" -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis " + outputFileName);
}
else if(convertTo.equals("ogv")){
logger.info("-------------------------- Started converting to OGG ----------------------------------------");
outputFileName = dlEntry.getFileName().substring(0, dlEntry.getFileName().length()-4) + ".ogv";
p = Runtime.getRuntime().exec("ffmpeg -i " + tmpSourceFile.getAbsolutePath() +" -codec:v libtheora -qscale:v 7 -codec:a libvorbis -qscale:a 5 " + outputFileName);
}
String line;
BufferedReader in = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = in.readLine()) != null) {
logger.info(line);
}
while(p.isAlive()){
// make sure the process is finished
}
in.close();
File tmpOutputFile = new File (outputFileName);
logger.info("-------------------------------- Conversion finished. Created temp file at " + tmpOutputFile.getAbsolutePath() + " -----------------------------------");
logger.info("------------------------------- Saving converted file to Liferay Docs library -----------------------------------");
Ideas i = IdeasUtil.findByPrimaryKey(ideasId);
String title = i.getUserName() + "IDEAS_VIDEO" + UUID.randomUUID () + "." + convertTo;
FileEntry createdEntry = DLAppLocalServiceUtil.addFileEntry(i.getUserId(), i.getGroupId(),
dlEntry.getFolderId(), tmpOutputFile.getName(),
MimeTypesUtil.getContentType(tmpOutputFile), title,
"converted video file", "none", tmpOutputFile, new ServiceContext());
String fileUrl = getFullyQualifiedUrlForFileEntry(portalUrl, contextPath, gId, createdEntry);
logger.info("CREATED ENTRY: " + fileUrl);
String newIdeasVideoUrlEntry = i.getVideoUrl() + "," + fileUrl;
i.setVideoUrl(newIdeasVideoUrlEntry);
i.persist();
logger.info("-------------------------------- Deleting temp files -----------------------------------");
tmpSourceFile.delete();
tmpOutputFile.delete();
logger.info("--------------------- Execution of background task finished ---------------------");
return BackgroundTaskResult.SUCCESS;
}
@Override
public BackgroundTaskDisplay getBackgroundTaskDisplay(BackgroundTask backgroundTask) {
return BackgroundTaskDisplayFactoryUtil.getBackgroundTaskDisplay(backgroundTask);
}
@Override
public int getIsolationLevel(){
return BackgroundTaskConstants.ISOLATION_LEVEL_TASK_NAME;
}
@Override
public BackgroundTaskExecutor clone() {
return this;
}
@Override
public boolean isSerial(){
return false;
}
private static void copyStream(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
private String getFullyQualifiedUrlForFileEntry(String portalUrl,String contextPath , long gId, FileEntry entry){
return portalUrl + contextPath + "/documents/" + gId + "/" + entry.getFolderId() + "/" +entry.getTitle();
}
}
......@@ -14,13 +14,17 @@
package ideaService.service.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.model.AssetLinkConstants;
import com.liferay.counter.kernel.service.CounterLocalServiceUtil;
import com.liferay.document.library.kernel.service.DLAppLocalServiceUtil;
import com.liferay.portal.kernel.backgroundtask.BackgroundTaskManagerUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.LayoutFriendlyURL;
......@@ -38,17 +42,19 @@ import com.liferay.portal.kernel.service.LayoutFriendlyURLLocalServiceUtil;
import com.liferay.portal.kernel.service.LayoutLocalServiceUtil;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.UserLocalServiceUtil;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.PortalUtil;
import aQute.bnd.annotation.ProviderType;
import analysisService.service.TagDataLocalServiceUtil;
import ideaService.exception.NoSuchIdeasException;
import ideaService.model.Ideas;
import ideaService.service.IdeasLocalServiceUtil;
import ideaService.service.avconversion.VideoConverter;
import ideaService.service.base.IdeasLocalServiceBaseImpl;
import ideaService.service.persistence.IdeasUtil;
import ideasService.service.enums.ReviewStatus;
import analysisService.service.TagDataLocalServiceUtil;
/**
* The implementation of the ideas local service.
......@@ -147,18 +153,33 @@ public class IdeasLocalServiceImpl extends IdeasLocalServiceBaseImpl {
}
}
public void addVideoToExistingIdea(long ideasId, long videoId, String videoRef){
public void addVideoToExistingIdea(long ideasId, long videoId, String videoRef, ThemeDisplay themedisplay){
try {
Ideas i = IdeasUtil.findByPrimaryKey(ideasId);
i.setVideoFileRef(videoId);
i.setVideoUrl(videoRef);
i.persist();
} catch (NoSuchIdeasException e) {
startBackgroundVideoConversion(i,"webm", themedisplay);
startBackgroundVideoConversion(i,"ogv", themedisplay);
} catch (PortalException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void startBackgroundVideoConversion(Ideas i, String convertTo, ThemeDisplay themeDisplay ) throws PortalException{
Map<String, Serializable> taskContextMap = new HashMap<String, Serializable>();
taskContextMap.put("ideasId",i.getPrimaryKey());
taskContextMap.put("videoId",i.getVideoFileRef());
taskContextMap.put("videoRef",i.getVideoUrl());
taskContextMap.put("convertTo",convertTo);
taskContextMap.put("portalUrl", themeDisplay.getPortalURL());
taskContextMap.put("contextPath", themeDisplay.getPathContext());
taskContextMap.put("gId", themeDisplay.getScopeGroupId());
BackgroundTaskManagerUtil.addBackgroundTask(i.getUserId(),i.getGroupId(),"ConvertVideo",VideoConverter.class.getName(),
taskContextMap, new ServiceContext());
}
/**
* Gets all Ideas that reference layoutRef
......
......@@ -13,6 +13,6 @@
##
build.namespace=IDEA
build.number=233
build.date=1516699218468
build.number=234
build.date=1521122805788
build.auto.upgrade=true
\ No newline at end of file
......@@ -13,6 +13,6 @@
##
build.namespace=PROJECT
build.number=145
build.date=1516699221538
build.number=146
build.date=1521122808612
build.auto.upgrade=true
\ No newline at end of file
......@@ -13,6 +13,6 @@
##
build.namespace=SURVEY
build.number=244
build.date=1516699226534
build.number=245
build.date=1521122813867
build.auto.upgrade=true
\ No newline at end of file
Supports Markdown
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