.svn
+iptd_html/3rd-party-apps/
+iptd_html/WEB-INF/
+iptd_html/css/
+iptd_html/docs/
+iptd_html/favicon.ico
+iptd_html/index.html
+iptd_html/iui/
+iptd_html/mobile/
+iptd_html/qunit/
+iptd_html/qutests/
+iptd_html/samples/
+iptd_html/test/
+iptd_html/tutorials/
#endif\r
// -- #include "Resource.h"\r
\r
-#include <Raym/Log.h>\r
-#include <Raym/Raym.h>\r
-#include <Raym/GlobalHook.h>\r
+#define DBG_LEBEL 3\r
+#include "Raym/Log.h"\r
+#include "Raym/Raym.h"\r
+#include "Raym/GlobalHook.h"\r
\r
#if 0\r
LPCWSTR wakeTaskName_ = L"com.mac.rmitachi.misc.PowerManager.WakeTask";\r
deleteNotifyIcon();\r
DestroyWindow(_wnd);\r
\r
-// debugLog("will terminate");\r
+ DebugLog0("will terminate");\r
}\r
flag = false;\r
}\r
// FileManager.cpp\r
//\r
\r
-#define DBG_LEVEL 0\r
-#include <Raym/Log.h>\r
-#include <Raym/Raym.h>\r
#include <sys/stat.h>\r
+#include <direct.h>\r
+\r
+#define DBG_LEVEL 0\r
+#include "Raym/Log.h"\r
+#include "Raym/Raym.h"\r
+\r
\r
namespace Raym\r
{\r
return result;\r
}\r
\r
+bool FileManager::removeItemAtPath(String *path, Error **error)\r
+{\r
+ DebugLog2("FileManager::removeItemAtPath()");\r
+\r
+ bool result = false;\r
+ if (path != NULL)\r
+ {\r
+ bool isDir = false;\r
+ if (fileExistsAtPath(path, &isDir))\r
+ {\r
+ if (isDir)\r
+ {\r
+ result = (_rmdir(path->cString()) == 0);\r
+ }\r
+ else\r
+ {\r
+ result = (remove(path->cString()) == 0);\r
+ }\r
+ }\r
+ }\r
+ return result;\r
+}\r
+\r
const char *FileManager::className()\r
{\r
return "FileManager";\r
\r
#pragma once\r
\r
-#include <Raym/Object.h>\r
+#include "Raym/Object.h"\r
+#include "Raym/Error.h"\r
\r
namespace Raym\r
{\r
bool fileExistsAtPath(String *path, bool *isDirectory);\r
bool fileExistsAtPath(const char *path, bool *isDirectory);\r
\r
+ bool removeItemAtPath(String *path, Error **error);\r
+\r
virtual const char *className();\r
};\r
\r
#define URI_PROGRAMS_HTML "programs.html"\r
#define URI_RESERVATION_HTML "reservation.html"\r
\r
+// other\r
+static const char * KEY_COUNTER = "Counter";\r
+\r
#endif // __RY0_KEYS_H__\r
//\r
\r
#define DBG_LEVEL 0\r
-#include <Raym/Log.h>\r
-#include <Raym/Raym.h>\r
+#include "Raym/Log.h"\r
+#include "Raym/Raym.h"\r
#include "net/HTTPDaemon.h"\r
\r
using namespace Raym;\r
{\r
header->setFieldBodyWithName("application/x-mpegURL", "Content-Type");\r
}\r
+ else if (ext->isEqualToString("ts"))\r
+ {\r
+ header->setFieldBodyWithName("video/mp2t", "Content-Type");\r
+ }\r
else\r
{\r
header->setFieldBodyWithName("application/octet-stream", "Content-Type");\r
}\r
else\r
{\r
- DebugLog3("reauest is null");\r
+ DebugLog3("request is null");\r
done = true;\r
}\r
\r
// セッションの終了待ち\r
if (_sockets->count() > 0)\r
{\r
+ DebugLog2("wait for session close 00");\r
// 残存セッションを終了させる為、ソケットを閉じる\r
for (uint i = 0; i < _sockets->count(); ++i)\r
{\r
SOCKET s = (SOCKET)((Number *)_sockets->objectAtIndex(i))->intValue();\r
closesocket(s);\r
}\r
+ DebugLog2("wait for session close 01");\r
// セッションが終了して_socketからオブジェクトを削除するのを待つ\r
while (_sockets->count() > 0)\r
{\r
LeaveCriticalSection(&_cs);\r
- Sleep(20);\r
+ ::Sleep(200);\r
EnterCriticalSection(&_cs);\r
}\r
+ DebugLog2("wait for session close 02");\r
}\r
\r
DebugLog2("HTTPDaemon::run() session close done.");\r
\r
void HTTPDaemon::stop()\r
{\r
- DebugLog2("HTTPDaemon::stop()", __FUNCTION__);\r
+ DebugLog2("HTTPDaemon::stop()");\r
\r
EnterCriticalSection(&_cs);\r
if (_state == ST_RUN)\r
LeaveCriticalSection(&_cs);\r
\r
wait();\r
+\r
+ DebugLog2("HTTPDaemon::stop() done.");\r
}\r
\r
void HTTPDaemon::wait()\r
{\r
+ DebugLog2("HTTPDaemon::wait()");\r
bool done = false;\r
while (!done)\r
{\r
::Sleep(100);\r
}\r
}\r
+ DebugLog2("HTTPDaemon::wait() done.");\r
}\r
\r
const char *HTTPDaemon::className()\r
\r
HTTPRequest *HTTPRequest::requestWithSocket(SOCKET sock)\r
{\r
- DebugLog2("%s\n", __FUNCTION__);\r
+ DebugLog2("%s", __FUNCTION__);\r
\r
char buf[16384];\r
int offset = 0;\r
}\r
buf[offset] = '\0';\r
\r
+ DebugLog2("%s 02", __FUNCTION__);\r
+\r
HTTPRequest *result = NULL;\r
\r
String *method = NULL;\r
CommandRunner::~CommandRunner()
{
+ stop();
+
RELEASE(_command);
RELEASE(_arguments);
void CommandRunner::stop()
{
+ DebugLog2("CommandRunner::stop()");
+ RaymLock(this);
+ if (_state != ST_IDLE)
+ {
+ _state = ST_DONE;
+ }
+ RaymUnlock(this);
+ bool done = false;
+ while (!done)
+ {
+ RaymLock(this);
+ done = (_state == ST_IDLE);
+ RaymUnlock(this);
+ if (!done)
+ {
+ ::Sleep(100);
+ }
+ }
+ DebugLog2("CommandRunner::stop() done.");
}
bool CommandRunner::isRunning()
return result;\r
}\r
\r
+#ifndef _WIN32\r
+#pragma mark '\r
+#pragma mark ------- システム関連 周期処理 -------\r
+#endif\r
+\r
//\r
// チューナ(streaming)制御/システム関連 周期処理\r
//\r
}\r
}\r
\r
+ //\r
+ // HLS\r
+ //\r
+ Dictionary *hls_info = _streaming_ctrls->dictionaryForKey(KEY_HLS_INFO);\r
+ if (hls_info != NULL)\r
+ {\r
+ for (int i = 0; i < _tunerCount; ++i)\r
+ {\r
+ RaymLock(this);\r
+ Dictionary *hls_info_tuner = hls_info->dictionaryForKey(_tuners[i]->name());\r
+ if (hls_info_tuner != NULL)\r
+ {\r
+ int counter = hls_info_tuner->integerForKey(KEY_COUNTER);\r
+ if (counter < 60)\r
+ {\r
+ hls_info_tuner->setInteger(counter + 1, KEY_COUNTER);\r
+ }\r
+ else\r
+ {\r
+ hls_info->removeObjectForKey(_tuners[i]->name());\r
+ }\r
+ }\r
+ RaymUnlock(this);\r
+ }\r
+ }\r
\r
\r
//\r
*/\r
HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_IN *client, int tuner, int channel, String *preset)\r
{\r
- DebugLog0("Controller::responseForHLSControl()");\r
+ DebugLog2("Controller::responseForHLSControl()");\r
\r
HTTPResponse *result = NULL;\r
\r
char hostname[NI_MAXHOST];\r
if (getnameinfo((SOCKADDR *)client, sizeof(SOCKADDR_IN), hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0)\r
{\r
- // 取得OK\r
- DebugLog0("host: %s", hostname);\r
-\r
// ストリーミング制御情報からHLS情報を取得\r
Dictionary *hls_info = _streaming_ctrls->dictionaryForKey(KEY_HLS_INFO);\r
if (hls_info == NULL)\r
{\r
- DebugLog0("hls_info == NULL");\r
hls_info = Dictionary::dictionaryWithCapacity(0);\r
_streaming_ctrls->setObject(hls_info, KEY_HLS_INFO);\r
}\r
Dictionary *hls_info_tuner = hls_info->dictionaryForKey(_tuners[tuner]->name());\r
if (hls_info_tuner == NULL)\r
{\r
- DebugLog0("hls_info_tuner == NULL");\r
hls_info_tuner = Dictionary::dictionaryWithCapacity(0);\r
hls_info->setObject(hls_info_tuner, _tuners[tuner]->name());\r
}\r
// 指定チューナの情報からホスト名を確認\r
if ((hls_info_tuner->stringForKey(KEY_HOSTNAME) == NULL) || hls_info_tuner->stringForKey(KEY_HOSTNAME)->isEqualToString(hostname))\r
{\r
- DebugLog0("new host or reconnect");\r
// ホスト名を設定\r
hls_info_tuner->setString(hostname, KEY_HOSTNAME);\r
\r
HTTPLiveStreaming *hls = (HTTPLiveStreaming *)hls_info_tuner->objectForKey(KEY_HLS_INSTANCE);\r
if (hls == NULL)\r
{\r
- DebugLog0("hls == NULL");\r
// 生成\r
hls = HTTPLiveStreaming::alloc()->init()->autorelease();\r
hls_info_tuner->setObject(hls, KEY_HLS_INSTANCE);\r
if (((hls_info_tuner->integerForKey(KEY_CHANNEL) != 0) && (hls_info_tuner->integerForKey(KEY_CHANNEL) != channel)) ||\r
((hls_info_tuner->stringForKey(KEY_PRESET) != NULL) && !hls_info_tuner->stringForKey(KEY_PRESET)->isEqualToString(preset)))\r
{\r
- DebugLog0("hls->stop()");\r
-\r
// 停止\r
hls->stop();\r
\r
hls_info_tuner->removeObjectForKey(KEY_PRESET);\r
}\r
\r
- DebugLog0("start ?");\r
-\r
// 初回リクエスト or チャンネル/プリセット変更 か?\r
if ((hls_info_tuner->integerForKey(KEY_CHANNEL) == 0) && (hls_info_tuner->stringForKey(KEY_PRESET) == NULL))\r
{\r
- DebugLog0("start or restart");\r
-\r
// UDPポートを検索\r
Dictionary *mapping = _streaming_ctrls->dictionaryForKey(KEY_MAPPING_UDP_TO_TUNER_CHANNEL);\r
if (mapping != NULL)\r
DebugLog0("udp mapping %d -> %d,%d", port->intValue(), tuner, channel);\r
\r
// ソースを設定\r
- hls->setSource(String::stringWithFormat("udp://@:%d", port->intValue()));\r
+ hls->setSource(String::stringWithFormat("udp://@0.0.0.0:%d", port->intValue()));\r
\r
// トランスコード\r
// hls->setTranscode(_props->dictionaryForKey(KEY_PRESETS)->dictionaryForKey(preset));\r
\r
// 出力先を設定\r
- hls->setOutputPath(_props->stringForKey(KEY_CACHE_PATH));\r
+ String *outpath = _props->stringForKey(KEY_CACHE_PATH)->stringByAppendingPathComponent(String::stringWithFormat("%03d", tuner));\r
+ _mkdir(outpath->cString());\r
+ hls->setOutputPath(outpath);\r
\r
// インデックス名\r
hls->setIndexName(String::stringWithFormat("live_%03d_%03d", tuner, channel));\r
DebugLog0("hls->start() success");\r
\r
// チャンネルを保存\r
- hls_info_tuner->setInteger(0, KEY_CHANNEL);\r
+ hls_info_tuner->setInteger(channel, KEY_CHANNEL);\r
\r
// プリセットを保存\r
hls_info_tuner->setString(preset, KEY_PRESET);\r
}\r
}\r
\r
+ RaymUnlock(this);\r
\r
String *index_path = hls->indexPath();\r
FileManager *fm = FileManager::defaultManager();\r
- bool isDirectory = false;\r
- if (fm->fileExistsAtPath(index_path, &isDirectory))\r
+ int count = 0;\r
+ while (count++ < 30)\r
{\r
- if (!isDirectory)\r
+ bool isDirectory = false;\r
+ if (fm->fileExistsAtPath(index_path, &isDirectory))\r
{\r
- DebugLog0("file exists");\r
- result = _httpd->responseWithPath(index_path, request);\r
+ if (!isDirectory)\r
+ {\r
+ DebugLog0("file exists");\r
+ bool done = false;\r
+ while (!done)\r
+ {\r
+ RaymLock(this);\r
+ result = _httpd->responseWithPath(index_path, request);\r
+ RaymUnlock(this);\r
+ if (result != NULL)\r
+ {\r
+ break;\r
+ }\r
+ ::Sleep(100);\r
+ }\r
+ break;\r
+ }\r
}\r
+ ::Sleep(1000);\r
}\r
+\r
+ RaymLock(this);\r
+\r
if (result == NULL)\r
{\r
DebugLog0("file no exists");\r
result = responseForReloadURI(request, client, request->URI()->cString(), 10);\r
}\r
-\r
-// result = responseForFailed(request);\r
+ else\r
+ {\r
+ hls_info_tuner->setInteger(0, KEY_COUNTER);\r
+ }\r
}\r
else\r
{\r
\r
HTTPResponse *Controller::requestTunerControl(HTTPRequest *request, SOCKADDR_IN *client, int tuner)\r
{\r
- DebugLog0("%s\n", __FUNCTION__);\r
+ DebugLog2("%s\n", __FUNCTION__);\r
\r
HTTPResponse *result = NULL;\r
\r
//\r
else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming(-[^\\.]+)?.m3u8$") && (cgi == NULL))\r
{\r
- DebugLog0("uri: %s", uri->cString());\r
-\r
// URIからチャンネル番号を抽出\r
// Range実装したい...\r
int ch = uri->substringFromIndex(5)->substringToIndex(3)->intValue();\r
- DebugLog0("ch: %d", ch);\r
\r
// presetが指定されている場合、presetを抽出\r
String *preset = NULL;\r
{\r
preset = uri->substringFromIndex(19);\r
preset = preset->substringToIndex(preset->length() - 5);\r
- DebugLog0("opt: preset: %s", preset->cString());\r
}\r
else\r
{\r
{\r
result = responseForFailed(request);\r
}\r
- DebugLog0("hls req. done");\r
}\r
else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming-[0-9]+.ts$") && (cgi == NULL))\r
{\r
- // 分割されたTS\r
- DebugLog0("uri: %s", uri->cString());\r
+ // URIからチャンネル番号を抽出\r
+ // Range実装したい...\r
+ int ch = uri->substringFromIndex(5)->substringToIndex(3)->intValue();\r
+\r
+ // client からホスト名を取得\r
+ char hostname[NI_MAXHOST];\r
+ if (getnameinfo((SOCKADDR *)client, sizeof(SOCKADDR_IN), hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0)\r
+ {\r
+ Dictionary *hls_info = _streaming_ctrls->dictionaryForKey(KEY_HLS_INFO);\r
+ if (hls_info != NULL)\r
+ {\r
+ Dictionary *hls_info_tuner = hls_info->dictionaryForKey(_tuners[tuner]->name());\r
+ if (hls_info_tuner != NULL)\r
+ {\r
+ if (hls_info_tuner->stringForKey(KEY_HOSTNAME)->isEqualToString(hostname) &&\r
+ (hls_info_tuner->integerForKey(KEY_CHANNEL) == ch))\r
+ {\r
+ String *path = ((HTTPLiveStreaming *)hls_info_tuner->objectForKey(KEY_HLS_INSTANCE))->outputPath();\r
+ if (path != NULL)\r
+ {\r
+ result = _httpd->responseWithPath(path->stringByAppendingPathComponent(uri->substringFromIndex(9)), request);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
\r
break;\r
//\r
else if (uri->isMatch("^/[0-9]{3}/"))\r
{\r
-DebugLog0("tuner control");\r
// String::substringWithRange() を実装するのを後回しにするので。。\r
std::string s = uri->cString();\r
int tuner = atoi(s.substr(1, 3).c_str());\r
if ((0 <= tuner) && (tuner < _tunerCount))\r
{\r
response = requestTunerControl(request, client, tuner);\r
-DebugLog0("tuner control done");\r
}\r
}\r
\r
// 設定以前にログ出力しないこと\r
Raym::LOG_NUM_MAX = 8;\r
\r
+ HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId());\r
+ if (hProcess != NULL)\r
+ {\r
+ if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS) == FALSE)\r
+ {\r
+ DebugLog0("SetPriorityClass failed.");\r
+ }\r
+ CloseHandle(hProcess);\r
+ }\r
+\r
#ifdef RAYM_MEMORY_CHECK\r
DebugLog0("");\r
DebugLog0("global_raym_count_ = %d", Raym::global_raym_count_);\r
// キャッシュ(HLSの一時ファイル格納先)パス\r
if (_props->stringForKey(KEY_CACHE_PATH) == NULL)\r
{\r
- _props->setString(_store_path, KEY_CACHE_PATH);\r
+ _props->setString(_store_path->stringByAppendingPathComponent("Cache"), KEY_CACHE_PATH);\r
+ _mkdir(_props->stringForKey(KEY_CACHE_PATH)->cString());\r
updated = true;\r
}\r
+ isDir = false;\r
+ if (!fm->fileExistsAtPath(_props->stringForKey(KEY_CACHE_PATH), &isDir))\r
+ {\r
+ isDir = false;\r
+ }\r
+ if (!isDir)\r
+ {\r
+ DebugLog0("error: \"%s\" is not exists.", _props->stringForKey(KEY_CACHE_PATH)->cString());\r
+ result = -1;\r
+ break;\r
+ }\r
\r
// プロパティファイルを保存\r
if (updated)\r
{\r
result = Application::start();\r
\r
+ DebugLog0("will terminate. 00");\r
+\r
// httpd終了待ち\r
_httpd->stop();\r
}\r
\r
+ DebugLog0("will terminate. 01");\r
+\r
RaymLock(this);\r
_cancel_epg_collect = true;\r
RaymUnlock(this);\r
\r
#include "net/HTTPDaemon.h"\r
\r
-#define VERSION "0.01"\r
-#define REVISION 16\r
+#define VERSION "0.02"\r
+#define REVISION 19\r
\r
namespace ry0\r
{\r
return this;
}
-void HTTPLiveStreaming::setSource(Raym::String *source)
+void HTTPLiveStreaming::setSource(String *source)
{
DebugLog2("HTTPLiveStreaming::setSource()");
}
}
-void HTTPLiveStreaming::setOutputPath(Raym::String *output_path)
+void HTTPLiveStreaming::setOutputPath(String *output_path)
{
DebugLog2("HTTPLiveStreaming::setOutputPath()");
}
}
-void HTTPLiveStreaming::setIndexName(Raym::String *index_name)
+String *HTTPLiveStreaming::outputPath()
+{
+ return _output_path;
+}
+
+void HTTPLiveStreaming::setIndexName(String *index_name)
{
DebugLog2("HTTPLiveStreaming::setIndexName()");
bool HTTPLiveStreaming::start()
{
+ DebugLog2("%s", __FUNCTION__);
+
+ if ((_output_path == NULL) || (_source == NULL) || (_index_name == NULL))
+ {
+ return false;
+ }
+
+ DebugLog2("output path: %s", _output_path->cString());
+ DebugLog2("source: %s", _source->cString());
+ DebugLog2("index: %s", _index_name->cString());
+
+ String *index_path = indexPath();
+ if (index_path != NULL)
+ {
+ FileManager::defaultManager()->removeItemAtPath(index_path, NULL);
+ }
//
// %>ffmpeg -i C:\WORK\20151024_211758_086_PT2@050000-01.ts -vcodec libx264 -r 30000/1001 -aspect 16:9 -s 1280x720
// 暫定処理
// Array *args = STR_ARRAY("-i", "C:\\WORK\\20151024_211758_086_PT2@050000-01.ts",
// Array *args = STR_ARRAY("-i", "udp://0.0.0.0:51027",
- Array *args = STR_ARRAY("-i", "udp://@0.0.0.0:51027?overrun_nonfatal=1&fifo_size=50000000",
+#if 0
+ Array *arg2 = STR_ARRAY("-i", "udp://@0.0.0.0:51027?overrun_nonfatal=1&fifo_size=50000000",
+// Array *args = STR_ARRAY("-i", "udp://@51027?overrun_nonfatal=1&fifo_size=50000000",
"-vcodec", "libx264",
"-r", "30000/1001",
"-aspect", "16:9",
"-segment_list", "C:\\WORK\\www\\index.m3u8",
"C:\\WORK\\www\\test%03d.ts",
NULL);
+#endif
+
+ Array *args = Array::arrayWithCapacity(0);
+ args->addObject(String::stringWithUTF8String("-i"));
+// args->addObject(String::stringWithUTF8String("udp://@0.0.0.0:51027?overrun_nonfatal=1&fifo_size=50000000"));
+ if (_source->hasPrefix("udp://"))
+ {
+ args->addObject(String::stringWithFormat("%s?overrun_nonfatal=1&fifo_size=50000000", _source->cString()));
+ }
+ else
+ {
+ args->addObject(String::stringWithUTF8String("hogehoge"));
+ }
+
+ args->addObject(String::stringWithUTF8String("-vcodec"));
+ args->addObject(String::stringWithUTF8String("libx264"));
+ args->addObject(String::stringWithUTF8String("-r"));
+ args->addObject(String::stringWithUTF8String("30000/1001"));
+ args->addObject(String::stringWithUTF8String("-aspect"));
+ args->addObject(String::stringWithUTF8String("16:9"));
+ args->addObject(String::stringWithUTF8String("-s"));
+ args->addObject(String::stringWithUTF8String("1280x720"));
+ args->addObject(String::stringWithUTF8String("-bufsize"));
+ args->addObject(String::stringWithUTF8String("20000k"));
+ args->addObject(String::stringWithUTF8String("-maxrate"));
+ args->addObject(String::stringWithUTF8String("25000k"));
+ args->addObject(String::stringWithUTF8String("-acodec"));
+ args->addObject(String::stringWithUTF8String("libvo_aacenc"));
+ args->addObject(String::stringWithUTF8String("-ac"));
+ args->addObject(String::stringWithUTF8String("2"));
+ args->addObject(String::stringWithUTF8String("-ar"));
+ args->addObject(String::stringWithUTF8String("48000"));
+ args->addObject(String::stringWithUTF8String("-ab"));
+ args->addObject(String::stringWithUTF8String("128k"));
+ args->addObject(String::stringWithUTF8String("-threads"));
+ args->addObject(String::stringWithUTF8String("2"));
+ args->addObject(String::stringWithUTF8String("-f"));
+ args->addObject(String::stringWithUTF8String("segment"));
+ args->addObject(String::stringWithUTF8String("-segment_format"));
+ args->addObject(String::stringWithUTF8String("mpegts"));
+ args->addObject(String::stringWithUTF8String("-segment_time"));
+ args->addObject(String::stringWithUTF8String("10"));
+
+ args->addObject(String::stringWithUTF8String("-segment_list"));
+ args->addObject(_output_path->stringByAppendingPathComponent(String::stringWithFormat("%s.m3u8", _index_name->cString())));
+
+ args->addObject(_output_path->stringByAppendingPathComponent(String::stringWithUTF8String("streaming-%05d.ts")));
+
setArguments(args);
return FFmpeg::start();
String * HTTPLiveStreaming::indexPath()
{
- return NULL;
+ if ((_output_path == NULL) || (_index_name == NULL))
+ {
+ return false;
+ }
+ return _output_path->stringByAppendingPathComponent(String::stringWithFormat("%s.m3u8", _index_name->cString()));
}
{
if (line != NULL)
{
- DebugLog3("ffmpeg: %s", line->cString());
+// DebugLog3("ffmpeg: %s", line->cString());
}
return false;
}
void setSource(Raym::String *source);
void setOutputPath(Raym::String *output_path);
+ Raym::String *outputPath();
void setIndexName(Raym::String *index_name);
bool start();