001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.util;
016    
017    import com.liferay.portal.fabric.InputResource;
018    import com.liferay.portal.fabric.OutputResource;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.image.ImageBag;
021    import com.liferay.portal.kernel.image.ImageToolUtil;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.messaging.DestinationNames;
025    import com.liferay.portal.kernel.process.ClassPathUtil;
026    import com.liferay.portal.kernel.process.ProcessCallable;
027    import com.liferay.portal.kernel.process.ProcessChannel;
028    import com.liferay.portal.kernel.process.ProcessException;
029    import com.liferay.portal.kernel.process.ProcessExecutorUtil;
030    import com.liferay.portal.kernel.repository.model.FileEntry;
031    import com.liferay.portal.kernel.repository.model.FileVersion;
032    import com.liferay.portal.kernel.util.FileUtil;
033    import com.liferay.portal.kernel.util.PropsKeys;
034    import com.liferay.portal.kernel.util.ServerDetector;
035    import com.liferay.portal.kernel.util.SetUtil;
036    import com.liferay.portal.kernel.util.StreamUtil;
037    import com.liferay.portal.kernel.util.StringBundler;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.SystemEnv;
040    import com.liferay.portal.kernel.xml.Element;
041    import com.liferay.portal.kernel.xuggler.XugglerUtil;
042    import com.liferay.portal.log.Log4jLogFactoryImpl;
043    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
044    import com.liferay.portal.util.PropsUtil;
045    import com.liferay.portal.util.PropsValues;
046    import com.liferay.portlet.documentlibrary.exception.NoSuchFileEntryException;
047    import com.liferay.portlet.documentlibrary.model.DLProcessorConstants;
048    import com.liferay.portlet.exportimport.lar.PortletDataContext;
049    import com.liferay.util.log4j.Log4JUtil;
050    
051    import java.awt.image.RenderedImage;
052    
053    import java.io.File;
054    import java.io.InputStream;
055    
056    import java.util.List;
057    import java.util.Map;
058    import java.util.Properties;
059    import java.util.Set;
060    import java.util.Vector;
061    import java.util.concurrent.CancellationException;
062    import java.util.concurrent.Future;
063    
064    import org.apache.commons.lang.time.StopWatch;
065    
066    /**
067     * @author Juan Gonz??lez
068     * @author Sergio Gonz??lez
069     * @author Mika Koivisto
070     * @author Ivica Cardic
071     */
072    public class VideoProcessorImpl
073            extends DLPreviewableProcessor implements VideoProcessor {
074    
075            @Override
076            public void afterPropertiesSet() {
077                    boolean valid = true;
078    
079                    if ((_PREVIEW_TYPES.length == 0) || (_PREVIEW_TYPES.length > 2)) {
080                            valid = false;
081                    }
082                    else {
083                            for (String previewType : _PREVIEW_TYPES) {
084                                    if (!previewType.equals("mp4") && !previewType.equals("ogv")) {
085                                            valid = false;
086    
087                                            break;
088                                    }
089                            }
090                    }
091    
092                    if (!valid && _log.isWarnEnabled()) {
093                            StringBundler sb = new StringBundler(5);
094    
095                            sb.append("Liferay is incorrectly configured to generate video ");
096                            sb.append("previews using video containers other than MP4 or ");
097                            sb.append("OGV. Please change the property ");
098                            sb.append(PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS);
099                            sb.append(" in portal-ext.properties.");
100    
101                            _log.warn(sb.toString());
102                    }
103    
104                    FileUtil.mkdirs(PREVIEW_TMP_PATH);
105                    FileUtil.mkdirs(THUMBNAIL_TMP_PATH);
106            }
107    
108            @Override
109            public void generateVideo(
110                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
111                    throws Exception {
112    
113                    _generateVideo(sourceFileVersion, destinationFileVersion);
114            }
115    
116            @Override
117            public InputStream getPreviewAsStream(FileVersion fileVersion, String type)
118                    throws Exception {
119    
120                    return doGetPreviewAsStream(fileVersion, type);
121            }
122    
123            @Override
124            public long getPreviewFileSize(FileVersion fileVersion, String type)
125                    throws Exception {
126    
127                    return doGetPreviewFileSize(fileVersion, type);
128            }
129    
130            @Override
131            public InputStream getThumbnailAsStream(FileVersion fileVersion, int index)
132                    throws Exception {
133    
134                    return doGetThumbnailAsStream(fileVersion, index);
135            }
136    
137            @Override
138            public long getThumbnailFileSize(FileVersion fileVersion, int index)
139                    throws Exception {
140    
141                    return doGetThumbnailFileSize(fileVersion, index);
142            }
143    
144            @Override
145            public String getType() {
146                    return DLProcessorConstants.VIDEO_PROCESSOR;
147            }
148    
149            @Override
150            public Set<String> getVideoMimeTypes() {
151                    return _videoMimeTypes;
152            }
153    
154            @Override
155            public boolean hasVideo(FileVersion fileVersion) {
156                    boolean hasVideo = false;
157    
158                    try {
159                            hasVideo = _hasVideo(fileVersion);
160    
161                            if (!hasVideo && isSupported(fileVersion)) {
162                                    _queueGeneration(null, fileVersion);
163                            }
164                    }
165                    catch (Exception e) {
166                            _log.error(e, e);
167                    }
168    
169                    return hasVideo;
170            }
171    
172            @Override
173            public boolean isSupported(String mimeType) {
174                    if (_videoMimeTypes.contains(mimeType) && XugglerUtil.isEnabled()) {
175                            return true;
176                    }
177    
178                    return false;
179            }
180    
181            @Override
182            public boolean isVideoSupported(FileVersion fileVersion) {
183                    return isSupported(fileVersion);
184            }
185    
186            @Override
187            public boolean isVideoSupported(String mimeType) {
188                    return isSupported(mimeType);
189            }
190    
191            @Override
192            public void trigger(
193                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
194    
195                    super.trigger(sourceFileVersion, destinationFileVersion);
196    
197                    _queueGeneration(sourceFileVersion, destinationFileVersion);
198            }
199    
200            @Override
201            protected void doExportGeneratedFiles(
202                            PortletDataContext portletDataContext, FileEntry fileEntry,
203                            Element fileEntryElement)
204                    throws Exception {
205    
206                    exportThumbnails(
207                            portletDataContext, fileEntry, fileEntryElement, "video");
208    
209                    exportPreviews(portletDataContext, fileEntry, fileEntryElement);
210            }
211    
212            @Override
213            protected void doImportGeneratedFiles(
214                            PortletDataContext portletDataContext, FileEntry fileEntry,
215                            FileEntry importedFileEntry, Element fileEntryElement)
216                    throws Exception {
217    
218                    importThumbnails(
219                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement,
220                            "video");
221    
222                    importPreviews(
223                            portletDataContext, fileEntry, importedFileEntry, fileEntryElement);
224            }
225    
226            protected void exportPreviews(
227                            PortletDataContext portletDataContext, FileEntry fileEntry,
228                            Element fileEntryElement)
229                    throws Exception {
230    
231                    FileVersion fileVersion = fileEntry.getFileVersion();
232    
233                    if (!isSupported(fileVersion) || !hasPreviews(fileVersion)) {
234                            return;
235                    }
236    
237                    if (!portletDataContext.isPerformDirectBinaryImport()) {
238                            if ((_PREVIEW_TYPES.length == 0) || (_PREVIEW_TYPES.length > 2)) {
239                                    return;
240                            }
241    
242                            for (String previewType : _PREVIEW_TYPES) {
243                                    if (previewType.equals("mp4") || previewType.equals("ogv")) {
244                                            exportPreview(
245                                                    portletDataContext, fileEntry, fileEntryElement,
246                                                    "video", previewType);
247                                    }
248                            }
249                    }
250            }
251    
252            @Override
253            protected List<Long> getFileVersionIds() {
254                    return _fileVersionIds;
255            }
256    
257            @Override
258            protected String getPreviewType(FileVersion fileVersion) {
259                    return _PREVIEW_TYPES[0];
260            }
261    
262            @Override
263            protected String[] getPreviewTypes() {
264                    return _PREVIEW_TYPES;
265            }
266    
267            @Override
268            protected String getThumbnailType(FileVersion fileVersion) {
269                    return THUMBNAIL_TYPE;
270            }
271    
272            protected void importPreviews(
273                            PortletDataContext portletDataContext, FileEntry fileEntry,
274                            FileEntry importedFileEntry, Element fileEntryElement)
275                    throws Exception {
276    
277                    if ((_PREVIEW_TYPES.length == 0) || (_PREVIEW_TYPES.length > 2)) {
278                            return;
279                    }
280    
281                    for (String previewType : _PREVIEW_TYPES) {
282                            if (previewType.equals("mp4") || previewType.equals("ogv")) {
283                                    importPreview(
284                                            portletDataContext, fileEntry, importedFileEntry,
285                                            fileEntryElement, "video", previewType);
286                            }
287                    }
288            }
289    
290            @Override
291            protected void storeThumbnailImages(FileVersion fileVersion, File file)
292                    throws Exception {
293    
294                    if (!hasThumbnail(fileVersion, THUMBNAIL_INDEX_DEFAULT)) {
295                            addFileToStore(
296                                    fileVersion.getCompanyId(), THUMBNAIL_PATH,
297                                    getThumbnailFilePath(fileVersion, THUMBNAIL_INDEX_DEFAULT),
298                                    file);
299                    }
300    
301                    if (isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_1) ||
302                            isThumbnailEnabled(THUMBNAIL_INDEX_CUSTOM_2)) {
303    
304                            ImageBag imageBag = ImageToolUtil.read(file);
305    
306                            RenderedImage renderedImage = imageBag.getRenderedImage();
307    
308                            storeThumbnailImage(
309                                    fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
310                            storeThumbnailImage(
311                                    fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_2);
312                    }
313            }
314    
315            private void _generateThumbnailXuggler(
316                            FileVersion fileVersion, File file, int height, int width)
317                    throws Exception {
318    
319                    StopWatch stopWatch = new StopWatch();
320    
321                    stopWatch.start();
322    
323                    String tempFileId = DLUtil.getTempFileId(
324                            fileVersion.getFileEntryId(), fileVersion.getVersion());
325    
326                    File thumbnailTempFile = getThumbnailTempFile(tempFileId);
327    
328                    try {
329                            try {
330                                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
331                                            ProcessCallable<String> processCallable =
332                                                    new LiferayVideoThumbnailProcessCallable(
333                                                            ServerDetector.getServerId(),
334                                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
335                                                            Log4JUtil.getCustomLogSettings(), file,
336                                                            thumbnailTempFile, THUMBNAIL_TYPE, height, width,
337                                                            PropsValues.
338                                                                    DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE);
339    
340                                            ProcessChannel<String> processChannel =
341                                                    ProcessExecutorUtil.execute(
342                                                            ClassPathUtil.getPortalProcessConfig(),
343                                                            processCallable);
344    
345                                            Future<String> future =
346                                                    processChannel.getProcessNoticeableFuture();
347    
348                                            String processIdentity = String.valueOf(
349                                                    fileVersion.getFileVersionId());
350    
351                                            futures.put(processIdentity, future);
352    
353                                            future.get();
354                                    }
355                                    else {
356                                            LiferayConverter liferayConverter =
357                                                    new LiferayVideoThumbnailConverter(
358                                                            file.getCanonicalPath(), thumbnailTempFile,
359                                                            THUMBNAIL_TYPE, height, width,
360                                                            PropsValues.
361                                                                    DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE);
362    
363                                            liferayConverter.convert();
364                                    }
365                            }
366                            catch (CancellationException ce) {
367                                    if (_log.isInfoEnabled()) {
368                                            _log.info(
369                                                    "Cancellation received for " +
370                                                            fileVersion.getFileVersionId() + " " +
371                                                                    fileVersion.getTitle());
372                                    }
373                            }
374                            catch (Exception e) {
375                                    _log.error(e, e);
376                            }
377    
378                            storeThumbnailImages(fileVersion, thumbnailTempFile);
379    
380                            if (_log.isInfoEnabled()) {
381                                    _log.info(
382                                            "Xuggler generated a thumbnail for " +
383                                                    fileVersion.getTitle() + " in " + stopWatch.getTime() +
384                                                            " ms");
385                            }
386                    }
387                    catch (Exception e) {
388                            throw new SystemException(e);
389                    }
390                    finally {
391                            FileUtil.delete(thumbnailTempFile);
392                    }
393            }
394    
395            private void _generateVideo(
396                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
397                    throws Exception {
398    
399                    if (!XugglerUtil.isEnabled() || _hasVideo(destinationFileVersion)) {
400                            return;
401                    }
402    
403                    InputStream inputStream = null;
404    
405                    File[] previewTempFiles = new File[_PREVIEW_TYPES.length];
406    
407                    File videoTempFile = null;
408    
409                    try {
410                            if (sourceFileVersion != null) {
411                                    copy(sourceFileVersion, destinationFileVersion);
412    
413                                    return;
414                            }
415    
416                            File file = null;
417    
418                            if (!hasPreviews(destinationFileVersion) ||
419                                    !hasThumbnails(destinationFileVersion)) {
420    
421                                    if (destinationFileVersion instanceof LiferayFileVersion) {
422                                            try {
423                                                    LiferayFileVersion liferayFileVersion =
424                                                            (LiferayFileVersion)destinationFileVersion;
425    
426                                                    file = liferayFileVersion.getFile(false);
427                                            }
428                                            catch (UnsupportedOperationException uoe) {
429                                            }
430                                    }
431    
432                                    if (file == null) {
433                                            inputStream = destinationFileVersion.getContentStream(
434                                                    false);
435    
436                                            videoTempFile = FileUtil.createTempFile(
437                                                    destinationFileVersion.getExtension());
438    
439                                            FileUtil.write(videoTempFile, inputStream);
440    
441                                            file = videoTempFile;
442                                    }
443                            }
444    
445                            if (!hasPreviews(destinationFileVersion)) {
446                                    String tempFileId = DLUtil.getTempFileId(
447                                            destinationFileVersion.getFileEntryId(),
448                                            destinationFileVersion.getVersion());
449    
450                                    for (int i = 0; i < _PREVIEW_TYPES.length; i++) {
451                                            previewTempFiles[i] = getPreviewTempFile(
452                                                    tempFileId, _PREVIEW_TYPES[i]);
453                                    }
454    
455                                    try {
456                                            _generateVideoXuggler(
457                                                    destinationFileVersion, file, previewTempFiles);
458                                    }
459                                    catch (Exception e) {
460                                            _log.error(e, e);
461                                    }
462                            }
463    
464                            if (!hasThumbnails(destinationFileVersion)) {
465                                    try {
466                                            _generateThumbnailXuggler(
467                                                    destinationFileVersion, file,
468                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
469                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
470                                    }
471                                    catch (Exception e) {
472                                            _log.error(e, e);
473                                    }
474                            }
475                    }
476                    catch (NoSuchFileEntryException nsfee) {
477                            if (_log.isDebugEnabled()) {
478                                    _log.debug(nsfee, nsfee);
479                            }
480                    }
481                    finally {
482                            StreamUtil.cleanUp(inputStream);
483    
484                            _fileVersionIds.remove(destinationFileVersion.getFileVersionId());
485    
486                            for (int i = 0; i < previewTempFiles.length; i++) {
487                                    FileUtil.delete(previewTempFiles[i]);
488                            }
489    
490                            FileUtil.delete(videoTempFile);
491                    }
492            }
493    
494            private void _generateVideoXuggler(
495                            FileVersion fileVersion, File sourceFile, File destinationFile,
496                            String containerType)
497                    throws Exception {
498    
499                    if (hasPreview(fileVersion, containerType)) {
500                            return;
501                    }
502    
503                    StopWatch stopWatch = new StopWatch();
504    
505                    stopWatch.start();
506    
507                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
508                            ProcessCallable<String> processCallable =
509                                    new LiferayVideoProcessCallable(
510                                            ServerDetector.getServerId(),
511                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
512                                            Log4JUtil.getCustomLogSettings(), sourceFile,
513                                            destinationFile, containerType,
514                                            PropsUtil.getProperties(
515                                                    PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
516                                            PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
517    
518                            ProcessChannel<String> processChannel = ProcessExecutorUtil.execute(
519                                    ClassPathUtil.getPortalProcessConfig(), processCallable);
520    
521                            Future<String> future = processChannel.getProcessNoticeableFuture();
522    
523                            String processIdentity = String.valueOf(
524                                    fileVersion.getFileVersionId());
525    
526                            futures.put(processIdentity, future);
527    
528                            future.get();
529                    }
530                    else {
531                            LiferayConverter liferayConverter = new LiferayVideoConverter(
532                                    sourceFile.getCanonicalPath(),
533                                    destinationFile.getCanonicalPath(), containerType,
534                                    PropsUtil.getProperties(
535                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
536                                    PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
537    
538                            liferayConverter.convert();
539                    }
540    
541                    addFileToStore(
542                            fileVersion.getCompanyId(), PREVIEW_PATH,
543                            getPreviewFilePath(fileVersion, containerType), destinationFile);
544    
545                    if (_log.isInfoEnabled()) {
546                            _log.info(
547                                    "Xuggler generated a " + containerType + " preview video for " +
548                                            fileVersion.getTitle() + " in " + stopWatch.getTime() +
549                                                    " ms");
550                    }
551            }
552    
553            private void _generateVideoXuggler(
554                    FileVersion fileVersion, File sourceFile, File[] destinationFiles) {
555    
556                    try {
557                            for (int i = 0; i < destinationFiles.length; i++) {
558                                    _generateVideoXuggler(
559                                            fileVersion, sourceFile, destinationFiles[i],
560                                            _PREVIEW_TYPES[i]);
561                            }
562                    }
563                    catch (CancellationException ce) {
564                            if (_log.isInfoEnabled()) {
565                                    _log.info(
566                                            "Cancellation received for " +
567                                                    fileVersion.getFileVersionId() + " " +
568                                                            fileVersion.getTitle());
569                            }
570                    }
571                    catch (Exception e) {
572                            _log.error(e, e);
573                    }
574            }
575    
576            private boolean _hasVideo(FileVersion fileVersion) throws Exception {
577                    if (!isSupported(fileVersion)) {
578                            return false;
579                    }
580    
581                    return hasPreviews(fileVersion) && hasThumbnails(fileVersion);
582            }
583    
584            private void _queueGeneration(
585                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
586    
587                    if (_fileVersionIds.contains(
588                                    destinationFileVersion.getFileVersionId()) ||
589                            !isSupported(destinationFileVersion)) {
590    
591                            return;
592                    }
593    
594                    _fileVersionIds.add(destinationFileVersion.getFileVersionId());
595    
596                    sendGenerationMessage(
597                            DestinationNames.DOCUMENT_LIBRARY_VIDEO_PROCESSOR,
598                            sourceFileVersion, destinationFileVersion);
599            }
600    
601            private static final String[] _PREVIEW_TYPES =
602                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS;
603    
604            private static final Log _log = LogFactoryUtil.getLog(
605                    VideoProcessorImpl.class);
606    
607            private final List<Long> _fileVersionIds = new Vector<>();
608            private final Set<String> _videoMimeTypes = SetUtil.fromArray(
609                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_MIME_TYPES);
610    
611            private static class LiferayVideoProcessCallable
612                    implements ProcessCallable<String> {
613    
614                    public LiferayVideoProcessCallable(
615                            String serverId, String liferayHome,
616                            Map<String, String> customLogSettings, File inputFile,
617                            File outputFile, String videoContainer, Properties videoProperties,
618                            Properties ffpresetProperties) {
619    
620                            _serverId = serverId;
621                            _liferayHome = liferayHome;
622                            _customLogSettings = customLogSettings;
623                            _inputFile = inputFile;
624                            _outputFile = outputFile;
625                            _videoContainer = videoContainer;
626                            _videoProperties = videoProperties;
627                            _ffpresetProperties = ffpresetProperties;
628                    }
629    
630                    @Override
631                    public String call() throws ProcessException {
632                            XugglerAutoInstallHelper.installNativeLibraries();
633    
634                            Properties systemProperties = System.getProperties();
635    
636                            SystemEnv.setProperties(systemProperties);
637    
638                            Class<?> clazz = getClass();
639    
640                            ClassLoader classLoader = clazz.getClassLoader();
641    
642                            Log4JUtil.initLog4J(
643                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
644                                    _customLogSettings);
645    
646                            try {
647                                    LiferayConverter liferayConverter = new LiferayVideoConverter(
648                                            _inputFile.getCanonicalPath(),
649                                            _outputFile.getCanonicalPath(), _videoContainer,
650                                            _videoProperties, _ffpresetProperties);
651    
652                                    liferayConverter.convert();
653                            }
654                            catch (Exception e) {
655                                    throw new ProcessException(e);
656                            }
657    
658                            return StringPool.BLANK;
659                    }
660    
661                    private static final long serialVersionUID = 1L;
662    
663                    private Map<String, String> _customLogSettings;
664                    private final Properties _ffpresetProperties;
665    
666                    @InputResource
667                    private File _inputFile;
668    
669                    private String _liferayHome;
670    
671                    @OutputResource
672                    private File _outputFile;
673    
674                    private String _serverId;
675                    private final String _videoContainer;
676                    private final Properties _videoProperties;
677    
678            }
679    
680            private static class LiferayVideoThumbnailProcessCallable
681                    implements ProcessCallable<String> {
682    
683                    public LiferayVideoThumbnailProcessCallable(
684                            String serverId, String liferayHome,
685                            Map<String, String> customLogSettings, File inputFile,
686                            File outputFile, String extension, int height, int width,
687                            int percentage) {
688    
689                            _serverId = serverId;
690                            _liferayHome = liferayHome;
691                            _customLogSettings = customLogSettings;
692                            _inputFile = inputFile;
693                            _outputFile = outputFile;
694                            _extension = extension;
695                            _height = height;
696                            _width = width;
697                            _percentage = percentage;
698                    }
699    
700                    @Override
701                    public String call() throws ProcessException {
702                            XugglerAutoInstallHelper.installNativeLibraries();
703    
704                            Class<?> clazz = getClass();
705    
706                            ClassLoader classLoader = clazz.getClassLoader();
707    
708                            Properties systemProperties = System.getProperties();
709                            SystemEnv.setProperties(systemProperties);
710    
711                            Log4JUtil.initLog4J(
712                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
713                                    _customLogSettings);
714    
715                            try {
716                                    LiferayConverter liferayConverter =
717                                            new LiferayVideoThumbnailConverter(
718                                                    _inputFile.getCanonicalPath(), _outputFile, _extension,
719                                                    _height, _width, _percentage);
720    
721                                    liferayConverter.convert();
722                            }
723                            catch (Exception e) {
724                                    throw new ProcessException(e);
725                            }
726    
727                            return StringPool.BLANK;
728                    }
729    
730                    private static final long serialVersionUID = 1L;
731    
732                    private Map<String, String> _customLogSettings;
733                    private final String _extension;
734                    private final int _height;
735    
736                    @InputResource
737                    private File _inputFile;
738    
739                    private String _liferayHome;
740    
741                    @OutputResource
742                    private File _outputFile;
743    
744                    private final int _percentage;
745                    private String _serverId;
746                    private final int _width;
747    
748            }
749    
750    }