VideoFileStream *CreateFileStream(String strOutputFile) { String strFileExtension = GetPathExtension(strOutputFile); if (strFileExtension.CompareI(TEXT("flv"))) return CreateFLVFileStream(strOutputFile); else if (strFileExtension.CompareI(TEXT("mp4"))) return CreateMP4FileStream(strOutputFile); return nullptr; }
void HttpResponse::WriteTemplate(char* code) { char buf[DATA_BUFSIZE]; memset(buf, '\0', DATA_BUFSIZE); std::string str = GetTemplateContent(code); std::string filename = GetTemplateFilepath(code); GetPathExtension(filename.c_str()); SetContentTypeFromExtension(); std::vector<byte> rv; const char *ret = str.c_str(); rv.assign(ret, ret + strlen(ret)); m_sbResponsePackage = rv; }
String GetExpandedRecordingDirectoryBase(String path) { if (GetPathExtension(path)) path = GetPathDirectory(path); String expanded = path; do { expanded = ExpandRecordingFilename(path); if (expanded == path) break; if (OSFileIsDirectory(expanded)) break; path = GetPathDirectory(path); } while (expanded != path); CreatePath(expanded); return expanded; }
void OBS::Start() { if(bRunning) return; OSEnterMutex (hStartupShutdownMutex); scenesConfig.Save(); //------------------------------------------------------------- fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30); frameTime = 1000/fps; //------------------------------------------------------------- if(!bLoggedSystemStats) { LogSystemStats(); bLoggedSystemStats = TRUE; } OSCheckForBuggyDLLs(); //------------------------------------------------------------- retryHookTest: bool alreadyWarnedAboutModules = false; if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (pre-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { OSLeaveMutex (hStartupShutdownMutex); return; } else if (ret == IDRETRY) { goto retryHookTest; } alreadyWarnedAboutModules = true; } String strPatchesError; if (OSIncompatiblePatchesLoaded(strPatchesError)) { OSLeaveMutex (hStartupShutdownMutex); MessageBox(hwndMain, strPatchesError.Array(), NULL, MB_ICONERROR); Log(TEXT("Incompatible patches detected.")); return; } //------------------------------------------------------------- String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (!scmp(processPriority, TEXT("Idle"))) SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("Above Normal"))) SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("High"))) SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); DWORD delayTime = (DWORD)AppConfig->GetInt(TEXT("Publish"), TEXT("Delay")); String strError; bFirstConnect = !bReconnecting; if(bTestStream) network = CreateNullNetwork(); else { switch(networkMode) { case 0: network = (delayTime > 0) ? CreateDelayedPublisher(delayTime) : CreateRTMPPublisher(); break; case 1: network = CreateNullNetwork(); break; } } if(!network) { OSLeaveMutex (hStartupShutdownMutex); if(!bReconnecting) MessageBox(hwndMain, strError, NULL, MB_ICONERROR); else DialogBox(hinstMain, MAKEINTRESOURCE(IDD_RECONNECTING), hwndMain, OBS::ReconnectDialogProc); return; } bReconnecting = false; //------------------------------------------------------------- Log(TEXT("=====Stream Start: %s==============================================="), CurrentDateTimeString().Array()); //------------------------------------------------------------- bEnableProjectorCursor = GlobalConfig->GetInt(L"General", L"EnableProjectorCursor", 1) != 0; bPleaseEnableProjector = bPleaseDisableProjector = false; int monitorID = AppConfig->GetInt(TEXT("Video"), TEXT("Monitor")); if(monitorID >= (int)monitors.Num()) monitorID = 0; RECT &screenRect = monitors[monitorID].rect; int defCX = screenRect.right - screenRect.left; int defCY = screenRect.bottom - screenRect.top; downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0); downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX); baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY); baseCX = MIN(MAX(baseCX, 128), 4096); baseCY = MIN(MAX(baseCY, 128), 4096); scaleCX = UINT(double(baseCX) / double(downscale)); scaleCY = UINT(double(baseCY) / double(downscale)); //align width to 128bit for fast SSE YUV4:2:0 conversion outputCX = scaleCX & 0xFFFFFFFC; outputCY = scaleCY & 0xFFFFFFFE; bUseMultithreadedOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0; Log(TEXT(" Multithreaded optimizations: %s"), (CTSTR)(bUseMultithreadedOptimizations ? TEXT("On") : TEXT("Off"))); encoderSkipThreshold = GlobalConfig->GetInt(TEXT("Video"), TEXT("EncoderSkipThreshold"), fps/4); //------------------------------------------------------------------ Log(TEXT(" Base resolution: %ux%u"), baseCX, baseCY); Log(TEXT(" Output resolution: %ux%u"), outputCX, outputCY); Log(TEXT("------------------------------------------")); //------------------------------------------------------------------ GS = new D3D10System; GS->Init(); //Thanks to ASUS OSD hooking the goddamn user mode driver framework (!!!!), we have to re-check for dangerous //hooks after initializing D3D. retryHookTestV2: if (!alreadyWarnedAboutModules) { if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (post-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { //FIXME: really need a better way to abort startup than this... delete network; delete GS; OSLeaveMutex (hStartupShutdownMutex); return; } else if (ret == IDRETRY) { goto retryHookTestV2; } } } //------------------------------------------------------------- mainVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader")); mainPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawTexture.pShader")); solidVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader")); solidPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader")); if(!mainVertexShader || !mainPixelShader) CrashError(TEXT("Unable to load DrawTexture shaders")); if(!solidVertexShader || !solidPixelShader) CrashError(TEXT("Unable to load DrawSolid shaders")); //------------------------------------------------------------------ CTSTR lpShader; if(CloseFloat(downscale, 1.0)) lpShader = TEXT("shaders/DrawYUVTexture.pShader"); else if(downscale < 2.01) { switch(downscaleType) { case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break; case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break; case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break; } } else if(downscale < 3.01) lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader"); else CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)")); yuvScalePixelShader = CreatePixelShaderFromFile(lpShader); if (!yuvScalePixelShader) CrashError(TEXT("Unable to create shader from file %s"), lpShader); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { mainRenderTextures[i] = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE); yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE); } //------------------------------------------------------------- D3D10_TEXTURE2D_DESC td; zero(&td, sizeof(td)); td.Width = outputCX; td.Height = outputCY; td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; td.MipLevels = 1; td.ArraySize = 1; td.SampleDesc.Count = 1; td.ArraySize = 1; td.Usage = D3D10_USAGE_STAGING; td.CPUAccessFlags = D3D10_CPU_ACCESS_READ; for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { HRESULT err = GetD3D()->CreateTexture2D(&td, NULL, ©Textures[i]); if(FAILED(err)) { CrashError(TEXT("Unable to create copy texture")); //todo - better error handling } } //------------------------------------------------------------------ UINT format = AppConfig->GetInt(L"Audio Encoding", L"Format", 1); switch (format) { case 0: sampleRateHz = 44100; break; default: case 1: sampleRateHz = 48000; break; } Log(L"------------------------------------------"); Log(L"Audio Format: %uhz", sampleRateHz); //------------------------------------------------------------------ AudioDeviceList playbackDevices; GetAudioDevices(playbackDevices, ADT_PLAYBACK); String strPlaybackDevice = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); if(strPlaybackDevice.IsEmpty() || !playbackDevices.HasID(strPlaybackDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); strPlaybackDevice = TEXT("Default"); } Log(TEXT("Playback device %s"), strPlaybackDevice.Array()); playbackDevices.FreeData(); desktopAudio = CreateAudioSource(false, strPlaybackDevice); if(!desktopAudio) { CrashError(TEXT("Cannot initialize desktop audio sound, more info in the log file.")); } AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); String strDefaultMic; bool bHasDefault = GetDefaultMicID(strDefaultMic); if(strDevice.CompareI(TEXT("Disable"))) EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); else { bool bUseDefault = strDevice.CompareI(TEXT("Default")) != 0; if(!bUseDefault || bHasDefault) { if(bUseDefault) strDevice = strDefaultMic; micAudio = CreateAudioSource(true, strDevice); if(!micAudio) MessageBox(hwndMain, Str("MicrophoneFailure"), NULL, 0); else micAudio->SetTimeOffset(AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0)); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), micAudio != NULL); } else EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); } //------------------------------------------------------------- bool bDisableEncoding = false; if (bTestStream) bDisableEncoding = GlobalConfig->GetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), false) != 0; //------------------------------------------------------------- UINT bitRate = (UINT)AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96); String strEncoder = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); if (bDisableEncoding) audioEncoder = CreateNullAudioEncoder(); else #ifdef USE_AAC if(strEncoder.CompareI(TEXT("AAC")))// && OSGetVersion() >= 7) audioEncoder = CreateAACEncoder(bitRate); else #endif audioEncoder = CreateMP3Encoder(bitRate); //------------------------------------------------------------- desktopVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("DesktopVolume"), 1.0f); micVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("MicVolume"), 1.0f); //------------------------------------------------------------- bRunning = true; if(sceneElement) { scene = CreateScene(sceneElement->GetString(TEXT("class")), sceneElement->GetElement(TEXT("data"))); XElement *sources = sceneElement->GetElement(TEXT("sources")); if(sources) { UINT numSources = sources->NumElements(); for(UINT i=0; i<numSources; i++) { SceneItem *item = scene->AddImageSource(sources->GetElementByID(i)); if(item) { if(ListView_GetItemState(GetDlgItem(hwndMain, ID_SOURCES), i, LVIS_SELECTED) > 0) item->Select(true); } } } scene->BeginScene(); } if(scene && scene->HasMissingSources()) MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0); //------------------------------------------------------------- int maxBitRate = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int bufferSize = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("BufferSize"), 1000); int quality = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Quality"), 8); String preset = AppConfig->GetString(TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); bUsing444 = false;//AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Use444"), 0) != 0; bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 1) != 0; //------------------------------------------------------------- bWriteToFile = networkMode == 1 || AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")) != 0; String strOutputFile = AppConfig->GetString(TEXT("Publish"), TEXT("SavePath")); strOutputFile.FindReplace(TEXT("\\"), TEXT("/")); if (bWriteToFile) { OSFindData ofd; HANDLE hFind = NULL; bool bUseDateTimeName = true; bool bOverwrite = GlobalConfig->GetInt(L"General", L"OverwriteRecordings", false) != 0; if(!bOverwrite && (hFind = OSFindFirstFile(strOutputFile, ofd))) { String strFileExtension = GetPathExtension(strOutputFile); String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile); if(strFileExtension.IsValid() && !ofd.bDirectory) { String strNewFilePath; UINT curFile = 0; do { strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension; } while(OSFileExists(strNewFilePath)); strOutputFile = strNewFilePath; bUseDateTimeName = false; } if(ofd.bDirectory) strOutputFile.AppendChar('/'); OSFindClose(hFind); } if(bUseDateTimeName) { String strFileName = GetPathFileName(strOutputFile); if(!strFileName.IsValid() || !IsSafeFilename(strFileName)) { SYSTEMTIME st; GetLocalTime(&st); String strDirectory = GetPathDirectory(strOutputFile), extension = GetPathExtension(strOutputFile); if(extension.IsEmpty()) extension = TEXT("mp4"); strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.%s"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, extension.Array()); } } } //------------------------------------------------------------- bufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 700); Log(TEXT("Scene buffering time set to %u"), bufferingTime); //------------------------------------------------------------- bForceMicMono = AppConfig->GetInt(TEXT("Audio"), TEXT("ForceMicMono")) != 0; bRecievedFirstAudioFrame = false; //hRequestAudioEvent = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL); hSoundDataMutex = OSCreateMutex(); hSoundThread = OSCreateThread((XTHREAD)OBS::MainAudioThread, NULL); //------------------------------------------------------------- StartBlankSoundPlayback(strPlaybackDevice); //------------------------------------------------------------- colorDesc.fullRange = false; colorDesc.primaries = ColorPrimaries_BT709; colorDesc.transfer = ColorTransfer_IEC6196621; colorDesc.matrix = outputCX >= 1280 || outputCY > 576 ? ColorMatrix_BT709 : ColorMatrix_SMPTE170M; videoEncoder = nullptr; if (bDisableEncoding) videoEncoder = CreateNullVideoEncoder(); else if(AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0) videoEncoder = CreateQSVEncoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR); if(!videoEncoder) videoEncoder = CreateX264Encoder(fps, outputCX, outputCY, quality, preset, bUsing444, colorDesc, maxBitRate, bufferSize, bUseCFR); //------------------------------------------------------------- // Ensure that the render frame is properly sized ResizeRenderFrame(true); //------------------------------------------------------------- if(!bTestStream && bWriteToFile && strOutputFile.IsValid()) { String strFileExtension = GetPathExtension(strOutputFile); if(strFileExtension.CompareI(TEXT("flv"))) fileStream = CreateFLVFileStream(strOutputFile); else if(strFileExtension.CompareI(TEXT("mp4"))) fileStream = CreateMP4FileStream(strOutputFile); if(!fileStream) { Log(TEXT("Warning - OBSCapture::Start: Unable to create the file stream. Check the file path in Broadcast Settings.")); MessageBox(hwndMain, Str("Capture.Start.FileStream.Warning"), Str("Capture.Start.FileStream.WarningCaption"), MB_OK | MB_ICONWARNING); } } //------------------------------------------------------------- curFramePic = NULL; bShutdownVideoThread = false; bShutdownEncodeThread = false; //ResetEvent(hVideoThread); hEncodeThread = OSCreateThread((XTHREAD)OBS::EncodeThread, NULL); hVideoThread = OSCreateThread((XTHREAD)OBS::MainCaptureThread, NULL); if(bTestStream) { EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.StopTest")); } else { EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StopStream")); } EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), TRUE); //------------------------------------------------------------- ReportStartStreamTrigger(); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0); SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED | ES_DISPLAY_REQUIRED); UpdateRenderViewMessage(); //update notification icon to reflect current status UpdateNotificationAreaIcon(); OSLeaveMutex (hStartupShutdownMutex); }
void OBS::StartRecording() { if (bRecording) return; int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); bWriteToFile = networkMode == 1 || AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")) != 0; String strOutputFile = AppConfig->GetString(TEXT("Publish"), TEXT("SavePath")); strOutputFile.FindReplace(TEXT("\\"), TEXT("/")); // Don't request a keyframe while everything is starting up for the first time if(!bStartingUp) videoEncoder->RequestKeyframe(); if (bWriteToFile) { OSFindData ofd; HANDLE hFind = NULL; bool bUseDateTimeName = true; bool bOverwrite = GlobalConfig->GetInt(L"General", L"OverwriteRecordings", false) != 0; if(!bOverwrite && (hFind = OSFindFirstFile(strOutputFile, ofd))) { String strFileExtension = GetPathExtension(strOutputFile); String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile); if(strFileExtension.IsValid() && !ofd.bDirectory) { String strNewFilePath; UINT curFile = 0; do { strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension; } while(OSFileExists(strNewFilePath)); strOutputFile = strNewFilePath; bUseDateTimeName = false; } if(ofd.bDirectory) strOutputFile.AppendChar('/'); OSFindClose(hFind); } if(bUseDateTimeName) { String strFileName = GetPathFileName(strOutputFile); if(!strFileName.IsValid() || !IsSafeFilename(strFileName)) { SYSTEMTIME st; GetLocalTime(&st); String strDirectory = GetPathDirectory(strOutputFile); String file = strOutputFile.Right(strOutputFile.Length() - strDirectory.Length()); String extension; if (!file.IsEmpty()) extension = GetPathExtension(file.Array()); if(extension.IsEmpty()) extension = TEXT("mp4"); strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.%s"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, extension.Array()); } } } if(!bTestStream && bWriteToFile && strOutputFile.IsValid()) { String strFileExtension = GetPathExtension(strOutputFile); if(strFileExtension.CompareI(TEXT("flv"))) fileStream = CreateFLVFileStream(strOutputFile); else if(strFileExtension.CompareI(TEXT("mp4"))) fileStream = CreateMP4FileStream(strOutputFile); if(!fileStream) { Log(TEXT("Warning - OBSCapture::Start: Unable to create the file stream. Check the file path in Broadcast Settings.")); MessageBox(hwndMain, Str("Capture.Start.FileStream.Warning"), Str("Capture.Start.FileStream.WarningCaption"), MB_OK | MB_ICONWARNING); bRecording = false; } else { bRecording = true; ReportStartRecordingTrigger(); } ConfigureStreamButtons(); } }
String GetOutputFilename(bool replayBuffer=false) { String path = OSGetDefaultVideoSavePath(replayBuffer ? L"\\Replay-$T.flv" : L"\\.flv"); String strOutputFile = AppConfig->GetString(TEXT("Publish"), replayBuffer ? L"ReplayBufferSavePath" : L"SavePath", path.IsValid() ? path.Array() : nullptr); strOutputFile.FindReplace(TEXT("\\"), TEXT("/")); OSFindData ofd; HANDLE hFind = NULL; bool bUseDateTimeName = true; bool bOverwrite = GlobalConfig->GetInt(L"General", L"OverwriteRecordings", false) != 0; strOutputFile = ExpandRecordingFilename(strOutputFile); CreatePath(GetPathDirectory(strOutputFile)); if (!bOverwrite && (hFind = OSFindFirstFile(strOutputFile, ofd))) { String strFileExtension = GetPathExtension(strOutputFile); String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile); if (strFileExtension.IsValid() && !ofd.bDirectory) { String strNewFilePath; UINT curFile = 0; do { strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension; } while (OSFileExists(strNewFilePath)); strOutputFile = strNewFilePath; bUseDateTimeName = false; } if (ofd.bDirectory) strOutputFile.AppendChar('/'); OSFindClose(hFind); } if (bUseDateTimeName) { String strFileName = GetPathFileName(strOutputFile); if (!strFileName.IsValid() || !IsSafeFilename(strFileName)) { SYSTEMTIME st; GetLocalTime(&st); String strDirectory = GetPathDirectory(strOutputFile); String file = strOutputFile.Right(strOutputFile.Length() - strDirectory.Length()); String extension; if (!file.IsEmpty()) extension = GetPathExtension(file.Array()); if (extension.IsEmpty()) extension = TEXT("mp4"); strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.%s"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, extension.Array()); } } return strOutputFile; }
INT_PTR SettingsPublish::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { HWND hwndTemp; switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); RECT serviceRect, saveToFileRect; GetWindowRect(GetDlgItem(hwnd, IDC_SERVICE), &serviceRect); GetWindowRect(GetDlgItem(hwnd, IDC_SAVEPATH), &saveToFileRect); data.fileControlOffset = saveToFileRect.top-serviceRect.top; //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_MODE); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish.Mode.LiveStream")); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)Str("Settings.Publish.Mode.FileOnly")); int mode = LoadSettingComboInt(hwndTemp, TEXT("Publish"), TEXT("Mode"), 0, 2); data.mode = mode; //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_SERVICE); int itemId = (int)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)TEXT("Custom")); SendMessage(hwndTemp, CB_SETITEMDATA, itemId, 0); UINT numServices = 0; XConfig serverData; if(serverData.Open(TEXT("services.xconfig"))) { XElement *services = serverData.GetElement(TEXT("services")); if(services) { numServices = services->NumElements(); for(UINT i=0; i<numServices; i++) { XElement *service = services->GetElementByID(i); itemId = (int)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)service->GetName()); SendMessage(hwndTemp, CB_SETITEMDATA, itemId, service->GetInt(TEXT("id"))); } } } int serviceID = AppConfig->GetInt(TEXT("Publish"), TEXT("Service"), 0); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_PLAYPATH); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("PlayPath"), NULL); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); if(serviceID == 0) //custom { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_URL); LoadSettingEditString(hwndTemp, TEXT("Publish"), TEXT("URL"), NULL); SendDlgItemMessage(hwnd, IDC_SERVICE, CB_SETCURSEL, 0, 0); } else { ShowWindow(GetDlgItem(hwnd, IDC_URL), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_SERVERLIST); XElement *services = serverData.GetElement(TEXT("services")); if(services) { XElement *service = NULL; numServices = services->NumElements(); for(UINT i=0; i<numServices; i++) { XElement *curService = services->GetElementByID(i); if(curService->GetInt(TEXT("id")) == serviceID) { SendDlgItemMessage(hwnd, IDC_SERVICE, CB_SETCURSEL, i+1, 0); service = curService; break; } } if(service) { XElement *servers = service->GetElement(TEXT("servers")); if(servers) { UINT numServers = servers->NumDataItems(); for(UINT i=0; i<numServers; i++) { XDataItem *server = servers->GetDataItemByID(i); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)server->GetName()); } } } } LoadSettingComboString(hwndTemp, TEXT("Publish"), TEXT("URL"), NULL); } if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_LOWLATENCYMODE); BOOL bLowLatencyMode = AppConfig->GetInt(TEXT("Publish"), TEXT("LowLatencyMode"), 0); SendMessage(hwndTemp, BM_SETCHECK, bLowLatencyMode ? BST_CHECKED : BST_UNCHECKED, 0); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_AUTORECONNECT); BOOL bAutoReconnect = AppConfig->GetInt(TEXT("Publish"), TEXT("AutoReconnect"), 1); SendMessage(hwndTemp, BM_SETCHECK, bAutoReconnect ? BST_CHECKED : BST_UNCHECKED, 0); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT); EnableWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_EDIT), bAutoReconnect); EnableWindow(hwndTemp, bAutoReconnect); int retryTime = AppConfig->GetInt(TEXT("Publish"), TEXT("AutoReconnectTimeout"), 10); if(retryTime > 60) retryTime = 60; else if(retryTime < 0) retryTime = 0; SendMessage(hwndTemp, UDM_SETRANGE32, 0, 60); SendMessage(hwndTemp, UDM_SETPOS32, 0, retryTime); if(mode != 0) ShowWindow(hwndTemp, SW_HIDE); //-------------------------------------------- hwndTemp = GetDlgItem(hwnd, IDC_DELAY); int delayTime = AppConfig->GetInt(TEXT("Publish"), TEXT("Delay"), 0); SendMessage(hwndTemp, UDM_SETRANGE32, 0, 900); SendMessage(hwndTemp, UDM_SETPOS32, 0, delayTime); //-------------------------------------------- if(mode != 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVICE_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_URL_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_SERVER_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_LOWLATENCYMODE), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_EDIT), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_DELAY_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_DELAY_EDIT), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_DELAY), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_KEEPRECORDING), SW_HIDE); //ShowWindow(GetDlgItem(hwnd, IDC_DASHBOARDLINK), SW_HIDE); //ShowWindow(GetDlgItem(hwnd, IDC_DASHBOARDLINK_STATIC), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_SAVETOFILE), SW_HIDE); AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_BROWSE), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTSTREAM), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTRECORDING), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STOPRECORDING), 0, -data.fileControlOffset); } //-------------------------------------------- DWORD startHotkey = AppConfig->GetInt(TEXT("Publish"), TEXT("StartStreamHotkey")); SendMessage(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), HKM_SETHOTKEY, startHotkey, 0); //-------------------------------------------- DWORD stopHotkey = AppConfig->GetInt(TEXT("Publish"), TEXT("StopStreamHotkey")); SendMessage(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), HKM_SETHOTKEY, stopHotkey, 0); //-------------------------------------------- startHotkey = AppConfig->GetInt(TEXT("Publish"), TEXT("StartRecordingHotkey")); SendMessage(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), HKM_SETHOTKEY, startHotkey, 0); //-------------------------------------------- stopHotkey = AppConfig->GetInt(TEXT("Publish"), TEXT("StopRecordingHotkey")); SendMessage(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), HKM_SETHOTKEY, stopHotkey, 0); //-------------------------------------------- BOOL bKeepRecording = AppConfig->GetInt(TEXT("Publish"), TEXT("KeepRecording")); SendMessage(GetDlgItem(hwnd, IDC_KEEPRECORDING), BM_SETCHECK, bKeepRecording ? BST_CHECKED : BST_UNCHECKED, 0); BOOL bSaveToFile = AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")); SendMessage(GetDlgItem(hwnd, IDC_SAVETOFILE), BM_SETCHECK, bSaveToFile ? BST_CHECKED : BST_UNCHECKED, 0); String path = OSGetDefaultVideoSavePath(L"\\.flv"); CTSTR lpSavePath = AppConfig->GetStringPtr(TEXT("Publish"), TEXT("SavePath"), path.IsValid() ? path.Array() : nullptr); SetWindowText(GetDlgItem(hwnd, IDC_SAVEPATH), lpSavePath); EnableWindow(GetDlgItem(hwnd, IDC_KEEPRECORDING), true); EnableWindow(GetDlgItem(hwnd, IDC_SAVEPATH), true); EnableWindow(GetDlgItem(hwnd, IDC_BROWSE), true); //-------------------------------------------- //SetWindowText(GetDlgItem(hwnd, IDC_DASHBOARDLINK), App->strDashboard); //-------------------------------------------- SetWarningInfo(); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); SetChangedSettings(false); return TRUE; } case WM_CTLCOLORSTATIC: { switch (GetDlgCtrlID((HWND)lParam)) { case IDC_WARNINGS: SetTextColor((HDC)wParam, RGB(255, 0, 0)); SetBkColor((HDC)wParam, COLORREF(GetSysColor(COLOR_3DFACE))); return (INT_PTR)GetSysColorBrush(COLOR_BTNFACE); } } break; case WM_DESTROY: { } break; case WM_NOTIFY: { NMHDR *nmHdr = (NMHDR*)lParam; if(nmHdr->idFrom == IDC_AUTORECONNECT_TIMEOUT) { if(nmHdr->code == UDN_DELTAPOS) SetChangedSettings(true); } break; } case WM_COMMAND: { bool bDataChanged = false; switch(LOWORD(wParam)) { case IDC_MODE: { if(HIWORD(wParam) != CBN_SELCHANGE) break; int mode = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); int swShowControls = (mode == 0) ? SW_SHOW : SW_HIDE; ShowWindow(GetDlgItem(hwnd, IDC_SERVICE), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH), swShowControls); int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0); if(serviceID == 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_URL), swShowControls); } else { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_URL), SW_HIDE); } if(mode == 0 && data.mode == 1) { AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH_STATIC), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_BROWSE), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY_STATIC), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY_STATIC), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTSTREAM), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY_STATIC), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY_STATIC), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTRECORDING), 0, data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STOPRECORDING), 0, data.fileControlOffset); } else if(mode == 1 && data.mode == 0) { AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_SAVEPATH), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_BROWSE), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTSTREAM), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY_STATIC), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STARTRECORDING), 0, -data.fileControlOffset); AdjustWindowPos(GetDlgItem(hwnd, IDC_CLEARHOTKEY_STOPRECORDING), 0, -data.fileControlOffset); } data.mode = mode; ShowWindow(GetDlgItem(hwnd, IDC_SERVICE_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_PLAYPATH_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_URL_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_SERVER_STATIC), swShowControls); //ShowWindow(GetDlgItem(hwnd, IDC_DASHBOARDLINK), swShowControls); //ShowWindow(GetDlgItem(hwnd, IDC_DASHBOARDLINK_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_LOWLATENCYMODE), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_EDIT), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_DELAY_STATIC), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_DELAY_EDIT), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_DELAY), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_SAVETOFILE), swShowControls); ShowWindow(GetDlgItem(hwnd, IDC_KEEPRECORDING), swShowControls); SetWarningInfo(); bDataChanged = true; break; } case IDC_SERVICE: if(HIWORD(wParam) == CBN_SELCHANGE) { int serviceID = (int)SendMessage((HWND)lParam, CB_GETCURSEL, 0, 0); if(serviceID == 0) { ShowWindow(GetDlgItem(hwnd, IDC_SERVERLIST), SW_HIDE); ShowWindow(GetDlgItem(hwnd, IDC_URL), SW_SHOW); SetWindowText(GetDlgItem(hwnd, IDC_URL), NULL); //SetWindowText(GetDlgItem(hwnd, IDC_DASHBOARDLINK), NULL); } else { ShowWindow(GetDlgItem(hwnd, IDC_URL), SW_HIDE); hwndTemp = GetDlgItem(hwnd, IDC_SERVERLIST); ShowWindow(hwndTemp, SW_SHOW); SendMessage(hwndTemp, CB_RESETCONTENT, 0, 0); XConfig serverData; if(serverData.Open(TEXT("services.xconfig"))) { XElement *services = serverData.GetElement(TEXT("services")); if(services) { XElement *service = services->GetElementByID(serviceID-1); if(service) { XElement *servers = service->GetElement(TEXT("servers")); if(servers) { UINT numServers = servers->NumDataItems(); for(UINT i=0; i<numServers; i++) { XDataItem *server = servers->GetDataItemByID(i); SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)server->GetName()); } } } } } SendMessage(hwndTemp, CB_SETCURSEL, 0, 0); } SetWindowText(GetDlgItem(hwnd, IDC_PLAYPATH), NULL); bDataChanged = true; } SetWarningInfo(); break; case IDC_AUTORECONNECT: if(HIWORD(wParam) == BN_CLICKED) { BOOL bAutoReconnect = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; EnableWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT), bAutoReconnect); EnableWindow(GetDlgItem(hwnd, IDC_AUTORECONNECT_TIMEOUT_EDIT), bAutoReconnect); SetChangedSettings(true); } break; case IDC_AUTORECONNECT_TIMEOUT_EDIT: if(HIWORD(wParam) == EN_CHANGE) SetChangedSettings(true); break; case IDC_DELAY_EDIT: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_KEEPRECORDING: if(HIWORD(wParam) == BN_CLICKED) { BOOL bKeepRecording = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED; App->bKeepRecording = bKeepRecording != 0; bDataChanged = true; } break; case IDC_BROWSE: { TCHAR lpFile[512]; OPENFILENAME ofn; zero(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = lpFile; ofn.nMaxFile = 511; ofn.lpstrFile[0] = 0; ofn.lpstrFilter = TEXT("MP4 File (*.mp4)\0*.mp4\0Flash Video File (*.flv)\0*.flv\0"); ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.nFilterIndex = 1; String path = OSGetDefaultVideoSavePath(); ofn.lpstrInitialDir = AppConfig->GetStringPtr(TEXT("Publish"), TEXT("LastSaveDir"), path.IsValid() ? path.Array() : nullptr); ofn.Flags = OFN_PATHMUSTEXIST; TCHAR curDirectory[512]; GetCurrentDirectory(511, curDirectory); BOOL bChoseFile = GetSaveFileName(&ofn); SetCurrentDirectory(curDirectory); if(*lpFile && bChoseFile) { String strFile = lpFile; strFile.FindReplace(TEXT("\\"), TEXT("/")); String strExtension = GetPathExtension(strFile); if(strExtension.IsEmpty() || (!strExtension.CompareI(TEXT("flv")) && /*!strExtension.CompareI(TEXT("avi")) &&*/ !strExtension.CompareI(TEXT("mp4")))) { switch(ofn.nFilterIndex) { case 1: strFile << TEXT(".mp4"); break; case 2: strFile << TEXT(".flv"); break; /*case 3: strFile << TEXT(".avi"); break;*/ } } String strFilePath = GetPathDirectory(strFile).FindReplace(TEXT("/"), TEXT("\\")) << TEXT("\\"); AppConfig->SetString(TEXT("Publish"), TEXT("LastSaveDir"), strFilePath); strFile.FindReplace(TEXT("/"), TEXT("\\")); SetWindowText(GetDlgItem(hwnd, IDC_SAVEPATH), strFile); bDataChanged = true; } break; } case IDC_LOWLATENCYMODE: case IDC_SAVETOFILE: if(HIWORD(wParam) == BN_CLICKED) bDataChanged = true; break; case IDC_STARTSTREAMHOTKEY: case IDC_STOPSTREAMHOTKEY: //case IDC_DASHBOARDLINK: case IDC_STARTRECORDINGHOTKEY: case IDC_STOPRECORDINGHOTKEY: if(HIWORD(wParam) == EN_CHANGE) SetChangedSettings(true); break; case IDC_PLAYPATH: case IDC_URL: case IDC_SAVEPATH: if(HIWORD(wParam) == EN_CHANGE) bDataChanged = true; break; case IDC_CLEARHOTKEY_STARTSTREAM: if(HIWORD(wParam) == BN_CLICKED) { if(SendMessage(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), HKM_GETHOTKEY, 0, 0)) { SendMessage(GetDlgItem(hwnd, IDC_STARTSTREAMHOTKEY), HKM_SETHOTKEY, 0, 0); SetChangedSettings(true); } } break; case IDC_CLEARHOTKEY: if(HIWORD(wParam) == BN_CLICKED) { if(SendMessage(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), HKM_GETHOTKEY, 0, 0)) { SendMessage(GetDlgItem(hwnd, IDC_STOPSTREAMHOTKEY), HKM_SETHOTKEY, 0, 0); SetChangedSettings(true); } } break; case IDC_CLEARHOTKEY_STARTRECORDING: if (HIWORD(wParam) == BN_CLICKED) { if (SendMessage(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), HKM_GETHOTKEY, 0, 0)) { SendMessage(GetDlgItem(hwnd, IDC_STARTRECORDINGHOTKEY), HKM_SETHOTKEY, 0, 0); SetChangedSettings(true); } } break; case IDC_CLEARHOTKEY_STOPRECORDING: if (HIWORD(wParam) == BN_CLICKED) { if (SendMessage(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), HKM_GETHOTKEY, 0, 0)) { SendMessage(GetDlgItem(hwnd, IDC_STOPRECORDINGHOTKEY), HKM_SETHOTKEY, 0, 0); SetChangedSettings(true); } } break; case IDC_SERVERLIST: if(HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_SELCHANGE) bDataChanged = true; break; } if(bDataChanged) { ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); } break; } } return FALSE; }
void SslSocketCpServer::Dispatch(HttpRequest *httpRequest, HttpResponse *httpResponse) { if (httpRequest->GetMethod() == MethodType::HTTP_GET) { EvalGet(httpRequest, httpResponse); } if (httpRequest->GetMethod() == MethodType::HTTP_POST) { EvalPost(httpRequest, httpResponse); } if (IsStatic(httpRequest->GetUrl())) { printf("Static Directory\n"); EvalStatic(httpRequest, httpResponse); return; } if (HasUrlParams(httpRequest->GetUrl())) { printf("Has URL Params\n"); LPSTATICFUNC lpFunc = (LPSTATICFUNC)GetUrlParamHandler(httpRequest->GetUrl()); httpRequest->urlParams.assign(urlParams.begin(), urlParams.end()); if (lpFunc != NULL) { (*lpFunc)(httpRequest, httpResponse); } else { UrlNotFound(httpRequest, httpResponse); } return; } LPSTATICFUNC lpFunc = (LPSTATICFUNC)GetRoute(httpRequest->GetUrl()); if (lpFunc != NULL) { (*lpFunc)(httpRequest, httpResponse); } else { WCHAR buffer[BUFSIZMIN]; char *url = httpRequest->GetUrl(); std::string surl; surl.append("./"); surl.append(url); std::wstring wsurl(surl.begin(), surl.end()); DWORD dwres = GetFullPathName(wsurl.c_str(), BUFSIZMIN, buffer, NULL); if (dwres > 0) { PTSTR str = GetPathExtension(buffer); std::wstring wsbuffer(buffer); std::string sbuffer(wsbuffer.begin(), wsbuffer.end()); if (FileExist(wsbuffer.c_str())) { httpResponse->SetStaticFileName(sbuffer.c_str()); httpResponse->WriteStatic(sbuffer.c_str()); return; } else { printf("File not found: %s \n", sbuffer.c_str()); } } UrlNotFound(httpRequest, httpResponse); } }
void OBS::Start() { if(bRunning) return; OSEnterMutex (hStartupShutdownMutex); scenesConfig.Save(); //------------------------------------------------------------- fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30); frameTime = 1000/fps; //------------------------------------------------------------- if(!bLoggedSystemStats) { LogSystemStats(); bLoggedSystemStats = TRUE; } //------------------------------------------------------------- if (OSIncompatibleModulesLoaded()) { OSLeaveMutex (hStartupShutdownMutex); MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR); Log(TEXT("Incompatible modules detected.")); return; } String strPatchesError; if (OSIncompatiblePatchesLoaded(strPatchesError)) { OSLeaveMutex (hStartupShutdownMutex); MessageBox(hwndMain, strPatchesError.Array(), NULL, MB_ICONERROR); Log(TEXT("Incompatible patches detected.")); return; } //------------------------------------------------------------- int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); DWORD delayTime = (DWORD)AppConfig->GetInt(TEXT("Publish"), TEXT("Delay")); String strError; if(bTestStream) network = CreateNullNetwork(); else { switch(networkMode) { case 0: network = (delayTime > 0) ? CreateDelayedPublisher(delayTime) : CreateRTMPPublisher(); break; case 1: network = CreateNullNetwork(); break; } } if(!network) { OSLeaveMutex (hStartupShutdownMutex); if(!bReconnecting) MessageBox(hwndMain, strError, NULL, MB_ICONERROR); else DialogBox(hinstMain, MAKEINTRESOURCE(IDD_RECONNECTING), hwndMain, OBS::ReconnectDialogProc); return; } bReconnecting = false; //------------------------------------------------------------- Log(TEXT("=====Stream Start: %s==============================================="), CurrentDateTime().Array()); //------------------------------------------------------------- int monitorID = AppConfig->GetInt(TEXT("Video"), TEXT("Monitor")); if(monitorID >= (int)monitors.Num()) monitorID = 0; RECT &screenRect = monitors[monitorID].rect; int defCX = screenRect.right - screenRect.left; int defCY = screenRect.bottom - screenRect.top; downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0); downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX); baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY); baseCX = MIN(MAX(baseCX, 128), 4096); baseCY = MIN(MAX(baseCY, 128), 4096); scaleCX = UINT(double(baseCX) / double(downscale)); scaleCY = UINT(double(baseCY) / double(downscale)); //align width to 128bit for fast SSE YUV4:2:0 conversion outputCX = scaleCX & 0xFFFFFFFC; outputCY = scaleCY & 0xFFFFFFFE; bUseMultithreadedOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0; Log(TEXT(" Multithreaded optimizations: %s"), (CTSTR)(bUseMultithreadedOptimizations ? TEXT("On") : TEXT("Off"))); GlobalConfig->SetInt(TEXT("Audio"), TEXT("GlobalAudioTimeAdjust"), 0); //------------------------------------------------------------------ Log(TEXT(" Base resolution: %ux%u"), baseCX, baseCY); Log(TEXT(" Output resolution: %ux%u"), outputCX, outputCY); Log(TEXT("------------------------------------------")); //------------------------------------------------------------------ GS = new D3D10System; GS->Init(); //------------------------------------------------------------- mainVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader")); mainPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawTexture.pShader")); solidVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader")); solidPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader")); //------------------------------------------------------------------ CTSTR lpShader; if(CloseFloat(downscale, 1.0)) lpShader = TEXT("shaders/DrawYUVTexture.pShader"); else if(downscale < 2.01) { switch(downscaleType) { case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break; case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break; case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break; } } else if(downscale < 3.01) lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader"); else CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)")); yuvScalePixelShader = CreatePixelShaderFromFile(lpShader); if (!yuvScalePixelShader) CrashError(TEXT("Unable to create shader from file %s"), lpShader); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { mainRenderTextures[i] = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE); yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE); } //------------------------------------------------------------- D3D10_TEXTURE2D_DESC td; zero(&td, sizeof(td)); td.Width = outputCX; td.Height = outputCY; td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; td.MipLevels = 1; td.ArraySize = 1; td.SampleDesc.Count = 1; td.ArraySize = 1; td.Usage = D3D10_USAGE_STAGING; td.CPUAccessFlags = D3D10_CPU_ACCESS_READ; for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { HRESULT err = GetD3D()->CreateTexture2D(&td, NULL, ©Textures[i]); if(FAILED(err)) { CrashError(TEXT("Unable to create copy texture")); //todo - better error handling } } //------------------------------------------------------------- AudioDeviceList playbackDevices; GetAudioDevices(playbackDevices, ADT_PLAYBACK); String strPlaybackDevice = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); if(strPlaybackDevice.IsEmpty() || !playbackDevices.HasID(strPlaybackDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); strPlaybackDevice = TEXT("Default"); } Log(TEXT("Playback device %s"), strPlaybackDevice.Array()); playbackDevices.FreeData(); desktopAudio = CreateAudioSource(false, strPlaybackDevice); if(!desktopAudio) { CrashError(TEXT("Cannot initialize desktop audio sound, more info in the log file.")); } AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); String strDefaultMic; bool bHasDefault = GetDefaultMicID(strDefaultMic); if(strDevice.CompareI(TEXT("Disable"))) EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); else { bool bUseDefault = strDevice.CompareI(TEXT("Default")) != 0; if(!bUseDefault || bHasDefault) { if(bUseDefault) strDevice = strDefaultMic; micAudio = CreateAudioSource(true, strDevice); if(!micAudio) MessageBox(hwndMain, Str("MicrophoneFailure"), NULL, 0); else micAudio->SetTimeOffset(AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0)); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), micAudio != NULL); } else EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); } //------------------------------------------------------------- UINT bitRate = (UINT)AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96); String strEncoder = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); #ifdef USE_AAC if(strEncoder.CompareI(TEXT("AAC")) && OSGetVersion() >= 7) audioEncoder = CreateAACEncoder(bitRate); else #endif audioEncoder = CreateMP3Encoder(bitRate); //------------------------------------------------------------- desktopVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("DesktopVolume"), 1.0f); micVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("MicVolume"), 1.0f); //------------------------------------------------------------- bRunning = true; if(sceneElement) { scene = CreateScene(sceneElement->GetString(TEXT("class")), sceneElement->GetElement(TEXT("data"))); XElement *sources = sceneElement->GetElement(TEXT("sources")); if(sources) { UINT numSources = sources->NumElements(); for(UINT i=0; i<numSources; i++) { SceneItem *item = scene->AddImageSource(sources->GetElementByID(i)); if(item) { if(ListView_GetItemState(GetDlgItem(hwndMain, ID_SOURCES), i, LVIS_SELECTED) > 0) item->Select(true); } } } scene->BeginScene(); } if(scene && scene->HasMissingSources()) MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0); //------------------------------------------------------------- int maxBitRate = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int bufferSize = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("BufferSize"), 1000); int quality = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Quality"), 8); String preset = AppConfig->GetString(TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); bUsing444 = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Use444"), 0) != 0; bDupeFrames = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("DupeFrames"), 1) != 0; if(bUsing444) bDupeFrames = bUseCFR = false; else { bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 0) != 0; if(bUseCFR) bDupeFrames = true; } //------------------------------------------------------------- bWriteToFile = networkMode == 1 || AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")) != 0; String strOutputFile = AppConfig->GetString(TEXT("Publish"), TEXT("SavePath")); strOutputFile.FindReplace(TEXT("\\"), TEXT("/")); if (bWriteToFile) { OSFindData ofd; HANDLE hFind = NULL; bool bUseDateTimeName = true; if(hFind = OSFindFirstFile(strOutputFile, ofd)) { String strFileExtension = GetPathExtension(strOutputFile); String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile); if(strFileExtension.IsValid() && !ofd.bDirectory) { String strNewFilePath; UINT curFile = 0; do { strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension; } while(OSFileExists(strNewFilePath)); strOutputFile = strNewFilePath; bUseDateTimeName = false; } if(ofd.bDirectory) strOutputFile.AppendChar('/'); OSFindClose(hFind); } if(bUseDateTimeName) { String strFileName = GetPathFileName(strOutputFile); if(!strFileName.IsValid() || !IsSafeFilename(strFileName)) { SYSTEMTIME st; GetLocalTime(&st); String strDirectory = GetPathDirectory(strOutputFile); strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.mp4"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); } } } //------------------------------------------------------------- bufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 400); //------------------------------------------------------------- bForceMicMono = AppConfig->GetInt(TEXT("Audio"), TEXT("ForceMicMono")) != 0; bRecievedFirstAudioFrame = false; //hRequestAudioEvent = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL); hSoundDataMutex = OSCreateMutex(); hSoundThread = OSCreateThread((XTHREAD)OBS::MainAudioThread, NULL); //------------------------------------------------------------- StartBlankSoundPlayback(strPlaybackDevice); //------------------------------------------------------------- ctsOffset = 0; videoEncoder = CreateX264Encoder(fps, outputCX, outputCY, quality, preset, bUsing444, maxBitRate, bufferSize, bUseCFR, bDupeFrames); //------------------------------------------------------------- // Ensure that the render frame is properly sized ResizeRenderFrame(true); //------------------------------------------------------------- if(!bTestStream && bWriteToFile && strOutputFile.IsValid()) { String strFileExtension = GetPathExtension(strOutputFile); if(strFileExtension.CompareI(TEXT("flv"))) fileStream = CreateFLVFileStream(strOutputFile); else if(strFileExtension.CompareI(TEXT("mp4"))) fileStream = CreateMP4FileStream(strOutputFile); } //------------------------------------------------------------- hMainThread = OSCreateThread((XTHREAD)OBS::MainCaptureThread, NULL); if(bTestStream) { EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.StopTest")); } else { EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StopStream")); } EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), TRUE); //------------------------------------------------------------- ReportStartStreamTrigger(); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0); SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED | ES_DISPLAY_REQUIRED); UpdateRenderViewMessage(); //update notification icon to reflect current status UpdateNotificationAreaIcon(); OSLeaveMutex (hStartupShutdownMutex); }
ff::String ff::CleanFileName(StringRef name) { String szNewName(name); for (size_t i = PreviousSize(szNewName.length()); i != INVALID_SIZE; i = PreviousSize(i)) { wchar_t ch = szNewName[i]; if (ch == '.' && (i == szNewName.length() - 1 || (i > 0 && szNewName[i - 1] == '.'))) { // Don't allow more than one period in a row, // and don't allow a period at the end szNewName.erase(i, 1); } else if (ch < 32 || ch > 125) { szNewName[i] = '-'; } else switch (ch) { case '<': szNewName[i] = '('; break; case '>': szNewName[i] = ')'; break; case ':': szNewName[i] = '-'; break; case '\"': szNewName[i] = '\''; break; case '/': szNewName[i] = '-'; break; case '\\': szNewName[i] = '-'; break; case '|': szNewName[i] = '-'; break; case '?': szNewName[i] = '-'; break; case '*': szNewName[i] = '-'; break; } } String szExt = GetPathExtension(szNewName); ChangePathExtension(szNewName, GetEmptyString()); if (!_wcsicmp(szNewName.c_str(), L"CON") || !_wcsicmp(szNewName.c_str(), L"PRN") || !_wcsicmp(szNewName.c_str(), L"AUX") || !_wcsicmp(szNewName.c_str(), L"NUL") || !_wcsicmp(szNewName.c_str(), L"COM1") || !_wcsicmp(szNewName.c_str(), L"COM2") || !_wcsicmp(szNewName.c_str(), L"COM3") || !_wcsicmp(szNewName.c_str(), L"COM4") || !_wcsicmp(szNewName.c_str(), L"COM5") || !_wcsicmp(szNewName.c_str(), L"COM6") || !_wcsicmp(szNewName.c_str(), L"COM7") || !_wcsicmp(szNewName.c_str(), L"COM8") || !_wcsicmp(szNewName.c_str(), L"COM9") || !_wcsicmp(szNewName.c_str(), L"LPT1") || !_wcsicmp(szNewName.c_str(), L"LPT2") || !_wcsicmp(szNewName.c_str(), L"LPT3") || !_wcsicmp(szNewName.c_str(), L"LPT4") || !_wcsicmp(szNewName.c_str(), L"LPT5") || !_wcsicmp(szNewName.c_str(), L"LPT6") || !_wcsicmp(szNewName.c_str(), L"LPT7") || !_wcsicmp(szNewName.c_str(), L"LPT8") || !_wcsicmp(szNewName.c_str(), L"LPT9")) { szNewName += L"-File"; } ChangePathExtension(szNewName, szExt); return szNewName; }
void HttpResponse::SetStaticFileName(string path) { m_path = path; GetPathExtension(path.c_str()); SetContentTypeFromExtension(); }