void UpdateSettings()
    {
        for(UINT i=0; i<bitmapImages.Num(); i++)
            delete bitmapImages[i];
        bitmapImages.Clear();

        //------------------------------------

        bool bFirst = true;

        StringList bitmapList;
        data->GetStringList(TEXT("bitmap"), bitmapList);
        for(UINT i=0; i<bitmapList.Num(); i++)
        {
            String &strBitmap = bitmapList[i];
            if(strBitmap.IsEmpty())
            {
                AppWarning(TEXT("BitmapTransitionSource::UpdateSettings: Empty path"));
                continue;
            }

            BitmapImage *bitmapImage = new BitmapImage;
            bitmapImage->SetPath(strBitmap);
            bitmapImage->EnableFileMonitor(false);
            bitmapImage->Init();

            if(bFirst)
            {
                fullSize = bitmapImage->GetSize();
                baseAspect = double(fullSize.x)/double(fullSize.y);
                bFirst = false;
            }

            bitmapImages << bitmapImage;
        }

        //------------------------------------

        transitionTime = data->GetFloat(TEXT("transitionTime"));
        if(transitionTime < MIN_TRANSITION_TIME)
            transitionTime = MIN_TRANSITION_TIME;
        else if(transitionTime > MAX_TRANSITION_TIME)
            transitionTime = MAX_TRANSITION_TIME;

        //------------------------------------

        bFadeInOnly = data->GetInt(TEXT("fadeInOnly"), 1) != 0;
        bDisableFading = data->GetInt(TEXT("disableFading")) != 0;
        bRandomize = data->GetInt(TEXT("randomize")) != 0;

        //------------------------------------

        curTransitionTime = 0.0f;
        curTexture = 0;

        if(bRandomize)
        {
            srand( (unsigned)time( NULL ) );
            if(bitmapImages.Num() > 1)
            {
                curTexture = lrand(bitmapImages.Num());
                while((nextTexture = lrand(bitmapImages.Num())) == curTexture);
            }
        }
        else
            nextTexture = (curTexture == bitmapImages.Num()-1) ? 0 : curTexture+1;

        bTransitioning = false;
        curFadeValue = 0.0f;
    }
