Package org.apache.openmeetings.data.flvrecord.converter

Source Code of org.apache.openmeetings.data.flvrecord.converter.FlvRecorderConverter

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License") +  you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openmeetings.data.flvrecord.converter;

import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.openmeetings.OpenmeetingsVariables;
import org.apache.openmeetings.data.flvrecord.FlvRecordingDao;
import org.apache.openmeetings.data.flvrecord.FlvRecordingLogDao;
import org.apache.openmeetings.data.flvrecord.FlvRecordingMetaDataDao;
import org.apache.openmeetings.documents.beans.ConverterProcessResult;
import org.apache.openmeetings.persistence.beans.flvrecord.FlvRecording;
import org.apache.openmeetings.persistence.beans.flvrecord.FlvRecordingMetaData;
import org.apache.openmeetings.utils.ProcessHelper;
import org.red5.logging.Red5LoggerFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

public class FlvRecorderConverter extends BaseConverter {

  private static final Logger log = Red5LoggerFactory
      .getLogger(FlvRecorderConverter.class, OpenmeetingsVariables.webAppRootKey);

  // Spring loaded Beans
  @Autowired
  private FlvRecordingDao flvRecordingDaoImpl = null;
  @Autowired
  private FlvRecordingMetaDataDao flvRecordingMetaDataDaoImpl = null;
  @Autowired
  private FlvRecordingLogDao flvRecordingLogDaoImpl;

  private String FFMPEG_MAP_PARAM = ":";

  public void startConversion(Long flvRecordingId) {
    try {
      if (isUseOldStyleFfmpegMap()) {
        FFMPEG_MAP_PARAM = ".";
      }

      FlvRecording flvRecording = this.flvRecordingDaoImpl
          .getFlvRecordingById(flvRecordingId);
      log.debug("flvRecording " + flvRecording.getFlvRecordingId());

      // Strip Audio out of all Audio-FLVs
      this.stripAudioFromFLVs(flvRecording);

      // Add empty pieces at the beginning and end of the wav

    } catch (Exception err) {
      log.error("[startConversion]", err);
    }
  }

  public void stripAudioFromFLVs(FlvRecording flvRecording) {
    List<ConverterProcessResult> returnLog = new ArrayList<ConverterProcessResult>();
    List<String> listOfFullWaveFiles = new LinkedList<String>();
    File streamFolder = getStreamFolder(flvRecording);
    try {
      stripAudioFirstPass(flvRecording, returnLog, listOfFullWaveFiles, streamFolder);

      // Merge Wave to Full Length
      String streamFolderGeneralName = getStreamFolder().getCanonicalPath() + File.separator; //FIXME

      FlvRecordingMetaData flvRecordingMetaDataOfScreen = this.flvRecordingMetaDataDaoImpl
          .getFlvRecordingMetaDataScreenFlvByRecording(flvRecording
              .getFlvRecordingId());
     
      if (flvRecordingMetaDataOfScreen == null) {
        throw new Exception("flvRecordingMetaDataOfScreen is Null FlvRecordingId "+flvRecording
              .getFlvRecordingId());
      }
     
      if (flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete() == null) {
        throw new Exception("StreamReaderThreadComplete Bit is NULL, error in recording");
      }
     
      if (!flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete()) {
       
        log.debug("### meta ScreenStream not yet written to disk" + flvRecordingMetaDataOfScreen.getFlvRecordingMetaDataId());
        boolean doStop = true;
        while(doStop) {
         
          log.debug("### Stream not yet written Thread Sleep - " + flvRecordingMetaDataOfScreen.getFlvRecordingMetaDataId());
         
          Thread.sleep(100L);
         
          flvRecordingMetaDataOfScreen = flvRecordingMetaDataDaoImpl.getFlvRecordingMetaDataById(flvRecordingMetaDataOfScreen.getFlvRecordingMetaDataId());
         
          if (flvRecordingMetaDataOfScreen.getStreamReaderThreadComplete()) {
            log.debug("### Screen Stream now written Thread continue - " );
            doStop = false;
          }
        }
      }
     
     
      String hashFileFullName = flvRecordingMetaDataOfScreen
          .getStreamName() + "_FINAL_WAVE.wav";
      String outputFullWav = new File(streamFolder, hashFileFullName).getCanonicalPath();

      if (listOfFullWaveFiles.size() == 1) {

        outputFullWav = listOfFullWaveFiles.get(0);

        flvRecordingMetaDataOfScreen
            .setFullWavAudioData(hashFileFullName);

      } else if (listOfFullWaveFiles.size() > 0) {

        String[] argv_full_sox = mergeAudioToWaves(listOfFullWaveFiles, outputFullWav);

        log.debug("START mergeAudioToWaves ################# ");
        log.debug(argv_full_sox.toString());
        String iString = "";
        for (int i = 0; i < argv_full_sox.length; i++) {
          iString += argv_full_sox[i] + " ";
        }
        log.debug(iString);
        log.debug("END mergeAudioToWaves ################# ");

        flvRecordingMetaDataOfScreen
            .setFullWavAudioData(hashFileFullName);

        this.flvRecordingMetaDataDaoImpl
            .updateFlvRecordingMetaData(flvRecordingMetaDataOfScreen);

        returnLog.add(ProcessHelper.executeScript("mergeWave",
            argv_full_sox));
      } else {

        // create default Audio to merge it.
        // strip to content length
        String outputWav = streamFolderGeneralName + "one_second.wav";

        // Calculate delta at beginning
        Long deltaTimeMilliSeconds = flvRecording.getRecordEnd()
            .getTime() - flvRecording.getRecordStart().getTime();
        Float deltaPadding = (Float.parseFloat(deltaTimeMilliSeconds
            .toString()) / 1000) - 1;

        String[] argv_full_sox = new String[] { this.getPathToSoX(),
            outputWav, outputFullWav, "pad", "0",
            deltaPadding.toString() };

        log.debug("START generateSampleAudio ################# ");
        String tString = "";
        for (int i = 0; i < argv_full_sox.length; i++) {
          tString += argv_full_sox[i] + " ";
        }
        log.debug(tString);
        log.debug("END generateSampleAudio ################# ");

        flvRecordingMetaDataOfScreen
            .setFullWavAudioData(hashFileFullName);

        this.flvRecordingMetaDataDaoImpl
            .updateFlvRecordingMetaData(flvRecordingMetaDataOfScreen);

        returnLog.add(ProcessHelper.executeScript("mergeWave",
            argv_full_sox));

      }

      // Merge Audio with Video / Calculate resulting FLV

      String inputScreenFullFlv = new File(streamFolder, flvRecordingMetaDataOfScreen.getStreamName() + ".flv").getCanonicalPath();

      String hashFileFullNameFlv = "flvRecording_"
          + flvRecording.getFlvRecordingId() + ".flv";
      String outputFullFlv = streamFolderGeneralName
          + hashFileFullNameFlv;

      // ffmpeg -vcodec flv -qscale 9.5 -r 25 -ar 22050 -ab 32k -s 320x240
      // -i
      // 65318fb5c54b1bc1b1bca077b493a914_28_12_2009_23_38_17_FINAL_WAVE.wav
      // -i 65318fb5c54b1bc1b1bca077b493a914_28_12_2009_23_38_17.flv
      // final1.flv

      int flvWidth = flvRecording.getWidth();
      int flvHeight = flvRecording.getHeight();

      log.debug("flvWidth -1- " + flvWidth);
      log.debug("flvHeight -1- " + flvHeight);

      flvWidth = Double.valueOf((Math.floor(flvWidth / 16)) * 16)
          .intValue();
      flvHeight = Double.valueOf((Math.floor(flvHeight / 16)) * 16)
          .intValue();

      log.debug("flvWidth -2- " + flvWidth);
      log.debug("flvHeight -2- " + flvHeight);

      flvRecording.setFlvWidth(flvWidth);
      flvRecording.setFlvHeight(flvHeight);

      String[] argv_fullFLV = new String[] {
          this.getPathToFFMPEG(), //
          "-i", inputScreenFullFlv, "-i", outputFullWav, "-ar",
          "22050", //
          "-acodec", "libmp3lame", //
          "-ab", "32k", //
          "-s", flvWidth + "x" + flvHeight, //
          "-vcodec", "flashsv", //
          "-map", "0" + FFMPEG_MAP_PARAM + "0", //
          "-map", "1" + FFMPEG_MAP_PARAM + "0", //
          outputFullFlv };

      log.debug("START generateFullFLV ################# ");
      String tString = "";
      for (int i = 0; i < argv_fullFLV.length; i++) {
        tString += argv_fullFLV[i] + " ";
        // log.debug(" i " + i + " argv-i " + argv_fullFLV[i]);
      }
      log.debug(tString);
      log.debug("END generateFullFLV ################# ");

      returnLog.add(ProcessHelper.executeScript("generateFullFLV",
          argv_fullFLV));

      flvRecording.setFileHash(hashFileFullNameFlv);

      // Extract first Image for preview purpose
      // ffmpeg -i movie.flv -vcodec mjpeg -vframes 1 -an -f rawvideo -s
      // 320x240 movie.jpg

      String hashFileFullNameJPEG = "flvRecording_"
          + flvRecording.getFlvRecordingId() + ".jpg";
      String outPutJpeg = streamFolderGeneralName + hashFileFullNameJPEG;

      flvRecording.setPreviewImage(hashFileFullNameJPEG);

      String[] argv_previewFLV = new String[] { //
          this.getPathToFFMPEG(), //
          "-i", outputFullFlv, //
          "-vcodec", "mjpeg", //
          "-vframes", "1", "-an", //
          "-f", "rawvideo", //
          "-s", flvWidth + "x" + flvHeight, //
          outPutJpeg };

      log.debug("START previewFullFLV ################# ");
      log.debug(argv_previewFLV.toString());
      String kString = "";
      for (int i = 0; i < argv_previewFLV.length; i++) {
        kString += argv_previewFLV[i] + " ";
      }
      log.debug(kString);
      log.debug("END previewFullFLV ################# ");

      returnLog.add(ProcessHelper.executeScript("generateFullFLV",
          argv_previewFLV));

      String alternateDownloadName = "flvRecording_"
          + flvRecording.getFlvRecordingId() + ".avi";
      String alternateDownloadFullName = streamFolderGeneralName
          + alternateDownloadName;

      String[] argv_alternateDownload = new String[] {
          this.getPathToFFMPEG(), "-i", outputFullFlv,
          "-vcodec", "copy",
          alternateDownloadFullName };

      log.debug("START alternateDownLoad ################# ");
      log.debug(argv_previewFLV.toString());
      String sString = "";
      for (int i = 0; i < argv_alternateDownload.length; i++) {
        sString += argv_alternateDownload[i] + " ";
      }
      log.debug(sString);
      log.debug("END alternateDownLoad ################# ");

      returnLog.add(ProcessHelper.executeScript("alternateDownload",
          argv_alternateDownload));

      flvRecording.setAlternateDownload(alternateDownloadName);

      this.flvRecordingDaoImpl.updateFlvRecording(flvRecording);

      for (ConverterProcessResult returnMap : returnLog) {
        this.flvRecordingLogDaoImpl.addFLVRecordingLog(
            "generateFFMPEG", flvRecording, returnMap);
      }

      // Delete Wave Files
      for (String fileName : listOfFullWaveFiles) {
        File audio = new File(fileName);
        if (audio.exists()) {
          audio.delete();
        }
      }

    } catch (Exception err) {
      log.error("[stripAudioFromFLVs]", err);
    }
  }

}
TOP

Related Classes of org.apache.openmeetings.data.flvrecord.converter.FlvRecorderConverter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.