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                            storeThumbnailmage(
309                                    fileVersion, renderedImage, THUMBNAIL_INDEX_CUSTOM_1);
310                            storeThumbnailmage(
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 = null;
320    
321                    if (_log.isInfoEnabled()) {
322                            stopWatch = new StopWatch();
323    
324                            stopWatch.start();
325                    }
326    
327                    String tempFileId = DLUtil.getTempFileId(
328                            fileVersion.getFileEntryId(), fileVersion.getVersion());
329    
330                    File thumbnailTempFile = getThumbnailTempFile(tempFileId);
331    
332                    try {
333                            try {
334                                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
335                                            ProcessCallable<String> processCallable =
336                                                    new LiferayVideoThumbnailProcessCallable(
337                                                            ServerDetector.getServerId(),
338                                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
339                                                            Log4JUtil.getCustomLogSettings(),
340                                                            file.getCanonicalPath(), thumbnailTempFile,
341                                                            THUMBNAIL_TYPE, height, width,
342                                                            PropsValues.
343                                                                    DL_FILE_ENTRY_THUMBNAIL_VIDEO_FRAME_PERCENTAGE);
344    
345                                            Future<String> future = ProcessExecutor.execute(
346                                                    ClassPathUtil.getPortalClassPath(), processCallable);
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);
384                            }
385                    }
386                    catch (Exception e) {
387                            throw new SystemException(e);
388                    }
389                    finally {
390                            FileUtil.delete(thumbnailTempFile);
391                    }
392            }
393    
394            private void _generateVideo(
395                            FileVersion sourceFileVersion, FileVersion destinationFileVersion)
396                    throws Exception {
397    
398                    if (!XugglerUtil.isEnabled() || _hasVideo(destinationFileVersion)) {
399                            return;
400                    }
401    
402                    InputStream inputStream = null;
403    
404                    File[] previewTempFiles = new File[_PREVIEW_TYPES.length];
405    
406                    File videoTempFile = null;
407    
408                    try {
409                            if (sourceFileVersion != null) {
410                                    copy(sourceFileVersion, destinationFileVersion);
411    
412                                    return;
413                            }
414    
415                            File file = null;
416    
417                            if (!hasPreviews(destinationFileVersion) ||
418                                    !hasThumbnails(destinationFileVersion)) {
419    
420                                    if (destinationFileVersion instanceof LiferayFileVersion) {
421                                            try {
422                                                    LiferayFileVersion liferayFileVersion =
423                                                            (LiferayFileVersion)destinationFileVersion;
424    
425                                                    file = liferayFileVersion.getFile(false);
426                                            }
427                                            catch (UnsupportedOperationException uoe) {
428                                            }
429                                    }
430    
431                                    if (file == null) {
432                                            inputStream = destinationFileVersion.getContentStream(
433                                                    false);
434    
435                                            videoTempFile = FileUtil.createTempFile(
436                                                    destinationFileVersion.getExtension());
437    
438                                            FileUtil.write(videoTempFile, inputStream);
439    
440                                            file = videoTempFile;
441                                    }
442                            }
443    
444                            if (!hasPreviews(destinationFileVersion)) {
445                                    String tempFileId = DLUtil.getTempFileId(
446                                            destinationFileVersion.getFileEntryId(),
447                                            destinationFileVersion.getVersion());
448    
449                                    for (int i = 0; i < _PREVIEW_TYPES.length; i++) {
450                                            previewTempFiles[i] = getPreviewTempFile(
451                                                    tempFileId, _PREVIEW_TYPES[i]);
452                                    }
453    
454                                    try {
455                                            _generateVideoXuggler(
456                                                    destinationFileVersion, file, previewTempFiles,
457                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
458                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
459                                    }
460                                    catch (Exception e) {
461                                            _log.error(e, e);
462                                    }
463                            }
464    
465                            if (!hasThumbnails(destinationFileVersion)) {
466                                    try {
467                                            _generateThumbnailXuggler(
468                                                    destinationFileVersion, file,
469                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_HEIGHT,
470                                                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_WIDTH);
471                                    }
472                                    catch (Exception e) {
473                                            _log.error(e, e);
474                                    }
475                            }
476                    }
477                    catch (NoSuchFileEntryException nsfee) {
478                    }
479                    finally {
480                            StreamUtil.cleanUp(inputStream);
481    
482                            _fileVersionIds.remove(destinationFileVersion.getFileVersionId());
483    
484                            for (int i = 0; i < previewTempFiles.length; i++) {
485                                    FileUtil.delete(previewTempFiles[i]);
486                            }
487    
488                            FileUtil.delete(videoTempFile);
489                    }
490            }
491    
492            private void _generateVideoXuggler(
493                            FileVersion fileVersion, File sourceFile, File destinationFile,
494                            String containerType)
495                    throws Exception {
496    
497                    if (hasPreview(fileVersion, containerType)) {
498                            return;
499                    }
500    
501                    StopWatch stopWatch = null;
502    
503                    if (_log.isInfoEnabled()) {
504                            stopWatch = new StopWatch();
505    
506                            stopWatch.start();
507                    }
508    
509                    if (PropsValues.DL_FILE_ENTRY_PREVIEW_FORK_PROCESS_ENABLED) {
510                            ProcessCallable<String> processCallable =
511                                    new LiferayVideoProcessCallable(
512                                            ServerDetector.getServerId(),
513                                            PropsUtil.get(PropsKeys.LIFERAY_HOME),
514                                            Log4JUtil.getCustomLogSettings(),
515                                            sourceFile.getCanonicalPath(),
516                                            destinationFile.getCanonicalPath(), containerType,
517                                            PropsUtil.getProperties(
518                                                    PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
519                                            PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
520    
521                            Future<String> future = ProcessExecutor.execute(
522                                    ClassPathUtil.getPortalClassPath(), processCallable);
523    
524                            String processIdentity = Long.toString(
525                                    fileVersion.getFileVersionId());
526    
527                            futures.put(processIdentity, future);
528    
529                            future.get();
530                    }
531                    else {
532                            LiferayConverter liferayConverter = new LiferayVideoConverter(
533                                    sourceFile.getCanonicalPath(),
534                                    destinationFile.getCanonicalPath(), containerType,
535                                    PropsUtil.getProperties(
536                                            PropsKeys.DL_FILE_ENTRY_PREVIEW_VIDEO, false),
537                                    PropsUtil.getProperties(PropsKeys.XUGGLER_FFPRESET, true));
538    
539                            liferayConverter.convert();
540                    }
541    
542                    addFileToStore(
543                            fileVersion.getCompanyId(), PREVIEW_PATH,
544                            getPreviewFilePath(fileVersion, containerType), destinationFile);
545    
546                    if (_log.isInfoEnabled()) {
547                            _log.info(
548                                    "Xuggler generated a " + containerType + " preview video for " +
549                                            fileVersion.getTitle() + " in " + stopWatch);
550                    }
551            }
552    
553            private void _generateVideoXuggler(
554                    FileVersion fileVersion, File sourceFile, File[] destinationFiles,
555                    int height, int width) {
556    
557                    try {
558                            for (int i = 0; i < destinationFiles.length; i++) {
559                                    _generateVideoXuggler(
560                                            fileVersion, sourceFile, destinationFiles[i],
561                                            _PREVIEW_TYPES[i]);
562                            }
563                    }
564                    catch (CancellationException ce) {
565                            if (_log.isInfoEnabled()) {
566                                    _log.info(
567                                            "Cancellation received for " +
568                                                    fileVersion.getFileVersionId() + " " +
569                                                            fileVersion.getTitle());
570                            }
571                    }
572                    catch (Exception e) {
573                            _log.error(e, e);
574                    }
575            }
576    
577            private boolean _hasVideo(FileVersion fileVersion) throws Exception {
578                    if (!isSupported(fileVersion)) {
579                            return false;
580                    }
581    
582                    return hasPreviews(fileVersion) && hasThumbnails(fileVersion);
583            }
584    
585            private void _queueGeneration(
586                    FileVersion sourceFileVersion, FileVersion destinationFileVersion) {
587    
588                    if (_fileVersionIds.contains(
589                                    destinationFileVersion.getFileVersionId()) ||
590                            !isSupported(destinationFileVersion)) {
591    
592                            return;
593                    }
594    
595                    _fileVersionIds.add(destinationFileVersion.getFileVersionId());
596    
597                    sendGenerationMessage(
598                            DestinationNames.DOCUMENT_LIBRARY_VIDEO_PROCESSOR,
599                            sourceFileVersion, destinationFileVersion);
600            }
601    
602            private static final String[] _PREVIEW_TYPES =
603                    PropsValues.DL_FILE_ENTRY_PREVIEW_VIDEO_CONTAINERS;
604    
605            private static Log _log = LogFactoryUtil.getLog(VideoProcessorImpl.class);
606    
607            private List<Long> _fileVersionIds = new Vector<Long>();
608            private 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, String inputURL,
617                            String outputURL, String videoContainer, Properties videoProperties,
618                            Properties ffpresetProperties) {
619    
620                            _serverId = serverId;
621                            _liferayHome = liferayHome;
622                            _customLogSettings = customLogSettings;
623                            _inputURL = inputURL;
624                            _outputURL = outputURL;
625                            _videoContainer = videoContainer;
626                            _videoProperties = videoProperties;
627                            _ffpresetProperties = ffpresetProperties;
628                    }
629    
630                    @Override
631                    public String call() throws ProcessException {
632                            Properties systemProperties = System.getProperties();
633    
634                            SystemEnv.setProperties(systemProperties);
635    
636                            Class<?> clazz = getClass();
637    
638                            ClassLoader classLoader = clazz.getClassLoader();
639    
640                            Log4JUtil.initLog4J(
641                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
642                                    _customLogSettings);
643    
644                            try {
645                                    LiferayConverter liferayConverter = new LiferayVideoConverter(
646                                            _inputURL, _outputURL, _videoContainer, _videoProperties,
647                                            _ffpresetProperties);
648    
649                                    liferayConverter.convert();
650                            }
651                            catch (Exception e) {
652                                    throw new ProcessException(e);
653                            }
654    
655                            return StringPool.BLANK;
656                    }
657    
658                    private static final long serialVersionUID = 1L;
659    
660                    private Map<String, String> _customLogSettings;
661                    private Properties _ffpresetProperties;
662                    private String _inputURL;
663                    private String _liferayHome;
664                    private String _outputURL;
665                    private String _serverId;
666                    private String _videoContainer;
667                    private Properties _videoProperties;
668    
669            }
670    
671            private static class LiferayVideoThumbnailProcessCallable
672                    implements ProcessCallable<String> {
673    
674                    public LiferayVideoThumbnailProcessCallable(
675                            String serverId, String liferayHome,
676                            Map<String, String> customLogSettings, String inputURL,
677                            File outputFile, String extension, int height, int width,
678                            int percentage) {
679    
680                            _serverId = serverId;
681                            _liferayHome = liferayHome;
682                            _customLogSettings = customLogSettings;
683                            _inputURL = inputURL;
684                            _outputFile = outputFile;
685                            _extension = extension;
686                            _height = height;
687                            _width = width;
688                            _percentage = percentage;
689                    }
690    
691                    @Override
692                    public String call() throws ProcessException {
693                            Class<?> clazz = getClass();
694    
695                            ClassLoader classLoader = clazz.getClassLoader();
696    
697                            Properties systemProperties = System.getProperties();
698                            SystemEnv.setProperties(systemProperties);
699    
700                            Log4JUtil.initLog4J(
701                                    _serverId, _liferayHome, classLoader, new Log4jLogFactoryImpl(),
702                                    _customLogSettings);
703    
704                            try {
705                                    LiferayConverter liferayConverter =
706                                            new LiferayVideoThumbnailConverter(
707                                                    _inputURL, _outputFile, _extension, _height, _width,
708                                                    _percentage);
709    
710                                    liferayConverter.convert();
711                            }
712                            catch (Exception e) {
713                                    throw new ProcessException(e);
714                            }
715    
716                            return StringPool.BLANK;
717                    }
718    
719                    private static final long serialVersionUID = 1L;
720    
721                    private Map<String, String> _customLogSettings;
722                    private String _extension;
723                    private int _height;
724                    private String _inputURL;
725                    private String _liferayHome;
726                    private File _outputFile;
727                    private int _percentage;
728                    private String _serverId;
729                    private int _width;
730    
731            }
732    
733    }