示例#2
0
void SettingsPublish::OptimizeSettings()
{
    auto refresh_on_exit = GuardScope([&] { SetWarningInfo(); });
    XConfig serverData;
    if (!serverData.Open(L"services.xconfig"))
        return;

    XElement *services = serverData.GetElement(L"services");
    if (!services)
        return;

    UINT numServices = services->NumElements();

    int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0), 0);
    XElement *r = nullptr;
    for (UINT i = 0; i < numServices; i++)
    {
        XElement *service = services->GetElementByID(i);
        if (service->GetInt(L"id") != serviceID)
            continue;

        //check to see if the service we're using has recommendations
        if (!service->HasItem(L"recommended"))
            return;

        r = service->GetElement(L"recommended");
        break;
    }

    if (!r)
        return;

    using optimizers_t = std::vector<std::function<void()>>;
    optimizers_t optimizers;

    String changes = Str("Settings.Publish.Optimize.Optimizations");

    String currentAudioCodec = AppConfig->GetString(L"Audio Encoding", L"Codec", L"AAC");
    int audioBitrate = AppConfig->GetInt(L"Audio Encoding", L"Bitrate", 96);

    if (r->HasItem(L"ratecontrol"))
    {
        bool useCBR = AppConfig->GetInt(L"Video Encoding", L"UseCBR", 1) != 0;
        CTSTR rc = r->GetString(L"ratecontrol");
        if (!scmp(rc, L"cbr") && !useCBR)
        {
            optimizers.push_back([] { AppConfig->SetInt(L"Video Encoding", L"UseCBR", 1); });
            changes << Str("Settings.Publish.Optimize.UseCBR");
        }
    }

    if (r->HasItem(L"max bitrate"))
    {
        int maxBitrate = AppConfig->GetInt(L"Video Encoding", L"MaxBitrate", 1000);
        int max_bitrate = r->GetInt(L"max bitrate");
        if (maxBitrate > max_bitrate)
        {
            optimizers.push_back([max_bitrate] { AppConfig->SetInt(L"Video Encoding", L"MaxBitrate", max_bitrate); });
            changes << FormattedString(Str("Settings.Publish.Optimize.Maxbitrate"), max_bitrate);
        }
    }

    if (r->HasItem(L"supported audio codec"))
    {
        StringList codecs;
        r->GetStringList(L"supported audio codec", codecs);
        if (codecs.FindValueIndex(currentAudioCodec) == INVALID)
        {
            String codec = codecs[0];
            optimizers.push_back([codec]
            {
                AppConfig->SetString(L"Audio Encoding", L"Codec", codec.Array());
                AppConfig->SetInt(L"Audio Encoding", L"Format", codec.CompareI(L"AAC") ? 1 : 0); //set to 44.1 kHz in case of MP3, see SettingsEncoding.cpp
            });
            changes << FormattedString(Str("Settings.Publish.Optimize.UnsupportedAudioCodec"), codec.Array());
        }
    }

    if (r->HasItem(L"max audio bitrate aac") && (!scmp(currentAudioCodec, L"AAC")))
    {
        int maxaudioaac = r->GetInt(L"max audio bitrate aac");
        if (audioBitrate > maxaudioaac)
        {
            optimizers.push_back([maxaudioaac] { AppConfig->SetInt(L"Audio Encoding", L"Bitrate", maxaudioaac); });
            changes << FormattedString(Str("Settings.Publish.Optimize.MaxAudiobitrate"), maxaudioaac);
        }
    }

    if (r->HasItem(L"max audio bitrate mp3") && (!scmp(currentAudioCodec, L"MP3")))
    {
        int maxaudiomp3 = r->GetInt(L"max audio bitrate mp3");
        if (audioBitrate > maxaudiomp3)
        {
            optimizers.push_back([maxaudiomp3] { AppConfig->SetInt(L"Audio Encoding", L"Bitrate", maxaudiomp3); });
            changes << FormattedString(Str("Settings.Publish.Optimize.MaxAudiobitrate"), maxaudiomp3);
        }
    }

    if (r->HasItem(L"profile"))
    {
        String currentx264Profile = AppConfig->GetString(L"Video Encoding", L"X264Profile", L"high");
        String expectedProfile = r->GetString(L"profile");
        if (!expectedProfile.CompareI(currentx264Profile))
        {
            optimizers.push_back([expectedProfile] { AppConfig->SetString(L"Video Encoding", L"X264Profile", expectedProfile); });
            changes << FormattedString(Str("Settings.Publish.Optimize.RecommendMainProfile"), expectedProfile.Array());
        }
    }

    if (r->HasItem(L"keyint"))
    {
        int keyframeInt = AppConfig->GetInt(L"Video Encoding", L"KeyframeInterval", 0);
        int keyint = r->GetInt(L"keyint");
        if (!keyframeInt || keyframeInt * 1000 > keyint)
        {
            optimizers.push_back([keyint] { AppConfig->SetInt(L"Video Encoding", L"KeyframeInterval", keyint / 1000); });
            changes << FormattedString(Str("Settings.Publish.Optimize.Keyint"), keyint / 1000);
        }
    }

    if (OBSMessageBox(hwnd, changes.Array(), Str("Optimize"), MB_OKCANCEL | MB_ICONINFORMATION) != IDOK)
        return;

    for (optimizers_t::const_reference i : optimizers)
        i();
}
    void UpdateSettings()
    {
        for(UINT i=0; i<textures.Num(); i++)
            delete textures[i];
        textures.Clear();

        //------------------------------------

        bool bFirst = true;

        StringList bitmapList;
        data->GetStringList(TEXT("bitmap"), bitmapList);
        for(UINT i=0; i<bitmapList.Num(); i++)
        {
            String &strBitmap = bitmapList[i];
            if(strBitmap.IsEmpty())
            {
                AppWarning(TEXT("BitmapTransitionSource::UpdateSettings: Empty path"));
                continue;
            }

            Texture *texture = GS->CreateTextureFromFile(strBitmap, TRUE);
            if(!texture)
            {
                AppWarning(TEXT("BitmapTransitionSource::UpdateSettings: could not create texture '%s'"), strBitmap.Array());
                continue;
            }

            if(bFirst)
            {
                fullSize.x = float(texture->Width());
                fullSize.y = float(texture->Height());
                baseAspect = double(fullSize.x)/double(fullSize.y);
                bFirst = false;
            }

            textures << texture;
        }

        if(textures.Num() == 0)
            CreateErrorTexture();

        //------------------------------------

        transitionTime = data->GetFloat(TEXT("transitionTime"));
        if(transitionTime < MIN_TRANSITION_TIME)
            transitionTime = MIN_TRANSITION_TIME;
        else if(transitionTime > MAX_TRANSITION_TIME)
            transitionTime = MAX_TRANSITION_TIME;

        //------------------------------------

        bFadeInOnly = data->GetInt(TEXT("fadeInOnly")) != 0;
        bDisableFading = data->GetInt(TEXT("disableFading")) != 0;
        bRandomize = data->GetInt(TEXT("randomize")) != 0;

        //------------------------------------

        curTransitionTime = 0.0f;
        curTexture = 0;

        if(bRandomize)
        {
            srand( (unsigned)time( NULL ) );
            if(textures.Num() > 1)
            {
                curTexture = lrand(textures.Num());
                while((nextTexture = lrand(textures.Num())) == curTexture);
            }
        }
        else
            nextTexture = (curTexture == textures.Num()-1) ? 0 : curTexture+1;

        bTransitioning = false;
        curFadeValue = 0.0f;
    }
