merging develepment branch. don't kill me!
parent
9cdb91903c
commit
e2ea43ca93
|
@ -6,6 +6,8 @@ publish/
|
|||
Release/
|
||||
Debug/
|
||||
x64/
|
||||
installer/32bit
|
||||
installer/64bit
|
||||
|
||||
*.aps
|
||||
*.suo
|
||||
|
|
|
@ -19,6 +19,10 @@
|
|||
|
||||
#include "DShowPlugin.h"
|
||||
|
||||
//todo: 1700 line file. this is another one of those abominations.
|
||||
//fix it jim
|
||||
|
||||
|
||||
extern "C" __declspec(dllexport) bool LoadPlugin();
|
||||
extern "C" __declspec(dllexport) void UnloadPlugin();
|
||||
extern "C" __declspec(dllexport) CTSTR GetPluginName();
|
||||
|
@ -100,8 +104,58 @@ bool CurrentDeviceExists(CTSTR lpDevice, bool bGlobal, bool &isGlobal)
|
|||
return false;
|
||||
}
|
||||
|
||||
IBaseFilter* GetExceptionDevice(CTSTR lpGUID)
|
||||
{
|
||||
String strGUID = lpGUID;
|
||||
if(strGUID.Length() != 38)
|
||||
return NULL;
|
||||
|
||||
strGUID = strGUID.Mid(1, strGUID.Length()-1);
|
||||
|
||||
StringList GUIDData;
|
||||
strGUID.GetTokenList(GUIDData, '-', FALSE);
|
||||
|
||||
if (GUIDData.Num() != 5)
|
||||
return NULL;
|
||||
|
||||
if (GUIDData[0].Length() != 8 ||
|
||||
GUIDData[1].Length() != 4 ||
|
||||
GUIDData[2].Length() != 4 ||
|
||||
GUIDData[3].Length() != 4 ||
|
||||
GUIDData[4].Length() != 12 )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GUID targetGUID;
|
||||
targetGUID.Data1 = (UINT)tstring_base_to_uint(GUIDData[0], NULL, 16);
|
||||
targetGUID.Data2 = (WORD)tstring_base_to_uint(GUIDData[1], NULL, 16);
|
||||
targetGUID.Data3 = (WORD)tstring_base_to_uint(GUIDData[2], NULL, 16);
|
||||
targetGUID.Data4[0] = (BYTE)tstring_base_to_uint(GUIDData[3].Left(2), NULL, 16);
|
||||
targetGUID.Data4[1] = (BYTE)tstring_base_to_uint(GUIDData[3].Right(2), NULL, 16);
|
||||
targetGUID.Data4[2] = (BYTE)tstring_base_to_uint(GUIDData[4].Left(2), NULL, 16);
|
||||
targetGUID.Data4[3] = (BYTE)tstring_base_to_uint(GUIDData[4].Mid(2, 4), NULL, 16);
|
||||
targetGUID.Data4[4] = (BYTE)tstring_base_to_uint(GUIDData[4].Mid(4, 6), NULL, 16);
|
||||
targetGUID.Data4[5] = (BYTE)tstring_base_to_uint(GUIDData[4].Mid(6, 8), NULL, 16);
|
||||
targetGUID.Data4[6] = (BYTE)tstring_base_to_uint(GUIDData[4].Mid(8, 10), NULL, 16);
|
||||
targetGUID.Data4[7] = (BYTE)tstring_base_to_uint(GUIDData[4].Right(2), NULL, 16);
|
||||
|
||||
IBaseFilter *filter;
|
||||
if(SUCCEEDED(CoCreateInstance(targetGUID, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, (void**)&filter)))
|
||||
return filter;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IBaseFilter* GetDeviceByValue(WSTR lpType, CTSTR lpName, WSTR lpType2, CTSTR lpName2)
|
||||
{
|
||||
//---------------------------------
|
||||
// exception devices
|
||||
if(scmpi(lpType2, L"DevicePath") == 0 && lpName2 && *lpName2 == '{')
|
||||
return GetExceptionDevice(lpName2);
|
||||
|
||||
//---------------------------------
|
||||
|
||||
ICreateDevEnum *deviceEnum;
|
||||
IEnumMoniker *videoDeviceEnum;
|
||||
|
||||
|
@ -262,13 +316,73 @@ IPin* GetOutputPin(IBaseFilter *filter)
|
|||
return foundPin;
|
||||
}
|
||||
|
||||
void AddOutput(AM_MEDIA_TYPE *pMT, BYTE *capsData, List<MediaOutputInfo> &outputInfoList)
|
||||
{
|
||||
VideoOutputType type = GetVideoOutputType(*pMT);
|
||||
|
||||
if(pMT->formattype == FORMAT_VideoInfo || pMT->formattype == FORMAT_VideoInfo2)
|
||||
{
|
||||
VIDEO_STREAM_CONFIG_CAPS *pVSCC = reinterpret_cast<VIDEO_STREAM_CONFIG_CAPS*>(capsData);
|
||||
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pMT->pbFormat);
|
||||
BITMAPINFOHEADER *bmiHeader = GetVideoBMIHeader(pMT);
|
||||
|
||||
bool bUsingFourCC = false;
|
||||
if(type == VideoOutputType_None)
|
||||
{
|
||||
type = GetVideoOutputTypeFromFourCC(bmiHeader->biCompression);
|
||||
bUsingFourCC = true;
|
||||
}
|
||||
|
||||
if(type != VideoOutputType_None)
|
||||
{
|
||||
MediaOutputInfo *outputInfo = outputInfoList.CreateNew();
|
||||
|
||||
if(pVSCC)
|
||||
{
|
||||
outputInfo->minFrameInterval = pVSCC->MinFrameInterval;
|
||||
outputInfo->maxFrameInterval = pVSCC->MaxFrameInterval;
|
||||
outputInfo->minCX = pVSCC->MinOutputSize.cx;
|
||||
outputInfo->maxCX = pVSCC->MaxOutputSize.cx;
|
||||
outputInfo->minCY = pVSCC->MinOutputSize.cy;
|
||||
outputInfo->maxCY = pVSCC->MaxOutputSize.cy;
|
||||
|
||||
//actually due to the other code in GetResolutionFPSInfo, we can have this granularity
|
||||
// back to the way it was. now, even if it's corrupted, it will always work
|
||||
outputInfo->xGranularity = max(pVSCC->OutputGranularityX, 1);
|
||||
outputInfo->yGranularity = max(pVSCC->OutputGranularityY, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
outputInfo->minCX = outputInfo->maxCX = bmiHeader->biWidth;
|
||||
outputInfo->minCY = outputInfo->maxCY = bmiHeader->biHeight;
|
||||
if(pVih->AvgTimePerFrame != 0)
|
||||
outputInfo->minFrameInterval = outputInfo->maxFrameInterval = pVih->AvgTimePerFrame;
|
||||
else
|
||||
outputInfo->minFrameInterval = outputInfo->maxFrameInterval = 10000000/30; //elgato hack
|
||||
|
||||
outputInfo->xGranularity = outputInfo->yGranularity = 1;
|
||||
}
|
||||
|
||||
outputInfo->mediaType = pMT;
|
||||
outputInfo->videoType = type;
|
||||
outputInfo->bUsingFourCC = bUsingFourCC;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeleteMediaType(pMT);
|
||||
}
|
||||
|
||||
void GetOutputList(IPin *curPin, List<MediaOutputInfo> &outputInfoList)
|
||||
{
|
||||
HRESULT hRes;
|
||||
|
||||
IAMStreamConfig *config;
|
||||
if(SUCCEEDED(curPin->QueryInterface(IID_IAMStreamConfig, (void**)&config)))
|
||||
{
|
||||
int count, size;
|
||||
if(SUCCEEDED(config->GetNumberOfCapabilities(&count, &size)))
|
||||
if(SUCCEEDED(hRes = config->GetNumberOfCapabilities(&count, &size)))
|
||||
{
|
||||
BYTE *capsData = (BYTE*)Allocate(size);
|
||||
|
||||
|
@ -277,63 +391,25 @@ void GetOutputList(IPin *curPin, List<MediaOutputInfo> &outputInfoList)
|
|||
{
|
||||
AM_MEDIA_TYPE *pMT;
|
||||
if(SUCCEEDED(config->GetStreamCaps(i, &pMT, capsData)))
|
||||
{
|
||||
VideoOutputType type = GetVideoOutputType(*pMT);
|
||||
|
||||
if(pMT->formattype == FORMAT_VideoInfo)
|
||||
{
|
||||
VIDEO_STREAM_CONFIG_CAPS *pVSCC = reinterpret_cast<VIDEO_STREAM_CONFIG_CAPS*>(capsData);
|
||||
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(pMT->pbFormat);
|
||||
|
||||
bool bUsingFourCC = false;
|
||||
if(type == VideoOutputType_None)
|
||||
{
|
||||
type = GetVideoOutputTypeFromFourCC(pVih->bmiHeader.biCompression);
|
||||
bUsingFourCC = true;
|
||||
}
|
||||
|
||||
if(type != VideoOutputType_None)
|
||||
{
|
||||
MediaOutputInfo *outputInfo = outputInfoList.CreateNew();
|
||||
outputInfo->mediaType = pMT;
|
||||
outputInfo->videoType = type;
|
||||
outputInfo->minFrameInterval = pVSCC->MinFrameInterval;
|
||||
outputInfo->maxFrameInterval = pVSCC->MaxFrameInterval;
|
||||
outputInfo->minCX = pVSCC->MinOutputSize.cx;
|
||||
outputInfo->maxCX = pVSCC->MaxOutputSize.cx;
|
||||
outputInfo->minCY = pVSCC->MinOutputSize.cy;
|
||||
outputInfo->maxCY = pVSCC->MaxOutputSize.cy;
|
||||
outputInfo->bUsingFourCC = bUsingFourCC;
|
||||
|
||||
//actually due to the other code in GetResolutionFPSInfo, we can have this granularity
|
||||
// back to the way it was. now, even if it's corrupted, it will always work
|
||||
outputInfo->xGranularity = max(pVSCC->OutputGranularityX, 1);
|
||||
outputInfo->yGranularity = max(pVSCC->OutputGranularityY, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeMediaType(*pMT);
|
||||
CoTaskMemFree(pMT);
|
||||
}
|
||||
}
|
||||
else if(pMT->formattype == FORMAT_WaveFormatEx)
|
||||
{
|
||||
AUDIO_STREAM_CONFIG_CAPS *pASCC = reinterpret_cast<AUDIO_STREAM_CONFIG_CAPS*>(capsData);
|
||||
WAVEFORMATEX *pWfx = reinterpret_cast<WAVEFORMATEX*>(pMT->pbFormat);
|
||||
|
||||
FreeMediaType(*pMT);
|
||||
CoTaskMemFree(pMT);
|
||||
}
|
||||
else
|
||||
{
|
||||
FreeMediaType(*pMT);
|
||||
CoTaskMemFree(pMT);
|
||||
}
|
||||
}
|
||||
AddOutput(pMT, capsData, outputInfoList);
|
||||
}
|
||||
|
||||
Free(capsData);
|
||||
}
|
||||
else if(hRes == E_NOTIMPL) //...usually elgato.
|
||||
{
|
||||
IEnumMediaTypes *mediaTypes;
|
||||
if(SUCCEEDED(curPin->EnumMediaTypes(&mediaTypes)))
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
AM_MEDIA_TYPE *pMT;
|
||||
if(mediaTypes->Next(1, &pMT, &i) == S_OK)
|
||||
AddOutput(pMT, NULL, outputInfoList);
|
||||
|
||||
mediaTypes->Release();
|
||||
}
|
||||
}
|
||||
|
||||
SafeRelease(config);
|
||||
}
|
||||
|
@ -521,11 +597,34 @@ struct ConfigDialogData
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
#define DEV_EXCEPTION_COUNT 1
|
||||
CTSTR lpExceptionNames[DEV_EXCEPTION_COUNT] = {TEXT("Elgato Game Capture HD")};
|
||||
CTSTR lpExceptionGUIDs[DEV_EXCEPTION_COUNT] = {TEXT("{39F50F4C-99E1-464a-B6F9-D605B4FB5918}")};
|
||||
|
||||
void FillOutListOfVideoDevices(HWND hwndCombo, ConfigDialogData &info)
|
||||
{
|
||||
info.deviceIDList.Clear();
|
||||
SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
for(int i=0; i<DEV_EXCEPTION_COUNT; i++)
|
||||
{
|
||||
IBaseFilter *exceptionFilter = GetExceptionDevice(lpExceptionGUIDs[i]);
|
||||
if(exceptionFilter)
|
||||
{
|
||||
info.deviceNameList << lpExceptionNames[i];
|
||||
info.deviceIDList << lpExceptionGUIDs[i];
|
||||
|
||||
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)lpExceptionNames[i]);
|
||||
|
||||
exceptionFilter->Release();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
ICreateDevEnum *deviceEnum;
|
||||
IEnumMoniker *videoDeviceEnum;
|
||||
|
||||
|
@ -550,6 +649,8 @@ void FillOutListOfVideoDevices(HWND hwndCombo, ConfigDialogData &info)
|
|||
if(err == S_FALSE) //no devices
|
||||
return;
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
IMoniker *deviceInfo;
|
||||
DWORD count;
|
||||
|
||||
|
@ -752,6 +853,13 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
|
|||
|
||||
//------------------------------------------
|
||||
|
||||
HWND hwndNoBuffering = GetDlgItem(hwnd, IDC_NOBUFFERING);
|
||||
|
||||
bool bNoBuffering = configData->data->GetInt(TEXT("noBuffering")) != 0;
|
||||
SendMessage(hwndNoBuffering, BM_SETCHECK, bNoBuffering ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
UINT opacity = configData->data->GetInt(TEXT("opacity"), 100);
|
||||
|
||||
SendMessage(GetDlgItem(hwnd, IDC_OPACITY), UDM_SETRANGE32, 0, 100);
|
||||
|
@ -826,7 +934,7 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
|
|||
|
||||
int pos = configData->data->GetInt(TEXT("soundTimeOffset"));
|
||||
|
||||
SendMessage(GetDlgItem(hwnd, IDC_TIMEOFFSET), UDM_SETRANGE32, -500, 3000);
|
||||
SendMessage(GetDlgItem(hwnd, IDC_TIMEOFFSET), UDM_SETRANGE32, -50, 3000);
|
||||
SendMessage(GetDlgItem(hwnd, IDC_TIMEOFFSET), UDM_SETPOS32, 0, pos);
|
||||
|
||||
//------------------------------------------
|
||||
|
@ -1441,6 +1549,11 @@ INT_PTR CALLBACK ConfigureDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPA
|
|||
|
||||
//------------------------------------------
|
||||
|
||||
BOOL bNoBuffering = SendMessage(GetDlgItem(hwnd, IDC_NOBUFFERING), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
configData->data->SetInt(TEXT("noBuffering"), bNoBuffering);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
BOOL bUseChromaKey = SendMessage(GetDlgItem(hwnd, IDC_USECHROMAKEY), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
DWORD color = CCGetColor(GetDlgItem(hwnd, IDC_COLOR));
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <dshow.h>
|
||||
#include <Amaudio.h>
|
||||
#include <Dvdmedia.h>
|
||||
|
||||
#include "MediaInfoStuff.h"
|
||||
#include "CaptureFilter.h"
|
||||
|
|
|
@ -52,7 +52,7 @@ END
|
|||
// Dialog
|
||||
//
|
||||
|
||||
IDD_CONFIG DIALOGEX 0, 0, 451, 267
|
||||
IDD_CONFIG DIALOGEX 0, 0, 451, 289
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "DeviceSelection"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
|
@ -67,40 +67,41 @@ BEGIN
|
|||
RTEXT "DeviceSelection.Opacity",IDC_STATIC,4,52,117,8
|
||||
EDITTEXT IDC_OPACITY_EDIT,124,49,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_OPACITY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,164,49,10,14
|
||||
GROUPBOX "DeviceSelection.Resolution",IDC_STATIC,7,68,252,85
|
||||
GROUPBOX "DeviceSelection.Resolution",IDC_STATIC,7,90,252,85
|
||||
CONTROL "DeviceSelection.CustomResolution",IDC_CUSTOMRESOLUTION,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,80,130,10,WS_EX_RIGHT
|
||||
RTEXT "DeviceSelection.Resolution",IDC_STATIC,18,98,117,8
|
||||
COMBOBOX IDC_RESOLUTION,138,95,113,72,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT "DeviceSelection.FPS",IDC_STATIC,18,115,117,8
|
||||
COMBOBOX IDC_FPS,138,113,67,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,102,130,10,WS_EX_RIGHT
|
||||
RTEXT "DeviceSelection.Resolution",IDC_STATIC,18,120,117,8
|
||||
COMBOBOX IDC_RESOLUTION,138,117,113,72,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT "DeviceSelection.FPS",IDC_STATIC,18,137,117,8
|
||||
COMBOBOX IDC_FPS,138,135,67,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "DeviceSelection.PreferredType",IDC_USEPREFERREDOUTPUT,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,134,117,10,WS_EX_RIGHT
|
||||
COMBOBOX IDC_PREFERREDOUTPUT,138,132,67,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "DeviceSelection.Sound",IDC_STATIC,264,68,180,85,WS_GROUP
|
||||
CONTROL "DeviceSelection.NoSound",IDC_NOSOUND,"Button",BS_AUTORADIOBUTTON,271,82,163,10
|
||||
CONTROL "DeviceSelection.OutputSound",IDC_OUTPUTSOUND,"Button",BS_AUTORADIOBUTTON,271,94,163,10
|
||||
LTEXT "DeviceSelection.SoundOffset",IDC_STATIC,268,110,117,8,NOT WS_GROUP,WS_EX_RIGHT
|
||||
EDITTEXT IDC_TIMEOFFSET_EDIT,389,108,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_TIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,429,109,10,14
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,156,117,10,WS_EX_RIGHT
|
||||
COMBOBOX IDC_PREFERREDOUTPUT,138,154,67,30,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "DeviceSelection.Sound",IDC_STATIC,264,90,180,85,WS_GROUP
|
||||
CONTROL "DeviceSelection.NoSound",IDC_NOSOUND,"Button",BS_AUTORADIOBUTTON,271,104,163,10
|
||||
CONTROL "DeviceSelection.OutputSound",IDC_OUTPUTSOUND,"Button",BS_AUTORADIOBUTTON,271,116,163,10
|
||||
LTEXT "DeviceSelection.SoundOffset",IDC_STATIC,268,132,117,8,NOT WS_GROUP,WS_EX_RIGHT
|
||||
EDITTEXT IDC_TIMEOFFSET_EDIT,389,130,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_TIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,429,131,10,14
|
||||
CONTROL "DeviceSelection.PlayToDesktop",IDC_PLAYDESKTOPSOUND,
|
||||
"Button",BS_AUTORADIOBUTTON,271,124,163,10
|
||||
GROUPBOX "DeviceSelection.ChromaKey",IDC_STATIC,7,157,222,103
|
||||
CONTROL "DeviceSelection.UseChromaKey",IDC_USECHROMAKEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,170,130,10,WS_EX_RIGHT
|
||||
RTEXT "DeviceSelection.Color",IDC_STATIC,19,189,117,8
|
||||
CONTROL "",IDC_COLOR,"OBSColorControl",WS_TABSTOP,139,186,28,14
|
||||
PUSHBUTTON "DeviceSelection.Select",IDC_SELECTCOLOR,171,186,50,14
|
||||
RTEXT "DeviceSelection.Similarity",IDC_STATIC,19,207,117,8
|
||||
EDITTEXT IDC_BASETHRESHOLD_EDIT,137,205,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_BASETHRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,178,205,10,14
|
||||
RTEXT "DeviceSelection.Blend",IDC_STATIC,17,223,117,8
|
||||
EDITTEXT IDC_BLEND_EDIT,137,222,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_BLEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,177,222,11,14
|
||||
RTEXT "DeviceSelection.SpillReduction",IDC_STATIC,17,239,117,8
|
||||
EDITTEXT IDC_SPILLREDUCTION_EDIT,137,238,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_SPILLREDUCTION,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,177,238,11,14
|
||||
DEFPUSHBUTTON "OK",IDOK,336,246,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,394,246,50,14
|
||||
"Button",BS_AUTORADIOBUTTON,271,146,163,10
|
||||
GROUPBOX "DeviceSelection.ChromaKey",IDC_STATIC,7,179,222,103
|
||||
CONTROL "DeviceSelection.UseChromaKey",IDC_USECHROMAKEY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,192,130,10,WS_EX_RIGHT
|
||||
RTEXT "DeviceSelection.Color",IDC_STATIC,19,211,117,8
|
||||
CONTROL "",IDC_COLOR,"OBSColorControl",WS_TABSTOP,139,208,28,14
|
||||
PUSHBUTTON "DeviceSelection.Select",IDC_SELECTCOLOR,171,208,50,14
|
||||
RTEXT "DeviceSelection.Similarity",IDC_STATIC,19,229,117,8
|
||||
EDITTEXT IDC_BASETHRESHOLD_EDIT,137,227,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_BASETHRESHOLD,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,178,227,10,14
|
||||
RTEXT "DeviceSelection.Blend",IDC_STATIC,17,245,117,8
|
||||
EDITTEXT IDC_BLEND_EDIT,137,244,40,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_BLEND,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,177,244,11,14
|
||||
RTEXT "DeviceSelection.SpillReduction",IDC_STATIC,17,261,117,8
|
||||
EDITTEXT IDC_SPILLREDUCTION_EDIT,137,260,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_SPILLREDUCTION,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,177,260,11,14
|
||||
DEFPUSHBUTTON "OK",IDOK,336,268,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,394,268,50,14
|
||||
CONTROL ".No Buffering (test)",IDC_NOBUFFERING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,72,126,10,WS_EX_RIGHT
|
||||
END
|
||||
|
||||
|
||||
|
@ -117,7 +118,7 @@ BEGIN
|
|||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 444
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 260
|
||||
BOTTOMMARGIN, 282
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
|
|
@ -35,7 +35,7 @@ bool DeviceAudioSource::GetNextBuffer(void **buffer, UINT *numFrames, QWORD *tim
|
|||
|
||||
*buffer = outputBuffer.Array();
|
||||
*numFrames = sampleFrameCount;
|
||||
*timestamp = API->GetAudioTime()+timeOffset;
|
||||
*timestamp = API->GetAudioTime()+GetTimeOffset();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -64,6 +64,15 @@ bool DeviceAudioSource::Initialize(DeviceSource *parent)
|
|||
|
||||
//---------------------------------
|
||||
|
||||
bool bFloat = false;
|
||||
UINT inputChannels;
|
||||
UINT inputSamplesPerSec;
|
||||
UINT inputBitsPerSample;
|
||||
UINT inputBlockSize;
|
||||
DWORD inputChannelMask;
|
||||
|
||||
//---------------------------------
|
||||
|
||||
if(device->audioFormat.wFormatTag == WAVE_FORMAT_EXTENSIBLE)
|
||||
{
|
||||
WAVEFORMATEXTENSIBLE *wfext = (WAVEFORMATEXTENSIBLE*)&device->audioFormat;
|
||||
|
@ -84,7 +93,7 @@ bool DeviceAudioSource::Initialize(DeviceSource *parent)
|
|||
|
||||
outputBuffer.SetSize(sampleSegmentSize);
|
||||
|
||||
InitAudioData();
|
||||
InitAudioData(bFloat, inputChannels, inputSamplesPerSec, inputBitsPerSample, inputBlockSize, inputChannelMask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,38 @@ const float yuvMat[16] = { 0.257f, 0.504f, 0.098f, 0.0625f,
|
|||
0.439f, -0.368f, -0.071f, 0.50f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
void DeviceSource::SetAudioInfo(AM_MEDIA_TYPE *audioMediaType, GUID &expectedAudioType)
|
||||
{
|
||||
expectedAudioType = audioMediaType->subtype;
|
||||
|
||||
if(audioMediaType->formattype == FORMAT_WaveFormatEx)
|
||||
{
|
||||
WAVEFORMATEX *pFormat = reinterpret_cast<WAVEFORMATEX*>(audioMediaType->pbFormat);
|
||||
mcpy(&audioFormat, pFormat, sizeof(audioFormat));
|
||||
|
||||
Log(TEXT(" device audio info - bits per sample: %u, channels: %u, samples per sec: %u, block size: %u"),
|
||||
audioFormat.wBitsPerSample, audioFormat.nChannels, audioFormat.nSamplesPerSec, audioFormat.nBlockAlign);
|
||||
|
||||
//avoid local resampling if possible
|
||||
/*if(pFormat->nSamplesPerSec != 44100)
|
||||
{
|
||||
pFormat->nSamplesPerSec = 44100;
|
||||
if(SUCCEEDED(audioConfig->SetFormat(audioMediaType)))
|
||||
{
|
||||
Log(TEXT(" also successfully set samples per sec to 44.1k"));
|
||||
audioFormat.nSamplesPerSec = 44100;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
else
|
||||
{
|
||||
AppWarning(TEXT("DShowPlugin: Audio format was not a normal wave format"));
|
||||
soundOutputType = 0;
|
||||
}
|
||||
|
||||
DeleteMediaType(audioMediaType);
|
||||
}
|
||||
|
||||
bool DeviceSource::LoadFilters()
|
||||
{
|
||||
if(bCapturing || bFiltersLoaded)
|
||||
|
@ -140,6 +172,8 @@ bool DeviceSource::LoadFilters()
|
|||
|
||||
bUseThreadedConversion = API->UseMultithreadedOptimizations() && (OSGetTotalCores() > 1);
|
||||
|
||||
bool bNoBuffering = data->GetInt(TEXT("noBuffering")) != 0;
|
||||
|
||||
//------------------------------------------------
|
||||
// basic initialization vars
|
||||
|
||||
|
@ -290,8 +324,6 @@ bool DeviceSource::LoadFilters()
|
|||
// log video info
|
||||
|
||||
{
|
||||
VIDEOINFOHEADER *pVih = reinterpret_cast<VIDEOINFOHEADER*>(bestOutput->mediaType->pbFormat);
|
||||
|
||||
String strTest = FormattedString(TEXT(" device: %s,\r\n device id %s,\r\n chosen type: %s, usingFourCC: %s, res: %ux%u - %ux%u, fps: %g-%g"),
|
||||
strDevice.Array(), strDeviceID.Array(),
|
||||
EnumToName[(int)bestOutput->videoType],
|
||||
|
@ -299,14 +331,16 @@ bool DeviceSource::LoadFilters()
|
|||
bestOutput->minCX, bestOutput->minCY, bestOutput->maxCX, bestOutput->maxCY,
|
||||
10000000.0/double(bestOutput->maxFrameInterval), 10000000.0/double(bestOutput->minFrameInterval));
|
||||
|
||||
BITMAPINFOHEADER *bmiHeader = GetVideoBMIHeader(bestOutput->mediaType);
|
||||
|
||||
char fourcc[5];
|
||||
mcpy(fourcc, &pVih->bmiHeader.biCompression, 4);
|
||||
mcpy(fourcc, &bmiHeader->biCompression, 4);
|
||||
fourcc[4] = 0;
|
||||
|
||||
if(pVih->bmiHeader.biCompression > 1000)
|
||||
if(bmiHeader->biCompression > 1000)
|
||||
strTest << FormattedString(TEXT(", fourCC: '%S'\r\n"), fourcc);
|
||||
else
|
||||
strTest << FormattedString(TEXT(", fourCC: %08lX\r\n"), pVih->bmiHeader.biCompression);
|
||||
strTest << FormattedString(TEXT(", fourCC: %08lX\r\n"), bmiHeader->biCompression);
|
||||
|
||||
Log(TEXT("------------------------------------------"));
|
||||
Log(strTest.Array());
|
||||
|
@ -371,16 +405,20 @@ bool DeviceSource::LoadFilters()
|
|||
AM_MEDIA_TYPE outputMediaType;
|
||||
CopyMediaType(&outputMediaType, bestOutput->mediaType);
|
||||
|
||||
VIDEOINFOHEADER *vih = reinterpret_cast<VIDEOINFOHEADER*>(outputMediaType.pbFormat);
|
||||
vih->AvgTimePerFrame = frameInterval;
|
||||
vih->bmiHeader.biWidth = renderCX;
|
||||
vih->bmiHeader.biHeight = renderCY;
|
||||
vih->bmiHeader.biSizeImage = renderCX*renderCY*(vih->bmiHeader.biBitCount>>3);
|
||||
VIDEOINFOHEADER *vih = reinterpret_cast<VIDEOINFOHEADER*>(outputMediaType.pbFormat);
|
||||
BITMAPINFOHEADER *bmi = GetVideoBMIHeader(&outputMediaType);
|
||||
vih->AvgTimePerFrame = frameInterval;
|
||||
bmi->biWidth = renderCX;
|
||||
bmi->biHeight = renderCY;
|
||||
bmi->biSizeImage = renderCX*renderCY*(bmi->biBitCount>>3);
|
||||
|
||||
if(FAILED(err = config->SetFormat(&outputMediaType)))
|
||||
{
|
||||
AppWarning(TEXT("DShowPlugin: SetFormat on device pin failed, result = %08lX"), err);
|
||||
goto cleanFinish;
|
||||
if(err != E_NOTIMPL)
|
||||
{
|
||||
AppWarning(TEXT("DShowPlugin: SetFormat on device pin failed, result = %08lX"), err);
|
||||
goto cleanFinish;
|
||||
}
|
||||
}
|
||||
|
||||
FreeMediaType(outputMediaType);
|
||||
|
@ -396,40 +434,35 @@ bool DeviceSource::LoadFilters()
|
|||
if(SUCCEEDED(audioPin->QueryInterface(IID_IAMStreamConfig, (void**)&audioConfig)))
|
||||
{
|
||||
AM_MEDIA_TYPE *audioMediaType;
|
||||
if(SUCCEEDED(audioConfig->GetFormat(&audioMediaType)))
|
||||
if(SUCCEEDED(err = audioConfig->GetFormat(&audioMediaType)))
|
||||
{
|
||||
expectedAudioType = audioMediaType->subtype;
|
||||
|
||||
if(audioMediaType->formattype == FORMAT_WaveFormatEx)
|
||||
SetAudioInfo(audioMediaType, expectedAudioType);
|
||||
}
|
||||
else if(err == E_NOTIMPL) //elgato probably
|
||||
{
|
||||
IEnumMediaTypes *audioMediaTypes;
|
||||
if(SUCCEEDED(err = audioPin->EnumMediaTypes(&audioMediaTypes)))
|
||||
{
|
||||
WAVEFORMATEX *pFormat = reinterpret_cast<WAVEFORMATEX*>(audioMediaType->pbFormat);
|
||||
mcpy(&audioFormat, pFormat, sizeof(audioFormat));
|
||||
|
||||
Log(TEXT(" device audio info - bits per sample: %u, channels: %u, samples per sec: %u"),
|
||||
audioFormat.wBitsPerSample, audioFormat.nChannels, audioFormat.nSamplesPerSec);
|
||||
|
||||
//avoid local resampling if possible
|
||||
/*if(pFormat->nSamplesPerSec != 44100)
|
||||
ULONG i = 0;
|
||||
if((err = audioMediaTypes->Next(1, &audioMediaType, &i)) == S_OK)
|
||||
SetAudioInfo(audioMediaType, expectedAudioType);
|
||||
else
|
||||
{
|
||||
pFormat->nSamplesPerSec = 44100;
|
||||
if(SUCCEEDED(audioConfig->SetFormat(audioMediaType)))
|
||||
{
|
||||
Log(TEXT(" also successfully set samples per sec to 44.1k"));
|
||||
audioFormat.nSamplesPerSec = 44100;
|
||||
}
|
||||
}*/
|
||||
AppWarning(TEXT("DShowPlugin: audioMediaTypes->Next failed, result = %08lX"), err);
|
||||
soundOutputType = 0;
|
||||
}
|
||||
|
||||
audioMediaTypes->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
AppWarning(TEXT("DShowPlugin: Audio format was not a normal wave format"));
|
||||
AppWarning(TEXT("DShowPlugin: audioMediaTypes->Next failed, result = %08lX"), err);
|
||||
soundOutputType = 0;
|
||||
}
|
||||
|
||||
DeleteMediaType(audioMediaType);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppWarning(TEXT("DShowPlugin: Could not get audio format"));
|
||||
AppWarning(TEXT("DShowPlugin: Could not get audio format, result = %08lX"), err);
|
||||
soundOutputType = 0;
|
||||
}
|
||||
|
||||
|
@ -498,14 +531,18 @@ bool DeviceSource::LoadFilters()
|
|||
//------------------------------------------------
|
||||
// connect all pins and set up the whole capture thing
|
||||
|
||||
/*IMediaFilter *mediaFilter;
|
||||
if(SUCCEEDED(graph->QueryInterface(IID_IMediaFilter, (void**)&mediaFilter)))
|
||||
if(bNoBuffering)
|
||||
{
|
||||
if(FAILED(mediaFilter->SetSyncSource(NULL)))
|
||||
AppWarning(TEXT("DShowPlugin: Failed to set sync source, result = %08lX"), err);
|
||||
IMediaFilter *mediaFilter;
|
||||
if(SUCCEEDED(graph->QueryInterface(IID_IMediaFilter, (void**)&mediaFilter)))
|
||||
{
|
||||
if(FAILED(mediaFilter->SetSyncSource(NULL)))
|
||||
AppWarning(TEXT("DShowPlugin: Failed to set sync source, result = %08lX"), err);
|
||||
|
||||
mediaFilter->Release();
|
||||
}*/
|
||||
Log(TEXT("Disabling buffering (hopefully)"));
|
||||
mediaFilter->Release();
|
||||
}
|
||||
}
|
||||
|
||||
//THANK THE NINE DIVINES I FINALLY GOT IT WORKING
|
||||
bool bConnected = SUCCEEDED(err = capture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, deviceFilter, NULL, captureFilter));
|
||||
|
|
|
@ -147,6 +147,8 @@ class DeviceSource : public ImageSource
|
|||
OSLeaveMutex(hSampleMutex);
|
||||
}
|
||||
|
||||
void SetAudioInfo(AM_MEDIA_TYPE *audioMediaType, GUID &expectedAudioType);
|
||||
|
||||
void ReceiveVideo(IMediaSample *sample);
|
||||
void ReceiveAudio(IMediaSample *sample);
|
||||
|
||||
|
|
|
@ -108,6 +108,13 @@ struct MediaOutputInfo
|
|||
}
|
||||
};
|
||||
|
||||
inline BITMAPINFOHEADER* GetVideoBMIHeader(const AM_MEDIA_TYPE *pMT)
|
||||
{
|
||||
return (pMT->formattype == FORMAT_VideoInfo) ?
|
||||
&reinterpret_cast<VIDEOINFOHEADER*>(pMT->pbFormat)->bmiHeader :
|
||||
&reinterpret_cast<VIDEOINFOHEADER2*>(pMT->pbFormat)->bmiHeader;
|
||||
}
|
||||
|
||||
VideoOutputType GetVideoOutputTypeFromFourCC(DWORD fourCC);
|
||||
VideoOutputType GetVideoOutputType(const AM_MEDIA_TYPE &media_type);
|
||||
bool GetVideoOutputTypes(const List<MediaOutputInfo> &outputList, UINT width, UINT height, UINT64 frameInterval, List<VideoOutputType> &types);
|
||||
|
|
|
@ -41,6 +41,8 @@
|
|||
#define IDC_EDIT1 1032
|
||||
#define IDC_TIMEOFFSET_EDIT 1032
|
||||
#define IDC_TIMEOFFSET 1033
|
||||
#define IDC_CHECK1 1034
|
||||
#define IDC_NOBUFFERING 1034
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
@ -48,7 +50,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 107
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1034
|
||||
#define _APS_NEXT_CONTROL_VALUE 1035
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
10
OBS-All.sln
10
OBS-All.sln
|
@ -27,6 +27,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DShowPlugin", "DShowPlugin\
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsCapture", "GraphicsCapture\GraphicsCapture.vcproj", "{7BB0C67E-9CDD-4ABB-8728-41F2BE5C54D8}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GraphicsCaptureHook", "GraphicsCapture\GraphicsCaptureHook\GraphicsCaptureHook.vcproj", "{12111D5C-819C-4BAF-9783-E6AF8CBC2700}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
@ -91,6 +93,14 @@ Global
|
|||
{7BB0C67E-9CDD-4ABB-8728-41F2BE5C54D8}.Release|Win32.Build.0 = Release|Win32
|
||||
{7BB0C67E-9CDD-4ABB-8728-41F2BE5C54D8}.Release|x64.ActiveCfg = Release|x64
|
||||
{7BB0C67E-9CDD-4ABB-8728-41F2BE5C54D8}.Release|x64.Build.0 = Release|x64
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Debug|x64.Build.0 = Debug|x64
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Release|Win32.Build.0 = Release|Win32
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Release|x64.ActiveCfg = Release|x64
|
||||
{12111D5C-819C-4BAF-9783-E6AF8CBC2700}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
125
OBS.rc
125
OBS.rc
|
@ -13,11 +13,13 @@
|
|||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Japanese (Japan) resources
|
||||
// 日本語 resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
|
||||
#pragma code_page(932)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -71,9 +73,9 @@ BEGIN
|
|||
COMBOBOX IDC_MODE,144,10,126,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT "Settings.Publish.Service",IDC_SERVICE_STATIC,4,29,138,8
|
||||
COMBOBOX IDC_SERVICE,144,27,126,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT ".FMS URL:",IDC_URL_STATIC,4,46,138,8
|
||||
RTEXT "Settings.Publish.Server",IDC_SERVER_STATIC,4,46,138,8
|
||||
COMBOBOX IDC_SERVERLIST,144,43,226,59,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
RTEXT ".FMS URL:",IDC_URL_STATIC,4,46,138,8
|
||||
EDITTEXT IDC_URL,144,43,226,14,ES_AUTOHSCROLL
|
||||
RTEXT "Settings.Publish.Playpath",IDC_PLAYPATH_STATIC,4,62,138,8
|
||||
EDITTEXT IDC_PLAYPATH,144,60,226,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
|
@ -85,19 +87,21 @@ BEGIN
|
|||
LTEXT "Settings.Publish.Delay",IDC_DELAY_STATIC,4,111,138,8,0,WS_EX_RIGHT
|
||||
EDITTEXT IDC_DELAY_EDIT,143,108,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_DELAY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,185,108,11,14
|
||||
RTEXT "Settings.Publish.DashboardLink",IDC_DASHBOARDLINK_STATIC,4,127,138,8
|
||||
EDITTEXT IDC_DASHBOARDLINK,143,125,225,14,ES_AUTOHSCROLL
|
||||
CONTROL "Settings.Publish.SaveToFile",IDC_SAVETOFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,143,145,10,WS_EX_RIGHT
|
||||
RTEXT "Settings.Publish.SavePath",IDC_SAVEPATH_STATIC,7,160,133,8
|
||||
EDITTEXT IDC_SAVEPATH,143,157,148,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Browse",IDC_BROWSE,295,157,63,14
|
||||
RTEXT "Settings.Publish.StartStreamHotkey",IDC_STARTSTREAMHOTKEY_STATIC,7,178,133,8
|
||||
CONTROL "カスタム1",IDC_STARTSTREAMHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,144,175,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARHOTKEY_STARTSTREAM,225,175,66,14
|
||||
RTEXT "Settings.Publish.StopStreamHotkey",IDC_STOPSTREAMHOTKEY_STATIC,7,196,133,8
|
||||
CONTROL "カスタム1",IDC_STOPSTREAMHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,144,193,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARHOTKEY,225,193,66,14
|
||||
LTEXT "Settings.Info",IDC_INFO,7,217,408,37,NOT WS_VISIBLE
|
||||
CONTROL "Settings.Publish.LowLatencyMode",IDC_LOWLATENCYMODE,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,127,145,10,WS_EX_RIGHT
|
||||
RTEXT "Settings.Publish.DashboardLink",IDC_DASHBOARDLINK_STATIC,4,143,138,8
|
||||
EDITTEXT IDC_DASHBOARDLINK,143,141,225,14,ES_AUTOHSCROLL
|
||||
CONTROL "Settings.Publish.SaveToFile",IDC_SAVETOFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,160,145,10,WS_EX_RIGHT
|
||||
RTEXT "Settings.Publish.SavePath",IDC_SAVEPATH_STATIC,7,177,133,8
|
||||
EDITTEXT IDC_SAVEPATH,143,174,148,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Browse",IDC_BROWSE,295,174,63,14
|
||||
RTEXT "Settings.Publish.StartStreamHotkey",IDC_STARTSTREAMHOTKEY_STATIC,7,195,133,8
|
||||
CONTROL "カスタム1",IDC_STARTSTREAMHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,144,192,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARHOTKEY_STARTSTREAM,225,192,66,14
|
||||
RTEXT "Settings.Publish.StopStreamHotkey",IDC_STOPSTREAMHOTKEY_STATIC,7,213,133,8
|
||||
CONTROL "カスタム1",IDC_STOPSTREAMHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,144,210,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARHOTKEY,225,210,66,14
|
||||
LTEXT "Settings.Info",IDC_INFO,7,234,408,37,NOT WS_VISIBLE
|
||||
END
|
||||
|
||||
IDD_SETTINGS_ENCODING DIALOGEX 0, 0, 427, 336
|
||||
|
@ -162,28 +166,30 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU
|
|||
EXSTYLE WS_EX_CONTROLPARENT
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
RTEXT "Settings.Audio.Device",IDC_STATIC,4,12,138,8
|
||||
COMBOBOX IDC_MICDEVICES,144,10,226,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Settings.Audio.PushToTalkHotkey",IDC_PUSHTOTALK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,31,143,10,WS_EX_RIGHT
|
||||
CONTROL "カスタム1",IDC_PUSHTOTALKHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,160,29,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARPUSHTOTALK,241,29,73,14
|
||||
RTEXT "Settings.Audio.PushToTalkDelay",IDC_STATIC,4,50,138,8
|
||||
EDITTEXT IDC_PTTDELAY_EDIT,144,47,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_PTTDELAY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,184,47,10,14
|
||||
RTEXT "Settings.Audio.MuteMicHotkey",IDC_STATIC,4,68,138,8
|
||||
CONTROL "カスタム1",IDC_MUTEMICHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,160,66,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARMUTEMIC,241,66,73,14
|
||||
RTEXT "Settings.Audio.MuteDesktopHotkey",IDC_STATIC,4,86,138,8
|
||||
CONTROL "カスタム1",IDC_MUTEDESKTOPHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,160,84,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARMUTEDESKTOP,241,84,73,14
|
||||
CONTROL "Settings.Audio.ForceMicMono",IDC_FORCEMONO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,103,143,10,WS_EX_RIGHT
|
||||
RTEXT "Settings.Audio.MicBoost",IDC_STATIC,4,122,138,8
|
||||
EDITTEXT IDC_MICBOOST_EDIT,143,120,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_MICBOOST,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,183,120,10,14
|
||||
RTEXT "Settings.Audio.MicTimeOffset",IDC_STATIC,3,140,138,8
|
||||
EDITTEXT IDC_MICTIMEOFFSET_EDIT,143,138,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_MICTIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,183,138,11,14
|
||||
LTEXT "Settings.Info",IDC_INFO,4,165,408,37,NOT WS_VISIBLE
|
||||
RTEXT "Settings.Audio.Device",IDC_STATIC,5,29,138,8
|
||||
COMBOBOX IDC_MICDEVICES,145,27,226,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Settings.Audio.PushToTalkHotkey",IDC_PUSHTOTALK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,46,143,10,WS_EX_RIGHT
|
||||
CONTROL "カスタム1",IDC_PUSHTOTALKHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,161,44,80,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARPUSHTOTALK,242,44,73,14
|
||||
RTEXT "Settings.Audio.PushToTalkDelay",IDC_STATIC,5,65,138,8
|
||||
EDITTEXT IDC_PTTDELAY_EDIT,145,62,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_PTTDELAY,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,174,62,10,14
|
||||
RTEXT "Settings.Audio.MuteMicHotkey",IDC_STATIC,5,83,138,8
|
||||
CONTROL "カスタム1",IDC_MUTEMICHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,145,81,96,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARMUTEMIC,242,81,73,14
|
||||
RTEXT "Settings.Audio.MuteDesktopHotkey",IDC_STATIC,5,101,138,8
|
||||
CONTROL "カスタム1",IDC_MUTEDESKTOPHOTKEY,"OBSHotkeyControlEx",WS_TABSTOP,145,99,96,14
|
||||
PUSHBUTTON "ClearHotkey",IDC_CLEARMUTEDESKTOP,242,99,73,14
|
||||
CONTROL "Settings.Audio.ForceMicMono",IDC_FORCEMONO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,118,143,10,WS_EX_RIGHT
|
||||
RTEXT "Settings.Audio.MicBoost",IDC_STATIC,5,137,138,8
|
||||
EDITTEXT IDC_MICBOOST_EDIT,144,135,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_MICBOOST,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,173,135,10,14
|
||||
RTEXT "Settings.Audio.MicTimeOffset",IDC_STATIC,4,156,138,8
|
||||
EDITTEXT IDC_MICTIMEOFFSET_EDIT,144,153,40,14,ES_AUTOHSCROLL
|
||||
CONTROL "",IDC_MICTIMEOFFSET,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,173,153,11,14
|
||||
LTEXT "Settings.Info",IDC_INFO,5,180,408,37,NOT WS_VISIBLE
|
||||
RTEXT "Settings.Audio.PlaybackDevice",IDC_STATIC,5,12,138,8
|
||||
COMBOBOX IDC_PLAYBACKDEVICES,145,10,226,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
IDD_ENTERNAME DIALOGEX 0, 0, 265, 49
|
||||
|
@ -318,29 +324,26 @@ BEGIN
|
|||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,17,173,10
|
||||
RTEXT "Settings.Advanced.ProcessPriority",IDC_STATIC,7,31,136,8
|
||||
COMBOBOX IDC_PRIORITY,145,29,82,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Settings.Video",IDC_STATIC,4,48,418,123
|
||||
RTEXT "Settings.Advanced.VideoEncoderCPUTradeoff",IDC_STATIC,5,60,138,8
|
||||
COMBOBOX IDC_PRESET,145,58,82,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Settings.Advanced.UseCBR",IDC_USECBR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,79,292,10
|
||||
GROUPBOX "Settings.Video",IDC_STATIC,4,50,418,122
|
||||
RTEXT "Settings.Advanced.VideoEncoderCPUTradeoff",IDC_STATIC,5,62,138,8
|
||||
COMBOBOX IDC_PRESET,145,60,82,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Settings.Advanced.UseCFR",IDC_USECFR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,82,292,10
|
||||
CONTROL "Settings.Advanced.UseCBR",IDC_USECBR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,95,292,10
|
||||
CONTROL "Settings.Advanced.VideoEncoderSettings",IDC_USEVIDEOENCODERSETTINGS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,92,260,10
|
||||
EDITTEXT IDC_VIDEOENCODERSETTINGS,33,105,373,14,ES_AUTOHSCROLL
|
||||
CONTROL "Settings.Advanced.UseSyncFix",IDC_USESYNCFIX,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,20,125,243,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,108,260,10
|
||||
EDITTEXT IDC_VIDEOENCODERSETTINGS,33,121,373,14,ES_AUTOHSCROLL
|
||||
CONTROL "Settings.Advanced.UseSyncFix",IDC_USESYNCFIX,"Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,20,141,243,10
|
||||
CONTROL "Settings.Advanced.UnlockHigherFPS",IDC_UNLOCKHIGHFPS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,139,217,10
|
||||
GROUPBOX "Settings.Audio",IDC_STATIC,4,174,418,29
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,155,217,10
|
||||
GROUPBOX "Settings.Audio",IDC_STATIC,4,176,418,44
|
||||
CONTROL "Settings.Advanced.UseHighQualityResampling",IDC_USEHIGHQUALITYRESAMPLING,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,187,332,10
|
||||
GROUPBOX "Settings.Advanced.Network",IDC_STATIC,4,211,418,67
|
||||
CONTROL "Settings.Advanced.UseSendBuffer",IDC_USESENDBUFFER,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,226,277,10
|
||||
RTEXT "Settings.Advanced.SendBufferSize",IDC_STATIC,5,241,138,8
|
||||
COMBOBOX IDC_SENDBUFFERSIZE,145,239,158,30,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Settings.Info",IDC_INFO,7,281,418,37,NOT WS_VISIBLE
|
||||
RTEXT "Settings.Advanced.BindToIP",IDC_STATIC,5,258,138,8
|
||||
COMBOBOX IDC_BINDIP,145,256,87,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL ".Allow negative CTS (for testing purposes)",IDC_DISABLECTSADJUST,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,154,286,10
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,189,332,10
|
||||
CONTROL "Settings.Advanced.SyncToVideoTime",IDC_SYNCTOVIDEOTIME,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,20,203,332,10
|
||||
GROUPBOX "Settings.Advanced.Network",IDC_STATIC,4,224,418,32
|
||||
RTEXT "Settings.Advanced.BindToIP",IDC_STATIC,5,237,138,8
|
||||
COMBOBOX IDC_BINDIP,145,235,87,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Settings.Info",IDC_INFO,7,262,418,37,NOT WS_VISIBLE
|
||||
END
|
||||
|
||||
IDD_CONFIGURETRANSITIONSOURCE DIALOGEX 0, 0, 338, 198
|
||||
|
@ -436,7 +439,7 @@ END
|
|||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_SETTINGS, DIALOG
|
||||
BEGIN
|
||||
|
@ -618,7 +621,7 @@ END
|
|||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_ACCELERATOR1 ACCELERATORS
|
||||
IDR_ACCELERATOR1 ACCELERATORS
|
||||
BEGIN
|
||||
"C", IDA_SOURCE_CENTER, VIRTKEY, CONTROL, NOINVERT
|
||||
VK_DELETE, IDA_SOURCE_DELETE, VIRTKEY, NOINVERT
|
||||
|
@ -674,7 +677,7 @@ END
|
|||
// Menu
|
||||
//
|
||||
|
||||
IDR_MAINMENU MENU
|
||||
IDR_MAINMENU MENU
|
||||
BEGIN
|
||||
POPUP "MainMenu.File"
|
||||
BEGIN
|
||||
|
@ -703,7 +706,7 @@ END
|
|||
//
|
||||
|
||||
IDC_COLORPICKER CURSOR "cursor1.cur"
|
||||
#endif // Japanese (Japan) resources
|
||||
#endif // 日本語 resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
12
OBS.vcproj
12
OBS.vcproj
|
@ -478,6 +478,18 @@
|
|||
RelativePath=".\Source\OBS.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\OBSCapture.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\OBSHotkeyHandlers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\OBSVideoCapture.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Source\RTMPPublisher.cpp"
|
||||
>
|
||||
|
|
|
@ -118,6 +118,8 @@ public:
|
|||
virtual void RemoveAudioSource(AudioSource *source)=0;
|
||||
|
||||
virtual QWORD GetAudioTime() const=0;
|
||||
|
||||
virtual CTSTR GetAppPath() const=0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -75,8 +75,17 @@ union TripleToLong
|
|||
};
|
||||
};
|
||||
|
||||
void AudioSource::InitAudioData()
|
||||
void AudioSource::InitAudioData(bool bFloat, UINT channels, UINT samplesPerSec, UINT bitsPerSample, UINT blockSize, DWORD channelMask)
|
||||
{
|
||||
this->bFloat = bFloat;
|
||||
inputChannels = channels;
|
||||
inputSamplesPerSec = samplesPerSec;
|
||||
inputBitsPerSample = bitsPerSample;
|
||||
inputBlockSize = blockSize;
|
||||
inputChannelMask = channelMask;
|
||||
|
||||
//-----------------------------
|
||||
|
||||
if(inputSamplesPerSec != 44100)
|
||||
{
|
||||
int errVal;
|
||||
|
@ -552,7 +561,11 @@ UINT AudioSource::QueryAudio(float curVolume)
|
|||
|
||||
QWORD difVal = GetQWDif(newTimestamp, lastUsedTimestamp);
|
||||
if(difVal > 70)
|
||||
{
|
||||
//Log(TEXT("----------------------------1\r\nlastUsedTimestamp before: %llu"), lastUsedTimestamp);
|
||||
lastUsedTimestamp = newTimestamp;
|
||||
//Log(TEXT("lastUsedTimestamp after: %llu"), lastUsedTimestamp);
|
||||
}
|
||||
|
||||
if(lastUsedTimestamp > lastSentTimestamp)
|
||||
{
|
||||
|
@ -579,7 +592,11 @@ UINT AudioSource::QueryAudio(float curVolume)
|
|||
|
||||
QWORD difVal = GetQWDif(newTimestamp, lastUsedTimestamp);
|
||||
if(difVal > 70)
|
||||
{
|
||||
//Log(TEXT("----------------------------2\r\nlastUsedTimestamp before: %llu"), lastUsedTimestamp);
|
||||
lastUsedTimestamp = newTimestamp - (QWORD(storedFrames)/2*1000/44100);
|
||||
//Log(TEXT("lastUsedTimestamp after: %llu"), lastUsedTimestamp);
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// add new data
|
||||
|
|
|
@ -49,6 +49,7 @@ class BASE_EXPORT AudioSource
|
|||
|
||||
bool bFirstBaseFrameReceived;
|
||||
QWORD lastSentTimestamp;
|
||||
int timeOffset;
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
|
@ -61,22 +62,22 @@ class BASE_EXPORT AudioSource
|
|||
List<float> tempBuffer;
|
||||
List<float> tempResampleBuffer;
|
||||
|
||||
protected:
|
||||
|
||||
int timeOffset;
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
bool bFloat;
|
||||
UINT inputChannels;
|
||||
UINT inputSamplesPerSec;
|
||||
UINT inputBitsPerSample;
|
||||
UINT inputBlockSize;
|
||||
bool bFloat;
|
||||
UINT inputChannels;
|
||||
UINT inputSamplesPerSec;
|
||||
UINT inputBitsPerSample;
|
||||
UINT inputBlockSize;
|
||||
DWORD inputChannelMask;
|
||||
|
||||
QWORD lastUsedTimestamp;
|
||||
|
||||
void InitAudioData();
|
||||
//-----------------------------------------
|
||||
|
||||
protected:
|
||||
|
||||
void InitAudioData(bool bFloat, UINT channels, UINT samplesPerSec, UINT bitsPerSample, UINT blockSize, DWORD channelMask);
|
||||
|
||||
//-----------------------------------------
|
||||
|
||||
|
@ -104,6 +105,10 @@ public:
|
|||
virtual void StartCapture() {}
|
||||
virtual void StopCapture() {}
|
||||
|
||||
inline UINT GetChannelCount() const {return inputChannels;}
|
||||
inline UINT GetSamplesPerSec() const {return inputSamplesPerSec;}
|
||||
|
||||
inline int GetTimeOffset() const {return timeOffset;}
|
||||
inline void SetTimeOffset(int newOffset) {timeOffset = newOffset;}
|
||||
};
|
||||
|
||||
|
|
|
@ -98,6 +98,30 @@ inline BOOL CloseDouble(double f1, double f2, double precision=0.001)
|
|||
return fabs(f1-f2) <= precision;
|
||||
}
|
||||
|
||||
inline QWORD GetQPCTime100NS(LONGLONG clockFreq)
|
||||
{
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
QWORD timeVal = currentTime.QuadPart;
|
||||
timeVal *= 10000000;
|
||||
timeVal /= clockFreq;
|
||||
|
||||
return timeVal;
|
||||
}
|
||||
|
||||
inline QWORD GetQPCTimeMS(LONGLONG clockFreq)
|
||||
{
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
QWORD timeVal = currentTime.QuadPart;
|
||||
timeVal *= 1000;
|
||||
timeVal /= clockFreq;
|
||||
|
||||
return timeVal;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
#include "GraphicsSystem.h"
|
||||
|
|
|
@ -128,8 +128,9 @@ BASE_EXPORT DEFPROC STDCALL OSGetProcAddress(HANDLE hLibrary, LPCSTR lpProcedure
|
|||
BASE_EXPORT void STDCALL OSFreeLibrary(HANDLE hLibrary);
|
||||
|
||||
BASE_EXPORT void STDCALL OSSleep(DWORD dwMSeconds);
|
||||
BASE_EXPORT void STDCALL OSSubMillisecondSleep(float fMSeconds);
|
||||
BASE_EXPORT void STDCALL OSMicrosecondSleep(QWORD qwMicroseconds);
|
||||
BASE_EXPORT void STDCALL OSSleepSubMillisecond(double fMSeconds);
|
||||
BASE_EXPORT void STDCALL OSSleepMicrosecond(QWORD qwMicroseconds);
|
||||
BASE_EXPORT void STDCALL OSSleep100NS(QWORD qw100NSTime); //why
|
||||
|
||||
BASE_EXPORT int STDCALL OSGetVersion();
|
||||
BASE_EXPORT int STDCALL OSGetTotalCores();
|
||||
|
|
|
@ -465,7 +465,7 @@ void STDCALL OSCloseMutex(HANDLE hMutex)
|
|||
}
|
||||
|
||||
|
||||
void STDCALL OSSubMillisecondSleep(float fMSeconds)
|
||||
void STDCALL OSSleepSubMillisecond(double fMSeconds)
|
||||
{
|
||||
int intPart;
|
||||
|
||||
|
@ -478,20 +478,20 @@ void STDCALL OSSubMillisecondSleep(float fMSeconds)
|
|||
fMSeconds -= intPart;
|
||||
|
||||
LARGE_INTEGER t1, t2;
|
||||
float fElapsedTime;
|
||||
double fElapsedTime;
|
||||
|
||||
QueryPerformanceCounter(&t1);
|
||||
for (;;)
|
||||
{
|
||||
QueryPerformanceCounter(&t2);
|
||||
fElapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0f / clockFreq.QuadPart;
|
||||
fElapsedTime = (t2.QuadPart - t1.QuadPart) * 1000.0 / clockFreq.QuadPart;
|
||||
if (fElapsedTime >= fMSeconds)
|
||||
return;
|
||||
Sleep(0);
|
||||
}
|
||||
}
|
||||
|
||||
void STDCALL OSMicrosecondSleep(QWORD qwMicroseconds)
|
||||
void STDCALL OSSleepMicrosecond(QWORD qwMicroseconds)
|
||||
{
|
||||
unsigned int milliseconds = (unsigned int)(qwMicroseconds/1000);
|
||||
if(bWindows8 && milliseconds >= 2)
|
||||
|
@ -515,6 +515,30 @@ void STDCALL OSMicrosecondSleep(QWORD qwMicroseconds)
|
|||
}
|
||||
}
|
||||
|
||||
void STDCALL OSSleep100NS(QWORD qw100NSTime)
|
||||
{
|
||||
unsigned int milliseconds = (unsigned int)(qw100NSTime/10000);
|
||||
if(bWindows8 && milliseconds >= 2)
|
||||
milliseconds--;
|
||||
if (milliseconds > 0)
|
||||
Sleep(milliseconds);
|
||||
|
||||
qw100NSTime -= milliseconds*10000;
|
||||
|
||||
LARGE_INTEGER t1, t2;
|
||||
QWORD qwElapsedTime;
|
||||
|
||||
QueryPerformanceCounter(&t1);
|
||||
for (;;)
|
||||
{
|
||||
QueryPerformanceCounter(&t2);
|
||||
qwElapsedTime = (t2.QuadPart - t1.QuadPart) * 10000000 / clockFreq.QuadPart;
|
||||
if (qwElapsedTime >= qw100NSTime)
|
||||
return;
|
||||
Sleep(0);
|
||||
}
|
||||
}
|
||||
|
||||
void STDCALL OSSleep(DWORD dwMSeconds)
|
||||
{
|
||||
if(bWindows8)
|
||||
|
|
|
@ -304,4 +304,3 @@ bool OBS::SetScene(CTSTR lpScene)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ struct BlankAudioPlayback
|
|||
IAudioClient *mmClient;
|
||||
IAudioRenderClient *mmRender;
|
||||
|
||||
inline BlankAudioPlayback()
|
||||
BlankAudioPlayback(CTSTR lpDevice)
|
||||
{
|
||||
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||
|
@ -47,7 +47,7 @@ struct BlankAudioPlayback
|
|||
if(FAILED(err))
|
||||
CrashError(TEXT("Could not create IMMDeviceEnumerator"));
|
||||
|
||||
err = mmEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &mmDevice);
|
||||
err = mmEnumerator->GetDevice(lpDevice, &mmDevice);
|
||||
if(FAILED(err))
|
||||
CrashError(TEXT("Could not create IMMDevice"));
|
||||
|
||||
|
@ -90,7 +90,7 @@ struct BlankAudioPlayback
|
|||
CrashError(TEXT("Could not start audio source"));
|
||||
}
|
||||
|
||||
inline ~BlankAudioPlayback()
|
||||
~BlankAudioPlayback()
|
||||
{
|
||||
mmClient->Stop();
|
||||
|
||||
|
@ -104,10 +104,10 @@ struct BlankAudioPlayback
|
|||
|
||||
static BlankAudioPlayback *curBlankPlaybackThingy = NULL;
|
||||
|
||||
void StartBlankSoundPlayback()
|
||||
void StartBlankSoundPlayback(CTSTR lpDevice)
|
||||
{
|
||||
if(!curBlankPlaybackThingy)
|
||||
curBlankPlaybackThingy = new BlankAudioPlayback;
|
||||
curBlankPlaybackThingy = new BlankAudioPlayback(lpDevice);
|
||||
}
|
||||
|
||||
void StopBlankSoundPlayback()
|
||||
|
|
|
@ -67,13 +67,15 @@ class X264Encoder : public VideoEncoder
|
|||
|
||||
bool bFirstFrameProcessed;
|
||||
|
||||
bool bUseCBR, bUseCTSAdjust;
|
||||
bool bUseCBR, bUseCFR;
|
||||
|
||||
List<VideoPacket> CurrentPackets;
|
||||
List<BYTE> HeaderPacket;
|
||||
|
||||
INT64 delayOffset;
|
||||
|
||||
int frameShift;
|
||||
|
||||
inline void ClearPackets()
|
||||
{
|
||||
for(UINT i=0; i<CurrentPackets.Num(); i++)
|
||||
|
@ -82,7 +84,7 @@ class X264Encoder : public VideoEncoder
|
|||
}
|
||||
|
||||
public:
|
||||
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, int maxBitRate, int bufferSize)
|
||||
X264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, int maxBitRate, int bufferSize, bool bUseCFR)
|
||||
{
|
||||
fps_ms = 1000/fps;
|
||||
|
||||
|
@ -106,6 +108,7 @@ public:
|
|||
//paramData.i_threads = 4;
|
||||
|
||||
bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR")) != 0;
|
||||
this->bUseCFR = bUseCFR;
|
||||
|
||||
if(bUseCBR)
|
||||
{
|
||||
|
@ -124,13 +127,11 @@ public:
|
|||
paramData.rc.f_rf_constant = baseCRF+float(10-quality);
|
||||
}
|
||||
|
||||
paramData.b_vfr_input = 1;
|
||||
paramData.i_keyint_max = fps*4; //keyframe every 4 sec, should make this an option
|
||||
paramData.b_vfr_input = !bUseCFR;
|
||||
paramData.i_width = width;
|
||||
paramData.i_height = height;
|
||||
paramData.vui.b_fullrange = 0; //specify full range input levels
|
||||
//paramData.i_frame_reference = 1;
|
||||
//paramData.b_in
|
||||
//paramData.vui.b_fullrange = 0; //specify full range input levels
|
||||
//paramData.i_keyint_max = fps*4; //keyframe every 4 sec, should make this an option
|
||||
|
||||
paramData.i_fps_num = fps;
|
||||
paramData.i_fps_den = 1;
|
||||
|
@ -141,7 +142,6 @@ public:
|
|||
//paramData.pf_log = get_x264_log;
|
||||
//paramData.i_log_level = X264_LOG_INFO;
|
||||
|
||||
bUseCTSAdjust = !AppConfig->GetInt(TEXT("Video Encoding"), TEXT("DisableCTSAdjust"));
|
||||
BOOL bUseCustomParams = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCustomSettings"));
|
||||
if(bUseCustomParams)
|
||||
{
|
||||
|
@ -168,14 +168,28 @@ public:
|
|||
{
|
||||
continue;
|
||||
}
|
||||
else if(strParamName.CompareI(TEXT("preset")))
|
||||
{
|
||||
LPSTR lpVal = strParamVal.CreateUTF8String();
|
||||
x264_param_default_preset(¶mData, lpVal, NULL);
|
||||
Free(lpVal);
|
||||
}
|
||||
else if(strParamName.CompareI(TEXT("tune")))
|
||||
{
|
||||
LPSTR lpVal = strParamVal.CreateUTF8String();
|
||||
x264_param_default_preset(¶mData, NULL, lpVal);
|
||||
Free(lpVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPSTR lpParam = strParamName.CreateUTF8String();
|
||||
LPSTR lpVal = strParamVal.CreateUTF8String();
|
||||
|
||||
LPSTR lpParam = strParamName.CreateUTF8String();
|
||||
LPSTR lpVal = strParamVal.CreateUTF8String();
|
||||
x264_param_parse(¶mData, lpParam, lpVal);
|
||||
|
||||
x264_param_parse(¶mData, lpParam, lpVal);
|
||||
|
||||
Free(lpParam);
|
||||
Free(lpVal);
|
||||
Free(lpParam);
|
||||
Free(lpVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,7 +239,18 @@ public:
|
|||
INT64 ts = INT64(outputTimestamp);
|
||||
int timeOffset = int((picOut.i_pts+delayOffset)-ts);
|
||||
|
||||
if(bUseCTSAdjust)
|
||||
if(bUseCFR)
|
||||
{
|
||||
//if CFR's being used, the shift will be insignificant, so just don't bother adjusting audio
|
||||
timeOffset += frameShift;
|
||||
|
||||
if(nalNum && timeOffset < 0)
|
||||
{
|
||||
frameShift -= timeOffset;
|
||||
timeOffset = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timeOffset += ctsOffset;
|
||||
|
||||
|
@ -370,6 +395,7 @@ public:
|
|||
TEXT("\r\n width: ") << IntString(width) << TEXT(", height: ") << IntString(height) <<
|
||||
TEXT("\r\n preset: ") << curPreset <<
|
||||
TEXT("\r\n CBR: ") << CTSTR((bUseCBR) ? TEXT("yes") : TEXT("no")) <<
|
||||
TEXT("\r\n CFR: ") << CTSTR((bUseCFR) ? TEXT("yes") : TEXT("no")) <<
|
||||
TEXT("\r\n max bitrate: ") << IntString(paramData.rc.i_vbv_max_bitrate);
|
||||
|
||||
if(!bUseCBR)
|
||||
|
@ -409,8 +435,8 @@ public:
|
|||
};
|
||||
|
||||
|
||||
VideoEncoder* CreateX264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, int maxBitRate, int bufferSize)
|
||||
VideoEncoder* CreateX264Encoder(int fps, int width, int height, int quality, CTSTR preset, bool bUse444, int maxBitRate, int bufferSize, bool bUseCFR)
|
||||
{
|
||||
return new X264Encoder(fps, width, height, quality, preset, bUse444, maxBitRate, bufferSize);
|
||||
return new X264Encoder(fps, width, height, quality, preset, bUse444, maxBitRate, bufferSize, bUseCFR);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <Functiondiscoverykeys_devpkey.h>
|
||||
|
||||
|
||||
void GetAudioDevices(AudioDeviceList &deviceList)
|
||||
void GetAudioDevices(AudioDeviceList &deviceList, AudioDeviceType deviceType)
|
||||
{
|
||||
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||
|
@ -41,9 +41,13 @@ void GetAudioDevices(AudioDeviceList &deviceList)
|
|||
|
||||
//-------------------------------------------------------
|
||||
|
||||
AudioDeviceInfo *info = deviceList.devices.CreateNew();
|
||||
info->strID = TEXT("Disable");
|
||||
info->strName = Str("Disable");
|
||||
AudioDeviceInfo *info;
|
||||
|
||||
if(deviceType == ADT_RECORDING) {
|
||||
info = deviceList.devices.CreateNew();
|
||||
info->strID = TEXT("Disable");
|
||||
info->strName = Str("Disable");
|
||||
}
|
||||
|
||||
info = deviceList.devices.CreateNew();
|
||||
info->strID = TEXT("Default");
|
||||
|
@ -52,7 +56,22 @@ void GetAudioDevices(AudioDeviceList &deviceList)
|
|||
//-------------------------------------------------------
|
||||
|
||||
IMMDeviceCollection *collection;
|
||||
err = mmEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &collection);
|
||||
|
||||
EDataFlow audioDeviceType;
|
||||
switch(deviceType)
|
||||
{
|
||||
case ADT_RECORDING:
|
||||
audioDeviceType = eCapture;
|
||||
break;
|
||||
case ADT_PLAYBACK:
|
||||
audioDeviceType = eRender;
|
||||
break;
|
||||
default:
|
||||
audioDeviceType = eAll;
|
||||
break;
|
||||
}
|
||||
|
||||
err = mmEnumerator->EnumAudioEndpoints(audioDeviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &collection);
|
||||
if(FAILED(err))
|
||||
{
|
||||
AppWarning(TEXT("GetAudioDevices: Could not enumerate audio endpoints"));
|
||||
|
@ -101,7 +120,7 @@ void GetAudioDevices(AudioDeviceList &deviceList)
|
|||
SafeRelease(mmEnumerator);
|
||||
}
|
||||
|
||||
bool GetDefaultMicID(String &strVal)
|
||||
bool GetDefaultDevice(String &strVal, EDataFlow df )
|
||||
{
|
||||
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
|
||||
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
|
||||
|
@ -115,7 +134,7 @@ bool GetDefaultMicID(String &strVal)
|
|||
//-------------------------------------------------------
|
||||
|
||||
IMMDevice *defDevice;
|
||||
if(FAILED(mmEnumerator->GetDefaultAudioEndpoint(eCapture, eCommunications, &defDevice)))
|
||||
if(FAILED(mmEnumerator->GetDefaultAudioEndpoint(df, eCommunications, &defDevice)))
|
||||
{
|
||||
SafeRelease(mmEnumerator);
|
||||
return false;
|
||||
|
@ -137,3 +156,11 @@ bool GetDefaultMicID(String &strVal)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetDefaultMicID(String &strVal) {
|
||||
return GetDefaultDevice(strVal, eCapture);
|
||||
}
|
||||
|
||||
bool GetDefaultSpeakerID(String &strVal) {
|
||||
return GetDefaultDevice(strVal, eRender);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,14 @@ class MMDeviceAudioSource : public AudioSource
|
|||
|
||||
String strDeviceName;
|
||||
|
||||
bool bUseVideoTime;
|
||||
QWORD lastVideoTime;
|
||||
QWORD curVideoTime;
|
||||
|
||||
UINT32 lastNumFramesRead;
|
||||
UINT sampleWindowSize;
|
||||
List<float> inputBuffer;
|
||||
|
||||
protected:
|
||||
virtual bool GetNextBuffer(void **buffer, UINT *numFrames, QWORD *timestamp);
|
||||
virtual void ReleaseBuffer();
|
||||
|
@ -94,13 +102,8 @@ bool MMDeviceAudioSource::Initialize(bool bMic, CTSTR lpID)
|
|||
return false;
|
||||
}
|
||||
|
||||
this->timeOffset = timeOffset;
|
||||
bIsMic = bMic;
|
||||
|
||||
if(bMic)
|
||||
err = mmEnumerator->GetDevice(lpID, &mmDevice);
|
||||
else
|
||||
err = mmEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &mmDevice);
|
||||
err = mmEnumerator->GetDevice(lpID, &mmDevice);
|
||||
|
||||
if(FAILED(err))
|
||||
{
|
||||
|
@ -138,6 +141,13 @@ bool MMDeviceAudioSource::Initialize(bool bMic, CTSTR lpID)
|
|||
Log(TEXT("------------------------------------------"));
|
||||
Log(TEXT("Using auxilary audio input: %s"), GetDeviceName());
|
||||
}
|
||||
else
|
||||
{
|
||||
Log(TEXT("------------------------------------------"));
|
||||
Log(TEXT("Using desktop audio input: %s"), GetDeviceName());
|
||||
|
||||
bUseVideoTime = AppConfig->GetInt(TEXT("Audio"), TEXT("SyncToVideoTime")) != 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// get format
|
||||
|
@ -150,6 +160,13 @@ bool MMDeviceAudioSource::Initialize(bool bMic, CTSTR lpID)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool bFloat;
|
||||
UINT inputChannels;
|
||||
UINT inputSamplesPerSec;
|
||||
UINT inputBitsPerSample;
|
||||
UINT inputBlockSize;
|
||||
DWORD inputChannelMask;
|
||||
|
||||
//the internal audio engine should always use floats (or so I read), but I suppose just to be safe better check
|
||||
if(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
|
||||
{
|
||||
|
@ -174,6 +191,8 @@ bool MMDeviceAudioSource::Initialize(bool bMic, CTSTR lpID)
|
|||
inputBlockSize = pwfx->nBlockAlign;
|
||||
inputSamplesPerSec = pwfx->nSamplesPerSec;
|
||||
|
||||
sampleWindowSize = (inputSamplesPerSec/100);
|
||||
|
||||
DWORD flags = bMic ? 0 : AUDCLNT_STREAMFLAGS_LOOPBACK;
|
||||
err = mmClient->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, ConvertMSTo100NanoSec(5000), 0, pwfx, NULL);
|
||||
if(FAILED(err))
|
||||
|
@ -203,7 +222,7 @@ bool MMDeviceAudioSource::Initialize(bool bMic, CTSTR lpID)
|
|||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
InitAudioData();
|
||||
InitAudioData(bFloat, inputChannels, inputSamplesPerSec, inputBitsPerSample, inputBlockSize, inputChannelMask);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -222,86 +241,117 @@ void MMDeviceAudioSource::StopCapture()
|
|||
|
||||
bool MMDeviceAudioSource::GetNextBuffer(void **buffer, UINT *numFrames, QWORD *timestamp)
|
||||
{
|
||||
UINT captureSize = 0;
|
||||
HRESULT err = mmCapture->GetNextPacketSize(&captureSize);
|
||||
if(FAILED(err))
|
||||
return false;
|
||||
float *captureBuffer = NULL;
|
||||
|
||||
numFramesRead = 0;
|
||||
QWORD qpcTimestamp;
|
||||
|
||||
if(captureSize)
|
||||
//all audio data should be sent out in 10ms data sizes.
|
||||
bool bNeedMoreFrames = true;
|
||||
while(bNeedMoreFrames)
|
||||
{
|
||||
LPBYTE captureBuffer;
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
UINT64 devPosition;
|
||||
UINT64 qpcTimestamp;
|
||||
err = mmCapture->GetBuffer(&captureBuffer, &numFramesRead, &dwFlags, &devPosition, &qpcTimestamp);
|
||||
UINT captureSize = 0;
|
||||
HRESULT err = mmCapture->GetNextPacketSize(&captureSize);
|
||||
if(FAILED(err))
|
||||
{
|
||||
RUNONCE AppWarning(TEXT("MMDeviceAudioSource::GetBuffer: GetBuffer failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// timestamp bs
|
||||
|
||||
QWORD newTimestamp = 0;
|
||||
|
||||
if(bIsMic)
|
||||
if(captureSize)
|
||||
{
|
||||
newTimestamp = App->GetAudioTime()+timeOffset;
|
||||
//Log(TEXT("newTimestamp: %llu"), newTimestamp);
|
||||
DWORD dwFlags = 0;
|
||||
|
||||
err = mmCapture->GetBuffer((BYTE**)&captureBuffer, &lastNumFramesRead, &dwFlags, NULL, &qpcTimestamp);
|
||||
if(FAILED(err))
|
||||
{
|
||||
RUNONCE AppWarning(TEXT("MMDeviceAudioSource::GetBuffer: GetBuffer failed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
qpcTimestamp /= 10000;
|
||||
|
||||
if(inputBuffer.Num() == 0 && lastNumFramesRead == sampleWindowSize)
|
||||
break;
|
||||
|
||||
qpcTimestamp -= inputBuffer.Num()/GetChannelCount()*1000/GetSamplesPerSec();
|
||||
inputBuffer.AppendArray(captureBuffer, lastNumFramesRead*GetChannelCount());
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
if(inputBuffer.Num() >= sampleWindowSize*GetChannelCount())
|
||||
{
|
||||
captureBuffer = inputBuffer.Array();
|
||||
bNeedMoreFrames = false;
|
||||
}
|
||||
else
|
||||
mmCapture->ReleaseBuffer(lastNumFramesRead);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
// timestamp bs. now using video timestamps as an audio base. kill me.
|
||||
QWORD newTimestamp = 0;
|
||||
|
||||
//don't even -bother- trying to get mic or auxilary audio time from timestamps.
|
||||
//half the time, they aren't valid. just use desktop timing and let the user deal with
|
||||
//offsetting the time.
|
||||
if(bIsMic)
|
||||
newTimestamp = App->GetAudioTime()+GetTimeOffset();
|
||||
else
|
||||
{
|
||||
//we're doing all these checks because device timestamps are only reliable "sometimes"
|
||||
if(!bFirstFrameReceived)
|
||||
{
|
||||
LARGE_INTEGER clockFreq;
|
||||
QueryPerformanceFrequency(&clockFreq);
|
||||
QWORD curTime = GetQPCTimeMS(clockFreq.QuadPart);
|
||||
|
||||
newTimestamp = qpcTimestamp;
|
||||
|
||||
if(bUseVideoTime || newTimestamp < (curTime-OUTPUT_BUFFER_TIME) || newTimestamp > (curTime+2000))
|
||||
{
|
||||
curVideoTime = lastVideoTime = App->GetVideoTime();
|
||||
|
||||
SetTimeOffset(GetTimeOffset()-int(lastVideoTime-App->GetSceneTimestamp()));
|
||||
bUseVideoTime = true;
|
||||
|
||||
newTimestamp = lastVideoTime+GetTimeOffset();
|
||||
}
|
||||
|
||||
bFirstFrameReceived = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dwFlags & AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR)
|
||||
if(bUseVideoTime)
|
||||
{
|
||||
RUNONCE AppWarning(TEXT("MMDeviceAudioSource::GetBuffer: woa woa woa, getting timestamp errors from the audio subsystem. device = %s"), GetDeviceName());
|
||||
newTimestamp = lastUsedTimestamp + numFramesRead*1000/inputSamplesPerSec;
|
||||
}
|
||||
else
|
||||
newTimestamp = qpcTimestamp/10000;
|
||||
QWORD newVideoTime = App->GetVideoTime();
|
||||
|
||||
//have to do this crap to account for broken devices or device drivers. absolutely unbelievable.
|
||||
if(!bFirstFrameReceived)
|
||||
{
|
||||
LARGE_INTEGER clockFreq;
|
||||
QueryPerformanceFrequency(&clockFreq);
|
||||
QWORD curTime = GetQPCTimeMS(clockFreq.QuadPart);
|
||||
|
||||
if(newTimestamp < (curTime-OUTPUT_BUFFER_TIME) || newTimestamp > (curTime+2000))
|
||||
if(newVideoTime != lastVideoTime)
|
||||
{
|
||||
//disabled for debug mode since this crashes when stepping through in the debugger
|
||||
#ifndef _DEBUG
|
||||
CrashError(TEXT("MMDeviceAudioSource::GetNextBuffer: Got bad audio timestamp offset %lld from device: '%s'. curTime: %llu, newTimestamp: %llu"), (LONGLONG)(newTimestamp - curTime), GetDeviceName(), curTime, newTimestamp);
|
||||
#endif
|
||||
lastUsedTimestamp = newTimestamp = curTime;
|
||||
lastVideoTime = newVideoTime;
|
||||
newTimestamp = curVideoTime = newVideoTime+GetTimeOffset();
|
||||
}
|
||||
else
|
||||
lastUsedTimestamp = newTimestamp;
|
||||
|
||||
bFirstFrameReceived = true;
|
||||
newTimestamp = curVideoTime += 10;
|
||||
}
|
||||
|
||||
//desktop audio is best audio! use it for the base audio
|
||||
App->latestAudioTime = newTimestamp;
|
||||
else
|
||||
newTimestamp = qpcTimestamp+GetTimeOffset();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//save data
|
||||
|
||||
*numFrames = numFramesRead;
|
||||
*buffer = (void*)captureBuffer;
|
||||
*timestamp = newTimestamp;
|
||||
|
||||
return true;
|
||||
App->latestAudioTime = newTimestamp;
|
||||
}
|
||||
|
||||
return false;
|
||||
//-----------------------------------------------------------------
|
||||
//save data
|
||||
|
||||
*numFrames = sampleWindowSize;
|
||||
*buffer = (void*)captureBuffer;
|
||||
*timestamp = newTimestamp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MMDeviceAudioSource::ReleaseBuffer()
|
||||
{
|
||||
mmCapture->ReleaseBuffer(numFramesRead);
|
||||
}
|
||||
if(inputBuffer.Num() != 0)
|
||||
inputBuffer.RemoveRange(0, sampleWindowSize*GetChannelCount());
|
||||
|
||||
mmCapture->ReleaseBuffer(lastNumFramesRead);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ time_t GetMacTime()
|
|||
return time(0)+2082844800;
|
||||
}
|
||||
|
||||
|
||||
struct SampleToChunk
|
||||
{
|
||||
UINT firstChunkID;
|
||||
|
@ -79,7 +78,6 @@ class MP4FileStream : public VideoFileStream
|
|||
|
||||
bool bStreamOpened;
|
||||
bool bMP3;
|
||||
bool bUseCTSAdjust;
|
||||
|
||||
List<BYTE> endBuffer;
|
||||
List<UINT> boxOffsets;
|
||||
|
@ -138,8 +136,6 @@ public:
|
|||
if(!fileOut.Open(lpFile, XFILE_CREATEALWAYS, 1024*1024))
|
||||
return false;
|
||||
|
||||
bUseCTSAdjust = !AppConfig->GetInt(TEXT("Video Encoding"), TEXT("DisableCTSAdjust"));
|
||||
|
||||
fileOut.OutputDword(DWORD_BE(0x20));
|
||||
fileOut.OutputDword(DWORD_BE('ftyp'));
|
||||
fileOut.OutputDword(DWORD_BE('isom'));
|
||||
|
@ -231,8 +227,10 @@ public:
|
|||
UINT width, height;
|
||||
App->GetOutputSize(width, height);
|
||||
|
||||
LPCSTR lpVideoTrack = "videoTrack";
|
||||
LPCSTR lpAudioTrack = "audioTrack";
|
||||
LPCSTR lpVideoTrack = "Video Media Handler";
|
||||
LPCSTR lpAudioTrack = "Sound Media Handler";
|
||||
|
||||
char videoCompressionName[31] = "AVC Coding";
|
||||
|
||||
//-------------------------------------------
|
||||
// get video headers
|
||||
|
@ -348,44 +346,44 @@ public:
|
|||
|
||||
//-------------------------------------------
|
||||
// sound descriptor thingy. this part made me die a little inside admittedly.
|
||||
UINT maxBitRate = fastHtonl(App->GetAudioEncoder()->GetBitRate()*1024);
|
||||
UINT maxBitRate = fastHtonl(App->GetAudioEncoder()->GetBitRate()*1000);
|
||||
|
||||
List<BYTE> esDecoderDescriptor;
|
||||
BufferOutputSerializer esDecoderOut(esDecoderDescriptor);
|
||||
esDecoderOut.OutputByte(bMP3 ? 107 : 64);
|
||||
esDecoderOut.OutputByte(0x15); //stream/type flags. always 0x15 for my purposes.
|
||||
esDecoderOut.OutputWord(0); //buffer size (seems ignorable from my testing, so 0)
|
||||
esDecoderOut.OutputByte(0);
|
||||
esDecoderOut.OutputByte(0); //buffer size, just set it to 1536 for both mp3 and aac
|
||||
esDecoderOut.OutputWord(WORD_BE(0x600));
|
||||
esDecoderOut.OutputDword(maxBitRate); //max bit rate (cue bill 'o reily meme for these two)
|
||||
esDecoderOut.OutputDword(maxBitRate); //avg bit rate
|
||||
|
||||
if(!bMP3) //if AAC, put in headers
|
||||
{
|
||||
esDecoderOut.OutputByte(0x5); //decoder specific descriptor type
|
||||
esDecoderOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esDecoderOut.OutputByte(0x80);
|
||||
/*esDecoderOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esDecoderOut.OutputByte(0x80);
|
||||
esDecoderOut.OutputByte(0x80);*/
|
||||
esDecoderOut.OutputByte(AACHeader.Num());
|
||||
esDecoderOut.Serialize((LPVOID)AACHeader.Array(), AACHeader.Num());
|
||||
}
|
||||
|
||||
esDecoderOut.OutputByte(0x6); //config descriptor type
|
||||
esDecoderOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esDecoderOut.OutputByte(0x80);
|
||||
esDecoderOut.OutputByte(0x80);
|
||||
esDecoderOut.OutputByte(1); //len
|
||||
esDecoderOut.OutputByte(2); //SL value(? always 2)
|
||||
|
||||
List<BYTE> esDescriptor;
|
||||
BufferOutputSerializer esOut(esDescriptor);
|
||||
esOut.OutputWord(0); //es id
|
||||
esOut.OutputByte(0); //stream priority
|
||||
esOut.OutputByte(4); //descriptor type
|
||||
esOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esOut.OutputByte(0x80);
|
||||
/*esOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esOut.OutputByte(0x80);
|
||||
esOut.OutputByte(0x80);*/
|
||||
esOut.OutputByte(esDecoderDescriptor.Num());
|
||||
esOut.Serialize((LPVOID)esDecoderDescriptor.Array(), esDecoderDescriptor.Num());
|
||||
esOut.OutputByte(0x6); //config descriptor type
|
||||
/*esOut.OutputByte(0x80); //some stuff that no one should probably care about
|
||||
esOut.OutputByte(0x80);
|
||||
esOut.OutputByte(0x80);*/
|
||||
esOut.OutputByte(1); //len
|
||||
esOut.OutputByte(2); //SL value(? always 2)
|
||||
|
||||
//-------------------------------------------
|
||||
|
||||
|
@ -416,14 +414,164 @@ public:
|
|||
PopBox(); //mvhd
|
||||
|
||||
//------------------------------------------------------
|
||||
// video track
|
||||
// audio track
|
||||
PushBox(output, DWORD_BE('trak'));
|
||||
PushBox(output, DWORD_BE('tkhd')); //track header
|
||||
output.OutputDword(DWORD_BE(0x0000000F)); //version (0) and flags (0xF)
|
||||
output.OutputDword(DWORD_BE(0x00000007)); //version (0) and flags (0xF)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(1)); //track ID
|
||||
output.OutputDword(0); //reserved
|
||||
output.OutputDword(audioDuration); //duration (in time base units)
|
||||
output.OutputQword(0); //reserved
|
||||
output.OutputWord(0); //video layer (0)
|
||||
output.OutputWord(WORD_BE(0)); //quicktime alternate track id
|
||||
output.OutputWord(WORD_BE(0x0100)); //volume
|
||||
output.OutputWord(0); //reserved
|
||||
output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 1 (1.0, 0.0, 0.0)
|
||||
output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 2 (0.0, 1.0, 0.0)
|
||||
output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x40000000)); //window matrix row 3 (0.0, 0.0, 16384.0)
|
||||
output.OutputDword(0); //width (fixed point)
|
||||
output.OutputDword(0); //height (fixed point)
|
||||
PopBox(); //tkhd
|
||||
/*PushBox(output, DWORD_BE('edts'));
|
||||
PushBox(output, DWORD_BE('elst'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
output.OutputDword(audioDuration); //duration
|
||||
output.OutputDword(0); //start time
|
||||
output.OutputDword(DWORD_BE(0x00010000)); //playback speed (1.0)
|
||||
PopBox(); //elst
|
||||
PopBox(); //tdst*/
|
||||
PushBox(output, DWORD_BE('mdia'));
|
||||
PushBox(output, DWORD_BE('mdhd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(44100)); //time scale
|
||||
output.OutputDword(audioUnitDuration);
|
||||
output.OutputDword(DWORD_BE(0x15c70000));
|
||||
PopBox(); //mdhd
|
||||
PushBox(output, DWORD_BE('hdlr'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //quicktime type (none)
|
||||
output.OutputDword(DWORD_BE('soun')); //media type
|
||||
output.OutputDword(0); //manufacturer reserved
|
||||
output.OutputDword(0); //quicktime component reserved flags
|
||||
output.OutputDword(0); //quicktime component reserved mask
|
||||
output.Serialize((LPVOID)lpAudioTrack, (DWORD)strlen(lpAudioTrack)+1); //track name
|
||||
PopBox(); //hdlr
|
||||
PushBox(output, DWORD_BE('minf'));
|
||||
PushBox(output, DWORD_BE('smhd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //balance (fixed point)
|
||||
PopBox(); //vdhd
|
||||
PushBox(output, DWORD_BE('dinf'));
|
||||
PushBox(output, DWORD_BE('dref'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
PushBox(output, DWORD_BE('url '));
|
||||
output.OutputDword(DWORD_BE(0x00000001)); //version (0) and flags (1)
|
||||
PopBox(); //url
|
||||
PopBox(); //dref
|
||||
PopBox(); //dinf
|
||||
PushBox(output, DWORD_BE('stbl'));
|
||||
PushBox(output, DWORD_BE('stsd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
PushBox(output, DWORD_BE('mp4a'));
|
||||
output.OutputDword(0); //reserved (6 bytes)
|
||||
output.OutputWord(0);
|
||||
output.OutputWord(WORD_BE(1)); //dref index
|
||||
output.OutputWord(0); //quicktime encoding version
|
||||
output.OutputWord(0); //quicktime encoding revision
|
||||
output.OutputDword(0); //quicktime audio encoding vendor
|
||||
output.OutputWord(0); //channels (ignored)
|
||||
output.OutputWord(WORD_BE(16)); //sample size
|
||||
output.OutputWord(0); //quicktime audio compression id
|
||||
output.OutputWord(0); //quicktime audio packet size
|
||||
output.OutputDword(DWORD_BE(44100<<16)); //sample rate (fixed point)
|
||||
PushBox(output, DWORD_BE('esds'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputByte(3); //ES descriptor type
|
||||
/*output.OutputByte(0x80);
|
||||
output.OutputByte(0x80);
|
||||
output.OutputByte(0x80);*/
|
||||
output.OutputByte(esDescriptor.Num());
|
||||
output.Serialize((LPVOID)esDescriptor.Array(), esDescriptor.Num());
|
||||
PopBox();
|
||||
PopBox();
|
||||
PopBox(); //stsd
|
||||
PushBox(output, DWORD_BE('stts')); //list of keyframe (i-frame) IDs
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes.Num()));
|
||||
for(UINT i=0; i<audioDecodeTimes.Num(); i++)
|
||||
{
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes[i].count));
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes[i].val));
|
||||
}
|
||||
PopBox(); //stss
|
||||
PushBox(output, DWORD_BE('stsc')); //sample to chunk list
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioSampleToChunk.Num()));
|
||||
for(UINT i=0; i<audioSampleToChunk.Num(); i++)
|
||||
{
|
||||
SampleToChunk &stc = audioSampleToChunk[i];
|
||||
output.OutputDword(fastHtonl(stc.firstChunkID));
|
||||
output.OutputDword(fastHtonl(stc.samplesPerChunk));
|
||||
output.OutputDword(DWORD_BE(1));
|
||||
}
|
||||
PopBox(); //stsc
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 30, 0);
|
||||
ProcessEvents();
|
||||
|
||||
PushBox(output, DWORD_BE('stsz')); //sample sizes
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //block size for all (0 if differing sizes)
|
||||
output.OutputDword(fastHtonl(audioFrames.Num()));
|
||||
for(UINT i=0; i<audioFrames.Num(); i++)
|
||||
output.OutputDword(fastHtonl(audioFrames[i].size));
|
||||
PopBox();
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 40, 0);
|
||||
ProcessEvents();
|
||||
|
||||
if(audioChunks.Num() && audioChunks.Last() > 0xFFFFFFFFLL)
|
||||
{
|
||||
PushBox(output, DWORD_BE('co64')); //chunk offsets
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioChunks.Num()));
|
||||
for(UINT i=0; i<audioChunks.Num(); i++)
|
||||
output.OutputQword(fastHtonll(audioChunks[i]));
|
||||
PopBox(); //co64
|
||||
}
|
||||
else
|
||||
{
|
||||
PushBox(output, DWORD_BE('stco')); //chunk offsets
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioChunks.Num()));
|
||||
for(UINT i=0; i<audioChunks.Num(); i++)
|
||||
output.OutputDword(fastHtonl((DWORD)audioChunks[i]));
|
||||
PopBox(); //stco
|
||||
}
|
||||
PopBox(); //stbl
|
||||
PopBox(); //minf
|
||||
PopBox(); //mdia
|
||||
PopBox(); //trak
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 50, 0);
|
||||
ProcessEvents();
|
||||
|
||||
//------------------------------------------------------
|
||||
// video track
|
||||
PushBox(output, DWORD_BE('trak'));
|
||||
PushBox(output, DWORD_BE('tkhd')); //track header
|
||||
output.OutputDword(DWORD_BE(0x00000007)); //version (0) and flags (0x7)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(2)); //track ID
|
||||
output.OutputDword(0); //reserved
|
||||
output.OutputDword(videoDuration); //duration (in time base units)
|
||||
output.OutputQword(0); //reserved
|
||||
output.OutputWord(0); //video layer (0)
|
||||
|
@ -436,7 +584,7 @@ public:
|
|||
output.OutputDword(fastHtonl(width<<16)); //width (fixed point)
|
||||
output.OutputDword(fastHtonl(height<<16)); //height (fixed point)
|
||||
PopBox(); //tkhd
|
||||
PushBox(output, DWORD_BE('edts'));
|
||||
/*PushBox(output, DWORD_BE('edts'));
|
||||
PushBox(output, DWORD_BE('elst'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
|
@ -444,7 +592,7 @@ public:
|
|||
output.OutputDword(0); //start time
|
||||
output.OutputDword(DWORD_BE(0x00010000)); //playback speed (1.0)
|
||||
PopBox(); //elst
|
||||
PopBox(); //tdst
|
||||
PopBox(); //tdst*/
|
||||
PushBox(output, DWORD_BE('mdia'));
|
||||
PushBox(output, DWORD_BE('mdhd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
|
@ -499,8 +647,8 @@ public:
|
|||
output.OutputDword(DWORD_BE(0x00480000)); //fixed point height pixel resolution (72.0)
|
||||
output.OutputDword(0); //quicktime video data size
|
||||
output.OutputWord(WORD_BE(1)); //frame count(?)
|
||||
for(UINT i=0; i<4; i++) //encoding name (byte 1 = string length, 31 bytes = string (whats the point of having a size here?)
|
||||
output.OutputQword(0);
|
||||
output.OutputByte((BYTE)strlen(videoCompressionName)); //compression name length
|
||||
output.Serialize(videoCompressionName, 31); //31 bytes for the name
|
||||
output.OutputWord(WORD_BE(24)); //bit depth
|
||||
output.OutputWord(0xFFFF); //quicktime video color table id (none = -1)
|
||||
PushBox(output, DWORD_BE('avcC'));
|
||||
|
@ -528,7 +676,7 @@ public:
|
|||
}
|
||||
PopBox(); //stts
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 30, 0);
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 60, 0);
|
||||
ProcessEvents();
|
||||
|
||||
PushBox(output, DWORD_BE('stss')); //list of keyframe (i-frame) IDs
|
||||
|
@ -537,10 +685,8 @@ public:
|
|||
output.Serialize(IFrameIDs.Array(), IFrameIDs.Num()*sizeof(UINT));
|
||||
PopBox(); //stss
|
||||
PushBox(output, DWORD_BE('ctts')); //list of composition time offsets
|
||||
if(bUseCTSAdjust)
|
||||
output.OutputDword(0); //version (0) and flags (none)
|
||||
else
|
||||
output.OutputDword(DWORD_BE(0x01000000)); //version (1) and flags (none)
|
||||
output.OutputDword(0); //version (0) and flags (none)
|
||||
//output.OutputDword(DWORD_BE(0x01000000)); //version (1) and flags (none)
|
||||
|
||||
output.OutputDword(fastHtonl(compositionOffsets.Num()));
|
||||
for(UINT i=0; i<compositionOffsets.Num(); i++)
|
||||
|
@ -550,7 +696,7 @@ public:
|
|||
}
|
||||
PopBox(); //ctts
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 40, 0);
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 70, 0);
|
||||
ProcessEvents();
|
||||
|
||||
PushBox(output, DWORD_BE('stsc')); //sample to chunk list
|
||||
|
@ -595,156 +741,6 @@ public:
|
|||
PopBox(); //mdia
|
||||
PopBox(); //trak
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 50, 0);
|
||||
ProcessEvents();
|
||||
|
||||
//------------------------------------------------------
|
||||
// audio track
|
||||
PushBox(output, DWORD_BE('trak'));
|
||||
PushBox(output, DWORD_BE('tkhd')); //track header
|
||||
output.OutputDword(DWORD_BE(0x0000000F)); //version (0) and flags (0xF)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(2)); //track ID
|
||||
output.OutputDword(0); //reserved
|
||||
output.OutputDword(audioDuration); //duration (in time base units)
|
||||
output.OutputQword(0); //reserved
|
||||
output.OutputWord(0); //video layer (0)
|
||||
output.OutputWord(WORD_BE(1)); //quicktime alternate track id
|
||||
output.OutputWord(WORD_BE(0x0100)); //volume
|
||||
output.OutputWord(0); //reserved
|
||||
output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 1 (1.0, 0.0, 0.0)
|
||||
output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00010000)); output.OutputDword(DWORD_BE(0x00000000)); //window matrix row 2 (0.0, 1.0, 0.0)
|
||||
output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x00000000)); output.OutputDword(DWORD_BE(0x40000000)); //window matrix row 3 (0.0, 0.0, 16384.0)
|
||||
output.OutputDword(0); //width (fixed point)
|
||||
output.OutputDword(0); //height (fixed point)
|
||||
PopBox(); //tkhd
|
||||
PushBox(output, DWORD_BE('edts'));
|
||||
PushBox(output, DWORD_BE('elst'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
output.OutputDword(audioDuration); //duration
|
||||
output.OutputDword(0); //start time
|
||||
output.OutputDword(DWORD_BE(0x00010000)); //playback speed (1.0)
|
||||
PopBox(); //elst
|
||||
PopBox(); //tdst
|
||||
PushBox(output, DWORD_BE('mdia'));
|
||||
PushBox(output, DWORD_BE('mdhd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(macTime); //creation time
|
||||
output.OutputDword(macTime); //modified time
|
||||
output.OutputDword(DWORD_BE(44100)); //time scale
|
||||
output.OutputDword(audioUnitDuration);
|
||||
output.OutputDword(DWORD_BE(0x55c40000));
|
||||
PopBox(); //mdhd
|
||||
PushBox(output, DWORD_BE('hdlr'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //quicktime type (none)
|
||||
output.OutputDword(DWORD_BE('soun')); //media type
|
||||
output.OutputDword(0); //manufacturer reserved
|
||||
output.OutputDword(0); //quicktime component reserved flags
|
||||
output.OutputDword(0); //quicktime component reserved mask
|
||||
output.Serialize((LPVOID)lpAudioTrack, (DWORD)strlen(lpAudioTrack)+1); //track name
|
||||
PopBox(); //hdlr
|
||||
PushBox(output, DWORD_BE('minf'));
|
||||
PushBox(output, DWORD_BE('smhd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //balance (fixed point)
|
||||
PopBox(); //vdhd
|
||||
PushBox(output, DWORD_BE('dinf'));
|
||||
PushBox(output, DWORD_BE('dref'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
PushBox(output, DWORD_BE('url '));
|
||||
output.OutputDword(DWORD_BE(0x00000001)); //version (0) and flags (1)
|
||||
PopBox(); //url
|
||||
PopBox(); //dref
|
||||
PopBox(); //dinf
|
||||
PushBox(output, DWORD_BE('stbl'));
|
||||
PushBox(output, DWORD_BE('stsd'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(DWORD_BE(1)); //count
|
||||
PushBox(output, DWORD_BE('mp4a'));
|
||||
output.OutputDword(0); //reserved (6 bytes)
|
||||
output.OutputWord(0);
|
||||
output.OutputWord(WORD_BE(1)); //dref index
|
||||
output.OutputWord(0); //quicktime encoding version
|
||||
output.OutputWord(0); //quicktime encoding revision
|
||||
output.OutputDword(0); //quicktime audio encoding vendor
|
||||
output.OutputWord(WORD_BE(2)); //channels
|
||||
output.OutputWord(WORD_BE(16)); //sample size
|
||||
output.OutputWord(0); //quicktime audio compression id
|
||||
output.OutputWord(0); //quicktime audio packet size
|
||||
output.OutputDword(DWORD_BE(44100<<16)); //sample rate (fixed point)
|
||||
PushBox(output, DWORD_BE('esds'));
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputByte(3); //ES descriptor type
|
||||
output.OutputByte(0x80);
|
||||
output.OutputByte(0x80);
|
||||
output.OutputByte(0x80);
|
||||
output.OutputByte(esDescriptor.Num());
|
||||
output.Serialize((LPVOID)esDescriptor.Array(), esDescriptor.Num());
|
||||
PopBox();
|
||||
PopBox();
|
||||
PopBox(); //stsd
|
||||
PushBox(output, DWORD_BE('stts')); //list of keyframe (i-frame) IDs
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes.Num()));
|
||||
for(UINT i=0; i<audioDecodeTimes.Num(); i++)
|
||||
{
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes[i].count));
|
||||
output.OutputDword(fastHtonl(audioDecodeTimes[i].val));
|
||||
}
|
||||
PopBox(); //stss
|
||||
PushBox(output, DWORD_BE('stsc')); //sample to chunk list
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioSampleToChunk.Num()));
|
||||
for(UINT i=0; i<audioSampleToChunk.Num(); i++)
|
||||
{
|
||||
SampleToChunk &stc = audioSampleToChunk[i];
|
||||
output.OutputDword(fastHtonl(stc.firstChunkID));
|
||||
output.OutputDword(fastHtonl(stc.samplesPerChunk));
|
||||
output.OutputDword(DWORD_BE(1));
|
||||
}
|
||||
PopBox(); //stsc
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 60, 0);
|
||||
ProcessEvents();
|
||||
|
||||
PushBox(output, DWORD_BE('stsz')); //sample sizes
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(0); //block size for all (0 if differing sizes)
|
||||
output.OutputDword(fastHtonl(audioFrames.Num()));
|
||||
for(UINT i=0; i<audioFrames.Num(); i++)
|
||||
output.OutputDword(fastHtonl(audioFrames[i].size));
|
||||
PopBox();
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 70, 0);
|
||||
ProcessEvents();
|
||||
|
||||
if(audioChunks.Num() && audioChunks.Last() > 0xFFFFFFFFLL)
|
||||
{
|
||||
PushBox(output, DWORD_BE('co64')); //chunk offsets
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioChunks.Num()));
|
||||
for(UINT i=0; i<audioChunks.Num(); i++)
|
||||
output.OutputQword(fastHtonll(audioChunks[i]));
|
||||
PopBox(); //co64
|
||||
}
|
||||
else
|
||||
{
|
||||
PushBox(output, DWORD_BE('stco')); //chunk offsets
|
||||
output.OutputDword(0); //version and flags (none)
|
||||
output.OutputDword(fastHtonl(audioChunks.Num()));
|
||||
for(UINT i=0; i<audioChunks.Num(); i++)
|
||||
output.OutputDword(fastHtonl((DWORD)audioChunks[i]));
|
||||
PopBox(); //stco
|
||||
}
|
||||
PopBox(); //stbl
|
||||
PopBox(); //minf
|
||||
PopBox(); //mdia
|
||||
PopBox(); //trak
|
||||
|
||||
SendMessage(GetDlgItem(hwndProgressDialog, IDC_PROGRESS1), PBM_SETPOS, 80, 0);
|
||||
ProcessEvents();
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ HINSTANCE hinstMain = NULL;
|
|||
ConfigFile *GlobalConfig = NULL;
|
||||
ConfigFile *AppConfig = NULL;
|
||||
OBS *App = NULL;
|
||||
TCHAR lpAppPath[MAX_PATH];
|
||||
TCHAR lpAppDataPath[MAX_PATH];
|
||||
|
||||
//----------------------------
|
||||
|
@ -435,6 +436,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
|||
strDirectory.SetLength(dirSize);
|
||||
GetCurrentDirectory(dirSize, strDirectory.Array());
|
||||
|
||||
scpy(lpAppPath, strDirectory);
|
||||
|
||||
GlobalConfig->SetString(TEXT("General"), TEXT("LastAppDirectory"), strDirectory.Array());
|
||||
|
||||
//--------------------------------------------
|
||||
|
|
|
@ -68,12 +68,13 @@ extern HINSTANCE hinstMain;
|
|||
extern ConfigFile *GlobalConfig;
|
||||
extern ConfigFile *AppConfig;
|
||||
extern OBS *App;
|
||||
extern TCHAR lpAppPath[MAX_PATH];
|
||||
extern TCHAR lpAppDataPath[MAX_PATH];
|
||||
|
||||
#define OBS_VERSION 0x000466
|
||||
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.466a"
|
||||
#define OBS_VERSION_STRING_ANSI "Open Broadcaster Software v0.467a (test 5)"
|
||||
#define OBS_VERSION_STRING TEXT(OBS_VERSION_STRING_ANSI)
|
||||
//#define OBS_TEST_BUILD 1 //define this if releasing a test build to disable the auto updater
|
||||
#define OBS_TEST_BUILD 1 //define this if releasing a test build to disable the auto updater
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define OBS_DISABLE_AUTOUPDATE 1
|
||||
|
|
687
Source/OBS.cpp
687
Source/OBS.cpp
File diff suppressed because it is too large
Load Diff
88
Source/OBS.h
88
Source/OBS.h
|
@ -27,7 +27,7 @@ static const int minClientWidth = 700;
|
|||
static const int minClientHeight = 200;
|
||||
|
||||
|
||||
#define OUTPUT_BUFFER_TIME 700
|
||||
#define OUTPUT_BUFFER_TIME 100
|
||||
|
||||
|
||||
struct AudioDeviceInfo
|
||||
|
@ -66,8 +66,14 @@ struct AudioDeviceList
|
|||
}
|
||||
};
|
||||
|
||||
void GetAudioDevices(AudioDeviceList &deviceList);
|
||||
enum AudioDeviceType {
|
||||
ADT_PLAYBACK,
|
||||
ADT_RECORDING
|
||||
};
|
||||
|
||||
void GetAudioDevices(AudioDeviceList &deviceList, AudioDeviceType deviceType);
|
||||
bool GetDefaultMicID(String &strVal);
|
||||
bool GetDefaultSpeakerID(String &strVal);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
@ -363,6 +369,9 @@ struct VideoSegment
|
|||
|
||||
//----------------------------
|
||||
|
||||
struct FrameProcessInfo;
|
||||
|
||||
//todo: this class has become way too big, it's horrible, and I should be ashamed of myself
|
||||
class OBS
|
||||
{
|
||||
friend class Scene;
|
||||
|
@ -392,17 +401,21 @@ class OBS
|
|||
Shader *solidVertexShader, *solidPixelShader;
|
||||
|
||||
//---------------------------------------------------
|
||||
// network
|
||||
|
||||
NetworkStream *network;
|
||||
|
||||
//---------------------------------------------------
|
||||
// audio
|
||||
// audio sources/encoder
|
||||
|
||||
AudioSource *desktopAudio;
|
||||
AudioSource *micAudio;
|
||||
List<AudioSource*> auxAudioSources;
|
||||
|
||||
AudioEncoder *audioEncoder;
|
||||
|
||||
//---------------------------------------------------
|
||||
// video
|
||||
// scene/encoder
|
||||
|
||||
Scene *scene;
|
||||
VideoEncoder *videoEncoder;
|
||||
HDC hCaptureDC;
|
||||
|
@ -430,6 +443,7 @@ class OBS
|
|||
|
||||
//---------------------------------------------------
|
||||
// settings window
|
||||
|
||||
int curSettingsSelection;
|
||||
HWND hwndSettings;
|
||||
HWND hwndCurrentSettings;
|
||||
|
@ -452,6 +466,7 @@ class OBS
|
|||
static INT_PTR CALLBACK AdvancedSettingsProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
//---------------------------------------------------
|
||||
// mainly manly main window stuff
|
||||
|
||||
String strLanguage;
|
||||
bool bTestStream;
|
||||
|
@ -485,6 +500,7 @@ class OBS
|
|||
bool bSSE2Available;
|
||||
|
||||
//---------------------------------------------------
|
||||
// resolution/fps/downscale/etc settings
|
||||
|
||||
int lastRenderTarget;
|
||||
UINT baseCX, baseCY;
|
||||
|
@ -492,34 +508,52 @@ class OBS
|
|||
UINT outputCX, outputCY;
|
||||
float downscale;
|
||||
UINT frameTime, fps;
|
||||
HANDLE hMainThread;
|
||||
HANDLE hSceneMutex;
|
||||
bool bUsing444;
|
||||
|
||||
//---------------------------------------------------
|
||||
// stats
|
||||
|
||||
int ctsOffset;
|
||||
DWORD bytesPerSec;
|
||||
DWORD captureFPS;
|
||||
DWORD curFramesDropped;
|
||||
DWORD totalStreamTime;
|
||||
double curStrain;
|
||||
|
||||
//---------------------------------------------------
|
||||
// main capture loop stuff
|
||||
|
||||
HANDLE hMainThread;
|
||||
HANDLE hSceneMutex;
|
||||
|
||||
List<VideoSegment> bufferedVideo;
|
||||
bool BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, VideoSegment &segmentOut);
|
||||
|
||||
DWORD totalStreamTime;
|
||||
int curPTS;
|
||||
List<UINT> bufferedTimes;
|
||||
|
||||
bool bUseSyncFix;
|
||||
List<UINT> bufferedTimes;
|
||||
bool bRecievedFirstAudioFrame, bSentHeaders, bFirstAudioPacket;
|
||||
|
||||
bool bRecievedFirstAudioFrame;
|
||||
DWORD lastAudioTimestamp;
|
||||
|
||||
QWORD firstSceneTimestamp;
|
||||
QWORD latestVideoTime;
|
||||
|
||||
bool bUseCFR;
|
||||
|
||||
bool bWriteToFile;
|
||||
VideoFileStream *fileStream;
|
||||
|
||||
static DWORD STDCALL MainCaptureThread(LPVOID lpUnused);
|
||||
bool BufferVideoData(const List<DataPacket> &inputPackets, const List<PacketType> &inputTypes, DWORD timestamp, VideoSegment &segmentOut);
|
||||
bool ProcessFrame(FrameProcessInfo &frameInfo);
|
||||
void MainCaptureLoop();
|
||||
|
||||
//---------------------------------------------------
|
||||
// main audio capture loop stuff
|
||||
|
||||
HANDLE hSoundThread, hSoundDataMutex, hRequestAudioEvent;
|
||||
QWORD latestAudioTime;
|
||||
|
||||
float desktopVol, micVol, curMicVol;
|
||||
float desktopPeak, micPeak;
|
||||
float desktopMax, micMax;
|
||||
|
@ -529,9 +563,9 @@ class OBS
|
|||
float micBoost;
|
||||
|
||||
HANDLE hAuxAudioMutex;
|
||||
List<AudioSource*> auxAudioSources;
|
||||
|
||||
//---------------------------------------------------
|
||||
// hotkey stuff
|
||||
|
||||
HANDLE hHotkeyMutex;
|
||||
HANDLE hHotkeyThread;
|
||||
|
@ -547,12 +581,12 @@ class OBS
|
|||
|
||||
bool bStartStreamHotkeyDown, bStopStreamHotkeyDown;
|
||||
|
||||
//---------------------------------------------------
|
||||
|
||||
bool bWriteToFile;
|
||||
VideoFileStream *fileStream;
|
||||
static DWORD STDCALL MainAudioThread(LPVOID lpUnused);
|
||||
bool QueryNewAudio(QWORD ×tamp);
|
||||
void MainAudioLoop();
|
||||
|
||||
//---------------------------------------------------
|
||||
// random bla-haa
|
||||
|
||||
String streamReport;
|
||||
|
||||
|
@ -633,13 +667,6 @@ class OBS
|
|||
void Start();
|
||||
void Stop();
|
||||
|
||||
void MainCaptureLoop();
|
||||
static DWORD STDCALL MainCaptureThread(LPVOID lpUnused);
|
||||
|
||||
bool QueryNewAudio(QWORD ×tamp);
|
||||
void MainAudioLoop();
|
||||
static DWORD STDCALL MainAudioThread(LPVOID lpUnused);
|
||||
|
||||
static void STDCALL StartStreamHotkey(DWORD hotkey, UPARAM param, bool bDown);
|
||||
static void STDCALL StopStreamHotkey(DWORD hotkey, UPARAM param, bool bDown);
|
||||
|
||||
|
@ -710,6 +737,7 @@ public:
|
|||
}
|
||||
|
||||
inline QWORD GetAudioTime() const {return latestAudioTime;}
|
||||
inline QWORD GetVideoTime() const {return latestVideoTime;}
|
||||
|
||||
char* EncMetaData(char *enc, char *pend, bool bFLVFile=false);
|
||||
|
||||
|
@ -776,17 +804,5 @@ public:
|
|||
virtual void AddSourceItem(LPWSTR name, bool checked, UINT index);
|
||||
};
|
||||
|
||||
inline QWORD GetQPCTimeMS(LONGLONG clockFreq)
|
||||
{
|
||||
LARGE_INTEGER currentTime;
|
||||
QueryPerformanceCounter(¤tTime);
|
||||
|
||||
QWORD timeVal = 1000 * currentTime.QuadPart / clockFreq;
|
||||
|
||||
return timeVal;
|
||||
}
|
||||
|
||||
ID3D10Blob* CompileShader(CTSTR lpShader, LPCSTR lpTarget);
|
||||
|
||||
LONG CALLBACK OBSExceptionHandler (PEXCEPTION_POINTERS exceptionInfo);
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/********************************************************************************
|
||||
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#include "Main.h"
|
|
@ -0,0 +1,22 @@
|
|||
/********************************************************************************
|
||||
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#include "Main.h"
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/********************************************************************************
|
||||
Copyright (C) 2012 Hugh Bailey <obs.jim@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
#include "Main.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ RTMPPublisher::RTMPPublisher()
|
|||
dropThreshold += bufferTime;
|
||||
|
||||
latencyFactor = AppConfig->GetInt(TEXT("Publish"), TEXT("LatencyFactor"), 20);
|
||||
|
||||
|
||||
if (latencyFactor < 3)
|
||||
latencyFactor = 3;
|
||||
|
||||
|
@ -434,9 +434,24 @@ DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
|
|||
String strURL = AppConfig->GetString(TEXT("Publish"), TEXT("URL"));
|
||||
String strPlayPath = AppConfig->GetString(TEXT("Publish"), TEXT("PlayPath"));
|
||||
|
||||
strURL.KillSpaces();
|
||||
strPlayPath.KillSpaces();
|
||||
|
||||
LPSTR lpAnsiURL = NULL, lpAnsiPlaypath = NULL;
|
||||
RTMP *rtmp = NULL;
|
||||
|
||||
//--------------------------------
|
||||
// unbelievably disgusting hack for elgato devices
|
||||
|
||||
String strOldDirectory;
|
||||
UINT dirSize = GetCurrentDirectory(0, 0);
|
||||
strOldDirectory.SetLength(dirSize);
|
||||
GetCurrentDirectory(dirSize, strOldDirectory.Array());
|
||||
|
||||
OSSetCurrentDirectory(API->GetAppPath());
|
||||
|
||||
//--------------------------------
|
||||
|
||||
if(!strURL.IsValid())
|
||||
{
|
||||
failReason = TEXT("No server specified to connect to");
|
||||
|
@ -483,6 +498,11 @@ DWORD WINAPI RTMPPublisher::CreateConnectionThread(RTMPPublisher *publisher)
|
|||
Log(TEXT(" Server selection: %s"), strURL.Array());
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// now back to the elgato directory if it needs the directory changed still to function *sigh*
|
||||
|
||||
OSSetCurrentDirectory(strOldDirectory);
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
rtmp = RTMP_Alloc();
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#include <Winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
struct AudioDeviceStorage {
|
||||
AudioDeviceList *playbackDevices;
|
||||
AudioDeviceList *recordingDevices;
|
||||
};
|
||||
|
||||
enum SettingsSelection
|
||||
{
|
||||
Settings_General,
|
||||
|
@ -645,6 +650,13 @@ INT_PTR CALLBACK OBS::PublishSettingsProc(HWND hwnd, UINT message, WPARAM wParam
|
|||
|
||||
//--------------------------------------------
|
||||
|
||||
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);
|
||||
|
@ -682,6 +694,7 @@ INT_PTR CALLBACK OBS::PublishSettingsProc(HWND hwnd, UINT message, WPARAM wParam
|
|||
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);
|
||||
|
@ -823,6 +836,7 @@ INT_PTR CALLBACK OBS::PublishSettingsProc(HWND hwnd, UINT message, WPARAM wParam
|
|||
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);
|
||||
|
@ -977,6 +991,11 @@ INT_PTR CALLBACK OBS::PublishSettingsProc(HWND hwnd, UINT message, WPARAM wParam
|
|||
break;
|
||||
}
|
||||
|
||||
case IDC_LOWLATENCYMODE:
|
||||
if(HIWORD(wParam) == BN_CLICKED)
|
||||
bDataChanged = true;
|
||||
break;
|
||||
|
||||
case IDC_STARTSTREAMHOTKEY:
|
||||
case IDC_STOPSTREAMHOTKEY:
|
||||
case IDC_DASHBOARDLINK:
|
||||
|
@ -1362,36 +1381,62 @@ INT_PTR CALLBACK OBS::AudioSettingsProc(HWND hwnd, UINT message, WPARAM wParam,
|
|||
|
||||
//--------------------------------------------
|
||||
|
||||
AudioDeviceList *audioDevices = new AudioDeviceList;
|
||||
GetAudioDevices(*audioDevices);
|
||||
AudioDeviceStorage *storage = new AudioDeviceStorage;
|
||||
|
||||
storage->playbackDevices = new AudioDeviceList;
|
||||
GetAudioDevices((*storage->playbackDevices), ADT_PLAYBACK);
|
||||
|
||||
storage->recordingDevices = new AudioDeviceList;
|
||||
GetAudioDevices((*storage->recordingDevices), ADT_RECORDING);
|
||||
|
||||
HWND hwndTemp = GetDlgItem(hwnd, IDC_MICDEVICES);
|
||||
HWND hwndPlayback = GetDlgItem(hwnd, IDC_PLAYBACKDEVICES);
|
||||
|
||||
for(UINT i=0; i<audioDevices->devices.Num(); i++)
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)audioDevices->devices[i].strName.Array());
|
||||
for(UINT i=0; i<storage->playbackDevices->devices.Num(); i++)
|
||||
SendMessage(hwndPlayback, CB_ADDSTRING, 0, (LPARAM)storage->playbackDevices->devices[i].strName.Array());
|
||||
|
||||
String strDeviceID = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), audioDevices->devices[0].strID);
|
||||
for(UINT i=0; i<storage->recordingDevices->devices.Num(); i++)
|
||||
SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)storage->recordingDevices->devices[i].strName.Array());
|
||||
|
||||
String strPlaybackID = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), storage->playbackDevices->devices[0].strID);
|
||||
String strDeviceID = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), storage->recordingDevices->devices[0].strID);
|
||||
|
||||
UINT iPlaybackDevice;
|
||||
for(iPlaybackDevice=0; iPlaybackDevice<storage->playbackDevices->devices.Num(); iPlaybackDevice++)
|
||||
{
|
||||
if(storage->playbackDevices->devices[iPlaybackDevice].strID == strPlaybackID)
|
||||
{
|
||||
SendMessage(hwndPlayback, CB_SETCURSEL, iPlaybackDevice, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT iDevice;
|
||||
for(iDevice=0; iDevice<audioDevices->devices.Num(); iDevice++)
|
||||
for(iDevice=0; iDevice<storage->recordingDevices->devices.Num(); iDevice++)
|
||||
{
|
||||
if(audioDevices->devices[iDevice].strID == strDeviceID)
|
||||
if(storage->recordingDevices->devices[iDevice].strID == strDeviceID)
|
||||
{
|
||||
SendMessage(hwndTemp, CB_SETCURSEL, iDevice, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(iDevice == audioDevices->devices.Num())
|
||||
if(iPlaybackDevice == storage->playbackDevices->devices.Num())
|
||||
{
|
||||
AppConfig->SetString(TEXT("Audio"), TEXT("Device"), audioDevices->devices[0].strID);
|
||||
AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), storage->playbackDevices->devices[0].strID);
|
||||
SendMessage(hwndPlayback, CB_SETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
if(iDevice == storage->recordingDevices->devices.Num())
|
||||
{
|
||||
AppConfig->SetString(TEXT("Audio"), TEXT("Device"), storage->recordingDevices->devices[0].strID);
|
||||
SendMessage(hwndTemp, CB_SETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)audioDevices);
|
||||
|
||||
//--------------------------------------------
|
||||
|
||||
SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)storage);
|
||||
|
||||
BOOL bPushToTalk = AppConfig->GetInt(TEXT("Audio"), TEXT("UsePushToTalk"));
|
||||
SendMessage(GetDlgItem(hwnd, IDC_PUSHTOTALK), BM_SETCHECK, bPushToTalk ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
EnableWindow(GetDlgItem(hwnd, IDC_PUSHTOTALKHOTKEY), bPushToTalk);
|
||||
|
@ -1434,12 +1479,12 @@ INT_PTR CALLBACK OBS::AudioSettingsProc(HWND hwnd, UINT message, WPARAM wParam,
|
|||
//--------------------------------------------
|
||||
|
||||
int micTimeOffset = AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0);
|
||||
if(micTimeOffset < -500)
|
||||
micTimeOffset = -500;
|
||||
if(micTimeOffset < -50)
|
||||
micTimeOffset = -50;
|
||||
else if(micTimeOffset > 3000)
|
||||
micTimeOffset = 3000;
|
||||
|
||||
SendMessage(GetDlgItem(hwnd, IDC_MICTIMEOFFSET), UDM_SETRANGE32, -500, 3000);
|
||||
SendMessage(GetDlgItem(hwnd, IDC_MICTIMEOFFSET), UDM_SETRANGE32, -50, 3000);
|
||||
SendMessage(GetDlgItem(hwnd, IDC_MICTIMEOFFSET), UDM_SETPOS32, 0, micTimeOffset);
|
||||
|
||||
//--------------------------------------------
|
||||
|
@ -1450,8 +1495,10 @@ INT_PTR CALLBACK OBS::AudioSettingsProc(HWND hwnd, UINT message, WPARAM wParam,
|
|||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
AudioDeviceList *audioDevices = (AudioDeviceList*)GetWindowLongPtr(hwnd, DWLP_USER);
|
||||
delete audioDevices;
|
||||
AudioDeviceStorage* storage = (AudioDeviceStorage*)GetWindowLongPtr(hwnd, DWLP_USER);
|
||||
delete storage->recordingDevices;
|
||||
delete storage->playbackDevices;
|
||||
delete storage;
|
||||
}
|
||||
|
||||
case WM_COMMAND:
|
||||
|
@ -1515,6 +1562,11 @@ INT_PTR CALLBACK OBS::AudioSettingsProc(HWND hwnd, UINT message, WPARAM wParam,
|
|||
if(HIWORD(wParam) == CBN_SELCHANGE)
|
||||
bDataChanged = true;
|
||||
break;
|
||||
|
||||
case IDC_PLAYBACKDEVICES:
|
||||
if(HIWORD(wParam) == CBN_SELCHANGE)
|
||||
bDataChanged = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(bDataChanged)
|
||||
|
@ -1578,6 +1630,9 @@ INT_PTR CALLBACK OBS::AdvancedSettingsProc(HWND hwnd, UINT message, WPARAM wPara
|
|||
|
||||
//------------------------------------
|
||||
|
||||
bool bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 0) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_USECFR), BM_SETCHECK, bUseCFR ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
bool bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_USECBR), BM_SETCHECK, bUseCBR ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
|
@ -1600,25 +1655,11 @@ INT_PTR CALLBACK OBS::AdvancedSettingsProc(HWND hwnd, UINT message, WPARAM wPara
|
|||
|
||||
//------------------------------------
|
||||
|
||||
bool bUseVideoSyncFix = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseSyncFix")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_USESYNCFIX), BM_SETCHECK, bUseVideoSyncFix ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
ti.lpszText = (LPWSTR)Str("Settings.Advanced.UseSyncFixTooltip");
|
||||
ti.uId = (UINT_PTR)GetDlgItem(hwnd, IDC_USESYNCFIX);
|
||||
SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
bool bUnlockFPS = AppConfig->GetInt(TEXT("Video"), TEXT("UnlockFPS")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_UNLOCKHIGHFPS), BM_SETCHECK, bUnlockFPS ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
bool bDisableCTSAdjust = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("DisableCTSAdjust")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_DISABLECTSADJUST), BM_SETCHECK, bDisableCTSAdjust ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
/*bool bDisableD3DCompat = AppConfig->GetInt(TEXT("Video"), TEXT("DisableD3DCompatibilityMode")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_DISABLED3DCOMPATIBILITY), BM_SETCHECK, bDisableD3DCompat ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
|
@ -1637,6 +1678,11 @@ INT_PTR CALLBACK OBS::AdvancedSettingsProc(HWND hwnd, UINT message, WPARAM wPara
|
|||
|
||||
//------------------------------------
|
||||
|
||||
bool bSyncToVideoTime = AppConfig->GetInt(TEXT("Audio"), TEXT("SyncToVideoTime")) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_SYNCTOVIDEOTIME), BM_SETCHECK, bSyncToVideoTime ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
BOOL bUseSendBuffer = AppConfig->GetInt(TEXT("Publish"), TEXT("UseSendBuffer"), 0) != 0;
|
||||
SendMessage(GetDlgItem(hwnd, IDC_USESENDBUFFER), BM_SETCHECK, bUseSendBuffer ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
|
||||
|
@ -1781,24 +1827,11 @@ INT_PTR CALLBACK OBS::AdvancedSettingsProc(HWND hwnd, UINT message, WPARAM wPara
|
|||
}
|
||||
break;
|
||||
|
||||
case IDC_SYNCTOVIDEOTIME:
|
||||
case IDC_USECBR:
|
||||
if(HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
String strText;
|
||||
strText << Str("Settings.Advanced.UseCBR");
|
||||
if(SendMessage((HWND)lParam, BM_GETCHECK, 0, 0) == BST_CHECKED)
|
||||
strText << TEXT(" (..I hope you know what you're doing)");
|
||||
|
||||
SetWindowText((HWND)lParam, strText.Array());
|
||||
ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW);
|
||||
App->SetChangedSettings(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDC_DISABLECTSADJUST:
|
||||
case IDC_USECFR:
|
||||
case IDC_USEHIGHQUALITYRESAMPLING:
|
||||
case IDC_USEMULTITHREADEDOPTIMIZATIONS:
|
||||
case IDC_USESYNCFIX:
|
||||
case IDC_UNLOCKHIGHFPS:
|
||||
if(HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
|
@ -1872,6 +1905,11 @@ void OBS::ApplySettings()
|
|||
|
||||
//------------------------------------------
|
||||
|
||||
bool bLowLatencyMode = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_LOWLATENCYMODE), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt(TEXT("Publish"), TEXT("LowLatencyMode"), bLowLatencyMode);
|
||||
|
||||
//------------------------------------------
|
||||
|
||||
App->bAutoReconnect = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_AUTORECONNECT), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
|
||||
BOOL bError = FALSE;
|
||||
|
@ -1972,18 +2010,32 @@ void OBS::ApplySettings()
|
|||
|
||||
case Settings_Audio:
|
||||
{
|
||||
AudioDeviceList *audioDevices = (AudioDeviceList*)GetWindowLongPtr(hwndCurrentSettings, DWLP_USER);
|
||||
AudioDeviceStorage *storage = (AudioDeviceStorage*)GetWindowLongPtr(hwndCurrentSettings, DWLP_USER);
|
||||
UINT iPlaybackDevice = (UINT)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_PLAYBACKDEVICES), CB_GETCURSEL, 0, 0);
|
||||
String strPlaybackDevice;
|
||||
|
||||
if(iPlaybackDevice == CB_ERR) {
|
||||
strPlaybackDevice = TEXT("Default");
|
||||
}
|
||||
else {
|
||||
strPlaybackDevice = storage->playbackDevices->devices[iPlaybackDevice].strID;
|
||||
}
|
||||
|
||||
AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), strPlaybackDevice);
|
||||
|
||||
UINT iDevice = (UINT)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_MICDEVICES), CB_GETCURSEL, 0, 0);
|
||||
|
||||
String strDevice;
|
||||
|
||||
if(iDevice == CB_ERR)
|
||||
strDevice = TEXT("Disable");
|
||||
else
|
||||
strDevice = audioDevices->devices[iDevice].strID;
|
||||
strDevice = storage->recordingDevices->devices[iDevice].strID;
|
||||
|
||||
|
||||
AppConfig->SetString(TEXT("Audio"), TEXT("Device"), strDevice);
|
||||
|
||||
|
||||
if(strDevice.CompareI(TEXT("Disable")))
|
||||
EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE);
|
||||
else
|
||||
|
@ -2059,8 +2111,8 @@ void OBS::ApplySettings()
|
|||
//------------------------------------
|
||||
|
||||
int micTimeOffset = (int)SendMessage(GetDlgItem(hwndCurrentSettings, IDC_MICTIMEOFFSET), UDM_GETPOS32, 0, 0);
|
||||
if(micTimeOffset < -500)
|
||||
micTimeOffset = -500;
|
||||
if(micTimeOffset < -50)
|
||||
micTimeOffset = -50;
|
||||
else if(micTimeOffset > 3000)
|
||||
micTimeOffset = 3000;
|
||||
AppConfig->SetInt(TEXT("Audio"), TEXT("MicTimeOffset"), micTimeOffset);
|
||||
|
@ -2086,6 +2138,11 @@ void OBS::ApplySettings()
|
|||
|
||||
//--------------------------------------------------
|
||||
|
||||
bool bUseCFR = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_USECFR), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video Encoding"), TEXT("UseCFR"), bUseCFR);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
bool bUseCBR = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_USECBR), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video Encoding"), TEXT("UseCBR"), bUseCBR);
|
||||
|
||||
|
@ -2099,26 +2156,21 @@ void OBS::ApplySettings()
|
|||
|
||||
//--------------------------------------------------
|
||||
|
||||
BOOL bUseVideoSyncFix = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_USESYNCFIX), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video Encoding"), TEXT("UseSyncFix"), bUseVideoSyncFix);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
BOOL bUnlockFPS = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_UNLOCKHIGHFPS), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video"), TEXT("UnlockFPS"), bUnlockFPS);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
BOOL bDisableCTSAdjust = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_DISABLECTSADJUST), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video Encoding"), TEXT("DisableCTSAdjust"), bDisableCTSAdjust);
|
||||
|
||||
//------------------------------------
|
||||
|
||||
BOOL bUseHQResampling = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_USEHIGHQUALITYRESAMPLING), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Audio"), TEXT("UseHighQualityResampling"), bUseHQResampling);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
BOOL bSyncToVideoTime = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_SYNCTOVIDEOTIME), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Audio"), TEXT("SyncToVideoTime"), bSyncToVideoTime);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/*BOOL bDisableD3DCompat = SendMessage(GetDlgItem(hwndCurrentSettings, IDC_DISABLED3DCOMPATIBILITY), BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||
AppConfig->SetInt (TEXT("Video"), TEXT("DisableD3DCompatibilityMode"), bDisableD3DCompat);*/
|
||||
|
||||
|
|
|
@ -293,10 +293,11 @@ LRESULT CALLBACK OBS::ListboxHook(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
if(!App->sceneElement)
|
||||
return 0;
|
||||
|
||||
HMENU hmenuAdd = CreatePopupMenu();
|
||||
|
||||
for(UINT i=0; i<App->imageSourceClasses.Num(); i++)
|
||||
{
|
||||
String strAdd = Str("Listbox.Add");
|
||||
strAdd.FindReplace(TEXT("$1"), App->imageSourceClasses[i].strName);
|
||||
String strAdd = App->imageSourceClasses[i].strName;
|
||||
|
||||
if(App->imageSourceClasses[i].strClass == TEXT("GlobalSource"))
|
||||
{
|
||||
|
@ -311,12 +312,14 @@ LRESULT CALLBACK OBS::ListboxHook(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
for(UINT j=0; j<sourceNames.Num(); j++)
|
||||
AppendMenu(hmenuGlobals, MF_STRING, ID_LISTBOX_GLOBALSOURCE+j, sourceNames[j]);
|
||||
|
||||
AppendMenu(hMenu, MF_STRING|MF_POPUP, (UINT_PTR)hmenuGlobals, strAdd.Array());
|
||||
AppendMenu(hmenuAdd, MF_STRING|MF_POPUP, (UINT_PTR)hmenuGlobals, strAdd.Array());
|
||||
}
|
||||
else
|
||||
AppendMenu(hMenu, MF_STRING, ID_LISTBOX_ADD+i, strAdd.Array());
|
||||
AppendMenu(hmenuAdd, MF_STRING, ID_LISTBOX_ADD+i, strAdd.Array());
|
||||
}
|
||||
|
||||
AppendMenu(hMenu, MF_STRING|MF_POPUP, (UINT_PTR)hmenuAdd, Str("Add"));
|
||||
|
||||
bSelected = ListView_GetSelectedCount(hwnd) != 0;
|
||||
}
|
||||
|
||||
|
@ -328,6 +331,7 @@ LRESULT CALLBACK OBS::ListboxHook(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
String strMoveDown = Str("MoveDown");
|
||||
String strMoveTop = Str("MoveToTop");
|
||||
String strMoveToBottom = Str("MoveToBottom");
|
||||
String strPositionSize = Str("Listbox.Positioning");
|
||||
String strCenter = Str("Listbox.Center");
|
||||
String strFitToScreen = Str("Listbox.FitToScreen");
|
||||
String strResize = Str("Listbox.ResetSize");
|
||||
|
@ -369,9 +373,13 @@ LRESULT CALLBACK OBS::ListboxHook(HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
if(id == ID_SOURCES)
|
||||
{
|
||||
AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
|
||||
AppendMenu(hMenu, MF_STRING, ID_LISTBOX_CENTER, strCenter);
|
||||
AppendMenu(hMenu, MF_STRING, ID_LISTBOX_FITTOSCREEN, strFitToScreen);
|
||||
AppendMenu(hMenu, MF_STRING, ID_LISTBOX_RESETSIZE, strResize);
|
||||
|
||||
HMENU hmenuPositioning = CreatePopupMenu();
|
||||
AppendMenu(hmenuPositioning, MF_STRING, ID_LISTBOX_CENTER, strCenter);
|
||||
AppendMenu(hmenuPositioning, MF_STRING, ID_LISTBOX_FITTOSCREEN, strFitToScreen);
|
||||
AppendMenu(hmenuPositioning, MF_STRING, ID_LISTBOX_RESETSIZE, strResize);
|
||||
|
||||
AppendMenu(hMenu, MF_STRING|MF_POPUP, (UINT_PTR)hmenuPositioning, strPositionSize.Array());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2014,6 +2022,7 @@ LRESULT CALLBACK OBS::OBSProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
|
|||
RECT client;
|
||||
GetClientRect(hwnd, &client);
|
||||
|
||||
//todo: bSizeChanging = false never gets set because this never gets called when maximizing
|
||||
App->ResizeWindow(true);
|
||||
App->bSizeChanging = false;
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@
|
|||
#define IDC_USEMULTITHREADEDOPTIMIZATIONS 1099
|
||||
#define IDC_CAPTURELAYERED 1099
|
||||
#define IDC_USEOUTLINE 1099
|
||||
#define IDC_LOWLATENCYMODE 1099
|
||||
#define IDC_TIMER1 1100
|
||||
#define IDC_PROGRESS1 1101
|
||||
#define IDC_DASHBOARDLINK_STATIC 1102
|
||||
|
@ -185,6 +186,8 @@
|
|||
#define IDC_USEHIGHQUALITYRESAMPLING 1105
|
||||
#define IDC_OUTLINECOLOR 1105
|
||||
#define IDC_USETEXT 1106
|
||||
#define IDC_USEVIDEOSYNC 1106
|
||||
#define IDC_SYNCTOVIDEOTIME 1106
|
||||
#define IDC_USEFILE 1107
|
||||
#define IDC_FILE 1108
|
||||
#define IDC_FONT 1112
|
||||
|
@ -209,6 +212,9 @@
|
|||
#define IDC_USECBR 1133
|
||||
#define IDC_COMBO1 1139
|
||||
#define IDC_DISABLECTSADJUST 1140
|
||||
#define IDC_USECFR 1141
|
||||
#define IDC_PLAYBACKDEVICES 1142
|
||||
|
||||
#define IDA_SOURCE_MOVEUP 40018
|
||||
#define IDA_SOURCE_MOVEDOWN 40019
|
||||
#define IDA_SOURCE_MOVETOTOP 40020
|
||||
|
@ -241,7 +247,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 141
|
||||
#define _APS_NEXT_COMMAND_VALUE 40046
|
||||
#define _APS_NEXT_CONTROL_VALUE 1141
|
||||
#define _APS_NEXT_CONTROL_VALUE 1143
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
Add "Tilføj"
|
||||
Apply "Apply"
|
||||
Browse "Gennemse"
|
||||
BuildingMP4Dialog "Bygger MP4"
|
||||
Cancel "Annullér"
|
||||
ClearHotkey "Ryd"
|
||||
Color "Farve"
|
||||
Default "Standard"
|
||||
DeleteConfirm "Er du sikker på at du ønsker at slette de valgte emner?"
|
||||
Desktop "Skrivebord"
|
||||
Disable "Deaktiver"
|
||||
EndingDelay "Afslutter Forsinket Stream..."
|
||||
EnterName "Skriv venligst et navn"
|
||||
GlobalSources "Globale Kilder"
|
||||
IncompatibleModules "Inkompatible hook moduler blev fundet i OBS processen. Vær venligst sikker på at OBS er tilføjet til ignoreringslisten af optageprogrammer så som DXTory, FRAPs, osv.\r\n\r\nEfter at have ændret ignoreringsinsdtillinger skal du måske genstarte OBS og alle hook-baserede optageprogrammer for at ændringerne tager effekt."
|
||||
MicrophoneFailure "En fejl opstod under initialiseringen af mikrofonlyden - den er måske ikke tilsluttet eller en anden applikation kan bruge den eksklusivt."
|
||||
MoveDown "Ryk Ned"
|
||||
MoveToBottom "Ryk til Bunden"
|
||||
MoveToTop "Ryk til Toppen"
|
||||
MoveUp "Ryk Op"
|
||||
NameExists "'$1' eksisterer allerede. Skriv venligst et andet navn"
|
||||
None "Ingen"
|
||||
OK "OK"
|
||||
Plugins "Plugins"
|
||||
Reconnecting "Reconnecter..."
|
||||
Remove "Fjern"
|
||||
Rename "Omdøb"
|
||||
Scene "Scene"
|
||||
Settings "Indstillinger"
|
||||
StreamReport "Stream Rapport"
|
||||
|
||||
BuildingMP4Dialog.Progress "Bygger MP4, vent venligst..."
|
||||
|
||||
Connection.CouldNotConnect "Kunne ikke forbinde til server"
|
||||
Connection.CouldNotParseURL "Kunne ikke parse RTMP URL"
|
||||
Connection.Disconnected "Forbindelse afbrudt af server"
|
||||
Connection.InvalidStream "Ugyldig stream kanal / stream nøgle"
|
||||
|
||||
DeleteConfirm.Title "Slet valgte emner?"
|
||||
|
||||
EndingDelay.TimeLeft "Tid Tilbage: $1"
|
||||
|
||||
GlobalSources.DeleteConfirm "Hvis du sletter en global kilde vil den blive fjernet fra alle scener der bruger den. Er du sikker på at du vil fortsætte?"
|
||||
|
||||
Listbox.Add "Tilføj $1"
|
||||
Listbox.Center "Centrér"
|
||||
Listbox.Config "Egenskaber"
|
||||
Listbox.FitToScreen "Tilpas til skærm"
|
||||
Listbox.ResetSize "Nulstil Størrelse"
|
||||
Listbox.SetHotkey "Sæt Hotkey"
|
||||
|
||||
MainMenu.File "&Fil"
|
||||
MainMenu.Help "&Hjælp"
|
||||
MainMenu.Settings "&Indstillinger"
|
||||
MainMenu.Settings.AlwaysOnTop "A<id Øverst"
|
||||
|
||||
MainMenu.File.Exit "&Afslut"
|
||||
|
||||
MainMenu.Help.Contents "I&ndhold"
|
||||
MainMenu.Help.VisitWebsite "Besøg Website"
|
||||
|
||||
MainMenu.Settings.OpenConfigFolder "Åben &Konfigurationsmappe"
|
||||
MainMenu.Settings.OpenLogFolder "Åben &Logmappe"
|
||||
|
||||
MainWindow.Dashboard "Instrumentbræt"
|
||||
MainWindow.DroppedFrames "Tabte Frames:"
|
||||
MainWindow.Exit "Afslut"
|
||||
MainWindow.Plugins "Plugins"
|
||||
MainWindow.SceneEditor "Rediger Scene"
|
||||
MainWindow.Scenes "Scener:"
|
||||
MainWindow.Sources "Kilder:"
|
||||
MainWindow.StartStream "Start Streaming"
|
||||
MainWindow.StopStream "Stop Streaming"
|
||||
MainWindow.StopTest "Stop Forhåndsvisning"
|
||||
MainWindow.TestStream "Forhåndsvis Stream"
|
||||
|
||||
Plugins.Configure "Konfigurer"
|
||||
Plugins.Description "Beskrivelse:"
|
||||
Plugins.Filename "Filnavn:"
|
||||
|
||||
Reconnecting.Retrying "Kunne ikke genetablere forbindelse. Prøver igen"
|
||||
|
||||
RenderView.EnableView "Aktiver Visning"
|
||||
|
||||
Scene.Hotkey "Scene Hotkey"
|
||||
Scene.MissingSources "Var ikke i stand til at indlæse alle billedkilder pga. ugyldige indstillinger eller manglende plugins"
|
||||
|
||||
Scene.Hotkey.AlreadyInUse "Denne hotkey er allerede i brug."
|
||||
Scene.Hotkey.Hotkey "Hotkey:"
|
||||
|
||||
Settings.Advanced "Avanceret"
|
||||
Settings.Audio "Lyd"
|
||||
Settings.Encoding "Encoding"
|
||||
Settings.General "Generelt"
|
||||
Settings.Info "Disse ændringer vil ikke træde i kraft før næste gang du begynder at streame."
|
||||
Settings.Publish "Broadcast Indstillinger"
|
||||
Settings.SaveChangesPrompt "Vil du gerne gemme og anvende dine ændringer?"
|
||||
Settings.SaveChangesTitle "Anvend indstillinger?"
|
||||
Settings.Video "Video"
|
||||
|
||||
Settings.Advanced.BindToIP "Bind til Interface:"
|
||||
Settings.Advanced.Network "Netværk"
|
||||
Settings.Advanced.PresetWarning "ADVARSEL! Ændring af x264 preset kan have alvorlig negativ effekt på dit streams kvalitet og CPU-forbrug.\r\n\r\nLad være med at ændre denne indstilling medmindre du fuldt ud forstå konsekvenserne af hvordan dette preset vil påvirke dit stream.\r\n\r\nEnhver guide der foreslår ændringer til dette bør du udvise forsigtig med. Du bør næsten aldrig have brug for at ændre denne indstilling fra standarden (veryfast).\r\n\r\nEr du sikker på du vil ændre dette preset?"
|
||||
Settings.Advanced.ProcessPriority "Processens Prioritetsklasse"
|
||||
Settings.Advanced.SendBufferSize "Send Buffer Størrelse:"
|
||||
Settings.Advanced.UnlockHigherFPS "Tillad 61-120 FPS indtastninger i video indstillinger"
|
||||
Settings.Advanced.UseCBR "Brug CBR"
|
||||
Settings.Advanced.UseHighQualityResampling "Brug Højkvalitets Resampling"
|
||||
Settings.Advanced.UseHighQualityResamplingTooltip "Når lyd subsystemet er tvunget til at resample, bruger det sinc interpolation i stedet for lineær interpolation til at resample lyden. Dette kræver en lille smule mere CPU."
|
||||
Settings.Advanced.UseMultithreadedOptimizations "Brug Multithreadede Optimeringer"
|
||||
Settings.Advanced.UseSendBuffer "Brug Send Buffer"
|
||||
Settings.Advanced.UseSendBufferTooltip "Send bufferen forårsager at al netværksdata bliver bufferet op til specifikke pakkestørrelser før afsendelse. Ved brug af denne indstilling forøges netværkskapaciteten i høj grad, men det gør også at streamet bliver en smule mere forsinket.\r\n\r\nAnbefalet: Til, ved et mulitplum af din maksimale segment størrelse (typisk 1460)"
|
||||
Settings.Advanced.UseSyncFix "Brug Video/Lyd Synkronisering Fix"
|
||||
Settings.Advanced.UseSyncFixTooltip "I sjældne tilfælde kan bestemte CPUer og bundkort have timing fejl der kan forårsage synkroniserings problemer på streamet. Dette fix udregninger tidsstempler i stedet for at bruge CPU timing. Det er rimelig præcist, men vær sikker på at sætte din maksimale FPS tæt på hvad du capturer ved for at forhindre potentielle rystelser i billedet."
|
||||
Settings.Advanced.VideoEncoderCPUTradeoff "x264 CPU Preset:"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "Ved at sætte denne værdi højere reduceres CPU forbruget ved at ofre visse aspekter af kvaliteten. På den anden siden opnåes der højere kvalitet på bekostning af mere CPU forbrug, hvis denne værdi sættes lavere.\r\n\r\nAnbefalet: Meget Hurtig"
|
||||
Settings.Advanced.VideoEncoderSettings "Brugerdefineret x264 Encoder Indstillinger"
|
||||
Settings.Advanced.VideoEncoderSettingsTooltip "Dette tillader at du kan sætte brugerdefinerede x264 encoder indstillinger. Dette gøres på formen [parameter]=[værdi] (fx \"vbv-maxrate=1000 vbv-bufsize=1000\")."
|
||||
|
||||
Settings.Audio.Device "Mikrofon/Auxiliary Lydenheder:"
|
||||
Settings.Audio.ForceMicMono "Tving Mikrofon/Auxiliary til Mono:"
|
||||
Settings.Audio.MicBoost "Mic/Aux Boost (multiple):"
|
||||
Settings.Audio.MicTimeOffset "Mic Tidsforskydning (millisekunder):"
|
||||
Settings.Audio.MuteDesktopHotkey "Mute/Unmute Skrivebords Hotkey:"
|
||||
Settings.Audio.MuteMicHotkey "Mute/Unmute Mic Hotkey:"
|
||||
Settings.Audio.PushToTalkDelay "Push-to-talk Forsinkelse (millisekunder):"
|
||||
Settings.Audio.PushToTalkHotkey "Brug Push-to-talk:"
|
||||
|
||||
Settings.Encoding.Audio "Lyd Encoding"
|
||||
Settings.Encoding.Video "Video Encoding"
|
||||
|
||||
Settings.Encoding.Audio.Bitrate "Bitrate:"
|
||||
Settings.Encoding.Audio.Codec "Codec:"
|
||||
Settings.Encoding.Audio.Format "Format:"
|
||||
|
||||
Settings.Encoding.Video.BufferSize "Buffer Størrelse (kbit):"
|
||||
Settings.Encoding.Video.BufferSizeTooltip "Buffer størrelsen bestemmer hvor meget data der skal bufferes. Denne værdi påvirker især scener med meget bevægelse. Hvis du ikke ved hvad du skal bruge, sæt den til det samme som din bitrate. Se hjælpefilen for mere information."
|
||||
Settings.Encoding.Video.MaxBitRate "Max Bitrate (kb/s):"
|
||||
Settings.Encoding.Video.MaxBitRateTooltip "Dette sætter den maksimale bitrate brugt til video. Venligst vær opmærksom på at selvom din gennemsnitlige bitrate vil være denne værdi, så er denne værdi baseret på din buffer størrelse. Du vil generelt ønske at have denne værdi lavere end din upload bitrate.\r\n\r\nBrug en side så som speedtest.net til at bestemme din upload bitrate."
|
||||
Settings.Encoding.Video.Quality "Kvalitetsbalance:"
|
||||
Settings.Encoding.Video.QualityTooltip "Denne indstilling vil forsøge at ramme en bestemt kvalitet afhængig af din bitrate og buffer størrelse. Ved at sætte denne indstilling til en høj værdi ved en lav bitrate vil den ofre kvaliteten af scener med meget bevægelse til fordel for scener med ingen bevægelse, hvilket vil forårsage inkonsistent kvalitet."
|
||||
|
||||
Settings.General.Add "Tilføj Ny"
|
||||
Settings.General.ConfirmDelete "Er du sikker på at du vil fjerne profilen '$1'?"
|
||||
Settings.General.InvalidName "Profilnavne kan ikke indholde de følgende karakterer:\r\n\\ / : * ? \" < > |"
|
||||
Settings.General.Language "Sprog:"
|
||||
Settings.General.Profile "Indstillingsprofil:"
|
||||
Settings.General.Restart "Skift af sprog vil kræve at du genstarter OBS.\r\n\r\n.. Dog gætter jeg på, at hvis du er ved at ændre sproget, så forstår du nok ikke dette."
|
||||
|
||||
Settings.Publish.AutoReconnect "Auto-Reconnect:"
|
||||
Settings.Publish.AutoReconnectTimeout "Auto-Reconnect Timeout:"
|
||||
Settings.Publish.ChannelName "Kanalnavn:"
|
||||
Settings.Publish.DashboardLink "Instrumentbrætslink (hvis noget):"
|
||||
Settings.Publish.Delay "Forsinkelse (sekunder):"
|
||||
Settings.Publish.Mode "Mode:"
|
||||
Settings.Publish.Password "Password (hvis noget):"
|
||||
Settings.Publish.Playpath "Afspilningssti/Stream Nøgle (hvis nogen):"
|
||||
Settings.Publish.SavePath "Filsti:"
|
||||
Settings.Publish.SaveToFile "Gem til fil:"
|
||||
Settings.Publish.Server "Server:"
|
||||
Settings.Publish.Service "Streaming Service:"
|
||||
Settings.Publish.StartStreamHotkey "Start Stream Hotkey:"
|
||||
Settings.Publish.StopStreamHotkey "Stop Stream Hotkey:"
|
||||
Settings.Publish.Username "Brugernavn (hvis noget):"
|
||||
|
||||
Settings.Publish.Mode.FileOnly "Kun Output til Fil"
|
||||
Settings.Publish.Mode.LiveStream "Live Stream"
|
||||
|
||||
Settings.Video.Custom "Brugerdefineret:"
|
||||
Settings.Video.DisableAero "Deaktiver Aero ved start af OBS:"
|
||||
Settings.Video.DisableAeroTooltip "Deaktivering af Aero er anbefalet hvis du bruger software skærm capture"
|
||||
Settings.Video.Downscale "Downscale Opløsning:"
|
||||
Settings.Video.DownscaleTooltip "Downscale kan forbedre videokvaliteten på bekostning af opløsningen."
|
||||
Settings.Video.FPS "FPS:"
|
||||
Settings.Video.Monitor "Skærm:"
|
||||
Settings.Video.Resolution "Basis Opløsning:"
|
||||
|
||||
Sources.BitmapSource "Billede"
|
||||
Sources.GameCaptureSource "Game Capture"
|
||||
Sources.GlobalSource "Global Kilde"
|
||||
Sources.SoftwareCaptureSource "Software Capture"
|
||||
Sources.TextSource "Tekst"
|
||||
Sources.TransitionSource "Billede Slide Show"
|
||||
|
||||
Sources.BitmapSource.Color "Farve:"
|
||||
Sources.BitmapSource.Empty "Intet bitmap indtastet. Gennemse venligst og vælg et bitmap"
|
||||
Sources.BitmapSource.Opacity "Uigennemsigtighed:"
|
||||
Sources.BitmapSource.Monitor "Tjek for ændringer:"
|
||||
|
||||
Sources.GameCaptureSource.Application "Application:"
|
||||
Sources.GameCaptureSource.IgnoreAspect "Ignorer formatforhold"
|
||||
Sources.GameCaptureSource.PluginDescription "Optager frames direkte fra spil og grafiske applikationer ved at hooke ind i applikationen og læse frames som de kommer."
|
||||
Sources.GameCaptureSource.PluginName "Game Capture Plugin"
|
||||
Sources.GameCaptureSource.Requires32bit "Disse applikationer kræver 32bit versionen af OBS for at optage:"
|
||||
Sources.GameCaptureSource.Requires64bit "Disse applikationer kræver 64bit versionen af OBS for at optage:"
|
||||
Sources.GameCaptureSource.RequiresAdmin "Disse applikationer kræver administrator rettigheder for at optage (start OBS som administrator for at optage):"
|
||||
Sources.GameCaptureSource.StretchToScreen "Stræk billede i forhold til skærm"
|
||||
|
||||
Sources.SoftwareCaptureSource.Blend "Bland (1-100):"
|
||||
Sources.SoftwareCaptureSource.CaptureLayered "Optag Lagdelte Vinduer"
|
||||
Sources.SoftwareCaptureSource.CaptureLayeredTip "Optag skinnede eller gennemsigtige / brugerdefineret lagdelte vinduer når Aero er deaktiveret. Kan forårsage flimren af musen når aktiveret. Aktiver kun hvis du ikke er i stand til at optage en specifik applikation."
|
||||
Sources.SoftwareCaptureSource.ColorKey "Farvenøgle"
|
||||
Sources.SoftwareCaptureSource.EntireWindow "Hele Vinduet"
|
||||
Sources.SoftwareCaptureSource.InnerWindow "Indre Vindue"
|
||||
Sources.SoftwareCaptureSource.InvertMouseOnClick "Vend markøren ved klik"
|
||||
Sources.SoftwareCaptureSource.Monitor "Skærm:"
|
||||
Sources.SoftwareCaptureSource.MonitorCapture "Skærm Capture"
|
||||
Sources.SoftwareCaptureSource.MonitorCaptureTooltip "Deaktiver aero i videoindstillingerne for at maksimere FPS"
|
||||
Sources.SoftwareCaptureSource.MouseCapture "Optag musen"
|
||||
Sources.SoftwareCaptureSource.Position "Position:"
|
||||
Sources.SoftwareCaptureSource.Refresh "Opdatér"
|
||||
Sources.SoftwareCaptureSource.RegionCapture "Under-Region"
|
||||
Sources.SoftwareCaptureSource.RegionWindowText "Tryk Enter, Esc eller klik uden for denne rektangel når du er færdig."
|
||||
Sources.SoftwareCaptureSource.Select "Vælg"
|
||||
Sources.SoftwareCaptureSource.SelectRegion "Vælg Region"
|
||||
Sources.SoftwareCaptureSource.SelectRegionTooltip "Når du vælger en region, flyt ved at klikke og trække, eller ændr størrelsen på rektanglet ved at klikke på kanterne."
|
||||
Sources.SoftwareCaptureSource.Similarity "Lighed (1-100):"
|
||||
Sources.SoftwareCaptureSource.Size "Størrelse:"
|
||||
Sources.SoftwareCaptureSource.SpillReduction "Reduktion af Spild:"
|
||||
Sources.SoftwareCaptureSource.UseColorKey "Brug Farvenøgle:"
|
||||
Sources.SoftwareCaptureSource.Window "Vindue:"
|
||||
Sources.SoftwareCaptureSource.WindowCapture "Vindue Capture"
|
||||
Sources.SoftwareCaptureSource.WindowCaptureTooltip "Aero kan være aktiveret hvis du kun bruge video capture. Billedet kan ikke opdatere så længe det er minimeret. Optagning er oftest meget hurtigere med denne metode end med skærm capture. Når aero er aktiveret, vil vinduer oven på ikke blive vist."
|
||||
Sources.SoftwareCaptureSource.WindowMinimized "Vindue er minimeret"
|
||||
Sources.SoftwareCaptureSource.WindowNotFound "Kan ikke finde vindue"
|
||||
|
||||
Sources.TextSource.Align "Juster:"
|
||||
Sources.TextSource.Bold "Fed"
|
||||
Sources.TextSource.Center "Center"
|
||||
Sources.TextSource.EnterText "Skriv Tekst"
|
||||
Sources.TextSource.FileNotFound "Kunne ikke åbne filen '$1'"
|
||||
Sources.TextSource.Font "Skrifttype:"
|
||||
Sources.TextSource.FontNotFound "Skrifttypen '$1' blev ikke fundet"
|
||||
Sources.TextSource.FontSize "Skriftstørrelse:"
|
||||
Sources.TextSource.Italic "Kursiv"
|
||||
Sources.TextSource.Left "Venstre"
|
||||
Sources.TextSource.Right "Højre"
|
||||
Sources.TextSource.ScrollSpeed "Scroll Hastighed:"
|
||||
Sources.TextSource.Size "Størrelse:"
|
||||
Sources.TextSource.Underline "Understregning"
|
||||
Sources.TextSource.UseCustomExtents "Brug Brugerdefinerede Tekstomfang"
|
||||
Sources.TextSource.UseOutline "Brug Kontur"
|
||||
Sources.TextSource.OutlineThickness "Tykkelse:"
|
||||
Sources.TextSource.UseTextExtents "Brug Brugerdefinerede Tekstomfang"
|
||||
Sources.TextSource.UseTextFromFile "Brug Tekst Fra Fil (UTF-8 eller kompatibel)"
|
||||
Sources.TextSource.VerticalScript "Vertikal"
|
||||
Sources.TextSource.Wrap "Ombryd"
|
||||
|
||||
Sources.TransitionSource.Bitmaps "Bitmaps:"
|
||||
Sources.TransitionSource.Empty "Der er ingen indtastede bitmaps at vise."
|
||||
Sources.TransitionSource.FadeInOnly "Kun Fade In:"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "Tid imellem billeder (sekunder):"
|
||||
|
||||
Updater.DownloadNow "Ønsker du at downloade dem nu?"
|
||||
Updater.NewUpdates "Følgende opdateringer er tilgængelige:\r\n\r\n"
|
||||
Updater.RunningWarning "OBS vil blive genstartet for at installere opdateringerne.\r\n\r\nEr du sikker på at du ønsker at fortsætte?"
|
||||
Updater.UpdatesAvailable "Opdateringer er tilgængelige"
|
|
@ -46,6 +46,7 @@ Listbox.Add "Add $1"
|
|||
Listbox.Center "Center"
|
||||
Listbox.Config "Properties"
|
||||
Listbox.FitToScreen "Fit to screen"
|
||||
Listbox.Positioning "Position/Size"
|
||||
Listbox.ResetSize "Reset Size"
|
||||
Listbox.SetHotkey "Set Hotkey"
|
||||
|
||||
|
@ -105,19 +106,21 @@ Settings.Advanced.ProcessPriority "Process Priority Class"
|
|||
Settings.Advanced.SendBufferSize "Send Buffer Size:"
|
||||
Settings.Advanced.UnlockHigherFPS "Allow 61-120 FPS entry in video settings"
|
||||
Settings.Advanced.UseCBR "Use CBR"
|
||||
Settings.Advanced.UseCFR "Use CFR"
|
||||
Settings.Advanced.UseHighQualityResampling "Use Higher Quality Resampling"
|
||||
Settings.Advanced.UseHighQualityResamplingTooltip "When the audio subsystem is forced to resample, uses sinc interpolation instead of linear interpolation to resample sound. Requires a little bit more CPU."
|
||||
Settings.Advanced.UseMultithreadedOptimizations "Use Multithreaded Optimizations"
|
||||
Settings.Advanced.UseSendBuffer "Use Send Buffer"
|
||||
Settings.Advanced.UseSendBufferTooltip "The send buffer causes all network data to be buffered up to specific packet sizes before sending. Using this greatly increases network throughput, but will make the stream a bit more delayed.\r\n\r\nRecommended: On, at a multiple of your maximum segment size (typically 1460)"
|
||||
Settings.Advanced.UseSyncFix "Use Video/Audio Sync Fix"
|
||||
Settings.Advanced.UseSyncFixTooltip "In rare cases, certain CPUs and motherboards can have timing bugs that can cause sync issues in the stream. This fix calculates timestamps instead of using CPU timing. It's pretty accurate, but just make sure to set your maximum FPS close to what you capture at to prevent any potential frame jitter."
|
||||
Settings.Advanced.SyncToVideoTime "Force audio to sync to video time"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoff "x264 CPU Preset:"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "Setting this value higher reduces CPU usage by sacrificing certain aspects of quality. On the other hand, setting this value lower increases quality at the cost of more CPU.\r\n\r\nRecommended: Very Fast"
|
||||
Settings.Advanced.VideoEncoderSettings "Custom x264 Encoder Settings"
|
||||
Settings.Advanced.VideoEncoderSettingsTooltip "This allows you to set custom x264 encoder settings. In the form of [parameter]=[value] (e.g. \"vbv-maxrate=1000 vbv-bufsize=1000\")."
|
||||
|
||||
Settings.Audio.PlaybackDevice "Playback Audio Device:"
|
||||
Settings.Audio.Device "Microphone/Auxiliary Audio Device:"
|
||||
|
||||
Settings.Audio.ForceMicMono "Force Microphone/Auxiliary to Mono:"
|
||||
Settings.Audio.MicBoost "Mic/Aux Boost (multiple):"
|
||||
Settings.Audio.MicTimeOffset "Mic Time Offset (milliseconds):"
|
||||
|
@ -152,6 +155,7 @@ Settings.Publish.AutoReconnectTimeout "Auto-Reconnect Timeout:"
|
|||
Settings.Publish.ChannelName "Channel Name:"
|
||||
Settings.Publish.DashboardLink "Dashboard Link (if any):"
|
||||
Settings.Publish.Delay "Delay (seconds):"
|
||||
Settings.Publish.LowLatencyMode "Low Latency mode:"
|
||||
Settings.Publish.Mode "Mode:"
|
||||
Settings.Publish.Password "Password (if any):"
|
||||
Settings.Publish.Playpath "Play Path/Stream Key (if any):"
|
||||
|
|
|
@ -47,6 +47,7 @@ Listbox.Add "Lisää $1"
|
|||
Listbox.Center "Keskitä"
|
||||
Listbox.Config "Ominaisuudet"
|
||||
Listbox.FitToScreen "Sovita ruudulle"
|
||||
Listbox.Positioning "Paikka/Koko"
|
||||
Listbox.ResetSize "Palauta koko"
|
||||
Listbox.SetHotkey "Pikanäppäin"
|
||||
|
||||
|
@ -119,6 +120,7 @@ Settings.Advanced.BindToIP "Liitä sovittimeen:"
|
|||
Settings.Audio.Device "Mikrofoni/muu -äänilaite:"
|
||||
Settings.Audio.ForceMicMono "Pakota mikrofoni yksikanavaiseksi:"
|
||||
Settings.Audio.MicBoost "Mikrofonin tehonlisäys (kerroin):"
|
||||
Settings.Audio.MicTimeOffset "Mikrofonin viive (millisekunteina):"
|
||||
Settings.Audio.MuteDesktopHotkey "Hiljennä työpöytä:"
|
||||
Settings.Audio.MuteMicHotkey "Hiljennä mikrofoni:"
|
||||
Settings.Audio.PushToTalkDelay "Push-to-talk viive (millisekunteina):"
|
||||
|
@ -243,4 +245,4 @@ Sources.TextSource.Wrap "Sido"
|
|||
Sources.TransitionSource.Bitmaps "Kuvakartat:"
|
||||
Sources.TransitionSource.Empty "Kuvakarttoja ei ole asetettu."
|
||||
Sources.TransitionSource.FadeInOnly "Lisää näkyvyyttä:"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "Aika kuvien valissä (sekunnit):"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "Aika kuvien valissä (sekunnit):"
|
||||
|
|
|
@ -0,0 +1,255 @@
|
|||
Add "Hozzáad"
|
||||
Apply "Alkalmaz"
|
||||
Browse "Tallózás"
|
||||
BuildingMP4Dialog "MP4 Építése"
|
||||
Cancel "Mégse"
|
||||
ClearHotkey "Törlés"
|
||||
Color "Szín"
|
||||
Default "Alapértelmezett"
|
||||
DeleteConfirm "Biztos vagy benne hogy törölni akarod a kijelőlt tételt?"
|
||||
Desktop "Asztal"
|
||||
Disable "Litiltás"
|
||||
EndingDelay "Késleltető Stream lekapcsolása..."
|
||||
EnterName "Írj be egy nevet"
|
||||
GlobalSources "Globális forrás"
|
||||
IncompatibleModules "Inkompatibilis becsatlakozó modult észlelt az OBS folyamat. Bozonyosodj meg arról hogy az OBS hozzá van adva a az olyan felvevő programok kizárások listájához mint DXTory, FRAPS etc.\r\n\r\nA kizárási listák beállításának módosítása után lehet hogy újra kell indítania a programokat, hogy a változtatások életbe lépjenek."
|
||||
MicrophoneFailure "Hiba történt a mikrofon hang inicializálásakor - lehet hogy nincs bedugva, vagy egy másik program exkluzív módban használja."
|
||||
MoveDown "Mozgatás le"
|
||||
MoveToBottom "Mozgatás az aljára"
|
||||
MoveToTop "Mozgatás a tetejére"
|
||||
MoveUp "Mozgatás fel"
|
||||
NameExists "'$1' már létezik. Kérlek próbálj egy másik nevet"
|
||||
None "Semmi"
|
||||
OK "OK"
|
||||
Plugins "Bővítmények"
|
||||
Reconnecting "Újracsatlakozás..."
|
||||
Remove "Töröl"
|
||||
Rename "Átnevez"
|
||||
Scene "Jelenet"
|
||||
Settings "Beállítások"
|
||||
StreamReport "Stream jelentés"
|
||||
|
||||
BuildingMP4Dialog.Progress "MP4 építése, kérlek várj..."
|
||||
|
||||
Connection.CouldNotConnect "Nem sikerült a szerverhez csatlakozni"
|
||||
Connection.CouldNotParseURL "Nem sikerült az RTMP URL lehívása"
|
||||
Connection.Disconnected "Szétkapcsolódva a szervertől"
|
||||
Connection.InvalidStream "Érvénytelen stream csatorna / stream kulcs"
|
||||
|
||||
DeleteConfirm.Title "Kijelőlt tételeket töröljük?"
|
||||
|
||||
EndingDelay.TimeLeft "Maradt idő: $1"
|
||||
|
||||
GlobalSources.DeleteConfirm "Ha törölsz egy globális forrást minden jelenetből törlődni fog amiben benne van. Biztos vagy benne hogy folytassuk?"
|
||||
|
||||
Listbox.Add "Hozzáad $1"
|
||||
Listbox.Center "Középre"
|
||||
Listbox.Config "Tulajdonságok"
|
||||
Listbox.FitToScreen "Képernyő nagyságú"
|
||||
Listbox.ResetSize "Méret visszaállítása"
|
||||
Listbox.SetHotkey "Gyorsbillentyű beállítása"
|
||||
|
||||
MainMenu.File "&Fájl"
|
||||
MainMenu.Help "&Segítség"
|
||||
MainMenu.Settings "&Beállítások"
|
||||
|
||||
MainMenu.File.Exit "&Kilépés"
|
||||
|
||||
MainMenu.Help.Contents "&Súgó"
|
||||
MainMenu.Help.VisitWebsite "Weboldal meglátogatása"
|
||||
|
||||
MainMenu.Settings.OpenConfigFolder "B&eállítási Mappa Megnyitása"
|
||||
MainMenu.Settings.OpenLogFolder "&Naplózó Mappa Megnyitása"
|
||||
|
||||
MainWindow.Dashboard "Műszerfal"
|
||||
MainWindow.DroppedFrames "Ejtett Képkockák:"
|
||||
MainWindow.Exit "Kilépés"
|
||||
MainWindow.Plugins "Bővítmények"
|
||||
MainWindow.SceneEditor "Jelenet Módosítása"
|
||||
MainWindow.Scenes "Jelenetek:"
|
||||
MainWindow.Sources "Források:"
|
||||
MainWindow.StartStream "Stream indítása"
|
||||
MainWindow.StopStream "Stream leállítása"
|
||||
MainWindow.StopTest "Előnézet leállítása"
|
||||
MainWindow.TestStream "Stream Előnézet"
|
||||
|
||||
Plugins.Configure "Beállít"
|
||||
Plugins.Description "Leírás:"
|
||||
Plugins.Filename "Fájl név:"
|
||||
|
||||
Reconnecting.Retrying "Sikertelen újracsatlakozás. Újra próbálkozás"
|
||||
|
||||
RenderView.EnableView "Nézet bekapcsolva"
|
||||
|
||||
Scene.Hotkey "Jelenet Gyorsbillentyű"
|
||||
Scene.MissingSources "Nem tudtam betölteni az összes képi forrást érvénytelen beállítás, vagy hiányzó bővítmény miatt."
|
||||
|
||||
Scene.Hotkey.AlreadyInUse "Ez a gyorsbillentyű már használatban van."
|
||||
Scene.Hotkey.Hotkey "Gyorsbillentyű:"
|
||||
|
||||
Settings.Advanced "Haladó"
|
||||
Settings.Audio "Hang"
|
||||
Settings.Encoding "Kódolás"
|
||||
Settings.General "Általános"
|
||||
Settings.Info "Ezek a beállítások nem lépnek életbe a következő stream megkezdéséig."
|
||||
Settings.Publish "Adás Beállítások"
|
||||
Settings.SaveChangesPrompt "Szeretnéd menteni és alkalmazni a változtatásokat?"
|
||||
Settings.SaveChangesTitle "Beállítások alkalmazzuk?"
|
||||
Settings.Video "Videó"
|
||||
|
||||
Settings.Advanced.BindToIP "Kimeneti ponthoz rendelés:"
|
||||
Settings.Advanced.Network "Hálózat"
|
||||
Settings.Advanced.PresetWarning "VIGYÁZAT! Az x264 beállítás megváltoztatása komoly problémákat okozhat a stream minőségében és a processzor terhelésében.\r\n\r\n Ne változtasd meg a beállítást, csak ha tisztában vagy streamre kiható következményekkel.\r\n\r\nMinden ismertetőt ami a megváltoztatását javasolja kezelj gyanakvással. Szinte semmilyen körülmények között nem kell ezt a beállítást elállítani az alapról(veryfast)\r\n\r\nTeljesen biztos vagy benne hogy meg akarod változtatni a beállítást?"
|
||||
Settings.Advanced.ProcessPriority "Folyamat Prioritás szint"
|
||||
Settings.Advanced.SendBufferSize "Küldő Buffer Méret:"
|
||||
Settings.Advanced.UnlockHigherFPS "61-120 FPS közötti érték engedélyezése a videó beállításokban"
|
||||
Settings.Advanced.UseCBR "CBR Használata"
|
||||
Settings.Advanced.UseHighQualityResampling "Használjon magasabb minőségű mintavételt"
|
||||
Settings.Advanced.UseHighQualityResamplingTooltip "Amikor hang alrendszer kényszerítve van a mintavételezésre használj szinkronizált interpolációt a lineáris interpoláció helyett. Kicsit több processzor teljesítményt igényel."
|
||||
Settings.Advanced.UseMultithreadedOptimizations "Használj Többszálas Optimalizálást"
|
||||
Settings.Advanced.UseSendBuffer "Használj Küldő Buffert"
|
||||
Settings.Advanced.UseSendBufferTooltip "A küldő buffer miatt a hálózati adat egy megadott csomag nagyságig tárolódjon mielőtt elküldi. Ennek a használata lényegesen megnövelheti a hálózat teljesitményét, de megnöveli a stream késési idejét. Ajánlott ha a maximum szegmens méreted többszöröse (általában 1460)"
|
||||
Settings.Advanced.UseSyncFix "Videó/Audió szinkron javítás bekapcsolása"
|
||||
Settings.Advanced.UseSyncFixTooltip "Ritka esetkeben bizonyos processzorok és alaplapok rendelkezhetnek időzítési hibákkal amik szinkronizálási problémákhoz vezethetnek. Ez javítja az időjelölést a procszor időzítése helyett. Elég pontos, de a bizonyosodj meg, hogy a maximum FPSedet ahhoz igazítod aminél rögzítesz a képkocka hibák elkerőlése végett."
|
||||
Settings.Advanced.VideoEncoderCPUTradeoff "x264 CPU Beállítás:"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "Ennek az értéknek a magasabbra állítása könnyít a proceszzor terhelésén minőségi romlásért cserében. Ugyanakkor az érték csökkentése növeli a processzor terhelését jobb minőség elérésének érdekében.\r\n\r\nAjánlott: Very Fast"
|
||||
Settings.Advanced.VideoEncoderSettings "Egyedi x264 Kódoló Beállítás"
|
||||
Settings.Advanced.VideoEncoderSettingsTooltip "Ez engedélyezi egyedi x264 kódolási beállítások hozzáadását. A használható format [parameter]=[value] (pl.: \"vbv-maxrate=1000 vbv-bufsize=1000\")."
|
||||
|
||||
Settings.Audio.Device "Mikrofon/Kiegészítő Hang Eszköz:"
|
||||
Settings.Audio.ForceMicMono "Mikrofon/Kiegészítő Mono kényszerítése:"
|
||||
Settings.Audio.MicBoost "Mik/Kieg erősítő (szorzó):"
|
||||
Settings.Audio.MicTimeOffset "Mik idő eltolás (milliszekundum):"
|
||||
Settings.Audio.MuteDesktopHotkey "Asztal némítás gyorsbillentyű"
|
||||
Settings.Audio.MuteMicHotkey "Mikrofon némítás gyorsbillentyű:"
|
||||
Settings.Audio.PushToTalkDelay "Push-to-talk késleltetés (milliszekundum):"
|
||||
Settings.Audio.PushToTalkHotkey "Push-to-talk használata:"
|
||||
|
||||
Settings.Encoding.Audio "Hang Kódolás"
|
||||
Settings.Encoding.Video "Videó Kódolás"
|
||||
|
||||
Settings.Encoding.Audio.Bitrate "Bitrate:"
|
||||
Settings.Encoding.Audio.Codec "Kodek:"
|
||||
Settings.Encoding.Audio.Format "Formátum:"
|
||||
|
||||
Settings.Encoding.Video.BufferSize "Buffer méret (kbit):"
|
||||
Settings.Encoding.Video.BufferSizeTooltip "A buffer méret határozza meg hogy mennyi adatot halmozol fel. Ez a beállítás a nagymozgással járó jelenetekre van hatással leinkább. Ha nem tudod mennyire állítsd, állítsd annyira mint a bitrated. További információért nézd meg a Súgót."
|
||||
Settings.Encoding.Video.MaxBitRate "Max Bitrate (kb/s):"
|
||||
Settings.Encoding.Video.MaxBitRateTooltip "Ez határozza meg a videó maximális bitratjét. Bár az átlag bitrated megfog eggyezni az értékkel, ez az érték a buffer méretedre épül. Általában ezt az értéket a a feltöltési sebességed alatt kell tartanod\r\n\r\nHasználd a speedtest.net-et hogy megtudd mekkora a feltöltési sebességed."
|
||||
Settings.Encoding.Video.Quality "Minőségi egyensúly:"
|
||||
Settings.Encoding.Video.QualityTooltip "Ez a beállítás megpróbálja a streamed minőségét a bitrated és a buffered alapján egyensúlyozni. Ha ezt magasra állítod alacson bitrattel akkor feláldozod a nagy mozgásos jelenetek minőségét az állóképekért, és ez inkonzisztens minőséget eredményez."
|
||||
|
||||
Settings.General.Add "Új hozzáadása"
|
||||
Settings.General.ConfirmDelete "Biztos hogy törölni akarod '$1' profilt?"
|
||||
Settings.General.InvalidName "A profil nevek nem használhatják a következő karaktereket:\r\n\\ / : * ? \" < > |"
|
||||
Settings.General.Language "Nyelv:"
|
||||
Settings.General.Profile "Beállítás Profil:"
|
||||
Settings.General.Restart "A nyelv megváltoztatása az OBS újraindítását igényli.\r\n\r\n..Bár ha a nyelvet változtatod akkor gondolom nem érted mi van ide írva."
|
||||
|
||||
Settings.Publish.AutoReconnect "Auto-Újracsatlakozás:"
|
||||
Settings.Publish.AutoReconnectTimeout "Auto-Újracsatlakozás időtúllépés:"
|
||||
Settings.Publish.ChannelName "Csatorna Név:"
|
||||
Settings.Publish.DashboardLink "Műszerfal Link (ha kell):"
|
||||
Settings.Publish.Delay "Késleltetés (mp):"
|
||||
Settings.Publish.Mode "Mód:"
|
||||
Settings.Publish.Password "Jelszó (ha kell):"
|
||||
Settings.Publish.Playpath "Lejátszási Elérés/Stream Kulcs (ha kell):"
|
||||
Settings.Publish.SavePath "Fájl elérés:"
|
||||
Settings.Publish.SaveToFile "Mentés Fájlba:"
|
||||
Settings.Publish.Server "Szerver:"
|
||||
Settings.Publish.Service "Stream Kiszolgáló:"
|
||||
Settings.Publish.StartStreamHotkey "Stream Indítás Gyorsbillentyű:"
|
||||
Settings.Publish.StopStreamHotkey "Stream Leállítás Gyorsbillentyű:"
|
||||
Settings.Publish.Username "Felhasználónév (ha kell):"
|
||||
|
||||
Settings.Publish.Mode.FileOnly "Csak Fileba Rögzítés"
|
||||
Settings.Publish.Mode.LiveStream "Live Stream"
|
||||
|
||||
Settings.Video.Custom "Egyedi:"
|
||||
Settings.Video.DisableAero "Aero kikapcsolása indításkor:"
|
||||
Settings.Video.DisableAeroTooltip "Az Aero kikapcsolása javasolt ha software minotr felvételt használsz"
|
||||
Settings.Video.Downscale "Felbontás csökkentése:"
|
||||
Settings.Video.DownscaleTooltip "A csökkentés javíthatja a videó minőségét a felbontás kárán."
|
||||
Settings.Video.FPS "FPS:"
|
||||
Settings.Video.Monitor "Monitor:"
|
||||
Settings.Video.Resolution "Alap Felbontás:"
|
||||
|
||||
Sources.BitmapSource "Kép"
|
||||
Sources.GameCaptureSource "Játék Felvétel"
|
||||
Sources.GlobalSource "Globális Forrás"
|
||||
Sources.SoftwareCaptureSource "Software Felvétel"
|
||||
Sources.TextSource "Szöveg"
|
||||
Sources.TransitionSource "Kép Montázs"
|
||||
|
||||
Sources.BitmapSource.Color "Szín:"
|
||||
Sources.BitmapSource.Empty "Nem adtál meg képet. Kérlek keress és vállasz egy képet"
|
||||
Sources.BitmapSource.Opacity "Áttetszőség:"
|
||||
|
||||
Sources.GameCaptureSource.Application "Program:"
|
||||
Sources.GameCaptureSource.IgnoreAspect "Képarány figyelmenkívűl hagyása"
|
||||
Sources.GameCaptureSource.PluginDescription "A képkockákat egyenesen a játékból vagy grafikus programból emeli ki rákapcsolódva és azonnal kiemelve a képkockákat."
|
||||
Sources.GameCaptureSource.PluginName "Játék Felvétel Bővítmény"
|
||||
Sources.GameCaptureSource.Requires32bit "Ezek a programok csak az OBS 32bites verziójával felvehetőek:"
|
||||
Sources.GameCaptureSource.Requires64bit "Ezek a programok csak az OBS 64bites verziójával felvehetőek:"
|
||||
Sources.GameCaptureSource.RequiresAdmin "Ezek a programok csak adminisztrációs joggal felvehetőek (a felvételhez indítsd el az OBSot adminisztrátor ként):"
|
||||
Sources.GameCaptureSource.StretchToScreen "Kép nyújtása a képernyőhöz"
|
||||
|
||||
Sources.SoftwareCaptureSource.Blend "Vegyítés (1-100):"
|
||||
Sources.SoftwareCaptureSource.CaptureLayered "Rétegelt Ablakok Felvétele"
|
||||
Sources.SoftwareCaptureSource.CaptureLayeredTip "Áttetsző vagy átalakított/egyedi rétegelt ablakok felvételéhez Windows Aero kikapcsolásánál. Lehet hogy egér vibrálást okoz bekapcsolt állapotban. Csak akkor használd ha máshogy nem tudsz egy bizonyos programot felvenni."
|
||||
Sources.SoftwareCaptureSource.ColorKey "Színkulcs"
|
||||
Sources.SoftwareCaptureSource.EntireWindow "Teljes Ablak"
|
||||
Sources.SoftwareCaptureSource.InnerWindow "Belső Ablak"
|
||||
Sources.SoftwareCaptureSource.InvertMouseOnClick "Kurzor invert gombnyomásra."
|
||||
Sources.SoftwareCaptureSource.Monitor "Monitor:"
|
||||
Sources.SoftwareCaptureSource.MonitorCapture "Monitor Felvétel"
|
||||
Sources.SoftwareCaptureSource.MonitorCaptureTooltip "Kapcsold ki az Aero-t a beállításokban az FPS maximalizálásához"
|
||||
Sources.SoftwareCaptureSource.MouseCapture "Egér kurzor felvétele"
|
||||
Sources.SoftwareCaptureSource.Position "Pozíció:"
|
||||
Sources.SoftwareCaptureSource.Refresh "Frissít"
|
||||
Sources.SoftwareCaptureSource.RegionCapture "Belterület"
|
||||
Sources.SoftwareCaptureSource.RegionWindowText "Nyomj Enter-t, Esc-et, vagy kattints a négyszögön kívülre a befejezéshez."
|
||||
Sources.SoftwareCaptureSource.Select "Kijelölés"
|
||||
Sources.SoftwareCaptureSource.SelectRegion "Terület Kijelölése"
|
||||
Sources.SoftwareCaptureSource.SelectRegionTooltip "Kijelölés alatt mozgasd gomb lenyomással és húzással, és méretezd át az éleknél fogva."
|
||||
Sources.SoftwareCaptureSource.Similarity "Hasonlóság (1-100):"
|
||||
Sources.SoftwareCaptureSource.Size "Méret:"
|
||||
Sources.SoftwareCaptureSource.SpillReduction "Túlfolyás Csökkentés:"
|
||||
Sources.SoftwareCaptureSource.UseColorKey "Színkulcs használata:"
|
||||
Sources.SoftwareCaptureSource.Window "Ablak:"
|
||||
Sources.SoftwareCaptureSource.WindowCapture "Ablak Felvétel"
|
||||
Sources.SoftwareCaptureSource.WindowCaptureTooltip "Aero-t csak akkor szabad bekapcsolni amikot Ablak Felvételt használsz. A kép nem frissül ha a program a tálcára van kicsinyítve. Ez a felvételi megoldás általában gyorsabb mint a Monitor felvétel. Amikor az Aero be van kapcsolva a felvett ablak fölé húzott ablakok nem látszanak."
|
||||
Sources.SoftwareCaptureSource.WindowMinimized "Ablak kicsinyítve"
|
||||
Sources.SoftwareCaptureSource.WindowNotFound "Nem található az ablak"
|
||||
|
||||
Sources.TextSource.Align "Igazít:"
|
||||
Sources.TextSource.Bold "Félkövér"
|
||||
Sources.TextSource.Center "Középre"
|
||||
Sources.TextSource.EnterText "Szöveg megadása"
|
||||
Sources.TextSource.FileNotFound "A '$1' fájlt nem lehet megnyitni"
|
||||
Sources.TextSource.Font "Betűtípus:"
|
||||
Sources.TextSource.FontNotFound "A '$1' betűtípus nem található"
|
||||
Sources.TextSource.FontSize "Betűméret:"
|
||||
Sources.TextSource.Italic "Dőlt"
|
||||
Sources.TextSource.Left "Balra"
|
||||
Sources.TextSource.Right "Jobbra"
|
||||
Sources.TextSource.ScrollSpeed "Tekerési sebesség:"
|
||||
Sources.TextSource.Size "Méret:"
|
||||
Sources.TextSource.Underline "Aláhúzott"
|
||||
Sources.TextSource.UseCustomExtents "Egyedi szöveg doboz használata"
|
||||
Sources.TextSource.UseOutline "Használj körvonalat"
|
||||
Sources.TextSource.OutlineThickness "Vastagság:"
|
||||
Sources.TextSource.UseTextExtents "Egyedi szöveg doboz használata"
|
||||
Sources.TextSource.UseTextFromFile "Egyedi szöveg file használata (UTF-8 vagy kompatibilis)"
|
||||
Sources.TextSource.VerticalScript "Függőleges"
|
||||
Sources.TextSource.Wrap "Sortörés"
|
||||
|
||||
Sources.TransitionSource.Bitmaps "Kép:"
|
||||
Sources.TransitionSource.Empty "Nem lett kép megadva megjelenítésre."
|
||||
Sources.TransitionSource.FadeInOnly "Csak beúszásnál:"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "Képek közötti idő (mp):"
|
||||
|
||||
Updater.DownloadNow "Szeretnéd most letölteni őket?"
|
||||
Updater.NewUpdates "A következő frissítések elérhetőek:\r\n\r\n"
|
||||
Updater.RunningWarning "OBs most újra fog indulni a frissítések telepítéséhez.\r\n\r\nBiztos hogy folytatni akarod?"
|
||||
Updater.UpdatesAvailable "Frissítések elérhetőek"
|
|
@ -46,6 +46,7 @@ Listbox.Add "Добавить $1"
|
|||
Listbox.Center "По центру"
|
||||
Listbox.Config "Настройки"
|
||||
Listbox.FitToScreen "По размеру экрана"
|
||||
Listbox.Positioning "Позиция/Размер"
|
||||
Listbox.ResetSize "Сбросить размер"
|
||||
Listbox.SetHotkey "Добавить горячую клавишу"
|
||||
|
||||
|
@ -105,7 +106,8 @@ Settings.Advanced.DisableD3DCompatibilityModeTooltip "Отключает ре
|
|||
Settings.Advanced.Network "Сеть"
|
||||
Settings.Advanced.SendBufferSize "Размер исходящего буфера:"
|
||||
Settings.Advanced.UnlockHigherFPS "Разрешить использование 61-120 FPS в настройках видео"
|
||||
Settings.Advanced.UseCBR "Использовать постоянный битрейт"
|
||||
Settings.Advanced.UseCBR "Использовать CBR (постоянный битрейт)"
|
||||
Settings.Advanced.UseCFR "Использовать CFR (постоянная частота кадров)"
|
||||
Settings.Advanced.UseHighQualityResampling "Использовать высококачественное преобразование звука"
|
||||
Settings.Advanced.UseHighQualityResamplingTooltip "Когда звуковая подсистема принудительно использует высококачественное преобразование звука, то вместо линейной интерполяции используется синусоидальная. Слегка увеличивает нагрузку на CPU."
|
||||
Settings.Advanced.UseMultithreadedOptimizations "Использовать многопоточную оптимизацию"
|
||||
|
@ -113,6 +115,7 @@ Settings.Advanced.UseSendBuffer "Использовать и
|
|||
Settings.Advanced.UseSendBufferTooltip "Исходящий буфер заставляет сетевые данные буферизоваться до определенных размеров пакета перед отправкой. Это позволяет значительно увеличить сетевую пропускную способность, но слегка увеличивает задержку трансляции.\r\n\r\nРекомендуется: включить. Размер буфера должен быть кратен максимальному размеру блока данных (обычно 1460)"
|
||||
Settings.Advanced.UseSyncFix "Исправлять Видео / Аудио синхронизацию"
|
||||
Settings.Advanced.UseSyncFixTooltip "В редких случаях у определенных процессоров и/или материнских плат возникают ошибки с таймингами. Использование данного исправления гарантирует, что аудио / видео синхронизация всегда будет корректна, но менее точна чет при правильных таймингах. Не используйте это если не уверенны что у вас есть данная ошибка."
|
||||
Settings.Advanced.SyncToVideoTime "Подгонять звук под тайминг видео"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoff "x264 CPU предустановка:"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "Увеличение этого значения уменьшит загрузку процессора в ущерб качеству. Уменьшение этого значения повысит качество, но загрузка процессора увеличится.\r\n\r\nРекомендуется: Very Fast"
|
||||
Settings.Advanced.VideoEncoderSettings "Пользовательские настройки энкодера x264"
|
||||
|
@ -124,6 +127,7 @@ Settings.Advanced.BindToIP "Привязка к инт
|
|||
Settings.Audio.Device "Микрофон:"
|
||||
Settings.Audio.ForceMicMono "Принудительный режим моно:"
|
||||
Settings.Audio.MicBoost "Усиление (множитель):"
|
||||
Settings.Audio.MicTimeOffset "Смещение времени (миллисекунды):"
|
||||
Settings.Audio.MuteDesktopHotkey "Горячая клавиша Вкл/Откл звука:"
|
||||
Settings.Audio.MuteMicHotkey "Горячая клавиша Вкл/Откл микрофона:"
|
||||
Settings.Audio.PushToTalkDelay "Задержка РТТ (миллисекунды):"
|
||||
|
@ -155,6 +159,7 @@ Settings.Publish.AutoReconnectTimeout "Задержка автоперепод
|
|||
Settings.Publish.ChannelName "Имя канала:"
|
||||
Settings.Publish.DashboardLink "Ссылка на дэшборд (если есть):"
|
||||
Settings.Publish.Delay "Задержка (в секундах):"
|
||||
Settings.Publish.LowLatencyMode "Режим низкой задержки:"
|
||||
Settings.Publish.Mode "Режим:"
|
||||
Settings.Publish.Password "Пароль (если имеется):"
|
||||
Settings.Publish.Playpath "Play Path/Stream Key (если имеется):"
|
||||
|
@ -188,6 +193,7 @@ Sources.TransitionSource "Слайд-шоу"
|
|||
Sources.BitmapSource.Color "Цвет:"
|
||||
Sources.BitmapSource.Empty "Изображение не найдено. Пожалуйста, найдите и выберите картинку."
|
||||
Sources.BitmapSource.Opacity "Прозрачность:"
|
||||
Sources.BitmapSource.Monitor "Следить за изменениями:"
|
||||
|
||||
Sources.GameCaptureSource.Application "Приложение:"
|
||||
Sources.GameCaptureSource.IgnoreAspect "Игнорировать соотношение сторон"
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
Add "Lägg till"
|
||||
Apply "Bekräfta"
|
||||
Browse "Bläddra"
|
||||
BuildingMP4Dialog "Bygger MP4"
|
||||
Cancel "Avbryt"
|
||||
ClearHotkey "Rensa"
|
||||
Color "Färg"
|
||||
Default "Grundinställning"
|
||||
DeleteConfirm "Vill du radera de valda objekten?"
|
||||
Desktop "Skrivbord"
|
||||
Disable "Avaktivera"
|
||||
EndingDelay "Avslutar fördröjd stream..."
|
||||
EnterName "Ange ett namn"
|
||||
GlobalSources "Globala källor"
|
||||
IncompatibleModules "Ej kompatibla hookmoduler upptäcktes i OBS-processen. Vänligen försäkra dig om att OBS är tillagd i ignorelistan i dessa captureprogram, såsom DXtory, FRAPS och dylikt.\r\n\r\nNär du ändrat undantagsinställningarna i dessa program kan det vara nödvändigt att starta om OBS och eventuella program med hookmoduler för att ändringarna ska träda i kraft."
|
||||
MicrophoneFailure "Ett fel uppstod när mikrofonen skulle initialiseras. Det kan hända att den inte är inkopplad, eller att ett annat program använder den i exklusivt läge."
|
||||
MoveDown "Flytta ned"
|
||||
MoveToBottom "Flytta längst ned"
|
||||
MoveToTop "Flytta längst upp"
|
||||
MoveUp "Flytta upp"
|
||||
NameExists "'$1' finns redan. Var god ange ett annat namn."
|
||||
None "Ingen"
|
||||
OK "OK"
|
||||
Plugins "Plugins"
|
||||
Reconnecting "Återanslutning sker..."
|
||||
Remove "Ta bort"
|
||||
Rename "Byt namn"
|
||||
Scene "Scen"
|
||||
Settings "Inställningar"
|
||||
StreamReport "Streamrapport"
|
||||
|
||||
BuildingMP4Dialog.Progress "Bygger MP4, var god vänta..."
|
||||
|
||||
Connection.CouldNotConnect "Kunde inte ansluta till servern"
|
||||
Connection.CouldNotParseURL "Tolkning av RTMP-URL misslyckades"
|
||||
Connection.Disconnected "Nedkopplad från servern"
|
||||
Connection.InvalidStream "Stream channel/stream key är inte giltig"
|
||||
|
||||
DeleteConfirm.Title "Ta bort valda objekt?"
|
||||
|
||||
EndingDelay.TimeLeft "Tid som återstår: $1"
|
||||
|
||||
GlobalSources.DeleteConfirm "Om du tar bort en global källa tas den bort från alla scener där den används. Är du säker på att du vill fortsätta?"
|
||||
|
||||
Listbox.Add "Lägg till $1"
|
||||
Listbox.Center "Centrera"
|
||||
Listbox.Config "Egenskaper"
|
||||
Listbox.FitToScreen "Passa till skärm"
|
||||
Listbox.Positioning "Position/Storlek"
|
||||
Listbox.ResetSize "Återställ storlek"
|
||||
Listbox.SetHotkey "Ange snabbtangent"
|
||||
|
||||
MainMenu.File "&Fil"
|
||||
MainMenu.Help "&Hjälp"
|
||||
MainMenu.Settings "In&ställningar"
|
||||
MainMenu.Settings.AlwaysOnTop "&Alltid i förgrunden"
|
||||
|
||||
MainMenu.File.Exit "&Avsluta"
|
||||
|
||||
MainMenu.Help.Contents "&Innehåll"
|
||||
MainMenu.Help.VisitWebsite "Besök webbplats"
|
||||
|
||||
MainMenu.Settings.OpenConfigFolder "Öppna mappen för &inställningar"
|
||||
MainMenu.Settings.OpenLogFolder "Öppna mappen för &loggar"
|
||||
|
||||
MainWindow.Dashboard "Dashboard"
|
||||
MainWindow.DroppedFrames "Tappade bildrutor:"
|
||||
MainWindow.Exit "Avsluta"
|
||||
MainWindow.Plugins "Plugins"
|
||||
MainWindow.SceneEditor "Redigera scen"
|
||||
MainWindow.Scenes "Scener:"
|
||||
MainWindow.Sources "Källor:"
|
||||
MainWindow.StartStream "Börja streama"
|
||||
MainWindow.StopStream "Sluta streama"
|
||||
MainWindow.StopTest "Sluta förhandsvisa"
|
||||
MainWindow.TestStream "Förhandsvisa stream"
|
||||
|
||||
Plugins.Configure "Konfigurera"
|
||||
Plugins.Description "Beskrivning:"
|
||||
Plugins.Filename "Filnamn:"
|
||||
|
||||
Reconnecting.Retrying "Återanslutning misslyckades. Försöker igen."
|
||||
|
||||
RenderView.EnableView "Aktivera förhandsvisning"
|
||||
|
||||
Scene.Hotkey "Scen-snabbtangent"
|
||||
Scene.MissingSources "Misslyckades att ladda bildkällor, antingen p.g.a. felaktiga inställningar eller saknade plugins."
|
||||
|
||||
Scene.Hotkey.AlreadyInUse "Denna snabbtangent används redan."
|
||||
Scene.Hotkey.Hotkey "Snabbtangent:"
|
||||
|
||||
Settings.Advanced "Avancerat"
|
||||
Settings.Audio "Ljud"
|
||||
Settings.Encoding "Encoding"
|
||||
Settings.General "Allmänt"
|
||||
Settings.Info "Dessa inställningar träder inte i kraft förrän nästa gång du börjar streama."
|
||||
Settings.Publish "Sändningsinställningar"
|
||||
Settings.SaveChangesPrompt "Vill du spara och aktivera dina ändringar?"
|
||||
Settings.SaveChangesTitle "Aktivera inställningar?"
|
||||
Settings.Video "Video"
|
||||
|
||||
Settings.Advanced.BindToIP "Bind till gränssnitt:"
|
||||
Settings.Advanced.Network "Nätverk"
|
||||
Settings.Advanced.PresetWarning "VARING! Att ändra din x264-grundinställning kan ha negativ inverkan på din streamkvalitet och CPU-användning.\r\n\r\nÄndra inte denna inställning om du inte är fullständigt medveten om konsekvenserna detta kan ha för din stream.\r\n\r\nTa eventuella guider som rekommenderar att du ändrar denna inställning med försiktighet. I nästan alla situationer bör detta inte ändras från sin förinställning (veryfast).\r\n\r\nÄr du helt säker på att du vill ändra din x264-grundinställning?"
|
||||
Settings.Advanced.ProcessPriority "Processprioritet"
|
||||
Settings.Advanced.SendBufferSize "Sändbuffert:"
|
||||
Settings.Advanced.UnlockHigherFPS "Tillåt 61-120 FPS i videoinställningarna"
|
||||
Settings.Advanced.UseCBR "Använd CBR"
|
||||
Settings.Advanced.UseHighQualityResampling "Använd högkvalitetsomsampling"
|
||||
Settings.Advanced.UseHighQualityResamplingTooltip "Använder sincinterpolering istället för linjär interpolering när systemet måste omsampla ljud. Kräver lite extra CPU."
|
||||
Settings.Advanced.UseMultithreadedOptimizations "Använd flertrådsoptimiseringar"
|
||||
Settings.Advanced.UseSendBuffer "Använd sändbuffert"
|
||||
Settings.Advanced.UseSendBufferTooltip "Detta buffrar all nätverksdata innan den sänds. Ökar avsevärt din nätverkskapacitet, men kan leda till en något mer fördröjd stream.\r\n\r\nRekommendation: På, med en storlek delbar med din maximala segmentstorlek (vanligtvis 1460)."
|
||||
Settings.Advanced.UseSyncFix "Använd video-/ljudsynkfix"
|
||||
Settings.Advanced.UseSyncFixTooltip "I sällsynta fall kan vissa processorer och moderbord ha timing-buggar som orsakar synkroniseringsproblem hos din stream. Denna fix använder tidsstämplar istället för processortiming för att synkronisera ljud och bild. Den fungerar oftast korrekt, men försäkra dig om att din maximala FPS är så nära din capture-FPS som möjligt för att undvika eventuella bildflimmer."
|
||||
Settings.Advanced.VideoEncoderCPUTradeoff "x264-grundinställning:"
|
||||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "Öka denna inställning för att minska processoranvändning i utbyte av i streamkvalitet i någon mån. Å andra sidan kan minskning av denna inställning ge dig bättre bildkvalitet i utbyte mot mer processoranvändning.\r\n\r\nRekommendation: Veryfast"
|
||||
Settings.Advanced.VideoEncoderSettings "Anpassade x264-encoderinställningar"
|
||||
Settings.Advanced.VideoEncoderSettingsTooltip "Detta låter dig ange anpassade x264-encoderinställningar i form av [parameter]=[värde]. (T.ex. \"vbv-maxrate=1000 vbv-bufsize=1000\")."
|
||||
|
||||
Settings.Audio.Device "Mikrofon/Extra ljudenhet:"
|
||||
Settings.Audio.ForceMicMono "Tvinga mic/aux-ljudenhet att använda mono:"
|
||||
Settings.Audio.MicBoost "Mic/aux-boost (gånger):"
|
||||
Settings.Audio.MicTimeOffset "Mic-tidsskillnad (millisekunder):"
|
||||
Settings.Audio.MuteDesktopHotkey "Snabbtangent för Ljud av/på, skrivbord:"
|
||||
Settings.Audio.MuteMicHotkey "Snabbtangent för Ljud av/på, mikrofon:"
|
||||
Settings.Audio.PushToTalkDelay "Push-to-talk-fördröjning (millisekunder):"
|
||||
Settings.Audio.PushToTalkHotkey "Använd Push-to-talk:"
|
||||
|
||||
Settings.Encoding.Audio "Ljudencoding"
|
||||
Settings.Encoding.Video "Videoencoding"
|
||||
|
||||
Settings.Encoding.Audio.Bitrate "Bithastighet:"
|
||||
Settings.Encoding.Audio.Codec "Codec:"
|
||||
Settings.Encoding.Audio.Format "Format:"
|
||||
|
||||
Settings.Encoding.Video.BufferSize "Buffertstorlek (kbit):"
|
||||
Settings.Encoding.Video.BufferSizeTooltip "Bufferstorleken anger hur stor mängd data som buffras. Detta värde påverkar i störst mån scener med mycket rörelse. Om du inte är säker på hur du ska ställa in den, använd samma värde som för din bithastighet. Vänligen se hjälpfilen för ytterligare information."
|
||||
Settings.Encoding.Video.MaxBitRate "Maximal bithastighet (kb/s):"
|
||||
Settings.Encoding.Video.MaxBitRateTooltip "Detta anger den genomsnittliga bithastigheten som används för video. Observera dock att din maximala bithastighet under korta perioder kan påverkas av din bufferstorlek. Normalt sett vill du ställa in detta en viss mängd under din maximala uppladdningshastighet.\r\n\r\nAnvänd valfri webbplats, t.ex. speedtest.net, för att ta reda på din uppladdningshastighet."
|
||||
Settings.Encoding.Video.Quality "Kvalitetsbalans:"
|
||||
Settings.Encoding.Video.QualityTooltip "Denna inställning försöker att hålla en viss kvalitetsbalans beroende på din maximala bithastighet och buffertstorlek. Ett högt värde ger prioritet till scener med lite rörelse, och kan orsaka ikonsekvent kvalitet för scener med mycket rörelse."
|
||||
|
||||
Settings.General.Add "Lägg till ny"
|
||||
Settings.General.ConfirmDelete "Vill du verkligen ta bort profilen '$1'?"
|
||||
Settings.General.InvalidName "Profilnamn kan inte innehålla följande tecken:\r\n\\ / : * ? \" < > |"
|
||||
Settings.General.Language "Språk:"
|
||||
Settings.General.Profile "Inställningsprofil:"
|
||||
Settings.General.Restart "Om du byter språk måste du starta om OBS.\r\n\r\n...Fast om du försöker byta språk kanske du inte förstår det här ändå."
|
||||
|
||||
Settings.Publish.AutoReconnect "Automatisk återanslutning:"
|
||||
Settings.Publish.AutoReconnectTimeout "Timeout for autoåteranslutning:"
|
||||
Settings.Publish.ChannelName "Kanalnamn:"
|
||||
Settings.Publish.DashboardLink "Dashboard-länk (om tillgängligt):"
|
||||
Settings.Publish.Delay "Fördröjning (sekunder):"
|
||||
Settings.Publish.Mode "Läge:"
|
||||
Settings.Publish.Password "Lösenord (om tillgängligt):"
|
||||
Settings.Publish.Playpath "Play Path/Stream Key (om tillgängligt):"
|
||||
Settings.Publish.SavePath "Filsökväg:"
|
||||
Settings.Publish.SaveToFile "Spara till fil:"
|
||||
Settings.Publish.Server "Server:"
|
||||
Settings.Publish.Service "Streamtjänst:"
|
||||
Settings.Publish.StartStreamHotkey "Snabbtangent för att börja streama:"
|
||||
Settings.Publish.StopStreamHotkey "Snabbtangent för att sluta streama:"
|
||||
Settings.Publish.Username "Användarnamn (om tillgängligt):"
|
||||
|
||||
Settings.Publish.Mode.FileOnly "Endast inspelning till fil"
|
||||
Settings.Publish.Mode.LiveStream "Live-sändning"
|
||||
|
||||
Settings.Video.Custom "Anpassat:"
|
||||
Settings.Video.DisableAero "Avaktivera Aero vid programstart:"
|
||||
Settings.Video.DisableAeroTooltip "Du rekommenderas att avaktivera Aero om du använder mjukvarucapture för att streama ditt skrivbord i Windows Vista eller 7."
|
||||
Settings.Video.Downscale "Upplösningsnedskalning:"
|
||||
Settings.Video.DownscaleTooltip "Nedskalning kan ge ökad kvalitet och skärpa i utbyte mot upplösning."
|
||||
Settings.Video.FPS "FPS:"
|
||||
Settings.Video.Monitor "Monitor:"
|
||||
Settings.Video.Resolution "Grundupplösning:"
|
||||
|
||||
Sources.BitmapSource "Bild"
|
||||
Sources.GameCaptureSource "Game Capture"
|
||||
Sources.GlobalSource "Global källa"
|
||||
Sources.SoftwareCaptureSource "Mjukvarucapture"
|
||||
Sources.TextSource "Text"
|
||||
Sources.TransitionSource "Bildspel"
|
||||
|
||||
Sources.BitmapSource.Color "Färg:"
|
||||
Sources.BitmapSource.Empty "Ingen bildfil angiven. Vänligen bläddra efter en bildfil."
|
||||
Sources.BitmapSource.Opacity "Opacitet:"
|
||||
Sources.BitmapSource.Monitor "Övervaka filändring:"
|
||||
|
||||
Sources.GameCaptureSource.Application "Program:"
|
||||
Sources.GameCaptureSource.IgnoreAspect "Ignorera bildförhållande"
|
||||
Sources.GameCaptureSource.PluginDescription "Fångar bilder direkt från spel och program genom att fästa sig vid bildbufferten och läsa bilder direkt de presenteras."
|
||||
Sources.GameCaptureSource.PluginName "Game Capture-plugin"
|
||||
Sources.GameCaptureSource.Requires32bit "Dessa program kräver 32-bit-versionen av OBS för att visas:"
|
||||
Sources.GameCaptureSource.Requires64bit "Dessa program kräver 64-bit-versionen av OBS för att visas:"
|
||||
Sources.GameCaptureSource.RequiresAdmin "Dessa program kräver att du startar OBS som administratör för att visas:"
|
||||
Sources.GameCaptureSource.StretchToScreen "Sträck ut bilden över hela skärmen"
|
||||
|
||||
Sources.SoftwareCaptureSource.Blend "Blandning (1-100):"
|
||||
Sources.SoftwareCaptureSource.CaptureLayered "Visa layered-fönster"
|
||||
Sources.SoftwareCaptureSource.CaptureLayeredTip "Visa genomskinliga/anpassade eller fönster med särskilda skins även när Aero är avaktiverad. Kan orsaka musflimmer. Aktivera endast detta om du har problem med att visa ett särskilt program."
|
||||
Sources.SoftwareCaptureSource.ColorKey "Färgfilter"
|
||||
Sources.SoftwareCaptureSource.EntireWindow "Hela fönstret"
|
||||
Sources.SoftwareCaptureSource.InnerWindow "Inre delen av fönstret"
|
||||
Sources.SoftwareCaptureSource.InvertMouseOnClick "Invertera muspekare vid klick"
|
||||
Sources.SoftwareCaptureSource.Monitor "Monitor:"
|
||||
Sources.SoftwareCaptureSource.MonitorCapture "Monitor-capture"
|
||||
Sources.SoftwareCaptureSource.MonitorCaptureTooltip "Avaktivera Aero i videoinställningarna för maximal prestanda i Windows Vista/7."
|
||||
Sources.SoftwareCaptureSource.MouseCapture "Visa muspekare"
|
||||
Sources.SoftwareCaptureSource.Position "Position:"
|
||||
Sources.SoftwareCaptureSource.Refresh "Uppdatera"
|
||||
Sources.SoftwareCaptureSource.RegionCapture "Delregion"
|
||||
Sources.SoftwareCaptureSource.RegionWindowText "Tryck på Enter, Esc eller klicka utanför denna rektangel när du är klar."
|
||||
Sources.SoftwareCaptureSource.Select "Välj"
|
||||
Sources.SoftwareCaptureSource.SelectRegion "Välj region"
|
||||
Sources.SoftwareCaptureSource.SelectRegionTooltip "Du kan flytta regionen genom att klicka och dra eller ändra regionens storlek genom att klicka och dra i kanterna."
|
||||
Sources.SoftwareCaptureSource.Similarity "Likhet (1-100):"
|
||||
Sources.SoftwareCaptureSource.Size "Storlek:"
|
||||
Sources.SoftwareCaptureSource.SpillReduction "Spillminskning:"
|
||||
Sources.SoftwareCaptureSource.UseColorKey "Använd färgfilter:"
|
||||
Sources.SoftwareCaptureSource.Window "Fönster:"
|
||||
Sources.SoftwareCaptureSource.WindowCapture "Fönster-capture"
|
||||
Sources.SoftwareCaptureSource.WindowCaptureTooltip "Lämna Aero aktiverat om du endast använder fönster-capture. Bilden kan inte uppdateras om fönstret är minimerat. Att visa fönster med denna metod är vanligtvis mycket snabbare än monitor-capture. Om Aero är aktiverat visas endast det valda fönstret, inte eventuella fönster som ligger ovanpå."
|
||||
Sources.SoftwareCaptureSource.WindowMinimized "Fönstret är minimerat"
|
||||
Sources.SoftwareCaptureSource.WindowNotFound "Kunde ej hitta fönstret"
|
||||
|
||||
Sources.TextSource.Align "Justering:"
|
||||
Sources.TextSource.Bold "Fetstil"
|
||||
Sources.TextSource.Center "Centrera"
|
||||
Sources.TextSource.EnterText "Skriv in text"
|
||||
Sources.TextSource.FileNotFound "Kunde inte öppna filen '$1'"
|
||||
Sources.TextSource.Font "Typsnitt:"
|
||||
Sources.TextSource.FontNotFound "Kunde inte hitta typsnitt '$1'"
|
||||
Sources.TextSource.FontSize "Typsnittsstorlek:"
|
||||
Sources.TextSource.Italic "Kursiv"
|
||||
Sources.TextSource.Left "Vänster"
|
||||
Sources.TextSource.Right "Höger"
|
||||
Sources.TextSource.ScrollSpeed "Rullningshastighet:"
|
||||
Sources.TextSource.Size "Storlek:"
|
||||
Sources.TextSource.Underline "Understryk"
|
||||
Sources.TextSource.UseCustomExtents "Använd anpassad textgrad"
|
||||
Sources.TextSource.UseOutline "Använd outline"
|
||||
Sources.TextSource.OutlineThickness "Tjocklek:"
|
||||
Sources.TextSource.UseTextExtents "Använd anpassad textgrad"
|
||||
Sources.TextSource.UseTextFromFile "Hämta text från fil (UTF-8 eller kompatibel)"
|
||||
Sources.TextSource.VerticalScript "Stående"
|
||||
Sources.TextSource.Wrap "Rulla runt"
|
||||
|
||||
Sources.TransitionSource.Bitmaps "Bilder:"
|
||||
Sources.TransitionSource.Empty "Det finns inga bilder att visa."
|
||||
Sources.TransitionSource.FadeInOnly "Tona endast in:"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "Tid mellan bildbyten (sekunder):"
|
||||
|
||||
Updater.DownloadNow "Vill du ladda ned dem nu?"
|
||||
Updater.NewUpdates "Följande uppdateringar finns tillgängliga:\r\n\r\n"
|
||||
Updater.RunningWarning "OBS kommer att startas om för att installera uppdateringarna\r\n\r\nÄr du säker på att du vill fortsätta?"
|
||||
Updater.UpdatesAvailable "Uppdateringar finns tillgängliga"
|
|
@ -52,7 +52,6 @@ Listbox.SetHotkey "設定快捷鍵"
|
|||
MainMenu.File "檔案(&F)"
|
||||
MainMenu.Help "幫助(&H)"
|
||||
MainMenu.Settings "設定(&S)"
|
||||
MainMenu.Settings.AlwaysOnTop "總在最前"
|
||||
|
||||
MainMenu.File.Exit "退出(&X)"
|
||||
|
||||
|
@ -63,7 +62,7 @@ MainMenu.Settings.OpenConfigFolder "打開設置資料夾(&C)"
|
|||
MainMenu.Settings.OpenLogFolder "打開日誌資料夾(&L)"
|
||||
|
||||
MainWindow.Dashboard "儀表盤"
|
||||
MainWindow.DroppedFrames "丟幀:"
|
||||
MainWindow.DroppedFrames "丟失影格:"
|
||||
MainWindow.Exit "退出"
|
||||
MainWindow.Plugins "插件"
|
||||
MainWindow.SceneEditor "編輯場景"
|
||||
|
@ -98,7 +97,10 @@ Settings.SaveChangesPrompt "您想要儲存並且應用您的變更嗎?"
|
|||
Settings.SaveChangesTitle "應用設定?"
|
||||
Settings.Video "影像"
|
||||
|
||||
Settings.Advanced.BindToIP "綁定介面:"
|
||||
Settings.Advanced.Network "網路"
|
||||
Settings.Advanced.PresetWarning "警告!改變 x264 預設可能在你的串流品質和 CPU 使用會有嚴重負面的影響。\r\n\r\n不要更改此設置,除非你完全明白此設定會如何影響您的串流。\r\n\r\n面對任何指南建議的變更要謹慎。 你應該幾乎不需要更改此選項的預設值 (Very Fast)。\r\n\r\n你確定希望變更為預設嗎?"
|
||||
Settings.Advanced.ProcessPriority "程序優先級別"
|
||||
Settings.Advanced.SendBufferSize "緩衝大小:"
|
||||
Settings.Advanced.UnlockHigherFPS "在影像設定中允許輸入 61-120 FPS"
|
||||
Settings.Advanced.UseCBR "使用 CBR 固定位元率"
|
||||
|
@ -113,13 +115,11 @@ Settings.Advanced.VideoEncoderCPUTradeoff "x264 CPU 預設:"
|
|||
Settings.Advanced.VideoEncoderCPUTradeoffToolTip "設定更高的值犧牲某些部分的畫質降低 CPU 的使用率。另一方面,設定較低的值提高畫質則會增加更多的 CPU使用率。\r\n\r\n建議設定:Very Fast"
|
||||
Settings.Advanced.VideoEncoderSettings "自訂 x264 編碼設定"
|
||||
Settings.Advanced.VideoEncoderSettingsTooltip "允許您自訂 x264 編碼設定。 在欄位中輸入 [參數]=[值] (例如:\"vbv-maxrate=1000 vbv-bufsize=1000\")。"
|
||||
Settings.Advanced.ProcessPriority "程序優先級別"
|
||||
Settings.Advanced.PresetWarning "警告!改變 x264 預設可能在你的串流品質和 CPU 使用會有嚴重負面的影響。\r\n\r\n不要更改此設置,除非你完全明白此設定會如何影響您的串流。\r\n\r\n面對任何指南建議的變更要謹慎。 你應該幾乎不需要更改此選項的預設值 (Very Fast)。\r\n\r\n你確定希望變更為預設嗎?"
|
||||
Settings.Advanced.BindToIP "綁定到介面:"
|
||||
|
||||
Settings.Audio.Device "麥克風/輔助音訊裝置:"
|
||||
Settings.Audio.ForceMicMono "強制麥克風/輔助音訊裝置單聲道:"
|
||||
Settings.Audio.MicBoost "麥克風/輔助音訊裝置音量增量 (多工):"
|
||||
Settings.Audio.MicTimeOffset "麥克風時間偏移 (毫秒):"
|
||||
Settings.Audio.MuteDesktopHotkey "桌面靜音/回復熱鍵:"
|
||||
Settings.Audio.MuteMicHotkey "麥克風靜音/回復熱鍵:"
|
||||
Settings.Audio.PushToTalkDelay "按鍵發話的延遲 (毫秒):"
|
||||
|
@ -204,7 +204,7 @@ Sources.SoftwareCaptureSource.InvertMouseOnClick "反轉游標點擊"
|
|||
Sources.SoftwareCaptureSource.Monitor "監控器:"
|
||||
Sources.SoftwareCaptureSource.MonitorCapture "監控器擷取"
|
||||
Sources.SoftwareCaptureSource.MonitorCaptureTooltip "停用 Aero 在影像設定中的最大 FPS 設定。"
|
||||
Sources.SoftwareCaptureSource.MouseCapture "擷取滑鼠"
|
||||
Sources.SoftwareCaptureSource.MouseCapture "擷取游標"
|
||||
Sources.SoftwareCaptureSource.Position "位置:"
|
||||
Sources.SoftwareCaptureSource.Refresh "重新整理"
|
||||
Sources.SoftwareCaptureSource.RegionCapture "區域"
|
||||
|
@ -248,3 +248,8 @@ Sources.TransitionSource.Bitmaps "點陣圖:"
|
|||
Sources.TransitionSource.Empty "沒有加入要顯示的點陣圖。"
|
||||
Sources.TransitionSource.FadeInOnly "只有淡入:"
|
||||
Sources.TransitionSource.TimeBetweenBitmaps "變換圖片間隔 (秒):"
|
||||
|
||||
Updater.DownloadNow "您現在想要下載他們嗎?"
|
||||
Updater.NewUpdates "以下為可用的更新:\r\n\r\n"
|
||||
Updater.RunningWarning "OBS 將重新啟動來安裝更新。\r\n\r\n您確定要繼續嗎?"
|
||||
Updater.UpdatesAvailable "有可用的更新"
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
Cancel "Annuller"
|
||||
ClassName "Video Optageenhed"
|
||||
DeviceSelection "Enhedsvalg"
|
||||
OK "OK"
|
||||
|
||||
DeviceSelection.Blend "Bland (1-1000):"
|
||||
DeviceSelection.ChromaKey "Chroma Nøgle"
|
||||
DeviceSelection.Color "Farve:"
|
||||
DeviceSelection.Config "Konfigurer"
|
||||
DeviceSelection.CustomResolution "Brugerdefineret Opløsning:"
|
||||
DeviceSelection.Device "Enhed:"
|
||||
DeviceSelection.ExistsInScene "En kilde, der bruger denne enhed, eksisterer allerede."
|
||||
DeviceSelection.ExistsSomewhere "Denne enhed bliver brugt som kilde i en eller flere scener."
|
||||
DeviceSelection.FlipImage "Flip Billede Vertikalt"
|
||||
DeviceSelection.FlipImageHorizontal "Flip Billede Horizontalt"
|
||||
DeviceSelection.FPS "FPS:"
|
||||
DeviceSelection.GlobalExists "En global kilde, der bruger denne enhed, eksisterer allerede."
|
||||
DeviceSelection.InvalidResolution "Ugyldig Opløsning"
|
||||
DeviceSelection.NoSound "Ingen Lyd"
|
||||
DeviceSelection.Opacity "Uigennemsigtighed"
|
||||
DeviceSelection.OutputSound "Output kun lyd til stream"
|
||||
DeviceSelection.PlayToDesktop "Output lyd til skrivebord"
|
||||
DeviceSelection.PreferredType "Brug Output Format"
|
||||
DeviceSelection.Refresh "Opdater"
|
||||
DeviceSelection.Resolution "Opløsning"
|
||||
DeviceSelection.Select "Vælg"
|
||||
DeviceSelection.Similarity "Lighed (1-1000):"
|
||||
DeviceSelection.Sound "Lyd"
|
||||
DeviceSelection.SoundOffset "Lydens Tidsforskydning (millisekunder):
|
||||
DeviceSelection.SpillReduction "Reduktion af Spild (1-1000):"
|
||||
DeviceSelection.UnsupportedResolution "Denne enhed understøtter ikke den opløsning"
|
||||
DeviceSelection.UseChromaKey "Brug Chroma Nøgle"
|
||||
|
||||
Plugin.Description "Dette plugin muliggør at du kan tilfæje DirectShow videoenheder (webkameraer, optagekort, osv) to scenen"
|
||||
Plugin.Name "DirectShow Videoenhed Plugin"
|
|
@ -16,15 +16,20 @@ DeviceSelection.FlipImageHorizontal "水平翻轉影像"
|
|||
DeviceSelection.FPS "FPS:"
|
||||
DeviceSelection.GlobalExists "已經有全域來源在使用這個裝置。"
|
||||
DeviceSelection.InvalidResolution "無效的解析度"
|
||||
DeviceSelection.NoSound "沒有聲音"
|
||||
DeviceSelection.Opacity "不透明度"
|
||||
DeviceSelection.OutputSound "只有輸出至串流"
|
||||
DeviceSelection.PlayToDesktop "輸出聲音到桌面"
|
||||
DeviceSelection.PreferredType "使用偏好的輸出類型"
|
||||
DeviceSelection.Refresh "重新整理"
|
||||
DeviceSelection.Resolution "解析度:"
|
||||
DeviceSelection.Select "選擇"
|
||||
DeviceSelection.Similarity "相似度 (1-1000):"
|
||||
DeviceSelection.Sound "聲音"
|
||||
DeviceSelection.SoundOffset "聲音時間偏移 (毫秒):
|
||||
DeviceSelection.SpillReduction "溢出減少 (1-1000):"
|
||||
DeviceSelection.UnsupportedResolution "這個裝置無法支援此解析度"
|
||||
DeviceSelection.UseChromaKey "使用色度碼"
|
||||
|
||||
Plugin.Description "這個插件可以讓您將 DirectShow 視訊裝置 (網路攝影機、擷取卡...等) 加入到場景中。"
|
||||
Plugin.Name "DirectShow 視訊裝置插件"
|
||||
Plugin.Name "DirectShow 視訊裝置插件"
|
||||
|
|
Loading…
Reference in New Issue