All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.day.cq.dam.video.servlet.VideoTestServlet Maven / Gradle / Ivy

/*
 * Copyright 1997-2008 Day Management AG
 * Barfuesserplatz 6, 4001 Basel, Switzerland
 * All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Day Management AG, ("Confidential Information"). You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Day.
 */
package com.day.cq.dam.video.servlet;

import java.awt.Dimension;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;

import javax.jcr.Binary;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import javax.servlet.ServletException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;
import org.apache.jackrabbit.commons.JcrUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.dam.handler.ffmpeg.ExecutableLocator;
import com.day.cq.dam.handler.ffmpeg.FFMpegWrapper;
import com.day.cq.dam.handler.ffmpeg.FfmpegNotFoundException;
import com.day.cq.dam.video.VideoProfile;

/**
 * Video Test Servlet
 */
@Component(policy = ConfigurationPolicy.REQUIRE)
@Service
@Properties({ 
    @Property(name="sling.servlet.resourceTypes", value="dam/components/video/profile"),
    @Property(name="sling.servlet.extensions", value="json"),
    @Property(name="sling.servlet.selectors", value="transcode.test"),
    @Property(name="sling.servlet.methods", value="GET"),
    @Property(name="service.description", value="Test a video profile.")
    })
public class VideoTestServlet extends SlingAllMethodsServlet {
    private static final long serialVersionUID = -780464494271946961L;

    private static final String NN_TEST = "test";
    private static final String PROPERTY_INPUT_FILE_NAME = "inputName";
    private static final String PROPERTY_OUTPUT_FILE_NAME = "outputName";
    private static final String PROPERTY_INPUT_DURATION = "inputDuration";
    private static final String PROPERTY_INPUT_SIZE = "inputSize";
    private static final String PROPERTY_TEST_LOG = "log";
    private static final String PROPERTY_TEST_SUCCESS = "success";
    private static final String PROPERTY_TEST_LAST_RUN = "lastRun";
    private static final String NODE_INPUT_FILE = "input";
    private static final String NODE_OUTPUT_FILE = "output";

    private static final String TMP_DIR = "videotest";

    private final Logger log = LoggerFactory.getLogger(VideoTestServlet.class);

    @Reference(policy = ReferencePolicy.STATIC)
    protected ExecutableLocator locator;

    @Override
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException,
            IOException {
        File tmpDir = null;
        try {
            tmpDir = File.createTempFile(TMP_DIR, null);
            tmpDir.delete();
            tmpDir.mkdir();

            VideoProfile videoProfile = new VideoProfile(request.getResource());
            Node testNode = getTestNode(videoProfile);

            VideoTestResult testResult = runTest(videoProfile, testNode, tmpDir);
            storeTestResult(testNode, testResult);

            writeTestResult(response, testResult);
        } catch (JSONException e) {
            throw new ServletException(e.getMessage(), e);
        } catch (FileNotFoundException e) {
            throw new ServletException(e.getMessage(), e);
        } catch (RepositoryException e) {
            throw new ServletException(e.getMessage(), e);
        } finally {
            if (tmpDir != null) {
                try {
                    FileUtils.deleteDirectory(tmpDir);
                } catch (IOException e) {
                    throw new ServletException(e.getMessage(), e);
                }
            }
        }

    }

    private void storeTestResult(Node testNode, VideoTestResult testResult) throws RepositoryException,
            FileNotFoundException {
        if (testResult.getOutput() != null) {
            InputStream resultIs = null;
            try {
                resultIs = new FileInputStream(testResult.getOutput());
                JcrUtils.putFile(testNode, NODE_OUTPUT_FILE, testResult.getOutputMimeType(), resultIs);
            } finally {
                IOUtils.closeQuietly(resultIs);
            }
        }
        if (testResult.getOutputName() != null) {
            testNode.setProperty(PROPERTY_OUTPUT_FILE_NAME, testResult.getOutputName());
        }
        if (testResult.getInputDuration() > 0) {
            testNode.setProperty(PROPERTY_INPUT_DURATION, testResult.getInputDuration());
        }
        if (testResult.getInputSize() != null) {
            testNode.setProperty(PROPERTY_INPUT_SIZE, formatInputSize(testResult.getInputSize()));
        }
        if (testResult.getFfmpegLog() != null) {
            testNode.setProperty(PROPERTY_TEST_LOG, testResult.getFfmpegLog());
        }
        testNode.setProperty(PROPERTY_TEST_SUCCESS, testResult.isSuccess());
        testNode.setProperty(PROPERTY_TEST_LAST_RUN, Calendar.getInstance());
        testNode.getSession().save();
    }