示例#4
0
void SettingsPublish::SetWarningInfo()
{
    int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0), 0);

    bool bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0;
    int maxBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
    int keyframeInt = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0);
    int audioBitRate = AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96);
    String currentx264Profile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), L"high");
    String currentAudioCodec = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC"));
    float currentAspect = AppConfig->GetInt(L"Video", L"BaseWidth") / (float)max(1, AppConfig->GetInt(L"Video", L"BaseHeight"));

    //ignore for non-livestreams
    if (data.mode != 0)
    {
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
        return;
    }

    bool hasErrors = false;
    bool canOptimize = false;
    String strWarnings;

    XConfig serverData;
    if(serverData.Open(TEXT("services.xconfig")))
    {
        XElement *services = serverData.GetElement(TEXT("services"));
        if(services)
        {
            UINT numServices = services->NumElements();

            for(UINT i=0; i<numServices; i++)
            {
                XElement *service = services->GetElementByID(i);
                if (service->GetInt(TEXT("id")) == serviceID)
                {
                    strWarnings = FormattedString(Str("Settings.Publish.Warning.BadSettings"), service->GetName());

                    //check to see if the service we're using has recommendations
                    if (!service->HasItem(TEXT("recommended")))
                    {
                        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
                        return;
                    }

                    XElement *r = service->GetElement(TEXT("recommended"));

                    if (r->HasItem(TEXT("ratecontrol")))
                    {
                        CTSTR rc = r->GetString(TEXT("ratecontrol"));
                        if (!scmp (rc, TEXT("cbr")) && !bUseCBR)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << Str("Settings.Publish.Warning.UseCBR");
                        }
                    }

                    if (r->HasItem(TEXT("max bitrate")))
                    {
                        int max_bitrate = r->GetInt(TEXT("max bitrate"));
                        if (maxBitRate > max_bitrate)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Maxbitrate"), max_bitrate);
                        }
                    }

                    if (r->HasItem(L"supported audio codec"))
                    {
                        StringList codecs;
                        r->GetStringList(L"supported audio codec", codecs);
                        if (codecs.FindValueIndex(currentAudioCodec) == INVALID)
                        {
                            String msg = Str("Settings.Publish.Warning.UnsupportedAudioCodec"); //good thing OBS only supports MP3 (and AAC), otherwise I'd have to come up with a better translation solution
                            msg.FindReplace(L"$1", codecs[0].Array());
                            msg.FindReplace(L"$2", currentAudioCodec.Array());
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << msg;
                        }
                    }

                    if (r->HasItem(TEXT("max audio bitrate aac")) && (!scmp(currentAudioCodec, TEXT("AAC"))))
                    {
                        int maxaudioaac = r->GetInt(TEXT("max audio bitrate aac"));
                        if (audioBitRate > maxaudioaac)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudioaac);
                        }
                    }

                    if (r->HasItem(TEXT("max audio bitrate mp3")) && (!scmp(currentAudioCodec, TEXT("MP3"))))
                    {
                        int maxaudiomp3 = r->GetInt(TEXT("max audio bitrate mp3"));
                        if (audioBitRate > maxaudiomp3)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudiomp3);
                        }
                    }

                    if (r->HasItem(L"video aspect ratio"))
                    {
                        String aspectRatio = r->GetString(L"video aspect ratio");
                        StringList numbers;
                        aspectRatio.GetTokenList(numbers, ':');
                        if (numbers.Num() == 2)
                        {
                            float aspect = numbers[0].ToInt() / max(1.f, numbers[1].ToFloat());
                            if (!CloseFloat(aspect, currentAspect))
                            {
                                String aspectLocalized = Str("Settings.Video.AspectRatioFormat");
                                aspectLocalized.FindReplace(L"$1", UIntString(numbers[0].ToInt()));
                                aspectLocalized.FindReplace(L"$2", UIntString(numbers[1].ToInt()));

                                String msg = Str("Settings.Publish.Warning.VideoAspectRatio");
                                msg.FindReplace(L"$1", aspectLocalized);
                                strWarnings << msg;
                                hasErrors = true;
                            }
                        }
                    }

                    if (r->HasItem(TEXT("profile")))
                    {
                        String expectedProfile = r->GetString(TEXT("profile"));

                        if (!expectedProfile.CompareI(currentx264Profile))
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << Str("Settings.Publish.Warning.RecommendMainProfile");
                        }
                    }

                    if (r->HasItem(TEXT("keyint")))
                    {
                        int keyint = r->GetInt(TEXT("keyint"));
                        if (!keyframeInt || keyframeInt * 1000 > keyint)
                        {
                            hasErrors = true;
                            canOptimize = true;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Keyint"), keyint / 1000);
                        }
                    }

                    break;
                }
            }
        }
    }

    if (hasErrors)
    {
        if (canOptimize)
            strWarnings << Str("Settings.Publish.Warning.CanOptimize");
        SetDlgItemText(hwnd, IDC_WARNINGS, strWarnings.Array());
    }
    else
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
    SetCanOptimizeSettings(canOptimize);
}
示例#5
0
void SettingsPublish::SetWarningInfo()
{
    int serviceID = (int)SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETITEMDATA, SendMessage(GetDlgItem(hwnd, IDC_SERVICE), CB_GETCURSEL, 0, 0), 0);

    bool bUseCBR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCBR"), 1) != 0;
    int maxBitRate = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000);
    int keyframeInt = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("KeyframeInterval"), 0);
    int audioBitRate = AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96);
    String currentx264Profile = AppConfig->GetString(TEXT("Video Encoding"), TEXT("X264Profile"), L"high");
    String currentAudioCodec = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC"));

    //ignore for non-livestreams
    if (data->mode != 0)
    {
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
        return;
    }

    int errors = 0;
    String strWarnings;

    XConfig serverData;
    if(serverData.Open(TEXT("services.xconfig")))
    {
        XElement *services = serverData.GetElement(TEXT("services"));
        if(services)
        {
            UINT numServices = services->NumElements();

            for(UINT i=0; i<numServices; i++)
            {
                XElement *service = services->GetElementByID(i);
                if (service->GetInt(TEXT("id")) == serviceID)
                {
                    strWarnings = FormattedString(Str("Settings.Publish.Warning.BadSettings"), service->GetName());

                    //check to see if the service we're using has recommendations
                    if (!service->HasItem(TEXT("recommended")))
                    {
                        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));
                        return;
                    }

                    XElement *r = service->GetElement(TEXT("recommended"));

                    if (r->HasItem(TEXT("ratecontrol")))
                    {
                        CTSTR rc = r->GetString(TEXT("ratecontrol"));
                        if (!scmp (rc, TEXT("cbr")) && !bUseCBR)
                        {
                            errors++;
                            strWarnings << Str("Settings.Publish.Warning.UseCBR");
                        }
                    }

                    if (r->HasItem(TEXT("max bitrate")))
                    {
                        int max_bitrate = r->GetInt(TEXT("max bitrate"));
                        if (maxBitRate > max_bitrate)
                        {
                            errors++;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Maxbitrate"), max_bitrate);
                        }
                    }

                    if (r->HasItem(TEXT("profile")))
                    {
                        String expectedProfile = r->GetString(TEXT("profile"));

                        if (!expectedProfile.CompareI(currentx264Profile))
                        {
                            errors++;
                            strWarnings << Str("Settings.Publish.Warning.RecommendMainProfile");
                        }
                    }

                    if (r->HasItem(TEXT("max audio bitrate aac")) && (!scmp(currentAudioCodec, TEXT("AAC"))))
                    {
                        int maxaudioaac = r->GetInt(TEXT("max audio bitrate aac"));
                        if (audioBitRate > maxaudioaac)
                        {
                            errors++;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudioaac);
                        }
                    }
                    
                    if (r->HasItem(TEXT("max audio bitrate mp3")) && (!scmp(currentAudioCodec, TEXT("MP3"))))
                    {
                        int maxaudiomp3 = r->GetInt(TEXT("max audio bitrate mp3"));
                        if (audioBitRate > maxaudiomp3)
                        {
                            errors++;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.MaxAudiobitrate"), maxaudiomp3);
                        }
                    }

                    if (r->HasItem(TEXT("keyint")))
                    {
                        int keyint = r->GetInt(TEXT("keyint"));
                        if (!keyframeInt || keyframeInt * 1000 > keyint)
                        {
                            errors++;
                            strWarnings << FormattedString(Str("Settings.Publish.Warning.Keyint"), keyint / 1000);
                        }
                    }

                    if (r->HasItem(L"supported audio codec"))
                    {
                        StringList codecs;
                        r->GetStringList(L"supported audio codec", codecs);
                        if (codecs.FindValueIndex(currentAudioCodec) == INVALID)
                        {
                            String msg = Str("Settings.Publish.Warning.UnsupportedAudioCodec"); //good thing OBS only supports MP3 (and AAC), otherwise I'd have to come up with a better translation solution
                            msg.FindReplace(L"$1", codecs[0].Array());
                            msg.FindReplace(L"$2", currentAudioCodec.Array());
                            errors += 1;
                            strWarnings << msg;
                        }
                    }

                    break;
                }
            }
        }
    }

    if (errors)
        SetDlgItemText(hwnd, IDC_WARNINGS, strWarnings.Array());
    else
        SetDlgItemText(hwnd, IDC_WARNINGS, TEXT(""));

}