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

com.day.cq.dam.video.servlet.VideoClipServlet 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.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;


import javax.servlet.ServletException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import com.day.cq.dam.api.Asset;
import com.day.cq.dam.handler.ffmpeg.ExecutableLocator;
import com.day.cq.dam.handler.ffmpeg.FFMpegWrapper;
import com.day.cq.dam.handler.ffmpeg.FfmpegNotFoundException;

/**
 * Servlet to clip video and add it as rendition.
 */
@Component
@Service
@Properties({ 
    @Property(name="sling.servlet.resourceTypes", value="sling/servlet/default"),
    @Property(name="sling.servlet.selectors", value="videoclip"),
    @Property(name="sling.servlet.methods", value="POST"),
    @Property(name="service.description", value="Servlet to clip video.")
    })
public class VideoClipServlet extends SlingAllMethodsServlet {
    private static final long serialVersionUID = -780464494271946961L;

    private final Logger log = LoggerFactory.getLogger(VideoProfileListServlet.class);
    
    private File workingDir;
    
    @Reference(policy = ReferencePolicy.STATIC)
    protected ExecutableLocator locator;
    
    @Property(value="./logs/ffmpeg")
    public static final String PROP_WORKING_DIR = "ffmpeg.workingdir";

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException,
            IOException {

    	Resource resource = request.getResource();
    	Asset asset = null;
    	//final Resource resource = getResourceResolver(session).getResource(path);
        if (null != resource) {
            asset = resource.adaptTo(Asset.class);
        }
       
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");


        FFMpegWrapper wrapper=null;
        File tmpWorkingDir = null;
        File tmpDir = null;
        FileOutputStream fos = null;
        InputStream is = null;
        try {
            // creating temp directory
            tmpDir = File.createTempFile("cqdam", null);
            tmpDir.delete();
            tmpDir.mkdir();

            //creating temp working directory for ffmpeg 
            tmpWorkingDir = createTempDir(getWorkingDir());
            
            // streaming file to temp directory
            final File tmpFile = new File(tmpDir, asset.getName().replace(' ','_'));
            fos = new FileOutputStream(tmpFile);
            is = asset.getOriginal().getStream();
            IOUtils.copy(is, fos);


            // get information about original video file (size, video length, ...)
            wrapper = new FFMpegWrapper(tmpFile, tmpWorkingDir);
            wrapper.setExecutableLocator(locator);
            File clippedFile = wrapper.getClip(Double.parseDouble(startTime),Double.parseDouble(endTime),asset.getMimeType());
            FileInputStream fis = new FileInputStream(clippedFile);
            String roundStartTime = startTime.substring(0,startTime.indexOf("."));
            String roundEndTime = endTime.substring(0, endTime.indexOf("."));
            String mimeType = asset.getMimeType();
            String outputFormat = mimeType.substring(mimeType.indexOf("/")+1);
            asset.addRendition("cq5dam.clipped." + roundStartTime + "."+roundEndTime + "." + outputFormat, fis, asset.getMimeType());
               

        } catch (IOException e) {
        
        } catch(FfmpegNotFoundException e){
            log.error(e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(is);
            IOUtils.closeQuietly(fos);
            try {
                // cleaning up temp directory
                if (tmpDir != null) {
                    FileUtils.deleteDirectory(tmpDir);
                }
            } catch (IOException e) {
                log.error("Could not delete temp directory: {}", tmpDir.getPath());;

            }
            try {
                // cleaning up ffmpeg's temp working directory
                if (tmpWorkingDir != null) {
                    FileUtils.deleteDirectory(tmpWorkingDir);
                }
            } catch (IOException e) {
                log.warn(
                    "Could not delete ffmpeg's temporary working directory: {}",
                    tmpWorkingDir.getPath());
            }
        }
    }
    
    public File getWorkingDir() {
        workingDir.mkdir();
        return workingDir;
    }
    
    private File resolveWorkingDir(String slingHome, String path) {
        if (path == null) {
            path = "";
        }
        // ensure proper separator in the path (esp. for systems, which do
        // not use "slash" as a separator, e.g Windows)
        path = path.replace('/', File.separatorChar);

        // create a file instance and check whether this is absolute. If not
        // create a new absolute file instance with the base dir (sling.home or
        // working dir of current JVM) and get the absolute path name from that
        File workingDir = new File(path);
        if (!workingDir.isAbsolute()) {
            File baseDir = new File((slingHome == null) ? "" /* jvm working dir */ : slingHome).getAbsoluteFile();
            workingDir = new File(baseDir, path).getAbsoluteFile();
        }
        try {
            log.info("ffmpeg working directory: {}", workingDir.getCanonicalPath());
        } catch (IOException e) {
            log.info("ffmpeg working directory: {}", workingDir.getAbsolutePath());
        }
        
        return workingDir;
    }
    
    protected void activate(ComponentContext ctx) {
        String slingHome = ctx.getBundleContext().getProperty("sling.home");
        workingDir = resolveWorkingDir(slingHome, (String) ctx.getProperties().get(PROP_WORKING_DIR));
    }

    /**
     * creates a temporary directory in the given dir.
     * 
     * @param parentDir parent directory in which temporary directory is to be
     *            created
     */
    protected File createTempDir(File parentDir) {
        File tempDir = null;
        try {
            tempDir = File.createTempFile("cqdam", null, parentDir);
            tempDir.delete();
            tempDir.mkdir();
        } catch (IOException e) {
            log.warn(
                "could not create temp directory in the [{}] with the exception",
                parentDir, e);
        }
        return tempDir;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy