/* * myLib - https://github.com/taktod/myLib * Copyright (c) 2014 ttProject. All rights reserved. * * Licensed under The MIT license. */ package com.ttProject.convert.ffmpeg; //import java.nio.channels.Channels; import java.nio.channels.Channels; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.UUID; import org.apache.log4j.Logger; import com.ttProject.convert.IConvertListener; import com.ttProject.nio.channels.IReadChannel; import com.ttProject.nio.channels.ReadableByteReadChannel; /** * ffmpegConvertManagerで利用する内部プロセスのハンドルクラス * @author taktod */ public class ProcessHandler { /** ロガー */ private static final Logger logger = Logger.getLogger(ProcessHandler.class); /** サーバーにアクセスするためのキー */ private final String key; /** アクセスポート番号 */ private final int port; /** 子プロセスの標準出力受付thread */ private Thread thread = null; /** 動作させるコマンド(標準入力でデータを渡して、標準出力に吐く必要あり) */ private String processCommand = null; /** コマンド動作時に追加する追加環境変数 */ private Map<String, String> envExtra = null; /** データ受け取り時のイベント処理 */ private final Set<IConvertListener> listeners = new HashSet<IConvertListener>(); /** 動作プロセス */ private Process process = null; /** * コンストラクタ * @param port */ protected ProcessHandler(int port) { this.port = port; this.key = UUID.randomUUID().toString(); } /** * キー参照 * @return */ protected String getKey() { return key; } /** * 動作コマンドを設定する * @param command */ public void setCommand(String command) { this.processCommand = command; } /** * 追加環境変数を設定 * @param envExtra */ public void setEnvExtra(Map<String, String> envExtra) { this.envExtra = envExtra; } /** * データ受け取り時の処理listenerの追加 * @param listener * / public void addListener(IConvertListener listener) { listeners.add(listener); } /** * データ受け取り時の処理listenerの除去 * @param listener * / public void removeListener(IConvertListener listener) { listeners.remove(listener); } /** * プロセスの実行 */ protected void executeProcess() throws Exception { if(processCommand == null) { logger.error("process用のコマンドが存在していないのに、動作させようとしました。"); throw new Exception("process用のコマンドが設定されていません。"); } // たぶん、動作用のclasspathはjava.class.pathのデータをみればいいと思う。 StringBuilder command = new StringBuilder(); command.append("java -Dfile.encoding=UTF-8 -cp").append(" "); command.append(System.getProperty("java.class.path")).append(" "); // これがめちゃくちゃ長くなる command.append("com.ttProject.convert.ffmpeg.process.ProcessEntry").append(" "); command.append(port).append(" "); command.append(key).append(" "); command.append("2>/dev/null"); command.append(" | "); command.append(processCommand); logger.info("コマンド:" + processCommand); ProcessBuilder processBuilder = new ProcessBuilder("/bin/bash", "-c", command.toString()); // 環境変数の変更が必要な場合はここでいじっておきます。 if(envExtra != null) { Map<String, String> env = processBuilder.environment(); for(String key : envExtra.keySet()) { String envData = env.get(key); if(env == null || "".equals(envData)) { envData = envExtra.get(key); } else { envData += ":" + envExtra.get(key); } env.put(key, envData); } } // プロセスを開始する process = processBuilder.start(); // 応答読み取りスレッド // worker = new DataReceiveWorker(Channels.newChannel(process.getInputStream()), listeners); // thread = new Thread(worker); // thread.setDaemon(true); // thread.setName("ffmpegDataReceiveThread"); // thread.start(); } /** * 読み込みチャンネルを作成して応答するようにしておく。 * @return */ public IReadChannel getReadChannel() { return new ReadableByteReadChannel(Channels.newChannel(process.getInputStream())); } /** * 閉じる処理 */ public void close() { // 管理リスナーを解放しておく。 listeners.clear(); // 内部threadの処理を抜けさせる // if(worker != null) { // worker.stop(); // } // Threadの解放 if(thread != null) { thread.interrupt(); thread = null; } // 作成プロセスをこわしておく if(process != null) { process.destroy(); process = null; } } }