    private String formatInputSize(Dimension inputSize) {
        if (inputSize != null) {
            return inputSize.width + ":" + inputSize.height;
        }
        return "";

    }

    private void writeTestResult(SlingHttpServletResponse response, VideoTestResult testResult) throws IOException,
            JSONException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        JSONWriter writer = new JSONWriter(response.getWriter());
        writer.object();
        writer.key(PROPERTY_INPUT_SIZE).value(formatInputSize(testResult.getInputSize()));
        writer.key(PROPERTY_INPUT_DURATION).value(testResult.getInputDuration());
        writer.key(PROPERTY_OUTPUT_FILE_NAME).value(testResult.getOutputName());
        writer.key("success").value(testResult.isSuccess());
        writer.key("log").value(testResult.getFfmpegLog());
        writer.endObject();
    }

    private VideoTestResult runTest(VideoProfile videoProfile, Node testNode, File tmpDir) {
        VideoTestResult result = new VideoTestResult();
        String testVideoName;
        try {
            testVideoName = FilenameUtils.getName(testNode.getProperty(PROPERTY_INPUT_FILE_NAME).getString());
            javax.jcr.Property testVideoData = testNode.getProperty(NODE_INPUT_FILE + "/" + JcrConstants.JCR_CONTENT + "/"
                    + JcrConstants.JCR_DATA);
            Binary binary = null;
            InputStream is = null;
            FFMpegWrapper wrapper = null;
            FileOutputStream fos = null;
            try {
                binary = testVideoData.getBinary();
                is = binary.getStream();
                final File tmpFile = new File(tmpDir, testVideoName);
                fos = new FileOutputStream(tmpFile);
                IOUtils.copy(is, fos);
                wrapper = FFMpegWrapper.fromProfile(tmpFile, videoProfile, tmpDir);
                wrapper.setExecutableLocator(locator);
                final File video = wrapper.transcode();
                result.setOutput(video);
                result.setOutputName(video.getName());
                result.setOutputMimeType(wrapper.getOutputMimetype());
                result.setInputDuration(wrapper.getInputDuration());
                result.setInputSize(wrapper.getInputSize());
                result.setFfmpegLog(wrapper.getFFMpegOutput().toString());
                result.setSuccess(true);
            } catch (IOException e) {
                log.error(e.getMessage(), e);
                if (wrapper != null) {
                    result.setFfmpegLog(wrapper.getFFMpegOutput().toString());
                }
            } finally {
                IOUtils.closeQuietly(is);
                IOUtils.closeQuietly(fos);
                if (binary != null) {
                    binary.dispose();
                }
            }
        } catch (FfmpegNotFoundException e) {
            log.error(e.getMessage(), e);
            result.setFfmpegLog("Error transcoding: " + e.getMessage());
        } catch (ValueFormatException e) {
            log.error(e.getMessage(), e);
            result.setFfmpegLog("Error transcoding: " + e.getMessage());
        } catch (PathNotFoundException e) {
            log.error(e.getMessage(), e);
            result.setFfmpegLog("Error transcoding: " + e.getMessage());
        } catch (RepositoryException e) {
            log.error(e.getMessage(), e);
            result.setFfmpegLog("Error transcoding: " + e.getMessage());
        }

        return result;
    }

    private Node getTestNode(VideoProfile videoProfile) throws RepositoryException {
        Node profileNode = videoProfile.getContentNode();
        if (profileNode.hasNode(NN_TEST)) {
            return profileNode.getNode(NN_TEST);
        } else {
            return profileNode.addNode(NN_TEST);
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy