OSDN Git Service

HLS試作
authorosx86_pt1 <rmitachi@ta2.so-net.ne.jp>
Sun, 20 Mar 2016 12:27:15 +0000 (21:27 +0900)
committerosx86_pt1 <rmitachi@ta2.so-net.ne.jp>
Sun, 20 Mar 2016 12:27:15 +0000 (21:27 +0900)
http://hogehoge:50080/ttt/ccc/streaming.m3u8

ttt = チューナ番号
ccc = チャンネル

でHLS開始
要ffmpeg.exe

13 files changed:
.gitignore
iPTd_R2.sdf
src/Raym/Application.cpp
src/Raym/FileManager.cpp
src/Raym/FileManager.h
src/keys.h
src/net/HTTPDaemon.cpp
src/net/HTTPRequest.cpp
src/ry0/iPTd/CommandRunner.cpp
src/ry0/iPTd/Controller.cpp
src/ry0/iPTd/Controller.h
src/ry0/iPTd/HTTPLiveStreaming.cpp
src/ry0/iPTd/HTTPLiveStreaming.h

index 90ec22b..af9c5ba 100644 (file)
@@ -1 +1,14 @@
 .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/
index 360268b..3eda853 100644 (file)
Binary files a/iPTd_R2.sdf and b/iPTd_R2.sdf differ
index ee868d3..2b16e0f 100644 (file)
 #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
@@ -345,7 +346,7 @@ LRESULT Application::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
                         deleteNotifyIcon();\r
                         DestroyWindow(_wnd);\r
 \r
-//                        debugLog("will terminate");\r
+                        DebugLog0("will terminate");\r
                     }\r
                     flag = false;\r
                 }\r
index 2642ae5..358506d 100644 (file)
@@ -2,10 +2,13 @@
 // 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
@@ -74,6 +77,29 @@ bool FileManager::fileExistsAtPath(const char *path, bool *isDirectory)
     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
index 267f09a..2fd83c3 100644 (file)
@@ -4,7 +4,8 @@
 \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
@@ -21,6 +22,8 @@ public:
     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
index ea3e87b..26daa6c 100644 (file)
@@ -96,4 +96,7 @@ static const char *KEY_RESULT                   = "Result";
 #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
index 911e4e8..d3aaa2e 100644 (file)
@@ -3,8 +3,8 @@
 //\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
@@ -179,6 +179,10 @@ HTTPResponse *HTTPDaemon::responseWithPath(String *path, HTTPRequest *request)
             {\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
@@ -477,7 +481,7 @@ void HTTPDaemon::session(SOCKET sock, struct sockaddr_in *client)
         }\r
         else\r
         {\r
-            DebugLog3("reauest is null");\r
+            DebugLog3("request is null");\r
             done = true;\r
         }\r
 \r
@@ -627,19 +631,22 @@ void HTTPDaemon::run()
     // セッションの終了待ち\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
@@ -717,7 +724,7 @@ bool HTTPDaemon::start()
 \r
 void HTTPDaemon::stop()\r
 {\r
-    DebugLog2("HTTPDaemon::stop()", __FUNCTION__);\r
+    DebugLog2("HTTPDaemon::stop()");\r
 \r
     EnterCriticalSection(&_cs);\r
     if (_state == ST_RUN)\r
@@ -727,10 +734,13 @@ void HTTPDaemon::stop()
     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
@@ -742,6 +752,7 @@ void HTTPDaemon::wait()
             ::Sleep(100);\r
         }\r
     }\r
+    DebugLog2("HTTPDaemon::wait() done.");\r
 }\r
 \r
 const char *HTTPDaemon::className()\r
index 3463bc9..b4ff3a7 100644 (file)
@@ -32,7 +32,7 @@ HTTPRequest::~HTTPRequest()
 \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
@@ -55,6 +55,8 @@ HTTPRequest *HTTPRequest::requestWithSocket(SOCKET sock)
     }\r
     buf[offset] = '\0';\r
 \r
+    DebugLog2("%s 02", __FUNCTION__);\r
+\r
     HTTPRequest *result = NULL;\r
 \r
     String *method  = NULL;\r
index d1ee053..16674d9 100644 (file)
@@ -27,6 +27,8 @@ CommandRunner::CommandRunner()
 
 CommandRunner::~CommandRunner()
 {
+    stop();
+
     RELEASE(_command);
     RELEASE(_arguments);
 
@@ -247,6 +249,25 @@ bool CommandRunner::start()
 
 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()
index 9515469..aab83f2 100644 (file)
@@ -1534,6 +1534,11 @@ bool Controller::setChannel(int tuner, int channel)
     return result;\r
 }\r
 \r
+#ifndef _WIN32\r
+#pragma mark '\r
+#pragma mark ------- システム関連 周期処理 -------\r
+#endif\r
+\r
 //\r
 // チューナ(streaming)制御/システム関連 周期処理\r
 //\r
@@ -1728,6 +1733,31 @@ void Controller::periodic_2(void)
         }\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
@@ -3792,7 +3822,7 @@ rtmp://80.82.78.87:443/liverepeater/starsp pageUrl=http://xxxxxxxxxxxxxxxx.xx/rt
  */\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
@@ -3800,14 +3830,10 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
     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
@@ -3816,7 +3842,6 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
         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
@@ -3824,7 +3849,6 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
         // 指定チューナの情報からホスト名を確認\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
@@ -3832,7 +3856,6 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
             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
@@ -3842,8 +3865,6 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
             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
@@ -3852,13 +3873,9 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
                 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
@@ -3878,13 +3895,15 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
                                 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
@@ -3895,7 +3914,7 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
                                     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
@@ -3908,25 +3927,48 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
                 }\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
@@ -3939,7 +3981,7 @@ HTTPResponse *Controller::responseForHLSControl(HTTPRequest *request, SOCKADDR_I
 \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
@@ -4311,12 +4353,9 @@ DebugLog0("set %d channel:%d(%s)\n", tuner, channel, ch->cString());
         //\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
@@ -4324,7 +4363,6 @@ DebugLog0("set %d channel:%d(%s)\n", tuner, channel, ch->cString());
             {\r
                 preset = uri->substringFromIndex(19);\r
                 preset = preset->substringToIndex(preset->length() - 5);\r
-                DebugLog0("opt: preset: %s", preset->cString());\r
             }\r
             else\r
             {\r
@@ -4344,12 +4382,35 @@ DebugLog0("set %d channel:%d(%s)\n", tuner, channel, ch->cString());
             {\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
@@ -4431,14 +4492,12 @@ HTTPResponse *Controller::request(HTTPRequest *request, SOCKADDR_IN *client)
         //\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
@@ -5362,6 +5421,16 @@ int Controller::start()
     //   設定以前にログ出力しないこと\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
@@ -5660,9 +5729,21 @@ int Controller::start()
         // キャッシュ(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
@@ -5780,10 +5861,14 @@ int Controller::start()
     {\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
index 08acdaf..eaa3195 100644 (file)
@@ -12,8 +12,8 @@
 \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
index 9ff5e16..907cf8d 100644 (file)
@@ -71,7 +71,7 @@ HTTPLiveStreaming *HTTPLiveStreaming::autorelease()
     return this;
 }
 
-void HTTPLiveStreaming::setSource(Raym::String *source)
+void HTTPLiveStreaming::setSource(String *source)
 {
     DebugLog2("HTTPLiveStreaming::setSource()");
 
@@ -82,7 +82,7 @@ void HTTPLiveStreaming::setSource(Raym::String *source)
     }
 }
 
-void HTTPLiveStreaming::setOutputPath(Raym::String *output_path)
+void HTTPLiveStreaming::setOutputPath(String *output_path)
 {
     DebugLog2("HTTPLiveStreaming::setOutputPath()");
 
@@ -93,7 +93,12 @@ void HTTPLiveStreaming::setOutputPath(Raym::String *output_path)
     }
 }
 
-void HTTPLiveStreaming::setIndexName(Raym::String *index_name)
+String *HTTPLiveStreaming::outputPath()
+{
+    return _output_path;
+}
+
+void HTTPLiveStreaming::setIndexName(String *index_name)
 {
     DebugLog2("HTTPLiveStreaming::setIndexName()");
 
@@ -106,6 +111,22 @@ void HTTPLiveStreaming::setIndexName(Raym::String *index_name)
 
 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
@@ -116,7 +137,9 @@ bool HTTPLiveStreaming::start()
     // 暫定処理
 //    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",
@@ -135,6 +158,54 @@ bool HTTPLiveStreaming::start()
                               "-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();
@@ -142,7 +213,11 @@ bool HTTPLiveStreaming::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()));
 }
 
 
@@ -150,7 +225,7 @@ bool HTTPLiveStreaming::readLine(String *line)
 {
     if (line != NULL)
     {
-        DebugLog3("ffmpeg: %s", line->cString());
+//        DebugLog3("ffmpeg: %s", line->cString());
     }
     return false;
 }
index 64d7b77..8190c8b 100644 (file)
@@ -38,6 +38,7 @@ public:
 
     void setSource(Raym::String *source);
     void setOutputPath(Raym::String *output_path);
+    Raym::String *outputPath();
     void setIndexName(Raym::String *index_name);
 
     bool start();