001    /**
002     * Copyright (c) 2000-2013 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.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.image.ImageBag;
019    import com.liferay.portal.kernel.image.ImageToolUtil;
020    import com.liferay.portal.kernel.lar.PortletDataContext;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.messaging.DestinationNames;
024    import com.liferay.portal.kernel.process.ClassPathUtil;
025    import com.liferay.portal.kernel.process.ProcessCallable;
026    import com.liferay.portal.kernel.process.ProcessException;
027    import com.liferay.portal.kernel.process.ProcessExecutor;
028    import com.liferay.portal.kernel.repository.model.FileEntry;
029    import com.liferay.portal.kernel.repository.model.FileVersion;
030    import com.liferay.portal.kernel.util.FileUtil;
031    import com.liferay.portal.kernel.util.PropsKeys;
032    import com.liferay.portal.kernel.util.ServerDetector;
033    import com.liferay.portal.kernel.util.SetUtil;
034    import com.liferay.portal.kernel.util.StreamUtil;
035    import com.liferay.portal.kernel.util.StringBundler;
036    import com.liferay.portal.kernel.util.StringPool;
037    import com.liferay.portal.kernel.util.SystemEnv;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.kernel.xml.Element;
040    import com.liferay.portal.kernel.xuggler.XugglerUtil;
041    import com.liferay.portal.log.Log4jLogFactoryImpl;
042    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
043    import com.liferay.portal.util.PropsUtil;
044    import com.liferay.portal.util.PropsValues;
045    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
046    import com.liferay.util.log4j.Log4JUtil;
047    
048    import java.awt.image.RenderedImage;
049    
050    import java.io.File;
051    import java.io.InputStream;
052    
053    import java.util.List;
054    import java.util.Map;
055    import java.util.Properties;
056    import java.util.Set;
057    import java.util.Vector;
058    import java.util.concurrent.CancellationException;
059    import java.util.concurrent.Future;
060    
061    import org.apache.commons.lang.time.StopWatch;
062    
063    /**
064     * @author Juan Gonz??lez
065     * @author Sergio Gonz??lez
066     * @author Mika Koivisto
067     * @author Ivica Cardic
068     */
069    public class VideoProcessorImpl
070            extends DLPreviewableProcessor implements VideoProcessor {
071    
072            @Override
073            public void afterPropertiesSet() {
074                    boolean valid = true;
075    
076                    if ((_PREVIEW_TYPES.length == 0) || (_PREVIEW_TYPES.length > 2)) {
077                            valid = false;
078                    }
079                    else {
080                            for (String previewType : _PREVIEW_TYPES) {
081                                    if (!previewType.equals("mp4") && !previewType.equals("ogv")) {
082                                            valid = false;
083    
084                                            break;
085                                    }
086                            }
087                    }
088    
089                    if (!valid && _log.isWarnEnabled()) {
090                            StringBundler sb = new StringBundler(5);
091    
092                            sb.append("Liferay is incorrectly configured to generate video ");
093                            sb.append("previews using video containers other than MP4 or ");
094                            sb.append("OGV. Please change the property ");
095                            sb.append(PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS);
096                            sb.append(" in portal-ext.properties.");
097    
098                            _log.warn(sb.toString());
099                    }
100    
101                    FileUtil.mkdirs(PREVIEW_TMP_PATH);
102                    FileUtil.mkdirs(THUMBNAIL_TMP_PATH);
103            }
104    
105            @Override
106            public void generateVideo(
107                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
108                    throws Exception {
109    
110                    _generateVideo(sourceFileVersion, destinationFileVersion);
111            }
112    
113            @Override
114            public InputStream getPreviewAsStream(FileVersion fileVersion, String type)
115                    throws Exception {
116    
117                    return doGetPreviewAsStream(fileVersion, type);
118            }
119    
120            @Override
121            public long getPreviewFileSize(FileVersion fileVersion, String type)
122                    throws Exception {
123    
124                    return doGetPreviewFileSize(fileVersion, type);
125            }
126    
127            @Override
128            public InputStream getThumbnailAsStream(FileVersion fileVersion, int index)
129                    throws Exception {
130    
131                    return doGetThumbnailAsStream(fileVersion, index);
132            }
133    
134            @Override
135            public long getThumbnailFileSize(FileVersion fileVersion, int index)
136                    throws Exception {
137    
138                    return doGetThumbnailFileSize(fileVersion, index);
139            }
140    
141            @Override
142            public Set<String> getVideoMimeTypes() {
143                    return _videoMimeTypes;
144            }
145    
146            @Override
147            public boolean hasVideo(FileVersion fileVersion) {
148                    boolean hasVideo = false;
149    
150                    try {
151                            hasVideo = _hasVideo(fileVersion);
152    
153                            if (!hasVideo && isSupported(fileVersion)) {
154                                    _queueGeneration(null, fileVersion);
155                            }
156                    }
157                    catch (Exception e) {
158                            _log.error(e, e);
159                    }
160    
161                    return hasVideo;
162            }
163    
164            @Override
165            public boolean isSupported(String mimeType) {
166                    if (Validator.isNull(mimeType)) {
167                            return false;
168                    }
169    
170                    try {
171                            if (XugglerUtil.isEnabled()) {
172                                    return _videoMimeTypes.contains(mimeType);
173                            }
174                    }
175                    catch (Exception e) {
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(),
336                                                            file.getCanonicalPath(), thumbnailTempFile,
337                                                            THUMBNAIL_TYPE, height, width,
338                                                            PropsValues.
339                                                                    DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE);
340    
341                                            Future<String> future = ProcessExecutor.execute(
342                                                    ClassPathUtil.getPortalClassPath(), processCallable);
343    
344                                            String processIdentity = String.valueOf(
345                                                    fileVersion.getFileVersionId());
346    
347                                            futures.put(processIdentity, future);
348    
349                                            future.get();
350                                    }
351                                    else {
352                                            LiferayConverter liferayConverter =
353                                                    new LiferayVideoThumbnailConverter(
354                                                            file.getCanonicalPath(), thumbnailTempFile,
355                                                            THUMBNAIL_TYPE, height, width,
356                                                            PropsValues.
357                                                                    DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE);
358    
359                                            liferayConverter.convert();
360                                    }
361                            }
362                            catch (CancellationException ce) {
363                                    if (_log.isInfoEnabled()) {
364                                            _log.info(
365                                                    "Cancellation received for " +
366                                                            fileVersion.getFileVersionId() + " " +
367                                                                    fileVersion.getTitle());
368                                    }
369                            }
370                            catch (Exception e) {
371                                    _log.error(e, e);
372                            }
373    
374                            storeThumbnailImages(fileVersion, thumbnailTempFile);
375    
376                            if (_log.isInfoEnabled()) {
377                                    _log.info(
378                                            "Xuggler generated a thumbnail for " +
379                                                    fileVersion.getTitle() + " in " + stopWatch.getTime() +
380                                                            " ms");
381                            }
382                    }
383                    catch (Exception e) {
384                            throw new SystemException(e);
385                    }
386                    finally {
387                            FileUtil.delete(thumbnailTempFile);
388                    }
389            }
390    
391            private void _generateVideo(
392                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
393                    throws Exception {
394    
395                    if (!XugglerUtil.isEnabled() || _hasVideo(destinationFileVersion)) {
396                            return;
397                    }
398    
399                    InputStream inputStream = null;
400    
401                    File[] previewTempFiles = new File[_PREVIEW_TYPES.length];
402    
403                    File videoTempFile = null;
404    
405                    try {
406                            if (sourceFileVersion != null) {
407                                    copy(sourceFileVersion, destinationFileVersion);
408    
409                                    return;
410                            }
411    
412                            File file = null;
413    
414                            if (!hasPreviews(destinationFileVersion) ||
415                                    !hasThumbnails(destinationFileVersion)) {
416    
417                                    if (destinationFileVersion instanceof LiferayFileVersion) {
418                                            try {
419                                                    LiferayFileVersion liferayFileVersion =
420                                                            (LiferayFileVersion)destinationFileVersion;
421    
422                                                    file = liferayFileVersion.getFile(false);
423                                            }
424                                            catch (UnsupportedOperationException uoe) {
425                                            }
426                                    }
427    
428                                    if (file == null) {
429                                            inputStream = destinationFileVersion.getContentStream(
430                                                    false);
431    
432                                            videoTempFile = FileUtil.createTempFile(
433                                                    destinationFileVersion.getExtension());
434    
435                                            FileUtil.write(videoTempFile, inputStream);
436    
437                                            file = videoTempFile;
438                                    }
439                            }
440    
441                            if (!hasPreviews(destinationFileVersion)) {
442                                    String tempFileId = DLUtil.getTempFileId(
443                                            destinationFileVersion.getFileEntryId(),
444                                            destinationFileVersion.getVersion());
445    
446                                    for (int i = 0; i < _PREVIEW_TYPES.length; i++) {
447                                            previewTempFiles[i] = getPreviewTempFile(
448                                                    tempFileId, _PREVIEW_TYPES[i]);
449                                    }
450    
451                                    try {
452                                            _generateVideoXuggler(
453                                                    destinationFileVersion, file, previewTempFiles,
454                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
455                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
456                                    }
457                                    catch (Exception e) {
458                                            _log.error(e, e);
459                                    }
460                            }
461    
462                            if (!hasThumbnails(destinationFileVersion)) {
463                                    try {
464                                            _generateThumbnailXuggler(
465                                                    destinationFileVersion, file,
466                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
467                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
468                                    }
469                                    catch (Exception e) {
470                                            _log.error(e, e);
471                                    }
472                            }
473                    }
474                    catch (NoSuchFileEntryException nsfee) {
475                    }
476                    finally {
477                            StreamUtil.cleanUp(inputStream);
478    
479                            _fileVersionIds.remove(destinationFileVersion.getFileVersionId());
480    
481                            for (int i = 0; i < previewTempFiles.length; i++) {
482                                    FileUtil.delete(previewTempFiles[i]);
483                            }
484    
485                            FileUtil.delete(videoTempFile);
486                    }
487            }
488    
489            private void _generateVideoXuggler(
490                            FileVersion fileVersion, File sourceFile, File destinationFile,
491                            String containerType)
492                    throws Exception {
493    
494                    if (hasPreview(fileVersion, containerType)) {
495                            return;
496                    }
497    
498                    StopWatch stopWatch = new StopWatch();
499    
500                    stopWatch.start();
501    
502                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
503                            ProcessCallable<String> processCallable =
504                                    new LiferayVideoProcessCallable(
505                                            ServerDetector.getServerId(),
506                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
507                                            Log4JUtil.getCustomLogSettings(),
508                                            sourceFile.getCanonicalPath(),
509                                            destinationFile.getCanonicalPath(), containerType,
510                                            PropsUtil.getProperties(
511                                                    PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
512                                            PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
513    
514                            Future<String> future = ProcessExecutor.execute(
515                                    ClassPathUtil.getPortalClassPath(), processCallable);
516    
517                            String processIdentity = Long.toString(
518                                    fileVersion.getFileVersionId());
519    
520                            futures.put(processIdentity, future);
521    
522                            future.get();
523                    }
524                    else {
525                            LiferayConverter liferayConverter = new LiferayVideoConverter(
526                                    sourceFile.getCanonicalPath(),
527                                    destinationFile.getCanonicalPath(), containerType,
528                                    PropsUtil.getProperties(
529                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
530                                    PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
531    
532                            liferayConverter.convert();
533                    }
534    
535                    addFileToStore(
536                            fileVersion.getCompanyId(), PREVIEW_PATH,
537                            getPreviewFilePath(fileVersion, containerType), destinationFile);
538    
539                    if (_log.isInfoEnabled()) {
540                            _log.info(
541                                    "Xuggler generated a " + containerType + " preview video for " +
542                                            fileVersion.getTitle() + " in " + stopWatch.getTime() +
543                                                    " ms");
544                    }
545            }
546    
547            private void _generateVideoXuggler(
548                    FileVersion fileVersion, File sourceFile, File[] destinationFiles,
549                    int height, int width) {
550    
551                    try {
552                            for (int i = 0; i < destinationFiles.length; i++) {
553                                    _generateVideoXuggler(
554                                            fileVersion, sourceFile, destinationFiles[i],
555                                            _PREVIEW_TYPES[i]);
556                            }
557                    }
558                    catch (CancellationException ce) {
559                            if (_log.isInfoEnabled()) {
560                                    _log.info(
561                                            "Cancellation received for " +
562                                                    fileVersion.getFileVersionId() + " " +
563                                                            fileVersion.getTitle());
564                            }
565                    }
566                    catch (Exception e) {
567                            _log.error(e, e);
568                    }
569            }
570    
571            private boolean _hasVideo(FileVersion fileVersion) throws Exception {
572                    if (!isSupported(fileVersion)) {
573                            return false;
574                    }
575    
576                    return hasPreviews(fileVersion) && hasThumbnails(fileVersion);
577            }
578    
579            private void _queueGeneration(
580                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
581    
582                    if (_fileVersionIds.contains(
583                                    destinationFileVersion.getFileVersionId()) ||
584                            !isSupported(destinationFileVersion)) {
585    
586                            return;
587                    }
588    
589                    _fileVersionIds.add(destinationFileVersion.getFileVersionId());
590    
591                    sendGenerationMessage(
592                            DestinationNames.DOCUMENT_LIBRARY_VIDEO_PROCESSOR,
593                            sourceFileVersion, destinationFileVersion);
594            }
595    
596            private static final String[] _PREVIEW_TYPES =
597                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS;
598    
599            private static Log _log = LogFactoryUtil.getLog(VideoProcessorImpl.class);
600    
601            private List<Long> _fileVersionIds = new Vector<Long>();
602            private Set<String> _videoMimeTypes = SetUtil.fromArray(
603                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_MIME_TYPES);
604    
605            private static class LiferayVideoProcessCallable
606                    implements ProcessCallable<String> {
607    
608                    public LiferayVideoProcessCallable(
609                            String serverId, String liferayHome,
610                            Map<String, String> customLogSettings, String inputURL,
611                            String outputURL, String videoContainer, Properties videoProperties,
612                            Properties ffpresetProperties) {
613    
614                            _serverId = serverId;
615                            _liferayHome = liferayHome;
616                            _customLogSettings = customLogSettings;
617                            _inputURL = inputURL;
618                            _outputURL = outputURL;
619                            _videoContainer = videoContainer;
620                            _videoProperties = videoProperties;
621                            _ffpresetProperties = ffpresetProperties;
622                    }
623    
624                    @Override
625                    public String call() throws ProcessException {
626                            Properties systemProperties = System.getProperties();
627    
628                            SystemEnv.setProperties(systemProperties);
629    
630                            Class<?> clazz = getClass();
631    
632                            ClassLoader classLoader = clazz.getClassLoader();
633    
634                            Log4JUtil.initLog4J(
635                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
636                                    _customLogSettings);
637    
638                            try {
639                                    LiferayConverter liferayConverter = new LiferayVideoConverter(
640                                            _inputURL, _outputURL, _videoContainer, _videoProperties,
641                                            _ffpresetProperties);
642    
643                                    liferayConverter.convert();
644                            }
645                            catch (Exception e) {
646                                    throw new ProcessException(e);
647                            }
648    
649                            return StringPool.BLANK;
650                    }
651    
652                    private static final long serialVersionUID = 1L;
653    
654                    private Map<String, String> _customLogSettings;
655                    private Properties _ffpresetProperties;
656                    private String _inputURL;
657                    private String _liferayHome;
658                    private String _outputURL;
659                    private String _serverId;
660                    private String _videoContainer;
661                    private Properties _videoProperties;
662    
663            }
664    
665            private static class LiferayVideoThumbnailProcessCallable
666                    implements ProcessCallable<String> {
667    
668                    public LiferayVideoThumbnailProcessCallable(
669                            String serverId, String liferayHome,
670                            Map<String, String> customLogSettings, String inputURL,
671                            File outputFile, String extension, int height, int width,
672                            int percentage) {
673    
674                            _serverId = serverId;
675                            _liferayHome = liferayHome;
676                            _customLogSettings = customLogSettings;
677                            _inputURL = inputURL;
678                            _outputFile = outputFile;
679                            _extension = extension;
680                            _height = height;
681                            _width = width;
682                            _percentage = percentage;
683                    }
684    
685                    @Override
686                    public String call() throws ProcessException {
687                            Class<?> clazz = getClass();
688    
689                            ClassLoader classLoader = clazz.getClassLoader();
690    
691                            Properties systemProperties = System.getProperties();
692                            SystemEnv.setProperties(systemProperties);
693    
694                            Log4JUtil.initLog4J(
695                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
696                                    _customLogSettings);
697    
698                            try {
699                                    LiferayConverter liferayConverter =
700                                            new LiferayVideoThumbnailConverter(
701                                                    _inputURL, _outputFile, _extension, _height, _width,
702                                                    _percentage);
703    
704                                    liferayConverter.convert();
705                            }
706                            catch (Exception e) {
707                                    throw new ProcessException(e);
708                            }
709    
710                            return StringPool.BLANK;
711                    }
712    
713                    private static final long serialVersionUID = 1L;
714    
715                    private Map<String, String> _customLogSettings;
716                    private String _extension;
717                    private int _height;
718                    private String _inputURL;
719                    private String _liferayHome;
720                    private File _outputFile;
721                    private int _percentage;
722                    private String _serverId;
723                    private int _width;
724    
725            }
726    
727    }