diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..4b0e759 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +open_collective: obsproject +patreon: obsproject diff --git a/.gitignore b/.gitignore index 19fb10b..f78f47a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ x64/ ipch/ GeneratedFiles/ .moc/ +/UI/obs.rc /other/ diff --git a/.gitmodules b/.gitmodules index 498a346..fa1c4f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,7 +6,7 @@ url = https://github.com/palana/Syphon-Framework.git [submodule "plugins/enc-amf"] path = plugins/enc-amf - url = https://github.com/Xaymar/obs-studio_amf-encoder-plugin.git + url = https://github.com/obsproject/obs-amd-encoder.git [submodule "plugins/obs-browser"] path = plugins/obs-browser url = https://github.com/obsproject/obs-browser.git diff --git a/.travis.yml b/.travis.yml index 9100196..939917e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,7 +29,7 @@ matrix: before_deploy: "./CI/before-deploy-osx.sh" - os: linux - dist: trusty + dist: xenial sudo: required before_install: "./CI/install-dependencies-linux.sh" before_script: "./CI/before-script-linux.sh" @@ -50,21 +50,10 @@ deploy: condition: "$TRAVIS_OS_NAME = osx" all_branches: true -# The channel name "azubu.il.us.quakenet.org#obs-dev" is encrypted against jp9000/obs-studio to prevent IRC spam of forks -#notifications: -# irc: -# skip_join: false -# template: -# - "[Travis CI|%{result}] %{repository_name}/%{branch} (%{author} - %{commit_subject}) %{build_url}" -# channels: -# - secure: k9j7+ogVODMlveZdd5pP73AVLCFl1VbzVaVon0ECn3EQcxnLSpiZbc6l+PnIUKgee5pRKtUB4breufgmr4puq3s69YeQiOVKk5gx2yJGZ5jGacbSne0xTspzPxapiEbVUkcJ2L7gKntDG4+SUiW67dtt4G26O7zsErDF/lY/woQ= -# on_failure: always -# on_success: change notifications: webhooks: urls: - - secure: T5RBY818nO40nr5eC8pdrCfAdQKGkjQdbyYw7mfFrhxWxgt/U5tyKXpX0l9zNGfobS0SnLSqF71OrfW04V97oijXx3q5Y24xV6mSrlLQZOq19+XvGp82LDpkVd4yi2N0kBYpoANB9Pkof4jWT/rKfdQCQttluOLjgr5SM0uWHRg= - secure: EVI2cu5OnNxVTl4jdVppps7O869gGN1PDcSi8fqq/HJVM5kif8iDe4wCrIKv6yWrK3dSNwRgBAwpcPZglRJnKRh23PdFoCdnTjgzBQlmjUR6BYlunQvoKR9mVX6AdT8zrFDgmtC4aOtGD2paptpqt+Equo25KrLwv+qOHJOTrSQ= - on_success: change + on_success: always on_failure: always diff --git a/AUTHORS b/AUTHORS index a2f5192..e0167d4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,513 +1,939 @@ +Original Author: Hugh Bailey ("Jim") + Contributors are sorted by their amount of commits / translated strings. Contributors: Jim Palana fryshorts +R1CH BtbN -John Bradley +DDRBoxman Gol-D-Ace -Richard Stanway -Colin Edwards +Shaolin +kc5nra +Ryan Foster Zachary Lund -Michael Fabian Dirks -Martell Malone cg2121 +Xaymar +SuslikV +Rodney Christoph Hohmann +pkv +Martell Malone HomeWorld dodgepong -Ryan Foster -derrod +Alex Anderson +juvester +Dmitry-Me +Fenrir Radzaquiel Socapex -juvester -Skyler Lipthay -SuslikV -Arkkis Cephas Reis -GoaLitiuM +Dillon Pentz +Kurt Kartaltepe +Luke Yelavich +mntone +sorayuki +Andrew Surzhynskyi +Skyler Lipthay +Arkkis Danni +GoaLitiuM +Hunter L. Allen +Marvin Scholz +Michel Snippe +Quinn Damerell +Tjienta Vara +craftwar +Clayton Groeneveld +Ilya Melamed Jess Mayo +Jimi Huotari Kris Moore +Alexandre Vicenzi Carl Fürstenberg +Kilian von Pflugk Anry CoDEmanX +H4ndy Ján Mlynek -Kurt Kartaltepe -Manuel Kroeber -sorayuki -Alexandre Vicenzi -Andrew Surzhynskyi +nleseul Benjamin Klettbach -bl +Bird, Christopher Bl00drav3n Blackhive Charles Ray Shisler III +Daniel Lopez +David Cooper +Exeldro Jeremiah Senkpiel -John R. Bradley -Kilian von Pflugk -mntone +Joseph El-Khouri +Matt WizardCM +Palakis +Philip Haynes +Robin Hielscher Serge Paquet +Timo Gurr +bl shiina424 shousa -Timo Gurr -adray +vokama +Alexander Schittler +Andreas Reischuck Andrei Nistor Azat Khasanshin -Ben Torell -bootkiller Brian S. Stephan -e00E +Chaturbate +Dead133 +DungFu Eric Bataille -Joseph El-Khouri -jpk +Igor Bochkariov +Justin Love Lexsus Lionheart Zhang +Lucian Poston +Matt Morrissette +Matthew McNamara +Michael Goulet +Skid-Inc +Taylor Blau +Tristan Matthews +Warchamp7 +Warren Turkal +adray +bootkiller +e00E +jpk paibox -Robin Hielscher skwerlman taesheren -Take Vos -Taylor Blau -Warren Turkal yogpstop Aarni Koskela +Abelardo E. Mendoza Aesen Vismea +Aidan Epstein Akagi201 +Alcaros Alexander Uhlmann Alexandre Biny -Andreas Reischuck +Alexandre Paré +Ali Kaviani Anthony Catel Anthony Super +Artem Merkulov Asgeir Mortensen Autumin Aydin Akan +Bas van Meel +Bazhenoff +Beau Russell +Ben Krueger +Ben Stahl +Benjamin Schubert Bernd Buschinski -bla -boombatower +Bjorn +Bongalive +C. Daniel Sanchez R Caitlin Potter Caleb Anderson CallumHoward Cam +Can Bal +Cheeseness CommanderRoot Copy Liu -craftwar Cray Elliott -cryptonaut Dan Dascalescu -David Cooper David McMackins II -dennis Derrick Lambert +Dmitry Odintsov Emil Sayahi EpicCoder Ethan Lee +Fazrad Karkhani Frank Gehann +Fred Emmott +Garrett Giorgio Pellero +Gregory Luneau Grigorii Chirkov Guillermo A. Amaral Gökberk Yaltıraklı Haden F +Han-Tai Chen +Hicham LEMGHARI Iblis Lin -Igor Bochkariov +J Lynn +J.D. Purcell Jake Probst +James Hurley Jamy Timmermans +JetMeta Jimmy Berry Jkoan -Joel Bethke +John Cheng +Jonathan +Joshua Rowe Julian Miller Kazuki Oishi -ka’imi Kevin Kevin Tardif Lasse Dalegaard -lemmi Lioncash -Lucian Poston Lukas Monka -Luke Yelavich -mape +Makeenon Marc Chambers Mark Vaughn Mathias Panzenböck -Matthew McNamara +Matthew Szatmary MedicMomcilo -michael bishop +Micah Elizabeth Scott Michael Hoang Momcilo Medic -nd +Murnux Nicolas F Night +Olivier Humbert Olle Kelderman -Palakis -pantonvich -partouf Patrick Ancillotti Peter SZTANOJEV -pipll -raincomplex -repeat +Philip Loche Ricardo Constantino Rodrigo Ipince -rpslack Ryan Sullivan -sam8641 +SammyJames +Serge Martial Nguetta Seth Murphy Seung-Woo Kim Shamun -Shaolin Simon +Sophie Hamilton SoraYuki +Steve Wills +Tatsuyuki Ishi +Taylor Teemu Kauhanen -thekrzos +Terje Gundersen +Thomas Crider +Thomas De Schampheleire Thomas McGrew +Thomas Schnitzler +Tom Peeters +Tom Pichler TotalCaesar659 -trwnh -vic -vividnightmare -VodBox -wayne wang +Wahaj Dar Weikardzaena Will Jamieson William Casarin +Wouter Younes SERRAJ +Yvo Ziemas +adocilesloth +astudios123 +bla +bluekirby0 +boombatower +bth +chinasarft +comex +cryptonaut +dennis +eastkiki +fefine +jamacanbacn +jeremiah +ka’imi +lemmi +mape +mhabedinpour +michael bishop +nd +notmark +pantonvich +partouf +pipll +pkuznetsov +probonopd +raincomplex +repeat +rkfg +rpslack +sam8641 +thekrzos +trwnh +vic +vividnightmare +wangrui05 +wayne wang -Translations: -Arabic - Abdullah AL-Qahtani (Za7ef_SA) - majdcomp - ZILZAL - BWU Wheelman (Wheelman) - Saleh Luxmaroc (salehoukiki) - Gol D. Ace (goldace) - معتصم دعنا (rozana-media) - chaironeko - dodgepong - FC Barcelona HD (kurdnews) -Basque - Alexander Gabilondo (alexgabi) - Xabier Aramendi (azpidatziak) - Osoitz - txaro - etxondoko - Gol D. Ace (goldace) - dodgepong -Bengali - shamuntohamd -Bulgarian - kalmarin - Seyhan Halil (yildirim17) - Viktor Kitov (viktorkitov) - Stanislav_Evtimov - Ivan (SKDown) -Catalan - Jaime Muñoz Martín (jmmartin_5) - jmontane - Nil Campamà (Soifam) - Aleix Vidal i Gaya (leixet) - Gol D. Ace (goldace) -Chinese Simplified - Bob Liu (Akagi201) - PabloLiu (719018105) - Sasasu - cai_miao - David Kuo (s50407s) - Boyuan Yang (073plan) - 鲜童 (xiananjyzy) - copyliu - wwj402_github - Bing Feng (fengbing123) - Hexcolyte - Gol D. Ace (goldace) - dodgepong - WaterOtaku -Chinese Traditional - TzeKei Lee (chikei) - dodgepong - Julian_Lai - Chien-Yu Lin (u900011) - David Kuo (s50407s) - You-Ruei Tzeng (e222et) - Inndy.Lin (inndy) - Meng Hao Li (GazCore) - Gol D. Ace (goldace) - Wingo Chan (wingo19932003) - ak-47root - Watson Tsai (ashaneba) - Han-Jen Cheng (notexist) - cai_miao - Jimmy Huang (f56112000) - chaironeko - tomoe-musashi -Croatian - medicmomcilo - Gol D. Ace (goldace) - dodgepong -Czech - Jirka 'Venty' Michel (VentyCZ) - Sawanyo - dodgepong - Kiznoh -Danish - Jens Hyllegaard (Hyllegaard) - NCAA - Anders G. Jørgensen (spirit55555) - MaltahlGaming (maltahlgaming) - Anders Urban (minikaliffen) - Christian Henriksen (cnhenriksen) - Gol D. Ace (goldace) - Johan Keller Jensen (JKeller) -Dutch - Eric Bataille (ThoNohT) - Michel Snippe (michelsnippe) - Greendweller - robbert0891 (robbertoorschot38) - Nicole (Dutchess_Nicole) - Jasper J (JassieJ) - Gol D. Ace (goldace) - Bo Alsemgeest (bo.alsemgeest.wausie) - JorRy - Julian Meijboom (julianmeijboom) - markpc -Estonian - MartinEwing - AndresTraks -Finnish - ArkkisN (j) - Jarska - dodgepong - Obama (Obama44) - Gol D. Ace (goldace) - chaironeko -French - radzaquiel - Nunzio Conte (nunzioconte54) - Yberion - Léo (leeo97one) - Stéphane Lepin (Palakis) - DoK_- - BoboopTeam - DarkInFire - Ben Turner (ben-turner) - steve_fr - Grisou2907 - Theguiguix - McGuygnol - Gabriel Dugny (Gabigabigo) - Gol D. Ace (goldace) - GANGAT Naeem (zboggum) - kyllian (tardigradeus) - dodgepong - chaironeko -Galician - Xesús M. Mosquera Carregal (xesusmosquera) - Gol D. Ace (goldace) - chaironeko -German - Gol D. Ace (goldace) - Michael Fabian Dirks (Xaymar) - dodgepong - Benjamin Klettbach (benklett) - Sven Kirschbaum (fallobst22) (fallobst22) - random31415 - Palana - Dennis Giebert (Isegrim) (isegrimderwolf) - Jonathan (macburgerjunior) - Robin Hielscher (Jack0r) - Tim (robske_110) (robske110) - BoJustus - Jonas Otto (jottosmail) - mdod - Prince_of_Raop - Tiim - WurstOnAir -Greek - Mepharees - Tasos Sahanidis (tatokis) - Alex Kalles (alexakis1997) - iosifidis - chaironeko - dodgepong -Hebrew - amirsher - Chemi - epic_ziver_D -Hindi - shamuntohamd -Hungarian - Gige - Adam Liszkai (adamos42) - dodgepong - Gol D. Ace (goldace) -Italian - LordShadow95 - Marocco2 - smart2128 - dodgepong - Edoardo Macrì (edomacri) - Edoardo “OfficialDJMela” Macrì (agersforum) - ScemEnzo - Gol D. Ace (goldace) - Fisherozzo - Sergio Beneduce (sbeneduce) - SkyLion -Japanese - shousa - Kenta (kenta0644) - dodgepong - chaironeko -Korean - Wonjoo Noh (ynetwork) - Gol D. Ace (goldace) - antome -Lithuanian - Justas Vilimas (tyntas) -Malay - amsyar ZeRo (amsyarminer555) - dodgepong -Norwegian Bokmal - Taesh (magnusmbratteng) - dodgepong - mgKaiztra - Tommy (nwgat) - Oddbjørn Grytdal (Fooshi) - Decicus - Sander Skjegstad (r530er) - Legend27 - Gol D. Ace (goldace) - areedw - chaironeko - Mats Andreassen (MatsA) -Pirate English - Matthew Hatcher (MatthewSH) - jkcoaster - Charlie W. (wallichc) - iltrof - chaironeko - Gol D. Ace (goldace) -Polish - grocal - Michał Durak (micechal) - Damian Korcz (damikiller) - opl - Gol D. Ace (goldace) - dodgepong - Mateusz (Silesianek) - Michał Lewczak (michal200507) -Portuguese - André Biscaia (LazP) - dodgepong - joaoboia - Gol D. Ace (goldace) -Portuguese, Brazilian - Shaolin (admshao) - Ramon Mendes (rbrgameplays) - Fabio Madia (Shaolin) - TFSThiagoBR98 - CaioWzy - clr0dr1g - mizifih - aalonsomb - André Gama (ToeOficial) - Gol D. Ace (goldace) - ThisGuy - dodgepong -Romanian - Cristian Silaghi (stelistcristi) - banrek - Hisashi - Gol D. Ace (goldace) - chaironeko - dodgepong -Russian - iltrof - Alek Nirov (dectanova) - VNGXR - dodgepong - Pavel (Shevalie) - Maxim Gribanov (MaximGribanov) - Bugo - Andy (anry025) - fromgate - Gol D. Ace (goldace) - Andrei Stepanov (adem4ik) - Vlad (KoTmaxHo) - Mixaill - Sergei Fug1t1v3 (fug) - Walt Gee (vovanych) - Sigge Stjärnholm (Kladdy) - Yuri Mihaqlov (yurijmi) -Serbian (Cyrillic) - medicmomcilo - Gol D. Ace (goldace) -Serbian (Latin) - medicmomcilo - Gol D. Ace (goldace) - dodgepong -Slovak - Ján M (longmoped) - Anton Lokaj (anlo) - LoLLy Nka (lollynka279) - Gol D. Ace (goldace) -Slovenian - kristjan.krusic (krusic22) - Gol D. Ace (goldace) - ArcaneWater - dodgepong -Spanish - Roberto Lorenzo (HonzoNebro) - Jaime Martinez Rincon (mrjaime1999) - Marcos Vidal Martinez (M4RK22) - Jaime Muñoz Martín (jmmartin_5) - Maximiliano Schtroumpftech Pena-Roig (som2tokmynam) - Ruben Deig Ramos (rdeigramos) - Eleazar Córcoles (MtrElee3) - Gol D. Ace (goldace) - Sigge Stjärnholm (Kladdy) - chaironeko - dodgepong - Rodrigo Ipince (ipince) - Rubén Pérez (RixzZ) -Swedish - Anton R (FirePhoenix) - Sigge Stjärnholm (Kladdy) - Laccy IEST (Laccy) - Olle Dahström (odahlstrom) - Gustav Ekner (ekner) - Gol D. Ace (goldace) - Henrik Mattsson-Mårn (rchk) - chaironeko - Jonas Svensson (jonassanojj99) -Tamil - Kolappan Nathan (kolappannathan) -Thai - sakuhanachan* (sakuhanachanloli) - 盛凤阁 (execzero) - nongnoobjung (kitcharuk_4) - dodgepong - Gol D. Ace (goldace) -Turkish - Ali Kömesöğütlü (Mobile46) (byzlo685) - omer.karagoz (mrkaragoz) - monolifed - Cemal Dursun (cmldrs) - Savas Tokmak (Laserist) - Murat Karagöz (anemon_1994) - gecebekcisi1 - Gol D. Ace (goldace) - Hydroboost - mustafaa -Ukrainian - SuslikV - Юрій (Devinit) - Andy (anry025) - Maksym Tymoshyk (maximillian_) -Urdu (Pakistan) - shamuntohamd -Vietnamese - Johnny “max20091” Utah (boostyourprogram) - Hưng Nguyễn (hoyostudio) - Hà Phi Hùng (haphihungcom) - Gol D. Ace (goldace) - dodgepong +Translators: +Afrikaans: + - Samuel Nthoroane (Samuel_Nthoroane) +Albanian: + - Albin Pllana (albinnpllanaa) + - Aredio Vani (aredio.vani) +Arabic: + - ZILZAL + - Abdullah AL-Qahtani (Za7ef_SA) + - majdcomp + - aaakjt + - Gol D. Ace (goldace) + - BWU Wheelman (Wheelman) + - Saleh Luxmaroc (salehoukiki) + - معتصم دعنا (rozana-media) + - Hani Sweileh (hno.sweileh) + - Mustafa2018 + - Tensai + - Vainock (ivo.lemmert) + - Mnsor The-Ghost (mnsor1722011) + - FC Barcelona HD (kurdnews) + - Ndalabo Taema (hake_bsowq) + - dodgepong + - chaironeko +Azerbaijani: + - Shahin Farzaliyev (Khan27) +Basque: + - Alexander Gabilondo (alexgabi) + - Osoitz (Osoitz) + - Gol D. Ace (goldace) + - txaro (txaro) + - EG Gamer (eggamer131) + - etxondoko + - Vainock (ivo.lemmert) + - dodgepong +Bengali: + - shamuntohamd + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Nurul Huda (nurulhuda859) + - Md Arafat (zonoiko) +Bulgarian: + - j3dy + - kalmarin + - Zakxaev68 + - Seyhan Halil (yildirim17) + - Dremski + - Martin Georgiev (DivideByNone) + - Viktor Kitov (viktorkitov) + - Stanislav_Evtimov + - Stoyan Stoyanov (sstoyanov) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Ivan (SKDown) + - Warchamp7 +Catalan: + - Jaime Muñoz Martín (jmmartin_5) + - jmontane + - Nil Campamà (Soifam) + - Benet R. i Camps (BennyBeat) (BennyBeat) + - Aleix Vidal i Gaya (leixet) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Pere O. (gotrunks) + - Aniol Pagès (aniolpages) +Chinese Simplified: + - Bob Liu (Akagi201) + - AlexGuo1998 (AlexGuo1998) + - wwj402_github + - PabloLiu (719018105) + - Gol D. Ace (goldace) + - Licardo (Licardo) + - AthlonHD (AthlonHD) + - Hexcolyte (Hexcolyte) + - Sasasu (Sasasu) + - cai_miao + - Boyuan Yang (073plan) + - David Kuo (s50407s) + - 鲜童 (xiananjyzy) + - Opportunity (OpportunityLiu) + - Forbidden (cptbl00dra1n) + - yunluzhang + - Inku Xuan (inkuxuan) + - copyliu + - Bing Feng (fengbing123) + - pan93412 + - WeiYuanStudio + - 科技小白堂 (lipeng0820) + - Richard Stanway (r1ch) + - WaterOtaku + - dodgepong + - MarsYoung + - sorayuki + - cylin + - Vainock (ivo.lemmert) + - 赵杭灵 (h1679083640) + - wordlessWind (wordlesswind) + - OYYZ + - FaZe Fakay (fazefakay) + - Bob Wei (BobWaver) +Chinese Traditional: + - TzeKei Lee (chikei) + - dodgepong + - Julian_Lai + - Chien-Yu Lin (u900011) + - pan93412 + - David Kuo (s50407s) + - Michael Yeh (hinet60613) + - You-Ruei Tzeng (e222et) + - myjourney in Steemit (myjourney) + - craftwar + - Gol D. Ace (goldace) + - Inndy.Lin (inndy) + - Han-Jen Cheng (notexist) + - Watson Tsai (ashaneba) + - Meng Hao Li (GazCore) + - abc0922001 + - Thomas (thomassth) + - louis921222 + - ak-47root + - Jimmy Huang (f56112000) + - cai_miao + - Append Huang (append) + - 曹恩逢 (nelson22768384) + - Vainock (ivo.lemmert) + - xixiaofan (Hs0) + - tomoe-musashi + - FaZe Fakay (fazefakay) + - chaironeko + - JackYeah +Croatian: + - medicmomcilo + - srdjan_m + - Runicar (dajtisina) + - OfficialwobY + - Gol D. Ace (goldace) + - Wildrage + - Maky (the.real.maky) + - Vainock (ivo.lemmert) + - dodgepong +Czech: + - Jirka 'Venty' Michel (VentyCZ) + - Kryštof Černý (cleverline1mc) + - Sawanyo + - Kiznoh + - Gol D. Ace (goldace) + - Erik Bročko (ericek111) + - Vainock (ivo.lemmert) + - dodgepong +Danish: + - NCAA (NCAA) + - Jens Hyllegaard (Hyllegaard) + - Anders G. Jørgensen (spirit55555) + - MaltahlGaming (maltahlgaming) + - Gol D. Ace (goldace) + - Anders Urban (minikaliffen) + - Richard Stanway (r1ch) + - Johan Keller Jensen (JKeller) + - Christian Henriksen (cnhenriksen) + - Vainock (ivo.lemmert) + - Marque Ziqulr (lugtelort) + - HeroGamers (Fido2603) + - Nicolai (Nicolai9852) + - Daniel Aundal (aundal) +Dutch: + - Eric Bataille (ThoNohT) + - Michel Snippe (michelsnippe) + - Greendweller + - Coen (Trigstur) + - exeldro (exeldro) + - Nicole (Dutchess_Nicole) + - robbert0891 (robbertoorschot38) + - Danny (Dkamps18) + - Gol D. Ace (goldace) + - Albakham (albakham) + - Jasper J (JassieJ) + - Bond-009 + - b__dm + - F_Producktions + - Harm van den Hoek (harm27) + - markpc + - JorRy + - Julian Meijboom (julianmeijboom) + - Bo Alsemgeest (bo.alsemgeest.wausie) + - andymidside + - JustMaffie (JustMaffie) + - RyyzQ + - Vainock (ivo.lemmert) +Estonian: + - MartinEwing + - AndresTraks + - Gol D. Ace (goldace) +Filipino: + - dwaeji-aizelle (dwaeji-aizelle) + - jermel + - nyakayed (nyakayed) + - Loyd Stephen Jayme (loydjayme25) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Raylir +Finnish: + - Arkkis (j) + - Jarska + - dodgepong + - Pyscowicz (Pyscowicz) + - Gol D. Ace (goldace) + - Obama (Obama44) + - Tero Keso (tero.keso) + - Vainock (ivo.lemmert) + - chaironeko + - Ville Närhi (daimaah) +French: + - radzaquiel + - pkviet + - Stéphane Lepin (Palakis) + - Yberion + - Tocram2 (tocram2) + - DoK_- + - BoboopTeam + - Léo (leeo97one) + - Benjamin Cambour (lesinfox) + - RisedSky (THEMINECRAFT951) + - DarkInFire + - Youtubeur FR│Giaco35 (Giaco35) + - Pikana (Pikana) + - steve_fr + - Ben Turner (ben-turner) + - Deski_ (Deski_) + - DarckCrystale + - Gol D. Ace (goldace) + - Grisou2907 + - Theguiguix + - Gabriel Dugny (Gabigabigo) + - McGuygnol + - Yolopix + - GANGAT Naeem (zboggum) + - kyllian (tardigradeus) + - BaguetteDePain_ + - Richard Stanway (r1ch) + - Mathieu Hautebas (matteyeux) + - Zalki + - dodgepong + - 🌠 DarK | #Hello 🌠 (DarKTV_FR) + - Vainock (ivo.lemmert) + - illusdidi + - Adrien “GameZone Tv” de Decker (redcraft007) + - Warchamp7 + - Albakham (albakham) + - SkylixX + - chaironeko + - Camille Nury (kamsdu30) + - Alexis Brandner (Alexinfos) + - tburette +Galician: + - Xesús M. Mosquera Carregal (xesusmosquera) + - Gol D. Ace (goldace) + - chaironeko + - Vainock (ivo.lemmert) +Georgian: + - georgianizator + - EduCare Razmik Badalyan (badalyanrazmik) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) +German: + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Michael Fabian Dirks (Xaymar) + - dodgepong + - Dennis Giebert (Isegrim) (isegrimderwolf) + - Benjamin Klettbach (benklett) + - Gregor Bigalke (gregtcltk) + - Sven Kirschbaum (fallobst22) (fallobst22) + - Manuel (ElectronicWar) + - eZ_KrieG3R | Der Fabse (fabian.schwarz.26.06.1998) + - Palana + - Tim (robske_110) (robske110) + - Jonas Otto (jottosmail) + - mdod + - Jonathan (macburgerjunior) + - Prince_of_Raop + - Enderdrache LP (enderdrachelp) + - Robin Hielscher (Jack0r) + - lebaston100.de + - Richard Stanway (r1ch) + - Patrick Frings (Ragnos) + - WurstOnAir + - BoJustus + - AndreLeonardo (andreleonardoyt) + - Tiim +Greek: + - Scourgemcdak + - Mepharees + - Katerina (katerinaramm) + - Tasos Sahanidis (tatokis) + - George T. (tzikas97) + - Alex Kalles (alexakis1997) + - iosifidis + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - dodgepong + - Themis T. (Deminho) + - chaironeko +Hebrew: + - amirsher + - lonelywolf11 + - Chemi (Chemi) + - epic_ziver_D (epic_ziver_D) + - Uri Ben Yossef (uribenyossef) + - Gol D. Ace (goldace) + - Light1c3 + - ghsi + - yair (5shekel) + - TheOver (upmeboost) + - djsavta + - אפיק רוזנר (afikr333) + - Vainock (ivo.lemmert) + - Tal Machani (talmachani) +Hindi: + - SneakyFish5 + - shamuntohamd +Hungarian: + - Gige + - Gol D. Ace (goldace) + - Adam Liszkai (adamos42) + - abydosan (abydoshun) + - dodgepong + - vargag159 + - Vainock (ivo.lemmert) +Italian: + - Manfre#9262 (manfre) + - LordShadow95 + - Marocco2 + - smart2128 + - Tiwi90 (tiwi90) + - dodgepong + - imcesca + - Michele (ScrappyCocco) + - Edoardo Macrì (edomacri) + - ScemEnzo + - Tommaso Cammelli (tomganguz) (tomganguz) + - Edoardo “OfficialDJMela” Macrì (agersforum) + - Martazza (Martazza) + - Gol D. Ace (goldace) + - gianni morandi (strabbioboy) + - Fisherozzo + - Alessandro Sarto (alesarto03) + - Sergio Beneduce (sbeneduce) + - Albakham (albakham) + - Andrea-M3 + - SkyLion + - Vainock (ivo.lemmert) + - Federico Tensi (habby1337) + - Silpheel + - Alessandro Iepure (alessandro_iepure) + - riccardotornesello +Japanese: + - shousa + - Kenta Takumi (kenta0644) + - dodgepong + - SplatRT + - Gol D. Ace (goldace) + - 神成フィルム (kami00nari) + - ato lash (hal_shu_sato) + - Noi (Noi_noel2647) + - CKK COBALT (CKKCOBALT) + - Yuki Yu (Yukiyu) + - chaironeko + - Bob Liu (Akagi201) + - Alex Shafer (enzanki-ars) + - Vainock (ivo.lemmert) +Khmer: + - បងមាន តែអូន (cheaiphone267) +Korean: + - ynetwork (ynetwork) + - Gol D. Ace (goldace) + - RedditRook + - Jong Kwon Choi (dailypro) + - antome +Kurdish: + - Omer Kurdish (OmerKurd) +Lithuanian: + - Justas Vilimas (tyntas) + - xNaii (lyrikas5) + - Vainock (ivo.lemmert) + - Gol D. Ace (goldace) +Malay: + - amsyar ZeRo (amsyarminer555) + - WeingHong + - Gol D. Ace (goldace) + - dodgepong + - Vainock (ivo.lemmert) +Mongolian: + - begjan + - Vainock (ivo.lemmert) +Nigerian Pidgin: +Norwegian Bokmal: + - Taesh (magnusmbratteng) + - Imre Kristoffer Eilertsen (DandelionSprout) + - dodgepong + - Oddbjørn Grytdal (Fooshi) + - Tommy (nwgat) + - Patrick Williamson (wpatrick59) + - Mats Edvin Aarø (matsedvin) + - mgKaiztra + - Syver Stensholt (sssandum) + - Alex Thomassen (Decicus) + - OsteHovel + - areedw + - Sander Skjegstad (r530er) + - Gol D. Ace (goldace) + - Legend27 + - Vainock (ivo.lemmert) + - chaironeko + - Mats Andreassen (MatsA) +Norwegian Nynorsk: + - Imre Kristoffer Eilertsen (DandelionSprout) +Persian: + - MZ MAXIMUM (mahdigamermax) + - Alireza Firouzi (pikhoshorg) + - peymanr34 +Pirate English: + - Matt Gajownik (WizardCM) + - Uaiquqjwnsns + - Matthew Hatcher (MatthewSH) + - jkcoaster + - Emu-Phoenix + - Coen (Trigstur) + - Charlie W. (wallichc) + - Vainock (ivo.lemmert) + - chaironeko + - Gol D. Ace (goldace) + - ncb +Polish: + - grocal (grocal) + - Michał Durak (micechal) + - The Syntox (TheSyntox) + - Vassamo (jotpl69) + - Damian Korcz (damikiller) + - opl + - Gol D. Ace (goldace) + - Łukasz Wójcik (lwojcik) + - Daniel Wieczorek (Kennyluz) + - Albakham (albakham) + - popek069 + - sebek1pan + - Mateusz (Silesianek) + - Julia Drewniak (ewagsi) + - dodgepong + - Vainock (ivo.lemmert) + - Patryk Kunda (ner.i.ol) + - Michał Lewczak (michal200507) +Portuguese: + - André Biscaia (LazP) + - Ev1lbl0w + - dodgepong + - joaofvieira + - Tomás Antunes (tomasantunes) + - joaoboia + - Albakham (albakham) + - alexandre433 + - Gol D. Ace (goldace) +Portuguese, Brazilian: + - Shaolin (admshao) + - Ramon Mendes (rbrgameplays) + - Fabio Madia (Shaolin) + - TFSThiagoBR98 + - CaioWzy + - clr0dr1g + - aalonsomb + - André Gama (ToeOficial) + - Gol D. Ace (goldace) + - Emanoel Lopes (emanoelopes) + - mizifih + - DevilLorde + - flor.com (florretardada) + - Vainock (ivo.lemmert) + - dodgepong + - Esdras Tarsis (esdrastarsis) + - Ramon Gonzalez (ramon200000) +Punjabi: + - manjotsingh0202 +Romanian: + - Cristian Silaghi (stelistcristi) + - banrek + - Hisashi + - BlakeNowah + - Andrei Ionescu (abcdedjdmddx) + - Victor Paul (corvinpaul) + - Skellytone + - Mihai G (babasghenciu) + - Gol D. Ace (goldace) + - dodgepong + - chaironeko + - Vainock (ivo.lemmert) +Russian: + - Alek Nirov (dectanova) + - Pavel (Shevalie) + - dodgepong + - VNGXR + - Gol D. Ace (goldace) + - Bugo (Bugo) + - Andy (anry025) + - Strange Grey Cat (StrangeGreyCat) + - Yaroslav (MrYadro) + - Andrei Stepanov (adem4ik) + - fromgate (fromgate) + - Vlad (KoTmaxHo) + - Runoff Screen (glebpozbnakov62) + - Mixaill + - Vainock (ivo.lemmert) + - Sergei Fug1t1v3 (fug) + - Walt Gee (vovanych) + - Serge Sklyarov (sergesklyarov) + - Yuri Mihaqlov (yurijmi) + - MUHADDIS MEDIA (muhaddismedia) + - TR1D + - Sigge Stjärnholm (Kladdy) + - SandoBY + - Kuji Kitamura (KujiKita) +Scottish Gaelic: + - GunChleoc + - Vainock (ivo.lemmert) +Serbian (Cyrillic): + - medicmomcilo + - Acamicamacaraca + - Gol D. Ace (goldace) + - dodgepong + - LittleGirl_WithPonyTail (alexs1320) + - Vainock (ivo.lemmert) +Serbian (Latin): + - medicmomcilo + - LittleGirl_WithPonyTail (alexs1320) + - Gol D. Ace (goldace) + - Rale Sarcevic (ralesarcevic) + - dodgepong + - Vainock (ivo.lemmert) +Slovak: + - Luki (luki1412) + - Ján M (longmoped) + - Erik Bročko (ericek111) + - Anton Lokaj (anlo) + - LoLLy Nka (lollynka279) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) +Slovenian: + - kristjan.krusic (krusic22) + - MG lolenstine (mglolenstine) + - Grimpy + - Gol D. Ace (goldace) + - ArcaneWater + - Vainock (ivo.lemmert) + - dodgepong +Southern Sotho: + - Samuel Nthoroane (Samuel_Nthoroane) +Spanish: + - Roberto Lorenzo (HonzoNebro) + - Jaime Martinez Rincon (mrjaime1999) + - Marcos Vidal Martinez (M4RK22) + - Jaime Muñoz Martín (jmmartin_5) + - EG Gamer (eggamer131) + - Dalia Sofía Magallón Páramo (SweetSofiMC) + - Gol D. Ace (goldace) + - Monsteer + - Pilar G. (TheMadnessLady) + - Maximiliano Schtroumpftech Pena-Roig (som2tokmynam) + - Carlos Plata (carlosesgenial33) + - Ruben Deig Ramos (rdeigramos) + - Marcos Vidal (markitos.maki22) + - eskaidom (sergiomalagonmartin) + - Alex E. D. B. (alexedb) + - Santiago Pereyra (SannttVIII) + - Eleazar Córcoles (MtrElee3) + - eemiroj + - Ray (Ipsumry) + - makiza1 (micosil_2) + - Sigge Stjärnholm (Kladdy) + - henrycontreras + - Vainock (ivo.lemmert) + - chaironeko + - dodgepong + - amssusgameplays (willifake052) + - Rodrigo Ipince (ipince) + - David Sonico (davidsubsonico) +Swedish: + - Anton R (FirePhoenix) + - Sigge Stjärnholm (Kladdy) + - Laccy IEST (Laccy) + - Olle Dahström (odahlstrom) + - Gustav Ekner (ekner) + - Gol D. Ace (goldace) + - Jonatan Nyberg (sweuser) + - Henrik Mattsson-Mårn (rchk) + - chaironeko + - Vainock (ivo.lemmert) + - Jonas Svensson (jonassanojj99) + - TacticalKebab + - Hannes Blåman (thebluis) +Tagalog: + - dandalion + - philiparniebinag + - jermel + - jbeguna04 + - Red Dayao (steemitph) + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Raylir +Tamil: + - anto27 + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) +Thai: + - sakuhanachan* (sakuhanachanloli) + - ธีรภัทร์ โยชนา (Gataro) + - Sakia Normal Human (arcanaarcana5) + - 盛凤阁 (execzero) + - nongnoobjung (kitcharuk_4) + - Vainock (ivo.lemmert) + - dodgepong + - Gol D. Ace (goldace) +Turkish: + - Ali Kömesöğütlü (Mobile46) (byzlo685) + - omer.karagoz (mrkaragoz) + - Cemal Dursun (cmldrs) + - Savas Tokmak (Laserist) + - Murat Karagöz (anemon_1994) + - BruhSoundeffect2 (DoomerDoge) + - gecebekcisi1 + - Gol D. Ace (goldace) + - Umut kılıç (kilic190787) + - berkcan uçan (ibnehayati) + - Khedi + - mustafaa + - Richard Stanway (r1ch) + - Hydroboost (Hydroboost) + - Vainock (ivo.lemmert) + - Türker Yıldırım (turkeryildirim) + - chaironeko + - basakbk + - Alican Gultekin (Vitaefinis) +Ukrainian: + - SuslikV + - Юрій (Devinit) + - Andy (anry025) + - Sergey (LegionAnon) + - L1Q + - Gol D. Ace (goldace) + - Vainock (ivo.lemmert) + - Maksym Tymoshyk (maximillian_) + - NoPressure + - powerdef + - geimfis + - បងមាន តែអូន (cheaiphone267) +Urdu (Pakistan): + - Rana Awais (ehtisham) + - tahirsada + - shamuntohamd +Vietnamese: + - Johnny “max20091” Utah (boostyourprogram) + - Hưng Nguyễn (hoyostudio) + - ngoisaosang (ngoisaosang) + - Drake Strike (phjtieudoc) + - Gol D. Ace (goldace) + - IoeCmcomc (Ioe2015) (hopdaigia2004) + - BIGO - 지혜 (parkjihye96) + - Hà Phi Hùng (haphihungcom) + - Vainock (ivo.lemmert) + - Vũ Hải Tây (tayngungo1999) + - NCAA (NCAA) + - dodgepong diff --git a/CI/before-deploy-osx.sh b/CI/before-deploy-osx.sh index 38528d6..2c1fd69 100755 --- a/CI/before-deploy-osx.sh +++ b/CI/before-deploy-osx.sh @@ -9,7 +9,7 @@ set -e # Generate file name variables export GIT_HASH=$(git rev-parse --short HEAD) -export FILE_DATE=$(date +%Y-%m-%d.%H:%M:%S) +export FILE_DATE=$(date +%Y-%m-%d.%H-%M-%S) export FILENAME=$FILE_DATE-$GIT_HASH-$TRAVIS_BRANCH-osx.pkg cd ./build @@ -49,20 +49,24 @@ sudo install_name_tool -change \ hr "Generating .pkg" packagesbuild ../CI/install/osx/CMakeLists.pkgproj -# Signing stuff -hr "Decrypting Cert" -openssl aes-256-cbc -K $encrypted_dd3c7f5e9db9_key -iv $encrypted_dd3c7f5e9db9_iv -in ../CI/osxcert/Certificates.p12.enc -out Certificates.p12 -d -hr "Creating Keychain" -security create-keychain -p mysecretpassword build.keychain -security default-keychain -s build.keychain -security unlock-keychain -p mysecretpassword build.keychain -security set-keychain-settings -t 3600 -u build.keychain -hr "Importing certs into keychain" -security import ./Certificates.p12 -k build.keychain -T /usr/bin/productsign -P "" -# macOS 10.12+ -security set-key-partition-list -S apple-tool:,apple: -s -k mysecretpassword build.keychain -hr "Signing Package" -productsign --sign 2MMRE5MTB8 ./OBS.pkg ./$FILENAME +if [ -v "$TRAVIS" ]; then + # Signing stuff + hr "Decrypting Cert" + openssl aes-256-cbc -K $encrypted_dd3c7f5e9db9_key -iv $encrypted_dd3c7f5e9db9_iv -in ../CI/osxcert/Certificates.p12.enc -out Certificates.p12 -d + hr "Creating Keychain" + security create-keychain -p mysecretpassword build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p mysecretpassword build.keychain + security set-keychain-settings -t 3600 -u build.keychain + hr "Importing certs into keychain" + security import ./Certificates.p12 -k build.keychain -T /usr/bin/productsign -P "" + # macOS 10.12+ + security set-key-partition-list -S apple-tool:,apple: -s -k mysecretpassword build.keychain + hr "Signing Package" + productsign --sign 2MMRE5MTB8 ./OBS.pkg ./$FILENAME +else + cp ./OBS.pkg ./$FILENAME +fi # Move to the folder that travis uses to upload artifacts from hr "Moving package to nightly folder for distribution" diff --git a/CI/before-deploy-win.cmd b/CI/before-deploy-win.cmd index 0597fe0..e9dcb48 100644 --- a/CI/before-deploy-win.cmd +++ b/CI/before-deploy-win.cmd @@ -1,3 +1,3 @@ -robocopy C:\projects\obs-studio\build32\rundir\RelWithDebInfo C:\projects\obs-studio\build\ /E /XF .gitignore -robocopy C:\projects\obs-studio\build64\rundir\RelWithDebInfo C:\projects\obs-studio\build\ /E /XC /XN /XO /XF .gitignore -7z a build.zip C:\projects\obs-studio\build\* \ No newline at end of file +robocopy .\build32\rundir\RelWithDebInfo .\build\ /E /XF .gitignore +robocopy .\build64\rundir\RelWithDebInfo .\build\ /E /XC /XN /XO /XF .gitignore +7z a build.zip .\build\* \ No newline at end of file diff --git a/CI/before-script-osx.sh b/CI/before-script-osx.sh index a0cf54b..50a9a19 100755 --- a/CI/before-script-osx.sh +++ b/CI/before-script-osx.sh @@ -9,6 +9,8 @@ cmake -DENABLE_SPARKLE_UPDATER=ON \ -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 \ -DQTDIR=/usr/local/Cellar/qt/5.10.1 \ -DDepsPath=/tmp/obsdeps \ --DVLCPath=$PWD/../../vlc-master \ +-DVLCPath=$PWD/../../vlc-3.0.4 \ -DBUILD_BROWSER=ON \ +-DBROWSER_DEPLOY=ON \ +-DBUILD_CAPTIONS=ON \ -DCEF_ROOT_DIR=$PWD/../../cef_binary_${CEF_BUILD_VERSION}_macosx64 .. diff --git a/CI/install-dependencies-linux-ubuntu16.sh b/CI/install-dependencies-linux-ubuntu16.sh new file mode 100755 index 0000000..52e8d22 --- /dev/null +++ b/CI/install-dependencies-linux-ubuntu16.sh @@ -0,0 +1,59 @@ +#!/bin/sh +set -ex + +sudo apt-get -qq update +sudo apt-get install -y \ + build-essential \ + checkinstall \ + cmake \ + libasound2-dev \ + libavcodec-dev \ + libavdevice-dev \ + libavfilter-dev \ + libavformat-dev \ + libavutil-dev \ + libcurl4-openssl-dev \ + libfdk-aac-dev \ + libfontconfig-dev \ + libfreetype6-dev \ + libgl1-mesa-dev \ + libjack-jackd2-dev \ + libjansson-dev \ + libluajit-5.1-dev \ + libpulse-dev \ + libqt5x11extras5-dev \ + libspeexdsp-dev \ + libswresample-dev \ + libswscale-dev \ + libudev-dev \ + libv4l-dev \ + libvlc-dev \ + libx11-dev \ + libx264-dev \ + libxcb-randr0-dev \ + libxcb-shm0-dev \ + libxcb-xinerama0-dev \ + libxcomposite-dev \ + libxinerama-dev \ + pkg-config \ + python3-dev \ + qtbase5-dev \ + libqt5svg5-dev \ + swig + + +# build mbedTLS +cd ~/projects +mkdir mbedtls +cd mbedtls +mbedtlsPath=$PWD +curl -L -O https://github.com/ARMmbed/mbedtls/archive/mbedtls-2.12.0.tar.gz +tar -xf mbedtls-2.12.0.tar.gz +mkdir build +cd ./build +cmake -DENABLE_TESTING=Off -DUSE_SHARED_MBEDTLS_LIBRARY=On ../mbedtls-mbedtls-2.12.0 +make -j 12 +sudo make install + +# return to OBS build dir +cd $APPVEYOR_BUILD_FOLDER diff --git a/CI/install-dependencies-linux.sh b/CI/install-dependencies-linux.sh index 2cbd8de..4ab0219 100755 --- a/CI/install-dependencies-linux.sh +++ b/CI/install-dependencies-linux.sh @@ -1,18 +1,19 @@ #!/bin/sh set -ex -sudo add-apt-repository ppa:kirillshkrogalev/ffmpeg-next -y +sudo add-apt-repository ppa:jonathonf/ffmpeg-3 -y +curl -L https://packagecloud.io/github/git-lfs/gpgkey | sudo apt-key add - sudo apt-get -qq update sudo apt-get install -y \ build-essential \ checkinstall \ cmake \ libasound2-dev \ - libavcodec-ffmpeg-dev \ - libavdevice-ffmpeg-dev \ - libavfilter-ffmpeg-dev \ - libavformat-ffmpeg-dev \ - libavutil-ffmpeg-dev \ + libavcodec-dev \ + libavdevice-dev \ + libavfilter-dev \ + libavformat-dev \ + libavutil-dev \ libcurl4-openssl-dev \ libfdk-aac-dev \ libfontconfig-dev \ @@ -24,13 +25,15 @@ sudo apt-get install -y \ libpulse-dev \ libqt5x11extras5-dev \ libspeexdsp-dev \ - libswresample-ffmpeg-dev \ - libswscale-ffmpeg-dev \ + libswresample-dev \ + libswscale-dev \ libudev-dev \ libv4l-dev \ + libva-dev \ libvlc-dev \ libx11-dev \ libx264-dev \ + libxcb-randr0-dev \ libxcb-shm0-dev \ libxcb-xinerama0-dev \ libxcomposite-dev \ @@ -38,4 +41,5 @@ sudo apt-get install -y \ pkg-config \ python3-dev \ qtbase5-dev \ + libqt5svg5-dev \ swig diff --git a/CI/install-dependencies-osx.sh b/CI/install-dependencies-osx.sh index 82f3aac..24b8018 100755 --- a/CI/install-dependencies-osx.sh +++ b/CI/install-dependencies-osx.sh @@ -10,7 +10,9 @@ set -e # Echo all commands before executing set -v -git fetch --unshallow +if [[ $TRAVIS ]]; then + git fetch --unshallow +fi # Leave obs-studio folder cd ../ @@ -24,8 +26,9 @@ sudo installer -pkg ./Packages.pkg -target / brew update #Base OBS Deps and ccache -brew install jack speexdsp ccache swig mbedtls -brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/9a70413d137839de0054571e5f85fd07ee400955/Formula/qt.rb +brew install jack speexdsp ccache mbedtls +brew install https://gist.githubusercontent.com/DDRBoxman/b3956fab6073335a4bf151db0dcbd4ad/raw/ed1342a8a86793ea8c10d8b4d712a654da121ace/qt.rb +brew install https://gist.githubusercontent.com/DDRBoxman/4cada55c51803a2f963fa40ce55c9d3e/raw/572c67e908bfbc1bcb8c476ea77ea3935133f5b5/swig.rb export PATH=/usr/local/opt/ccache/libexec:$PATH ccache -s || echo "CCache is not available." @@ -37,8 +40,8 @@ tar -xf ./osx-deps-2018-08-09.tar.gz -C /tmp # Fetch vlc codebase hr "Downloading VLC repo" -wget --quiet --retry-connrefused --waitretry=1 -O vlc-master.zip https://github.com/videolan/vlc/archive/master.zip -unzip -q ./vlc-master.zip +wget --quiet --retry-connrefused --waitretry=1 https://downloads.videolan.org/vlc/3.0.4/vlc-3.0.4.tar.xz +tar -xf vlc-3.0.4.tar.xz # Get sparkle hr "Downloading Sparkle framework" @@ -54,6 +57,8 @@ tar -xf ./cef_binary_${CEF_BUILD_VERSION}_macosx64.tar.bz2 cd ./cef_binary_${CEF_BUILD_VERSION}_macosx64 # remove a broken test sed -i '.orig' '/add_subdirectory(tests\/ceftests)/d' ./CMakeLists.txt +# target 10.11 +sed -i '.orig' s/\"10.9\"/\"10.11\"/ ./cmake/cef_variables.cmake mkdir build cd ./build cmake -DCMAKE_CXX_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_EXE_LINKER_FLAGS="-std=c++11 -stdlib=libc++" -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11 .. diff --git a/CI/install-qt-win.cmd b/CI/install-qt-win.cmd new file mode 100644 index 0000000..46e14e8 --- /dev/null +++ b/CI/install-qt-win.cmd @@ -0,0 +1,4 @@ +curl -kLO https://cdn-fastly.obsproject.com/downloads/Qt_5.10.1.7z -f --retry 5 -C - +7z x Qt_5.10.1.7z -oQt +mv Qt C:\QtDep +dir C:\QtDep \ No newline at end of file diff --git a/CI/install-script-linux.sh b/CI/install-script-linux.sh new file mode 100755 index 0000000..abbfbf0 --- /dev/null +++ b/CI/install-script-linux.sh @@ -0,0 +1,4 @@ +#!/bin/sh +set -ex + +build_config=RelWithDebInfo diff --git a/CI/install-script-win.cmd b/CI/install-script-win.cmd new file mode 100644 index 0000000..a3051c3 --- /dev/null +++ b/CI/install-script-win.cmd @@ -0,0 +1,29 @@ +if exist dependencies2017.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -z dependencies2017.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -) +if exist vlc.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -z vlc.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/vlc.zip -f --retry 5 -C -) +if exist cef_binary_%CEF_VERSION%_windows32.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows32.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -C -) +if exist cef_binary_%CEF_VERSION%_windows64.zip (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows64.zip) else (curl -kLO https://cdn-fastly.obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -C -) +7z x dependencies2017.zip -odependencies2017 +7z x vlc.zip -ovlc +7z x cef_binary_%CEF_VERSION%_windows32.zip -oCEF_32 +7z x cef_binary_%CEF_VERSION%_windows64.zip -oCEF_64 +set DepsPath32=%CD%\dependencies2017\win32 +set DepsPath64=%CD%\dependencies2017\win64 +set VLCPath=%CD%\vlc +set QTDIR32=C:\QtDep\5.10.1\msvc2017 +set QTDIR64=C:\QtDep\5.10.1\msvc2017_64 +set CEF_32=%CD%\CEF_32\cef_binary_%CEF_VERSION%_windows32 +set CEF_64=%CD%\CEF_64\cef_binary_%CEF_VERSION%_windows64 +set build_config=RelWithDebInfo +mkdir build build32 build64 +if "%TWITCH-CLIENTID%"=="$(twitch_clientid)" ( +cd ./build32 +cmake -G "Visual Studio 15 2017" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_32% .. +cd ../build64 +cmake -G "Visual Studio 15 2017 Win64" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_64% .. +) else ( +cd ./build32 +cmake -G "Visual Studio 15 2017" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_32% -DTWITCH_CLIENTID="%TWITCH-CLIENTID%" -DTWITCH_HASH="%TWITCH-HASH%" -DMIXER_CLIENTID="%MIXER-CLIENTID%" -DMIXER_HASH="%MIXER-HASH%" -DRESTREAM_CLIENTID="%RESTREAM-CLIENTID%" -DRESTREAM_HASH="%RESTREAM-HASH%" .. +cd ../build64 +cmake -G "Visual Studio 15 2017 Win64" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_64% -DTWITCH_CLIENTID="%TWITCH-CLIENTID%" -DTWITCH_HASH="%TWITCH-HASH%" -DMIXER_CLIENTID="%MIXER-CLIENTID%" -DMIXER_HASH="%MIXER-HASH%" -DRESTREAM_CLIENTID="%RESTREAM-CLIENTID%" -DRESTREAM_HASH="%RESTREAM-HASH%" .. +) +cd .. diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bac27c..47dadab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,17 @@ else() set(OBS_RELEASE_CANDIDATE 0) endif() +# Binary Versioning for Windows +if(WIN32) + string(REPLACE "-" ";" UI_VERSION_SPLIT ${OBS_VERSION}) + list(GET UI_VERSION_SPLIT 0 UI_VERSION) + string(REPLACE "." ";" UI_VERSION_SEMANTIC ${UI_VERSION}) + list(GET UI_VERSION_SEMANTIC 0 UI_VERSION_MAJOR) + list(GET UI_VERSION_SEMANTIC 1 UI_VERSION_MINOR) + list(GET UI_VERSION_SEMANTIC 2 UI_VERSION_PATCH) + configure_file(UI/obs.rc.in ${PROJECT_BINARY_DIR}/obs.rc) +endif() + if(MSVC AND NOT EXISTS "${CMAKE_BINARY_DIR}/ALL_BUILD.vcxproj.user") file(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/ALL_BUILD.vcxproj.user" @@ -66,9 +77,13 @@ if(${CMAKE_C_COMPILER_ID} MATCHES "Clang" OR ${CMAKE_CXX_COMPILER_ID} MATCHES "C set(CMAKE_COMPILER_IS_CLANG TRUE) endif() +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") + add_compile_definitions(NO_WARN_X86_INTRINSICS) +endif() + if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANG) - set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing") - set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-field-initializers ${CMAKE_CXX_FLAGS} -fno-strict-aliasing") + set(CMAKE_C_FLAGS "-Wall -Wextra -Wvla -Wno-unused-function -Werror-implicit-function-declaration -Wno-missing-braces -Wno-missing-field-initializers ${CMAKE_C_FLAGS} -std=gnu99 -fno-strict-aliasing") option(USE_LIBC++ "Use libc++ instead of libstdc++" ${APPLE}) if(USE_LIBC++) @@ -90,6 +105,7 @@ if(WIN32) endif() if(MSVC) + add_compile_options("/MP") set(CMAKE_C_FLAGS_DEBUG "/DDEBUG=1 /D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_DEBUG "/DDEBUG=1 /D_DEBUG=1 ${CMAKE_C_FLAGS_DEBUG}") @@ -132,6 +148,24 @@ if(NOT INSTALLER_RUN) set(UI_ENABLED FALSE) else() set(UI_ENABLED TRUE) + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_lib_suffix 64) + else() + set(_lib_suffix 32) + endif() + + if(DEFINED QTDIR${_lib_suffix}) + list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}") + elseif(DEFINED QTDIR) + list(APPEND CMAKE_PREFIX_PATH "${QTDIR}") + elseif(DEFINED ENV{QTDIR${_lib_suffix}}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}") + elseif(DEFINED ENV{QTDIR}) + list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}") + endif() + + find_package(Qt5Widgets ${FIND_MODE}) endif() add_subdirectory(deps) @@ -142,8 +176,8 @@ if(NOT INSTALLER_RUN) add_subdirectory(libobs-opengl) add_subdirectory(libobs) - add_subdirectory(UI) add_subdirectory(plugins) + add_subdirectory(UI) if (BUILD_TESTS) add_subdirectory(test) endif() diff --git a/COMMITMENT b/COMMITMENT new file mode 100644 index 0000000..a687e0d --- /dev/null +++ b/COMMITMENT @@ -0,0 +1,46 @@ +GPL Cooperation Commitment +Version 1.0 + +Before filing or continuing to prosecute any legal proceeding or claim +(other than a Defensive Action) arising from termination of a Covered +License, we commit to extend to the person or entity ('you') accused +of violating the Covered License the following provisions regarding +cure and reinstatement, taken from GPL version 3. As used here, the +term 'this License' refers to the specific Covered License being +enforced. + + However, if you cease all violation of this License, then your + license from a particular copyright holder is reinstated (a) + provisionally, unless and until the copyright holder explicitly + and finally terminates your license, and (b) permanently, if the + copyright holder fails to notify you of the violation by some + reasonable means prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is + reinstated permanently if the copyright holder notifies you of the + violation by some reasonable means, this is the first time you + have received notice of violation of this License (for any work) + from that copyright holder, and you cure the violation prior to 30 + days after your receipt of the notice. + +We intend this Commitment to be irrevocable, and binding and +enforceable against us and assignees of or successors to our +copyrights. + +Definitions + +'Covered License' means the GNU General Public License, version 2 +(GPLv2), the GNU Lesser General Public License, version 2.1 +(LGPLv2.1), or the GNU Library General Public License, version 2 +(LGPLv2), all as published by the Free Software Foundation. + +'Defensive Action' means a legal proceeding or claim that We bring +against you in response to a prior proceeding or claim initiated by +you or your affiliate. + +'We' means each contributor to this repository as of the date of +inclusion of this file, including subsidiaries of a corporate +contributor. + +This work is available under a Creative Commons Attribution-ShareAlike +4.0 International license (https://creativecommons.org/licenses/by-sa/4.0/). diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 6ea05c2..43c1934 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -10,7 +10,9 @@ Quick Links for Contributing - Our bug tracker (linked to forum accounts): https://obsproject.com/mantis/ - - Development IRC channel: #obs-dev on QuakeNet + - Discord Server: https://obsproject.com/discord + + - Development chat: #development on the Discord server (see above) - Development forum: https://obsproject.com/forum/list/general-development.21/ @@ -50,10 +52,11 @@ Commit Guidelines - Make sure commit titles are always in present tense, and are not followed by punctuation. - - Prefix commit titles with the module name, followed by a colon and a - space (unless modifying a file in the base directory). When - modifying cmake modules, prefix with "cmake". So for example, if you - are modifying the obs-ffmpeg plugin:: + - Prefix each commit's titles with the module name, followed by a colon + and a space (unless modifying a file in the base directory). After + that, the first word should be capitalized. + + So for example, if you are modifying the obs-ffmpeg plugin:: obs-ffmpeg: Fix bug with audio output @@ -61,4 +64,6 @@ Commit Guidelines libobs: Fix source not displaying + Note: When modifying cmake modules, just prefix with "cmake". + - If you still need examples, please view the commit history. diff --git a/README.rst b/README.rst index 3e0e02d..92c4938 100644 --- a/README.rst +++ b/README.rst @@ -1,14 +1,30 @@ OBS Studio =================================== +.. image:: https://travis-ci.org/obsproject/obs-studio.svg?branch=master + :alt: OBS Studio Build Status - Travis CI + :target: https://travis-ci.org/obsproject/obs-studio + +.. image:: https://ci.appveyor.com/api/projects/status/github/obsproject/obs-studio?branch=master&svg=true + :alt: OBS Studio Build Status - AppVeyor CI + :target: https://ci.appveyor.com/project/jp9000/obs-studio/branch/master + +.. image:: https://dev.azure.com/obsjim/obsjim/_apis/build/status/obsproject.obs-studio?branchName=master + :alt: OBS Studio Build Status - Azure Pipelines + :target: https://dev.azure.com/obsjim/obsjim/_build/latest?definitionId=1&branchName=master + +.. image:: https://discordapp.com/api/guilds/348973006581923840/widget.png?style=shield + :alt: OBS Studio Discord Server + :target: https://obsproject.com/discord + What is OBS Studio? ------------------- OBS Studio is software designed for capturing, compositing, encoding, recording, and streaming video content, efficiently. - It's distributed under the GNU General Public License v2 - see the - accompanying COPYING file for more details. + It's distributed under the GNU General Public License v2 (or any later + version) - see the accompanying COPYING file for more details. Quick Links ----------- @@ -23,6 +39,8 @@ Quick Links - Developer/API Documentation: https://obsproject.com/docs + - Donating/backing/sponsoring: https://obsproject.com/contribute + - Bug Tracker: https://obsproject.com/mantis/ (Note: The bug tracker is linked to forum accounts. To use the bug @@ -31,6 +49,12 @@ Quick Links Contributing ------------ + - If you would like to help fund or sponsor the project, you can do so + via `Patreon `_, `OpenCollective + `_, or `PayPal + `_. See our `contribute page + `_ for more information. + - If you wish to contribute code to the project, please make sure to read the coding and commit guidelines: https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index f414488..ac54110 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -7,6 +7,10 @@ else() set(FIND_MODE QUIET) endif() +if(BROWSER_AVAILABLE_INTERNAL) + add_definitions(-DBROWSER_AVAILABLE) +endif() + add_subdirectory(obs-frontend-api) # ---------------------------------------------------------------------------- @@ -15,26 +19,45 @@ project(obs) set(DISABLE_UPDATE_MODULE TRUE CACHE BOOL "Disables building the update module") -if(DEFINED QTDIR${_lib_suffix}) - list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}") -elseif(DEFINED QTDIR) - list(APPEND CMAKE_PREFIX_PATH "${QTDIR}") -elseif(DEFINED ENV{QTDIR${_lib_suffix}}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}") -elseif(DEFINED ENV{QTDIR}) - list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}") +if(NOT DEFINED TWITCH_CLIENTID OR "${TWITCH_CLIENTID}" STREQUAL "" OR + NOT DEFINED TWITCH_HASH OR "${TWITCH_HASH}" STREQUAL "" OR + NOT BROWSER_AVAILABLE_INTERNAL) + set(TWITCH_ENABLED FALSE) + set(TWITCH_CLIENTID "") + set(TWITCH_HASH "0") +else() + set(TWITCH_ENABLED TRUE) endif() +if(NOT DEFINED MIXER_CLIENTID OR "${MIXER_CLIENTID}" STREQUAL "" OR + NOT DEFINED MIXER_HASH OR "${MIXER_HASH}" STREQUAL "" OR + NOT BROWSER_AVAILABLE_INTERNAL) + set(MIXER_ENABLED FALSE) + set(MIXER_CLIENTID "") + set(MIXER_HASH "0") +else() + set(MIXER_ENABLED TRUE) +endif() + +if(NOT DEFINED RESTREAM_CLIENTID OR "${RESTREAM_CLIENTID}" STREQUAL "" OR + NOT DEFINED RESTREAM_HASH OR "${RESTREAM_HASH}" STREQUAL "" OR + NOT BROWSER_AVAILABLE_INTERNAL) + set(RESTREAM_ENABLED FALSE) + set(RESTREAM_CLIENTID "") + set(RESTREAM_HASH "0") +else() + set(RESTREAM_ENABLED TRUE) +endif() + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/ui-config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/ui-config.h") + set(CMAKE_INCLUDE_CURRENT_DIR TRUE) set(CMAKE_AUTOMOC TRUE) -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_lib_suffix 64) -else() - set(_lib_suffix 32) -endif() +find_package(Qt5Svg ${FIND_MODE}) -find_package(Qt5Widgets ${FIND_MODE}) find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil avformat) if(APPLE) @@ -52,11 +75,14 @@ endif() include_directories(${FFMPEG_INCLUDE_DIRS}) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(SYSTEM "obs-frontend-api") include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/libobs") include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/deps/libff") include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/deps/json11") -include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/plugins/obs-browser/panel") +if(BROWSER_AVAILABLE_INTERNAL) + include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/plugins/obs-browser/panel") +endif() find_package(Libcurl REQUIRED) include_directories(${LIBCURL_INCLUDE_DIRS}) @@ -71,7 +97,7 @@ if(WIN32) win-update/update-window.cpp win-update/win-update.cpp win-update/win-update-helpers.cpp - obs.rc) + ${obs-studio_BINARY_DIR}/obs.rc) set(obs_PLATFORM_HEADERS win-update/update-window.hpp win-update/win-update.hpp @@ -80,6 +106,10 @@ if(WIN32) crypt32 blake2 ${OBS_JANSSON_IMPORT}) + + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE") + endif() elseif(APPLE) set(obs_PLATFORM_SOURCES platform-osx.mm) @@ -112,6 +142,44 @@ elseif(UNIX) Qt5::X11Extras) endif() +if(BROWSER_AVAILABLE_INTERNAL) + list(APPEND obs_PLATFORM_SOURCES + obf.c + auth-oauth.cpp + ) + list(APPEND obs_PLATFORM_HEADERS + obf.h + auth-oauth.hpp + ) + + if(TWITCH_ENABLED) + list(APPEND obs_PLATFORM_SOURCES + auth-twitch.cpp + ) + list(APPEND obs_PLATFORM_HEADERS + auth-twitch.hpp + ) + endif() + + if(MIXER_ENABLED) + list(APPEND obs_PLATFORM_SOURCES + auth-mixer.cpp + ) + list(APPEND obs_PLATFORM_HEADERS + auth-mixer.hpp + ) + endif() + + if(RESTREAM_ENABLED) + list(APPEND obs_PLATFORM_SOURCES + auth-restream.cpp + ) + list(APPEND obs_PLATFORM_HEADERS + auth-restream.hpp + ) + endif() +endif() + set(obs_libffutil_SOURCES ../deps/libff/libff/ff-util.c ) @@ -131,6 +199,7 @@ set(obs_SOURCES ${obs_libffutil_SOURCES} ../deps/json11/json11.cpp obs-app.cpp + window-dock.cpp api-interface.cpp window-basic-main.cpp window-basic-stats.cpp @@ -141,35 +210,38 @@ set(obs_SOURCES window-basic-auto-config.cpp window-basic-main-outputs.cpp window-basic-source-select.cpp + window-basic-settings-stream.cpp window-basic-auto-config-test.cpp window-basic-main-scene-collections.cpp window-basic-main-transitions.cpp window-basic-main-dropfiles.cpp window-basic-main-profiles.cpp - window-license-agreement.cpp + window-basic-main-browser.cpp window-basic-status-bar.cpp window-basic-adv-audio.cpp window-basic-transform.cpp window-basic-preview.cpp + window-basic-about.cpp window-namedialog.cpp window-log-reply.cpp window-projector.cpp window-remux.cpp + auth-base.cpp source-tree.cpp properties-view.cpp focus-list.cpp menu-button.cpp double-slider.cpp + slider-ignorewheel.cpp + combobox-ignorewheel.cpp + spinbox-ignorewheel.cpp volume-control.cpp adv-audio-control.cpp item-widget-helpers.cpp - visibility-checkbox.cpp - locked-checkbox.cpp horizontal-scroll-area.cpp vertical-scroll-area.cpp visibility-item-widget.cpp slider-absoluteset-style.cpp - source-list-widget.cpp qt-display.cpp crash-report.cpp hotkey-edit.cpp @@ -184,6 +256,7 @@ set(obs_HEADERS ../deps/json11/json11.hpp obs-app.hpp platform.hpp + window-dock.hpp window-main.hpp window-basic-main.hpp window-basic-stats.hpp @@ -194,7 +267,7 @@ set(obs_HEADERS window-basic-auto-config.hpp window-basic-main-outputs.hpp window-basic-source-select.hpp - window-license-agreement.hpp + window-basic-about.hpp window-basic-status-bar.hpp window-basic-adv-audio.hpp window-basic-transform.hpp @@ -203,11 +276,16 @@ set(obs_HEADERS window-log-reply.hpp window-projector.hpp window-remux.hpp + auth-base.hpp source-tree.hpp properties-view.hpp properties-view.moc.hpp display-helpers.hpp + balance-slider.hpp double-slider.hpp + slider-ignorewheel.hpp + combobox-ignorewheel.hpp + spinbox-ignorewheel.hpp focus-list.hpp menu-button.hpp mute-checkbox.hpp @@ -221,14 +299,14 @@ set(obs_HEADERS vertical-scroll-area.hpp visibility-item-widget.hpp slider-absoluteset-style.hpp - source-list-widget.hpp qt-display.hpp crash-report.hpp hotkey-edit.hpp source-label.hpp remote-text.hpp audio-encoders.hpp - qt-wrappers.hpp) + qt-wrappers.hpp + clickable-label.hpp) set(obs_UI forms/NameDialog.ui @@ -237,7 +315,6 @@ set(obs_UI forms/AutoConfigStreamPage.ui forms/AutoConfigTestPage.ui forms/ColorSelect.ui - forms/OBSLicenseAgreement.ui forms/OBSLogReply.ui forms/OBSBasic.ui forms/OBSBasicTransform.ui @@ -246,7 +323,8 @@ set(obs_UI forms/OBSBasicSourceSelect.ui forms/OBSBasicInteraction.ui forms/OBSUpdate.ui - forms/OBSRemux.ui) + forms/OBSRemux.ui + forms/OBSAbout.ui) set(obs_QRC forms/obs.qrc) @@ -275,6 +353,7 @@ endif() target_link_libraries(obs libobs Qt5::Widgets + Qt5::Svg obs-frontend-api ${FFMPEG_LIBRARIES} ${LIBCURL_LIBRARIES} @@ -298,11 +377,10 @@ define_graphic_modules(obs) install_obs_core(obs) install_obs_data(obs data obs-studio) +install_obs_data_file(obs ../AUTHORS obs-studio/authors) if (UNIX AND UNIX_STRUCTURE AND NOT APPLE) - install(FILES dist/obs.desktop DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/applications) - install(FILES forms/images/obs.png - DESTINATION ${CMAKE_INSTALL_FULL_DATAROOTDIR}/icons/hicolor/256x256/apps) + add_subdirectory(xdg-data) endif() add_subdirectory(frontend-plugins) diff --git a/UI/adv-audio-control.cpp b/UI/adv-audio-control.cpp index 2c602b6..db97504 100644 --- a/UI/adv-audio-control.cpp +++ b/UI/adv-audio-control.cpp @@ -4,15 +4,18 @@ #include #include #include -#include #include "qt-wrappers.hpp" #include "obs-app.hpp" #include "adv-audio-control.hpp" +#include "window-basic-main.hpp" #ifndef NSEC_PER_MSEC #define NSEC_PER_MSEC 1000000 #endif +#define MIN_DB -96.0 +#define MAX_DB 26.0 + OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) : source(source_) { @@ -25,13 +28,13 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) forceMonoContainer = new QWidget(); mixerContainer = new QWidget(); - panningContainer = new QWidget(); + balanceContainer = new QWidget(); labelL = new QLabel(); labelR = new QLabel(); nameLabel = new QLabel(); - volume = new QSpinBox(); + volume = new QDoubleSpinBox(); forceMono = new QCheckBox(); - panning = new QSlider(Qt::Horizontal); + balance = new BalanceSlider(); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO monitoringType = new QComboBox(); #endif @@ -60,8 +63,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) mixerContainer->setLayout(hlayout); hlayout = new QHBoxLayout(); hlayout->setContentsMargins(0, 0, 0, 0); - panningContainer->setLayout(hlayout); - panningContainer->setMinimumWidth(100); + balanceContainer->setLayout(hlayout); + balanceContainer->setMinimumWidth(100); labelL->setText("L"); @@ -71,9 +74,15 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) nameLabel->setText(QT_UTF8(sourceName)); nameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); - volume->setMinimum(0); - volume->setMaximum(2000); - volume->setValue(int(vol * 100.0f)); + volume->setMinimum(MIN_DB - 0.1); + volume->setMaximum(MAX_DB); + volume->setSingleStep(0.1); + volume->setDecimals(1); + volume->setSuffix(" dB"); + volume->setValue(obs_mul_to_db(vol)); + + if (volume->value() < MIN_DB) + volume->setSpecialValueText("-inf dB"); forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0); @@ -81,14 +90,27 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) forceMonoContainer->layout()->setAlignment(forceMono, Qt::AlignHCenter | Qt::AlignVCenter); - panning->setMinimum(0); - panning->setMaximum(100); - panning->setTickPosition(QSlider::TicksAbove); - panning->setEnabled(false); - panning->setValue(50); /* XXX */ + balance->setOrientation(Qt::Horizontal); + balance->setMinimum(0); + balance->setMaximum(100); + balance->setTickPosition(QSlider::TicksAbove); + balance->setTickInterval(50); + + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + + const char *speakers = config_get_string(main->Config(), "Audio", + "ChannelSetup"); + + if (strcmp(speakers, "Mono") == 0) + balance->setEnabled(false); + else + balance->setEnabled(true); + + float bal = obs_source_get_balance_value(source) * 100.0f; + balance->setValue((int)bal); int64_t cur_sync = obs_source_get_sync_offset(source); - syncOffset->setMinimum(-20000); + syncOffset->setMinimum(-950); syncOffset->setMaximum(20000); syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC)); @@ -118,10 +140,14 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) mixer6->setText("6"); mixer6->setChecked(mixers & (1<<5)); - panningContainer->layout()->addWidget(labelL); - panningContainer->layout()->addWidget(panning); - panningContainer->layout()->addWidget(labelR); - panningContainer->setMaximumWidth(170); + speaker_layout sl = obs_source_get_speaker_layout(source); + + if (sl == SPEAKERS_STEREO) { + balanceContainer->layout()->addWidget(labelL); + balanceContainer->layout()->addWidget(balance); + balanceContainer->layout()->addWidget(labelR); + balanceContainer->setMaximumWidth(170); + } mixerContainer->layout()->addWidget(mixer1); mixerContainer->layout()->addWidget(mixer2); @@ -130,12 +156,14 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_) mixerContainer->layout()->addWidget(mixer5); mixerContainer->layout()->addWidget(mixer6); - QWidget::connect(volume, SIGNAL(valueChanged(int)), - this, SLOT(volumeChanged(int))); + QWidget::connect(volume, SIGNAL(valueChanged(double)), + this, SLOT(volumeChanged(double))); QWidget::connect(forceMono, SIGNAL(clicked(bool)), this, SLOT(downmixMonoChanged(bool))); - QWidget::connect(panning, SIGNAL(valueChanged(int)), - this, SLOT(panningChanged(int))); + QWidget::connect(balance, SIGNAL(valueChanged(int)), + this, SLOT(balanceChanged(int))); + QWidget::connect(balance, SIGNAL(doubleClicked()), + this, SLOT(ResetBalance())); QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this, SLOT(syncOffsetChanged(int))); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO @@ -163,7 +191,7 @@ OBSAdvAudioCtrl::~OBSAdvAudioCtrl() nameLabel->deleteLater(); volume->deleteLater(); forceMonoContainer->deleteLater(); - panningContainer->deleteLater(); + balanceContainer->deleteLater(); syncOffset->deleteLater(); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO monitoringType->deleteLater(); @@ -179,7 +207,7 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout) layout->addWidget(nameLabel, lastRow, idx++); layout->addWidget(volume, lastRow, idx++); layout->addWidget(forceMonoContainer, lastRow, idx++); - layout->addWidget(panningContainer, lastRow, idx++); + layout->addWidget(balanceContainer, lastRow, idx++); layout->addWidget(syncOffset, lastRow, idx++); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO layout->addWidget(monitoringType, lastRow, idx++); @@ -240,7 +268,7 @@ void OBSAdvAudioCtrl::SourceFlagsChanged(uint32_t flags) void OBSAdvAudioCtrl::SourceVolumeChanged(float value) { volume->blockSignals(true); - volume->setValue(int(round(value * 100.0f))); + volume->setValue(obs_mul_to_db(value)); volume->blockSignals(false); } @@ -262,9 +290,14 @@ void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers) /* ------------------------------------------------------------------------- */ /* Qt control callbacks */ -void OBSAdvAudioCtrl::volumeChanged(int percentage) +void OBSAdvAudioCtrl::volumeChanged(double db) { - float val = float(percentage) / 100.0f; + if (db < MIN_DB) { + volume->setSpecialValueText("-inf dB"); + db = -INFINITY; + } + + float val = obs_db_to_mul(db); obs_source_set_volume(source, val); } @@ -283,12 +316,26 @@ void OBSAdvAudioCtrl::downmixMonoChanged(bool checked) } } -void OBSAdvAudioCtrl::panningChanged(int val) +void OBSAdvAudioCtrl::balanceChanged(int val) { - /* TODO */ - UNUSED_PARAMETER(val); + float bal = (float)val / 100.0f; + + if (abs(50 - val) < 10) { + balance->blockSignals(true); + balance->setValue(50); + bal = 0.5f; + balance->blockSignals(false); + } + + obs_source_set_balance_value(source, bal); } +void OBSAdvAudioCtrl::ResetBalance() +{ + balance->setValue(50); +} + + void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds) { int64_t cur_val = obs_source_get_sync_offset(source); diff --git a/UI/adv-audio-control.hpp b/UI/adv-audio-control.hpp index 1352a4b..05743a5 100644 --- a/UI/adv-audio-control.hpp +++ b/UI/adv-audio-control.hpp @@ -3,12 +3,13 @@ #include #include #include +#include +#include "balance-slider.hpp" class QGridLayout; class QLabel; class QSpinBox; class QCheckBox; -class QSlider; class QComboBox; class OBSAdvAudioCtrl : public QObject { @@ -19,12 +20,12 @@ private: QPointer forceMonoContainer; QPointer mixerContainer; - QPointer panningContainer; + QPointer balanceContainer; QPointer nameLabel; - QPointer volume; + QPointer volume; QPointer forceMono; - QPointer panning; + QPointerbalance; QPointer labelL; QPointer labelR; QPointer syncOffset; @@ -59,9 +60,9 @@ public slots: void SourceSyncChanged(int64_t offset); void SourceMixersChanged(uint32_t mixers); - void volumeChanged(int percentage); + void volumeChanged(double db); void downmixMonoChanged(bool checked); - void panningChanged(int val); + void balanceChanged(int val); void syncOffsetChanged(int milliseconds); void monitoringTypeChanged(int index); void mixer1Changed(bool checked); @@ -70,4 +71,5 @@ public slots: void mixer4Changed(bool checked); void mixer5Changed(bool checked); void mixer6Changed(bool checked); + void ResetBalance(); }; diff --git a/UI/api-interface.cpp b/UI/api-interface.cpp index e7cc836..c69b3ef 100644 --- a/UI/api-interface.cpp +++ b/UI/api-interface.cpp @@ -20,6 +20,10 @@ static T GetOBSRef(QListWidgetItem *item) void EnumProfiles(function &&cb); void EnumSceneCollections(function &&cb); +extern volatile bool streaming_active; +extern volatile bool recording_active; +extern volatile bool replaybuf_active; + /* ------------------------------------------------------------------------- */ template struct OBSStudioCallback { @@ -63,6 +67,11 @@ struct OBSStudioAPI : obs_frontend_callbacks { return (void*)main->winId(); } + void *obs_frontend_get_system_tray(void) override + { + return (void*)main->trayIcon.data(); + } + void obs_frontend_get_scenes( struct obs_frontend_source_list *sources) override { @@ -130,6 +139,17 @@ struct OBSStudioAPI : obs_frontend_callbacks { Q_ARG(OBSSource, OBSSource(transition))); } + int obs_frontend_get_transition_duration(void) override + { + return main->ui->transitionDuration->value(); + } + + void obs_frontend_set_transition_duration(int duration) override + { + QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue", + Q_ARG(int, duration)); + } + void obs_frontend_get_scene_collections( std::vector &strings) override { @@ -232,7 +252,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { bool obs_frontend_streaming_active(void) override { - return main->outputHandler->StreamingActive(); + return os_atomic_load_bool(&streaming_active); } void obs_frontend_recording_start(void) override @@ -247,7 +267,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { bool obs_frontend_recording_active(void) override { - return main->outputHandler->RecordingActive(); + return os_atomic_load_bool(&recording_active); } void obs_frontend_replay_buffer_start(void) override @@ -267,7 +287,7 @@ struct OBSStudioAPI : obs_frontend_callbacks { bool obs_frontend_replay_buffer_active(void) override { - return main->outputHandler->ReplayBufferActive(); + return os_atomic_load_bool(&replaybuf_active); } void *obs_frontend_add_tools_menu_qaction(const char *name) override @@ -290,6 +310,11 @@ struct OBSStudioAPI : obs_frontend_callbacks { QObject::connect(action, &QAction::triggered, func); } + void *obs_frontend_add_dock(void *dock) override + { + return (void*)main->AddDockWidget((QDockWidget *)dock); + } + void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data) override { @@ -430,6 +455,11 @@ struct OBSStudioAPI : obs_frontend_callbacks { main->SetPreviewProgramMode(enable); } + void obs_frontend_preview_program_trigger_transition(void) override + { + QMetaObject::invokeMethod(main, "TransitionClicked"); + } + bool obs_frontend_preview_enabled(void) override { return main->previewEnabled; diff --git a/UI/audio-encoders.hpp b/UI/audio-encoders.hpp index 81c69e6..7bbde42 100644 --- a/UI/audio-encoders.hpp +++ b/UI/audio-encoders.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include diff --git a/UI/auth-base.cpp b/UI/auth-base.cpp new file mode 100644 index 0000000..6a6bcfc --- /dev/null +++ b/UI/auth-base.cpp @@ -0,0 +1,71 @@ +#include "auth-base.hpp" +#include "window-basic-main.hpp" + +#include +#include + +struct AuthInfo { + Auth::Def def; + Auth::create_cb create; +}; + +static std::vector authDefs; + +void Auth::RegisterAuth(const Def &d, create_cb create) +{ + AuthInfo info = {d, create}; + authDefs.push_back(info); +} + +std::shared_ptr Auth::Create(const std::string &service) +{ + for (auto &a : authDefs) { + if (service.find(a.def.service) != std::string::npos) { + return a.create(); + } + } + + return nullptr; +} + +Auth::Type Auth::AuthType(const std::string &service) +{ + for (auto &a : authDefs) { + if (service.find(a.def.service) != std::string::npos) { + return a.def.type; + } + } + + return Type::None; +} + +void Auth::Load() +{ + OBSBasic *main = OBSBasic::Get(); + const char *typeStr = config_get_string(main->Config(), "Auth", "Type"); + if (!typeStr) typeStr = ""; + + main->auth = Create(typeStr); + if (main->auth) { + if (main->auth->LoadInternal()) { + main->auth->LoadUI(); + } + } +} + +void Auth::Save() +{ + OBSBasic *main = OBSBasic::Get(); + Auth *auth = main->auth.get(); + if (!auth) { + if (config_has_user_value(main->Config(), "Auth", "Type")) { + config_remove_value(main->Config(), "Auth", "Type"); + config_save_safe(main->Config(), "tmp", nullptr); + } + return; + } + + config_set_string(main->Config(), "Auth", "Type", auth->service()); + auth->SaveInternal(); + config_save_safe(main->Config(), "tmp", nullptr); +} diff --git a/UI/auth-base.hpp b/UI/auth-base.hpp new file mode 100644 index 0000000..8e04ec1 --- /dev/null +++ b/UI/auth-base.hpp @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include + +class Auth : public QObject { + Q_OBJECT + +protected: + virtual void SaveInternal()=0; + virtual bool LoadInternal()=0; + + bool firstLoad = true; + + struct ErrorInfo { + std::string message; + std::string error; + + ErrorInfo(std::string message_, std::string error_) + : message(message_), error(error_) + {} + }; + +public: + enum class Type { + None, + OAuth_StreamKey + }; + + struct Def { + std::string service; + Type type; + }; + + typedef std::function ()> create_cb; + + inline Auth(const Def &d) : def(d) {} + virtual ~Auth() {} + + inline Type type() const {return def.type;} + inline const char *service() const {return def.service.c_str();} + + virtual void LoadUI() {} + + virtual void OnStreamConfig() {} + + static std::shared_ptr Create(const std::string &service); + static Type AuthType(const std::string &service); + static void Load(); + static void Save(); + +protected: + static void RegisterAuth(const Def &d, create_cb create); + +private: + Def def; +}; diff --git a/UI/auth-mixer.cpp b/UI/auth-mixer.cpp new file mode 100644 index 0000000..dc2cb5b --- /dev/null +++ b/UI/auth-mixer.cpp @@ -0,0 +1,336 @@ +#include "auth-mixer.hpp" + +#include +#include +#include + +#include +#include + +#include "window-basic-main.hpp" +#include "remote-text.hpp" +#include "window-dock.hpp" + +#include + +#include + +#include "ui-config.h" +#include "obf.h" + +using namespace json11; + +#include +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +/* ------------------------------------------------------------------------- */ + +#define MIXER_AUTH_URL \ + "https://obsproject.com/app-auth/mixer?action=redirect" +#define MIXER_TOKEN_URL \ + "https://obsproject.com/app-auth/mixer-token" + +#define MIXER_SCOPE_VERSION 1 + +static Auth::Def mixerDef = { + "Mixer", + Auth::Type::OAuth_StreamKey +}; + +/* ------------------------------------------------------------------------- */ + +MixerAuth::MixerAuth(const Def &d) + : OAuthStreamKey(d) +{ +} + +bool MixerAuth::GetChannelInfo(bool allow_retry) +try { + std::string client_id = MIXER_CLIENTID; + deobfuscate_str(&client_id[0], MIXER_HASH); + + if (!GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION)) + return false; + if (token.empty()) + return false; + if (!key_.empty()) + return true; + + std::string auth; + auth += "Authorization: Bearer "; + auth += token; + + std::vector headers; + headers.push_back(std::string("Client-ID: ") + client_id); + headers.push_back(std::move(auth)); + + std::string output; + std::string error; + Json json; + bool success; + + if (id.empty()) { + auto func = [&] () { + success = GetRemoteFile( + "https://mixer.com/api/v1/users/current", + output, + error, + nullptr, + "application/json", + nullptr, + headers, + nullptr, + 5); + }; + + ExecThreadedWithoutBlocking( + func, + QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); + if (!success || output.empty()) + throw ErrorInfo("Failed to get user info from remote", + error); + + Json json = Json::parse(output, error); + if (!error.empty()) + throw ErrorInfo("Failed to parse json", error); + + error = json["error"].string_value(); + if (!error.empty()) + throw ErrorInfo(error, + json["error_description"].string_value()); + + id = std::to_string(json["channel"]["id"].int_value()); + name = json["channel"]["token"].string_value(); + } + + /* ------------------ */ + + std::string url; + url += "https://mixer.com/api/v1/channels/"; + url += id; + url += "/details"; + + output.clear(); + + auto func = [&] () { + success = GetRemoteFile( + url.c_str(), + output, + error, + nullptr, + "application/json", + nullptr, + headers, + nullptr, + 5); + }; + + ExecThreadedWithoutBlocking( + func, + QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); + if (!success || output.empty()) + throw ErrorInfo("Failed to get stream key from remote", error); + + json = Json::parse(output, error); + if (!error.empty()) + throw ErrorInfo("Failed to parse json", error); + + error = json["error"].string_value(); + if (!error.empty()) + throw ErrorInfo(error, json["error_description"].string_value()); + + std::string key_suffix = json["streamKey"].string_value(); + + /* Mixer does not throw an error; instead it gives you the channel data + * json without the data you normally have privileges for, which means + * it'll be an empty stream key usually. So treat empty stream key as + * an error. */ + if (key_suffix.empty()) { + if (allow_retry && RetryLogin()) { + return GetChannelInfo(false); + } + throw ErrorInfo("Auth Failure", "Could not get channel data"); + } + + key_ = id + "-" + key_suffix; + + return true; +} catch (ErrorInfo info) { + QString title = QTStr("Auth.ChannelFailure.Title"); + QString text = QTStr("Auth.ChannelFailure.Text") + .arg(service(), info.message.c_str(), info.error.c_str()); + + QMessageBox::warning(OBSBasic::Get(), title, text); + + blog(LOG_WARNING, "%s: %s: %s", + __FUNCTION__, + info.message.c_str(), + info.error.c_str()); + return false; +} + +void MixerAuth::SaveInternal() +{ + OBSBasic *main = OBSBasic::Get(); + config_set_string(main->Config(), service(), "Name", name.c_str()); + config_set_string(main->Config(), service(), "Id", id.c_str()); + if (uiLoaded) { + config_set_string(main->Config(), service(), "DockState", + main->saveState().toBase64().constData()); + } + OAuthStreamKey::SaveInternal(); +} + +static inline std::string get_config_str( + OBSBasic *main, + const char *section, + const char *name) +{ + const char *val = config_get_string(main->Config(), section, name); + return val ? val : ""; +} + +bool MixerAuth::LoadInternal() +{ + if (!cef) + return false; + + OBSBasic *main = OBSBasic::Get(); + name = get_config_str(main, service(), "Name"); + id = get_config_str(main, service(), "Id"); + firstLoad = false; + return OAuthStreamKey::LoadInternal(); +} + +class MixerChat : public OBSDock { +public: + inline MixerChat() : OBSDock() {} + + QScopedPointer widget; +}; + +void MixerAuth::LoadUI() +{ + if (!cef) + return; + if (uiLoaded) + return; + if (!GetChannelInfo()) + return; + + OBSBasic::InitBrowserPanelSafeBlock(); + OBSBasic *main = OBSBasic::Get(); + + std::string url; + url += "https://mixer.com/embed/chat/"; + url += id; + + QSize size = main->frameSize(); + QPoint pos = main->pos(); + + chat.reset(new MixerChat()); + chat->setObjectName("mixerChat"); + chat->resize(300, 600); + chat->setMinimumSize(200, 300); + chat->setWindowTitle(QTStr("Auth.Chat")); + chat->setAllowedAreas(Qt::AllDockWidgetAreas); + + QCefWidget *browser = cef->create_widget(nullptr, url, panel_cookies); + chat->setWidget(browser); + + main->addDockWidget(Qt::RightDockWidgetArea, chat.data()); + chatMenu.reset(main->AddDockWidget(chat.data())); + + /* ----------------------------------- */ + + chat->setFloating(true); + chat->move(pos.x() + size.width() - chat->width() - 50, pos.y() + 50); + + if (firstLoad) { + chat->setVisible(true); + } else { + const char *dockStateStr = config_get_string(main->Config(), + service(), "DockState"); + QByteArray dockState = + QByteArray::fromBase64(QByteArray(dockStateStr)); + main->restoreState(dockState); + } + + uiLoaded = true; +} + +bool MixerAuth::RetryLogin() +{ + if (!cef) + return false; + + OAuthLogin login(OBSBasic::Get(), MIXER_AUTH_URL, false); + cef->add_popup_whitelist_url("about:blank", &login); + + if (login.exec() == QDialog::Rejected) { + return false; + } + + std::shared_ptr auth = std::make_shared(mixerDef); + std::string client_id = MIXER_CLIENTID; + deobfuscate_str(&client_id[0], MIXER_HASH); + + return GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()), true); +} + +std::shared_ptr MixerAuth::Login(QWidget *parent) +{ + if (!cef) { + return nullptr; + } + + OAuthLogin login(parent, MIXER_AUTH_URL, false); + cef->add_popup_whitelist_url("about:blank", &login); + + if (login.exec() == QDialog::Rejected) { + return nullptr; + } + + std::shared_ptr auth = std::make_shared(mixerDef); + + std::string client_id = MIXER_CLIENTID; + deobfuscate_str(&client_id[0], MIXER_HASH); + + if (!auth->GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()))) { + return nullptr; + } + + std::string error; + if (auth->GetChannelInfo(false)) { + return auth; + } + + return nullptr; +} + +static std::shared_ptr CreateMixerAuth() +{ + return std::make_shared(mixerDef); +} + +static void DeleteCookies() +{ + if (panel_cookies) { + panel_cookies->DeleteCookies("mixer.com", std::string()); + panel_cookies->DeleteCookies("microsoft.com", std::string()); + } +} + +void RegisterMixerAuth() +{ + OAuth::RegisterOAuth( + mixerDef, + CreateMixerAuth, + MixerAuth::Login, + DeleteCookies); +} diff --git a/UI/auth-mixer.hpp b/UI/auth-mixer.hpp new file mode 100644 index 0000000..29a6e33 --- /dev/null +++ b/UI/auth-mixer.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "auth-oauth.hpp" + +class MixerChat; + +class MixerAuth : public OAuthStreamKey { + Q_OBJECT + + QSharedPointer chat; + QSharedPointer chatMenu; + bool uiLoaded = false; + + std::string name; + std::string id; + + virtual bool RetryLogin() override; + + virtual void SaveInternal() override; + virtual bool LoadInternal() override; + + bool GetChannelInfo(bool allow_retry = true); + + virtual void LoadUI() override; + +public: + MixerAuth(const Def &d); + + static std::shared_ptr Login(QWidget *parent); +}; diff --git a/UI/auth-oauth.cpp b/UI/auth-oauth.cpp new file mode 100644 index 0000000..976bca4 --- /dev/null +++ b/UI/auth-oauth.cpp @@ -0,0 +1,311 @@ +#include "auth-oauth.hpp" + +#include +#include +#include + +#include +#include + +#include "window-basic-main.hpp" +#include "remote-text.hpp" + +#include + +#include + +using namespace json11; + +#include +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +/* ------------------------------------------------------------------------- */ + +OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token) + : QDialog (parent), + get_token (token) +{ + if (!cef) { + return; + } + + setWindowTitle("Auth"); + setMinimumSize(400, 400); + resize(700, 700); + + Qt::WindowFlags flags = windowFlags(); + Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint; + setWindowFlags(flags & (~helpFlag)); + + OBSBasic::InitBrowserPanelSafeBlock(); + + cefWidget = cef->create_widget(nullptr, url, panel_cookies); + if (!cefWidget) { + fail = true; + return; + } + + connect(cefWidget, SIGNAL(titleChanged(const QString &)), + this, SLOT(setWindowTitle(const QString &))); + connect(cefWidget, SIGNAL(urlChanged(const QString &)), + this, SLOT(urlChanged(const QString &))); + + QPushButton *close = new QPushButton(QTStr("Cancel")); + connect(close, &QAbstractButton::clicked, + this, &QDialog::reject); + + QHBoxLayout *bottomLayout = new QHBoxLayout(); + bottomLayout->addStretch(); + bottomLayout->addWidget(close); + bottomLayout->addStretch(); + + QVBoxLayout *topLayout = new QVBoxLayout(this); + topLayout->addWidget(cefWidget); + topLayout->addLayout(bottomLayout); +} + +OAuthLogin::~OAuthLogin() +{ + delete cefWidget; +} + +int OAuthLogin::exec() +{ + if (cefWidget) { + return QDialog::exec(); + } + + return QDialog::Rejected; +} + +void OAuthLogin::urlChanged(const QString &url) +{ + std::string uri = get_token ? "access_token=" : "code="; + int code_idx = url.indexOf(uri.c_str()); + if (code_idx == -1) + return; + + if (url.left(22) != "https://obsproject.com") + return; + + code_idx += (int)uri.size(); + + int next_idx = url.indexOf("&", code_idx); + if (next_idx != -1) + code = url.mid(code_idx, next_idx - code_idx); + else + code = url.right(url.size() - code_idx); + + accept(); +} + +/* ------------------------------------------------------------------------- */ + +struct OAuthInfo { + Auth::Def def; + OAuth::login_cb login; + OAuth::delete_cookies_cb delete_cookies; +}; + +static std::vector loginCBs; + +void OAuth::RegisterOAuth(const Def &d, create_cb create, login_cb login, + delete_cookies_cb delete_cookies) +{ + OAuthInfo info = {d, login, delete_cookies}; + loginCBs.push_back(info); + RegisterAuth(d, create); +} + +std::shared_ptr OAuth::Login(QWidget *parent, const std::string &service) +{ + for (auto &a : loginCBs) { + if (service.find(a.def.service) != std::string::npos) { + return a.login(parent); + } + } + + return nullptr; +} + +void OAuth::DeleteCookies(const std::string &service) +{ + for (auto &a : loginCBs) { + if (service.find(a.def.service) != std::string::npos) { + a.delete_cookies(); + } + } +} + +void OAuth::SaveInternal() +{ + OBSBasic *main = OBSBasic::Get(); + config_set_string(main->Config(), service(), "RefreshToken", + refresh_token.c_str()); + config_set_string(main->Config(), service(), "Token", token.c_str()); + config_set_uint(main->Config(), service(), "ExpireTime", expire_time); + config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer); +} + +static inline std::string get_config_str( + OBSBasic *main, + const char *section, + const char *name) +{ + const char *val = config_get_string(main->Config(), section, name); + return val ? val : ""; +} + +bool OAuth::LoadInternal() +{ + OBSBasic *main = OBSBasic::Get(); + refresh_token = get_config_str(main, service(), "RefreshToken"); + token = get_config_str(main, service(), "Token"); + expire_time = config_get_uint(main->Config(), service(), "ExpireTime"); + currentScopeVer = (int)config_get_int(main->Config(), service(), + "ScopeVer"); + return implicit + ? !token.empty() + : !refresh_token.empty(); +} + +bool OAuth::TokenExpired() +{ + if (token.empty()) + return true; + if ((uint64_t)time(nullptr) > expire_time - 5) + return true; + return false; +} + +bool OAuth::GetToken(const char *url, const std::string &client_id, + int scope_ver, const std::string &auth_code, bool retry) +try { + std::string output; + std::string error; + std::string desc; + + if (currentScopeVer > 0 && currentScopeVer < scope_ver) { + if (RetryLogin()) { + return true; + } else { + QString title = QTStr("Auth.InvalidScope.Title"); + QString text = QTStr("Auth.InvalidScope.Text") + .arg(service()); + + QMessageBox::warning(OBSBasic::Get(), title, text); + } + } + + if (auth_code.empty() && !TokenExpired()) { + return true; + } + + std::string post_data; + post_data += "action=redirect&client_id="; + post_data += client_id; + + if (!auth_code.empty()) { + post_data += "&grant_type=authorization_code&code="; + post_data += auth_code; + } else { + post_data += "&grant_type=refresh_token&refresh_token="; + post_data += refresh_token; + } + + bool success = false; + + auto func = [&] () { + success = GetRemoteFile( + url, + output, + error, + nullptr, + "application/x-www-form-urlencoded", + post_data.c_str(), + std::vector(), + nullptr, + 5); + }; + + ExecThreadedWithoutBlocking( + func, + QTStr("Auth.Authing.Title"), + QTStr("Auth.Authing.Text").arg(service())); + if (!success || output.empty()) + throw ErrorInfo("Failed to get token from remote", error); + + Json json = Json::parse(output, error); + if (!error.empty()) + throw ErrorInfo("Failed to parse json", error); + + /* -------------------------- */ + /* error handling */ + + error = json["error"].string_value(); + if (!retry && error == "invalid_grant") { + if (RetryLogin()) { + return true; + } + } + if (!error.empty()) + throw ErrorInfo(error, json["error_description"].string_value()); + + /* -------------------------- */ + /* success! */ + + expire_time = (uint64_t)time(nullptr) + json["expires_in"].int_value(); + token = json["access_token"].string_value(); + if (token.empty()) + throw ErrorInfo("Failed to get token from remote", error); + + if (!auth_code.empty()) { + refresh_token = json["refresh_token"].string_value(); + if (refresh_token.empty()) + throw ErrorInfo("Failed to get refresh token from " + "remote", error); + + currentScopeVer = scope_ver; + } + + return true; + +} catch (ErrorInfo info) { + if (!retry) { + QString title = QTStr("Auth.AuthFailure.Title"); + QString text = QTStr("Auth.AuthFailure.Text") + .arg(service(), info.message.c_str(), info.error.c_str()); + + QMessageBox::warning(OBSBasic::Get(), title, text); + } + + blog(LOG_WARNING, "%s: %s: %s", + __FUNCTION__, + info.message.c_str(), + info.error.c_str()); + return false; +} + +void OAuthStreamKey::OnStreamConfig() +{ + if (key_.empty()) + return; + + OBSBasic *main = OBSBasic::Get(); + obs_service_t *service = main->GetService(); + + obs_data_t *settings = obs_service_get_settings(service); + + bool bwtest = obs_data_get_bool(settings, "bwtest"); + + if (bwtest && strcmp(this->service(), "Twitch") == 0) + obs_data_set_string(settings, "key", + (key_ + "?bandwidthtest=true").c_str()); + else + obs_data_set_string(settings, "key", key_.c_str()); + + obs_service_update(service, settings); + + obs_data_release(settings); +} diff --git a/UI/auth-oauth.hpp b/UI/auth-oauth.hpp new file mode 100644 index 0000000..7cf035c --- /dev/null +++ b/UI/auth-oauth.hpp @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include + +#include "auth-base.hpp" + +class QCefWidget; + +class OAuthLogin : public QDialog { + Q_OBJECT + + QCefWidget *cefWidget = nullptr; + QString code; + bool get_token = false; + bool fail = false; + +public: + OAuthLogin(QWidget *parent, const std::string &url, bool token); + ~OAuthLogin(); + + inline QString GetCode() const {return code;} + inline bool LoadFail() const {return fail;} + + virtual int exec() override; + +public slots: + void urlChanged(const QString &url); +}; + +class OAuth : public Auth { + Q_OBJECT + +public: + inline OAuth(const Def &d) : Auth(d) {} + + typedef std::function (QWidget *)> login_cb; + typedef std::function delete_cookies_cb; + + static std::shared_ptr Login(QWidget *parent, + const std::string &service); + static void DeleteCookies(const std::string &service); + + static void RegisterOAuth(const Def &d, create_cb create, + login_cb login, delete_cookies_cb delete_cookies); + +protected: + std::string refresh_token; + std::string token; + bool implicit = false; + uint64_t expire_time = 0; + int currentScopeVer = 0; + + virtual void SaveInternal() override; + virtual bool LoadInternal() override; + + virtual bool RetryLogin()=0; + bool TokenExpired(); + bool GetToken(const char *url, const std::string &client_id, + int scope_ver, + const std::string &auth_code = std::string(), + bool retry = false); +}; + +class OAuthStreamKey : public OAuth { + Q_OBJECT + +protected: + std::string key_; + +public: + inline OAuthStreamKey(const Def &d) : OAuth(d) {} + + inline const std::string &key() const {return key_;} + + virtual void OnStreamConfig() override; +}; diff --git a/UI/auth-restream.cpp b/UI/auth-restream.cpp new file mode 100644 index 0000000..f10e8cb --- /dev/null +++ b/UI/auth-restream.cpp @@ -0,0 +1,283 @@ +#include "auth-restream.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "window-basic-main.hpp" +#include "remote-text.hpp" +#include "ui-config.h" +#include "obf.h" +#include + +using namespace json11; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +/* ------------------------------------------------------------------------- */ + +#define RESTREAM_AUTH_URL "https://obsproject.com/app-auth/restream?action=redirect" +#define RESTREAM_TOKEN_URL "https://obsproject.com/app-auth/restream-token" +#define RESTREAM_STREAMKEY_URL "https://api.restream.io/v2/user/streamKey" +#define RESTREAM_SCOPE_VERSION 1 + + +static Auth::Def restreamDef = { + "Restream", + Auth::Type::OAuth_StreamKey +}; + +/* ------------------------------------------------------------------------- */ + +RestreamAuth::RestreamAuth(const Def &d) + : OAuthStreamKey(d) +{ +} + +bool RestreamAuth::GetChannelInfo() +try { + std::string client_id = RESTREAM_CLIENTID; + deobfuscate_str(&client_id[0], RESTREAM_HASH); + + if (!GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION)) + return false; + if (token.empty()) + return false; + if (!key_.empty()) + return true; + + std::string auth; + auth += "Authorization: Bearer "; + auth += token; + + std::vector headers; + headers.push_back(std::string("Client-ID: ") + client_id); + headers.push_back(std::move(auth)); + + std::string output; + std::string error; + Json json; + bool success; + + auto func = [&] () { + success = GetRemoteFile( + RESTREAM_STREAMKEY_URL, + output, + error, + nullptr, + "application/json", + nullptr, + headers, + nullptr, + 5); + }; + + ExecThreadedWithoutBlocking( + func, + QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); + if (!success || output.empty()) + throw ErrorInfo("Failed to get stream key from remote", error); + + json = Json::parse(output, error); + if (!error.empty()) + throw ErrorInfo("Failed to parse json", error); + + error = json["error"].string_value(); + if (!error.empty()) + throw ErrorInfo(error, json["error_description"].string_value()); + + key_ = json["streamKey"].string_value(); + + return true; +} catch (ErrorInfo info) { + QString title = QTStr("Auth.ChannelFailure.Title"); + QString text = QTStr("Auth.ChannelFailure.Text") + .arg(service(), info.message.c_str(), info.error.c_str()); + + QMessageBox::warning(OBSBasic::Get(), title, text); + + blog(LOG_WARNING, "%s: %s: %s", + __FUNCTION__, + info.message.c_str(), + info.error.c_str()); + return false; +} + +void RestreamAuth::SaveInternal() +{ + OBSBasic *main = OBSBasic::Get(); + config_set_string(main->Config(), service(), "DockState", + main->saveState().toBase64().constData()); + OAuthStreamKey::SaveInternal(); +} + +static inline std::string get_config_str( + OBSBasic *main, + const char *section, + const char *name) +{ + const char *val = config_get_string(main->Config(), section, name); + return val ? val : ""; +} + +bool RestreamAuth::LoadInternal() +{ + firstLoad = false; + return OAuthStreamKey::LoadInternal(); +} + +class RestreamWidget : public QDockWidget { +public: + inline RestreamWidget() : QDockWidget() {} + + QScopedPointer widget; +}; + +void RestreamAuth::LoadUI() +{ + if (uiLoaded) + return; + if (!GetChannelInfo()) + return; + + OBSBasic::InitBrowserPanelSafeBlock(); + OBSBasic *main = OBSBasic::Get(); + + QCefWidget *browser; + std::string url; + std::string script; + + /* ----------------------------------- */ + + url = "https://restream.io/chat-application"; + + QSize size = main->frameSize(); + QPoint pos = main->pos(); + + chat.reset(new RestreamWidget()); + chat->setObjectName("restreamChat"); + chat->resize(420, 600); + chat->setMinimumSize(200, 300); + chat->setWindowTitle(QTStr("Auth.Chat")); + chat->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + chat->setWidget(browser); + + main->addDockWidget(Qt::RightDockWidgetArea, chat.data()); + chatMenu.reset(main->AddDockWidget(chat.data())); + + /* ----------------------------------- */ + + url = "https://restream.io/titles/embed"; + + info.reset(new RestreamWidget()); + info->setObjectName("restreamInfo"); + info->resize(410, 600); + info->setMinimumSize(200, 150); + info->setWindowTitle(QTStr("Auth.StreamInfo")); + info->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + info->setWidget(browser); + + main->addDockWidget(Qt::RightDockWidgetArea, info.data()); + infoMenu.reset(main->AddDockWidget(info.data())); + + /* ----------------------------------- */ + + chat->setFloating(true); + info->setFloating(true); + chat->move(pos.x() + size.width() - chat->width() - 50, pos.y() + 50); + info->move(pos.x() + 40, pos.y() + 50); + + if (firstLoad) { + chat->setVisible(true); + info->setVisible(true); + } + else { + const char *dockStateStr = config_get_string(main->Config(), + service(), "DockState"); + QByteArray dockState = + QByteArray::fromBase64(QByteArray(dockStateStr)); + main->restoreState(dockState); + } + + uiLoaded = true; +} + +bool RestreamAuth::RetryLogin() +{ + OAuthLogin login(OBSBasic::Get(), RESTREAM_AUTH_URL, false); + cef->add_popup_whitelist_url("about:blank", &login); + if (login.exec() == QDialog::Rejected) { + return false; + } + + std::shared_ptr auth = + std::make_shared(restreamDef); + + std::string client_id = RESTREAM_CLIENTID; + deobfuscate_str(&client_id[0], RESTREAM_HASH); + + return GetToken(RESTREAM_TOKEN_URL, client_id, + RESTREAM_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()), true); +} + +std::shared_ptr RestreamAuth::Login(QWidget *parent) +{ + OAuthLogin login(parent, RESTREAM_AUTH_URL, false); + cef->add_popup_whitelist_url("about:blank", &login); + + if (login.exec() == QDialog::Rejected) { + return nullptr; + } + + std::shared_ptr auth = + std::make_shared(restreamDef); + + std::string client_id = RESTREAM_CLIENTID; + deobfuscate_str(&client_id[0], RESTREAM_HASH); + + if (!auth->GetToken(RESTREAM_TOKEN_URL, client_id, + RESTREAM_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()))) { + return nullptr; + } + + std::string error; + if (auth->GetChannelInfo()) { + return auth; + } + + return nullptr; +} + +static std::shared_ptr CreateRestreamAuth() +{ + return std::make_shared(restreamDef); +} + +static void DeleteCookies() +{ + if (panel_cookies) { + panel_cookies->DeleteCookies("restream.io", std::string()); + } +} + +void RegisterRestreamAuth() +{ + OAuth::RegisterOAuth( + restreamDef, + CreateRestreamAuth, + RestreamAuth::Login, + DeleteCookies); +} diff --git a/UI/auth-restream.hpp b/UI/auth-restream.hpp new file mode 100644 index 0000000..5e66fb0 --- /dev/null +++ b/UI/auth-restream.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "auth-oauth.hpp" + +class RestreamWidget; + +class RestreamAuth : public OAuthStreamKey { + Q_OBJECT + + QSharedPointer chat; + QSharedPointer info; + QSharedPointer chatMenu; + QSharedPointer infoMenu; + bool uiLoaded = false; + + virtual bool RetryLogin() override; + + virtual void SaveInternal() override; + virtual bool LoadInternal() override; + + bool GetChannelInfo(); + + virtual void LoadUI() override; + +public: + RestreamAuth(const Def &d); + + static std::shared_ptr Login(QWidget *parent); +}; diff --git a/UI/auth-twitch.cpp b/UI/auth-twitch.cpp new file mode 100644 index 0000000..3206c32 --- /dev/null +++ b/UI/auth-twitch.cpp @@ -0,0 +1,483 @@ +#include "auth-twitch.hpp" + +#include +#include +#include + +#include +#include + +#include "window-basic-main.hpp" +#include "remote-text.hpp" +#include "window-dock.hpp" + +#include + +#include "ui-config.h" +#include "obf.h" + +using namespace json11; + +#include +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +/* ------------------------------------------------------------------------- */ + +#define TWITCH_AUTH_URL \ + "https://obsproject.com/app-auth/twitch?action=redirect" +#define TWITCH_TOKEN_URL \ + "https://obsproject.com/app-auth/twitch-token" +#define ACCEPT_HEADER \ + "Accept: application/vnd.twitchtv.v5+json" + +#define TWITCH_SCOPE_VERSION 1 + +static Auth::Def twitchDef = { + "Twitch", + Auth::Type::OAuth_StreamKey +}; + +/* ------------------------------------------------------------------------- */ + +TwitchAuth::TwitchAuth(const Def &d) + : OAuthStreamKey(d) +{ + if (!cef) + return; + + cef->add_popup_whitelist_url( + "https://twitch.tv/popout/frankerfacez/chat?ffz-settings", + this); + uiLoadTimer.setSingleShot(true); + uiLoadTimer.setInterval(500); + connect(&uiLoadTimer, &QTimer::timeout, + this, &TwitchAuth::TryLoadSecondaryUIPanes); +} + +bool TwitchAuth::GetChannelInfo() +try { + std::string client_id = TWITCH_CLIENTID; + deobfuscate_str(&client_id[0], TWITCH_HASH); + + if (!GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION)) + return false; + if (token.empty()) + return false; + if (!key_.empty()) + return true; + + std::string auth; + auth += "Authorization: OAuth "; + auth += token; + + std::vector headers; + headers.push_back(std::string("Client-ID: ") + client_id); + headers.push_back(ACCEPT_HEADER); + headers.push_back(std::move(auth)); + + std::string output; + std::string error; + long error_code = 0; + + bool success = false; + + auto func = [&] () { + success = GetRemoteFile( + "https://api.twitch.tv/kraken/channel", + output, + error, + &error_code, + "application/json", + nullptr, + headers, + nullptr, + 5); + }; + + ExecThreadedWithoutBlocking( + func, + QTStr("Auth.LoadingChannel.Title"), + QTStr("Auth.LoadingChannel.Text").arg(service())); + if (error_code == 403) { + OBSMessageBox::warning(OBSBasic::Get(), + Str("TwitchAuth.TwoFactorFail.Title"), + Str("TwitchAuth.TwoFactorFail.Text"), + true); + blog(LOG_WARNING, "%s: %s", + __FUNCTION__, + "Got 403 from Twitch, user probably does not " + "have two-factor authentication enabled on " + "their account"); + return false; + } + + if (!success || output.empty()) + throw ErrorInfo("Failed to get text from remote", error); + + Json json = Json::parse(output, error); + if (!error.empty()) + throw ErrorInfo("Failed to parse json", error); + + error = json["error"].string_value(); + if (!error.empty()) { + if (error == "Unauthorized") { + if (RetryLogin()) { + return GetChannelInfo(); + } + throw ErrorInfo(error, + json["message"].string_value()); + } + throw ErrorInfo(error, json["error_description"].string_value()); + } + + name = json["name"].string_value(); + key_ = json["stream_key"].string_value(); + + return true; +} catch (ErrorInfo info) { + QString title = QTStr("Auth.ChannelFailure.Title"); + QString text = QTStr("Auth.ChannelFailure.Text") + .arg(service(), info.message.c_str(), info.error.c_str()); + + QMessageBox::warning(OBSBasic::Get(), title, text); + + blog(LOG_WARNING, "%s: %s: %s", + __FUNCTION__, + info.message.c_str(), + info.error.c_str()); + return false; +} + +void TwitchAuth::SaveInternal() +{ + OBSBasic *main = OBSBasic::Get(); + config_set_string(main->Config(), service(), "Name", name.c_str()); + if (uiLoaded) { + config_set_string(main->Config(), service(), "DockState", + main->saveState().toBase64().constData()); + } + OAuthStreamKey::SaveInternal(); +} + +static inline std::string get_config_str( + OBSBasic *main, + const char *section, + const char *name) +{ + const char *val = config_get_string(main->Config(), section, name); + return val ? val : ""; +} + +bool TwitchAuth::LoadInternal() +{ + if (!cef) + return false; + + OBSBasic *main = OBSBasic::Get(); + name = get_config_str(main, service(), "Name"); + firstLoad = false; + return OAuthStreamKey::LoadInternal(); +} + +class TwitchWidget : public OBSDock { +public: + inline TwitchWidget() : OBSDock() {} + + QScopedPointer widget; + + inline void SetWidget(QCefWidget *widget_) + { + setWidget(widget_); + widget.reset(widget_); + } +}; + +static const char *ffz_script = "\ +var ffz = document.createElement('script');\ +ffz.setAttribute('src','https://cdn.frankerfacez.com/script/script.min.js');\ +document.head.appendChild(ffz);"; + +static const char *bttv_script = "\ +localStorage.setItem('bttv_clickTwitchEmotes', true);\ +localStorage.setItem('bttv_darkenedMode', true);\ +localStorage.setItem('bttv_bttvGIFEmotes', true);\ +var bttv = document.createElement('script');\ +bttv.setAttribute('src','https://cdn.betterttv.net/betterttv.js');\ +document.head.appendChild(bttv);"; + +static const char *referrer_script1 = "\ +Object.defineProperty(document, 'referrer', {get : function() { return '"; +static const char *referrer_script2 = "'; }});"; + +void TwitchAuth::LoadUI() +{ + if (!cef) + return; + if (uiLoaded) + return; + if (!GetChannelInfo()) + return; + + OBSBasic::InitBrowserPanelSafeBlock(); + OBSBasic *main = OBSBasic::Get(); + + QCefWidget *browser; + std::string url; + std::string script; + + std::string moderation_tools_url; + moderation_tools_url = "https://www.twitch.tv/"; + moderation_tools_url += name; + moderation_tools_url += "/dashboard/settings/moderation?no-reload=true"; + + /* ----------------------------------- */ + + url = "https://www.twitch.tv/popout/"; + url += name; + url += "/chat"; + + QSize size = main->frameSize(); + QPoint pos = main->pos(); + + chat.reset(new TwitchWidget()); + chat->setObjectName("twitchChat"); + chat->resize(300, 600); + chat->setMinimumSize(200, 300); + chat->setWindowTitle(QTStr("Auth.Chat")); + chat->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + chat->SetWidget(browser); + cef->add_force_popup_url(moderation_tools_url, chat.data()); + + script = bttv_script; + script += ffz_script; + browser->setStartupScript(script); + + main->addDockWidget(Qt::RightDockWidgetArea, chat.data()); + chatMenu.reset(main->AddDockWidget(chat.data())); + + /* ----------------------------------- */ + + chat->setFloating(true); + chat->move(pos.x() + size.width() - chat->width() - 50, pos.y() + 50); + + if (firstLoad) { + chat->setVisible(true); + } else { + const char *dockStateStr = config_get_string(main->Config(), + service(), "DockState"); + QByteArray dockState = + QByteArray::fromBase64(QByteArray(dockStateStr)); + main->restoreState(dockState); + } + + TryLoadSecondaryUIPanes(); + + uiLoaded = true; +} + +void TwitchAuth::LoadSecondaryUIPanes() +{ + OBSBasic *main = OBSBasic::Get(); + + QCefWidget *browser; + std::string url; + std::string script; + + QSize size = main->frameSize(); + QPoint pos = main->pos(); + + script = "localStorage.setItem('twilight.theme', 1);"; + script += referrer_script1; + script += "https://www.twitch.tv/"; + script += name; + script += "/dashboard/live"; + script += referrer_script2; + script += bttv_script; + script += ffz_script; + + /* ----------------------------------- */ + + url = "https://www.twitch.tv/popout/"; + url += name; + url += "/dashboard/live/stream-info"; + + info.reset(new TwitchWidget()); + info->setObjectName("twitchInfo"); + info->resize(300, 650); + info->setMinimumSize(200, 300); + info->setWindowTitle(QTStr("Auth.StreamInfo")); + info->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + info->SetWidget(browser); + browser->setStartupScript(script); + + main->addDockWidget(Qt::RightDockWidgetArea, info.data()); + infoMenu.reset(main->AddDockWidget(info.data())); + + /* ----------------------------------- */ + + url = "https://www.twitch.tv/popout/"; + url += name; + url += "/dashboard/live/stats"; + + stat.reset(new TwitchWidget()); + stat->setObjectName("twitchStats"); + stat->resize(200, 250); + stat->setMinimumSize(200, 150); + stat->setWindowTitle(QTStr("TwitchAuth.Stats")); + stat->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + stat->SetWidget(browser); + browser->setStartupScript(script); + + main->addDockWidget(Qt::RightDockWidgetArea, stat.data()); + statMenu.reset(main->AddDockWidget(stat.data())); + + /* ----------------------------------- */ + + url = "https://www.twitch.tv/popout/"; + url += name; + url += "/dashboard/live/activity-feed"; + + feed.reset(new TwitchWidget()); + feed->setObjectName("twitchFeed"); + feed->resize(300, 650); + feed->setMinimumSize(200, 300); + feed->setWindowTitle(QTStr("TwitchAuth.Feed")); + feed->setAllowedAreas(Qt::AllDockWidgetAreas); + + browser = cef->create_widget(nullptr, url, panel_cookies); + feed->SetWidget(browser); + browser->setStartupScript(script); + + main->addDockWidget(Qt::RightDockWidgetArea, feed.data()); + feedMenu.reset(main->AddDockWidget(feed.data())); + + /* ----------------------------------- */ + + info->setFloating(true); + stat->setFloating(true); + feed->setFloating(true); + + QSize statSize = stat->frameSize(); + + info->move(pos.x() + 50, pos.y() + 50); + stat->move(pos.x() + size.width() / 2 - statSize.width() / 2, + pos.y() + size.height() / 2 - statSize.height() / 2); + feed->move(pos.x() + 100, pos.y() + 100); + + if (firstLoad) { + info->setVisible(true); + stat->setVisible(false); + feed->setVisible(false); + } else { + uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General", + "LastVersion"); + + if (lastVersion <= MAKE_SEMANTIC_VERSION(23, 0, 2)) { + feed->setVisible(false); + } + + const char *dockStateStr = config_get_string(main->Config(), + service(), "DockState"); + QByteArray dockState = + QByteArray::fromBase64(QByteArray(dockStateStr)); + main->restoreState(dockState); + } +} + +/* Twitch.tv has an OAuth for itself. If we try to load multiple panel pages + * at once before it's OAuth'ed itself, they will all try to perform the auth + * process at the same time, get their own request codes, and only the last + * code will be valid -- so one or more panels are guaranteed to fail. + * + * To solve this, we want to load just one panel first (the chat), and then all + * subsequent panels should only be loaded once we know that Twitch has auth'ed + * itself (if the cookie "auth-token" exists for twitch.tv). + * + * This is annoying to deal with. */ +void TwitchAuth::TryLoadSecondaryUIPanes() +{ + QPointer this_ = this; + + auto cb = [this_] (bool found) + { + if (!this_) { + return; + } + + if (!found) { + QMetaObject::invokeMethod(&this_->uiLoadTimer, + "start"); + } else { + QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes"); + } + }; + + panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", cb); +} + +bool TwitchAuth::RetryLogin() +{ + OAuthLogin login(OBSBasic::Get(), TWITCH_AUTH_URL, false); + if (login.exec() == QDialog::Rejected) { + return false; + } + + std::shared_ptr auth = std::make_shared(twitchDef); + std::string client_id = TWITCH_CLIENTID; + deobfuscate_str(&client_id[0], TWITCH_HASH); + + return GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()), true); +} + +std::shared_ptr TwitchAuth::Login(QWidget *parent) +{ + OAuthLogin login(parent, TWITCH_AUTH_URL, false); + if (login.exec() == QDialog::Rejected) { + return nullptr; + } + + std::shared_ptr auth = std::make_shared(twitchDef); + + std::string client_id = TWITCH_CLIENTID; + deobfuscate_str(&client_id[0], TWITCH_HASH); + + if (!auth->GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION, + QT_TO_UTF8(login.GetCode()))) { + return nullptr; + } + + std::string error; + if (auth->GetChannelInfo()) { + return auth; + } + + return nullptr; +} + +static std::shared_ptr CreateTwitchAuth() +{ + return std::make_shared(twitchDef); +} + +static void DeleteCookies() +{ + if (panel_cookies) + panel_cookies->DeleteCookies("twitch.tv", std::string()); +} + +void RegisterTwitchAuth() +{ + OAuth::RegisterOAuth( + twitchDef, + CreateTwitchAuth, + TwitchAuth::Login, + DeleteCookies); +} diff --git a/UI/auth-twitch.hpp b/UI/auth-twitch.hpp new file mode 100644 index 0000000..76698d1 --- /dev/null +++ b/UI/auth-twitch.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include +#include + +#include "auth-oauth.hpp" + +class TwitchWidget; + +class TwitchAuth : public OAuthStreamKey { + Q_OBJECT + + friend class TwitchLogin; + + QSharedPointer chat; + QSharedPointer info; + QSharedPointer stat; + QSharedPointer feed; + QSharedPointer chatMenu; + QSharedPointer infoMenu; + QSharedPointer statMenu; + QSharedPointer feedMenu; + bool uiLoaded = false; + + std::string name; + + virtual bool RetryLogin() override; + + virtual void SaveInternal() override; + virtual bool LoadInternal() override; + + bool GetChannelInfo(); + + virtual void LoadUI() override; + +public: + TwitchAuth(const Def &d); + + static std::shared_ptr Login(QWidget *parent); + + QTimer uiLoadTimer; + +public slots: + void TryLoadSecondaryUIPanes(); + void LoadSecondaryUIPanes(); +}; diff --git a/UI/balance-slider.hpp b/UI/balance-slider.hpp new file mode 100644 index 0000000..06be1b5 --- /dev/null +++ b/UI/balance-slider.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +class BalanceSlider : public QSlider { + Q_OBJECT + +public: + inline BalanceSlider(QWidget *parent = 0) : QSlider(parent) {} + +signals: + void doubleClicked(); + +protected: + void mouseDoubleClickEvent(QMouseEvent *event) + { + emit doubleClicked(); + event->accept(); + } +}; diff --git a/UI/clickable-label.hpp b/UI/clickable-label.hpp new file mode 100644 index 0000000..3c76a8b --- /dev/null +++ b/UI/clickable-label.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +class ClickableLabel : public QLabel { + Q_OBJECT + +public: + inline ClickableLabel(QWidget *parent = 0) : QLabel(parent) {} + +signals: + void clicked(); + +protected: + void mousePressEvent(QMouseEvent *event) + { + emit clicked(); + event->accept(); + } +}; diff --git a/UI/combobox-ignorewheel.cpp b/UI/combobox-ignorewheel.cpp new file mode 100644 index 0000000..c7c24eb --- /dev/null +++ b/UI/combobox-ignorewheel.cpp @@ -0,0 +1,14 @@ +#include "combobox-ignorewheel.hpp" + +ComboBoxIgnoreScroll::ComboBoxIgnoreScroll(QWidget *parent) : QComboBox(parent) +{ + setFocusPolicy(Qt::StrongFocus); +} + +void ComboBoxIgnoreScroll::wheelEvent(QWheelEvent *event) +{ + if (!hasFocus()) + event->ignore(); + else + QComboBox::wheelEvent(event); +} diff --git a/UI/combobox-ignorewheel.hpp b/UI/combobox-ignorewheel.hpp new file mode 100644 index 0000000..479e1bb --- /dev/null +++ b/UI/combobox-ignorewheel.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include + +class ComboBoxIgnoreScroll : public QComboBox { + Q_OBJECT + +public: + ComboBoxIgnoreScroll(QWidget *parent = nullptr); + +protected: + virtual void wheelEvent(QWheelEvent *event) override; +}; diff --git a/UI/data/images/overflow.png b/UI/data/images/overflow.png new file mode 100644 index 0000000..5bddc33 Binary files /dev/null and b/UI/data/images/overflow.png differ diff --git a/UI/data/locale.ini b/UI/data/locale.ini index 00e4c1f..6068f13 100644 --- a/UI/data/locale.ini +++ b/UI/data/locale.ini @@ -153,3 +153,12 @@ Name=فارسی [gd-GB] Name=Gàidhlig + +[mn-MN] +Name=монгол хэл + +[ku-TR] +Name=کوردی + +[pa-IN] +Name=ਪੰਜਾਬੀ diff --git a/UI/data/locale/af-ZA.ini b/UI/data/locale/af-ZA.ini index ffc182a..91a1316 100644 --- a/UI/data/locale/af-ZA.ini +++ b/UI/data/locale/af-ZA.ini @@ -90,6 +90,10 @@ Rename="Hernoem" + + + + diff --git a/UI/data/locale/ar-SA.ini b/UI/data/locale/ar-SA.ini index ae2c6f9..e18f7c1 100644 --- a/UI/data/locale/ar-SA.ini +++ b/UI/data/locale/ar-SA.ini @@ -1,6 +1,6 @@ Language="العربية" -Region="الوطن العربي" +Region="الولايات المتحدة الأمريكية" OK="موافق" Apply="تطبيق" @@ -78,26 +78,50 @@ None="لا شيء" StudioMode.Preview="معاينة" StudioMode.Program="البث" ShowInMultiview="إظهار في العرض المتعدد" +VerticalLayout="تنسيق عمودي" +Group="مجموعة" +DoNotShowAgain="عدم الإظهار مرة أخرى" +Default="(الافتراضي)" +Calculating="جاري حساب الوقت..." AlreadyRunning.Title="البرنامج قيد التشغيل بالفعل" AlreadyRunning.Text="أوبس قيد التشغيل بالفعل! إلا إذا كنت تريد القيام بذلك، يرجى إيقاف أية مثيلات موجودة من للبرنامج قبل محاولة تشغيله من جديد. إذا كان لديك أوبس تعيين لتقليل إلى علبة النظام، يرجى التحقق لمعرفة ما إذا كان لا يزال قيد التشغيل هناك." AlreadyRunning.LaunchAnyway="إطلاق على أي حال" +DockCloseWarning.Title="إغلاق إطار قابل للإرساء" +DockCloseWarning.Text="لقد قمت بإغلاق إطار قابل للإرساء. إذا كنت ترغب في إظهاره مرة أخرى، استخدم قائمة عرض ← أرصفة من شريط القوائم." + +Auth.Authing.Title="جاري المصادقة..." +Auth.Authing.Text="جارٍ المصادقة مع %1, الرجاء الانتظار..." +Auth.AuthFailure.Title="فشل المصادقة" +Auth.AuthFailure.Text="فشل في المصادقة مع %1:\n\n%2: %3" +Auth.InvalidScope.Title="مطلوب المصادقة" +Auth.InvalidScope.Text="متطلبات المصادقة ل %1 تغيرت. قد لا تعمل بعض الميزات." +Auth.LoadingChannel.Title="جارٍ تحميل معلومات القناة..." +Auth.LoadingChannel.Text="جارٍ تحميل معلومات القناة من%1, الرجاء الانتظار..." +Auth.ChannelFailure.Title="فشل تحميل معلومات القناة" +Auth.ChannelFailure.Text="فشل في تحميل معلومات القناة %1\n\n%2: %3" +Auth.Chat="الدردشة" +Auth.StreamInfo="معلومات البث" +TwitchAuth.Stats="إحصائيات Twitch" +TwitchAuth.TwoFactorFail.Title="لم نتمكن من الاستعلام عن مفتاح البث" + Copy.Filters="نسخ الفلتر" Paste.Filters="لصق الفلتر" +BrowserPanelInit.Title="جارٍ بدء المستعرض..." +BrowserPanelInit.Text="جارٍ بدء المستعرض, الرجاء الانتظار..." + BandwidthTest.Region="منطقة" BandwidthTest.Region.US="الولايات المتحدة" BandwidthTest.Region.EU="أوروبا" BandwidthTest.Region.Asia="آسيا" BandwidthTest.Region.Other="\"غير ذلك\"" -Basic.FirstStartup.RunWizard="هل تريد تشغيل معالج التكوين التلقائي؟ يمكنك أيضا يدوياً تكوين الإعدادات الخاصة بك بواسطة النقر فوق زر \"إعدادات\" في الواجهة الرئيسية." -Basic.FirstStartup.RunWizard.BetaWarning="(ملاحظة: معالج التكوين التلقائي حاليا نسخة تجريبية)" +Basic.FirstStartup.RunWizard="هل تريد تشغيل معالج التكوين التلقائي؟ يمكنك أيضا يدوياً تكوين الإعدادات الخاصة بك بواسطة النقر فوق زر \"إعدادات\" في الواجهة الرئيسية." Basic.FirstStartup.RunWizard.NoClicked="إذا قمت بتغيير رأيك، يمكنك تشغيل معالج التكوين التلقائي في أي وقت مرة أخرى من قائمة أدوات." Basic.AutoConfig="معالج التكوين التلقائي" -Basic.AutoConfig.Beta="معالج التكوين التلقائي (نسخة تجريبية)" Basic.AutoConfig.ApplySettings="تطبيق الإعدادات" Basic.AutoConfig.StartPage="معلومات الاستخدام" Basic.AutoConfig.StartPage.SubTitle="حدد ما تريد استخدامه للبرنامج" @@ -113,8 +137,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="إما 60 أو 30، ولكن يف Basic.AutoConfig.VideoPage.CanvasExplanation="ملاحظة: قرار قاعدة (قاعدة) ليس بالضرورة يكون بنفس دقة البث أو التسجيل. قد يتم تصغير حجم تدفق البث/ دقة التسجيل أقل من دقة القاعدة لتقليل استخدام الموارد أو متطلبات معدل البت." Basic.AutoConfig.StreamPage="معلومات البث" Basic.AutoConfig.StreamPage.SubTitle="من فضلك ادخل معلومات الخادم أو السيرفر" +Basic.AutoConfig.StreamPage.ConnectAccount="تسجيل الدخول إلى قناتك (اختياري)" +Basic.AutoConfig.StreamPage.DisconnectAccount="إلغاء ربط الحساب" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="إلغاء ربط الحساب؟" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="هذا التغيير سيتم تطبيقه مباشرة. هل أنت متأكد من أنك تريد إلغاء ربط حسابك؟" +Basic.AutoConfig.StreamPage.UseStreamKey="استخدم مفتاح البث" Basic.AutoConfig.StreamPage.Service="خدمة" Basic.AutoConfig.StreamPage.Service.ShowAll="عرض الكل..." +Basic.AutoConfig.StreamPage.Service.Custom="مخصص..." Basic.AutoConfig.StreamPage.Server="الخادم" Basic.AutoConfig.StreamPage.StreamKey="مفتاح البث" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(رابط)" @@ -122,16 +152,27 @@ Basic.AutoConfig.StreamPage.PerformBandwidthTest="تقدير معدل التدف Basic.AutoConfig.StreamPage.PreferHardwareEncoding="تفضيل استخدام الترميز بواسطة الهاردوير" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="استخدام الترميز بالهاردوير يلغي الحاجة الى معظم موارد المعالج, لكن قد يحتاج الى معدل بث أعلى للحفاظ على نفس مستوى الجودة." Basic.AutoConfig.StreamPage.StreamWarning.Title="تحذير يتعلق بالبث" +Basic.AutoConfig.StreamPage.StreamWarning.Text="اختبار مستوى التدفق على وشك بدأ عرض مباشر لبيانات من فيديو عشوائي بدون صوت للقناة الخاصة بك. إذا أمكنك، يوصى بإيقاف حفظ فيديو للعرض المباشر مؤقتا وتعيين خصوصية العرض المباشر ل خاص إلى أن بكتمل الاختبار. هل تريد المتابعة؟" Basic.AutoConfig.TestPage="النتيجة النهائية" Basic.AutoConfig.TestPage.SubTitle.Testing="يقوم البرنامج الآن بتنفيذ مجموعة من الإختبارات لتقدير الإعدادات الأكثر مثالية" Basic.AutoConfig.TestPage.SubTitle.Complete="انتهى الاختبار" Basic.AutoConfig.TestPage.TestingBandwidth="إجراء اختبار النطاق الترددي، قد يستغرق هذا بضع دقائق..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="الاتصال ب1:%..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="فشل الاتصال بأي سيرفر، رجاءا تحقق من اتصالك بالانترنت وأعد المحاولة." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="اختبار التدفق لـ: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="جاري فحص برمجية ترميز البث، قد تستغرق هذه العملية دقيقة..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="جاري فحص برمجية ترميز تسجيل الفيديو، قد تستغرق هذه العملية دقيقة..." +Basic.AutoConfig.TestPage.TestingRes="اختبار الدِّقة (الأَبعاد)، قد يستغرق هذا بضع دقائق..." +Basic.AutoConfig.TestPage.TestingRes.Fail="فشل بدء برمجية الترميز" +Basic.AutoConfig.TestPage.TestingRes.Resolution="جاري فحص دقة %1x%2 ب%3 اطار/ث..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="نوعية ترميز البث" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="ترميز تسجيل الفيديو" +Basic.AutoConfig.TestPage.Result.Header="قام البرنامج بتقدير ان هذه هي الإعدادات المثالية لك:" +Basic.AutoConfig.TestPage.Result.Footer="لاستخدام هذه الإعدادات اضغط على \"تطبيق الإعدادات\". لإعادة القيام بالإعدادات و المحاولة مرة أخرى، اضغط للخلف. للقيام بعمل الإعدادات يدوياً بنفسك، اضغط إلغاء و افتح الإعدادات." Basic.Stats="إحصائيات" Basic.Stats.CPUUsage="استخدام المعالج" -Basic.Stats.HDDSpaceAvailable="مساحة القرص الصلب المتوفرة" +Basic.Stats.HDDSpaceAvailable="مساحة القرص المتوفرة" Basic.Stats.MemoryUsage="استخدام الذاكرة" Basic.Stats.AverageTimeToRender="معدل الوقت لإنشاء الإطار الواحد" Basic.Stats.SkippedFrames="إطارات تم تخطيها بسبب تأخر الترميز" @@ -145,9 +186,24 @@ Basic.Stats.Status.Reconnecting="جاري إعادة الاتصال" Basic.Stats.Status.Inactive="غير نشط" Basic.Stats.DroppedFrames="الاطارات المفقودة (بسبب الشبكة)" Basic.Stats.MegabytesSent="إجمالي البيانات الصادرة" +Basic.Stats.Bitrate="معدل النقل" +Basic.Stats.DiskFullIn="سيمتلىء القرص خلال (تقريباً)" +ResetUIWarning.Title="هل أنت متأكد أنك تريد إعادة تعيين واجهة المستخدم ؟" +ResetUIWarning.Text="إعادة تعيين واجهة المستخدم سيخفي المربعات الاضافية. سيتوجب عليك إظهارها من قائمة \"عرض\" اذا اردت ذلك.\n\nهل أنت متأكد انك تريد إعادة تعيين واجهة المستخدم ؟" + +Updater.Title="تحديث جديد متوفر" +Updater.Text="هناك إصدار جديد متوفر:" +Updater.UpdateNow="حدث الآن" +Updater.RemindMeLater="ذكرني لاحقاً" +Updater.Skip="تخطي الإصدار" +Updater.Running.Title="البرنامج نشط حالياً" +Updater.Running.Text="المخارج نشطة حالياً، الرجاء اغلاق اي مخرج نشط قبل محاولة التحديث" +Updater.NoUpdatesAvailable.Title="لا توجد تحديثات متوفرة" Updater.NoUpdatesAvailable.Text="لا توجد تحديثات متوفرة حاليا" Updater.FailedToLaunch="فشل في تشغيل التحديث" +Updater.GameCaptureActive.Title="إلتقاط الألعاب نشط" +Updater.GameCaptureActive.Text="مكتبة شبك التقاط الألعاب مشغولة حالياً. الرجاء اغلاء اي لعبة/برنامج يتم إلتقاطه (تصويره) حالياً (أو قم بإعادة تشغيل ويندوز) و حاول مرة أخرى." QuickTransitions.SwapScenes="التبديل بين مشهدي المعاينة و الاخراج بعد عملية الانتقال" QuickTransitions.SwapScenesTT="يقوم بتبديل مشهد المعاينة مع مشهد الاخراج بعد عملية الانتقال بين المشاهد (اذا كان مشهد الاخراج الاصلي لازال موجوداً) \n هذا لن يقوم بالتراجع عن اي تغييرات قمت بها على مشهد الاخراج الأصلي." @@ -158,6 +214,7 @@ QuickTransitions.EditPropertiesTT="عند تحرير المشهد نفسه، ي QuickTransitions.HotkeyName="الانتقال السريع: %1" Basic.AddTransition="إضافة المراحل الانتقالية للتكوين" +Basic.RemoveTransition="إزالة التأثير القابل للتكوين" Basic.TransitionProperties="خصائص تأثير الإنتقال" Basic.SceneTransitions="تأثير انتقال المشهد" Basic.TransitionDuration="مدة الانتقال" @@ -181,54 +238,62 @@ ConfirmStart.Text="هل انت متأكد انك تريد بدء البث ؟" ConfirmStop.Title="ايقاف البث؟" ConfirmStop.Text="هل أنت متأكد انك تريد ايقاف البث؟" +ConfirmBWTest.Title="بدء فحص سرعة التدفق؟" +ConfirmBWTest.Text="OBS لديك معد في وضع فحص تدفق السرعة. هذا الوضع يسمح لك بفحص الشبكة بدون ان تظهر في بث مباشر على قناتك. بمجرد انتهاء الفحص يجب عليك تعطيله لكي يستطيع مشاهدوك من رؤية البث.\n\nهل تريد الاستمرار ؟" + ConfirmExit.Title="الخروج من OBS ؟" ConfirmExit.Text="OBS حالياً نشط، كافة عمليات البث/التسجيلات سيتم إيقافها، هل أنت متأكد من رغبتك في الخروج ؟" ConfirmRemove.Title="تأكيد الإزالة" ConfirmRemove.Text="هل أنت متأكد من رغبتك في إزالة '$1' ?" +ConfirmRemove.TextMultiple="هل أنت متاكد انك تريد حذف هذه ال%1 عناصر؟" Output.StartStreamFailed="فشل في بدء البث" Output.StartRecordingFailed="فشل في بدء التسجيل" +Output.StartReplayFailed="فشل بدء التخزين المؤقت للإعادة" +Output.StartFailedGeneric="فشل بدء الإخراج. الرجاء مراجعة السجل للتفاصيل.\n\nملاحظة: اذا كنت تستخدم مُرَمِز NVENC أو مُرَمِز AMD, تأكد من أن تعريف بطاقة الشاشة لديك محدَّث." + Output.ConnectFail.Title="فشل في الاتصال" Output.ConnectFail.BadPath="مسار أو رابط الاتصال غير صالح. الرجاء التحقق من الإعدادات للتحقق من كونه صالح." Output.ConnectFail.ConnectFailed="فشل الاتصال بالسيرفر" Output.ConnectFail.InvalidStream="تعذر الوصول إلى القناة أو مفتاح البث المحدد، الرجاء أعد التحقق من صحة مفتاح البث الخاص بك، أما إذا كان صحيحاً، قد تكون المشكلة في الاتصال بالخادم." -Output.ConnectFail.Error="حدث خطأ غير متوقع عند محاولة الاتصال بالخادم. مزيد من المعلومات في ملف السجل." +Output.ConnectFail.Error="حدث خطأ غير متوقع عند محاولة الاتصال بالخادم. مزيد من المعلومات في ملف السجل." Output.ConnectFail.Disconnected="تم قطع الاتصال من السيرفر." +Output.StreamEncodeError.Title="خطأ في الترميز" +Output.StreamEncodeError.Msg="حدث خطأ في الترميز أثناء البث." + Output.RecordFail.Title="فشل في بدء التسجيل" -Output.RecordFail.Unsupported="تنسيق الإخراج أما غير معتمد أو لا يدعم أكثر من مسار للصوت. الرجاء التحقق من الإعدادات الخاصة بك وحاول مرة أخرى." +Output.RecordFail.Unsupported="تنسيق الإخراج أما غير معتمد أو لا يدعم أكثر من مسار للصوت. الرجاء التحقق من الإعدادات الخاصة بك وحاول مرة أخرى." +Output.RecordNoSpace.Title="مساحة القرص غير كافية" Output.RecordNoSpace.Msg="لا توجد مساحة كافية على القرص لمتابعة التسجيل." Output.RecordError.Title="خطأ في التسجيل" Output.RecordError.Msg="حدث خطأ غير محدد أثناء التسجيل." +Output.RecordError.EncodeErrorMsg="حدث خطأ في الترميز أثناء التسجيل." +Output.ReplayBuffer.NoHotkey.Title="لم يتم تعيين مفتاح اختصار!" +Output.ReplayBuffer.NoHotkey.Msg="لم يتم تعيين مفتاح اختصار لحفظ التخزين المؤقَت للإعادة. الرجاء قم بتعيين مفتاح \"حفظ\" لاستخدامها في حفظ تسجيلات الإعادات." Output.BadPath.Title="مسار الملف غير صحيح" -Output.BadPath.Text="مسار الإخراج ملف تكوين غير صالح. الرجاء التحقق من الإعدادات الخاصة بك للتأكد من أنه تم تعيين مسار ملف صحيح." +Output.BadPath.Text="مسار الإخراج ملف تكوين غير صالح. الرجاء التحقق من الإعدادات الخاصة بك للتأكد من أنه تم تعيين مسار ملف صحيح." LogReturnDialog="تم رفع السجل بنجاح" LogReturnDialog.CopyURL="نسخ الرابط" LogReturnDialog.ErrorUploadingLog="خطأ في رفع ملف السجل" -LicenseAgreement="اتفاقية الترخيص" -LicenseAgreement.PleaseReview="الرجاء مراجعة شروط الترخيص قبل استخدام OBS، أنك تقر بأنك قد قرأت وتوافق على شروط رخصة جنو العمومية v2.0. رجاء التمرير لأسفل لرؤية بقية الاتفاق." -LicenseAgreement.ClickIAgreeToContinue="إذا قمت بقبول شروط الاتفاق، انقر فوق أوافق الاستمرار. يجب قبول الاتفاق لاستخدام OBS." -LicenseAgreement.IAgree="موافق" -LicenseAgreement.Exit="خروج" - Remux.SourceFile="تسجيل OBS" Remux.TargetFile="الملف الهدف" Remux.Remux="تحويل الصيغة" +Remux.ClearFinished="مسح العناصر المنتهية" +Remux.ClearAll="مسح كل العناصر" Remux.OBSRecording="تسجيل OBS" Remux.FinishedTitle="انتهت عملية تحويل الصيغة" Remux.Finished="تسجيل عملية تحويل الصيغة" Remux.FinishedError="عملية التحويل قد تكون غير مكتملة" -Remux.SelectRecording="إختر تسجيل OBS …" -Remux.SelectTarget="إختر الملف الهدف …" Remux.FileExistsTitle="الملف الهدف موجود" -Remux.FileExists="الملف الهدف موجود، هل تريد استبداله؟" +Remux.FileExists="الملفات التالية موجودة فعليا. هل ترغب في استبدالها؟" Remux.ExitUnfinishedTitle="تقدم عملية التحويل" -Remux.ExitUnfinished="إيقاف عميلة التحويل الآن قد تجعل الملف غير قابل للاستخدام./n هل أنت متأكد أنك تريد إيقاف عملية التحويل؟" +Remux.ExitUnfinished="إيقاف عميلة التحويل الآن قد تجعل الملف غير قابل للاستخدام./n هل أنت متأكد أنك تريد إيقاف عملية التحويل؟" UpdateAvailable="تحديث جديد متوفر" UpdateAvailable.Text="الإصدار %1.%2.%3 متوفر الآن. انقر هنا للتتحميل" @@ -245,12 +310,23 @@ Basic.DisplayCapture="التقاط الشاشة" Basic.Main.PreviewConextMenu.Enable="تمكين المعاينة" +Basic.Main.Preview.Disable="تعطيل المعاينه" + ScaleFiltering="مقياس التصفية" ScaleFiltering.Point="نقطة" +ScaleFiltering.Bilinear="ثنائي خطي" +ScaleFiltering.Bicubic="ثنائي تكعيبي" +ScaleFiltering.Lanczos="والغاوسي" +Deinterlacing="تصحيح تشابك الصورة" Deinterlacing.Discard="تجاهل" +Deinterlacing.Retro="ريترو" +Deinterlacing.Blend="مزج" +Deinterlacing.Blend2x="مزج مضاعف" Deinterlacing.Linear="خطي" Deinterlacing.Linear2x="X 2 الخطي" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="أعلى الحقل الأول" Deinterlacing.BottomFieldFirst="أسفل الحقل الأول" @@ -269,21 +345,40 @@ Basic.Main.AddSceneCollection.Text="الرجاء إدخال اسم لمجموع Basic.Main.RenameSceneCollection.Title="اعادة تسمية مجموعة مشاهد" +AddProfile.Title="إضافة ملف تعريف" +AddProfile.Text="الرجاء إدخال اسم الملف التعريفي" + +RenameProfile.Title="إعادة تسمية الملف التعريفي" + +Basic.Main.MixerRename.Title="إعادة تسمية المصدر الصوتي" +Basic.Main.MixerRename.Text="الرجاء إدخال اسم للمصدر الصوتي" - - +Basic.Main.PreviewDisabled="المعاينة تم تعطيلها" Basic.SourceSelect="إنشاء/تحديد المصدر" Basic.SourceSelect.CreateNew="انشاء جديد" Basic.SourceSelect.AddExisting="إضافة عنصر موجود" +Basic.SourceSelect.AddVisible="جعل المصدر ظاهراً" Basic.PropertiesWindow="خصائص ل '%1'" +Basic.PropertiesWindow.AutoSelectFormat="%1 (اختيار تلقائي: %2)" Basic.PropertiesWindow.SelectColor="تحديد اللون" Basic.PropertiesWindow.SelectFont="إختيار خط" +Basic.PropertiesWindow.ConfirmTitle="تم تغيير الإعدادات" +Basic.PropertiesWindow.Confirm="يوجد تعديلات غير محفوظة. هل تريد الإبقاء عليها؟" +Basic.PropertiesWindow.NoProperties="لا يوجد خصائص متوفرة" Basic.PropertiesWindow.AddFiles="إضافة ملفات" +Basic.PropertiesWindow.AddDir="إضافة مجلد" +Basic.PropertiesWindow.AddURL="إضافة مسار/رابط" +Basic.PropertiesWindow.AddEditableListDir="إضافة مجلد إلى '%1'" +Basic.PropertiesWindow.AddEditableListFiles="أضف ملفات إلى '%1'" +Basic.PropertiesWindow.AddEditableListEntry="أضف إدخال إلى '%1'" +Basic.PropertiesWindow.EditEditableListEntry="تعديل إدخال من '%1'" +Basic.PropertiesView.FPS.Simple="صيغ مبسطة لعدد الإطارات/ث" +Basic.InteractionWindow="التفاعل مع '%1'" Basic.StatusBar.ReconnectSuccessful="إعادة الاتصال الناجح" @@ -323,7 +418,7 @@ Basic.TransformWindow.BoundsType.ScaleToWidth="مقياس لعرض الحدود" Basic.TransformWindow.BoundsType.ScaleToHeight="مقياس للارتفاع الحدود" Basic.TransformWindow.BoundsType.Stretch="تمتد إلى الحدود" -Basic.Main.AddSourceHelp.Title="لا يمكن إضافة المصدر" +Basic.Main.AddSourceHelp.Title="لا يمكن إضافة المصدر" Basic.Main.AddSourceHelp.Text="تحتاج إلى أن يكون على الأقل مشهد واحد لإضافة مصدر." Basic.Main.Scenes="المشاهد" @@ -334,51 +429,61 @@ Basic.Main.StartStreaming="بدء البث" Basic.Main.StopRecording="إيقاف التسجيل" Basic.Main.StopStreaming="ايقاف البث" -Basic.MainMenu.File="&ملف" -Basic.MainMenu.File.Export="&تصدير" -Basic.MainMenu.File.Import="&استيراد" -Basic.MainMenu.File.ShowRecordings="إظهار &التسجيلات" -Basic.MainMenu.File.Settings="&الإعدادات" +Basic.MainMenu.File="ملف (&F)" +Basic.MainMenu.File.Export="تصدير (6) (&E)" +Basic.MainMenu.File.Import="استيراد (&I)" +Basic.MainMenu.File.ShowRecordings="إظهار التسجيلات (&R)" +Basic.MainMenu.File.Settings="الإعدادات (&S)" Basic.MainMenu.File.ShowSettingsFolder="إظهار مجلد الإعدادات" Basic.MainMenu.File.ShowProfileFolder="إظهار مجلد الملف الشخصي" -Basic.MainMenu.AlwaysOnTop="&دائماً في القمة" -Basic.MainMenu.File.Exit="&خروج" +Basic.MainMenu.AlwaysOnTop="دائماً في القمة (&A)" +Basic.MainMenu.File.Exit="خروج (&X)" -Basic.MainMenu.Edit="&تعديل" -Basic.MainMenu.Edit.Undo="&تراجع" -Basic.MainMenu.Edit.Redo="&إعادة" -Basic.MainMenu.Edit.UndoAction="&تراجع $1" -Basic.MainMenu.Edit.RedoAction="&إعادة $1" -Basic.MainMenu.Edit.Transform="&تحويل" -Basic.MainMenu.Edit.Transform.EditTransform="&تحرير التحويل..." -Basic.MainMenu.Edit.Transform.ResetTransform="&إعادة التحويل" +Basic.MainMenu.Edit="تعديل (&E)" +Basic.MainMenu.Edit.Undo="تراجع (&U)" +Basic.MainMenu.Edit.Redo="إعادة (&R)" +Basic.MainMenu.Edit.UndoAction="تراجع $1 (&U)" +Basic.MainMenu.Edit.RedoAction="إعادة $1 (&R)" +Basic.MainMenu.Edit.Transform="تحويل (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="تحرير التحويل... (&E)" +Basic.MainMenu.Edit.Transform.ResetTransform="إعادة التحويل (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="تدوير 90 درجة CW" Basic.MainMenu.Edit.Transform.Rotate90CCW="تدوير 90 درجة CCW" Basic.MainMenu.Edit.Transform.Rotate180="تدوير 180 درجة" -Basic.MainMenu.Edit.Transform.FlipHorizontal="انعكاس &أفقي" -Basic.MainMenu.Edit.Transform.FlipVertical="انعكاس &عمودي" -Basic.MainMenu.Edit.Transform.FitToScreen="&تمديد الشاشة" -Basic.MainMenu.Edit.Transform.StretchToScreen="&تمتد إلى الشاشة" -Basic.MainMenu.Edit.Transform.CenterToScreen="&وسط الشاشة" -Basic.MainMenu.Edit.Order="&الترتيب" -Basic.MainMenu.Edit.Order.MoveUp="التحرك &للأعلى" -Basic.MainMenu.Edit.Order.MoveDown="التحرك &للأسفل" -Basic.MainMenu.Edit.Order.MoveToTop="التحرك &للقمة" -Basic.MainMenu.Edit.Order.MoveToBottom="التحرك &للقاع" -Basic.MainMenu.Edit.AdvAudio="&خصائص الصوت المتقدمة" +Basic.MainMenu.Edit.Transform.FlipHorizontal="انعكاس أفقي (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="انعكاس عمودي (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="تمديد الشاشة (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="تمتد إلى الشاشة (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="وسط الشاشة (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="توسيط عامودي" +Basic.MainMenu.Edit.Transform.HorizontalCenter="توسيط أفقي" +Basic.MainMenu.Edit.Order="الترتيب (&O)" +Basic.MainMenu.Edit.Order.MoveUp="التحرك للأعلى (&U)" +Basic.MainMenu.Edit.Order.MoveDown="التحرك للأسفل (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="التحرك للقمة (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="التحرك للقاع (&B)" +Basic.MainMenu.Edit.AdvAudio="خصائص الصوت المتقدمة (&A)" -Basic.MainMenu.View="عرض" -Basic.MainMenu.View.Toolbars="شريط الأدوات" +Basic.MainMenu.View="عرض (&V)" +Basic.MainMenu.View.Toolbars="شريط الأدوات (&T)" +Basic.MainMenu.View.Docks="أرصفة" +Basic.MainMenu.View.Docks.ResetUI="إعادة ضبط الواجهة" +Basic.MainMenu.View.Docks.LockUI="قفل تعديل الواجهة" +Basic.MainMenu.View.StatusBar="شريط الحالة (&S)" +Basic.MainMenu.View.Fullscreen.Interface="ملء الشاشة" -Basic.MainMenu.SceneCollection="&مجموعة المشاهد" -Basic.MainMenu.Profile="&الملف الشخصي" +Basic.MainMenu.SceneCollection="مجموعة المشاهد (&S)" +Basic.MainMenu.Profile="الملف الشخصي (&P)" +Basic.MainMenu.Profile.Import="استيراد ملف تعريف" +Basic.MainMenu.Profile.Export="تصدير ملف التعريف" +Basic.MainMenu.Tools="أدوات (&T)" -Basic.MainMenu.Help="&مساعدة" -Basic.MainMenu.Help.Website="زيارة &الموقع الإلكتروني" -Basic.MainMenu.Help.Logs="&ملفات السجل" -Basic.MainMenu.Help.Logs.UploadCurrentLog="رفع &ملف السجل الحالي" -Basic.MainMenu.Help.Logs.UploadLastLog="رفع &آخر ملف سجل" +Basic.MainMenu.Help="مساعدة (&H)" +Basic.MainMenu.Help.Website="زيارة الموقع الإلكتروني (&W)" +Basic.MainMenu.Help.Logs="ملفات السجل (&L)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="رفع ملف السجل الحالي (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="رفع آخر ملف سجل (&L)" Basic.MainMenu.Help.CheckForUpdates="التحقق من وجود تحديثات" Basic.Settings.ProgramRestart="يجب إعادة تشغيل البرنامج حتى تصبح الإعدادات نافذة المفعول." @@ -433,17 +538,17 @@ Basic.Settings.Output.Adv.FFmpeg.FormatVideo="فيديو" Basic.Settings.Video="الفيديو" -Basic.Settings.Video.Adapter="محول الفيديو:" -Basic.Settings.Video.DownscaleFilter="فلتر Downscale:" +Basic.Settings.Video.Adapter="محول الفيديو" +Basic.Settings.Video.DownscaleFilter="فلتر Downscale" Basic.Settings.Video.DisableAeroWindows="تعطيل Aero (فقط للويندوز)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="القيم المشتركة للـFPS" Basic.Settings.Video.FPSInteger="قيمة FPS صحيحة" Basic.Settings.Video.FPSFraction="قيمة FPS كسرى" -Basic.Settings.Video.Numerator="البسط:" -Basic.Settings.Video.Denominator="قاسم:" -Basic.Settings.Video.Renderer="العارض:" -Basic.Settings.Video.InvalidResolution="قيمة الأبعاد غير صالحة. يجب أن يكون [العرض] x [الطول] (مثال. 1920 × 1080)" +Basic.Settings.Video.Numerator="البسط" +Basic.Settings.Video.Denominator="قاسم" +Basic.Settings.Video.Renderer="العارض" +Basic.Settings.Video.InvalidResolution="قيمة الأبعاد غير صالحة. يجب أن يكون [العرض] x [الطول] (مثال. 1920 × 1080)" Basic.Settings.Video.CurrentlyActive="إخراج الفيديو نشط حاليا. الرجاء إيقاف كل الإخراجات لتغيير إعدادات الفيديو." Basic.Settings.Video.DisableAero="تعطيل Aero" @@ -451,11 +556,9 @@ Basic.Settings.Video.DisableAero="تعطيل Aero" Basic.Settings.Audio="الصوت" Basic.Settings.Audio.SampleRate="معدل العينات" Basic.Settings.Audio.Channels="قنوات" -Basic.Settings.Audio.DesktopDevice="جهاز صوت سطح المكتب" -Basic.Settings.Audio.DesktopDevice2="جهاز صوت سطح المكتب 2" -Basic.Settings.Audio.AuxDevice="جهاز صوت Mic/Auxiliary" -Basic.Settings.Audio.AuxDevice2="جهاز صوت Mic/Auxiliary 2" -Basic.Settings.Audio.AuxDevice3="جهاز صوت Mic/Auxiliary 3" +Basic.Settings.Audio.Devices="الأجهزة" +Basic.Settings.Audio.DesktopDevice="صوت سطح المكتب" +Basic.Settings.Audio.DesktopDevice2="صوت سطح المكتب 2" Basic.Settings.Audio.UnknownAudioDevice="[الجهاز غير متصل أو غير متوفر]" Basic.Settings.Advanced="متقدم" @@ -465,7 +568,6 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="أعلى من ال Basic.Settings.Advanced.General.ProcessPriority.Normal="عادي" Basic.Settings.Advanced.General.ProcessPriority.Idle="خامل" Basic.Settings.Advanced.Video.ColorFormat="تنسيق اللون" -Basic.Settings.Advanced.Video.ColorSpace="مساحة ألوان YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="جزئي" Basic.Settings.Advanced.Video.ColorRange.Full="كامل" @@ -479,6 +581,10 @@ Basic.Settings.Advanced.Video.ColorRange.Full="كامل" +NoSources.Label="لا يوجد لديك اي مصادر.\nاضغط على اشارة الـ+ في الأسفل,\nأو انقر هنا بالزر الأيمن للفأرة لإضافة واحد." + + + diff --git a/UI/data/locale/bg-BG.ini b/UI/data/locale/bg-BG.ini index 183e2d4..317e1fa 100644 --- a/UI/data/locale/bg-BG.ini +++ b/UI/data/locale/bg-BG.ini @@ -27,7 +27,7 @@ Mixer="Миксер" Browse="Преглед" Mono="Моно" Stereo="Стерео" -DroppedFrames="Изпуснати кадри %1 (%2%)" +DroppedFrames="Изпуснати кадри %1 (%2%)" StudioProgramProjector="Прожектиране на цял екран (от Програмата)" PreviewProjector="Прожектиране на цял екран (Предварителен преглед)" SceneProjector="Прожектиране на цял екран (Сцена)" @@ -78,26 +78,30 @@ None="Без" StudioMode.Preview="Преглед" StudioMode.Program="Програмен Изглед" ShowInMultiview="Покажи във Множествен изглед" +VerticalLayout="Вертикално разположение" +Group="Група" AlreadyRunning.Title="OBS вече се изпълнява" AlreadyRunning.Text="OBS вече е включен! Освен ако не е по желание, моля изключете другите работещи инстанции на OBS преди да включите нова. Ако сте настроили OBS да се минимизира във системната табла, моля проверете дали все още е включен там." AlreadyRunning.LaunchAnyway="Включи въпреки това" + +Auth.Chat="Чат" + Copy.Filters="Копирай Филтъри" Paste.Filters="Постави Филтъри" + BandwidthTest.Region="Регион" BandwidthTest.Region.US="САЩ" BandwidthTest.Region.EU="Европа" BandwidthTest.Region.Asia="Азия" BandwidthTest.Region.Other="Друг" -Basic.FirstStartup.RunWizard="Искате ли да изпълните съветника за автоматично конфигуриране? Можете също ръчно да конфигурирате настройките, като щракнете върху бутона настройки в главния прозорец." -Basic.FirstStartup.RunWizard.BetaWarning="(Забележка: съветника за автоматично конфигуриране в момента е в бета версия)" +Basic.FirstStartup.RunWizard="Искате ли да изпълните съветника за автоматично конфигуриране? Можете също ръчно да конфигурирате настройките, като щракнете върху бутона настройки в главния прозорец." Basic.FirstStartup.RunWizard.NoClicked="Ако промените решението си, можете да стартирате съветника за автоматично конфигуриране отново от меню \"Инструменти\"." Basic.AutoConfig="Съветник за автоматично конфигуриране" -Basic.AutoConfig.Beta="Съветник за автоматично конфигуриране (Бета версия)" Basic.AutoConfig.ApplySettings="Приложи настройките" Basic.AutoConfig.StartPage="Информация за използване" Basic.AutoConfig.StartPage.SubTitle="Посочете за какво искате да използвате програмата" @@ -142,7 +146,6 @@ Basic.AutoConfig.TestPage.Result.Footer="За да ползвате тези н Basic.Stats="Статистика" Basic.Stats.CPUUsage="Използване на централния процесор" -Basic.Stats.HDDSpaceAvailable="Свободно пространство на диска" Basic.Stats.MemoryUsage="Използване на паметта" Basic.Stats.AverageTimeToRender="Средно време за рендиране на кадър" Basic.Stats.SkippedFrames="Изпуснати кадри заради забавяне във кодирането" @@ -158,6 +161,7 @@ Basic.Stats.DroppedFrames="Изпуснати Кадри (Мрежа)" Basic.Stats.MegabytesSent="Общо количество изпратени данни" Basic.Stats.Bitrate="Битрейт" + Updater.Title="Има нова актуализация" Updater.Text="Нова версия на приложението е налична:" Updater.UpdateNow="Обнови сега" @@ -169,7 +173,6 @@ Updater.NoUpdatesAvailable.Title="Няма обновявания" Updater.NoUpdatesAvailable.Text="Няма текущи обновявания на разположение" Updater.FailedToLaunch="Неуспешно стартиране на обновителя" Updater.GameCaptureActive.Title="Записването на Игра е активно" -Updater.GameCaptureActive.Text="Библиотеката със куки за Записване на Игра се ползва. Моля затворете игрите/програмите които се записват (или пуснете операционната система наново) и опитайте отново." QuickTransitions.SwapScenes="Смени сцените Преглед/Продукция след Преминаване" QuickTransitions.SwapScenesTT="Сменя сцените за Преглед и Продукция след преминаването (ако все още съществува оригиналната сцена).\n Това няма да отмени промените, които може да са направени в оригиналната сцена на изхода." @@ -204,6 +207,7 @@ ConfirmStart.Text="Сигурни ли сте че искате да започ ConfirmStop.Title="Спри излъчването?" ConfirmStop.Text="Сигурни ли сте че искате да спрете предаването?" + ConfirmExit.Title="Изход от OBS?" ConfirmExit.Text="OBS във момента е активен. Всички предавания/записи ще бъдат изключени. Сигурни ли сте че искате да излезнете от програмата?" @@ -216,13 +220,15 @@ Output.StartRecordingFailed="Неуспешно стартиране на зап Output.StartReplayFailed="Неуспешно включване на Буферa за повторение" Output.StartFailedGeneric="Започването на изкарване на кадри неуспешно. Моля проверете списъка за подробности. \n\n Бележка: Ако ползвате кодиране NVENC или AMD, моля проверете дали версията на драйвъри за видео картата е актуална." + Output.ConnectFail.Title="Неуспешно свързване" Output.ConnectFail.BadPath="Невалиден път или URL. Проверете дали настройките ви са валидни." Output.ConnectFail.ConnectFailed="Неуспешна връзка със сървъра" Output.ConnectFail.InvalidStream="Неуспешно сързване към посоченият канал или ключ за предаване, моля проверете повторно вашия ключ. Ако е верен, може би има проблем със всъзката към сървъра." -Output.ConnectFail.Error="Неочаквана грешка при опит за връзка със сървъра. Повече информация в \"log\" файла." +Output.ConnectFail.Error="Неочаквана грешка при опит за връзка със сървъра. Повече информация в \"log\" файла." Output.ConnectFail.Disconnected="Изключен от сървъра." + Output.RecordFail.Title="Неуспешно стартиране на запис" Output.RecordFail.Unsupported="Формата на записа или не е подържа или не подържа повече от една писта за звук. Моля проверете настройките си и опитайте отново." Output.RecordNoSpace.Title="Недостатъчно място на диска" @@ -239,28 +245,23 @@ LogReturnDialog="\"Log\" файл качен успешно" LogReturnDialog.CopyURL="Копирай URL адреса" LogReturnDialog.ErrorUploadingLog="Грешка при качването на \"log\" файла" -LicenseAgreement="Лицензионно споразумение" -LicenseAgreement.PleaseReview="Моля прегледайте лицензионните условия, преди да използвате OBS. С използването на тази програма, вие потвърждавате, че сте прочели и сте съгласни с условията на този лиценз: GNU General Public License v2.0. Моля, погледнете отдолу, за да видите останалата част от Споразумението." -LicenseAgreement.ClickIAgreeToContinue="Ако приемете условията на споразумението, натиснете \"Приемам\", за да продължите. Трябва да приемете споразумението да използвате OBS." -LicenseAgreement.IAgree="Приемам" -LicenseAgreement.Exit="Изход" - Remux.SourceFile="OBS запис" Remux.TargetFile="Целеви файл" Remux.Remux="Конвертиране" +Remux.ClearFinished="Изчисти готовите елементи" +Remux.ClearAll="Изчисти всички елементи" Remux.OBSRecording="OBS запис" Remux.FinishedTitle="Конвертирането завърши" Remux.Finished="Записът е конвертиран" Remux.FinishedError="Записът е конвертиран, но файлът може да бъде незавършен" -Remux.SelectRecording="Изберете OBS запис …" -Remux.SelectTarget="Изберете целевия файл …" -Remux.FileExistsTitle="Файлът съществува" -Remux.FileExists="Файлът съществува, искате ли да го замените?" +Remux.FileExistsTitle="Целевите файлове съществуват" +Remux.FileExists="Следните целеви файлове вече съществуват. Желаете ли да ги замените?" Remux.ExitUnfinishedTitle="Конвертиране в ход" Remux.ExitUnfinished="Конвертирането не е завършено все още, ако го спрете сега файлът може да бъде неизползваем.\nСигурни ли сте, че искате да спрете конвертирането?" +Remux.HelpText="Пуснете файловете чрез влачене в този прозорец, за да ги преобразувате или изберете празна \"OBS Recording\" клетка, за да отворите прозореца за търсене на файл." UpdateAvailable="Има нова актуализация" -UpdateAvailable.Text="Версия %1.%2.%3 е налична. Щракнете тук, за да изтеглите" +UpdateAvailable.Text="Версия %1.%2.%3 е налична. Щракнете тук, за да изтеглите" Basic.DesktopDevice1="Аудио - работен плот" Basic.DesktopDevice2="Аудио - работен плот 2" @@ -274,6 +275,7 @@ Basic.DisplayCapture="Заснемане на екрана" Basic.Main.PreviewConextMenu.Enable="Разреши преглед" + ScaleFiltering="Мащабно Филтриране" ScaleFiltering.Point="Точково" ScaleFiltering.Bilinear="Двулинейно" @@ -328,7 +330,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (автоматично: %2)" Basic.PropertiesWindow.SelectColor="Избор на цвят" Basic.PropertiesWindow.SelectFont="Избор на шрифт" Basic.PropertiesWindow.ConfirmTitle="Настройките са променени" -Basic.PropertiesWindow.Confirm="Има незаписани промени. Искате ли да ги запишете?" +Basic.PropertiesWindow.Confirm="Има незаписани промени. Искате ли да ги запишете?" Basic.PropertiesWindow.NoProperties="Без налични характеристики" Basic.PropertiesWindow.AddFiles="Добавяне на файлове" Basic.PropertiesWindow.AddDir="Добави директория" @@ -405,60 +407,63 @@ Basic.Main.StoppingReplayBuffer="Спиране на Буферa за Повто Basic.Main.StopStreaming="Спри стрийм" Basic.Main.StoppingStreaming="Спиране на излъчването..." Basic.Main.ForceStopStreaming="Спри излъчването (без забавяне)" +Basic.Main.Group="Група %1" +Basic.Main.GroupItems="Групиране на избраните елементи" +Basic.Main.Ungroup="Разгрупирай" -Basic.MainMenu.File="&Файл" -Basic.MainMenu.File.Export="&Експортиране" -Basic.MainMenu.File.Import="&Импортиране" -Basic.MainMenu.File.ShowRecordings="Покажи Записите" -Basic.MainMenu.File.Remux="Прекодиране на Записите" -Basic.MainMenu.File.Settings="&Настройки" +Basic.MainMenu.File="Файл (&F)" +Basic.MainMenu.File.Export="Експортиране (&E)" +Basic.MainMenu.File.Import="Импортиране (&I)" +Basic.MainMenu.File.ShowRecordings="Покажи Записите (&R)" +Basic.MainMenu.File.Remux="Прекодиране на Записите (&M)" +Basic.MainMenu.File.Settings="Настройки (&S)" Basic.MainMenu.File.ShowSettingsFolder="Покажи папката с Настройки" Basic.MainMenu.File.ShowProfileFolder="Покажи папката със Профили" -Basic.MainMenu.AlwaysOnTop="Винаги видим" -Basic.MainMenu.File.Exit="&Изход" +Basic.MainMenu.AlwaysOnTop="Винаги видим (&A)" +Basic.MainMenu.File.Exit="Изход (&X)" -Basic.MainMenu.Edit="&Редактирай" -Basic.MainMenu.Edit.Undo="&Отмени" -Basic.MainMenu.Edit.Redo="&Върни" -Basic.MainMenu.Edit.UndoAction="&Отмени $1" -Basic.MainMenu.Edit.RedoAction="&Отмени $1" -Basic.MainMenu.Edit.LockPreview="Заключване на прегледа" -Basic.MainMenu.Edit.Scale="Усъразмеряване на прегледа" +Basic.MainMenu.Edit="Редактирай (&E)" +Basic.MainMenu.Edit.Undo="Отмени (&U)" +Basic.MainMenu.Edit.Redo="Върни (&R)" +Basic.MainMenu.Edit.UndoAction="Отмени $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Отмени $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Заключване на прегледа (&L)" +Basic.MainMenu.Edit.Scale="Усъразмеряване на прегледа (&S)" Basic.MainMenu.Edit.Scale.Window="Усъразмери по Прозорец" Basic.MainMenu.Edit.Scale.Canvas="Платно (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Запис (%1x%2)" -Basic.MainMenu.Edit.Transform="&Трансформирай" -Basic.MainMenu.Edit.Transform.EditTransform="&Редактирай трансформация..." +Basic.MainMenu.Edit.Transform="Трансформирай (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Редактирай трансформация... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Копиране на местоположението" Basic.MainMenu.Edit.Transform.PasteTransform="Поставяне на местоположението" -Basic.MainMenu.Edit.Transform.ResetTransform="&Анулирай трансформация" +Basic.MainMenu.Edit.Transform.ResetTransform="Анулирай трансформация (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Завърти 90 градуса по часовниковата" Basic.MainMenu.Edit.Transform.Rotate90CCW="Завърти 90 градуса обратно на часовниковата" Basic.MainMenu.Edit.Transform.Rotate180="Завърти 180 градуса" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Обърни &Хоризонтално" -Basic.MainMenu.Edit.Transform.FlipVertical="Обърни &Вертикално" -Basic.MainMenu.Edit.Transform.FitToScreen="&Сходно с екрана" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Разтегни до екрана" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Центрирай сходно екрана" -Basic.MainMenu.Edit.Order="&Ред" -Basic.MainMenu.Edit.Order.MoveUp="Премести &нагоре" -Basic.MainMenu.Edit.Order.MoveDown="Премести &надолу" -Basic.MainMenu.Edit.Order.MoveToTop="Премести &най-отгоре" -Basic.MainMenu.Edit.Order.MoveToBottom="Премести най-о&тдолу" -Basic.MainMenu.Edit.AdvAudio="Допълнителни Звукови Характеристики" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Обърни Хоризонтално (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Обърни Вертикално (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Сходно с екрана (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Разтегни до екрана (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Центрирай сходно екрана (&C)" +Basic.MainMenu.Edit.Order="Ред (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Премести нагоре (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Премести надолу (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Премести най-отгоре (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Премести най-отдолу (&B)" +Basic.MainMenu.Edit.AdvAudio="Допълнителни Звукови Характеристики (&A)" -Basic.MainMenu.View="Изглед" -Basic.MainMenu.View.Toolbars="Лента Инструменти" +Basic.MainMenu.View="Изглед (&V)" +Basic.MainMenu.View.Toolbars="Лента Инструменти (&T)" Basic.MainMenu.View.Docks="Докове" Basic.MainMenu.View.Docks.ResetUI="Върни UI" Basic.MainMenu.View.Docks.LockUI="Заключи UI" -Basic.MainMenu.View.Toolbars.Listboxes="Често ползвани" -Basic.MainMenu.View.SceneTransitions="Преминавания между сцени" -Basic.MainMenu.View.StatusBar="Статус лента" +Basic.MainMenu.View.Toolbars.Listboxes="Често ползвани (&L)" +Basic.MainMenu.View.SceneTransitions="Преминавания между сцени (&C)" +Basic.MainMenu.View.StatusBar="Статус лента (&S)" Basic.MainMenu.View.Fullscreen.Interface="Изглед на цял екран" -Basic.MainMenu.SceneCollection="Колекция Сцени" -Basic.MainMenu.Profile="Профили" +Basic.MainMenu.SceneCollection="Колекция Сцени (&S)" +Basic.MainMenu.Profile="Профили (&P)" Basic.MainMenu.Profile.Import="Добави Профил" Basic.MainMenu.Profile.Export="Запис на Профил" Basic.MainMenu.SceneCollection.Import="Добавяне на Колекция от сцени" @@ -466,21 +471,26 @@ Basic.MainMenu.SceneCollection.Export="Запис на Колекция от с Basic.MainMenu.Profile.Exists="Профилът вече съществува" Basic.MainMenu.SceneCollection.Exists="Колекцията сцени вече съществува" -Basic.MainMenu.Tools="Инструменти" +Basic.MainMenu.Tools="Инструменти (&T)" -Basic.MainMenu.Help="&Помощ" -Basic.MainMenu.Help.HelpPortal="Портал за Помощ" -Basic.MainMenu.Help.Website="Посети Уебсайта" -Basic.MainMenu.Help.Logs="\"Log\" &файлове" -Basic.MainMenu.Help.Logs.ShowLogs="Покажи техническите записи" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Качи &текущия \"Log\" файл" -Basic.MainMenu.Help.Logs.UploadLastLog="Качи &последния \"Log\" файл" -Basic.MainMenu.Help.Logs.ViewCurrentLog="Преглеждане на Текущи Данни" +Basic.MainMenu.Help="Помощ (&H)" +Basic.MainMenu.Help.HelpPortal="Портал за Помощ (&P)" +Basic.MainMenu.Help.Website="Посети Уебсайта (&W)" +Basic.MainMenu.Help.Discord="Страмоца в &Discord" +Basic.MainMenu.Help.Logs="\"&Log\" файлове" +Basic.MainMenu.Help.Logs.ShowLogs="Покажи техническите записи (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Качи текущия \"Log\" файл (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Качи последния \"&Log\" файл" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Преглеждане на Текущи Данни (&V)" Basic.MainMenu.Help.CheckForUpdates="Провери за обновления" +Basic.MainMenu.Help.CrashLogs="Сигнали за проблеми (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Покажи сигнали за проблеми (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Качи последния доклад при проваляне на програмата (&L)" +Basic.MainMenu.Help.About="За програмата (&A)" Basic.Settings.ProgramRestart="Програмата трябва да бъде рестартирана, за да влязат в сила тези настройки." Basic.Settings.ConfirmTitle="Потвърди промените" -Basic.Settings.Confirm="Имате незаписани промени. Запиши промените?" +Basic.Settings.Confirm="Имате незаписани промени. Запиши промените?" Basic.Settings.General="Основни" Basic.Settings.General.Theme="Теми" @@ -505,12 +515,24 @@ Basic.Settings.General.SysTray="Системен контейнер" Basic.Settings.General.SysTrayWhenStarted="Минимизирай във системния контейнер при включване" Basic.Settings.General.SystemTrayHideMinimize="Винаги минимизирай във системния контейнер вместо във лентата със програми" Basic.Settings.General.SaveProjectors="Запамети прожекторите при изход" +Basic.Settings.General.Preview="Преглед" Basic.Settings.General.SwitchOnDoubleClick="Преминаване към сцена при двойно кликване" Basic.Settings.General.StudioPortraitLayout="Включи портретен / вертикален изглед" +Basic.Settings.General.Multiview="Мулти-изглед" +Basic.Settings.General.Multiview.MouseSwitch="Натиснете за превключване между сцените" +Basic.Settings.General.Multiview.DrawSourceNames="Покажи имената на сцените" +Basic.Settings.General.Multiview.DrawSafeAreas="Показване на безопасни зони (EBU R 95)" Basic.Settings.General.MultiviewLayout="Разположение на Множествения Изглед" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Хоризонтал, Горе (8 сцени)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Хоризонтал, Долу (8 сцени)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Вертикал, Ляво (8 сцени)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Вертикал, Дясно (8 сцени)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Хоризонтал, Горе (24 сцени)" Basic.Settings.Stream="Стрийм" Basic.Settings.Stream.StreamType="Тип Стрийм" +Basic.Settings.Stream.Custom.Username="Потребителско име" +Basic.Settings.Stream.Custom.Password="Парола" Basic.Settings.Output="Излъчване" Basic.Settings.Output.Format="Формат на Записа" @@ -542,7 +564,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Предупреждение: Зап Basic.Settings.Output.Simple.Warn.Lossless="Предупреждение: Оригиналното качество създава огромни файлове! Запис настроен на Оригинално качество може да заема над 7GB дисково пространство на минута, ако резолюцията и кадрите са високи. Не се препоръчва ако не разполагате със много пространство." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Сигурни ли сте че искате да ползвате оригиналното качество на записа?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Предупреждение при ползване на Оригинално Качество!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Предупреждение: Не можете да ползвате различни и отделни QSV енкодери докато предавате и записвате. Ако искате да предавате и да записвате едновременно, моля променете един от енкодерите." Basic.Settings.Output.Simple.Encoder.Software="Програмно (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Хардуеър (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Хардуеър (AMD)" @@ -554,7 +575,6 @@ Basic.Settings.Output.Reconnect="Автоматично повторно свъ Basic.Settings.Output.RetryDelay="Отлагане на повторно свързване (секунди)" Basic.Settings.Output.MaxRetries="Максимален брой повторни опити" Basic.Settings.Output.Advanced="Включи Допълнителни Настройки за Енкодера" -Basic.Settings.Output.EncoderPreset="Настройка на Енкодера (по-висока = по-малко процесор)" Basic.Settings.Output.CustomEncoderSettings="Допълнителни Настройки на Енкодера" Basic.Settings.Output.CustomMuxerSettings="Допълнителни Настройки при Смесване" Basic.Settings.Output.NoSpaceFileName="Създавай името на записа без Празни Места" @@ -599,22 +619,21 @@ Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Настройки при сли Basic.Settings.Output.Adv.FFmpeg.GOPSize="Интервал между ключови кадри (кадри)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Покажи всички кодеци (дори и ако са несъвместими)" -FilenameFormatting.completer="%ХХГГ-%ММ-%ДД %чч-%мм-%сс\n%ГГ-%ММ-%ДД %чч-%мм-%сс\n%Г-%м-%д %Ч-%М-%С\n%г-%м-%д %Ч-%М-%С\n%а %Г-%м-%д %Ч-%М-%С\n%А %Г-%м-%д %Ч-%М-%С\n%Г-%б-%д %Ч-%М-%С\n%Г-%Б-%д %Ч-%М-%С\n%Г- %м-%д %И-%М-%С-%п\n%Г-%м-%д %Ч-%М-%С-%з\n%Г-%м-%д %Ч-%М-%С-%ст" FilenameFormatting.TT="%CCYY Година, четири цифри\n%YY Година, последни две цифри (00-99)\n%MM Месецът като цяло число (01-12)\n%DD Ден от месеца, със добавена нула (01-31)\n%hh Часът във 24ч формат (00-23)\n%mm Минута (00-59)\n%ss Секунда (00-61)\n%% % подпис\n%a Съкратено име на деня\n%A Пълно име на деня\n%b Съкратено име на месеца\n%B Пълно име на месеца\n%d Ден от месеца, със добавена нула (01-31)\n%H Часът във 24ч формат (00-23)\n%I Часът във 12ч формат (01-12)\n%m Месецът като цяло число (01-12)\n%M Минута (00-59)\n%p AM или PM посочен\n%S Секунда (00-61)\n%y Година, последни две цифри (00-99)\n%Y Година\n%z ISO 8601 разминаване със UTC или времева зона\n име или съкращение\n%Z Име на Времевата зона или съкращение\n" Basic.Settings.Video="Видео" -Basic.Settings.Video.Adapter="Видео адаптер:" +Basic.Settings.Video.Adapter="Видео адаптер" Basic.Settings.Video.BaseResolution="Основна Резолюция на Платното" Basic.Settings.Video.ScaledResolution="Резолюция на записа (умален)" -Basic.Settings.Video.DownscaleFilter="Филтър:" +Basic.Settings.Video.DownscaleFilter="Филтър" Basic.Settings.Video.DisableAeroWindows="Изключи Aero прозрачност (само за Windows)" -Basic.Settings.Video.FPS="Кадри в секунда (FPS):" +Basic.Settings.Video.FPS="Кадри в секунда (FPS)" Basic.Settings.Video.FPSCommon="Често използвани FPS стойности" Basic.Settings.Video.FPSInteger="FPS стойност - цяло число" Basic.Settings.Video.FPSFraction="FPS стойност - дробно число" -Basic.Settings.Video.Numerator="Числител:" -Basic.Settings.Video.Denominator="Знаменател:" +Basic.Settings.Video.Numerator="Числител" +Basic.Settings.Video.Denominator="Знаменател" Basic.Settings.Video.Renderer="Презаписване" Basic.Settings.Video.InvalidResolution="Невалидна резолюция. Трябва да бъде [ширина] x [височина] (пример: 1920 x 1080)" Basic.Settings.Video.CurrentlyActive="В момента излъчвате. Моля спрете излъчването за да промените видео настройките." @@ -627,24 +646,22 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Изострено при Basic.Settings.Audio="Аудио" Basic.Settings.Audio.SampleRate="Честота на дискретизацията" Basic.Settings.Audio.Channels="Канали" -Basic.Settings.Audio.MeterDecayRate="Брой за Звуков Разпад" Basic.Settings.Audio.MeterDecayRate.Fast="Бързо" Basic.Settings.Audio.MeterDecayRate.Medium="Средно (ТИП I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Бавно (Type II PPM)" +Basic.Settings.Audio.PeakMeterType="Тип на връхната точка" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Образец на върха" +Basic.Settings.Audio.PeakMeterType.TruePeak="Истински връх (По-високо използване на CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ПРЕДУПРЕЖДЕНИЕ: Включен е Surround sound." Basic.Settings.Audio.MultichannelWarning="Ако предавате, проверете дали вашата услуга за стрийминг поддържа едновременно приемане на съраунд звук и възпроизвеждане на съраунд звук. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast са примери, при които съраунд звукът е напълно поддържан. Въпреки че, Facebook Live и YouTube Live подържат и приемат съраунд, Facebook Live пемиксира към стерео звук, а YouTube Live възпроизвежда само два канала.\n\nЗвуковите филтъри на OBS подържат съраунд звук, въпреки това VST поддръжката не е гарантирана." Basic.Settings.Audio.MultichannelWarning.Title="Включи записването на съраунд звук?" Basic.Settings.Audio.MultichannelWarning.Confirm="Сигурни ли сте че искате да включите записването на съраунд звук?" -Basic.Settings.Audio.DesktopDevice="Аудио устройство (Работен плот)" -Basic.Settings.Audio.DesktopDevice2="Аудио устройство 2 (Работен плот)" -Basic.Settings.Audio.AuxDevice="Микрофон/Вторично аудио устройство" -Basic.Settings.Audio.AuxDevice2="Микрофон/Вторично аудио устройство 2" -Basic.Settings.Audio.AuxDevice3="Микрофон/Вторично аудио устройство 3" Basic.Settings.Audio.EnablePushToMute="Включи Натисни-за-да-заглуши" Basic.Settings.Audio.PushToMuteDelay="Натисни-за-да-заглуши забавяне" Basic.Settings.Audio.EnablePushToTalk="Включи Натисни-за-говорене" Basic.Settings.Audio.PushToTalkDelay="Натисни-за-говорене забавяне" Basic.Settings.Audio.UnknownAudioDevice="[Устройството не е свързано или не е на разположение]" +Basic.Settings.Audio.Disabled="Деактивирано" Basic.Settings.Advanced="За напреднали" Basic.Settings.Advanced.General.ProcessPriority="Приоритет на Програмата" @@ -656,11 +673,8 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Свободен" Basic.Settings.Advanced.FormatWarning="Предупреждение: Цветните формати освен NV12 се ползват главно при записи и не са препоръчани при предаване. Предаването може да упражни завишено ползване на Процесора поради прекодиране на форматите." Basic.Settings.Advanced.Audio.BufferingTime="Време за буфериране на звук" Basic.Settings.Advanced.Video.ColorFormat="Формат на цвета" -Basic.Settings.Advanced.Video.ColorSpace="YUV Цветно Пространство" -Basic.Settings.Advanced.Video.ColorRange="YUV Цветен Обсег" Basic.Settings.Advanced.Video.ColorRange.Partial="Частично" Basic.Settings.Advanced.Video.ColorRange.Full="Пълен" -Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство за Звуково възпроизвеждане" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="По подразбиране" Basic.Settings.Advanced.Audio.DisableAudioDucking="Изключи намалянето на звука при разговори" Basic.Settings.Advanced.StreamDelay="Забавяне на Предаването" @@ -671,12 +685,14 @@ Basic.Settings.Advanced.Network="Мрежа" Basic.Settings.Advanced.Network.BindToIP="Свържи към IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Позволи нов мрежов код" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим на ниска латенция" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Изключване на клавишните комбинации, ако основният прозорец е на фокус" +Basic.Settings.Advanced.AutoRemux="Автоматично преобразувай в .mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(запиши като .mkv)" Basic.AdvAudio="Допълнителни Звукови Характеристики" Basic.AdvAudio.Name="Име" -Basic.AdvAudio.Volume="Сила на звука (%)" Basic.AdvAudio.Mono="Премиксирай към Mono звук" -Basic.AdvAudio.Panning="Накланяне" +Basic.AdvAudio.Balance="Баланс" Basic.AdvAudio.SyncOffset="Забавяне (мс)" Basic.AdvAudio.Monitoring="Звуков Мониториниг " Basic.AdvAudio.Monitoring.None="Мониторът Изключен" @@ -686,6 +702,7 @@ Basic.AdvAudio.AudioTracks="Писти" Basic.Settings.Hotkeys="Горещи клавиши" Basic.Settings.Hotkeys.Pair="Клавишни комбинации ползвани от `%1` действат като ключ" +Basic.Settings.Hotkeys.Filter="Филтър" Basic.Hotkeys.SelectScene="Премини към сцена" @@ -740,11 +757,27 @@ SceneItemHide="Скрии '%1'" OutputWarnings.NoTracksSelected="Трябва да изберете поне една писта за звук" OutputWarnings.MultiTrackRecording="Предупреждение: Някои формати (като FLV) не подържат множествен брой на писти при запис" -OutputWarnings.MP4Recording="Предупреждение: Записи запаметени като MP4 не могат да бъдат възстановени ако записът не е приключен (във случаи на спиране на програмата или загуба на ток и т.н.). Ако искате да записвате на множество звукови писти ползвайте MKV формат и конвертирайте записа на mp4 след като приключи (Файл->Преконвертиране на записи)" FinalScene.Title="Изтрий Сцената" FinalScene.Text="Трябва да има поне една сцена във наличност." - +NoSources.Title="Няма налични източници" +NoSources.Text="Изглежда все още не сте добавили никакви видео източници и ще се вижда само един празен екран. Сигурни ли сте, че желаете това?" +NoSources.Text.AddSource="Можете да добавите източници като щракнете върху + иконката под полето за източници в главния прозорец по всяко време." + +ChangeBG="Задаване на цвят" +CustomColor="Различен цвят" + +BrowserSource.EnableHardwareAcceleration="Позволи ускорение, чрез браузър" + +About="За програмата" +About.Info="OBS Studio е програма за видео запис и живи предавания с отворен код, разпространяваща се безплатно." +About.GetInvolved="Включете се" +About.Authors="Автори" +About.License="Лиценз" + +ResizeOutputSizeOfSource="Преоразмеряване изх. видео (по размер на източника)" +ResizeOutputSizeOfSource.Text="Базата и изходната резолюция ще бъдат преоразмерени до размера на текущия източник." +ResizeOutputSizeOfSource.Continue="Желаете ли да продължите?" diff --git a/UI/data/locale/bn-BD.ini b/UI/data/locale/bn-BD.ini index 8039b73..4c41702 100644 --- a/UI/data/locale/bn-BD.ini +++ b/UI/data/locale/bn-BD.ini @@ -28,6 +28,7 @@ Browse="ব্রাউজ" Mono="মোনো" Stereo="স্টিরিও" DroppedFrames="ছেড়ে দেওয়া ফ্রেমসমূহ %1 (%2 শতাংশ)" +StudioProgramProjector="পূর্ণ পর্দা জুড়ে প্রোজেক্টর (প্রোগ্রাম)" PreviewProjector="পূর্ণ পর্দা জুড়ে প্রোজেক্টর (প্রিভিউ)" SceneProjector="পূর্ণ পর্দা জুড়ে প্রোজেক্টর (দৃশ্য)" SourceProjector="পূর্ণ পর্দা জুড়ে প্রোজেক্টর (সূত্র)" @@ -41,7 +42,7 @@ Duplicate="প্রতিলিপি" Enable="সচল" DisableOSXVSync="OSX ভি-সমকালীন নিষ্ক্রিয় করা হবে" ResetOSXVSyncOnExit="প্রস্থান করার সময় ভি-সমকালীন OSX রিসেট করুন" -HighResourceUsage="এনকোডিং overloaded! ভিডিও সেটিংস ডাউন বাঁক বা দ্রুত এনকোডিং প্রিসেট ব্যবহার করে বিবেচনা করুন." +HighResourceUsage="এনকোডিং overloaded! ভিডিও সেটিংস ডাউন বাঁক বা দ্রুত এনকোডিং প্রিসেট ব্যবহার করে বিবেচনা করুন." Transition="স্থানান্তর" QuickTransitions="দ্রুত অবস্থান্তর" Left="বামদিকে" @@ -63,6 +64,11 @@ Export="ডাটা এক্সপোর্ট" + +Basic.AutoConfig.VideoPage="ভিডিও সেটিংস" + + + Updater.Title="নতুন আপডেট পাওয়া যাবে" Updater.Text="নতুন হালনাগাদ সুপ্রাপ্য নয়:" Updater.UpdateNow="এখনই হালনাগাদ করুন" @@ -74,7 +80,7 @@ Updater.NoUpdatesAvailable.Title="কোন আধুনিকীকরণ উ Updater.NoUpdatesAvailable.Text="কোন আধুনিকীকরণ বর্তমানে পাওয়া যায়।" Updater.FailedToLaunch="হালনাগাদকারী আরম্ভ করতে ব্যর্থ" Updater.GameCaptureActive.Title="খেলার অধিগ্রহণ সক্রিয়" -Updater.GameCaptureActive.Text="খেলার অধিগ্রহণ হুক লাইব্রেরী বর্তমানে ব্যবহার করা হচ্ছে। দয়া করে দখল করা কোন গেম/প্রোগ্রাম বন্ধ করুন (অথবা windows পুনর্সূচনা করুন) এবং পুনরায় চেষ্টা করুন." +Updater.GameCaptureActive.Text="খেলার অধিগ্রহণ হুক লাইব্রেরী বর্তমানে ব্যবহার করা হচ্ছে। দয়া করে দখল করা কোন গেম/প্রোগ্রাম বন্ধ করুন (অথবা Windows পুনর্সূচনা করুন) এবং পুনরায় চেষ্টা করুন." QuickTransitions.SwapScenes="প্রাক-দৃশ্য/আউটপুট দৃশ্য হলে পরে প্রক্রিয়াতে অদলবদল" QuickTransitions.SwapScenesTT="যদি (আউটপুট মূল দৃশ্য এখনো বিদ্যমান আছে) প্রাক্-বীক্ষণ এবং আউটপুট দৃশ্য হলে পরে প্রক্রিয়াতে swaps। \nThis যে আউটপুট মূল দৃশ্যের জন্য তৈরি করা হয়েছে যাতে কোন পরিবর্তন বাতিল হবে না." @@ -109,8 +115,9 @@ ConfirmStart.Text="আপনি কি নিশ্চিত যে আপনি ConfirmStop.Title="স্রোত বন্ধ করতে?" ConfirmStop.Text="আপনি কি নিশ্চিত যে আপনি ধারা সূচনা করতে চান?" + ConfirmExit.Title="OBS প্রস্থান করুন?" -ConfirmExit.Text="OBS বর্তমানে সক্রিয় আছে। সব নদী/রেকর্ডিং বন্ধ হয়ে যাবে। আপনি কি নিশ্চিত যে আপনি প্রস্থান করতে চান?" +ConfirmExit.Text="OBS বর্তমানে সক্রিয় আছে। সব নদী/রেকর্ডিং বন্ধ হয়ে যাবে। আপনি কি নিশ্চিত যে আপনি প্রস্থান করতে চান?" ConfirmRemove.Title="টেমপ্লেট সংরক্ষণ করো" ConfirmRemove.Text="আপনি কি নিশ্চিত যে আপনি '$1' মুছে ফেলতে চান?" @@ -119,37 +126,33 @@ ConfirmRemove.TextMultiple="আপনি কি নিশ্চিত যে আ Output.StartStreamFailed="স্ট্রীমিং চালু করতে ব্যর্থ হয়েছে" Output.StartRecordingFailed="রেকর্ড আরম্ভ করতে ব্যর্থ" Output.StartReplayFailed="রিপ্লে বাফার আরম্ভ করতে ব্যর্থ" -Output.StartFailedGeneric="আউটপুট শুরু করতে ব্যর্থ হয়েছে। Details.\n\nNote জন্য লগ চেক করুন: NVENC অথবা এএমডি encoders ব্যবহার করলে আপনার ভিডিও ড্রাইভার আপ-টু-ডেট রয়েছে নিশ্চিত করুন." +Output.StartFailedGeneric="আউটপুট শুরু করতে ব্যর্থ হয়েছে। Details.\n\nNote জন্য লগ চেক করুন: NVENC অথবা এএমডি encoders ব্যবহার করলে আপনার ভিডিও ড্রাইভার আপ-টু-ডেট রয়েছে নিশ্চিত করুন." + Output.ConnectFail.Title="সংযোগ করতে ব্যর্থ হয়েছে" -Output.ConnectFail.BadPath="ত্রুটিপূর্ণ URL পথ বা সংযোগ। দয়া করে সেগুলো কার্যকর নিশ্চিত করতে আপনার সেটিংস চেক করুন." +Output.ConnectFail.BadPath="ত্রুটিপূর্ণ URL পথ বা সংযোগ। দয়া করে সেগুলো কার্যকর নিশ্চিত করতে আপনার সেটিংস চেক করুন." Output.ConnectFail.ConnectFailed="সার্ভারের সাথে সংযোগ স্থাপন করতে ব্যর্থ" -Output.ConnectFail.InvalidStream="উল্লেখিত চ্যানেল বা ধারা কী, এ প্রবেশ করা যাচ্ছে না দয়া করে আপনার স্ট্রিম কী পরীক্ষা। যদি সঠিক হয়, সমস্যা হতে পারে সার্ভারের সাথে সংযোগ স্থাপন করা হচ্ছে." -Output.ConnectFail.Error="সার্ভারের সাথে সংযোগ করার চেষ্টা করার সময় একটি অপ্রত্যাশিত ত্রুটি সংঘটিত হয়েছে। লগ ফাইল আরও তথ্য." +Output.ConnectFail.InvalidStream="উল্লেখিত চ্যানেল বা ধারা কী, এ প্রবেশ করা যাচ্ছে না দয়া করে আপনার স্ট্রিম কী পরীক্ষা। যদি সঠিক হয়, সমস্যা হতে পারে সার্ভারের সাথে সংযোগ স্থাপন করা হচ্ছে." +Output.ConnectFail.Error="সার্ভারের সাথে সংযোগ করার চেষ্টা করার সময় একটি অপ্রত্যাশিত ত্রুটি সংঘটিত হয়েছে। লগ ফাইল আরও তথ্য." Output.ConnectFail.Disconnected="সার্ভার থেকে সংযোগ বিচ্ছিন্ন হয়েছে." + Output.RecordFail.Title="রেকর্ড আরম্ভ করতে ব্যর্থ" -Output.RecordFail.Unsupported="আউটপুট ফরম্যাট হয়। অসমর্থিত বা একাধিক অডিও ট্র্যাক সমর্থন করে না। অনুগ্রহ করে আপনার সেটিংস পরীক্ষা করুন এবং আবার চেষ্টা করুন." +Output.RecordFail.Unsupported="আউটপুট ফরম্যাট হয়। অসমর্থিত বা একাধিক অডিও ট্র্যাক সমর্থন করে না। অনুগ্রহ করে আপনার সেটিংস পরীক্ষা করুন এবং আবার চেষ্টা করুন." Output.RecordNoSpace.Title="অপর্যাপ্ত ডিস্ক পরিসর" Output.RecordNoSpace.Msg="না চালিয়ে রেকর্ড করার জন্য পর্যাপ্ত ডিস্ক পরিসর নেই." Output.RecordError.Title="রেকর্ড করার ত্রুটির" Output.RecordError.Msg="রেকর্ড করার সময় একটি অনির্দিষ্ট ত্রুটি সংঘটিত হয়েছে." Output.ReplayBuffer.NoHotkey.Title="কোন hotkey সেট!" -Output.ReplayBuffer.NoHotkey.Msg="কোন রিপ্লে বাফারের জন্য সেট hotkey ছাড়া। \"সংরক্ষণ\" hotkey রিপ্লে রেকর্ডিং সংরক্ষণের জন্য ব্যবহার করতে সেট করুন." +Output.ReplayBuffer.NoHotkey.Msg="কোন রিপ্লে বাফারের জন্য সেট hotkey ছাড়া। \"সংরক্ষণ\" hotkey রিপ্লে রেকর্ডিং সংরক্ষণের জন্য ব্যবহার করতে সেট করুন." Output.BadPath.Title="খারাপ পার্ট অনুসন্ধানname" -Output.BadPath.Text="কনফিগার ফাইল আউটপুট পথটি সঠিক নয়। অনুগ্রহ করে একটি কার্যকর পথ তৈরি করা হয়েছে নিশ্চিত করতে, আপনার সেটিংস পরীক্ষা করুন." +Output.BadPath.Text="কনফিগার ফাইল আউটপুট পথটি সঠিক নয়। অনুগ্রহ করে একটি কার্যকর পথ তৈরি করা হয়েছে নিশ্চিত করতে, আপনার সেটিংস পরীক্ষা করুন." LogReturnDialog="সফলভাবে আপলোড লগ" LogReturnDialog.CopyURL="URL অনুলিপি করুন" LogReturnDialog.ErrorUploadingLog="লগ ফাইল আপলোড করা হচ্ছে সমস্যা" -LicenseAgreement="লাইসেন্স চুক্তি" -LicenseAgreement.PleaseReview="দয়া করে আগে OBS. ব্যবহার করে এই অনুজ্ঞা শর্তাবলী পর্যালোচনা করুন এই প্রোগ্রামটি ব্যবহার করে আপনি যে আপনি পড়েছেন এবং v2.0 GNU সাধারণ পাবলিক লাইসেন্সের শর্তাবলীর সাথে সম্মত হচ্ছেন স্বীকার করেন। অনুগ্রহ করে এই চুক্তির বাকি দেখার সংঘ." -LicenseAgreement.ClickIAgreeToContinue="আপনি এই চুক্তির শর্তাদি স্বীকার করেন, আমি Agree অব্যাহত রাখার জন্য ক্লিক করুন। আপনি OBS. ব্যবহার করতে এই চুক্তি স্বীকার করতে হবে." -LicenseAgreement.IAgree="আমি তোমাকে শ্রদ্ধা করি" -LicenseAgreement.Exit="প্রস্থান করুন" - Remux.SourceFile="OBS রেকর্ডিং" Remux.TargetFile="গন্তব্য ফাইল" Remux.Remux="Remux" @@ -157,15 +160,11 @@ Remux.OBSRecording="OBS রেকর্ডিং" Remux.FinishedTitle="Remuxing শেষ" Remux.Finished="Remuxed রেকর্ড" Remux.FinishedError="রেকর্ড remuxed, কিন্তু ফাইলটি অসম্পূর্ণ হতে পারে" -Remux.SelectRecording="OBS রেকর্ডিং করুন …" -Remux.SelectTarget="গন্তব্য ফাইল নির্বাচন করুন…" -Remux.FileExistsTitle="লক্ষ্যবস্তু ফাইলটি বিদ্যমান" -Remux.FileExists="লক্ষ্যবস্তু ফাইলটি বিদ্যমান, এটি প্রতিস্থাপন করতে চান?" Remux.ExitUnfinishedTitle="Remuxing অগ্রসর হচ্ছে" Remux.ExitUnfinished="Remuxing শেষ হয় না, এখন বন্ধ হতে পারে যেন গন্তব্য ফাইলটি ব্যবহারের অযোগ্য। আপনি কি নিশ্চিত যে আপনি remuxing বন্ধ করতে \nAre?" UpdateAvailable="নতুন আপডেট পাওয়া যাবে" -UpdateAvailable.Text="সংস্করণ %1.%2.%3 পাওয়া যায়। ডাউনলোড করতে এখানে ক্লিক করুন।" +UpdateAvailable.Text="সংস্করণ %1.%2.%3 পাওয়া যায়। ডাউনলোড করতে এখানে ক্লিক করুন।" Basic.DesktopDevice1="ডেস্কটপ অডিও" Basic.DesktopDevice2="ডেস্কটপ অডিও 2" @@ -179,6 +178,7 @@ Basic.DisplayCapture="অধিগ্রহণ প্রদর্শন কর Basic.Main.PreviewConextMenu.Enable="প্রাকদর্শন সক্রিয় করুন" + ScaleFiltering="ফিল্টারিং এর আকার পরিবর্তন করো" ScaleFiltering.Point="বিন্দু" ScaleFiltering.Bilinear="Bilinear" @@ -231,7 +231,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (স্বয়ংনির্ব Basic.PropertiesWindow.SelectColor="রঙ নির্বাচন করুন" Basic.PropertiesWindow.SelectFont="ফন্ট নির্বাচন করুন" Basic.PropertiesWindow.ConfirmTitle="বৈশিষ্ট্য পরিবর্তিত হয়েছে" -Basic.PropertiesWindow.Confirm="এতে পরিবর্তন অসংরক্ষিত সংশোধনী রয়েছে। আপনি তাদের রেখে দিতে চান?" +Basic.PropertiesWindow.Confirm="এতে পরিবর্তন অসংরক্ষিত সংশোধনী রয়েছে। আপনি তাদের রেখে দিতে চান?" Basic.PropertiesWindow.NoProperties="কোন বৈশিষ্ট্য সুপ্রাপ্য নয়" Basic.PropertiesWindow.AddFiles="ফাইল যোগ করুন" Basic.PropertiesWindow.AddDir="ডিরেক্টরিটি যোগ করুন" @@ -308,55 +308,55 @@ Basic.Main.StopStreaming="স্ট্রিমিং বন্ধের" Basic.Main.StoppingStreaming="স্রোত বন্ধ হয়ে যাওয়ার..." Basic.Main.ForceStopStreaming="(অবকাশ বাতিল) Streaming বন্ধ" -Basic.MainMenu.File="এবং ফাইল" -Basic.MainMenu.File.Export="এবং এক্সপোর্ট করুন" -Basic.MainMenu.File.Import="এবং আমদানি করুন" -Basic.MainMenu.File.ShowRecordings="প্রদর্শন এবং রেকর্ডিং" -Basic.MainMenu.File.Remux="রি ও মুক্স রেকর্ডিং" -Basic.MainMenu.File.Settings="এবং সেটিংস" +Basic.MainMenu.File="এবং ফাইল (&F)" +Basic.MainMenu.File.Export="এবং এক্সপোর্ট করুন (&E)" +Basic.MainMenu.File.Import="এবং আমদানি করুন (&I)" +Basic.MainMenu.File.ShowRecordings="প্রদর্শন এবং রেকর্ডিং (&R)" +Basic.MainMenu.File.Remux="রি ও মুক্স রেকর্ডিং (&M)" +Basic.MainMenu.File.Settings="এবং সেটিংস (&S)" Basic.MainMenu.File.ShowSettingsFolder="বৈশিষ্ট্য ফোল্ডার প্রদর্শন করা হবে" Basic.MainMenu.File.ShowProfileFolder="প্রোফাইল ফোল্ডার প্রদর্শন করা হবে" -Basic.MainMenu.AlwaysOnTop="&সবসময় চালু শীর্ষে" -Basic.MainMenu.File.Exit="&প্রস্থান" +Basic.MainMenu.AlwaysOnTop="সবসময় চালু শীর্ষে (&A)" +Basic.MainMenu.File.Exit="প্রস্থান (&X)" -Basic.MainMenu.Edit="&সম্পাদনা করুন" -Basic.MainMenu.Edit.Undo="&বাতিল করুন" -Basic.MainMenu.Edit.Redo="&পুনরায় করুন" -Basic.MainMenu.Edit.UndoAction="&বাতিল করুন $1" -Basic.MainMenu.Edit.RedoAction="&পুনরায় $1" -Basic.MainMenu.Edit.LockPreview="&প্রাকদর্শন লক করুন" -Basic.MainMenu.Edit.Scale="প্রাক্-বীক্ষণ &স্কেল" +Basic.MainMenu.Edit="সম্পাদনা করুন (&E)" +Basic.MainMenu.Edit.Undo="বাতিল করুন (&U)" +Basic.MainMenu.Edit.Redo="পুনরায় করুন (&R)" +Basic.MainMenu.Edit.UndoAction="বাতিল করুন $1 (&U)" +Basic.MainMenu.Edit.RedoAction="পুনরায় $1 (&R)" +Basic.MainMenu.Edit.LockPreview="প্রাকদর্শন লক করুন (&L)" +Basic.MainMenu.Edit.Scale="প্রাক্-বীক্ষণ স্কেল (&S)" Basic.MainMenu.Edit.Scale.Window="ভেতর থেকে জানালা" Basic.MainMenu.Edit.Scale.Canvas="ক্যানভাস (%1x%2)" Basic.MainMenu.Edit.Scale.Output="আউটপুট (%1x%2)" -Basic.MainMenu.Edit.Transform="এবং রূপান্তর" -Basic.MainMenu.Edit.Transform.EditTransform="&রূপান্তর সম্পাদনা করুন..." +Basic.MainMenu.Edit.Transform="এবং রূপান্তর (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="রূপান্তর সম্পাদনা করুন... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="রূপান্তর অনুলিপি করুন" Basic.MainMenu.Edit.Transform.PasteTransform="রূপান্তর প্রতিলেপন করুন" -Basic.MainMenu.Edit.Transform.ResetTransform="এবং রূপান্তর রিসেট করুন" +Basic.MainMenu.Edit.Transform.ResetTransform="এবং রূপান্তর রিসেট করুন (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="CW 90 ডিগ্রী ঘোরাও" Basic.MainMenu.Edit.Transform.Rotate90CCW="CW 90 ডিগ্রী ঘোরাও" Basic.MainMenu.Edit.Transform.Rotate180="180 ডিগ্রী ঘোরাও" -Basic.MainMenu.Edit.Transform.FlipHorizontal="ফ্লিপ এবং অনুভূমিক" -Basic.MainMenu.Edit.Transform.FlipVertical="ফ্লিপ এবং উল্লম্ব" -Basic.MainMenu.Edit.Transform.FitToScreen="এবং পর্দায় সমন্বয় করুন" -Basic.MainMenu.Edit.Transform.StretchToScreen="এবং পর্দা করতে বিস্তৃত করুন" -Basic.MainMenu.Edit.Transform.CenterToScreen="এবং পর্দার কেন্দ্রে" -Basic.MainMenu.Edit.Order="ও যেন" -Basic.MainMenu.Edit.Order.MoveUp="সরিয়ে নিন এবং আপ" -Basic.MainMenu.Edit.Order.MoveDown="নিচে নামান" -Basic.MainMenu.Edit.Order.MoveToTop="সরিয়ে দিতে ও শীর্ষ" -Basic.MainMenu.Edit.Order.MoveToBottom="সরান এবং নিচে" -Basic.MainMenu.Edit.AdvAudio="এবং অডিও উন্নত বৈশিষ্ট্য" +Basic.MainMenu.Edit.Transform.FlipHorizontal="ফ্লিপ এবং অনুভূমিক (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="ফ্লিপ এবং উল্লম্ব (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="এবং পর্দায় সমন্বয় করুন (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="এবং পর্দা করতে বিস্তৃত করুন (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="এবং পর্দার কেন্দ্রে (&C)" +Basic.MainMenu.Edit.Order="ও যেন (&O)" +Basic.MainMenu.Edit.Order.MoveUp="সরিয়ে নিন এবং আপ (&U)" +Basic.MainMenu.Edit.Order.MoveDown="নিচে নামান (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="সরিয়ে দিতে ও শীর্ষ (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="সরান এবং নিচে (&B)" +Basic.MainMenu.Edit.AdvAudio="এবং অডিও উন্নত বৈশিষ্ট্য (&A)" -Basic.MainMenu.View="এবং প্রদর্শন করুন" -Basic.MainMenu.View.Toolbars="এবং টুলবার" -Basic.MainMenu.View.Toolbars.Listboxes="এবং Listboxes" -Basic.MainMenu.View.SceneTransitions="ঘটনাস্থলে অবস্থান্তর" -Basic.MainMenu.View.StatusBar="স্ট্যাটাস বার" +Basic.MainMenu.View="এবং প্রদর্শন করুন (&V)" +Basic.MainMenu.View.Toolbars="এবং টুলবার (&T)" +Basic.MainMenu.View.Toolbars.Listboxes="এবং &Listboxes" +Basic.MainMenu.View.SceneTransitions="ঘটনাস্থলে অবস্থান্তর (&C)" +Basic.MainMenu.View.StatusBar="স্ট্যাটাস বার (&S)" -Basic.MainMenu.SceneCollection="এবং দৃশ্য সংগ্রহ" -Basic.MainMenu.Profile="এবং প্রোফাইল" +Basic.MainMenu.SceneCollection="এবং দৃশ্য সংগ্রহ (&S)" +Basic.MainMenu.Profile="এবং প্রোফাইল (&P)" Basic.MainMenu.Profile.Import="প্রোফাইল আমদানি করুন" Basic.MainMenu.Profile.Export="প্রোফাইল রপ্তানি করুন" Basic.MainMenu.SceneCollection.Import="দৃশ্য সংগ্রহ আমদানি করুন" @@ -364,20 +364,20 @@ Basic.MainMenu.SceneCollection.Export="দৃশ্য সংগ্রহ আম Basic.MainMenu.Profile.Exists="প্রোফাইল ইতোমধ্যেই বিদ্যমান" Basic.MainMenu.SceneCollection.Exists="দৃশ্য সংগ্রহ ইতোমধ্যে বিদ্যমান" -Basic.MainMenu.Tools="ও সরঞ্জাম" +Basic.MainMenu.Tools="ও সরঞ্জাম (&T)" -Basic.MainMenu.Help="এবং সাহায্য" -Basic.MainMenu.Help.Website="দর্শন ও ওয়েবসাইট" -Basic.MainMenu.Help.Logs="এবং লগ ফাইল" -Basic.MainMenu.Help.Logs.ShowLogs="এবং লগ ফাইলগুলো প্রদর্শন করুন" -Basic.MainMenu.Help.Logs.UploadCurrentLog="আপলোড এবং বর্তমান লগ ফাইল" -Basic.MainMenu.Help.Logs.UploadLastLog="আপলোড এবং সর্বশেষ লগ ফাইল" +Basic.MainMenu.Help="এবং সাহায্য (&H)" +Basic.MainMenu.Help.Website="দর্শন ও ওয়েবসাইট (&W)" +Basic.MainMenu.Help.Logs="এবং লগ ফাইল (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="এবং লগ ফাইলগুলো প্রদর্শন করুন (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="আপলোড এবং বর্তমান লগ ফাইল (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="আপলোড এবং সর্বশেষ লগ ফাইল (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="&View লগ দেখাও" Basic.MainMenu.Help.CheckForUpdates="হালনাগাদের জন্য পরীক্ষা করুন" Basic.Settings.ProgramRestart="এই প্রোগ্রামটি এই সেটিংস প্রভাবী করতে পুনর্সূচনা করা আবশ্যক." Basic.Settings.ConfirmTitle="পরিবর্তন করুন" -Basic.Settings.Confirm="পরিবর্তন অসংরক্ষিত সংশোধনী রয়েছে। পরিবর্তন সংরক্ষণ করব?" +Basic.Settings.Confirm="পরিবর্তন অসংরক্ষিত সংশোধনী রয়েছে। পরিবর্তন সংরক্ষণ করব?" Basic.Settings.General="সাধারণ" Basic.Settings.General.Theme="থিম" @@ -419,7 +419,7 @@ Basic.Settings.Output.UseReplayBuffer="রিপ্লে বাফার সক Basic.Settings.Output.ReplayBuffer.SecondsMax="সর্বোচ্চ রিপ্লে সময় (সেকেন্ড)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="সর্বোচ্চ স্মৃতি (মেগাবাইট)" Basic.Settings.Output.ReplayBuffer.Estimate="ব্যবহার করা: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="স্মৃতি ব্যবহার অনুমান করতে পারে না। অনুগ্রহ করে স্মৃতি সর্বোচ্চ সীমা নির্ধারণ করুন." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="স্মৃতি ব্যবহার অনুমান করতে পারে না। অনুগ্রহ করে স্মৃতি সর্বোচ্চ সীমা নির্ধারণ করুন." Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="আউটপুট ফাইল" @@ -447,20 +447,20 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY বছর, চার digits\n%YY সালের শেষ দুটি অঙ্ক (00-99)\n%MM মাস হিসেবে দশমিক সংখ্যা (01-12) \n%DD মাসের জিরো-প্যাড, (01-31)\n%hh ঘন্টা 24 এইচ. আই. ভি ফরম্যাটে (00-23)\n%mm মিনিট (00-59) \n%ss (00-61) দ্বিতীয় \n%% এক শতাংশ sign\n%a সংক্ষিপ্ত সপ্তান্তের name\n%A পূর্ণ সপ্তান্তের name\n%b সংক্ষিপ্ত মাস name\n%B পুরো মাসের name\n%d দিনে মাসের শূন্য-প্যাড (01-31)\n%H ঘন্টা 24 জ বিন্যাস (00-23) \n%I ঘন্টা 12h বিন্যাস (01-12)\n%m মাস দশমিক সংখ্যা হিসেবে (01-12)\n%M মিনিট (00-59) \n%p বিকাল বা রাত designation\n%S দ্বিতীয় (00-61)\n%y সালের শেষ দুটি অঙ্ক থেকে ইউটিসি বা timezone\n নাম বা abbreviation\n%Z (00-99)\n%Y Year\n%z ISO 8601 অফসেট সময় অঞ্চল নাম বা abbreviation\n" Basic.Settings.Video="ভিডিও" -Basic.Settings.Video.Adapter="ভিডিও অভিযোজক:" -Basic.Settings.Video.BaseResolution="বেস (ক্যানভাস) নিয়মন:" -Basic.Settings.Video.ScaledResolution="আউটপুট রেজুলেশন: (আকার পরিবর্তিত):" -Basic.Settings.Video.DownscaleFilter="Downscale ফিল্টার:" +Basic.Settings.Video.Adapter="ভিডিও অভিযোজক" +Basic.Settings.Video.BaseResolution="বেস (ক্যানভাস) নিয়মন" +Basic.Settings.Video.ScaledResolution="আউটপুট রেজুলেশন: (আকার পরিবর্তিত)" +Basic.Settings.Video.DownscaleFilter="Downscale ফিল্টার" Basic.Settings.Video.DisableAeroWindows="এ্যারো (শুধুমাত্র Windows) নিষ্ক্রিয় করা হবে" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="FPS সাধারণ মানসমূহ" Basic.Settings.Video.FPSInteger="পূর্ণসংখ্যা FPS মান" Basic.Settings.Video.FPSFraction="ভগ্নাংশের FPS মান" -Basic.Settings.Video.Numerator="লব।:" -Basic.Settings.Video.Denominator="হর:" -Basic.Settings.Video.Renderer="রূপায়ন।:" -Basic.Settings.Video.InvalidResolution="অবৈধ প্রস্তাব মান। [width]x[height] (অর্থাৎ 1920 x 1080) থাকতে হবে" -Basic.Settings.Video.CurrentlyActive="ভিডিও আউটপুট বর্তমানে সক্রিয় আছে। ভিডিও বিন্যাসনসমূহ পরিবর্তন করতে কোন ভয়েস থেকে চালু করুন।." +Basic.Settings.Video.Numerator="লব।" +Basic.Settings.Video.Denominator="হর" +Basic.Settings.Video.Renderer="রূপায়ন।" +Basic.Settings.Video.InvalidResolution="অবৈধ প্রস্তাব মান। [width]x[height] (অর্থাৎ 1920 x 1080) থাকতে হবে" +Basic.Settings.Video.CurrentlyActive="ভিডিও আউটপুট বর্তমানে সক্রিয় আছে। ভিডিও বিন্যাসনসমূহ পরিবর্তন করতে কোন ভয়েস থেকে চালু করুন।." Basic.Settings.Video.DisableAero="এরো নিষ্ক্রিয় করুন" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (সবচেয়ে দ্রুত, কিন্তু ঘোলাটে হলে স্কেল)" @@ -470,11 +470,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened স্কেল Basic.Settings.Audio="অডিও" Basic.Settings.Audio.SampleRate="নমুনা হার" Basic.Settings.Audio.Channels="চ্যানেলসমূহ" -Basic.Settings.Audio.DesktopDevice="ডেস্কটপ অডিও ডিভাইস" -Basic.Settings.Audio.DesktopDevice2="ডেস্কটপ অডিও ডিভাইস" -Basic.Settings.Audio.AuxDevice="মাইক/সহযোগী অডিও ডিভাইস" -Basic.Settings.Audio.AuxDevice2="মাইক/সহযোগী অডিও ডিভাইস" -Basic.Settings.Audio.AuxDevice3="মাইক/সহযোগী অডিও ডিভাইস" Basic.Settings.Audio.EnablePushToMute="মৌন করার ধাক্কা সক্রিয় করা হবে" Basic.Settings.Audio.PushToMuteDelay="মৌন করার ধাক্কা বিলম্ব" Basic.Settings.Audio.EnablePushToTalk="পুশ করার কথা সক্রিয় করা হবে" @@ -487,14 +482,11 @@ Basic.Settings.Advanced.General.ProcessPriority.High="বেশি" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="স্বাভাবিকের উপরে" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="নিষ্ক্রিয়" -Basic.Settings.Advanced.FormatWarning="সতর্কতা: রং বিন্যাস ছাড়া NV12 রেকর্ডিং-এর জন্য প্রাথমিকভাবে উদ্দেশ্যে করা হয়, এবং স্ট্রীমিং-এর সময় সুপারিশকৃত নয়। এর রং বিন্যাস রূপান্তরের ফলে সিপিইউ ব্যবহার বৃদ্ধি ভয়ংকর হতে পারে।." +Basic.Settings.Advanced.FormatWarning="সতর্কতা: রং বিন্যাস ছাড়া NV12 রেকর্ডিং-এর জন্য প্রাথমিকভাবে উদ্দেশ্যে করা হয়, এবং স্ট্রীমিং-এর সময় সুপারিশকৃত নয়। এর রং বিন্যাস রূপান্তরের ফলে সিপিইউ ব্যবহার বৃদ্ধি ভয়ংকর হতে পারে।." Basic.Settings.Advanced.Audio.BufferingTime="অডিও বাফারিং সময়" Basic.Settings.Advanced.Video.ColorFormat="রঙ বিন্যাস" -Basic.Settings.Advanced.Video.ColorSpace="YUV কালার-স্পেস" -Basic.Settings.Advanced.Video.ColorRange="YUV রং বিন্যাস" Basic.Settings.Advanced.Video.ColorRange.Partial="আংশিক" Basic.Settings.Advanced.Video.ColorRange.Full="পূর্ণ" -Basic.Settings.Advanced.Audio.MonitoringDevice="অডিও মনিটরিং ডিভাইস" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="পূর্ব-নির্ধারিত" Basic.Settings.Advanced.StreamDelay="স্ট্রিম বিলম্ব" Basic.Settings.Advanced.StreamDelay.Duration="দৈর্ঘ্য (সেকেন্ড)" @@ -510,7 +502,7 @@ Basic.Hotkeys.SelectScene="ঘটনাস্থলে স্যুইচ কর Basic.SystemTray.Show="প্রদর্শন করা হবে" Basic.SystemTray.Hide="সরিয়ে রাখ" -Basic.SystemTray.Message.Reconnecting="বিচ্ছিন্ন হয়ে গেছে। পুনরায় সংযোগ করা হচ্ছে..." +Basic.SystemTray.Message.Reconnecting="বিচ্ছিন্ন হয়ে গেছে। পুনরায় সংযোগ করা হচ্ছে..." Hotkeys.Insert="প্রবেশ করান" Hotkeys.Delete="মুছে ফেলা" @@ -558,7 +550,9 @@ SceneItemHide="'%1' আড়াল করা হবে" OutputWarnings.NoTracksSelected="আপনি অবশ্যই কমপক্ষে একটি ট্র্যাক নির্বাচন" OutputWarnings.MultiTrackRecording="সতর্কতা: একাধিক ট্র্যাক রেকর্ড প্রতি নির্দিষ্ট ফরম্যাটে (যেমন FLV) সমর্থন করে না" -OutputWarnings.MP4Recording="সতর্কতা: রেকর্ডিং MP4 কাছে সংরক্ষিত ফাইল (যেমন: BSODs ফলে, বিদ্যুৎ লোকসান, ইত্যাদি।) চূড়ান্ত করা না হলে নির্বাহ হওয়ার সময়ের অপুনরুদ্ধারযোগ্য করা হবে। আপনি যদি রেকর্ড করতে চান একাধিক অডিও ট্র্যাক MKV এবং remux রেকর্ড করা mp4 ব্যবহার করে এটি সম্পন্ন করার পর বিবেচনা (Remux রেকর্ডিং-> ফাইল)" + + + diff --git a/UI/data/locale/ca-ES.ini b/UI/data/locale/ca-ES.ini index 1b58259..6642e91 100644 --- a/UI/data/locale/ca-ES.ini +++ b/UI/data/locale/ca-ES.ini @@ -80,14 +80,40 @@ StudioMode.Program="Programa" ShowInMultiview="Mostra en vista múltiple" VerticalLayout="Disposició vertical" Group="Grup" +DoNotShowAgain="No tornis a mostrar" +Default="(Per defecte)" +Calculating="S'està calculant..." AlreadyRunning.Title="L'OBS ja s'està executant" AlreadyRunning.Text="L'OBS ja s'està executant! A no ser que vulgueu fer això, tanqueu totes les finestres de l'OBS abans d'intentar iniciar una nova. Si teniu configurat OBS perquè es minimitzi a la barra de tasques, proveu a veure si segueix executant-se aquí." AlreadyRunning.LaunchAnyway="Executa de totes maneres" +DockCloseWarning.Title="Tancament de la finestra acoblada" +DockCloseWarning.Text="Heu tancat una finestra acoblada. Si voleu que es mostri novament, utilitzeu l'opció Visualitza → Acoblador de la barra de menús." + +Auth.Authing.Title="S'està autenticant..." +Auth.Authing.Text="S'està autenticant amb %1, espereu..." +Auth.AuthFailure.Title="Error d'autenticació" +Auth.AuthFailure.Text="No s'ha pogut autenticar amb %1:\n\n%2: %3" +Auth.InvalidScope.Title="Es necessita autenticació" +Auth.InvalidScope.Text="Han canviat els requisits d'autenticació per %1. Potser algunes funcions no estaran disponibles." +Auth.LoadingChannel.Title="S'està carregant la informació del canal..." +Auth.LoadingChannel.Text="S'està carregant la informació del canal a %1, espereu..." +Auth.ChannelFailure.Title="S'ha produït un error en carregar el canal" +Auth.ChannelFailure.Text="No s'ha pogut carregar la informació del canal per a %1\n\n%2: %3" +Auth.Chat="Xat" +Auth.StreamInfo="Informació de la transmissió" +TwitchAuth.Stats="Estat del Twitch" +TwitchAuth.Feed="Activitat del mur del Twitch" +TwitchAuth.TwoFactorFail.Title="No s'ha pogut consultar la clau de la transmissió" +TwitchAuth.TwoFactorFail.Text="L'OBS no ha pogut connectar amb el vostre compte del Twitch. Assegureu-vos que l'autenticació en 2 passos està habilitada a les opcions de seguretat del Twitch, atès que és un requeriment per retransmetre." + Copy.Filters="Copia els filtres" Paste.Filters="Enganxa els filtres" +BrowserPanelInit.Title="S'està inicialitzant el navegador..." +BrowserPanelInit.Text="S'està inicialitzant el navegador, espereu..." + BandwidthTest.Region="Regió" BandwidthTest.Region.US="Estats Units" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Àsia" BandwidthTest.Region.Other="Altre" Basic.FirstStartup.RunWizard="Voleu executar l'assistent de configuració automàtica? També podeu configurar els paràmetres manualment en fer clic al botó configuració de la finestra principal." -Basic.FirstStartup.RunWizard.BetaWarning="(Nota: L'assistent de configuració automàtica està en beta)" Basic.FirstStartup.RunWizard.NoClicked="Si canvia la seva ment, pot executar l'assistent de configuració automàtica en qualsevol moment des del menú eines." Basic.AutoConfig="Assistent de configuració automàtic" -Basic.AutoConfig.Beta="Assistent de configuració automàtica (beta)" Basic.AutoConfig.ApplySettings="Aplica la configuració" Basic.AutoConfig.StartPage="Informació sobre l'ús" Basic.AutoConfig.StartPage.SubTitle="Especifiqueu perquè vol fer servir el programa" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, però utilitza l'alta res Basic.AutoConfig.VideoPage.CanvasExplanation="La resolució del llenç (base) no és necessàriament la mateixa que la resolució de la transmissió o enregistrament. La resolució actual pot ser reduïda del llenç per reduir l'ús dels recursos o de la tassa de bits." Basic.AutoConfig.StreamPage="Informació de la transmissió" Basic.AutoConfig.StreamPage.SubTitle="Introduïu informació sobre la seva transmissió" +Basic.AutoConfig.StreamPage.ConnectAccount="Connecta un compte (opcional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Desconnecta el compte" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Voleu desconnectar el compte?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Aquest canvi s'aplicarà immediatament. Segur que voleu desconnectar el compte?" +Basic.AutoConfig.StreamPage.UseStreamKey="Utilitza una clau de transmissió" Basic.AutoConfig.StreamPage.Service="Servei" Basic.AutoConfig.StreamPage.Service.ShowAll="Mostra-ho tot..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalitzat..." Basic.AutoConfig.StreamPage.Server="Servidor" Basic.AutoConfig.StreamPage.StreamKey="Clau de la transmissió" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Enllaç)" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Inactiu" Basic.Stats.DroppedFrames="Fotogrames perduts (xarxa)" Basic.Stats.MegabytesSent="Sortida de dades total" Basic.Stats.Bitrate="Tassa de bits" +Basic.Stats.DiskFullIn="Disc ple en (aprox.)" + +ResetUIWarning.Title="Esteu segur que voleu reiniciar la interfície d'usuari?" +ResetUIWarning.Text="En reiniciar la interfície d'usuari s'amagaran els acobladors addicionals. Heu d'habilitar aquests acobladors des del menú Visualitza perquè siguin visibles. \n\nSegur que voleu reiniciar la interfície d'usuari?" Updater.Title="Nova actualització disponible" Updater.Text="Hi ha una nova actualització disponible:" @@ -206,8 +240,11 @@ ConfirmStart.Text="Està segur que desitja iniciar la transmissió?" ConfirmStop.Title="Atura la transmissió?" ConfirmStop.Text="Està segur que desitja aturar la transmissió?" +ConfirmBWTest.Title="Test d'amplada de banda" +ConfirmBWTest.Text="Heu configurat l'OBS en mode Test d'amplada de banda. Aquest mode us permet analitzar la connexió sense cap retransmissió en directe. Una vegada finalitzada l'anàlisi, inhabiliteu aquest mode perquè el públic pugui veure la retransmissió.\n\nVoleu continuar?" + ConfirmExit.Title="Voleu sortir de l'OBS?" -ConfirmExit.Text="OBS és actualment actiu. Tots els directes/gravacions s'aturaran. Esteu segur que voleu sortir?" +ConfirmExit.Text="OBS és actualment actiu. Tots els directes/gravacions s'aturaran. Esteu segur que voleu sortir?" ConfirmRemove.Title="Confirmeu la supressió" ConfirmRemove.Text="Esteu segur que voleu suprimir «$1»?" @@ -218,51 +255,54 @@ Output.StartRecordingFailed="No s'ha pogut iniciar la gravació" Output.StartReplayFailed="No s'ha pogut iniciar la memòria intermèdia de reproducció" Output.StartFailedGeneric="Error en iniciar la sortida. Comproveu el registre per més detalls.\n\nAvís: Si utilitzeu els codificadors NVENC o AMD, assegureu-vos que els controladors de vídeo estan actualitzats." + Output.ConnectFail.Title="Error en connectar" -Output.ConnectFail.BadPath="Ruta o adreça URL no vàlida. Si us plau, comproveu la configuració per confirmar que són vàlids." +Output.ConnectFail.BadPath="Ruta o adreça URL no vàlida. Si us plau, comproveu la configuració per confirmar que són vàlids." Output.ConnectFail.ConnectFailed="No ha pogut connectar al servidor" Output.ConnectFail.InvalidStream="No pot accedir a la clau del canal especificat o de la transmissió, per favor comprovar dues vegades la seva clau de transmissió. Si és correcte, pot haver-hi un problema connectant-se al servidor." -Output.ConnectFail.Error="S'ha produït un error inesperat quan s'intentava connectar amb el servidor. Més informació al fitxer de registre." +Output.ConnectFail.Error="S'ha produït un error inesperat quan s'intentava connectar amb el servidor. Més informació al fitxer de registre." Output.ConnectFail.Disconnected="Desconnectat del servidor." +Output.StreamEncodeError.Title="Error de codificació" +Output.StreamEncodeError.Msg="S'ha produït un error del codificador durant la transmissió." + Output.RecordFail.Title="Error en iniciar la gravació" -Output.RecordFail.Unsupported="El format de sortida és o no compatible o no admet més d'una pista d'àudio. Comproveu la configuració i torneu-ho a provar." +Output.RecordFail.Unsupported="El format de sortida és o no compatible o no admet més d'una pista d'àudio. Comproveu la configuració i torneu-ho a provar." Output.RecordNoSpace.Title="Espai de disc insuficient" Output.RecordNoSpace.Msg="No hi ha prou espai de disc per continuar la gravació." Output.RecordError.Title="Error en l'enregistrament" Output.RecordError.Msg="S'ha produït un error desconegut mentre es gravava." +Output.RecordError.EncodeErrorMsg="S'ha produït un error del codificador durant la gravació." Output.ReplayBuffer.NoHotkey.Title="Cap tecla d'accés ràpid!" Output.ReplayBuffer.NoHotkey.Msg="Cap tecla d'accés ràpid establerta per la memòria intermèdia de reproducció. Configureu la tecla d'accés \"Desa\" per desar els enregistraments de reproducció." Output.BadPath.Title="Ruta de l'arxiu incorrecta" -Output.BadPath.Text="La ruta configurada pel fitxer de sortida no és vàlida. Si us plau, comproveu la configuració per confirmar que s'ha creat una ruta de fitxer vàlida." +Output.BadPath.Text="La ruta configurada pel fitxer de sortida no és vàlida. Si us plau, comproveu la configuració per confirmar que s'ha creat una ruta de fitxer vàlida." LogReturnDialog="Registre carregat amb èxit" LogReturnDialog.CopyURL="Copia l'URL" LogReturnDialog.ErrorUploadingLog="Error en carregar el fitxer de registre" -LicenseAgreement="Acord de llicència" -LicenseAgreement.PleaseReview="Si us plau reviseu els termes de llicència abans d'utilitzar l'OBS. Mitjançant aquest programa, vostè reconeix que ha llegit i accepta les condicions de llicència pública GNU General v 2.0. Si us plau, desplaceu cap avall per veure la resta de l'acord." -LicenseAgreement.ClickIAgreeToContinue="Si accepteu els termes de l'acord, feu clic a accepto per continuar. Heu d'acceptar l'acord per utilitzar l'OBS." -LicenseAgreement.IAgree="Hi estic d'acord" -LicenseAgreement.Exit="Surt" - Remux.SourceFile="Enregistrament OBS" Remux.TargetFile="Fitxer de destinació" Remux.Remux="Converteix" +Remux.Stop="Atura la conversió" +Remux.ClearFinished="Neteja els elements finalitzats" +Remux.ClearAll="Neteja-ho tot" Remux.OBSRecording="Enregistrament OBS" Remux.FinishedTitle="Conversió finalitzada" Remux.Finished="Gravació convertida" Remux.FinishedError="Gravació convertida, però l'arxiu pot ser incomplet" -Remux.SelectRecording="Selecciona la gravació OBS …" -Remux.SelectTarget="Seleccioneu el fitxer de destí …" -Remux.FileExistsTitle="El fitxer de destinació existeix" -Remux.FileExists="El fitxer de destinació existeix, voleu reemplaçar-lo?" +Remux.SelectRecording="Seleccioneu l'enregistrament OBS..." +Remux.SelectTarget="Seleccioneu el fitxer de destinació..." +Remux.FileExistsTitle="Destinació existent" +Remux.FileExists="Aquests elements ja existeixen a la destinació. Voleu reemplaçar-los?" Remux.ExitUnfinishedTitle="Conversió en curs" Remux.ExitUnfinished="La conversió no ha finalitzat, parar ara pot fer l'arxiu de destinació inservible.\n Esteu segur que voleu aturar la conversió?" +Remux.HelpText="Arrossegueu fitxers en aquesta finestra per convertir-los o seleccioneu una cel·la buida a «Enregistrament OBS» per cercar un fitxer." UpdateAvailable="Hi ha disponible una actualització" -UpdateAvailable.Text="La versió %1.%2.%3 està disponible. feu clic aquí per a baixar-la" +UpdateAvailable.Text="La versió %1.%2.%3 està disponible. feu clic aquí per a baixar-la" Basic.DesktopDevice1="Àudio de l'escriptori" Basic.DesktopDevice2="Àudio de l'escriptori 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Captura de pantalla" Basic.Main.PreviewConextMenu.Enable="Habilita la visualització prèvia" +Basic.Main.Preview.Disable="Desactiva la vista prèvia" + ScaleFiltering="Escala de filtratge" ScaleFiltering.Point="Punt" ScaleFiltering.Bilinear="Bilineal" ScaleFiltering.Bicubic="Bicúbic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Àrea" Deinterlacing="Desentrellaçar" Deinterlacing.Discard="Descarta" @@ -330,7 +373,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselecció: %2)" Basic.PropertiesWindow.SelectColor="Seleccioneu un color" Basic.PropertiesWindow.SelectFont="Seleccioneu un tipus de lletra" Basic.PropertiesWindow.ConfirmTitle="Configuració canviada" -Basic.PropertiesWindow.Confirm="Hi ha canvis no desats. Voleu mantenir-los?" +Basic.PropertiesWindow.Confirm="Hi ha canvis no desats. Voleu mantenir-los?" Basic.PropertiesWindow.NoProperties="No hi ha propietats disponibles" Basic.PropertiesWindow.AddFiles="Afegeix fitxers" Basic.PropertiesWindow.AddDir="Afegir directori" @@ -404,7 +447,7 @@ Basic.Main.StopRecording="Atura l'enregistrament" Basic.Main.StoppingRecording="Aturant l'enregistrament..." Basic.Main.StopReplayBuffer="Atura la reproducció de la memòria intermèdia" Basic.Main.StoppingReplayBuffer="S'està aturant la reproducció de la memòria intermèdia..." -Basic.Main.StopStreaming="Atura l'enregistrament" +Basic.Main.StopStreaming="Atura la transmissió" Basic.Main.StoppingStreaming="Aturant la transmissió..." Basic.Main.ForceStopStreaming="Atura l'enregistrament (descarta el retard)" Basic.Main.Group="Grup %1" @@ -415,22 +458,22 @@ Basic.MainMenu.File="&Fitxer" Basic.MainMenu.File.Export="&Exporta" Basic.MainMenu.File.Import="&Importa" Basic.MainMenu.File.ShowRecordings="Mostra els en®istraments" -Basic.MainMenu.File.Remux="Converteix format de gravacions" -Basic.MainMenu.File.Settings="&Configuració" +Basic.MainMenu.File.Remux="Converteix for&mat de gravacions" +Basic.MainMenu.File.Settings="Configuració (&S)" Basic.MainMenu.File.ShowSettingsFolder="Mostrar carpeta de configuració" Basic.MainMenu.File.ShowProfileFolder="Mostra la carpeta del perfil" -Basic.MainMenu.AlwaysOnTop="&Sempre al davant" -Basic.MainMenu.File.Exit="&Surt" +Basic.MainMenu.AlwaysOnTop="Sempre &al davant" +Basic.MainMenu.File.Exit="Surt (&X)" Basic.MainMenu.Edit="&Edita" -Basic.MainMenu.Edit.Undo="&Desfés" +Basic.MainMenu.Edit.Undo="Desfés (&U)" Basic.MainMenu.Edit.Redo="&Refés" -Basic.MainMenu.Edit.UndoAction="&Desfés $1" +Basic.MainMenu.Edit.UndoAction="Desfés $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Refés $1" -Basic.MainMenu.Edit.LockPreview="&Bloquejar vista prèvia" -Basic.MainMenu.Edit.Scale="Vista prèvia i escalat" +Basic.MainMenu.Edit.LockPreview="B&loquejar vista prèvia" +Basic.MainMenu.Edit.Scale="Vi&sta prèvia i escalat" Basic.MainMenu.Edit.Scale.Window="Ajusta a la finestra" -Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)" +Basic.MainMenu.Edit.Scale.Canvas="Llenç (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Sortida (%1x%2)" Basic.MainMenu.Edit.Transform="&Transforma" Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformació..." @@ -442,27 +485,29 @@ Basic.MainMenu.Edit.Transform.Rotate90CCW="Gira 90 graus a l'esquerra" Basic.MainMenu.Edit.Transform.Rotate180="Gira 180 graus" Basic.MainMenu.Edit.Transform.FlipHorizontal="Capgira &horitzontalment" Basic.MainMenu.Edit.Transform.FlipVertical="Capgira &verticalment" -Basic.MainMenu.Edit.Transform.FitToScreen="&Ajusta a la pantalla" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Estira a la pantalla" +Basic.MainMenu.Edit.Transform.FitToScreen="Ajusta a la pantalla (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="E&stira a la pantalla" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centra a la pantalla" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centra verticalment" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centra horitzontalment" Basic.MainMenu.Edit.Order="&Ordre" -Basic.MainMenu.Edit.Order.MoveUp="Mou a&munt" -Basic.MainMenu.Edit.Order.MoveDown="Mou a&vall" -Basic.MainMenu.Edit.Order.MoveToTop="Mou a la part &superior" -Basic.MainMenu.Edit.Order.MoveToBottom="Mou a la part &inferior" -Basic.MainMenu.Edit.AdvAudio="&Propietats avançades d'àudio" +Basic.MainMenu.Edit.Order.MoveUp="Mo&u amunt" +Basic.MainMenu.Edit.Order.MoveDown="Mou avall (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Mou a la par&t superior" +Basic.MainMenu.Edit.Order.MoveToBottom="Mou a la part inferior (&B)" +Basic.MainMenu.Edit.AdvAudio="Propiet&ats avançades d'àudio" -Basic.MainMenu.View="Veure" -Basic.MainMenu.View.Toolbars="Barres d'eines" +Basic.MainMenu.View="&Veure" +Basic.MainMenu.View.Toolbars="Barres d'eines (&T)" Basic.MainMenu.View.Docks="Acoblador" Basic.MainMenu.View.Docks.ResetUI="Reinicia la interfície d'usuari" Basic.MainMenu.View.Docks.LockUI="Bloqueja la interfície d'usuari" -Basic.MainMenu.View.Toolbars.Listboxes="Quadre de Llista" -Basic.MainMenu.View.SceneTransitions="Transicions d'escena" -Basic.MainMenu.View.StatusBar="Barra d'estat" +Basic.MainMenu.View.Toolbars.Listboxes="Quadre de &Llista" +Basic.MainMenu.View.SceneTransitions="Transi&cions d'escena" +Basic.MainMenu.View.StatusBar="Barra d'e&stat" Basic.MainMenu.View.Fullscreen.Interface="Pantalla completa" -Basic.MainMenu.SceneCollection="&Col·lecció d'escenes" +Basic.MainMenu.SceneCollection="Col·lecció d'e&scenes" Basic.MainMenu.Profile="&Perfil" Basic.MainMenu.Profile.Import="Importació del perfil" Basic.MainMenu.Profile.Export="Exportació del perfil" @@ -471,25 +516,26 @@ Basic.MainMenu.SceneCollection.Export="Exporta la col·lecció d'escenes" Basic.MainMenu.Profile.Exists="El perfil ja existeix" Basic.MainMenu.SceneCollection.Exists="La col·lecció d'escenes ja existeix" -Basic.MainMenu.Tools="&Eines" +Basic.MainMenu.Tools="Eines (&T)" -Basic.MainMenu.Help="&Ajuda" -Basic.MainMenu.Help.HelpPortal="Portal d'ajuda" +Basic.MainMenu.Help="Ajuda (&H)" +Basic.MainMenu.Help.HelpPortal="&Portal d'ajuda" Basic.MainMenu.Help.Website="Visa el lloc &web" Basic.MainMenu.Help.Discord="Uniu-vos a un servidor &Discord" -Basic.MainMenu.Help.Logs="Fitxers de ®istre" -Basic.MainMenu.Help.Logs.ShowLogs="&Mostra els arxius de registre" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Carregar arxiu de registre actual" -Basic.MainMenu.Help.Logs.UploadLastLog="Carregar darrer fitxer de registre" +Basic.MainMenu.Help.Logs="Fitxers de registre (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Mo&stra els arxius de registre" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Carregar arxiu de registre actual" +Basic.MainMenu.Help.Logs.UploadLastLog="Carregar darrer fitxer de registre (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Visualitza el registre actual" Basic.MainMenu.Help.CheckForUpdates="Comprova si hi ha cap actualització" Basic.MainMenu.Help.CrashLogs="Info&rme de fallada" Basic.MainMenu.Help.CrashLogs.ShowLogs="Mo&stra els informes de fallada" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Penja el darrer informe de fa&llada" +Basic.MainMenu.Help.About="Qu&ant a" Basic.Settings.ProgramRestart="El programa ha de ser re-iniciat per tal que aquesta configuració tingui efecte." Basic.Settings.ConfirmTitle="Confirma els canvis" -Basic.Settings.Confirm="Hi han canvis no desats. Voleu desar els canvis?" +Basic.Settings.Confirm="Hi han canvis no desats. Voleu desar els canvis?" Basic.Settings.General="General" Basic.Settings.General.Theme="Tema" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Safata del sistema" Basic.Settings.General.SysTrayWhenStarted="Minimitzar a la safata del sistema en iniciar" Basic.Settings.General.SystemTrayHideMinimize="Minimitza sempre a la safata del sistema en lloc de la barra de tasques" Basic.Settings.General.SaveProjectors="Desa els projectors en sortir" +Basic.Settings.General.Preview="Vista prèvia" +Basic.Settings.General.OverflowHidden="Amaga el desbordament" +Basic.Settings.General.OverflowAlwaysVisible="Desbordament sempre visible" +Basic.Settings.General.OverflowSelectionHidden="Mostra el desbordament fins i tot quan la font és invisible" Basic.Settings.General.SwitchOnDoubleClick="Transició a l'escena en fer doble clic" Basic.Settings.General.StudioPortraitLayout="Habilita la disposició horitzontal/vertical" +Basic.Settings.General.TogglePreviewProgramLabels="Mostra les etiquetes de vista prèvia/programa" Basic.Settings.General.Multiview="Vista múltiple" Basic.Settings.General.Multiview.MouseSwitch="Feu clic per canviar entre escenes" Basic.Settings.General.Multiview.DrawSourceNames="Mostra el nom de l'escena" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horitzontal, par Basic.Settings.Stream="Directe" Basic.Settings.Stream.StreamType="Tipus de directe" +Basic.Settings.Stream.Custom.UseAuthentication="Utilitza l'autenticació" +Basic.Settings.Stream.Custom.Username="Usuari" +Basic.Settings.Stream.Custom.Password="Contrasenya" +Basic.Settings.Stream.BandwidthTestMode="Habilita el mode Test d'amplada de banda" Basic.Settings.Output="Sortida" Basic.Settings.Output.Format="Format d'enregistrament" @@ -554,13 +609,12 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Mateixa que en directe" Basic.Settings.Output.Simple.RecordingQuality.Small="Qualitat alta, mida d'arxiu mitjana" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualitat molt elevada, mida de fitxer gran" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualitat sense pèrdues, mida de l'arxiu molt gran" -Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTÈNCIA: La transmissió del vídeo s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTÈNCIA: La transmissió d'àudio s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." +Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTÈNCIA: La transmissió del vídeo s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTÈNCIA: La transmissió d'àudio s'establirà a %1, que és el límit superior per al servei de streaming actual. Si està segur que vol anar per sobre de %1, activi les opcions avançades del codificador i desactivi \"Forçar límits de tassa de bits al servei d'streaming\"." Basic.Settings.Output.Simple.Warn.Encoder="Advertiment: Gravar amb un software codificador en una qualitat diferent que el directe requerirà ús de CPU addicional si el directe i la gravació es fan a la vegada." -Basic.Settings.Output.Simple.Warn.Lossless="Advertiment: La qualitat sense pèrdues genera mides d'arxiu gegantines! La qualitat sense pèrdues pot utilitzar un total de 7 gigabytes d'espai de disc per minut a alta resolució i FPS. Aquesta qualitat no és recomanable per a enregistraments llargs llevat que tingui una gran quantitat d'espai de disc disponible." +Basic.Settings.Output.Simple.Warn.Lossless="Advertiment: La qualitat sense pèrdues genera mides d'arxiu gegantines! La qualitat sense pèrdues pot utilitzar un total de 7 gigabytes d'espai de disc per minut a alta resolució i FPS. Aquesta qualitat no és recomanable per a enregistraments llargs llevat que tingui una gran quantitat d'espai de disc disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Esteu segur que voleu utilitzar qualitat sense pèrdues?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Advertiment de qualitat sense pèrdues!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Advertència: No es poden utilitzar diversos descodificadors QSV separats en transmetre i enregistrar al mateix temps. Per transmetre i engrestriar al mateix temps, si us plau modifiqueu-los, ja sigui el codificador de gravació o el codificador de transmissió." Basic.Settings.Output.Simple.Encoder.Software="Programari (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Maquinari (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Maquinari (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Torna a connectar automàticament" Basic.Settings.Output.RetryDelay="Retard de tornar a provar (segons)" Basic.Settings.Output.MaxRetries="Nombre màxim de reintents" Basic.Settings.Output.Advanced="Activar configuració de codificador avançada" -Basic.Settings.Output.EncoderPreset="Preconfiguració de codificador (més alt = menys CPU)" +Basic.Settings.Output.EncoderPreset="Valors predefinits del codificador" Basic.Settings.Output.CustomEncoderSettings="Configuració del codificador personalitzada" Basic.Settings.Output.CustomMuxerSettings="Configuració del conversor personalitzada" Basic.Settings.Output.NoSpaceFileName="Generar nom de fitxer sense espai" @@ -622,20 +676,20 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY Any, quatre dígits\n%YY Any, darrers dos digits (00-99)\n%MM Mes com a número decimal (01-12)\n%DD Dia del mes, emplena amb zero (01-31)\n%hh Hora en format 24h (00-23)\n%mm Minut (00-59)\n%ss Segon (00-61)\n%% A % signe\n%a Nom de la setmana abreujat\n%A Nom complet de la setmana\n%b Nom del mes abreujat\n%B Nom del mes complet\n%d Dia del mes, zero-afegit (01-31)\n%H Hora en format 24h (00-23)\n%I Hora en format 12h (01-12)\n%m Mes com a número decimal (01-12)\n%M Minut (00-59)\n%p Designació AM o PM\n%S Segon (00-61)\n%y Any, darrers dos dígits (00-99)\n%Y Any\n%z ISO 8601 ajust UTC o zona horària\n nom or abreujament\n%Z Nom de la zona horària o abreujament\n" Basic.Settings.Video="Vídeo" -Basic.Settings.Video.Adapter="Adaptador de vídeo:" -Basic.Settings.Video.BaseResolution="Resolució base (quadre):" -Basic.Settings.Video.ScaledResolution="Resolució de sortida (escalat):" -Basic.Settings.Video.DownscaleFilter="Filtre de baixada d'escala:" +Basic.Settings.Video.Adapter="Adaptador de vídeo" +Basic.Settings.Video.BaseResolution="Resolució base (Llenç)" +Basic.Settings.Video.ScaledResolution="Resolució de sortida (escalat)" +Basic.Settings.Video.DownscaleFilter="Filtre de baixada d'escala" Basic.Settings.Video.DisableAeroWindows="Desactiva l'Aero (només al Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valors comuns FPS" Basic.Settings.Video.FPSInteger="Valor FPS sencer" Basic.Settings.Video.FPSFraction="Valor FPS fraccionari" -Basic.Settings.Video.Numerator="Numerador:" -Basic.Settings.Video.Denominator="Denominador:" -Basic.Settings.Video.Renderer="Renderitzador:" -Basic.Settings.Video.InvalidResolution="El valor de resolució no és vàlid. Ha de ser [amplada]x[alçada] (per exemple, 1920x1080)" -Basic.Settings.Video.CurrentlyActive="La sortida de vídeo és actualment activa. Si us plau desactiveu qualsevol sortida per canviar la configuració de vídeo." +Basic.Settings.Video.Numerator="Numerador" +Basic.Settings.Video.Denominator="Denominador" +Basic.Settings.Video.Renderer="Renderitzador" +Basic.Settings.Video.InvalidResolution="El valor de resolució no és vàlid. Ha de ser [amplada]x[alçada] (per exemple, 1920x1080)" +Basic.Settings.Video.CurrentlyActive="La sortida de vídeo és actualment activa. Si us plau desactiveu qualsevol sortida per canviar la configuració de vídeo." Basic.Settings.Video.DisableAero="Desactiva l'Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineal (més ràpida, però borrós si s'escala)" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalat accentuat, 32 mos Basic.Settings.Audio="Àudio" Basic.Settings.Audio.SampleRate="Frequència de mostreig" Basic.Settings.Audio.Channels="Canals" -Basic.Settings.Audio.MeterDecayRate="Resposta del ràtio de l'audiòmetre" +Basic.Settings.Audio.Meters="Metres" +Basic.Settings.Audio.MeterDecayRate="Velocitat de descomposició" Basic.Settings.Audio.MeterDecayRate.Fast="Ràpida" Basic.Settings.Audio.MeterDecayRate.Medium="Mitja (PPM de tipus I)" Basic.Settings.Audio.MeterDecayRate.Slow="Lenta (PPM de tipus II)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="ATENCIÓ: El so envoltant est Basic.Settings.Audio.MultichannelWarning="Si esteu retransmetent, verifiqueu que el servei triat suporta el so envoltant, tant a la reproducció d'entrada com de sortida. El Twitch, el Facebook 360 Live, el Mixer RTMP i el Smashcast són exemples on està completament suportat. Encara que el Facebook Live i el YouTube Live accepten l'entrada de so envoltant, el Facebook Live la converteix a estèreo i el YouTube Live la reprodueix només en 2 canals.\n\nEls filtres d'àudio de l'OBS són compatibles amb el so envoltant, encara que no es garanteix la compatibilitat amb connectors VST." Basic.Settings.Audio.MultichannelWarning.Title="Voleu habilitar el so envoltant?" Basic.Settings.Audio.MultichannelWarning.Confirm="Segur que voleu habilitar el so envoltant?" -Basic.Settings.Audio.DesktopDevice="Dispositiu d'àudio d'escriptori" -Basic.Settings.Audio.DesktopDevice2="Dispositiu d'àudio d'escriptori 2" -Basic.Settings.Audio.AuxDevice="Micròfon/Dispositiu d'àudio auxiliar" -Basic.Settings.Audio.AuxDevice2="Micròfon/Dispositiu d'àudio auxiliar 2" -Basic.Settings.Audio.AuxDevice3="Micròfon/Dispositiu d'àudio auxiliar 3" +Basic.Settings.Audio.Devices="Dispositius" +Basic.Settings.Audio.DesktopDevice="Àudio de l'escriptori" +Basic.Settings.Audio.DesktopDevice2="Àudio de l'escriptori 2" +Basic.Settings.Audio.AuxDevice="Dispositiu d'àudio mic/auxiliar" +Basic.Settings.Audio.AuxDevice2="Dispositiu d'àudio mic/auxiliar 2" +Basic.Settings.Audio.AuxDevice3="Dispositiu d'àudio mic/auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Dispositiu d'àudio mic/auxiliar 4" Basic.Settings.Audio.EnablePushToMute="Activa \"prémer-per-silenciar\"" Basic.Settings.Audio.PushToMuteDelay="Retard \"prémer-per-silenciar\"" Basic.Settings.Audio.EnablePushToTalk="Activa \"prémer-per-parlar\"" Basic.Settings.Audio.PushToTalkDelay="Retard de \"prémer-per-parlar\"" Basic.Settings.Audio.UnknownAudioDevice="[Dispositiu no connectat o no disponible]" +Basic.Settings.Audio.Disabled="Inhabilitat" Basic.Settings.Advanced="Avançat" Basic.Settings.Advanced.General.ProcessPriority="Prioritat del procés" @@ -674,14 +732,14 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Per sobre del norma Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Per sota del normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactiva" -Basic.Settings.Advanced.FormatWarning="Advertiment: Els formats de color diferents de NV12 estan destinats principalment per a la gravació i no són recomanables quan es fa un directe. Fer un directe pot comportar un major ús de CPU a causa de la conversió de format de color." +Basic.Settings.Advanced.FormatWarning="Advertiment: Els formats de color diferents de NV12 estan destinats principalment per a la gravació i no són recomanables quan es fa un directe. Fer un directe pot comportar un major ús de CPU a causa de la conversió de format de color." Basic.Settings.Advanced.Audio.BufferingTime="Temps de buffer d'àudio" Basic.Settings.Advanced.Video.ColorFormat="Format del color" -Basic.Settings.Advanced.Video.ColorSpace="Espai de color YUV" -Basic.Settings.Advanced.Video.ColorRange="Gamma de color YUV" +Basic.Settings.Advanced.Video.ColorSpace="Espai de color" +Basic.Settings.Advanced.Video.ColorRange="Gamma de colors" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" Basic.Settings.Advanced.Video.ColorRange.Full="Màxima" -Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositiu de monitorització d'àudio" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositiu de monitorització" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Per defecte" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desactiva la reducció d'àudio de Windows" Basic.Settings.Advanced.StreamDelay="Retard del directe" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Enllaçar amb" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activa el nou codi de xarxa" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode de baixa latència" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Inhabilita les tecles de drecera quan la finestra principal estigui en primer pla" +Basic.Settings.Advanced.AutoRemux="Converteix automàticament a mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(enregistra com a mkv)" Basic.AdvAudio="&Propietats avançades d'àudio" Basic.AdvAudio.Name="Nom" -Basic.AdvAudio.Volume="Volum (%)" +Basic.AdvAudio.Volume="Volum" Basic.AdvAudio.Mono="Mescla a Mono" -Basic.AdvAudio.Panning="Balanç" +Basic.AdvAudio.Balance="Balanç" Basic.AdvAudio.SyncOffset="Correcció de sincronització (ms)" Basic.AdvAudio.Monitoring="Monitorització d'àudio" Basic.AdvAudio.Monitoring.None="Monitorització desactivada" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Pistes" Basic.Settings.Hotkeys="Dreceres de teclat" Basic.Settings.Hotkeys.Pair="Combinacions de tecles compartides amb '%1' actuen com a palanques" +Basic.Settings.Hotkeys.Filter="Filtre" Basic.Hotkeys.SelectScene="Canviar a escena" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Teclat)" Hotkeys.AppleKeypadDecimal=". (Teclat)" Hotkeys.AppleKeypadEqual="= (Teclat)" Hotkeys.MouseButton="Ratolí %1" +Hotkeys.Escape="Esc" Mute="Silenci" Unmute="Treu el silenci" @@ -762,7 +824,7 @@ SceneItemHide="Amaga «%1»" OutputWarnings.NoTracksSelected="Heu de seleccionar almenys una cançó" OutputWarnings.MultiTrackRecording="Advertiment: Alguns formats (com FLV) no suporten múltiples cançons per gravació" -OutputWarnings.MP4Recording="Advertència: Els enregistraments desats en MP4 seran irrecuperables si l'arxiu no va poder finalitzar (p.ex. com a resultat de BSODs, pèrdues de potència, etc.). Si voleu enregistrar diverses pistes d'àudio utilitzi MKV i multiplexeu l'enregistrament a MP4 després que acabi (Fitxer-> Multiplexació d'enregistraments)" +OutputWarnings.MP4Recording="Advertència: els enregistraments creats en MP4/MOV no es podran recuperar si el fitxer no es pot finalitzar (p. ex. degut a un mal funcionament del sistema o interrupcions, etc.) Si voleu enregistrar diverses pistes d'àudio, considereu utilitzar el format MKV i convertir l'enregistrament a MP4/MOV després d'haver finalitzat (Fitxer → Conversió de gravació)" FinalScene.Title="Supressió de l'escena" FinalScene.Text="Cal que hi hagi almenys una escena." @@ -770,9 +832,24 @@ FinalScene.Text="Cal que hi hagi almenys una escena." NoSources.Title="Cap font" NoSources.Text="Sembla que encara no heu afegit cap font de vídeo, de manera que només es mostrarà una pantalla en blanc. Esteu segur que voleu fer això?" NoSources.Text.AddSource="Podeu afegir fonts fent clic a la icona «+» sota el quadre Fonts de la finestra principal en qualsevol moment." +NoSources.Label="No teniu cap font.\nFeu clic al botó + que hi ha a continuació \no bé feu clic aquí per afegir-ne una." ChangeBG="Estableix el color" CustomColor="Color personalitzat" BrowserSource.EnableHardwareAcceleration="Habilita l'acceleració per maquinari al navegador" +About="Quant a" +About.Info="L'OBS Studio és un programa de codi lliure i gratuït d'enregistrament de vídeo i retransmissió en directe." +About.Donate="Feu una aportació" +About.GetInvolved="Col·laboreu-hi" +About.Authors="Autoria" +About.License="Llicència" +About.Contribute="Col·laboreu amb l'OBS Project" + +ResizeOutputSizeOfSource="Redimensiona la sortida (mida de la font)" +ResizeOutputSizeOfSource.Text="La resolució base i de sortida es canviarà a la mida de la font actual." +ResizeOutputSizeOfSource.Continue="Voleu continuar?" + +PreviewTransition="Previsualitza la transició" + diff --git a/UI/data/locale/cs-CZ.ini b/UI/data/locale/cs-CZ.ini index 8ae5fd3..f0a4aca 100644 --- a/UI/data/locale/cs-CZ.ini +++ b/UI/data/locale/cs-CZ.ini @@ -8,7 +8,7 @@ Cancel="Zrušit" Close="Zavřít" Save="Uložit" Discard="Zahodit" -Disable="Vypnout" +Disable="Vypnuto" Yes="Ano" No="Ne" Add="Přidat" @@ -66,7 +66,7 @@ Import="Importovat" Export="Exportovat" Copy="Kopírovat" Paste="Vložit" -PasteReference="Vložit (jako odkaz)" +PasteReference="Vložit (jako referenci)" PasteDuplicate="Vložit (jako kopii)" RemuxRecordings="Převést nahrávky" Next="Další" @@ -80,14 +80,40 @@ StudioMode.Program="Program" ShowInMultiview="Zobrazit v Multiview" VerticalLayout="Vertikální rozložení" Group="Skupina" +DoNotShowAgain="Znovu nezobrazovat" +Default="(Výchozí)" +Calculating="Počítám..." AlreadyRunning.Title="OBS je již spuštěno" AlreadyRunning.Text="OBS již běží! Pokud jste to opravdu nechtěli udělat, tak prosím ukončete ostatní běžící instance programu OBS před spuštěním nové. Pokud máte nastavenu minimalizaci do lišty, tak se prosím podívejte, zda neběží tam." AlreadyRunning.LaunchAnyway="Spustit tak či tak" +DockCloseWarning.Title="Zavření dokovatelného okna" +DockCloseWarning.Text="Právě jste zavřeli dokovatelné okno. Pokud byste ho chtěli zobrazit znovu, tak použijte menu Zobrazit → Doky." + +Auth.Authing.Title="Přihlašování ..." +Auth.Authing.Text="Přihlašování ke službě %1 ..." +Auth.AuthFailure.Title="Přihlášení se nezdařilo" +Auth.AuthFailure.Text="Nepodařilo se nám přihlásit ke službě %1:\n\n%2: %3" +Auth.InvalidScope.Title="Vyžadováno přihlášení" +Auth.InvalidScope.Text="Požadavky pro přihlášení ke službě %1 se změnily. Některé funkce nemusí být dostupné." +Auth.LoadingChannel.Title="Načítání informací o kanálu ..." +Auth.LoadingChannel.Text="Načítání informací o kanálu ze služby %1 ..." +Auth.ChannelFailure.Title="Při načítání kanálu došlo k chybě" +Auth.ChannelFailure.Text="Informace o kanálu se pomocí služby %1 nepodařilo načíst\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informace o vysílání" +TwitchAuth.Stats="Statistiky služby Twitch" +TwitchAuth.Feed="Informační kanál služby Twitch" +TwitchAuth.TwoFactorFail.Title="Nepovedlo se získat vysílací klíč" +TwitchAuth.TwoFactorFail.Text="OBS se nemohl připojit k vašemu Twitch účtu. Zkontrolujte, zda máte nastaveno dvoufázové ověření ve vašem nastavení bezpečnosti, jelikož je to pro vysílání nutné." + Copy.Filters="Kopírovat filtry" Paste.Filters="Vložit filtry" +BrowserPanelInit.Title="Načítání prohlížeče ..." +BrowserPanelInit.Text="Vyčkejte na načtení prohlížeče ..." + BandwidthTest.Region="Oblast" BandwidthTest.Region.US="Spojené státy" BandwidthTest.Region.EU="Evropa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Asie" BandwidthTest.Region.Other="Jiná" Basic.FirstStartup.RunWizard="Chtěli byste použít průvodce nastavením? Pokud ne, nastavení můžete provést i manuálně a to po kliknutí na tlačítko Nastavení v hlavním okně." -Basic.FirstStartup.RunWizard.BetaWarning="(Poznámka: Průvodce nastavením je aktuálně v betě)" Basic.FirstStartup.RunWizard.NoClicked="Pokud změníte názor, tak můžete kdykoliv spustit průvodce z nabídky Nástrojů." Basic.AutoConfig="Průvodce nastavením" -Basic.AutoConfig.Beta="Průvodce nastavením (beta)" Basic.AutoConfig.ApplySettings="Použít" Basic.AutoConfig.StartPage="Informace o použití" Basic.AutoConfig.StartPage.SubTitle="Řekněte nám, k čemu chcete tento program používat" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 nebo 30, ale preferuji vyšší Basic.AutoConfig.VideoPage.CanvasExplanation="Poznámka: Základní rozlišení není nutně stejné jako rozlišení, ve kterém budete vysílat či nahrávat. Vaše opravdové rozlišení může být několikrát zmenšeno oproti základnímu rozlišení, aby bylo sníženo využití prostředků nebo požadavků na bitrate." Basic.AutoConfig.StreamPage="Informace o vysílání" Basic.AutoConfig.StreamPage.SubTitle="Prosím zadejte své informace o vysílání" +Basic.AutoConfig.StreamPage.ConnectAccount="Připojit účet (volitelné)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Odpojit účet" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odpojení účtu" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Tato změna proběhne okamžitě. Opravdu si přejete odpojit účet ?" +Basic.AutoConfig.StreamPage.UseStreamKey="Použít vysílací klíč" Basic.AutoConfig.StreamPage.Service="Služba" Basic.AutoConfig.StreamPage.Service.ShowAll="Zobrazit vše..." +Basic.AutoConfig.StreamPage.Service.Custom="Vlastní ..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Vysílací klíč" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Odkaz)" @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="Pro použití těchto nastavení klikn Basic.Stats="Statistika" Basic.Stats.CPUUsage="Využití CPU" -Basic.Stats.HDDSpaceAvailable="Dostupné místo na HDD" +Basic.Stats.HDDSpaceAvailable="Dostupné místo na disku" Basic.Stats.MemoryUsage="Využití paměti" Basic.Stats.AverageTimeToRender="Průměrný čas vykreslování snímku" Basic.Stats.SkippedFrames="Přeskočené snímky kvůli chybě v kódování" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Neaktivní" Basic.Stats.DroppedFrames="Ztracené snímky (síť)" Basic.Stats.MegabytesSent="Celkový datový výstup" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Disk bude plný za cca." + +ResetUIWarning.Title="Opravdu si přejete resetovat rozhraní ?" +ResetUIWarning.Text="Resetování rozhraním budou skryty přídavné doky. Pro zobrazení těchto doků je budete muset povolit v menu.\n\nOpravdu si přejete resetovat rozhraní ?" Updater.Title="Aktualizace" Updater.Text="K dispozici je nová verze:" @@ -206,6 +240,9 @@ ConfirmStart.Text="Opravdu si přejete začít vysílat ?" ConfirmStop.Title="Zastavit vysílání ?" ConfirmStop.Text="Opravdu si přejete zastavit vysílání ?" +ConfirmBWTest.Title="Spuštění testu rychlosti připojení" +ConfirmBWTest.Text="Nastavili jste OBS do režimu testování připojení. Tento režim vám umožňuje otestovat vaše připojení bez toho, abyste vysílali. Poté co skončíte s testováním jej budete muset vypnout, aby vaše vysílání viděli vaši diváci.\n\nChcete začít s testováním ?" + ConfirmExit.Title="Ukončit OBS ?" ConfirmExit.Text="Ukončením budou všechna vysílání/záznamy zastavena. Jste si jisti skončit ?" @@ -218,19 +255,24 @@ Output.StartRecordingFailed="Chyba při spouštění nahrávání" Output.StartReplayFailed="Chyba při spouštění nahrávání do paměti" Output.StartFailedGeneric="Nastala chyba při začátku nahrávání. Zkontrolujte, prosím, textový záznam pro další podrobnosti.\n\nPoznámka: Pokud používáte enkodér NVENC či AMD, zkontrolujte zda používáte aktuální verzi grafického ovladače." + Output.ConnectFail.Title="Spojení se nezdařilo" Output.ConnectFail.BadPath="Chybná cesta nebo adresa připojení. Zkontrolujte, prosím, správnost svých nastavení." Output.ConnectFail.ConnectFailed="K serveru se nepodařilo připojit" Output.ConnectFail.InvalidStream="K nastavenému kanálu či klíči nelze přistoupit. Zkontrolujte, zda je vysílací klíč správný. Pokud ano, může být problém s připojením k serveru." -Output.ConnectFail.Error="Při pokusu o připojení k serveru došlo k neočekávané chybě. Další informace v záznamovém souboru." +Output.ConnectFail.Error="Při pokusu o připojení k serveru došlo k neočekávané chybě. Další informace v záznamovém souboru." Output.ConnectFail.Disconnected="Odpojen od serveru." +Output.StreamEncodeError.Title="Chyba kodéru" +Output.StreamEncodeError.Msg="Při vysílání došlo k chybě kodéru." + Output.RecordFail.Title="Chyba při spouštění nahrávání" Output.RecordFail.Unsupported="Výstupní formát není podporovaný nebo nepodporuje více než jednu zvukovou stopu. Zkontrolujte nastavení a zkuste to znovu." Output.RecordNoSpace.Title="Nedostatek místa na disku" Output.RecordNoSpace.Msg="Pro pokračování nahrávání není dostatek místa na disku." Output.RecordError.Title="Chyba při nahrávání" Output.RecordError.Msg="Při nahrávání došlo k nespecifikované chybě." +Output.RecordError.EncodeErrorMsg="Při nahrávání došlo k chybě kodéru." Output.ReplayBuffer.NoHotkey.Title="Nepřiřazena žádná klávesová zkratka!" Output.ReplayBuffer.NoHotkey.Msg="Není nastavena žádná klávesová zkratka pro uložení záznamu. Nastavte ji prosím, abyste jej mohli ukládat." @@ -241,15 +283,12 @@ LogReturnDialog="Záznam byl úspěšně nahrán" LogReturnDialog.CopyURL="Zkopírovat" LogReturnDialog.ErrorUploadingLog="Nahrání záznamu se nezdařilo" -LicenseAgreement="Licenční smlouva" -LicenseAgreement.PleaseReview="Před použitím OBS si, prosím, přečtěte licenční podmínky. Použitím tohoto programu potvrzujete, že jste si přečetl/a a souhlasíte s podmínkami GNU General Public License v2.0. Pro zobrazení zbytku ujednání sjeďte dolů." -LicenseAgreement.ClickIAgreeToContinue="Pro pokračování klikněte na Souhlasím, pokud souhlasíte s podmínkami ujednání. Před použitím OBS je toto nutné odsouhlasit." -LicenseAgreement.IAgree="Souhlasím" -LicenseAgreement.Exit="Konec" - Remux.SourceFile="OBS nahrávka" Remux.TargetFile="Cílový soubor" Remux.Remux="Převést" +Remux.Stop="Zastavit převod" +Remux.ClearFinished="Odebrat dokončené položky" +Remux.ClearAll="Odebrat všechny položky" Remux.OBSRecording="OBS nahrávka" Remux.FinishedTitle="Převod dokončen" Remux.Finished="Nahrávka převedena" @@ -257,12 +296,13 @@ Remux.FinishedError="Nahrávka převedena, ale soubor nemusí být kompletní" Remux.SelectRecording="Vyberte OBS nahrávku …" Remux.SelectTarget="Vyberte cílový soubor …" Remux.FileExistsTitle="Cílový soubor již existuje" -Remux.FileExists="Chcete přepsat již existující cílový soubor ?" +Remux.FileExists="Následující soubory již existují, chcete je nahradit?" Remux.ExitUnfinishedTitle="Probíhá převod" Remux.ExitUnfinished="Převod nebyl dokončen, zastavení může znemožnit další použití cílového souboru.\nOpravdu chcete převod ukončit ?" +Remux.HelpText="Natáhněte soubory do tohoto okna k převodu nebo vyberte prázdné pole \"OBS nahrávka\" pro výběr souboru." UpdateAvailable="K dispozici je nová verze" -UpdateAvailable.Text="Verze %1.%2.%3 je nyní k dispozici. Stáhnout" +UpdateAvailable.Text="Verze %1.%2.%3 je nyní k dispozici. Stáhnout" Basic.DesktopDevice1="Zvuk plochy" Basic.DesktopDevice2="Zvuk plochy 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Záznam obrazovky" Basic.Main.PreviewConextMenu.Enable="Povolit náhled" -ScaleFiltering="Filtrování rozsahu" +Basic.Main.Preview.Disable="Vypnout náhled" + +ScaleFiltering="Filter škálování" ScaleFiltering.Point="Bod" ScaleFiltering.Bilinear="Bilineární" ScaleFiltering.Bicubic="Bikubický" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Oblastní" Deinterlacing="Odstranění prokladu" Deinterlacing.Discard="Zahození" @@ -420,7 +463,7 @@ Basic.MainMenu.File.Settings="Na&stavení" Basic.MainMenu.File.ShowSettingsFolder="Zobrazit složku nastavení" Basic.MainMenu.File.ShowProfileFolder="Zobrazit složku profilu" Basic.MainMenu.AlwaysOnTop="Vždy n&avrchu" -Basic.MainMenu.File.Exit="Kon&ec" +Basic.MainMenu.File.Exit="Ukončit (&X)" Basic.MainMenu.Edit="Upravit (&E)" Basic.MainMenu.Edit.Undo="Zpět (&U)" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="Překlopit s&visle" Basic.MainMenu.Edit.Transform.FitToScreen="Přizpůsobit obrazovce (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Roztáhnout na obrazovku (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="Vy¢rovat" +Basic.MainMenu.Edit.Transform.VerticalCenter="Vycentrovat svisle" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Vycentrovat vodorovně" Basic.MainMenu.Edit.Order="P&ořadí" Basic.MainMenu.Edit.Order.MoveUp="Posunout výše (&U)" Basic.MainMenu.Edit.Order.MoveDown="Posunout níže (&D)" @@ -478,7 +523,7 @@ Basic.MainMenu.Help.HelpPortal="&Portál pomoci" Basic.MainMenu.Help.Website="Navštívit &web" Basic.MainMenu.Help.Discord="Připojit se na &Discord server" Basic.MainMenu.Help.Logs="Soubory záznamu (&L)" -Basic.MainMenu.Help.Logs.ShowLogs="Zobrazit soubory záznamu (&S)" +Basic.MainMenu.Help.Logs.ShowLogs="Zobrazit &soubory záznamu" Basic.MainMenu.Help.Logs.UploadCurrentLog="Nahrát aktuální soubor záznamu (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Nahrát poslední soubor záznamu (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="Zobrazit aktuální záznam (&V)" @@ -486,6 +531,7 @@ Basic.MainMenu.Help.CheckForUpdates="Zkontrolovat aktualizace" Basic.MainMenu.Help.CrashLogs="Hlášení o pádech (&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="Zobrazit hlášení o pádech (&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Nahrát pos&lední hlášení" +Basic.MainMenu.Help.About="O &aplikaci" Basic.Settings.ProgramRestart="Pro projevení nastavení je potřeba restartovat aplikaci." Basic.Settings.ConfirmTitle="Potvrzení změn" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Systémová lišta" Basic.Settings.General.SysTrayWhenStarted="Minimalizovat do systémové lišty při spuštění" Basic.Settings.General.SystemTrayHideMinimize="Vždy minimalizovat do systémové lišty místo hlavního panelu" Basic.Settings.General.SaveProjectors="Ukládat projektory při ukončení" +Basic.Settings.General.Preview="Náhled" +Basic.Settings.General.OverflowHidden="Skrýt přetečení" +Basic.Settings.General.OverflowAlwaysVisible="Zobrazit přetečení" +Basic.Settings.General.OverflowSelectionHidden="Zobrazit přetečení, i když zdroj není viditelný" Basic.Settings.General.SwitchOnDoubleClick="Přejít na scénu po dvojitém kliknutí" Basic.Settings.General.StudioPortraitLayout="Povolit rozložení na výšku (portrét)" +Basic.Settings.General.TogglePreviewProgramLabels="Zobrazovat značky pod okny ve Studiovém módu" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Kliknutí pro přechod mezi scénami" Basic.Settings.General.Multiview.DrawSourceNames="Zobrazovat názvy scén" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontálně, Basic.Settings.Stream="Vysílání" Basic.Settings.Stream.StreamType="Typ vysílání" +Basic.Settings.Stream.Custom.UseAuthentication="Použít přihlášení" +Basic.Settings.Stream.Custom.Username="Uživatelské jméno" +Basic.Settings.Stream.Custom.Password="Heslo" +Basic.Settings.Stream.BandwidthTestMode="Zapnout režim testování připojení" Basic.Settings.Output="Výstup" Basic.Settings.Output.Format="Formát nahrávání" @@ -540,7 +595,7 @@ Basic.Settings.Output.Mode="Režim výstupu" Basic.Settings.Output.Mode.Simple="Jednoduché" Basic.Settings.Output.Mode.Adv="Rozšířené" Basic.Settings.Output.Mode.FFmpeg="Výstup FFmpeg" -Basic.Settings.Output.UseReplayBuffer="Povolit záznam od paměti" +Basic.Settings.Output.UseReplayBuffer="Povolit záznam do paměti" Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximální čas záznamu (s)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximální využití paměti (MB)" Basic.Settings.Output.ReplayBuffer.Estimate="Přibližné využití paměti: %1 MB" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Varování: Nahrávání se softwarov Basic.Settings.Output.Simple.Warn.Lossless="Varování: Při použití této kvality budou výsledné nahrávky obrovské! Při použití vysokého rozlišení a snímkování mohou využít až 7 GB diskového prostoru za minutu nahrávky. Tato kvalita není doporučena pro dlouhé nahrávky, pokud nemáte opravdu velký volný prostor na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Opravdu chcete použít tuto kvalitu ?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Varování nastavené kvality!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Varování: Není možné použit více oddělených QSV enkodérů pro streamování a nahrávání ve stejnou dobu. Pokud chcete tuto limitaci obejít, tak změňte použitý enkodér pro streamování či nahrávání." Basic.Settings.Output.Simple.Encoder.Software="Softwarový (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarový (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardwarový (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Automaticky obnovit spojení" Basic.Settings.Output.RetryDelay="Čas do pokusu (vteřiny)" Basic.Settings.Output.MaxRetries="Maximální počet pokusů" Basic.Settings.Output.Advanced="Povolit rozšířené nastavení enkodéru" -Basic.Settings.Output.EncoderPreset="Předvolba enkodéru (rychlejší = méně CPU)" +Basic.Settings.Output.EncoderPreset="Předvolba enkodéru" Basic.Settings.Output.CustomEncoderSettings="Vlastní nastavení enkodéru" Basic.Settings.Output.CustomMuxerSettings="Vlastní nastavení muxeru" Basic.Settings.Output.NoSpaceFileName="Generovat název souboru bez mezery" @@ -619,21 +673,21 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zobrazit všechny kodeky (i FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY Rok, 4 číslice\n%YY Rok, 2 poslední číslice (00-99)\n%MM Měsíc, číslo (01-12)\n%DD Den v měsíci, 2 číslice (01-31)\n%hh Hodina ve 24h formátu (00-23)\n%mm Minuta (00-59)\n%ss Vteřina (00-61)\n%% Znak %\n%a Zkratka dne v týdnu\n%A Den v týdnu\n%b Zkratka měsíce\n%B Měsíc\n%d Den v měsíci, 2 číslice (01-31)\n%H Hodina ve 24h formátu (00-23)\n%I Hodina ve 12h formátu (01-12)\n%m Měsíc, číslo (01-12)\n%M Minuta (00-59)\n%p AM / PM\n%S Vteřina (00-61)\n%y Rok, 2 poslední číslice (00-99)\n%Y Rok\n%z ISO 8601 časový posun od UTC nebo časového pásma\n - název nebo zkratka\n%Z Zkratka nebo název časového pásma\n" +FilenameFormatting.TT="%CCYY Rok, čtyři číslice\n%YY Rok, poslední dvě číslice (00-99)\n%MM Měsíc, číslem (01-12)\n%DD Den v měsíci, dvě číslice (01-31)\n%hh Hodina ve 24h formátu (00-23)\n%mm Minuta (00-59)\n%ss Vteřina (00-61)\n%% Znak %\n%a Zkrácený název dne v týdnu\n%A Název dne v týdnu\n%b Zkrácený název měsíce\n%B Název měsíce\n%d Den měsíce, dvě číslice (01-31)\n%H Hodina ve 24h formátu (00-23)\n%I Hodina ve 12h formátu (01-12)\n%m Měsíc, číslem (01-12)\n%M Minuta (00-59)\n%p AM / PM\n%S Vteřina (00-61)\n%y Rok, poslední dvě číslice (00-99)\n%Y Rok\n%z ISO 8601 posun od UTC v časové zóně\n%Z Název či zkratka časové zóny\n" Basic.Settings.Video="Obraz" -Basic.Settings.Video.Adapter="Grafická karta:" -Basic.Settings.Video.BaseResolution="Základní rozlišení:" -Basic.Settings.Video.ScaledResolution="Výstupní (škálované) rozlišení:" -Basic.Settings.Video.DownscaleFilter="Škálovací filter:" +Basic.Settings.Video.Adapter="Grafická karta" +Basic.Settings.Video.BaseResolution="Základní rozlišení" +Basic.Settings.Video.ScaledResolution="Výstupní (škálované) rozlišení" +Basic.Settings.Video.DownscaleFilter="Škálovací filter" Basic.Settings.Video.DisableAeroWindows="Zakázat Aero (pouze Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Běžné hodnoty FPS" Basic.Settings.Video.FPSInteger="Číselná hodnota FPS" Basic.Settings.Video.FPSFraction="Dílčí hodnota FPS" -Basic.Settings.Video.Numerator="Čitatel:" -Basic.Settings.Video.Denominator="Jmenovatel:" -Basic.Settings.Video.Renderer="Vykreslovač:" +Basic.Settings.Video.Numerator="Čitatel" +Basic.Settings.Video.Denominator="Jmenovatel" +Basic.Settings.Video.Renderer="Vykreslovač" Basic.Settings.Video.InvalidResolution="Chybná hodnota rozlišení. Správný formát je [width]x[height] (např. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Obrazový výstup je zapnutý. Pro změnu nastavení vypněte všechny výstupy." Basic.Settings.Video.DisableAero="Zakázat Aero" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Ostré při škálování Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Vzorkovací frekvence" Basic.Settings.Audio.Channels="Kanály" -Basic.Settings.Audio.MeterDecayRate="Rychlost útlumu snímače zvuku" +Basic.Settings.Audio.Meters="Měřiče" +Basic.Settings.Audio.MeterDecayRate="Rychlost rozpadu" Basic.Settings.Audio.MeterDecayRate.Fast="Rychle" Basic.Settings.Audio.MeterDecayRate.Medium="Střední (typ I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Pomalu (typ II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROVÁNÍ: Prostorový zvuk j Basic.Settings.Audio.MultichannelWarning="Předtím než začnete vysílat si zkontrolujte, zda vaše vysílací služba podporuje příjem a přehrávání prostorového zvuku. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast jsou příklady služeb, které jej plně podporují. I když Facebook Live a YouTube Live oba podporují příjem prostorového zvuku, Facebook Live jej převede na stereo a YouTube Live přehrává pouze dva kanály.\n\nOBS filtry zvuku jej plně podporují, ale podpora u pluginu VST není garantována." Basic.Settings.Audio.MultichannelWarning.Title="Povolit prostorový zvuk?" Basic.Settings.Audio.MultichannelWarning.Confirm="Jste si jisti, že chcete povolit prostorový zvuk?" -Basic.Settings.Audio.DesktopDevice="Zařízení zvuku plochy" -Basic.Settings.Audio.DesktopDevice2="Zařízení zvuku plochy 2" -Basic.Settings.Audio.AuxDevice="Zvukové zařízení - mikrofon/AUX" -Basic.Settings.Audio.AuxDevice2="Zvukové zařízení - mikrofon/AUX 2" -Basic.Settings.Audio.AuxDevice3="Zvukové zařízení - mikrofon/AUX 3" +Basic.Settings.Audio.Devices="Zařízení" +Basic.Settings.Audio.DesktopDevice="Zvuk plochy" +Basic.Settings.Audio.DesktopDevice2="Zvuk plochy 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/AUX" +Basic.Settings.Audio.AuxDevice2="Mikrofon/AUX 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/AUX 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/AUX 4" Basic.Settings.Audio.EnablePushToMute="Povolit Ztlumit podržením" Basic.Settings.Audio.PushToMuteDelay="Zpoždění" Basic.Settings.Audio.EnablePushToTalk="Povolit Naslouchat podržením" Basic.Settings.Audio.PushToTalkDelay="Zpoždění" Basic.Settings.Audio.UnknownAudioDevice="[Zařízení není připojeno nebo není k dispozici]" +Basic.Settings.Audio.Disabled="Vypnuto" Basic.Settings.Advanced="Rozšířené" Basic.Settings.Advanced.General.ProcessPriority="Priorita procesu" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Nečinný" Basic.Settings.Advanced.FormatWarning="Varování: Jiné formáty barev než je NV12 jsou primárně určeny pro nahrávání a neměly by být použity pro vysílání. Použití při vysílání zvýší využití CPU." Basic.Settings.Advanced.Audio.BufferingTime="Čas vyrovnávací paměti zvuku" Basic.Settings.Advanced.Video.ColorFormat="Formát barev" -Basic.Settings.Advanced.Video.ColorSpace="Barevný prostor YUV" -Basic.Settings.Advanced.Video.ColorRange="Oblast barev YUV" +Basic.Settings.Advanced.Video.ColorSpace="Barevný prostor" +Basic.Settings.Advanced.Video.ColorRange="Rozsah barev" Basic.Settings.Advanced.Video.ColorRange.Partial="Částečné" Basic.Settings.Advanced.Video.ColorRange.Full="Plné" -Basic.Settings.Advanced.Audio.MonitoringDevice="Zařízení pro monitorování zvuku" +Basic.Settings.Advanced.Audio.MonitoringDevice="Sledovací zařízení" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Výchozí" Basic.Settings.Advanced.Audio.DisableAudioDucking="Zakázat Windows výchozí utlumování zvuku" Basic.Settings.Advanced.StreamDelay="Zpoždění vysílání" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Svázat s adresou" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Použít nový síťový kód" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Režim nízké odezvy" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Zakázat klávesové zkratky, když je hlavní okno aktivní" +Basic.Settings.Advanced.AutoRemux="Automaticky převést do mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(nahrávat jako mkv)" Basic.AdvAudio="Rozšířené vlastnosti zvuku" Basic.AdvAudio.Name="Název" -Basic.AdvAudio.Volume="Hlasitost (%)" +Basic.AdvAudio.Volume="Hlasitost" Basic.AdvAudio.Mono="Převést na Mono" -Basic.AdvAudio.Panning="Pozicování" +Basic.AdvAudio.Balance="Vyvážení" Basic.AdvAudio.SyncOffset="Zpoždění synchronizace (ms)" Basic.AdvAudio.Monitoring="Monitorování zvuku" Basic.AdvAudio.Monitoring.None="Monitorování vypnuto" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Stopy" Basic.Settings.Hotkeys="Zkratky" Basic.Settings.Hotkeys.Pair="Kombinace kláves je sdílená s '%1' funguje jako přepínač" +Basic.Settings.Hotkeys.Filter="Filtrovat" Basic.Hotkeys.SelectScene="Přepnout na scénu" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Číselník)" Hotkeys.AppleKeypadDecimal=", (Číselník)" Hotkeys.AppleKeypadEqual="= (Číselník)" Hotkeys.MouseButton="Myš %1" +Hotkeys.Escape="Esc" Mute="Ztlumit" Unmute="Odtlumit" @@ -762,7 +824,7 @@ SceneItemHide="Skrýt '%1'" OutputWarnings.NoTracksSelected="Musíte vybrat alespoň jednu stopu" OutputWarnings.MultiTrackRecording="Varování: Některé formáty (např. FLV) nepodporují více zvukových stop na nahrávku" -OutputWarnings.MP4Recording="Varování: Nahrávky uložené v MP4 nebude možné obnovit, pokud soubor nemohl být dokončen (např. po BSOD, výpadku napájení atp.). Pokud chcete nahrávat více zvukových stop, promyslete použití MKV a poté převodení do MP4 (Soubor -> Převést nahrávky)" +OutputWarnings.MP4Recording="Varování: Nahrávky uložené v MP4/MOV nebude možné obnovit, pokud soubor nemohl být dokončen (např. po BSOD, výpadku napájení atp.). Pokud chcete nahrávat více zvukových stop, promyslete použití MKV a poté převedení do MP4/MOV (Soubor → Převést nahrávky)" FinalScene.Title="Odstranění scény" FinalScene.Text="Musí existovat alespoň jedna scéna, proto tuto není možno odstranit." @@ -770,9 +832,24 @@ FinalScene.Text="Musí existovat alespoň jedna scéna, proto tuto není možno NoSources.Title="Žádné zdroje" NoSources.Text="Vypadá to, že jste zatím nepřidali žádné zdroje obrazu, takže budete vysílat černou obrazovku. Opravdu chcete pokračovat ?" NoSources.Text.AddSource="Zdroje můžete kdykoliv přidat tlačítkem + pod seznamem Zdroje v hlavním okně." +NoSources.Label="Nepřidali jste žádné zdroj.\nKlikněte na tlačítko + níže, nebo klikněte zde pravým tlačítkem, pro přidání nového zdroje." ChangeBG="Nastavit barvu" CustomColor="Vlastní barva" BrowserSource.EnableHardwareAcceleration="Zapnout hardwarovou akceleraci pro zdroj prohlížeče" +About="O aplikaci" +About.Info="OBS je otevřený software pro nahrávání videa a živé vysílání." +About.Donate="Přispět" +About.GetInvolved="Zapojte se" +About.Authors="Autoři" +About.License="Licence" +About.Contribute="Podpořit projekt OBS" + +ResizeOutputSizeOfSource="Změnit velikost výstupu (velikost zdroje)" +ResizeOutputSizeOfSource.Text="Základní a výstupní rozlišení budou změněna na velikost aktuálního zdroje." +ResizeOutputSizeOfSource.Continue="Chcete pokračovat ?" + +PreviewTransition="Náhled přechodu" + diff --git a/UI/data/locale/da-DK.ini b/UI/data/locale/da-DK.ini index 615dcd9..5460cfa 100644 --- a/UI/data/locale/da-DK.ini +++ b/UI/data/locale/da-DK.ini @@ -24,34 +24,34 @@ Display="Skærm" Name="Navn" Exit="Afslut" Mixer="Mixer" -Browse="Browse" +Browse="Gennemse" Mono="Mono" Stereo="Stereo" -DroppedFrames="Tabte frames %1 (%2%)" +DroppedFrames="Tabte billeder (frames) %1 (%2%)" StudioProgramProjector="Fuldskærmsprojektering (program)" PreviewProjector="Fuldskærmsprojektering (forhåndsvisning)" SceneProjector="Fuldskærmsprojektering (scene)" SourceProjector="Fuldskærmsprojektering (kilde)" StudioProgramWindow="Vinduesprojektering (program)" PreviewWindow="Vinduesprojektering (forhåndsvisning)" -SceneWindow="Vinduesprojektering (Scene)" +SceneWindow="Vinduesprojektering (scene)" SourceWindow="Vinduesprojektering (kilde)" -MultiviewProjector="Multi View (fuldskærm)" -MultiviewWindowed="Multi View (i vindue)" +MultiviewProjector="Multiview (fuldskærm)" +MultiviewWindowed="Multiview (i vindue)" Clear="Ryd" -Revert="Gendan" +Revert="Tilbagefør" Show="Vis" Hide="Skjul" UnhideAll="Vis alle" Untitled="Ikke-navngivet" New="Ny" -Duplicate="Dupliker" -Enable="Slå til" -DisableOSXVSync="Deaktiver OSX V-Sync" +Duplicate="Dublere" +Enable="Aktivér" +DisableOSXVSync="Deaktivér OSX V-Sync" ResetOSXVSyncOnExit="Nulstil OSX V-Sync ved afslutning" -HighResourceUsage="Encoding overbelastet! Overvej at skrue ned for videoindstillingerne eller brug et hurtigere encoding forvalg." -Transition="Overgange" -QuickTransitions="Hurtig overgange" +HighResourceUsage="Encodingproces overbelastet! Overvej at reducere videoressourceforbruget eller benytte et hurtigere encoding-forvalg." +Transition="Overgang" +QuickTransitions="Hurtige overgange" Left="Venstre" Right="Højre" Top="Top" @@ -60,7 +60,7 @@ Reset="Nulstil" Hours="Timer" Minutes="Minutter" Seconds="Sekunder" -Deprecated="Ophørt" +Deprecated="Forældet" ReplayBuffer="Genafspilningsbuffer" Import="Importér" Export="Eksportér" @@ -68,7 +68,7 @@ Copy="Kopiér" Paste="Indsæt" PasteReference="Indsæt (reference)" PasteDuplicate="Indsæt (dublet)" -RemuxRecordings="Remux-optagelser" +RemuxRecordings="Remux optagelser" Next="Næste" Back="Tilbage" Defaults="Standardindstillinger" @@ -77,216 +77,259 @@ TransitionOverride="Tilsidesæt overgang" None="Ingen" StudioMode.Preview="Forhåndsvisning" StudioMode.Program="Program" -ShowInMultiview="Vis i Multi View" +ShowInMultiview="Vis i Multiview" VerticalLayout="Lodret layout" Group="Gruppér" +DoNotShowAgain="Vis ikke igen" +Default="(Standard)" +Calculating="Beregner..." AlreadyRunning.Title="OBS kører allerede" -AlreadyRunning.Text="OBS kører allerede! Medmindre dette er tilsigtet, så bedes du lukke enhver eksisterende OBS-proces, inden du forsøger at køre en ny. Hvis du har OBS indstillet til at minimeres sig til systembakken, så tjek venligst om den stadig kører dér." +AlreadyRunning.Text="OBS kører allerede! Medmindre dette er tilsigtet, så bør du lukke enhver eksisterende OBS-proces, inden du forsøger at køre en ny. Hvis du har OBS opsat til at minimeres sig til systembakken, så tjek om den stadig kører dér." AlreadyRunning.LaunchAnyway="Start alligevel" -Copy.Filters="Kopieringsfiltre" -Paste.Filters="Indsætningsfiltre" +DockCloseWarning.Title="Lukker dokbart vindue" +DockCloseWarning.Text="Du har netop lukket et dokbart vindue. Hvis du vil vise det igen, skal du benytte menuen Vis → Doks på menulinjen." + +Auth.Authing.Title="Godkender..." +Auth.Authing.Text="Godkender med %1, afvent venligst..." +Auth.AuthFailure.Title="Godkendelsesfejl" +Auth.AuthFailure.Text="Mislykkedes at godkende med %1:\n\n%2: %3" +Auth.InvalidScope.Title="Godkendelse nødvendig" +Auth.InvalidScope.Text="Godkendelseskrav for %1 er ændret. Visse funktioner er muligvis ikke tilgængelige." +Auth.LoadingChannel.Title="Indlæser kanalinformation..." +Auth.LoadingChannel.Text="Indlæser kanalinformation for %1, afvent venligst..." +Auth.ChannelFailure.Title="Mislykkedes at indlæse kanal" +Auth.ChannelFailure.Text="Mislykkedes at indlæse kanalinformation for %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Streaminformation" +TwitchAuth.Stats="Twitch-statistikker" +TwitchAuth.Feed="Twitch-aktivitetsfeed" +TwitchAuth.TwoFactorFail.Title="Stream-nøgle kunne ikke forespørges" +TwitchAuth.TwoFactorFail.Text="OBS kunne ikke forbinde til din Twitch-konto. Tjek, at tofaktorgodkendelse er opsat i dine Twitch-sikkerhedsindstillinger, da dette er nødvendigt for at streame." + +Copy.Filters="Kopiér filtre" +Paste.Filters="Indsæt filtre" + +BrowserPanelInit.Title="Initialiserer browser..." +BrowserPanelInit.Text="Initialiserer browser, afvent venligst..." BandwidthTest.Region="Region" BandwidthTest.Region.US="USA" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asien" -BandwidthTest.Region.Other="Andet" +BandwidthTest.Region.Other="Anden" -Basic.FirstStartup.RunWizard="Ønsker du at køre autokonfigurationsguiden? Du kan også konfigurere dine indstillinger manuelt, ved at klikke på knappen Indstillinger i hovedvinduet." -Basic.FirstStartup.RunWizard.BetaWarning="(Bemærk: Autokonfigurationsguiden er i øjeblikket i beta)" -Basic.FirstStartup.RunWizard.NoClicked="Skifter du mening, så kan du altid køre autokonfigurationsguiden igen fra menuen Værktøjer." +Basic.FirstStartup.RunWizard="Vil du at køre auto-opsætningsguiden? Du kan også opsætte dine indstillinger manuelt ved at klikke på knappen Indstillinger i hovedvinduet." +Basic.FirstStartup.RunWizard.NoClicked="Skifter du mening, så kan du altid køre auto-opsætningsguiden igen fra menuen Værktøjer." -Basic.AutoConfig="Autokonfigurationsguide" -Basic.AutoConfig.Beta="Autokonfigurationsguide (beta)" -Basic.AutoConfig.ApplySettings="Anvend indstillinger" +Basic.AutoConfig="Auto-opsætningsguide" +Basic.AutoConfig.ApplySettings="Effektuér indstillinger" Basic.AutoConfig.StartPage="Brugsoplysninger" -Basic.AutoConfig.StartPage.SubTitle="Vælg hvad du ønsker at bruge programmet til" +Basic.AutoConfig.StartPage.SubTitle="Angiv, hvad du vil benytte programmet til" Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimér til streaming, sekundært til optagelse" Basic.AutoConfig.StartPage.PrioritizeRecording="Optimér kun til optagelse, jeg vil ikke foretage streaming" Basic.AutoConfig.VideoPage="Videoindstillinger" Basic.AutoConfig.VideoPage.SubTitle="Angiv de videoindstillinger du gerne vil benytte" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Brug aktuel (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Benyt aktuelle (%1x%2)" Basic.AutoConfig.VideoPage.BaseResolution.Display="Skærm %1 (%2x%3)" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="Brug aktuel (%1)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Benyt aktuelle (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Enten 60 eller 30, men foretræk 60 når muligt" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Enten 60 eller 30, men foretræk høj opløsning" -Basic.AutoConfig.VideoPage.CanvasExplanation="Bemærk: Lærredets (basis) opløsning er ikke nødvendigvis identisk med den opløsning, du vil streame med eller optage i. Din aktuelle stream-/optagelsesopløsning kan blive nedskaleret fra lærredsopløsningen for at reducere ressourceforbrug eller krav til bithastigheden." +Basic.AutoConfig.VideoPage.CanvasExplanation="Bemærk: Lærredets (basis-) opløsning er ikke nødvendigvis identisk med den opløsning, du vil streame med eller optage i. Din aktuelle stream-/optagelsesopløsning kan blive nedskaleret fra lærredsopløsningen for at reducere ressourceforbrug eller bit-hastighedskrav." Basic.AutoConfig.StreamPage="Streamoplysninger" -Basic.AutoConfig.StreamPage.SubTitle="Indtast venligst dine stream oplysninger" -Basic.AutoConfig.StreamPage.Service="Service" +Basic.AutoConfig.StreamPage.SubTitle="Angiv dine streamoplysninger" +Basic.AutoConfig.StreamPage.ConnectAccount="Forbind konto (valfrit)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Afbryd konto" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Afbryde konto?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Denne ændring effektueres straks. Sikker på, at du vil afbryde din konto?" +Basic.AutoConfig.StreamPage.UseStreamKey="Benyt Streamnøgle" +Basic.AutoConfig.StreamPage.Service="Tjeneste" Basic.AutoConfig.StreamPage.Service.ShowAll="Vis alle..." +Basic.AutoConfig.StreamPage.Service.Custom="Tilpasset..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Streamnøgle" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(link)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="Anslå bitrate med en båndbreddetest (kan tage et par minutter)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimér bit-hastigheden vha. en båndbreddetest (kan tage et par minutter)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Foretræk hardwarekodning" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardware kodning fjerne det meste CPU brug, men kan kræve højere bitrate for at opnå samme kvalitetsniveau." +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardwarekodning fjerner det meste CPU-forbrug, men kan kræve højere bit-hastighed for at opnå samme kvalitetsniveau." Basic.AutoConfig.StreamPage.StreamWarning.Title="Streamadvarsel" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Båndbreddetesten er ved at streame tilfældige videodata uden lyd til din kanal. Hvis du har mulighed for det, anbefales det at du midlertidigt fravælger at gemme streams og marker streamen som privat til testen er færdig. Fortsæt?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Båndbreddetesten er ved at streame tilfældige videodata uden lyd til din kanal. Det anbefales, hvis muligheden foreligger, midlertidigt at fravælger at gemme streams samt at angive streamen som privat indtil testen er fuldført. Fortsæt?" Basic.AutoConfig.TestPage="Endelige resultater" Basic.AutoConfig.TestPage.SubTitle.Testing="Programmet udfører nu en række tests for at estimere de bedste indstillinger" -Basic.AutoConfig.TestPage.SubTitle.Complete="Testen er færdig" -Basic.AutoConfig.TestPage.TestingBandwidth="Foretager båndbreddetest, dette kan tage et par minutter..." +Basic.AutoConfig.TestPage.SubTitle.Complete="Testning fuldført" +Basic.AutoConfig.TestPage.TestingBandwidth="Udfører båndbreddetest, kan tage nogle få minutter..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Forbinder til: %1..." -Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Kunne ikke forbinde til nogen servere, kontroller venligst din internetforbindelse og prøv igen." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Mislykkedes at forbinde til nogen servere. Tjek din Internetforbindelse og forsøg igen." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Tester båndbredde for: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="Tester streamkodning, dette kan tage et øjeblik..." -Basic.AutoConfig.TestPage.TestingRecordingEncoder="Tester optagelseskodning, dette kan tage et øjeblik..." +Basic.AutoConfig.TestPage.TestingStreamEncoder="Tester stream-encoder, dette kan tage et øjeblik..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Tester optagelses-encoder, dette kan tage et øjeblik..." Basic.AutoConfig.TestPage.TestingRes="Tester opløsninger, dette kan tage et par minutter..." -Basic.AutoConfig.TestPage.TestingRes.Fail="Kunne ikke starte kodning" +Basic.AutoConfig.TestPage.TestingRes.Fail="Mislykkedes at starte encoder" Basic.AutoConfig.TestPage.TestingRes.Resolution="Tester %1x%2 %3 FPS..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streamkodning" -Basic.AutoConfig.TestPage.Result.RecordingEncoder="Optagelseskodning" -Basic.AutoConfig.TestPage.Result.Header="Programmet har bestemt, at disse anslåede indstillinger er de mest ideelle for dig:" -Basic.AutoConfig.TestPage.Result.Footer="Klik på Anvend indstillinger for at benytte denne opsætning. Klik på Tilbage for at genopsætte guiden og forsøge igen. For at opsætte manuelt skal du klikke på Annullér og åbne Indstillinger." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streaming-encoder" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Optagelses-encoder" +Basic.AutoConfig.TestPage.Result.Header="Programmet har fastslået, at disse estimerede indstillinger er de mest idéelle for dig:" +Basic.AutoConfig.TestPage.Result.Footer="Klik på Anvend indstillinger for at benytte denne opsætning. Klik på Tilbage for at genopsætte guiden og forsøge igen. For at opsætte manuelt, så klik på Annullér og åbn Indstillinger." Basic.Stats="Statistikker" Basic.Stats.CPUUsage="CPU-forbrug" -Basic.Stats.HDDSpaceAvailable="Harddiskplads tilgængelig" +Basic.Stats.HDDSpaceAvailable="Tilgængelig diskplads" Basic.Stats.MemoryUsage="Hukommelsesforbrug" -Basic.Stats.AverageTimeToRender="Gennemsnitstid for frame-rendering" -Basic.Stats.SkippedFrames="Oversprang frames grundet kodningsforsinkelse" -Basic.Stats.MissedFrames="Gået glip af frames grundet renderingsforsinkelse" +Basic.Stats.AverageTimeToRender="Gennemsnitstid for billedrendering" +Basic.Stats.SkippedFrames="Oversprang billeder grundet kodningsforsinkelse" +Basic.Stats.MissedFrames="Billeder tabt grundet renderingsforsinkelse" Basic.Stats.Output.Stream="Stream" Basic.Stats.Output.Recording="Optagelse" Basic.Stats.Status="Status" Basic.Stats.Status.Recording="Optagelse" Basic.Stats.Status.Live="LIVE" -Basic.Stats.Status.Reconnecting="Forsøger at oprette forbindelse igen" +Basic.Stats.Status.Reconnecting="Genopretter forbindelse" Basic.Stats.Status.Inactive="Inaktiv" -Basic.Stats.DroppedFrames="Tabte frames (netværk)" -Basic.Stats.MegabytesSent="Samlede Data Output" -Basic.Stats.Bitrate="Bithastighed" +Basic.Stats.DroppedFrames="Tabte billeder (netværk)" +Basic.Stats.MegabytesSent="Samlet Dataoutput" +Basic.Stats.Bitrate="Bit-hastighed" +Basic.Stats.DiskFullIn="Disk fuld om (ca.)" + +ResetUIWarning.Title="Sikker på, at du vil nulstille UI'en?" +ResetUIWarning.Text="Nulstilling af UI'en vil skjule ekstra dok'er. Du skal synliggøre disse dok'er i visningsmenuen, hvis du ønsker at se dem.\n\nSikker på, at du vil nulstille UI'en?" Updater.Title="Ny opdatering tilgængelig" Updater.Text="Der er en ny opdatering tilgængelig:" -Updater.UpdateNow="Opdater nu" +Updater.UpdateNow="Opdatér nu" Updater.RemindMeLater="Påmind mig senere" -Updater.Skip="Spring versionen over" -Updater.Running.Title="Program er aktivt i øjeblikket" -Updater.Running.Text="Outputs er aktive i øjeblikket. Luk venligst alle aktive outputs før forsøg på opdatering" +Updater.Skip="Overspring version" +Updater.Running.Title="Program pt. aktivt" +Updater.Running.Text="Outputs er pt. aktive. Luk alle aktive outputs inden forsøg på opdatering" Updater.NoUpdatesAvailable.Title="Ingen opdateringer tilgængelige" -Updater.NoUpdatesAvailable.Text="Ingen opdateringer er tilgængelige i øjeblikket" -Updater.FailedToLaunch="Kunne ikke starte opdatering" -Updater.GameCaptureActive.Title="Spil capture aktiv" -Updater.GameCaptureActive.Text="Spil capture fangstbibliotek er i brug i øjeblikket. Luk venligst alle spil/programmer der bliver captured (eller genstart windows) og prøv igen." +Updater.NoUpdatesAvailable.Text="Ingen opdateringer er pt. tilgængelige" +Updater.FailedToLaunch="Mislykkedes at starte opdatering" +Updater.GameCaptureActive.Title="Spiloptagelse aktiv" +Updater.GameCaptureActive.Text="Spiloptagelses hook-bibliotek er pt. i brug. Luk alle spil/programmer som optages (eller genstart Windows) og forsøg igen." -QuickTransitions.SwapScenes="Byt om på forhåndsvisning/output scener efter overgang" -QuickTransitions.SwapScenesTT="Ombytter uddrag- og output-scener efter omskiftning (hvis oprindelige output-scene stadig eksisterer).\nDette vil ikke omgøre eventuelle ændringer, der måtte været udført på den oprindelige output-scene." -QuickTransitions.DuplicateScene="Dupliker scene" -QuickTransitions.DuplicateSceneTT="Muliggør, ved redigere af den samme, scene, redigering af transformering/synlighed af kilder uden at ændre på output. \nFor at rediger egenskaber for kilder uden at ændre på output, aktivér 'Duplikér Kilder'.\nÆndring af denne værd vil nulstille den nuværende output-scene (hvis den stadig findes)." -QuickTransitions.EditProperties="Dupliker kilder" -QuickTransitions.EditPropertiesTT="Muliggør, ved redigering af den samme scene, redigering af egenskaber for kilder uden at ændre på output.\nDette kan kun benyttes, hvis 'Duplikér Scene' er aktiv. \nVisse kilder (såsom optagne kilder eller mediekilder) understøtter ikke dette og kan ikke redigeres separat.\nÆndring af denne værdi vil nulstille den nuværende output-scene (hvis den stadig findes).\n\nAdvarsel: Da kilder vil blive duplikeret, kan dette kræve ekstra system- eller videoressourcer." +QuickTransitions.SwapScenes="Ombyt forhåndsvisnings-/outputscener efter overgang" +QuickTransitions.SwapScenesTT="Ombytter forhåndsvisnings- og outputscener efter omskiftning (hvis oprindelige outputscene stadig eksisterer).\nDette vil ikke omgøre eventuelle ændringer, som måtte været udført på det oprindelige outputs scene." +QuickTransitions.DuplicateScene="Dublér scene" +QuickTransitions.DuplicateSceneTT="Muliggør, ved redigering af den samme scene, redigering af transformering/synlighed af kilder uden at ændre på output.\nFor at redigere egenskaber for kilder uden at ændre på output, aktivér 'Dublér Kilder'.\nÆndring af denne værd vil nulstille den nuværende outputscene (hvis den stadig findes)." +QuickTransitions.EditProperties="Dublér kilder" +QuickTransitions.EditPropertiesTT="Muliggør, ved redigering af den samme scene, redigering af egenskaber for kilder uden at ændre på output.\nDette kan kun benyttes, hvis 'Dublér Scene' er aktiv.\nVisse kilder (såsom optagne kilder eller mediekilder) understøtter ikke dette og kan ikke redigeres separat.\nÆndring af denne værdi vil nulstille den nuværende outputscene (hvis den stadig findes).\n\nAdvarsel: Da kilder vil blive duubleret, kan dette kræve ekstra system- eller videoressourcer." QuickTransitions.HotkeyName="Hurtig overgang: %1" -Basic.AddTransition="Tilføj konfigurerbar overgang" -Basic.RemoveTransition="Fjern konfigurerbar overgang" +Basic.AddTransition="Tilføj opsætbar overgang" +Basic.RemoveTransition="Fjern opsætbar overgang" Basic.TransitionProperties="Overgangsegenskaber" -Basic.SceneTransitions="Scene overgange" +Basic.SceneTransitions="Sceneovergange" Basic.TransitionDuration="Varighed" -Basic.TogglePreviewProgramMode="Studio tilstand" +Basic.TogglePreviewProgramMode="Studiotilstand" -TransitionNameDlg.Text="Indtast venligst navnet på overgangen" +TransitionNameDlg.Text="Angiv navnet på overgangen" TransitionNameDlg.Title="Overgangsnavn" TitleBar.Profile="Profil" TitleBar.Scenes="Scener" -NameExists.Title="Navnet findes allerede" -NameExists.Text="Navnet er allerede i brug." +NameExists.Title="Navn findes allerede" +NameExists.Text="Navnet benyttes allerede." -NoNameEntered.Title="Indtast venligst et gyldigt navn" -NoNameEntered.Text="Du kan ikke bruge tomme navne." +NoNameEntered.Title="Angiv et gyldigt navn" +NoNameEntered.Text="Navn er obligatorisk." ConfirmStart.Title="Start stream?" -ConfirmStart.Text="Er du sikker på at du ønsker at starte streamen?" +ConfirmStart.Text="Sikker på, at du vil starte streamen?" ConfirmStop.Title="Stop stream?" -ConfirmStop.Text="Er du sikker på at du ønsker at stoppe streamen?" +ConfirmStop.Text="Sikker på, at du vil stoppe streamen?" -ConfirmExit.Title="Forlad OBS?" -ConfirmExit.Text="OBS er aktiv i øjeblikket. Alle streams/optagelser vil blive lukket ned. Er du sikker på at du ønsker at afslutte?" +ConfirmBWTest.Title="Start båndbreddetest?" +ConfirmBWTest.Text="Du har OBS opsat i tilstanden båndbreddetest. Denne tilstand muliggør netværksaftestning, uden at din kanal er online. Når aftestningen er gennemført, så deaktivér tilstanden, så seerne vil kunne se din stream.\n\nVil du fortsætte?" -ConfirmRemove.Title="Bekræfte fjern" -ConfirmRemove.Text="Er du sikker på du ønsker at fjerne '$1'?" -ConfirmRemove.TextMultiple="Er du sikker på at du vil fjerne %1 elementer?" +ConfirmExit.Title="Afslut OBS?" +ConfirmExit.Text="OBS er pt. aktiv. Alle streams/optagelser vil blive afsluttet. Sikker på, at du vil afslutte?" -Output.StartStreamFailed="Kunne ikke starte streaming" -Output.StartRecordingFailed="Kunne ikke begynde optagelsen" -Output.StartReplayFailed="Kunne ikke starte replay buffer" -Output.StartFailedGeneric="Start af output mislykkedes. Kontroller venligst loggen for oplysninger.\n\nBemærk: Hvis du bruger NVENC eller AMD encoder, så sørg for at dine video drivere er opdateret." +ConfirmRemove.Title="Bekræft Fjern" +ConfirmRemove.Text="Sikker på, at du vil fjerne '$1'?" +ConfirmRemove.TextMultiple="Sikker på, at du vil fjerne %1 emner?" -Output.ConnectFail.Title="Kunne ikke oprette forbindelse" -Output.ConnectFail.BadPath="Ugyldig sti eller forbindelses URL. Kontroller indstillinger for at bekræfte, at de er gyldige." -Output.ConnectFail.ConnectFailed="Kunne ikke forbinde til server" -Output.ConnectFail.InvalidStream="Kunne ikke tilgå den angivne kanel eller streamnøgle, kontroller venligst din streamnøgle. Hvis den er korrekt kan der være problemer med at forbinde til serveren." -Output.ConnectFail.Error="Der opstod en uventet fejl, da du forsøgte at oprette forbindelse til serveren. Du kan finde flere oplysninger i logfilen." +Output.StartStreamFailed="Mislykkedes at starte streaming" +Output.StartRecordingFailed="Mislykkedes at starte optagelse" +Output.StartReplayFailed="Mislykkedes at starte genafspilnings-buffer" +Output.StartFailedGeneric="Start af output mislykkedes. Tjek loggen for oplysninger.\n\nBemærk: Benytter du NVENC- eller AMD-encodere, så sørg for at dine videodrivere er opdaterede." + + +Output.ConnectFail.Title="Mislykkedes at forbinde" +Output.ConnectFail.BadPath="Ugyldig sti eller forbindelses-URL. Tjek dine indstillinger for at bekræfte, at de er gyldige." +Output.ConnectFail.ConnectFailed="Mislykkedes at forbinde til server" +Output.ConnectFail.InvalidStream="Kunne ikke tilgå den angivne kanel eller streamnøgle. Tjek din streamnøgle. Er den korrekt, kan der være et problemer med at forbinde til serveren." +Output.ConnectFail.Error="En uventet fejl opstod, under forsøgtet på at forbinde til serveren. Se yderligere info i logfilen." Output.ConnectFail.Disconnected="Afbrudt fra serveren." -Output.RecordFail.Title="Kunne ikke begynde optagelsen" -Output.RecordFail.Unsupported="Outputformatet er enten ikke understøttet eller understøtter ikke mere end ét lydspor. Tjek venligst dine indstillinger og prøv igen." +Output.StreamEncodeError.Title="Kodningsfejl" +Output.StreamEncodeError.Msg="En kodningsfejl opstod under streamingen." + +Output.RecordFail.Title="Mislykkedes at starte optagelse" +Output.RecordFail.Unsupported="Outputformatet er enten uunderstøttet eller understøtter ikke flere end ét lydspor. Tjek dine indstillinger og forsøg igen." Output.RecordNoSpace.Title="Utilstrækkelig diskplads" -Output.RecordNoSpace.Msg="Der er ikke tilstrækkelig diskplads til at fortsætte optagelsen." +Output.RecordNoSpace.Msg="Utilstrækkelig diskplads til at fortsætte optagelse." Output.RecordError.Title="Optagelsesfejl" -Output.RecordError.Msg="Der opstod en uangivet fejl under optagelsen." -Output.ReplayBuffer.NoHotkey.Title="Ingen genvejstast sat!" -Output.ReplayBuffer.NoHotkey.Msg="Ingen Gem-genvejstast sat til genafspilningsbuffer. Sæt venligst \"Gem\"-genvejstasten til brug for at gemme genafspilningsoptagelser." +Output.RecordError.Msg="En uspecificeret fejl opstod under optagelse." +Output.RecordError.EncodeErrorMsg="En kodningsfejl opstod under optagelsen." +Output.ReplayBuffer.NoHotkey.Title="Ingen genvejstast opsat!" +Output.ReplayBuffer.NoHotkey.Msg="Ingen Gem-genvejstast opsat til genafspilnings-buffer. Opsæt en \"Gem\"-genvejstast til brug for at gemme genafspilningsoptagelser." -Output.BadPath.Title="Dårlig filsti" -Output.BadPath.Text="Den konfigureret output sti er ugyldig. Kontroller indstillinger for at bekræfte, at en gyldig filsti er angivet." +Output.BadPath.Title="Ugyldig filsti" +Output.BadPath.Text="Den opsatte filoutputsti er ugyldig, så tjek at en gyldig er opsat i Indstillinger." -LogReturnDialog="Log upload vellykket" -LogReturnDialog.CopyURL="Kopier URL" -LogReturnDialog.ErrorUploadingLog="Fejl ved at uploading af log fil" +LogReturnDialog="Log er uploadet" +LogReturnDialog.CopyURL="Kopiér URL" +LogReturnDialog.ErrorUploadingLog="Fejl under upload af logfil" -LicenseAgreement="Licensaftale" -LicenseAgreement.PleaseReview="Venligst gennemse licensbetingelserne før du bruger OBS. Ved brug af dette program, accepterer du at du har læst og accepterer betingelserne af GNU General Public License v2.0. Venligst scroll ned for at se resten af aftalen." -LicenseAgreement.ClickIAgreeToContinue="Hvis du accepterer betingelserne i aftalen, skal du klikke på Jeg er enig for at fortsætte. Du skal acceptere aftalen at bruge OBS." -LicenseAgreement.IAgree="Jeg er enig" -LicenseAgreement.Exit="Afslut" - -Remux.SourceFile="OBS optagelse" +Remux.SourceFile="OBS-optagelse" Remux.TargetFile="Destinationsfil" Remux.Remux="Remux" -Remux.OBSRecording="OBS optagelse" -Remux.FinishedTitle="Remuxing færdigt" +Remux.Stop="Stop Remuxing" +Remux.ClearFinished="Ryd færdige emner" +Remux.ClearAll="Ryd alle emner" +Remux.OBSRecording="OBS-optagelse" +Remux.FinishedTitle="Remuxing færdig" Remux.Finished="Optagelse remuxed" -Remux.FinishedError="Optagelse remuxed, men filen kan være ufuldstændige" -Remux.SelectRecording="Vælg OBS optagelse…" -Remux.SelectTarget="Vælg destinationsfil…" -Remux.FileExistsTitle="Destinationsfilen findes" -Remux.FileExists="Destinationsfilen eksisterer, vil du erstatte den?" +Remux.FinishedError="Optagelse remuxed, men filen kan være ufuldstændig" +Remux.SelectRecording="Vælg OBS-optagelse..." +Remux.SelectTarget="Vælg destinationsfil..." +Remux.FileExistsTitle="Destinationsfil findes" +Remux.FileExists="Flg. destinationsfiler findes allerede. Erstat disse?" Remux.ExitUnfinishedTitle="Remuxing i gang" -Remux.ExitUnfinished="Remuxing er ikke færdig. Hvis du stopper nu, kan du gøre destinationsfilen ubrugelig. \nEr du sikker på du vil stoppe remuxing?" +Remux.ExitUnfinished="Remuxing er ikke færdig. Stopper du nu, kan det gøre destinationsfilen ubrugelig.\nSikker på, at du vil stoppe remuxing?" +Remux.HelpText="Slip filer i vinduet for at remuxe eller vælg en tom \"OBS-optagelse\" celle for at søge efter en fil." UpdateAvailable="Ny opdatering tilgængelig" -UpdateAvailable.Text="Version %1.%2.%3 er nu tilgængelig. Klik her for at downloade" +UpdateAvailable.Text="Version %1.%2.%3 er nu tilgængelig. Klik her for at downloade" -Basic.DesktopDevice1="Skrivebordslyd" -Basic.DesktopDevice2="Skrivebordslyd 2" +Basic.DesktopDevice1="Computerlyd" +Basic.DesktopDevice2="Computerlyd 2" Basic.AuxDevice1="Mic/Aux" Basic.AuxDevice2="Mic/Aux 2" Basic.AuxDevice3="Mic/Aux 3" Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="Scene" -Basic.DisplayCapture="Indfang display" +Basic.DisplayCapture="Skærmoptagelse" -Basic.Main.PreviewConextMenu.Enable="Aktiver visning" +Basic.Main.PreviewConextMenu.Enable="Aktivér forhåndsvisning" -ScaleFiltering="Skala filtrering" +Basic.Main.Preview.Disable="Deaktivér forhåndsvisning" + +ScaleFiltering="Skaleringsfiltrering" ScaleFiltering.Point="Punkt" -ScaleFiltering.Bilinear="Bilinear" +ScaleFiltering.Bilinear="Bilineær" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" Deinterlacing="Deinterlacing" Deinterlacing.Discard="Kassér" Deinterlacing.Retro="Retro" Deinterlacing.Blend="Bland" -Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Blend2x="Bland 2x" Deinterlacing.Linear="Lineær" Deinterlacing.Linear2x="Lineær 2x" Deinterlacing.Yadif="Yadif" @@ -294,23 +337,23 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="Øverste felt først" Deinterlacing.BottomFieldFirst="Nederste felt først" -VolControl.SliderUnmuted="Lydstyrkeskyder for '%1': %2" -VolControl.SliderMuted="Lydstyrkeskyder for '%1': %2 (lyd i øjeblikket slået fra)" -VolControl.Mute="Gør '%1' tavs" +VolControl.SliderUnmuted="Lydstyrkeskyder til '%1': %2" +VolControl.SliderMuted="Lydstyrkeskyder til '%1': %2 (pt. på lydløs)" +VolControl.Mute="Gør '%1' lydløs" VolControl.Properties="Egenskaber for '%1'" -Basic.Main.AddSceneDlg.Title="Tilføje scene" -Basic.Main.AddSceneDlg.Text="Angiv navnet på scene" +Basic.Main.AddSceneDlg.Title="Tilføj scene" +Basic.Main.AddSceneDlg.Text="Angiv navnet på scenen" Basic.Main.DefaultSceneName.Text="Scene %1" Basic.Main.AddSceneCollection.Title="Tilføj scenesamling" -Basic.Main.AddSceneCollection.Text="Indtast venligst navnet på scenesamlingen" +Basic.Main.AddSceneCollection.Text="Angiv navnet på scenesamlingen" Basic.Main.RenameSceneCollection.Title="Omdøb scenesamling" AddProfile.Title="Tilføj profil" -AddProfile.Text="Indtast venligst profilens navn" +AddProfile.Text="Angiv profilens navn" RenameProfile.Title="Omdøb profil" @@ -318,149 +361,151 @@ Basic.Main.MixerRename.Title="Omdøb lydkilde" Basic.Main.MixerRename.Text="Angiv navnet på lydkilden" -Basic.Main.PreviewDisabled="Forhåndsvisning er i øjeblikket deaktiveret" +Basic.Main.PreviewDisabled="Forhåndsvisning er i pt. inaktiv" Basic.SourceSelect="Opret/Vælg kilde" Basic.SourceSelect.CreateNew="Opret ny" Basic.SourceSelect.AddExisting="Tilføj eksisterende" -Basic.SourceSelect.AddVisible="Gør kilden synlig" +Basic.SourceSelect.AddVisible="Gør kilde synlig" Basic.PropertiesWindow="Egenskaber for '%1'" Basic.PropertiesWindow.AutoSelectFormat="%1 (auto-vælg: %2)" Basic.PropertiesWindow.SelectColor="Vælg farve" Basic.PropertiesWindow.SelectFont="Vælg skrifttype" Basic.PropertiesWindow.ConfirmTitle="Indstillinger ændret" -Basic.PropertiesWindow.Confirm="Der er ændringer, som ikke er gemt. Vil du gerne beholde dem?" +Basic.PropertiesWindow.Confirm="Der er ændringer, som ikke er gemt. Skal de gemmes?" Basic.PropertiesWindow.NoProperties="Ingen egenskaber tilgængelige" Basic.PropertiesWindow.AddFiles="Tilføj filer" Basic.PropertiesWindow.AddDir="Tilføj mappe" -Basic.PropertiesWindow.AddURL="Tilføj sti/url" -Basic.PropertiesWindow.AddEditableListDir="Tilføj mappe til '%1'" -Basic.PropertiesWindow.AddEditableListFiles="Tilføj filer til '%1'" -Basic.PropertiesWindow.AddEditableListEntry="Tilføj emne til '%1'" -Basic.PropertiesWindow.EditEditableListEntry="Rediger emne fra '%1'" +Basic.PropertiesWindow.AddURL="Tilføj sti/URL" +Basic.PropertiesWindow.AddEditableListDir="Føj mappe til '%1'" +Basic.PropertiesWindow.AddEditableListFiles="Føj filer til '%1'" +Basic.PropertiesWindow.AddEditableListEntry="Føj emne til '%1'" +Basic.PropertiesWindow.EditEditableListEntry="Redigér emne fra '%1'" -Basic.PropertiesView.FPS.Simple="Simple FPS værdier" -Basic.PropertiesView.FPS.Rational="Rationelle FPS værdier" -Basic.PropertiesView.FPS.ValidFPSRanges="Gyldige FPS områder:" +Basic.PropertiesView.FPS.Simple="Simple FPS-værdier" +Basic.PropertiesView.FPS.Rational="Rationelle FPS-værdier" +Basic.PropertiesView.FPS.ValidFPSRanges="Gyldige FPS-områder:" -Basic.InteractionWindow="Interagere med '%1'" +Basic.InteractionWindow="Interagerer med '%1'" -Basic.StatusBar.Reconnecting="Afbrudt, tilslutter igen om %2 sekund(er) (forsøg %1)" -Basic.StatusBar.AttemptingReconnect="Prøver at forbinde igen... (forsøg %1)" -Basic.StatusBar.ReconnectSuccessful="Gentilslutning vellykket" -Basic.StatusBar.Delay="Forsinkelse (%1 sek)" -Basic.StatusBar.DelayStartingIn="Forsinkelse (starter om %1 sek)" -Basic.StatusBar.DelayStoppingIn="Forsinkelse (stopper om %1 sek)" -Basic.StatusBar.DelayStartingStoppingIn="Forsinkelse (stopper om %1 sek, starter om %2 sek)" +Basic.StatusBar.Reconnecting="Afbrudt, genforbinder om %2 sekund(-er) (forsøg %1)" +Basic.StatusBar.AttemptingReconnect="Forsøger at genforbinde... (forsøg %1)" +Basic.StatusBar.ReconnectSuccessful="Genforbundet nu" +Basic.StatusBar.Delay="Forsinkelse (%1 sek.)" +Basic.StatusBar.DelayStartingIn="Forsinkelse (starter om %1 sek.)" +Basic.StatusBar.DelayStoppingIn="Forsinkelse (stopper om %1 sek.)" +Basic.StatusBar.DelayStartingStoppingIn="Forsinkelse (stopper om %1 sek., starter om %2 sek.)" Basic.Filters="Filtre" -Basic.Filters.AsyncFilters="Lyd/video filtre" -Basic.Filters.AudioFilters="Lyd filter" +Basic.Filters.AsyncFilters="Lyd-/videofiltre" +Basic.Filters.AudioFilters="Lydfiltre" Basic.Filters.EffectFilters="Effektfiltre" -Basic.Filters.Title="Filtre for '%1'" +Basic.Filters.Title="Filtre til '%1'" Basic.Filters.AddFilter.Title="Filternavn" Basic.Filters.AddFilter.Text="Angiv navnet på filteret" -Basic.TransformWindow="Scene Item Transform" +Basic.TransformWindow="Sceneemnetransformation" Basic.TransformWindow.Position="Position" Basic.TransformWindow.Rotation="Rotation" Basic.TransformWindow.Size="Størrelse" -Basic.TransformWindow.Alignment="Positionelle justering" -Basic.TransformWindow.BoundsType="Afgrænsning Rammen Boks Type" -Basic.TransformWindow.BoundsAlignment="Justering i afgrænsningsområdet" -Basic.TransformWindow.Bounds="Afgrænsning Rammen boksstørrelse" +Basic.TransformWindow.Alignment="Positionel justering" +Basic.TransformWindow.BoundsType="Afgrænsningskassetype" +Basic.TransformWindow.BoundsAlignment="Justering i afgrænsningskasse" +Basic.TransformWindow.Bounds="Afgrænsningskassestørrelse" Basic.TransformWindow.Crop="Beskær" Basic.TransformWindow.Alignment.TopLeft="Øverst til venstre" -Basic.TransformWindow.Alignment.TopCenter="Top Center" +Basic.TransformWindow.Alignment.TopCenter="Øverst midtfor" Basic.TransformWindow.Alignment.TopRight="Øverst til højre" -Basic.TransformWindow.Alignment.CenterLeft="Center venstre" -Basic.TransformWindow.Alignment.Center="Centrér" -Basic.TransformWindow.Alignment.CenterRight="Center højre" +Basic.TransformWindow.Alignment.CenterLeft="Venstre midtfor" +Basic.TransformWindow.Alignment.Center="Centreret" +Basic.TransformWindow.Alignment.CenterRight="Højre midtfor" Basic.TransformWindow.Alignment.BottomLeft="Nederst til venstre" -Basic.TransformWindow.Alignment.BottomCenter="Nederst center" +Basic.TransformWindow.Alignment.BottomCenter="Nederst midfor" Basic.TransformWindow.Alignment.BottomRight="Nederst til højre" -Basic.TransformWindow.BoundsType.None="Ingen grænser" -Basic.TransformWindow.BoundsType.MaxOnly="Maksimal størrelse kun" -Basic.TransformWindow.BoundsType.ScaleInner="Skalere til indre grænser" -Basic.TransformWindow.BoundsType.ScaleOuter="Skalere til ydre grænser" -Basic.TransformWindow.BoundsType.ScaleToWidth="Skalere til bredden af grænser" -Basic.TransformWindow.BoundsType.ScaleToHeight="Skalere højden af grænser" -Basic.TransformWindow.BoundsType.Stretch="Strække til grænser" +Basic.TransformWindow.BoundsType.None="Ingen afgrænsninger" +Basic.TransformWindow.BoundsType.MaxOnly="Kun maksimalstørrelse" +Basic.TransformWindow.BoundsType.ScaleInner="Skalér til indre grænser" +Basic.TransformWindow.BoundsType.ScaleOuter="Skalér til ydre grænser" +Basic.TransformWindow.BoundsType.ScaleToWidth="Skalér til afgrænsningsbredden" +Basic.TransformWindow.BoundsType.ScaleToHeight="Skalér til afgrænsningshøjden" +Basic.TransformWindow.BoundsType.Stretch="Stræk til grænser" Basic.Main.AddSourceHelp.Title="Kan ikke tilføje kilde" -Basic.Main.AddSourceHelp.Text="Du skal have mindst 1 scene til at tilføje en kilde." +Basic.Main.AddSourceHelp.Text="Du behøver mindst 1 scene for at tilføje en kilde." Basic.Main.Scenes="Scener" Basic.Main.Sources="Kilder" Basic.Main.Controls="Styring" Basic.Main.Connecting="Forbinder..." Basic.Main.StartRecording="Start optagelse" -Basic.Main.StartReplayBuffer="Start Genafspilningsbuffer" +Basic.Main.StartReplayBuffer="Start Genafspilnings-buffer" Basic.Main.StartStreaming="Start streaming" Basic.Main.StopRecording="Stop optagelse" Basic.Main.StoppingRecording="Stopper optagelse..." -Basic.Main.StopReplayBuffer="Stop Genafspilningsbuffer" -Basic.Main.StoppingReplayBuffer="Stopper Genafspilningsbuffer..." +Basic.Main.StopReplayBuffer="Stop Genafspilnings-buffer" +Basic.Main.StoppingReplayBuffer="Stopper Genafspilnings-buffer..." Basic.Main.StopStreaming="Stop streaming" Basic.Main.StoppingStreaming="Stopper stream..." -Basic.Main.ForceStopStreaming="Stop streaming (ignorer forsinkelse)" +Basic.Main.ForceStopStreaming="Stop streaming (ignorér forsinkelse)" Basic.Main.Group="Gruppe %1" -Basic.Main.GroupItems="Gruppér valgte elementer" -Basic.Main.Ungroup="Ikke-grupperet" +Basic.Main.GroupItems="Gruppér valgte emner" +Basic.Main.Ungroup="Afgruppér" Basic.MainMenu.File="&Fil" Basic.MainMenu.File.Export="&Eksport" Basic.MainMenu.File.Import="&Import" Basic.MainMenu.File.ShowRecordings="Vis optagelse&r" Basic.MainMenu.File.Remux="Re&mux optagelser" -Basic.MainMenu.File.Settings="Indstillinger (&S)" -Basic.MainMenu.File.ShowSettingsFolder="Vis indstillings-mappen" -Basic.MainMenu.File.ShowProfileFolder="Vis profil-mappe" +Basic.MainMenu.File.Settings="Ind&stillinger" +Basic.MainMenu.File.ShowSettingsFolder="Vis Indstillingsmappe" +Basic.MainMenu.File.ShowProfileFolder="Vis Profilmappe" Basic.MainMenu.AlwaysOnTop="&Altid øverst" Basic.MainMenu.File.Exit="Afslut (&X)" -Basic.MainMenu.Edit="Redigere (&E)" +Basic.MainMenu.Edit="R&edigér" Basic.MainMenu.Edit.Undo="Fortryd (&U)" -Basic.MainMenu.Edit.Redo="&Redo" +Basic.MainMenu.Edit.Redo="Gendan (&R)" Basic.MainMenu.Edit.UndoAction="Fortryd $1 (&U)" -Basic.MainMenu.Edit.RedoAction="&Redo $1" +Basic.MainMenu.Edit.RedoAction="Gendan $1 (&R)" Basic.MainMenu.Edit.LockPreview="&Lås forhåndsvisning" -Basic.MainMenu.Edit.Scale="Forhåndsvisning & Skalering" +Basic.MainMenu.Edit.Scale="Forhåndsvisnings&skalering" Basic.MainMenu.Edit.Scale.Window="Skalér til vindue" Basic.MainMenu.Edit.Scale.Canvas="Lærred (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformering" -Basic.MainMenu.Edit.Transform.EditTransform="Rediger transformering... (&E)" +Basic.MainMenu.Edit.Transform.EditTransform="R&edigere transformering..." Basic.MainMenu.Edit.Transform.CopyTransform="Kopiér transformation" Basic.MainMenu.Edit.Transform.PasteTransform="Indsæt transformation" -Basic.MainMenu.Edit.Transform.ResetTransform="Nulstille transformering (&R)" -Basic.MainMenu.Edit.Transform.Rotate90CW="Roter 90 grader CW" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Roter 90 grader CCW" -Basic.MainMenu.Edit.Transform.Rotate180="Rotere 180 grader" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip Vandret (&H)" -Basic.MainMenu.Edit.Transform.FlipVertical="Flip Lodret (&V)" +Basic.MainMenu.Edit.Transform.ResetTransform="Nulstil transforme&ring" +Basic.MainMenu.Edit.Transform.Rotate90CW="Rotér 90 grader højreom" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotér 90 grader venstreom" +Basic.MainMenu.Edit.Transform.Rotate180="Rotér 180 grader" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip &Horisontalt" +Basic.MainMenu.Edit.Transform.FlipVertical="Flip &Vertikalt" Basic.MainMenu.Edit.Transform.FitToScreen="Tilpas til skærm (&F)" -Basic.MainMenu.Edit.Transform.StretchToScreen="Strækning til skærm (&S)" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Center til skærm" +Basic.MainMenu.Edit.Transform.StretchToScreen="&Stræk til skærm" +Basic.MainMenu.Edit.Transform.CenterToScreen="&Centér på skærm" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrér vertikalt" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrér horisontalt" Basic.MainMenu.Edit.Order="Rækkefølge (&O)" Basic.MainMenu.Edit.Order.MoveUp="Flyt Op (&U)" -Basic.MainMenu.Edit.Order.MoveDown="Flyt Ned (&D)" -Basic.MainMenu.Edit.Order.MoveToTop="Flyt til &toppen" +Basic.MainMenu.Edit.Order.MoveDown="Flyt Ne&d" +Basic.MainMenu.Edit.Order.MoveToTop="Flyt til &Toppen" Basic.MainMenu.Edit.Order.MoveToBottom="Flyt til &Bunden" Basic.MainMenu.Edit.AdvAudio="&Avancerede lydegenskaber" Basic.MainMenu.View="&Vis" -Basic.MainMenu.View.Toolbars="&Værktøjslinjer" -Basic.MainMenu.View.Docks="Dokker" +Basic.MainMenu.View.Toolbars="Værk&tøjslinjer" +Basic.MainMenu.View.Docks="Dok'er" Basic.MainMenu.View.Docks.ResetUI="Nulstil UI" Basic.MainMenu.View.Docks.LockUI="Lås UI" Basic.MainMenu.View.Toolbars.Listboxes="&Listebokse" -Basic.MainMenu.View.SceneTransitions="S&cene overgange" -Basic.MainMenu.View.StatusBar="&Statuslinje" -Basic.MainMenu.View.Fullscreen.Interface="Fuldskærms-grænseflade" +Basic.MainMenu.View.SceneTransitions="S&ceneovergange" +Basic.MainMenu.View.StatusBar="&Statusbjælke" +Basic.MainMenu.View.Fullscreen.Interface="Fuldskærmsgrænseflade" Basic.MainMenu.SceneCollection="&Scenesamling" Basic.MainMenu.Profile="&Profil" @@ -475,52 +520,58 @@ Basic.MainMenu.Tools="Værk&tøjer" Basic.MainMenu.Help="&Hjælp" Basic.MainMenu.Help.HelpPortal="Hjælp og &Portal" -Basic.MainMenu.Help.Website="Besøg &websted" -Basic.MainMenu.Help.Discord="Join &Discord serveren" +Basic.MainMenu.Help.Website="Besøg &Websted" +Basic.MainMenu.Help.Discord="Tilmeld til &Discord-server" Basic.MainMenu.Help.Logs="&Logfiler" -Basic.MainMenu.Help.Logs.ShowLogs="Vis log-filer (&S)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload Aktuelle logfil (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="Upload Sidste logfil (&L)" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vis aktuel logfil" -Basic.MainMenu.Help.CheckForUpdates="Tjek for opdateringer" -Basic.MainMenu.Help.CrashLogs="Nedbrudsrapporter" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Vis nedbrudsrapporter" +Basic.MainMenu.Help.Logs.ShowLogs="Vi&s logfiler" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload aktuel logfil (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Upload seneste &logfil" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vis aktuel log" +Basic.MainMenu.Help.CheckForUpdates="Se efter opdateringer" +Basic.MainMenu.Help.CrashLogs="Nedbruds&rapporter" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&s nedbrudsrapporter" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Up&load seneste nedbrudsrapport" +Basic.MainMenu.Help.About="Om (&A)" -Basic.Settings.ProgramRestart="Programmet skal genstartes, før disse indstillinger træder i kraft." -Basic.Settings.ConfirmTitle="Bekræfte ændringer" -Basic.Settings.Confirm="Du har ugemte ændringer. Skal ændringerne gemmes?" +Basic.Settings.ProgramRestart="Programmet skal genstartes, for at effektuere disse indstillinger." +Basic.Settings.ConfirmTitle="Bekræft ændringer" +Basic.Settings.Confirm="Du har ugemte ændringer, gem dem nu?" Basic.Settings.General="Generelt" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Sprog" -Basic.Settings.General.EnableAutoUpdates="Automatisk søgning efter opdateringer ved opstart" -Basic.Settings.General.OpenStatsOnStartup="Åbn statistik dialogboksen ved opstart" -Basic.Settings.General.WarnBeforeStartingStream="Vis bekræftelses-dialog ved opstart af stream" -Basic.Settings.General.WarnBeforeStoppingStream="Vis bekræftelses-dialog ved afslutning af stream" +Basic.Settings.General.EnableAutoUpdates="Søg automatisk efter opdateringer ved opstart" +Basic.Settings.General.OpenStatsOnStartup="Åbn statistikdialogen ved opstart" +Basic.Settings.General.WarnBeforeStartingStream="Vis bekræftelsesdialog ved opstart af stream" +Basic.Settings.General.WarnBeforeStoppingStream="Vis bekræftelsesdialog ved afslutning af stream" Basic.Settings.General.Projectors="Projektorer" Basic.Settings.General.HideProjectorCursor="Skjul markør over projektorer" -Basic.Settings.General.ProjectorAlwaysOnTop="Hav altid projektorer øverst" -Basic.Settings.General.Snapping="Kilde justeringsfastgørelse" -Basic.Settings.General.ScreenSnapping="Fastgør kilder til kanten af skærmen" +Basic.Settings.General.ProjectorAlwaysOnTop="Projektorer altid øverst" +Basic.Settings.General.Snapping="Kildejusteringsfastgørelse" +Basic.Settings.General.ScreenSnapping="Fastgør kilder til skærmkant" Basic.Settings.General.CenterSnapping="Fastgør kilder til horisontalt og vertikalt centrum" Basic.Settings.General.SourceSnapping="Fastgør kilder til andre kilder" -Basic.Settings.General.SnapDistance="Fastgørings-følsomhed" +Basic.Settings.General.SnapDistance="Fastgøringsfølsomhed" Basic.Settings.General.RecordWhenStreaming="Optag automatisk ved streaming" -Basic.Settings.General.KeepRecordingWhenStreamStops="Bliv ved med at optage når stream stopper" -Basic.Settings.General.ReplayBufferWhileStreaming="Start automatisk replay buffer ved streaming" -Basic.Settings.General.KeepReplayBufferStreamStops="Hold replay buffer aktiv når stream stopper" -Basic.Settings.General.SysTray="Processlinjen" -Basic.Settings.General.SysTrayWhenStarted="Minimer til proceslinjen ved start" -Basic.Settings.General.SystemTrayHideMinimize="Minimer altid til processlinjen i stedet for værktøjslinjen" +Basic.Settings.General.KeepRecordingWhenStreamStops="Fortsæt med at optage når stream stopper" +Basic.Settings.General.ReplayBufferWhileStreaming="Start automatisk genafsplinings-buffer ved streaming" +Basic.Settings.General.KeepReplayBufferStreamStops="Behold genafsplinings-buffer aktiv når stream stopper" +Basic.Settings.General.SysTray="Systembakke" +Basic.Settings.General.SysTrayWhenStarted="Minimér til systembakke når startet" +Basic.Settings.General.SystemTrayHideMinimize="Minimér altid til systembakke i stedet for opgavebjælke" Basic.Settings.General.SaveProjectors="Gem projektorer ved afslutning" +Basic.Settings.General.Preview="Forhåndsvisning" +Basic.Settings.General.OverflowHidden="Skjul overløb" +Basic.Settings.General.OverflowAlwaysVisible="Overløb altid synlig" +Basic.Settings.General.OverflowSelectionHidden="Vis overløb, selv når kilden er usynlig" Basic.Settings.General.SwitchOnDoubleClick="Overgang til scenen ved dobbeltklik" -Basic.Settings.General.StudioPortraitLayout="Aktivere stående/liggende layout" +Basic.Settings.General.StudioPortraitLayout="Aktivér stående/liggende layout" +Basic.Settings.General.TogglePreviewProgramLabels="Vis etiket for forhåndsvisning/program" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Klik for at skifte mellem scener" Basic.Settings.General.Multiview.DrawSourceNames="Vis scenenavne" Basic.Settings.General.Multiview.DrawSafeAreas="Tegn sikre områder (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Multivisningslayout" +Basic.Settings.General.MultiviewLayout="Multiview-layout" Basic.Settings.General.MultiviewLayout.Horizontal.Top="Vandret, øverst (8 scener)" Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Vandret, nederst (8 scener)" Basic.Settings.General.MultiviewLayout.Vertical.Left="Lodret, venstre (8 scener)" @@ -529,58 +580,61 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Vandret, øverst Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Streamtype" +Basic.Settings.Stream.Custom.UseAuthentication="Benyt godkendelse" +Basic.Settings.Stream.Custom.Username="Brugernavn" +Basic.Settings.Stream.Custom.Password="Adgangskode" +Basic.Settings.Stream.BandwidthTestMode="Aktivér Båndbreddetesttilstand" Basic.Settings.Output="Output" Basic.Settings.Output.Format="Optagelsesformat" Basic.Settings.Output.Encoder="Encoder" Basic.Settings.Output.SelectDirectory="Vælg optagelsesmappe" Basic.Settings.Output.SelectFile="Vælg optagelsesfil" -Basic.Settings.Output.EnforceBitrate="Håndhæv streaming service bitrate grænser" -Basic.Settings.Output.Mode="Output tilstand" +Basic.Settings.Output.EnforceBitrate="Håndhæv streamingtjenestes bit-hastighedsbegrænsninger" +Basic.Settings.Output.Mode="Outputtilstand" Basic.Settings.Output.Mode.Simple="Simpel" Basic.Settings.Output.Mode.Adv="Avanceret" -Basic.Settings.Output.Mode.FFmpeg="FFmpeg output" -Basic.Settings.Output.UseReplayBuffer="Aktivér Genafspilningsbuffer" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg-output" +Basic.Settings.Output.UseReplayBuffer="Aktivér Genafspilnings-buffer" Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal genafspilningstid (sek.)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimal hukommelse (MB)" -Basic.Settings.Output.ReplayBuffer.Estimate="Anslået hukommelsesforbrug: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ikke kan beregne hukommelsesforbrug. Sæt venligst maks. hukommelsesgrænse." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Bemærk: Sørg for at sætte en genvejstast til genafspilningsbufferen i sektionen for genvejstaster)" -Basic.Settings.Output.ReplayBuffer.Prefix="Genafspilningsbuffer filnavn præfiks" +Basic.Settings.Output.ReplayBuffer.Estimate="Estimeret hukommelsesforbrug: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ikke kan estimere hukommelsesforbrug. Angiv en maks. hukommelsesgrænse." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Bemærk: Sørg for at opsætte en genvejstast til genafspilnings-bufferen i afsnittet for genvejstaster)" +Basic.Settings.Output.ReplayBuffer.Prefix="Genafspilnings-buffer, filnavnpræfiks" Basic.Settings.Output.ReplayBuffer.Suffix="Endelse" Basic.Settings.Output.Simple.SavePath="Optagelsessti" Basic.Settings.Output.Simple.RecordingQuality="Optagelseskvalitet" Basic.Settings.Output.Simple.RecordingQuality.Stream="Samme som stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Høj kvalitet, medium filstørrelse" -Basic.Settings.Output.Simple.RecordingQuality.HQ="Samme kvalitet, stor filstørrelse" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tabsfri kvalitet, utrolig stor filstørrelse" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Advarsel: Video-streaming bitraten sættes til %1, som er den øvre grænse for den aktuelle streaming-tjeneste. Er du sikker på, at du vil at gå over %1, så aktivér venligst avancerede valg for encoder og afmarkér \"Gennemtving streaming-tjenestes bitratebegrænsninger\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Advarsel: Audio-streaming bitraten sættes til %1, som er den øvre grænse for den aktuelle streaming-tjeneste. Er du sikker på, at du vil at gå over %1, så aktivér venligst avancerede valg for encoder og afmarkér \"Gennemtving streaming-tjenestes bitratebegrænsninger\"." -Basic.Settings.Output.Simple.Warn.Encoder="Advarsel: Optagelse med en software-encoder i en anden kvalitet end det streamede vil medføre ekstra CPU-forbrug, hvis du streamer og optager samtidigt." -Basic.Settings.Output.Simple.Warn.Lossless="Advarsel: Tabsfri kvalitet genererer gevaldigt store filstørrelser! Tabsfri kvalitet kan bruge op til 7 GB diskplads pr. minut ved høje opløsninger og billedhastigheder. Tabsfri tilstand anbefales ikke til lange optagelser, medmindre du har en meget stor mængde tilgængelig diskplads." +Basic.Settings.Output.Simple.RecordingQuality.HQ="Synlig identisk kvalitet, stor filstørrelse" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tabsfri kvalitet, enorm stor filstørrelse" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Advarsel: Videostreamingbit-hastigheden sættes til %1, som er den øvre grænse for den aktuelle streamingtjeneste. Er du sikker på, at du vil at gå over %1, så aktivér avancerede encoder-valg og afmarkér \"Gennemtving streamingtjenestes bit-hastighedsbegrænsninger\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Advarsel: Audiostreamingbit-hastigheden sættes til %1, som er den øvre grænse for den aktuelle streamingtjeneste. Er du sikker på, at du vil at gå over %1, så aktivér avancerede encoder-valg og afmarkér \"Gennemtving streamingtjenestes bit-hastighedsbegrænsninger\"." +Basic.Settings.Output.Simple.Warn.Encoder="Advarsel: Optagelse med en software-encoder i en anden kvalitet end den streamede vil medføre ekstra CPU-forbrug, hvis du streamer og optager samtidigt." +Basic.Settings.Output.Simple.Warn.Lossless="Advarsel: Tabsfri kvalitet genererer gevaldigt store filstørrelser! Tabsfri kvalitet kan forbruge op til 7 GB diskplads pr. minut ved høje opløsninger og billedhastigheder. Tabsfri tilstand anbefales ikke til lange optagelser, medmindre du har masser af tilgængelig diskplads." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sikker på, at du vil benytte tabsfri kvalitet?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Tabsfri kvalitet-advarsel!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Advarsel: Du kan ikke benytte flere særskilte QSV-encoders ved streaming og optagelse på samme tid. Ønsker du at streame og optage samtidig, bedes du ændre enten optagelses- eller stream-encoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 lav, forudindstillet CPU-forbrug, øger filstørrelsen)" -Basic.Settings.Output.VideoBitrate="Video Bitrate" -Basic.Settings.Output.AudioBitrate="Audio Bitrate" -Basic.Settings.Output.Reconnect="Automatisk Reconnect" -Basic.Settings.Output.RetryDelay="Retry forsinkelse (sekunder)" -Basic.Settings.Output.MaxRetries="Maksimum forsøg" -Basic.Settings.Output.Advanced="Aktiver avancerede Encoder indstillinger" -Basic.Settings.Output.EncoderPreset="Encoder forudindstilling (hurtigere= mindre CPU-kraft)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 lavt, forvalgt CPU-forbrug, øger filstørrelsen)" +Basic.Settings.Output.VideoBitrate="Videobit-hastighed" +Basic.Settings.Output.AudioBitrate="Audiobit-hastighed" +Basic.Settings.Output.Reconnect="Automatisk gentilslutning" +Basic.Settings.Output.RetryDelay="Forsøg igen-forsinkelse (sek.)" +Basic.Settings.Output.MaxRetries="Maks. antal forsøg" +Basic.Settings.Output.Advanced="Aktivér avancerede Encoder-indstillinger" +Basic.Settings.Output.EncoderPreset="Encoder-forvalg" Basic.Settings.Output.CustomEncoderSettings="Tilpasset Encoder-indstillinger" Basic.Settings.Output.CustomMuxerSettings="Tilpasset Muxer-indstillinger" -Basic.Settings.Output.NoSpaceFileName="Opret filnavne uden mellemrum" +Basic.Settings.Output.NoSpaceFileName="Generér filnavn uden mellemrum" -Basic.Settings.Output.Adv.Rescale="Om-skalere output" +Basic.Settings.Output.Adv.Rescale="Omskalér output" Basic.Settings.Output.Adv.AudioTrack="Lydspor" Basic.Settings.Output.Adv.Streaming="Streaming" -Basic.Settings.Output.Adv.ApplyServiceSettings="Håndhæv streaming service encoder indstillinger" +Basic.Settings.Output.Adv.ApplyServiceSettings="Håndhæv streamingtjenestes encoder-indstillinger" Basic.Settings.Output.Adv.Audio.Track1="Spor 1" Basic.Settings.Output.Adv.Audio.Track2="Spor 2" Basic.Settings.Output.Adv.Audio.Track3="Spor 3" @@ -592,9 +646,9 @@ Basic.Settings.Output.Adv.Recording="Optagelse" Basic.Settings.Output.Adv.Recording.Type="Type" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Tilpasset output (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Brug stream encoder)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Benyt stream-encoder)" Basic.Settings.Output.Adv.Recording.Filename="Filnavnsformatering" -Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overskriv hvis filen eksisterer" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Overskriv, hvis fil findes" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg outputtype" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output til URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output til fil" @@ -604,117 +658,124 @@ Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Filsti eller URL" Basic.Settings.Output.Adv.FFmpeg.Format="Containerformat" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Lyd" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" -Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standard format" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container-format beskrivelse" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Lyd/Video-codec gættet fra filsti eller URL" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard encoder" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Deaktiver encoder" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video encoder" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video encoder indstillinger (hvis nogen)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lyd encoder" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lyd encoder indstillinger (hvis nogen)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer indstillinger (hvis nogen)" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standardformat" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Containerformat beskrivelse" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Lyd-/Video-codec gættet fra filsti eller URL" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard-encoder" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Deaktivér encoder" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video-encoder" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video-encoder indstillinger (om nogle)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lyd-encoder" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lyd-encoder indstillinger (om nogle)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer-indstillinger (om nogle)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframe-Interval (billeder)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Vis alle codecs (selv potentielt inkompatible)" -FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" +FilenameFormatting.completer="%CCYY-%DD-%MM %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S\n%d-%m-%Y %I-%M-%S-%p\n%d-%m-%Y %H-%M-%S-%z\n%d-%m-%Y %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY år, fire cifre\n%YY år, sidste to cifre (00-99)\n%MM måned som tal (01-12)\n%DD dag i måneden, foranstillet nul (01-31)\n%hh time i 24t format (00-23)\n%mm minut (00-59)\n%ss sekund (00-61)\n%% et % tegn\n%a forkortet ugedagsnavn\n%A helt ugedagsnavn\n%b forkortet månedsnavn\n%B helt månedsnavn\n%d dag i åneden, foranstillet nul (01-31)\n%H time i 24t format (00-23)\n%I time i 12t format (01-12)\n%m måned som et tal (01-12)\n%M minut (00-59)\n%p am eller pm angivelse\n%S sekund (00-61)\n%y år, sidste to cifre (00-99)\n%Y år\n%z ISO 8601 offset fra UTC eller tidszone\n navn eller forkortelse\n%Z tidszone navn eller forkortelse\n" +FilenameFormatting.TT="%CCYY År, fire cifre\n%YY År, sidste to cifre (00-99)\n%MM Måned i decimaltalsform (01-12)\n%DD Månedsdag, nul-foranstillet (01-31)\n%hh Time i 24-timersformat (00-23)\n%mm Minut (00-59)\n%ss Sekund (00-61)\n%% Et %-tegn\n%a Forkortet ugedagsnavn\n%A Fuldt ugedagsnavn\n%b Forkortet månedsnavn\n%B Fuldt månedsnavn\n%d Månedsdag, nul-foranstillet (01-31)\n%H Time i 24-timersformat (00-23)\n%I Time i 12-timersformat (01-12)\n%m Måned i decimaltalsform (01-12)\n%M Minut (00-59)\n%p AM-/PM-betegnelse\n%S Sekund (00-61)\n%y År, sidste to cifre (00-99)\n%Y År\n%z ISO 8601-forskudt fra UTC i tidszone\n%Z Tidszonenavn eller -forkortelse\n" Basic.Settings.Video="Video" -Basic.Settings.Video.Adapter="Skærmkort:" -Basic.Settings.Video.BaseResolution="Grund (lærred) opløsning:" -Basic.Settings.Video.ScaledResolution="Output (skaleret) opløsning:" -Basic.Settings.Video.DownscaleFilter="Nedskaleringsfilter:" -Basic.Settings.Video.DisableAeroWindows="Deaktivere Aero (kun Windows)" -Basic.Settings.Video.FPS="FPS:" -Basic.Settings.Video.FPSCommon="Fælles FPS værdier" -Basic.Settings.Video.FPSInteger="Heltalsværdi FPS" -Basic.Settings.Video.FPSFraction="Fraktioneret FPS værdi" -Basic.Settings.Video.Numerator="Tæller:" -Basic.Settings.Video.Denominator="Nævneren:" -Basic.Settings.Video.Renderer="Renderer:" -Basic.Settings.Video.InvalidResolution="Ugyldig opløsningsværdi. Skal være [bredde] x [højde] (dvs. 1920 x 1080)" -Basic.Settings.Video.CurrentlyActive="Video output er aktiv i øjeblikket. Venligst slukke eventuelle udgange til at ændre videoindstillinger." -Basic.Settings.Video.DisableAero="Deaktiver Aero" +Basic.Settings.Video.Adapter="Skærmkort" +Basic.Settings.Video.BaseResolution="Grundopløsning (lærred)" +Basic.Settings.Video.ScaledResolution="Outputopløsning (skaleret)" +Basic.Settings.Video.DownscaleFilter="Nedskaleringsfilter" +Basic.Settings.Video.DisableAeroWindows="Deaktivér Aero (kun Windows)" +Basic.Settings.Video.FPS="FPS" +Basic.Settings.Video.FPSCommon="Almindelige FPS-værdier" +Basic.Settings.Video.FPSInteger="Heltals FPS-værdi" +Basic.Settings.Video.FPSFraction="Fraktioneret FPS-værdi" +Basic.Settings.Video.Numerator="Tæller" +Basic.Settings.Video.Denominator="Nævner" +Basic.Settings.Video.Renderer="Gengiver" +Basic.Settings.Video.InvalidResolution="Ugyldig opløsningsværdi. Skal være [width]x[height] (f.eks. 1.920x1.080)" +Basic.Settings.Video.CurrentlyActive="Videooutput erpt. aktivt. Afbryd evt. outputs fra for at ændre videoindstillinger." +Basic.Settings.Video.DisableAero="Deaktivér Aero" -Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (hurtigst, men sløret ved skalering)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubic (Skarp skalering, 16 prøver)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Skarp skalering, 32 prøver)" +Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinær (hurtigst, men sløret ved skalering)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bikubisk (skarp skalering, 16 samples)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skarp skalering, 32 samples)" Basic.Settings.Audio="Lyd" -Basic.Settings.Audio.SampleRate="Sample Rate" +Basic.Settings.Audio.SampleRate="Samplingshastighed" Basic.Settings.Audio.Channels="Kanaler" -Basic.Settings.Audio.MeterDecayRate="Lydmålerudstyring, faldhastighed" +Basic.Settings.Audio.Meters="Udstyringsmålere" +Basic.Settings.Audio.MeterDecayRate="Aftagelseshastighed" Basic.Settings.Audio.MeterDecayRate.Fast="Hurtig" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Langsom (Type II PPM)" Basic.Settings.Audio.PeakMeterType="Peak Meter-type" -Basic.Settings.Audio.PeakMeterType.SamplePeak="Intervalspidsværdi" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Samplingsspidsværdi" Basic.Settings.Audio.PeakMeterType.TruePeak="Sand spidsværdi (højere CPU-belastning)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ADVARSEL: Surround Sound-lyd er aktiveret." -Basic.Settings.Audio.MultichannelWarning="Tjek ifm. streamer, om din streaming-tjeneste understøtter både Surround Sound-input og -afspilning. Twitch, Facebook 360 Live, Mixer RTMP og Smashcast er eksempler, hvor surroundlyd understøttes fuldt ud. Selvom Facebook Live og YouTube Live begge accepterer surround input, nedmikser Facebook Live til stereo, og YouTube Live afspiller kun to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, dog er VST-pluginsupport ikke garanteret." +Basic.Settings.Audio.MultichannelWarning="Tjek ifm. streaming om din streamingtjeneste understøtter både Surround Sound-input og -afspilning. Twitch, Facebook 360 Live, Mixer RTMP og Smashcast er eksempler, hvor surroundlyd understøttes fuldt ud. Selvom Facebook Live og YouTube Live begge accepterer surround input, nedmikser Facebook Live til stereo, og YouTube Live afspiller kun to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, dog er VST-pluginsupport ikke garanteret." Basic.Settings.Audio.MultichannelWarning.Title="Aktivér Surround Sound-lyd?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sikker på, at du vil aktivere Surround Sound-lyd?" -Basic.Settings.Audio.DesktopDevice="Skrivebord lydenhed" -Basic.Settings.Audio.DesktopDevice2="Skrivebord lydenhed 2" -Basic.Settings.Audio.AuxDevice="Mic/Auxiliary lydenhed" -Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary lydenhed 2" -Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary lydenhed 3" -Basic.Settings.Audio.EnablePushToMute="Aktiver tryk-for-stilhed" -Basic.Settings.Audio.PushToMuteDelay="Tryk for at gøre tavs-forsinkelse" -Basic.Settings.Audio.EnablePushToTalk="Aktiver tryk-for-tale" -Basic.Settings.Audio.PushToTalkDelay="Tryk for at gøre hørbar-forsinkelse" -Basic.Settings.Audio.UnknownAudioDevice="[Enhed ikke tilsluttet eller ikke tilgængelig]" +Basic.Settings.Audio.Devices="Enheder" +Basic.Settings.Audio.DesktopDevice="Computerlyd" +Basic.Settings.Audio.DesktopDevice2="Computerlyd 2" +Basic.Settings.Audio.AuxDevice="Mic/Aux Lydenhed" +Basic.Settings.Audio.AuxDevice2="Mic/Aux Lydenhed 2" +Basic.Settings.Audio.AuxDevice3="Mic/Aux Lydenhed 3" +Basic.Settings.Audio.AuxDevice4="Mic/Aux Lydenhed 4" +Basic.Settings.Audio.EnablePushToMute="Aktivér tryk-gør-tavs" +Basic.Settings.Audio.PushToMuteDelay="Tryk-gør-tavs forsinkelse" +Basic.Settings.Audio.EnablePushToTalk="Aktivér tryk-for-tale" +Basic.Settings.Audio.PushToTalkDelay="Tryk-for-tale forsinkelse" +Basic.Settings.Audio.UnknownAudioDevice="[Enhed ikke tilsluttet eller utilgængelig]" +Basic.Settings.Audio.Disabled="Deaktiveret" Basic.Settings.Advanced="Avanceret" -Basic.Settings.Advanced.General.ProcessPriority="Proces prioritet" +Basic.Settings.Advanced.General.ProcessPriority="Procesprioritet" Basic.Settings.Advanced.General.ProcessPriority.High="Høj" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Over normal" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Under Normal" -Basic.Settings.Advanced.General.ProcessPriority.Idle="Ikke aktiv" +Basic.Settings.Advanced.General.ProcessPriority.Idle="Inaktiv" Basic.Settings.Advanced.FormatWarning="Advarsel: Farveformater ud over NV12 er primært beregnet til optagelse, og de anbefales ikke under streaming. Streaming kan medføre øget CPU-forbrug grundet farveformatkonvertering." Basic.Settings.Advanced.Audio.BufferingTime="Lyd-bufferinterval" Basic.Settings.Advanced.Video.ColorFormat="Farveformat" -Basic.Settings.Advanced.Video.ColorSpace="YUV farverum" -Basic.Settings.Advanced.Video.ColorRange="YUV farveområde" +Basic.Settings.Advanced.Video.ColorSpace="Farverum" +Basic.Settings.Advanced.Video.ColorRange="Farveområde" Basic.Settings.Advanced.Video.ColorRange.Partial="Delvis" Basic.Settings.Advanced.Video.ColorRange.Full="Fuld" -Basic.Settings.Advanced.Audio.MonitoringDevice="Lyd overvågningsenhed" +Basic.Settings.Advanced.Audio.MonitoringDevice="Moniteringsenhed" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Deaktiver Windows lyddæmpning" -Basic.Settings.Advanced.StreamDelay="Stream forsinkelse" -Basic.Settings.Advanced.StreamDelay.Duration="Varighed (sekunder)" -Basic.Settings.Advanced.StreamDelay.Preserve="Bevar afskæringspunkt (forøg forsinkelse) ved forbindelsesgendannelse" -Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslået hukommelsesbrug: %1 MB" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Deaktivér Windows-lyddæmpning" +Basic.Settings.Advanced.StreamDelay="Streamforsinkelse" +Basic.Settings.Advanced.StreamDelay.Duration="Varighed (sek.)" +Basic.Settings.Advanced.StreamDelay.Preserve="Bevar afskæringspunkt (forøg forsinkelse) ved gentilslutning" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimeret hukommelsesforbrug: %1 MB" Basic.Settings.Advanced.Network="Netværk" Basic.Settings.Advanced.Network.BindToIP="Bind til IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivér ny netværkskode" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lav forsinkelsestilstand" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Deaktivér genvejstaster, når hovedvinduet er i fokus" +Basic.Settings.Advanced.AutoRemux="Remux automatisk til mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(optag som mkv)" Basic.AdvAudio="Avancerede lydegenskaber" Basic.AdvAudio.Name="Navn" -Basic.AdvAudio.Volume="Volumen (%)" +Basic.AdvAudio.Volume="Lydstyrke" Basic.AdvAudio.Mono="Nedmix til Mono" -Basic.AdvAudio.Panning="Panorering" +Basic.AdvAudio.Balance="Balance" Basic.AdvAudio.SyncOffset="Synkr-forskydning (ms)" Basic.AdvAudio.Monitoring="Lydovervågning" -Basic.AdvAudio.Monitoring.None="Overvågning fra" -Basic.AdvAudio.Monitoring.MonitorOnly="Kun overvågning (mute output)" +Basic.AdvAudio.Monitoring.None="Overvågning Fra" +Basic.AdvAudio.Monitoring.MonitorOnly="Kun overvågning (gør output tavs)" Basic.AdvAudio.Monitoring.Both="Overvåg og output" Basic.AdvAudio.AudioTracks="Spor" Basic.Settings.Hotkeys="Genvejstaster" Basic.Settings.Hotkeys.Pair="Tastekombinationer delt med '%1' fungerer som omskiftere" +Basic.Settings.Hotkeys.Filter="Filtrér" Basic.Hotkeys.SelectScene="Skift til scene" Basic.SystemTray.Show="Vis" Basic.SystemTray.Hide="Skjul" -Basic.SystemTray.Message.Reconnecting="Afbrudt. Forbinder igen..." +Basic.SystemTray.Message.Reconnecting="Afbrudt. Genforbinder..." Hotkeys.Insert="Insert" Hotkeys.Delete="Delete" @@ -738,23 +799,24 @@ Hotkeys.Super="Super" Hotkeys.Menu="Menu" Hotkeys.Space="Mellemrum" Hotkeys.NumpadNum="Numerisk %1" -Hotkeys.NumpadMultiply="Numeriske tastatur gange" -Hotkeys.NumpadDivide="Numeriske tastatur dividere" -Hotkeys.NumpadAdd="Numeriske tastatur plus" -Hotkeys.NumpadSubtract="Numeriske tastatur minus" -Hotkeys.NumpadDecimal="Numeriske tastatur komma" -Hotkeys.AppleKeypadNum="%1 (numeriske tastatur)" -Hotkeys.AppleKeypadMultiply="* (numeriske tastatur)" -Hotkeys.AppleKeypadDivide="/ (numeriske tastatur)" -Hotkeys.AppleKeypadAdd="+ (numeriske tastatur)" -Hotkeys.AppleKeypadSubtract="- (numeriske tastatur)" -Hotkeys.AppleKeypadDecimal=", (numeriske tastatur)" -Hotkeys.AppleKeypadEqual="= (numeriske tastatur)" +Hotkeys.NumpadMultiply="Numerisk, multiplicér" +Hotkeys.NumpadDivide="Numerisk, dividér" +Hotkeys.NumpadAdd="Numerisk, addér" +Hotkeys.NumpadSubtract="Numerisk, subtrahér" +Hotkeys.NumpadDecimal="Numerisk, decimaltegn" +Hotkeys.AppleKeypadNum="%1 (numerisk)" +Hotkeys.AppleKeypadMultiply="* (numerisk)" +Hotkeys.AppleKeypadDivide="/ (numerisk)" +Hotkeys.AppleKeypadAdd="+ (numerisk)" +Hotkeys.AppleKeypadSubtract="- (numerisk)" +Hotkeys.AppleKeypadDecimal=", (numerisk)" +Hotkeys.AppleKeypadEqual="= (numerisk)" Hotkeys.MouseButton="Mus %1" +Hotkeys.Escape="Esc" Mute="Lyd fra" Unmute="Lyd til" -Push-to-mute="Tryk-for-lydløs" +Push-to-mute="Tryk-gør-tavs" Push-to-talk="Tryk-for-tale" SceneItemShow="Vis '%1'" @@ -762,17 +824,32 @@ SceneItemHide="Skjul '%1'" OutputWarnings.NoTracksSelected="Du skal vælge minimum ét spor" OutputWarnings.MultiTrackRecording="Advarsel: Visse formater (såsom FLV) understøtter ikke flere spor pr. optagelse" -OutputWarnings.MP4Recording="Advarsel: MP4-optagelser vil ikke kunne genoprettes, hvis filen ikke kan færdiggøres (f.eks. som følge af BSODs, strømafbrydelse m.v.). Ønsker du at optage flere lydspor, overvej da at benytte MKV, og remuxe optagelsen til MP4, efter at den er færdiggjort (fil-> Remux optagelser)" +OutputWarnings.MP4Recording="Advarsel: MP4-/MOV-optagelser vil ikke kunne genoprettes, såfremt filen ikke kan færdiggøres (grundet f.eks. BSOD'er, strømafbrydelse mv.). Vil du optage flere lydspor, så overvej at benytte MKV, og remuxe optagelsen til MP4, efter at den er færdiggjort (Fil → Remux optagelser)" FinalScene.Title="Slet scene" -FinalScene.Text="Der kræves mindst én scene." +FinalScene.Text="Mindst én scene kræves." NoSources.Title="Ingen kilder" -NoSources.Text="Det ser ud til, at du ikke har tilføjet nogen videokilder endnu, så dit output bliver en blank/tom skærm. Sikker på, at du vil gøre dette?" +NoSources.Text="Det ser ud til, at du endnu ikke har tilføjet nogle videokilder, så dit output bliver en blank/tom skærm. Sikker på, at du vil gøre dette?" NoSources.Text.AddSource="Du kan til enhver tid tilføje kilder ved at klikke på +-ikonet under feltet Kilder i hovedvinduet." +NoSources.Label="Du har ingen kilder.\nKlik på knappen + nedenfor,\neller højreklik hér for at tilføje en." ChangeBG="Sæt farve" -CustomColor="Brugerdefineret farve" +CustomColor="Tilpasset farve" BrowserSource.EnableHardwareAcceleration="Aktivér Browser Source-hardwareacceleration" +About="Om" +About.Info="OBS Studio er en gratis og open source videooptagelses og live-streaming software." +About.Donate="Giv et bidrag" +About.GetInvolved="Deltag" +About.Authors="Forfattere" +About.License="Licens" +About.Contribute="Støt OBS-projektet" + +ResizeOutputSizeOfSource="Tilpas størrelse for output (kildestørrelse)" +ResizeOutputSizeOfSource.Text="Grund- og outputopløsningerne tilpasses den aktuelle kildes størrelse." +ResizeOutputSizeOfSource.Continue="Fortsæt?" + +PreviewTransition="Overgangsforhåndsvisning" + diff --git a/UI/data/locale/de-DE.ini b/UI/data/locale/de-DE.ini index 5051ea5..273602d 100644 --- a/UI/data/locale/de-DE.ini +++ b/UI/data/locale/de-DE.ini @@ -2,8 +2,8 @@ Language="Deutsch" Region="Deutschland" -OK="OK" -Apply="Übernehmen" +OK="Okay" +Apply="Anwenden" Cancel="Abbrechen" Close="Schließen" Save="Speichern" @@ -20,26 +20,26 @@ Properties="Eigenschaften" MoveUp="Nach oben bewegen" MoveDown="Nach unten bewegen" Settings="Einstellungen" -Display="Anzeige" +Display="Bildschirm" Name="Name" Exit="Beenden" Mixer="Mixer" Browse="Durchsuchen" Mono="Mono" Stereo="Stereo" -DroppedFrames="Ausgelassene Frames %1 (%2%)" -StudioProgramProjector="Vollbild-Projektor (Programm)" -PreviewProjector="Vollbild-Projektor (Vorschau)" -SceneProjector="Vollbild-Projektor (Szene)" -SourceProjector="Vollbild-Projektor (Quelle)" -StudioProgramWindow="Fenstermodus-Projektor (Programm)" -PreviewWindow="Fenstermodus-Projektor (Vorschau)" -SceneWindow="Fenstermodus-Projektor (Szene)" -SourceWindow="Fenstermodus-Projektor (Quelle)" +DroppedFrames="Ausgelassene Frames %1 (%2 %)" +StudioProgramProjector="Vollbildprojektor (Programm)" +PreviewProjector="Vollbildprojektor (Vorschau)" +SceneProjector="Vollbildprojektor (Szene)" +SourceProjector="Vollbildprojektor (Quelle)" +StudioProgramWindow="Fenstermodusprojektor (Programm)" +PreviewWindow="Fenstermodusprojektor (Vorschau)" +SceneWindow="Fenstermodusprojektor (Szene)" +SourceWindow="Fenstermodusprojektor (Quelle)" MultiviewProjector="Multiview (Vollbild)" MultiviewWindowed="Multiview (Fenstermodus)" Clear="Löschen" -Revert="Zurücksetzen" +Revert="Rückgängig" Show="Anzeigen" Hide="Ausblenden" UnhideAll="Alle einblenden" @@ -49,9 +49,9 @@ Duplicate="Duplizieren" Enable="Aktivieren" DisableOSXVSync="OSX V-Sync deaktivieren" ResetOSXVSyncOnExit="OSX V-Sync beim Beenden zurücksetzen" -HighResourceUsage="Codierung überlastet! Erwägen Sie Ihre Video-Einstellungen zu verringern, oder benutzen Sie eine schnellere Codierer-Voreinstellung." +HighResourceUsage="Kodierung überlastet! Erwägen Sie Ihre Videoeinstellungen zu verringern oder benutzen Sie eine schnellere Kodierervoreinstellung." Transition="Übergang" -QuickTransitions="Schnelle Übergänge" +QuickTransitions="Schnellübergänge" Left="Links" Right="Rechts" Top="Oben" @@ -61,14 +61,14 @@ Hours="Stunde(n)" Minutes="Minute(n)" Seconds="Sekunde(n)" Deprecated="Veraltet" -ReplayBuffer="Replaypuffer" +ReplayBuffer="Replay-Puffer" Import="Importieren" Export="Exportieren" Copy="Kopieren" Paste="Einfügen" PasteReference="Einfügen (Referenz)" PasteDuplicate="Einfügen (Duplikat)" -RemuxRecordings="Remuxe Aufnahmen" +RemuxRecordings="Aufnahmen remuxen" Next="Weiter" Back="Zurück" Defaults="Zurücksetzen" @@ -80,85 +80,119 @@ StudioMode.Program="Programm" ShowInMultiview="In Multiview anzeigen" VerticalLayout="Vertikales Layout" Group="Gruppe" +DoNotShowAgain="Nicht nochmal anzeigen" +Default="(Standard)" +Calculating="Berechne …" AlreadyRunning.Title="OBS wird bereits ausgeführt" -AlreadyRunning.Text="OBS wird bereits ausgeführt! Bitte beenden Sie alle vorhandenen OBS Instanzen bevor Sie eine neue Instanz starten, es sei denn, Sie tun dies absichtlich. Wenn Sie OBS so eingestellt haben das es sich zum Infobereich minimiert, überprüfen Sie bitte, ob es dort läuft." +AlreadyRunning.Text="OBS wird bereits ausgeführt! Bitte beenden Sie alle vorhandenen OBS-Instanzen, bevor Sie eine neue Instanz starten, außer Sie tun dies absichtlich. Wenn Sie OBS so eingestellt haben, dass es sich zum Infobereich minimiert, überprüfen Sie bitte, ob es dort läuft." AlreadyRunning.LaunchAnyway="Trotzdem starten" +DockCloseWarning.Title="Dockbares Fenster schließen" +DockCloseWarning.Text="Sie haben gerade ein dockbares Fenster geschlossen. Wenn Sie es erneut anzeigen möchten, verwenden Sie das Menü „Ansicht” → „Docks” in der Menüleiste." + +Auth.Authing.Title="Authentifizierung …" +Auth.Authing.Text="Authentifizierung mit %1, bitte warten …" +Auth.AuthFailure.Title="Authentifizierungsfehler" +Auth.AuthFailure.Text="Fehler beim Authentifizieren mit %1:\n\n%2: %3" +Auth.InvalidScope.Title="Authentifizierung erforderlich" +Auth.InvalidScope.Text="Die Authentifizierungsanforderungen für %1 haben sich geändert. Einige Funktionen sind möglicherweise nicht verfügbar." +Auth.LoadingChannel.Title="Kanalinformationen werden geladen …" +Auth.LoadingChannel.Text="Kanalinformationen werden für %1 geladen, bitte warten …" +Auth.ChannelFailure.Title="Fehler beim Laden des Kanals" +Auth.ChannelFailure.Text="Fehler beim Laden der Kanalinformationen für %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Streaminformation" +TwitchAuth.Stats="Twitch-Statistiken" +TwitchAuth.Feed="Twitch-Aktivitätsfeed" +TwitchAuth.TwoFactorFail.Title="Streamschlüssel konnte nicht abgefragt werden" +TwitchAuth.TwoFactorFail.Text="OBS konnte sich nicht mit Ihrem Twitch-Konto verbinden. Bitte stellen Sie sicher, dass die Zwei-Faktor-Authentifizierung in Ihren Twitch-Sicherheitseinstellungen eingerichtet ist, da diese für das Sreamen benötigt wird." + Copy.Filters="Filter kopieren" Paste.Filters="Filter einfügen" +BrowserPanelInit.Title="Initialisiere Browser …" +BrowserPanelInit.Text="Initialisiere Browser, bitte warten …" + BandwidthTest.Region="Region" BandwidthTest.Region.US="USA" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asien" BandwidthTest.Region.Other="Andere" -Basic.FirstStartup.RunWizard="Möchten Sie den Autokonfigurationsassistent ausführen? Sie können Ihre Einstellungen auch manuell konfigurieren, indem Sie den Einstellungen-Knopf im Hauptfenster anklicken." -Basic.FirstStartup.RunWizard.BetaWarning="(Hinweis: Der Autokonfigurationsassistent ist zurzeit im Betastatus)" -Basic.FirstStartup.RunWizard.NoClicked="Wenn Sie Ihre Meinung ändern, können Sie den Autokonfigurationsassistent jederzeit erneut aus dem Menü \"Werkzeuge\" ausführen." +Basic.FirstStartup.RunWizard="Möchten Sie den Autokonfigurationsassistent ausführen? Sie können Ihre Einstellungen auch manuell konfigurieren, indem Sie die „Einstellungen“-Schaltfläche im Hauptfenster anklicken." +Basic.FirstStartup.RunWizard.NoClicked="Wenn Sie sich umentscheiden, können Sie den Autokonfigurationsassistent jederzeit aus dem Menü „Werkzeuge“ erneut ausführen." Basic.AutoConfig="Autokonfigurationsassistent" -Basic.AutoConfig.Beta="Autokonfigurationsassistent (Beta)" -Basic.AutoConfig.ApplySettings="Einstellungen übernehmen" +Basic.AutoConfig.ApplySettings="Einstellungen anwenden" Basic.AutoConfig.StartPage="Informationen zur Verwendung" Basic.AutoConfig.StartPage.SubTitle="Geben Sie an, wofür Sie das Programm verwenden möchten" -Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimieren für Streaming, Aufnehmen ist zweitrangig" -Basic.AutoConfig.StartPage.PrioritizeRecording="Nur für die Aufnahme optimieren, ich werde nicht streamen" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Für das Streamen optimieren, Aufnehmen ist zweitrangig" +Basic.AutoConfig.StartPage.PrioritizeRecording="Für das Aufnehmen optimieren, Streamen ist zweitrangig" Basic.AutoConfig.VideoPage="Videoeinstellungen" Basic.AutoConfig.VideoPage.SubTitle="Geben Sie die gewünschten Videoeinstellungen an, die Sie verwenden möchten" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Aktuelle verwenden (%1x%2)" -Basic.AutoConfig.VideoPage.BaseResolution.Display="Anzeige %1 (%2x%3)" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Aktuelle verwenden (%1×%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Bildschirm %1 (%2×%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Aktuelle verwenden (%1)" -Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Entweder 60 oder 30, aber bevorzugt 60, wenn möglich" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Entweder 60 oder 30, aber wenn möglich 60 bevorzugen" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Entweder 60 oder 30, aber hohe Auflösung bevorzugen" -Basic.AutoConfig.VideoPage.CanvasExplanation="Hinweis: Die Basis (Leinwand) Auflösung ist nicht unbedingt die Gleiche Auflösung mit der Sie Streamen oder Aufnehmen. Ihre tatsächliche Stream- / Aufzeichnungsauflösung kann ausgehend von der Leinwandauflösung herunterskaliert werden, um die Ressourcennutzung oder die Bitratenanforderungen zu reduzieren." +Basic.AutoConfig.VideoPage.CanvasExplanation="Hinweis: Die Basis-(Leinwand-)Auflösung ist nicht unbedingt die gleiche Auflösung, mit der Sie streamen oder aufnehmen. Ihre tatsächliche Stream-/Aufnahmeauflösung kann ausgehend von der Leinwandauflösung herunterskaliert werden, um die Ressourcennutzung oder die Bitratenanforderungen zu reduzieren." Basic.AutoConfig.StreamPage="Streaminformationen" Basic.AutoConfig.StreamPage.SubTitle="Bitte geben Sie Ihre Streaminformationen ein" +Basic.AutoConfig.StreamPage.ConnectAccount="Konto verbinden (optional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Konto trennen" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Konto trennen?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Diese Änderung wird sofort angewendet. Sind Sie sicher, dass Sie Ihr Konto trennen möchten?" +Basic.AutoConfig.StreamPage.UseStreamKey="Streamschlüssel verwenden" Basic.AutoConfig.StreamPage.Service="Plattform" -Basic.AutoConfig.StreamPage.Service.ShowAll="Alle anzeigen..." +Basic.AutoConfig.StreamPage.Service.ShowAll="Alle anzeigen …" +Basic.AutoConfig.StreamPage.Service.Custom="Benutzerdefiniert …" Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Streamschlüssel" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="Schätzung der Bitrate mit Bandbreitentest (kann einige Minuten dauern)" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Hardware-Codierung bevorzugen" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardware-Codierung beseitigt die meiste CPU-Auslastung, kann aber mehr Bitrate erfordern, um das gleiche Maß an Qualität zu erhalten." +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Bitrate mit Bandbreitentest schätzen (kann einige Minuten dauern)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Hardwarekodierung bevorzugen" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardwarekodierung beseitigt die meiste CPU-Auslastung, kann aber mehr Bitrate erfordern, um das gleiche Maß an Qualität zu erhalten." Basic.AutoConfig.StreamPage.StreamWarning.Title="Streamwarnung" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Der Bandbreitentest ist im Begriff, randomisierte Videodaten ohne Ton zu Ihrem Kanal zu streamen. Wenn Sie in der Lage sind, empfiehlt es sich, vorübergehend das Speichern von Videos abzuschalten und den Stream privat zu schalten, bis der Test abgeschlossen ist. Fortfahren?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Der Bandbreitentest streamt randomisierte Videodaten ohne Ton zu Ihrem Kanal. Wenn Sie in der Lage sind, empfiehlt es sich, vorübergehend das Speichern von Videos zu deaktivieren und den Stream privat zu schalten, bis der Test abgeschlossen ist. Fortfahren?" Basic.AutoConfig.TestPage="Endergebnisse" -Basic.AutoConfig.TestPage.SubTitle.Testing="Das Programm führt nun eine Reihe von Tests durch, um die idealen Einstellungen abzuschätzen" +Basic.AutoConfig.TestPage.SubTitle.Testing="Das Programm führt nun eine Reihe von Tests durch, um die besten Einstellungen für Ihr System zu finden" Basic.AutoConfig.TestPage.SubTitle.Complete="Tests abgeschlossen" -Basic.AutoConfig.TestPage.TestingBandwidth="Führe Bandbreitentests durch, dies kann einige Minuten dauern..." -Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Verbinde zu: %1..." -Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Keine Verbindung zu den Servern möglich, bitte überprüfen Sie ihre Internetverbindung und versuchen Sie es erneut." +Basic.AutoConfig.TestPage.TestingBandwidth="Führe Bandbreitentests durch, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Verbinde zu: %1 …" +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Keine Verbindung zu den Servern möglich, bitte überprüfen Sie Ihre Internetverbindung und versuchen Sie es erneut." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Teste Bandbreite für: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="Teste Streamcodierer, dies kann einige Minuten dauern..." -Basic.AutoConfig.TestPage.TestingRecordingEncoder="Teste Aufnahmecodierer, dies kann einige Minuten dauern..." -Basic.AutoConfig.TestPage.TestingRes="Teste Auflösungen, dies kann einige Minuten dauern..." -Basic.AutoConfig.TestPage.TestingRes.Fail="Fehler beim Starten des Codierers" -Basic.AutoConfig.TestPage.TestingRes.Resolution="Teste %1x%2 %3 FPS..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streamcodierer" -Basic.AutoConfig.TestPage.Result.RecordingEncoder="Aufnahmecodierer" -Basic.AutoConfig.TestPage.Result.Header="Das Programm hat festgestellt, dass diese geschätzten Einstellungen für Sie am idealsten sind:" -Basic.AutoConfig.TestPage.Result.Footer="Um den Assistenten neu zu konfigurieren und es erneut zu versuchen, klicken Sie auf Zurück." +Basic.AutoConfig.TestPage.TestingStreamEncoder="Teste Streamkodierer, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Teste Aufnahmekodierer, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingRes="Teste Auflösungen, dies kann einige Minuten dauern …" +Basic.AutoConfig.TestPage.TestingRes.Fail="Fehler beim Starten des Kodierers" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Teste Auflösung %1×%2 mit %3 FPS …" +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streamkodierer" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Aufnahmekodierer" +Basic.AutoConfig.TestPage.Result.Header="Das Programm hat festgestellt, dass diese geschätzten Einstellungen für Sie am besten sind:" +Basic.AutoConfig.TestPage.Result.Footer="Um den Assistenten neu zu konfigurieren und es erneut zu versuchen, klicken Sie auf „Zurück“. Um die Einstellungen selbst anzupassen, klicken Sie auf „Abbrechen“ und öffnen Sie die Einstellungen." Basic.Stats="Statistiken" Basic.Stats.CPUUsage="CPU-Auslastung" -Basic.Stats.HDDSpaceAvailable="Festplattenspeicher verfügbar" +Basic.Stats.HDDSpaceAvailable="Speicherplatz verfügbar" Basic.Stats.MemoryUsage="Speicherauslastung" Basic.Stats.AverageTimeToRender="Durchschnittliche Zeit, um Frame zu rendern" -Basic.Stats.SkippedFrames="Übersprungene Frames, wegen Codierungsverzögerung" -Basic.Stats.MissedFrames="Ausgelassene Frames. wegen Renderingverzögerung" +Basic.Stats.SkippedFrames="Übersprungene Frames durch Kodierungsverzögerung" +Basic.Stats.MissedFrames="Ausgelassene Frames durch Renderingverzögerung" Basic.Stats.Output.Stream="Stream" Basic.Stats.Output.Recording="Aufnahme" Basic.Stats.Status="Status" -Basic.Stats.Status.Recording="Aufnahme" +Basic.Stats.Status.Recording="Aufnehmen" Basic.Stats.Status.Live="LIVE" Basic.Stats.Status.Reconnecting="Erneut verbinden" Basic.Stats.Status.Inactive="Inaktiv" -Basic.Stats.DroppedFrames="Verworfene Frames (Netzwerk)" +Basic.Stats.DroppedFrames="Ausgelassene Frames (Netzwerk)" Basic.Stats.MegabytesSent="Insgesamte Datenausgabe" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Datenträger voll in ugf." + +ResetUIWarning.Title="Sind Sie sicher, dass Sie die Benutzeroberfläche zurücksetzen möchten?" +ResetUIWarning.Text="Das Zurücksetzen der Benutzeroberfläche wird zusätzliche Docks ausblenden. Sie müssen diese Docks im „Ansicht“-Menü wieder aktivieren, wenn sie sichtbar sein sollen.\n\nSind Sie sicher, dass Sie die Benutzeroberfläche zurücksetzen möchten?" Updater.Title="Neues Update verfügbar" Updater.Text="Es ist ein neues Update verfügbar:" @@ -171,15 +205,15 @@ Updater.NoUpdatesAvailable.Title="Keine Updates verfügbar" Updater.NoUpdatesAvailable.Text="Zurzeit sind keine Updates verfügbar" Updater.FailedToLaunch="Konnte den Updater nicht starten" Updater.GameCaptureActive.Title="Spielaufnahme aktiv" -Updater.GameCaptureActive.Text="Spielaufnahme Hook Bibliothek wird zurzeit verwendet. Bitte schließen Sie alle derzeitigen Spiele / Programme die aufgenommen werden (oder starten Sie Windows neu) und versuchen Sie es erneut." +Updater.GameCaptureActive.Text="Die Spielaufnahmen-Hook-Bibliothek wird zurzeit verwendet. Bitte schließen Sie alle derzeit aufgenommenen Programme und Spiele (oder starten Sie Windows neu) und versuchen Sie es erneut." -QuickTransitions.SwapScenes="Tausche Vorschau/Ausgabe-Szenen nach dem Übergang" -QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabe-Szenen nach dem Übergang (falls die ursprüngliche Ausgabe-Szene noch vorhanden ist).\nEventuelle Änderungen an der original Ausgabe-Szene werden hierbei nicht rückgängig gemacht." -QuickTransitions.DuplicateScene="Dupliziere Szene" -QuickTransitions.DuplicateSceneTT="Ermöglicht das Bearbeiten von Transformationen und der Sichtbarkeit von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nAktivieren Sie 'Dupliziere Szene' um die Eigenschaften von Quellen zu bearbeiten, ohne die Ausgabe zu verändern.\nDas Ändern dieses Wertes wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert)." -QuickTransitions.EditProperties="Dupliziere Quellen" -QuickTransitions.EditPropertiesTT="Ermöglicht das Bearbeiten der Eigenschaften von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nDies kann nur verwendet werden, wenn 'Dupliziere Szene' aktiviert ist.\nBestimmte Quellen (wie Aufnahme- oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\n Das Ändern dieses Wertes wird die derzeitige Ausgabe-Szene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System- oder Videoressourcen verbrauchen." -QuickTransitions.HotkeyName="Schneller Übergang: %1" +QuickTransitions.SwapScenes="Vorschau-/Ausgabeszene nach Übergang tauschen" +QuickTransitions.SwapScenesTT="Vertauscht die Vorschau- und Ausgabeszenen nach dem Übergang (falls die ursprüngliche Ausgabeszene noch vorhanden ist).\nEventuelle Änderungen an der originalen Ausgabeszene werden nicht rückgängig gemacht." +QuickTransitions.DuplicateScene="Szene duplizieren" +QuickTransitions.DuplicateSceneTT="Ermöglicht das Bearbeiten von Transformationen und der Sichtbarkeit von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nAktivieren Sie „Szene duplizieren“, um die Eigenschaften von Quellen zu bearbeiten, ohne die Ausgabe zu verändern.\nDas Ändern dieses Wertes wird die derzeitige Ausgabeszene zurücksetzen (falls sie noch existiert)." +QuickTransitions.EditProperties="Quellen duplizieren" +QuickTransitions.EditPropertiesTT="Ermöglicht das Bearbeiten der Eigenschaften von Quellen, ohne die Ausgabe zu verändern, wenn dieselbe Szene bearbeitet wird.\nDies kann nur verwendet werden, wenn „Szene duplizieren“ aktiviert ist.\nBestimmte Quellen (wie Aufnahme- oder Medienquellen) unterstützen dies nicht und können nicht separat bearbeitet werden.\nDas Ändern dieses Wertes wird die derzeitige Ausgabeszene zurücksetzen (falls sie noch existiert).\n\nWarnung: Da Quellen dupliziert werden, könnte dies zusätzliche System- oder Videoressourcen verbrauchen." +QuickTransitions.HotkeyName="Schnellübergang: %1" Basic.AddTransition="Konfigurierbaren Übergang hinzufügen" Basic.RemoveTransition="Konfigurierbaren Übergang entfernen" @@ -204,68 +238,74 @@ ConfirmStart.Title="Stream starten?" ConfirmStart.Text="Sind Sie sicher, dass Sie den Stream starten möchten?" ConfirmStop.Title="Stream stoppen?" -ConfirmStop.Text="Sind Sie sicher, dass Sie den Stream beenden möchten?" +ConfirmStop.Text="Sind Sie sicher, dass Sie den Stream stoppen möchten?" + +ConfirmBWTest.Title="Bandbreitentest starten?" +ConfirmBWTest.Text="Sie haben OBS im Bandbreitentestmodus konfiguriert. In diesem Modus können Sie Netzwerktests durchführen, ohne dass Ihr Kanal live geschaltet wird. Sobald Sie fertig mit dem Testen sind, müssen Sie ihn deaktivieren, damit die Zuschauer Ihren Stream sehen können.\n\nMöchten Sie fortfahren?" ConfirmExit.Title="OBS beenden?" -ConfirmExit.Text="OBS ist derzeit aktiv. Alle Streams/Aufnahmen werden beendet. Sind Sie sicher, dass Sie OBS beenden möchten?" +ConfirmExit.Text="OBS ist derzeit aktiv. Alle Streams/Aufnahmen werden gestoppt. Sind Sie sicher, dass Sie OBS beenden möchten?" ConfirmRemove.Title="Entfernen bestätigen" -ConfirmRemove.Text="Sind Sie sicher, dass Sie '$1' entfernen möchten?" +ConfirmRemove.Text="Sind Sie sicher, dass Sie „$1“ entfernen möchten?" ConfirmRemove.TextMultiple="Sind Sie sicher, dass Sie %1 Elemente löschen möchten?" -Output.StartStreamFailed="Fehler beim Start des Streams" +Output.StartStreamFailed="Fehler beim Starten des Streams" Output.StartRecordingFailed="Fehler beim Starten der Aufnahme" Output.StartReplayFailed="Fehler beim Starten des Replaypuffers" -Output.StartFailedGeneric="Start der Ausgabe fehlgeschlagen. Bitte überprüfen Sie die Logdatei für Details.\n\nHinweis: Wenn Sie die NVENC- oder AMD-Codierer verwenden, stellen Sie sicher, dass Ihre Videotreiber aktuell sind." +Output.StartFailedGeneric="Start der Ausgabe fehlgeschlagen. Bitte überprüfen Sie die Protokolldatei für Details.\n\nHinweis: Wenn Sie die NVENC- oder AMD-Kodierer verwenden, stellen Sie sicher, dass Ihre Videotreiber aktuell sind." + Output.ConnectFail.Title="Verbindung fehlgeschlagen" Output.ConnectFail.BadPath="Ungültiger Pfad oder Verbindungs-URL. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass diese korrekt sind." Output.ConnectFail.ConnectFailed="Verbindung zum Server fehlgeschlagen" -Output.ConnectFail.InvalidStream="Konnte nicht auf den angegebenen Kanal oder Stream-Key zugreifen. Bitte überprüfen Sie den eingegebenen Stream-Key. Wenn er richtig ist, kann es ein Problem beim Verbinden mit dem Server gegeben haben." -Output.ConnectFail.Error="Ein unerwarteter Fehler ist beim Verbindungsversuch zum Server aufgetreten. Mehr Informationen finden Sie in der Logdatei." +Output.ConnectFail.InvalidStream="Konnte nicht auf den angegebenen Kanal oder Streamschlüssel zugreifen. Bitte überprüfen Sie den eingegebenen Streamschlüssel. Wenn er richtig ist, kann es ein Problem beim Verbinden mit dem Server gegeben haben." +Output.ConnectFail.Error="Ein unerwarteter Fehler ist beim Verbindungsversuch zum Server aufgetreten. Mehr Informationen finden Sie in der Protokolldatei." Output.ConnectFail.Disconnected="Verbindung zum Server getrennt." +Output.StreamEncodeError.Title="Kodierungsfehler" +Output.StreamEncodeError.Msg="Ein Kodierungsfehler ist beim Streaming aufgetreten." + Output.RecordFail.Title="Fehler beim Starten der Aufnahme" -Output.RecordFail.Unsupported="Das Ausgabeformat wird entweder nicht unterstützt oder unterstützt nicht mehrere Audiospuren. Bitte überprüfen Sie Ihre Einstellungen und versuchen Sie es erneut." +Output.RecordFail.Unsupported="Das Ausgabeformat wird entweder nicht unterstützt oder unterstützt nicht mehrere Audiospuren. Bitte überprüfen Sie Ihre Einstellungen und versuchen Sie es erneut." Output.RecordNoSpace.Title="Nicht genügend Speicherplatz" Output.RecordNoSpace.Msg="Es gibt nicht genügend Speicherplatz, um die Aufnahme fortzusetzen." Output.RecordError.Title="Aufnahmefehler" Output.RecordError.Msg="Während der Aufnahme ist ein unbekannter Fehler aufgetreten." -Output.ReplayBuffer.NoHotkey.Title="Kein Hotkey festgelegt!" -Output.ReplayBuffer.NoHotkey.Msg="Kein Speichern Hotkey festgelegt für Replaypuffer. Legen Sie bitte den \"Speichern\" Hotkey fest, der zum Speichern der Replayaufnahmen verwendet werden soll." +Output.RecordError.EncodeErrorMsg="Ein Kodierungsfehler ist beim Aufnehmen aufgetreten." +Output.ReplayBuffer.NoHotkey.Title="Kein Hotkey festgelegt" +Output.ReplayBuffer.NoHotkey.Msg="Kein „Replay speichern“-Hotkey für Replaypuffer festgelegt. Legen Sie bitte den „Speichern“-Hotkey fest, der zum Speichern der Replayaufnahmen verwendet werden soll." Output.BadPath.Title="Ungültiger Dateipfad" Output.BadPath.Text="Der konfigurierte Ausgabepfad ist ungültig. Bitte überprüfen Sie Ihre Einstellungen und stellen Sie sicher, dass ein gültiger Pfad angegeben wurde." -LogReturnDialog="Log Upload erfolgreich" +LogReturnDialog="Protokoll erfolgreich hochgeladen" LogReturnDialog.CopyURL="URL kopieren" -LogReturnDialog.ErrorUploadingLog="Fehler beim Upload der Logdatei" +LogReturnDialog.ErrorUploadingLog="Fehler beim Hochladen der Protokolldatei" -LicenseAgreement="Lizenzvereinbarung" -LicenseAgreement.PleaseReview="Bitte lesen Sie die Lizenzbedingungen vor der Verwendung von OBS. Mit der Verwendung dieses Programms bestätigen Sie, dass Sie diese gelesen haben und den Bedingungen der GNU General Public License v2.0 zustimmen. Bitte scrollen Sie nach unten, um den Rest der Vereinbarung zu sehen." -LicenseAgreement.ClickIAgreeToContinue="Wenn Sie die Vereinbarung akzeptieren, klicken Sie auf ich stimme zu, um fortzufahren. Sie müssen akzeptieren, um OBS verwenden zu können." -LicenseAgreement.IAgree="Ich stimme zu" -LicenseAgreement.Exit="Beenden" - -Remux.SourceFile="OBS Aufnahme" +Remux.SourceFile="OBS-Aufnahme" Remux.TargetFile="Zieldatei" Remux.Remux="Remuxen" -Remux.OBSRecording="OBS Aufnahme" +Remux.Stop="Remuxen stoppen" +Remux.ClearFinished="Fertiggestellte Objekte entfernen" +Remux.ClearAll="Alle Objekte entfernen" +Remux.OBSRecording="OBS-Aufnahme" Remux.FinishedTitle="Remuxen beendet" Remux.Finished="Aufnahme remuxed" Remux.FinishedError="Aufnahme remuxed, aber die Datei könnte unvollständig sein" -Remux.SelectRecording="Wählen Sie die OBS Aufnahme aus …" -Remux.SelectTarget="Wähle Zieldatei …" -Remux.FileExistsTitle="Zieldatei ist bereits vorhanden" -Remux.FileExists="Zieldatei ist bereits vorhanden. Möchten Sie diese ersetzen?" +Remux.SelectRecording="OBS-Aufnahme auswählen …" +Remux.SelectTarget="Zieldatei auswählen" +Remux.FileExistsTitle="Zieldateien existieren bereits" +Remux.FileExists="Die folgenden Zieldateien existieren bereits. Möchten Sie diese ersetzen?" Remux.ExitUnfinishedTitle="Remuxen in Bearbeitung" -Remux.ExitUnfinished="Das Remuxen ist noch nicht fertig. Wenn Sie jetzt stoppen, kann die Zieldatei unbrauchbar werden. \nSind Sie sicher, dass Sie das Remuxen beenden möchten?" +Remux.ExitUnfinished="Das Remuxen ist noch nicht beendet. Wenn Sie jetzt stoppen, kann die Zieldatei unbrauchbar werden.\nSind Sie sicher, dass Sie das Remuxen beenden möchten?" +Remux.HelpText="Legen Sie Dateien in diesem Fenster ab, um sie zu remuxen oder wählen Sie eine leere „OBS-Aufnahme“-Zelle aus, um nach einer Datei zu suchen." UpdateAvailable="Neues Update verfügbar" -UpdateAvailable.Text="Version %1.%2.%3 ist nun verfügbar. Hier klicken zum Download" +UpdateAvailable.Text="Version %1.%2.%3 ist nun verfügbar. Hier klicken zum Herunterladen" -Basic.DesktopDevice1="Desktop Audio" -Basic.DesktopDevice2="Desktop Audio 2" +Basic.DesktopDevice1="Desktop-Audio" +Basic.DesktopDevice2="Desktop-Audio 2" Basic.AuxDevice1="Mic/Aux" Basic.AuxDevice2="Mic/Aux 2" Basic.AuxDevice3="Mic/Aux 3" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Monitoraufnahme" Basic.Main.PreviewConextMenu.Enable="Vorschau aktivieren" +Basic.Main.Preview.Disable="Vorschau deaktivieren" + ScaleFiltering="Skalierungsfilterung" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Bereich" Deinterlacing="Zeilenentflechtung (Deinterlacing)" Deinterlacing.Discard="Verwerfen" @@ -294,20 +337,20 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="Oberes Feld zuerst" Deinterlacing.BottomFieldFirst="Unteres Feld zuerst" -VolControl.SliderUnmuted="Lautstärke-Schieberegler für '%1': %2" -VolControl.SliderMuted="Lautstärke-Schieberegler für '%1': %2 (derzeit stumm geschaltet)" -VolControl.Mute="'%1' stumm schalten" -VolControl.Properties="Eigenschaften von '%1'" +VolControl.SliderUnmuted="Lautstärkeschieberegler für „%1“: %2" +VolControl.SliderMuted="Lautstärkeschieberegler für „%1“: %2 (derzeit stummgeschaltet)" +VolControl.Mute="„%1“ stummschalten" +VolControl.Properties="Eigenschaften von „%1“" Basic.Main.AddSceneDlg.Title="Szene hinzufügen" -Basic.Main.AddSceneDlg.Text="Bitte geben Sie einen Namen für die Szene ein" +Basic.Main.AddSceneDlg.Text="Bitte geben Sie den Namen der Szene ein" Basic.Main.DefaultSceneName.Text="Szene %1" -Basic.Main.AddSceneCollection.Title="Szenen-Sammlung hinzufügen" -Basic.Main.AddSceneCollection.Text="Bitte geben Sie den Namen der Szenen-Sammlung ein" +Basic.Main.AddSceneCollection.Title="Szenensammlung hinzufügen" +Basic.Main.AddSceneCollection.Text="Bitte geben Sie den Namen der Szenensammlung ein" -Basic.Main.RenameSceneCollection.Title="Szenen-Sammlung umbenennen" +Basic.Main.RenameSceneCollection.Title="Szenensammlung umbenennen" AddProfile.Title="Profil hinzufügen" AddProfile.Text="Bitte geben Sie den Namen des Profils ein" @@ -315,7 +358,7 @@ AddProfile.Text="Bitte geben Sie den Namen des Profils ein" RenameProfile.Title="Profil umbenennen" Basic.Main.MixerRename.Title="Audioquelle umbenennen" -Basic.Main.MixerRename.Text="Bitte geben Sie einen Namen für die Audioquelle ein" +Basic.Main.MixerRename.Text="Bitte geben Sie den Namen der Audioquelle ein" Basic.Main.PreviewDisabled="Vorschau ist derzeit deaktiviert" @@ -325,7 +368,7 @@ Basic.SourceSelect.CreateNew="Neu erstellen" Basic.SourceSelect.AddExisting="Existierende hinzufügen" Basic.SourceSelect.AddVisible="Quelle sichtbar machen" -Basic.PropertiesWindow="Eigenschaften von '%1'" +Basic.PropertiesWindow="Eigenschaften von „%1“" Basic.PropertiesWindow.AutoSelectFormat="%1 (automatisch ausgewählt: %2)" Basic.PropertiesWindow.SelectColor="Farbe auswählen" Basic.PropertiesWindow.SelectFont="Schriftart auswählen" @@ -333,21 +376,21 @@ Basic.PropertiesWindow.ConfirmTitle="Einstellungen geändert" Basic.PropertiesWindow.Confirm="Es gibt ungesicherte Änderungen. Möchten Sie diese behalten?" Basic.PropertiesWindow.NoProperties="Keine Eigenschaften verfügbar" Basic.PropertiesWindow.AddFiles="Dateien hinzufügen" -Basic.PropertiesWindow.AddDir="Verzeichnis hinzufügen" +Basic.PropertiesWindow.AddDir="Ordner hinzufügen" Basic.PropertiesWindow.AddURL="Pfad/URL hinzufügen" -Basic.PropertiesWindow.AddEditableListDir="Verzeichnis zu '%1' hinzufügen" -Basic.PropertiesWindow.AddEditableListFiles="Dateien zu '%1' hinzufügen" -Basic.PropertiesWindow.AddEditableListEntry="Eintrag zu '%1' hinzufügen" -Basic.PropertiesWindow.EditEditableListEntry="Eintrag aus '%1' bearbeiten" +Basic.PropertiesWindow.AddEditableListDir="Ordner zu „%1“ hinzufügen" +Basic.PropertiesWindow.AddEditableListFiles="Dateien zu „%1“ hinzufügen" +Basic.PropertiesWindow.AddEditableListEntry="Eintrag zu „%1“ hinzufügen" +Basic.PropertiesWindow.EditEditableListEntry="Eintrag aus „%1“ bearbeiten" Basic.PropertiesView.FPS.Simple="Einfache FPS-Werte" Basic.PropertiesView.FPS.Rational="Rationale FPS-Werte" Basic.PropertiesView.FPS.ValidFPSRanges="Gültige FPS-Bereiche:" -Basic.InteractionWindow="Interagiere mit '%1'" +Basic.InteractionWindow="Mit „%1“ interagieren" Basic.StatusBar.Reconnecting="Verbindung getrennt; Verbindungsversuch %1 in %2 Sekunde(n)" -Basic.StatusBar.AttemptingReconnect="Versuche die Verbindung wiederherzustellen ... (Versuch %1)" +Basic.StatusBar.AttemptingReconnect="Versuche die Verbindung wiederherzustellen … (Versuch %1)" Basic.StatusBar.ReconnectSuccessful="Wiederverbinden erfolgreich" Basic.StatusBar.Delay="Verzögerung (%1 s)" Basic.StatusBar.DelayStartingIn="Verzögerung (starte in %1 s)" @@ -355,14 +398,14 @@ Basic.StatusBar.DelayStoppingIn="Verzögerung (stoppe in %1 s)" Basic.StatusBar.DelayStartingStoppingIn="Verzögerung (stoppe in %1 s, beginne in %2 s)" Basic.Filters="Filter" -Basic.Filters.AsyncFilters="Audio/Video Filter" +Basic.Filters.AsyncFilters="Audio-/Videofilter" Basic.Filters.AudioFilters="Audiofilter" Basic.Filters.EffectFilters="Effektfilter" -Basic.Filters.Title="Filter für '%1'" +Basic.Filters.Title="Filter für „%1“" Basic.Filters.AddFilter.Title="Filtername" Basic.Filters.AddFilter.Text="Bitte geben Sie einen Namen für den Filter ein" -Basic.TransformWindow="Szenen-Element-Transformation" +Basic.TransformWindow="Szenen-Elementtransformation" Basic.TransformWindow.Position="Position" Basic.TransformWindow.Rotation="Drehung" Basic.TransformWindow.Size="Größe" @@ -390,23 +433,23 @@ Basic.TransformWindow.BoundsType.ScaleToWidth="Auf die Breite der Begrenzungen s Basic.TransformWindow.BoundsType.ScaleToHeight="Auf die Höhe der Begrenzungen skalieren" Basic.TransformWindow.BoundsType.Stretch="Bis zu den Begrenzungen strecken" -Basic.Main.AddSourceHelp.Title="Konnte Quelle nicht hinzufügen" +Basic.Main.AddSourceHelp.Title="Quelle konnte nicht hinzugefügt werden" Basic.Main.AddSourceHelp.Text="Sie müssen mindestens 1 Szene besitzen, um eine Quelle hinzuzufügen." Basic.Main.Scenes="Szenen" Basic.Main.Sources="Quellen" Basic.Main.Controls="Steuerung" -Basic.Main.Connecting="Verbinden..." +Basic.Main.Connecting="Verbinden …" Basic.Main.StartRecording="Aufnahme starten" Basic.Main.StartReplayBuffer="Replaypuffer starten" Basic.Main.StartStreaming="Streaming starten" Basic.Main.StopRecording="Aufnahme stoppen" -Basic.Main.StoppingRecording="Stoppe Aufnahme..." +Basic.Main.StoppingRecording="Stoppe Aufnahme ..." Basic.Main.StopReplayBuffer="Replaypuffer stoppen" -Basic.Main.StoppingReplayBuffer="Stoppe Replaypuffer..." +Basic.Main.StoppingReplayBuffer="Stoppe Replaypuffer …" Basic.Main.StopStreaming="Streaming stoppen" -Basic.Main.StoppingStreaming="Stoppe Stream..." -Basic.Main.ForceStopStreaming="Streaming stoppen (Verzögerung verwerfen)" +Basic.Main.StoppingStreaming="Stoppe Stream …" +Basic.Main.ForceStopStreaming="Streaming stoppen (Verzögerung missachten)" Basic.Main.Group="Gruppe %1" Basic.Main.GroupItems="Ausgewählte Elemente gruppieren" Basic.Main.Ungroup="Gruppierung aufheben" @@ -414,10 +457,10 @@ Basic.Main.Ungroup="Gruppierung aufheben" Basic.MainMenu.File="Datei (&F)" Basic.MainMenu.File.Export="&Exportieren" Basic.MainMenu.File.Import="&Importieren" -Basic.MainMenu.File.ShowRecordings="Zeige Aufnahmen (&R)" -Basic.MainMenu.File.Remux="Re&muxe Aufnahmen" +Basic.MainMenu.File.ShowRecordings="Aufnahmen anzeigen (&R)" +Basic.MainMenu.File.Remux="Aufnahmen re&muxen" Basic.MainMenu.File.Settings="Ein&stellungen" -Basic.MainMenu.File.ShowSettingsFolder="Einstellungen-Ordner anzeigen" +Basic.MainMenu.File.ShowSettingsFolder="Einstellungenordner anzeigen" Basic.MainMenu.File.ShowProfileFolder="Profilordner anzeigen" Basic.MainMenu.AlwaysOnTop="Immer im Vordergrund (&A)" Basic.MainMenu.File.Exit="Beenden (&X)" @@ -430,10 +473,10 @@ Basic.MainMenu.Edit.RedoAction="$1 Wiede&rherstellen" Basic.MainMenu.Edit.LockPreview="Vorschau sperren (&L)" Basic.MainMenu.Edit.Scale="Vorschau&skalierung" Basic.MainMenu.Edit.Scale.Window="An Fenstergröße anpassen" -Basic.MainMenu.Edit.Scale.Canvas="Leinwand (%1x%2)" -Basic.MainMenu.Edit.Scale.Output="Ausgabe (%1x%2)" +Basic.MainMenu.Edit.Scale.Canvas="Leinwand (%1×%2)" +Basic.MainMenu.Edit.Scale.Output="Ausgabe (%1×%2)" Basic.MainMenu.Edit.Transform="&Transformieren" -Basic.MainMenu.Edit.Transform.EditTransform="Transformation b&earbeiten..." +Basic.MainMenu.Edit.Transform.EditTransform="Transformation b&earbeiten …" Basic.MainMenu.Edit.Transform.CopyTransform="Transformation kopieren" Basic.MainMenu.Edit.Transform.PasteTransform="Transformation einfügen" Basic.MainMenu.Edit.Transform.ResetTransform="Transformation zu&rücksetzen" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="&Vertikal spiegeln" Basic.MainMenu.Edit.Transform.FitToScreen="An Bildschirmgröße anpassen (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Auf Bildschirmgröße &strecken" Basic.MainMenu.Edit.Transform.CenterToScreen="Auf dem Bildschirm zentrieren (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Vertikal zentrieren" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Horizontal zentrieren" Basic.MainMenu.Edit.Order="Reihenf&olge" Basic.MainMenu.Edit.Order.MoveUp="Nach oben bewegen (&U)" Basic.MainMenu.Edit.Order.MoveDown="Nach unten bewegen (&D)" @@ -460,34 +505,35 @@ Basic.MainMenu.View.Docks.LockUI="GUI sperren" Basic.MainMenu.View.Toolbars.Listboxes="&Listenfelder" Basic.MainMenu.View.SceneTransitions="Szenenübergänge (&c)" Basic.MainMenu.View.StatusBar="&Statusleiste" -Basic.MainMenu.View.Fullscreen.Interface="Vollbild-Benutzeroberfläche" +Basic.MainMenu.View.Fullscreen.Interface="Vollbildbenutzeroberfläche" -Basic.MainMenu.SceneCollection="&Szenen-Sammlung" +Basic.MainMenu.SceneCollection="&Szenensammlung" Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Profile.Import="Profil importieren" Basic.MainMenu.Profile.Export="Profil exportieren" -Basic.MainMenu.SceneCollection.Import="Szenen-Sammlung importieren" -Basic.MainMenu.SceneCollection.Export="Szenen-Sammlung exportieren" +Basic.MainMenu.SceneCollection.Import="Szenensammlung importieren" +Basic.MainMenu.SceneCollection.Export="Szenensammlung exportieren" Basic.MainMenu.Profile.Exists="Das Profil ist bereits vorhanden" -Basic.MainMenu.SceneCollection.Exists="Die Szenen-Sammlung existiert bereits" +Basic.MainMenu.SceneCollection.Exists="Die Szenensammlung existiert bereits" Basic.MainMenu.Tools="Werkzeuge (&T)" Basic.MainMenu.Help="&Hilfe" Basic.MainMenu.Help.HelpPortal="Hilfe&portal" Basic.MainMenu.Help.Website="&Webseite besuchen" -Basic.MainMenu.Help.Discord="Tritt unserem &Discordserver bei" -Basic.MainMenu.Help.Logs="&Logdateien" -Basic.MainMenu.Help.Logs.ShowLogs="Logdateien anzeigen (&S)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload aktuelle Logdatei (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="Upload &letzte Logdatei" +Basic.MainMenu.Help.Discord="Unserem &Discord-Server beitreten" +Basic.MainMenu.Help.Logs="Protoko&lldateien" +Basic.MainMenu.Help.Logs.ShowLogs="Protokolldateien anzeigen (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Aktuelle Protokolldatei hochladen (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Neuste Protoko&lldatei hochladen" Basic.MainMenu.Help.Logs.ViewCurrentLog="Aktuelles Protokoll anzeigen (&V)" -Basic.MainMenu.Help.CheckForUpdates="Auf Updates prüfen" +Basic.MainMenu.Help.CheckForUpdates="Nach Updates suchen" Basic.MainMenu.Help.CrashLogs="Abstu&rzberichte" Basic.MainMenu.Help.CrashLogs.ShowLogs="Ab&sturzberichte anzeigen" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Upload &letzten Absturzbericht" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Neusten Absturzbericht hoch&laden" +Basic.MainMenu.Help.About="Über OBS Studio (&A)" -Basic.Settings.ProgramRestart="Das Programm muss neu gestartet werden, damit die Änderungen wirksam werden." +Basic.Settings.ProgramRestart="Das Programm muss neugestartet werden, damit die Änderungen wirksam werden." Basic.Settings.ConfirmTitle="Änderungen bestätigen" Basic.Settings.Confirm="Sie haben ungespeicherte Änderungen. Änderungen speichern?" @@ -506,21 +552,26 @@ Basic.Settings.General.ScreenSnapping="Quellen am Bildschirmrand ausrichten" Basic.Settings.General.CenterSnapping="Quellen zur horizontalen und vertikalen Mitte ausrichten" Basic.Settings.General.SourceSnapping="Quellen an anderen Quellen ausrichten" Basic.Settings.General.SnapDistance="Ausrichtungsempfindlichkeit" -Basic.Settings.General.RecordWhenStreaming="Livestream automatisch aufnehmen" -Basic.Settings.General.KeepRecordingWhenStreamStops="Weiter aufnehmen, wenn der Livestream stoppt" -Basic.Settings.General.ReplayBufferWhileStreaming="Replaypuffer automatisch starten, beim Streamen" -Basic.Settings.General.KeepReplayBufferStreamStops="Replaypuffer weiter aktiv lassen, wenn der Livestream stoppt" +Basic.Settings.General.RecordWhenStreaming="Stream automatisch aufnehmen" +Basic.Settings.General.KeepRecordingWhenStreamStops="Weiter aufnehmen, wenn der Stream stoppt" +Basic.Settings.General.ReplayBufferWhileStreaming="Replaypuffer automatisch beim Streamen starten" +Basic.Settings.General.KeepReplayBufferStreamStops="Replaypuffer weiter aktiv lassen, wenn der Stream stoppt" Basic.Settings.General.SysTray="Infobereich" Basic.Settings.General.SysTrayWhenStarted="Beim Start zum Infobereich minimieren" -Basic.Settings.General.SystemTrayHideMinimize="Immer zum Infobereich. statt zur Taskleiste minimieren" +Basic.Settings.General.SystemTrayHideMinimize="Immer zum Infobereich anstatt zur Taskleiste minimieren" Basic.Settings.General.SaveProjectors="Projektoren beim Beenden speichern" +Basic.Settings.General.Preview="Vorschau" +Basic.Settings.General.OverflowHidden="Überlauf verstecken" +Basic.Settings.General.OverflowAlwaysVisible="Überlauf immer anzeigen" +Basic.Settings.General.OverflowSelectionHidden="Überlauf trotz unsichtbarer Quelle anzeigen" Basic.Settings.General.SwitchOnDoubleClick="Übergang zur Szene beim Doppelklicken" -Basic.Settings.General.StudioPortraitLayout="Porträt/vertikales Layout aktivieren" +Basic.Settings.General.StudioPortraitLayout="Porträt/Vertikales Layout aktivieren" +Basic.Settings.General.TogglePreviewProgramLabels="Vorschau-/Programmbeschriftung anzeigen" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Klicken, um zwischen den Szenen umzuschalten" Basic.Settings.General.Multiview.DrawSourceNames="Szenennamen anzeigen" -Basic.Settings.General.Multiview.DrawSafeAreas="Zeige sichere Bereiche (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Multiview Layout" +Basic.Settings.General.Multiview.DrawSafeAreas="Sichere Bereiche anzeigen (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Mehrbildanordnung" Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, oben (8 Szenen)" Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, unten (8 Szenen)" Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertikal, links (8 Szenen)" @@ -528,25 +579,29 @@ Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertikal, rechts (8 Szene Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, oben (24 Szenen)" Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Stream Typ" +Basic.Settings.Stream.StreamType="Streamtyp" +Basic.Settings.Stream.Custom.UseAuthentication="Authentifizierung verwenden" +Basic.Settings.Stream.Custom.Username="Nutzername" +Basic.Settings.Stream.Custom.Password="Passwort" +Basic.Settings.Stream.BandwidthTestMode="Bandbreitentestmodus aktivieren" Basic.Settings.Output="Ausgabe" Basic.Settings.Output.Format="Aufnahmeformat" -Basic.Settings.Output.Encoder="Codierer" -Basic.Settings.Output.SelectDirectory="Wählen Sie das Aufnahmeverzeichnis" -Basic.Settings.Output.SelectFile="Wählen Sie die Aufnahmedatei" -Basic.Settings.Output.EnforceBitrate="Erzwinge Bitratenlimit des Streamingdiensts" +Basic.Settings.Output.Encoder="Kodierer" +Basic.Settings.Output.SelectDirectory="Aufnahmeordner auswählen" +Basic.Settings.Output.SelectFile="Aufnahmedatei auswählen" +Basic.Settings.Output.EnforceBitrate="Bitratenlimit des Streamingdienstes erzwingen" Basic.Settings.Output.Mode="Ausgabemodus" Basic.Settings.Output.Mode.Simple="Einfach" Basic.Settings.Output.Mode.Adv="Erweitert" -Basic.Settings.Output.Mode.FFmpeg="FFmpeg Ausgabe" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg-Ausgabe" Basic.Settings.Output.UseReplayBuffer="Replaypuffer aktivieren" Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximale Replayzeit (Sekunden)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximale Speichernutzung (RAM) in Megabyte" Basic.Settings.Output.ReplayBuffer.Estimate="Geschätzte Speichernutzung (RAM): %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Speichernutzung kann nicht geschätzt werden. Stellen Sie bitte die maximale Speichergrenze ein." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Hinweis: Achten Sie darauf, einen Hotkey für den Replaypuffer im Abschnitt Hotkeys festzulegen)" -Basic.Settings.Output.ReplayBuffer.Prefix="Replaypuffer Dateiname Prefix" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Speichernutzung kann nicht geschätzt werden. Stellen Sie bitte die maximale Speichergrenze ein." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Hinweis: Achten Sie darauf, einen Hotkey für den Replaypuffer im Abschnitt „Hotkeys“ festzulegen)" +Basic.Settings.Output.ReplayBuffer.Prefix="Replaypuffer-Dateiname-Präfix" Basic.Settings.Output.ReplayBuffer.Suffix="Suffix" Basic.Settings.Output.Simple.SavePath="Aufnahmepfad" Basic.Settings.Output.Simple.RecordingQuality="Aufnahmequalität" @@ -554,33 +609,32 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Gleiche wie Stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Hohe Qualität, mittelgroße Dateien" Basic.Settings.Output.Simple.RecordingQuality.HQ="Ununterscheidbare Qualität, große Dateien" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Verlustfreie Qualität, enorm große Dateien" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Warnung: Die Videobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Codierereinstellungen." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim streamen wird auf %1 festlegt, was der Obergrenze des aktuellen Streamingdiensts entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie \"Erzwinge Bitratenlimit des Streamingdiensts\" in den erweiterten Codierereinstellungen." -Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Codierer in einer anderen Qualität als der des Stream aufzunehmen wird zusätzliche CPU-Auslastung erzeugen, wenn Sie gleichzeitig streamen und aufzeichnen." -Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm große Dateien! Verlustfreie Qualität, kann mehr als 7 Gigabyte Speicherplatz pro Minute, bei hohen Auflösungen und Frameraten in Anspruch nehmen. Verlustfrei ist für lange Aufnahmen nicht empfohlen, es sei denn, Sie haben eine sehr große Menge an Speicherplatz zur Verfügung." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Warnung: Die Videobitrate beim Streamen wird auf %1 festgelegt, was der Obergrenze des aktuellen Streamingdienstes entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie „Bitratenlimit des Streamingdienstes erzwingen“ in den erweiterten Kodierereinstellungen." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Warnung: Die Audiobitrate beim Streamen wird auf %1 festgelegt, was der Obergrenze des aktuellen Streamingdienstes entspricht. Falls Sie sicher sind, dass Sie %1 überschreiten wollen, deaktivieren Sie „Bitratenlimit des Streamingdienstes erzwingen“ in den erweiterten Kodierereinstellungen." +Basic.Settings.Output.Simple.Warn.Encoder="Warnung: Mit einem Software-Kodierer in einer anderen Qualität als der des Streams aufzunehmen erfordert zusätzliche CPU-Auslastung, wenn Sie gleichzeitig streamen und aufnehmen." +Basic.Settings.Output.Simple.Warn.Lossless="Warnung: Verlustfreie Qualität erzeugt enorm große Dateien! Verlustfreie Qualität kann mehr als 7 Gigabyte Speicherplatz pro Minute bei hohen Auflösungen und Frameraten in Anspruch nehmen. Verlustfrei ist für lange Aufnahmen nicht empfohlen, es sei denn, Sie haben eine sehr große Menge an Speicherplatz zur Verfügung." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sind Sie sicher, dass Sie verlustfreie Qualität verwenden möchten?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Verlustfreie Qualität-Warnung!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Achtung: Sie können nicht mehrere separate QSV-Codierer beim streamen und aufnehmen gleichzeitig verwenden. Wenn Sie zur gleichen Zeit streamen und aufnehmen möchten, dann ändern Sie bitte entweder den Aufnahmecodierer oder den Streamcodierer." +Basic.Settings.Output.Simple.Warn.Lossless.Title="Verlustfreie Qualitäts-Warnung" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 niedrige CPU-Auslastung Voreinstellung, erhöht die Dateigröße)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 niedrige CPU-Auslastungsvoreinstellung, erhöht die Dateigröße)" Basic.Settings.Output.VideoBitrate="Videobitrate" Basic.Settings.Output.AudioBitrate="Audiobitrate" Basic.Settings.Output.Reconnect="Automatisch wiederverbinden" Basic.Settings.Output.RetryDelay="Wiederverbindungsverzögerung (Sekunden)" Basic.Settings.Output.MaxRetries="Maximale Wiederholungsversuche" -Basic.Settings.Output.Advanced="Erweiterte Codierereinstellungen aktivieren" -Basic.Settings.Output.EncoderPreset="Codierer-Voreinstellung (höher = weniger CPU Auslastung)" -Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Codierer-Einstellungen" +Basic.Settings.Output.Advanced="Erweiterte Kodierereinstellungen aktivieren" +Basic.Settings.Output.EncoderPreset="Kodierervoreinstellung" +Basic.Settings.Output.CustomEncoderSettings="Benutzerdefinierte Kodierer-Einstellungen" Basic.Settings.Output.CustomMuxerSettings="Benutzerdefinierte Muxereinstellungen" Basic.Settings.Output.NoSpaceFileName="Dateinamen ohne Leerzeichen generieren" Basic.Settings.Output.Adv.Rescale="Ausgabe umskalieren" Basic.Settings.Output.Adv.AudioTrack="Audiospur" -Basic.Settings.Output.Adv.Streaming="Streamen" -Basic.Settings.Output.Adv.ApplyServiceSettings="Erzwinge Streamingdienst-Codierereinstellungen" +Basic.Settings.Output.Adv.Streaming="Streaming" +Basic.Settings.Output.Adv.ApplyServiceSettings="Streamingdienst-Kodierereinstellungen erzwingen" Basic.Settings.Output.Adv.Audio.Track1="Spur 1" Basic.Settings.Output.Adv.Audio.Track2="Spur 2" Basic.Settings.Output.Adv.Audio.Track3="Spur 3" @@ -588,11 +642,11 @@ Basic.Settings.Output.Adv.Audio.Track4="Spur 4" Basic.Settings.Output.Adv.Audio.Track5="Spur 5" Basic.Settings.Output.Adv.Audio.Track6="Spur 6" -Basic.Settings.Output.Adv.Recording="Aufnehmen" +Basic.Settings.Output.Adv.Recording="Aufnahme" Basic.Settings.Output.Adv.Recording.Type="Art" Basic.Settings.Output.Adv.Recording.Type.Standard="Normal" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Benutzerdefinierte Ausgabe (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Benutze Streamcodierer)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Streamkodierer verwenden)" Basic.Settings.Output.Adv.Recording.Filename="Dateinameformatierung" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Überschreiben, wenn die Datei vorhanden ist" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg-Ausgabetyp" @@ -606,35 +660,35 @@ Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Standardformat" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Container-Formatbeschreibung" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio- / Videocodec wird aus Dateipfad oder URL erraten." -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standard-Codierer" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Codierer deaktivieren" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Video-Codierer" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Video Codierer-Einstellungen (falls gewünscht)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audio-Codierer" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audio Codierer-Einstellungen (falls gewünscht)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer Einstellungen (falls vorhanden)" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Audio-/Videocodec wird aus Dateipfad oder URL gebildet" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Standardkodierer" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Kodierer deaktivieren" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Videokodierer" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videokodierereinstellungen (falls angegeben)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Audiokodierer" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Audiokodierereinstellungen (falls angegeben)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer-Einstellungen (falls angegeben)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="Keyframeintervall (Frames)" -Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zeige alle Codecs (auch wenn möglicherweise nicht kompatibel)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zeige alle Codecs (auch wenn möglicherweise inkompatibel)" -FilenameFormatting.completer="%DD-%MM-%CCYY %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S" +FilenameFormatting.completer="%DD. %MM. %CCYY %hh-%mm-%ss\n%DD. %MM. %YY %hh-%mm-%ss\n%d. %m. %Y %H-%M-%S\n%d. %m. %y %H-%M-%S" -FilenameFormatting.TT="%CCYY Jahr, vier Ziffern\n%YY Jahr, letzte zwei Ziffern (00-99)\n%MM Monat als Dezimalzahl (01-12)\n%DD Tag des Monats, mit Nullen aufgefüllt (01-31)\n%hh Stunden im 24 Stunden Format (00-23)\n%mm Minute (00-59)\n%ss Sekunde (00-61)\n%% Ein % Zeichen\n%a Abgekürzter Wochentagsname\n%A Voller Wochentagsname\n%b Abgekürzer Monatsname\n%B Voller Monatsname\n%d Tag des Monats, mit Nullen aufgefüllt (01-31)\n%H Stunden im 24 Stunden Format (00-23)\n%I Stunden im 12 Stunden Format (01-12)\n%m Monat als Dezimalzahl (01-12)\n%M Minute (00-59)\n%p AM oder PM Angabe\n%S Sekunde (00-61)\n%y Jahr, letzte zwei Ziffern (00-99)\n%Y Jahr\n%z ISO 8601 Verschiebung von UTC oder Zeitzone\n Name oder Abkürzung\n%Z Zeitzonenname oder Abkürzung\n" +FilenameFormatting.TT="%CCYY Jahr, vier Ziffern\n%YY Jahr, letzte zwei Ziffern (00–99)\n%MM Monat als Dezimalzahl (01–12)\n%DD Tag des Monats, mit Nullen aufgefüllt (01–31)\n%hh Stunden im 24-Stunden-Format (00–23)\n%mm Minute (00–59)\n%ss Sekunde (00–61)\n%% Ein %-Zeichen\n%a Abgekürzter Wochentagsname\n%A Voller Wochentagsname\n%b Abgekürzer Monatsname\n%B Voller Monatsname\n%d Tag des Monats, mit Nullen aufgefüllt (01–31)\n%H Stunden im 24-Stunden-Format (00–23)\n%I Stunden im 12-Stunden-Format (01–12)\n%m Monat als Dezimalzahl (01–12)\n%M Minute (00–59)\n%p Vormittags- oder nachmittags-Angabe\n%S Sekunde (00–61)\n%y Jahr, letzte zwei Ziffern (00–99)\n%Y Jahr\n%z ISO-8601-Verschiebung von UTC oder Zeitzone\n%Z Zeitzonenname oder Abkürzung" Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Grafikkarte" -Basic.Settings.Video.BaseResolution="Basis (Leinwand) Auflösung" -Basic.Settings.Video.ScaledResolution="Ausgabe (skaliert) Auflösung" -Basic.Settings.Video.DownscaleFilter="Skalierungs-Filter" +Basic.Settings.Video.BaseResolution="Basis-(Leinwand-)Auflösung" +Basic.Settings.Video.ScaledResolution="(Skalierte) Ausgabeauflösung" +Basic.Settings.Video.DownscaleFilter="Skalierungsfilter" Basic.Settings.Video.DisableAeroWindows="Aero deaktivieren (nur Windows)" Basic.Settings.Video.FPS="FPS" -Basic.Settings.Video.FPSCommon="Übliche FPS Werte" -Basic.Settings.Video.FPSInteger="Ganzzahl FPS Wert" -Basic.Settings.Video.FPSFraction="Bruchteil FPS Wert" +Basic.Settings.Video.FPSCommon="Übliche FPS-Werte" +Basic.Settings.Video.FPSInteger="Ganzzahl-FPS-Wert" +Basic.Settings.Video.FPSFraction="Bruch-FPS-Wert" Basic.Settings.Video.Numerator="Zähler" Basic.Settings.Video.Denominator="Nenner" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Ungültige Auflösung. Muss sein [width]x[height] (z.B. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Ungültige Auflösung. Korrekte Formatierung: [Breite]x[Höhe] (z. B. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Videoausgabe ist derzeit aktiv. Bitte schalten Sie alle Ausgaben ab, um die Videoeinstellungen zu ändern." Basic.Settings.Video.DisableAero="Aero deaktivieren" @@ -645,27 +699,31 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (geschärfte Skalierung, 3 Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Abtastrate" Basic.Settings.Audio.Channels="Kanäle" -Basic.Settings.Audio.MeterDecayRate="Aussteuerungsmesserverfallsrate" +Basic.Settings.Audio.Meters="Meter" +Basic.Settings.Audio.MeterDecayRate="Zerfallsrate" Basic.Settings.Audio.MeterDecayRate.Fast="Schnell" Basic.Settings.Audio.MeterDecayRate.Medium="Mittel (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Langsam (Type II PPM)" -Basic.Settings.Audio.PeakMeterType="Peakmeter Typ" +Basic.Settings.Audio.PeakMeterType="Spitzenmessertyp" Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample Peak" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (höhere CPU-Auslastung)" Basic.Settings.Audio.MultiChannelWarning.Enabled="WARNUNG: Surround-Sound-Audio ist aktiviert." -Basic.Settings.Audio.MultichannelWarning="Überprüfen Sie beim Streaming, ob Ihr Streaming-Dienst sowohl die Einspeisung von Surround-Sound als auch die Surround-Sound-Wiedergabe unterstützt. Twitch, Facebook 360 Live, Mixer RTMP und Smashcast sind Beispiele, bei denen Surround Sound voll unterstützt wird. Obwohl Facebook Live und YouTube Live beide die Surround-Einspeisung akzeptieren, wird Facebook Live auf Stereo heruntergemischt und YouTube Live spielt nur zwei Kanäle ab.\n\nOBS-Audiofilter sind mit Surround-Sound kompatibel, obwohl die VST-Plugin-Unterstützung nicht garantiert ist." +Basic.Settings.Audio.MultichannelWarning="Überprüfen Sie beim Streaming, ob Ihr Streamingdienst sowohl die Einspeisung von Surround-Sound als auch die Surround-Sound-Wiedergabe unterstützt. Twitch, Facebook 360 Live, Mixer RTMP und Smashcast sind Beispiele, bei denen Surround-Sound voll unterstützt wird. Obwohl Facebook Live und YouTube Live beide die Surround-Einspeisung akzeptieren, wird Facebook Live auf Stereo heruntergemischt und YouTube Live spielt nur zwei Kanäle ab.\n\nOBS-Audiofilter sind mit Surround-Sound kompatibel, obwohl die VST-Pluginunterstützung nicht garantiert ist." Basic.Settings.Audio.MultichannelWarning.Title="Surround-Sound-Audio aktivieren?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sind Sie sicher, dass Sie Surround-Sound-Audio wirklich aktivieren möchten?" -Basic.Settings.Audio.DesktopDevice="Desktop Audiogerät" -Basic.Settings.Audio.DesktopDevice2="Desktop Audiogerät 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/Externes Audiogerät" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Externes Audiogerät 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Externes Audiogerät 3" +Basic.Settings.Audio.Devices="Geräte" +Basic.Settings.Audio.DesktopDevice="Desktop-Audio" +Basic.Settings.Audio.DesktopDevice2="Desktop-Audio 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/Audiogerät" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Audiogerät 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Audiogerät 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/Audiogerät 4" Basic.Settings.Audio.EnablePushToMute="Push-To-Mute aktivieren" -Basic.Settings.Audio.PushToMuteDelay="Push-To-Mute Verzögerung" +Basic.Settings.Audio.PushToMuteDelay="Push-To-Mute-Verzögerung" Basic.Settings.Audio.EnablePushToTalk="Push-To-Talk aktivieren" -Basic.Settings.Audio.PushToTalkDelay="Push-To-Talk Verzögerung" +Basic.Settings.Audio.PushToTalkDelay="Push-To-Talk-Verzögerung" Basic.Settings.Audio.UnknownAudioDevice="[Gerät nicht angeschlossen oder nicht verfügbar]" +Basic.Settings.Audio.Disabled="Deaktiviert" Basic.Settings.Advanced="Erweitert" Basic.Settings.Advanced.General.ProcessPriority="Prozesspriorität" @@ -675,16 +733,16 @@ Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Niedriger als normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Niedrig" Basic.Settings.Advanced.FormatWarning="Warnung: Andere Farbformate als NV12 sind in erster Linie für die Aufnahme bestimmt und sind für Streaming nicht zu empfehlen. Die erforderliche Farbformatkonvertierung kann eine erhöhte CPU-Auslastung hervorrufen." -Basic.Settings.Advanced.Audio.BufferingTime="Audio Pufferungszeit" +Basic.Settings.Advanced.Audio.BufferingTime="Audiopufferungszeit" Basic.Settings.Advanced.Video.ColorFormat="Farbformat" -Basic.Settings.Advanced.Video.ColorSpace="YUV-Farbmatrix" -Basic.Settings.Advanced.Video.ColorRange="YUV Farbbereich" +Basic.Settings.Advanced.Video.ColorSpace="Farbraum" +Basic.Settings.Advanced.Video.ColorRange="Farbbereich" Basic.Settings.Advanced.Video.ColorRange.Partial="Begrenzt" Basic.Settings.Advanced.Video.ColorRange.Full="Voll" -Basic.Settings.Advanced.Audio.MonitoringDevice="Audiomonitoringgerät" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring-Gerät" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows Audioducking deaktivieren" -Basic.Settings.Advanced.StreamDelay="Stream-Verzögerung" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows-Audioducking deaktivieren" +Basic.Settings.Advanced.StreamDelay="Streamverzögerung" Basic.Settings.Advanced.StreamDelay.Duration="Dauer (Sekunden)" Basic.Settings.Advanced.StreamDelay.Preserve="Lückenloses Wiederverbinden (erhöht Verzögerung, um Videoverlust zu vermeiden)" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Geschätzte Speichernutzung: %1 MB" @@ -693,28 +751,31 @@ Basic.Settings.Advanced.Network.BindToIP="Interface" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Neuen Netzwerkcode aktivieren" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Niedriger Latenzmodus" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Hotkeys deaktivieren, wenn das Hauptfenster im Fokus ist" +Basic.Settings.Advanced.AutoRemux="Automatisch zu mp4 remuxen" +Basic.Settings.Advanced.AutoRemux.MP4="(als mkv aufnehmen)" Basic.AdvAudio="Erweiterte Audioeigenschaften" Basic.AdvAudio.Name="Name" -Basic.AdvAudio.Volume="Lautstärke (%)" +Basic.AdvAudio.Volume="Lautstärke" Basic.AdvAudio.Mono="Heruntermischen zu Mono" -Basic.AdvAudio.Panning="Schwenken" -Basic.AdvAudio.SyncOffset="Sync Verschiebung (ms)" -Basic.AdvAudio.Monitoring="Audiomonitoring" +Basic.AdvAudio.Balance="Balance" +Basic.AdvAudio.SyncOffset="Sync-Verschiebung (ms)" +Basic.AdvAudio.Monitoring="Audio-Monitoring" Basic.AdvAudio.Monitoring.None="Monitor aus" -Basic.AdvAudio.Monitoring.MonitorOnly="Nur Monitor (Ausgabe stumm schalten)" +Basic.AdvAudio.Monitoring.MonitorOnly="Nur Monitor (Ausgabe stummschalten)" Basic.AdvAudio.Monitoring.Both="Monitor und Ausgabe" Basic.AdvAudio.AudioTracks="Spuren" Basic.Settings.Hotkeys="Hotkeys" -Basic.Settings.Hotkeys.Pair="Mit '%1' geteilte Tastenkombinationen funktionieren als Schalter" +Basic.Settings.Hotkeys.Pair="Mit „%1“ geteilte Tastenkombinationen funktionieren als Schalter" +Basic.Settings.Hotkeys.Filter="Filtern" Basic.Hotkeys.SelectScene="Zu Szene wechseln" Basic.SystemTray.Show="Anzeigen" Basic.SystemTray.Hide="Ausblenden" -Basic.SystemTray.Message.Reconnecting="Verbindung verloren. Verbinde erneut..." +Basic.SystemTray.Message.Reconnecting="Verbindung verloren. Verbinde erneut …" Hotkeys.Insert="Einfügen" Hotkeys.Delete="Entfernen" @@ -737,7 +798,7 @@ Hotkeys.Windows="Windows" Hotkeys.Super="Super" Hotkeys.Menu="Menü" Hotkeys.Space="Leertaste" -Hotkeys.NumpadNum="Numpad %1" +Hotkeys.NumpadNum="Ziffernblock %1" Hotkeys.NumpadMultiply="Numpad Multiplizieren" Hotkeys.NumpadDivide="Numpad Dividieren" Hotkeys.NumpadAdd="Numpad Addieren" @@ -751,28 +812,44 @@ Hotkeys.AppleKeypadSubtract="- (Ziffernblock)" Hotkeys.AppleKeypadDecimal=", (Ziffernblock)" Hotkeys.AppleKeypadEqual="= (Ziffernblock)" Hotkeys.MouseButton="Maus %1" +Hotkeys.Escape="Esc" Mute="Stumm" Unmute="Stumm aus" Push-to-mute="Push-To-Mute" Push-to-talk="Push-To-Talk" -SceneItemShow="'%1' anzeigen" -SceneItemHide="'%1' verstecken" +SceneItemShow="„%1“ anzeigen" +SceneItemHide="„%1“ verstecken" OutputWarnings.NoTracksSelected="Sie müssen mindestens eine Spur auswählen" -OutputWarnings.MultiTrackRecording="Warnung: Bestimmte Formate (z. B. FLV) unterstützen nicht mehrere Spuren pro Aufnahme" -OutputWarnings.MP4Recording="Warnung: Aufnahmen, die in MP4 gespeichert werden, sind nicht wiederherstellbar, wenn die Datei nicht abgeschlossen werden kann (zum Beispiel als Folge von BSODs, Stromausfälle, etc). Wenn Sie mehrere Audiospuren aufnehmen möchten, sollten Sie MKV verwenden und die Aufnahme zu MP4 remuxen, nachdem sie fertig ist. (Datei-> Remuxe Aufnahmen)" +OutputWarnings.MultiTrackRecording="Warnung: Bestimmte Formate (z. B. FLV) unterstüzen nicht mehrere Spuren pro Aufnahme" +OutputWarnings.MP4Recording="Warnung: Aufnahmen, die in MP4/MOV gespeichert werden, sind nicht wiederherstellbar, wenn die Datei nicht abgeschlossen werden konnte (z. B. als Folge von BSODs, Stromausfällen, etc.). Wenn Sie mehrere Audiospuren aufnehmen möchten, sollten Sie MKV verwenden und die Aufnahme zu MP4/MOV remuxen, nachdem sie fertig ist (Datei → Aufnahmen remuxen)." FinalScene.Title="Szene löschen" FinalScene.Text="Es muss mindestens eine Szene vorhanden sein." NoSources.Title="Keine Quellen" -NoSources.Text="Offenbar haben Sie noch keine Videoquellen hinzugefügt, so dass Sie nur einen leeren Bildschirm ausgeben werden. Sind Sie sicher, dass Sie das wollen?" -NoSources.Text.AddSource="Sie können zu jeder Zeit Quellen hinzufügen, indem Sie auf das + Symbol unter dem Quellenfeld im Hauptfenster klicken." +NoSources.Text="Offenbar haben Sie noch keine Videoquellen hinzugefügt, sodass nur ein leerer Bildschirm ausgegeben wird. Sind Sie sicher, dass Sie das wollen?" +NoSources.Text.AddSource="Sie können jederzeit Quellen hinzufügen, indem Sie auf das +-Symbol unter dem Quellenfeld im Hauptfenster klicken." +NoSources.Label="Sie haben bis jetzt keine Quellen hinzugefügt.\nKlicken Sie auf das +-Symbol oder\nrechtsklicken Sie hier, um eine hinzuzufügen." ChangeBG="Farbe auswählen" CustomColor="Benutzerdefinierte Farbe" -BrowserSource.EnableHardwareAcceleration="Browser Hardwarebeschleunigung aktivieren" +BrowserSource.EnableHardwareAcceleration="Browser-Hardwarebeschleunigung aktivieren" + +About="Über OBS Studio" +About.Info="OBS Studio ist eine freie und Open-Source-Videoaufnahme- und Livestreaming-Software." +About.Donate="Beitrag leisten" +About.GetInvolved="Mitwirken" +About.Authors="Autoren" +About.License="Lizenzvereinbarung" +About.Contribute="Das OBS-Projekt unterstützen" + +ResizeOutputSizeOfSource="Ausgabeauflösung anpassen (Quellgröße)" +ResizeOutputSizeOfSource.Text="Die Basis- und Ausgabeauflösung wird auf die Größe der aktuellen Quelle geändert." +ResizeOutputSizeOfSource.Continue="Möchten Sie fortfahren?" + +PreviewTransition="Übergangsvorschau" diff --git a/UI/data/locale/el-GR.ini b/UI/data/locale/el-GR.ini index 5c9954e..cfbce15 100644 --- a/UI/data/locale/el-GR.ini +++ b/UI/data/locale/el-GR.ini @@ -27,18 +27,18 @@ Mixer="Μίκτης" Browse="Αναζήτηση" Mono="Μονοφωνικό" Stereo="Στερεοφωνικό" -DroppedFrames="Διακεκομμένα καρέ %1 (%2%)" -StudioProgramProjector="Προβολέας Πλήρους Οθόνης (Πηγή)" +DroppedFrames="Κομμένα καρέ %1 (%2%)" +StudioProgramProjector="Προβολέας Πλήρους Οθόνης (Έξοδος)" PreviewProjector="Προβολέας Πλήρους Οθόνης (Προεπισκόπηση)" SceneProjector="Προβολέας Πλήρους Οθόνης (Σκηνή)" SourceProjector="Προβολέας Πλήρους Οθόνης (Πηγή)" -StudioProgramWindow="Παραθύρου προβολής (πρόγραμμα)" -PreviewWindow="Σε παράθυρο στον Προβολέα (Προεπισκόπηση)" -SceneWindow="Σε παράθυρο στον Προβολέα (Σκηνή)" -SourceWindow="Σε παράθυρο στον Προβολέα (Πηγή)" -MultiviewProjector="MultiView (πλήρης οθόνη)" -MultiviewWindowed="MultiView (παραθύρου)" -Clear="Καθαρισμός" +StudioProgramWindow="Προβολέας σε Παράθυρο (Έξοδος)" +PreviewWindow="Προβολέας σε Παράθυρο (Προεπισκόπηση)" +SceneWindow="Προβολέας σε Παράθυρο (Σκηνή)" +SourceWindow="Προβολέας σε Παράθυρο (Πηγή)" +MultiviewProjector="MultiView (Πλήρης Οθόνη)" +MultiviewWindowed="MultiView (σε Παράθυρο)" +Clear="Εκκαθάριση" Revert="Επαναφορά" Show="Εμφάνιση" Hide="Απόκρυψη" @@ -51,7 +51,7 @@ DisableOSXVSync="Απενεργοποίηση OSX V-Sync" ResetOSXVSyncOnExit="Επαναφορά OSX V-Sync κατά την έξοδο" HighResourceUsage="Υπερφόρτωση κωδικοποίησης! Δοκιμάστε να χαμηλώσετε τις ρυθμίσεις βίντεο ή να χρησιμοποιήσετε μια ταχύτερη επιλογή κωδικοποίησης." Transition="Μετάβαση" -QuickTransitions="Γρήγορες μεταβάσεις" +QuickTransitions="Γρήγορες Μεταβάσεις" Left="Αριστερά" Right="Δεξιά" Top="Επάνω" @@ -60,15 +60,15 @@ Reset="Επαναφορά" Hours="Ώρες" Minutes="Λεπτά" Seconds="Δευτερόλεπτα" -Deprecated="Παλαιότερα Χρησιμοποιούμενες" -ReplayBuffer="Διάρκεια μνήμης Replay" +Deprecated="Καταργημένες" +ReplayBuffer="Προσωρινή Μνήμη Επανάληψης" Import="Εισαγωγή" Export="Εξαγωγή" Copy="Αντιγραφή" Paste="Επικόλληση" PasteReference="Επικόλληση (Με Αναφορά)" PasteDuplicate="Επικόλληση (Αντίγραφο)" -RemuxRecordings="Μετατροπή εγγεγραμένων αρχείων" +RemuxRecordings="Μετατροπή Καταγραφών" Next="Επόμενο" Back="Προηγούμενο" Defaults="Προεπιλογές" @@ -76,53 +76,56 @@ HideMixer="Απόκρυψη στον Μίκτη" TransitionOverride="Παράκαμψη της μετάβασης" None="Καμία" StudioMode.Preview="Προεπισκόπηση" -StudioMode.Program="Πρόγραμμα" +StudioMode.Program="Έξοδος" ShowInMultiview="Εμφάνιση σε Multiview" +VerticalLayout="Κατακόρυφη Διάταξη" +Group="Ομάδα" AlreadyRunning.Title="Το OBS εκτελείται ήδη" -AlreadyRunning.Text="Το OBS εκτελείται ήδη! Εκτός αν θέλατε να το κάνετε αυτό, παρακαλούμε τερματίστε τις τρέχουσες διεργασίες OBS πριν προσπαθήσετε να εκκινήσετε μια καινούρια. Εάν έχετε ρυθμίσει το OBS να ελαχιστοποιείται στην γραμμή εργαλείων, παρακαλούμε να ελένξετε αν τρέχει ήδη εκεί." +AlreadyRunning.Text="Το OBS εκτελείται ήδη! Εκτός αν αυτός ήταν ο σκοπός σας, παρακαλούμε τερματίστε τις τρέχουσες διεργασίες OBS πριν προσπαθήσετε να εκκινήσετε μια καινούρια. Εάν έχετε ρυθμίσει το OBS να ελαχιστοποιείται στην γραμμή εργαλείων, παρακαλούμε να ελέγξετε αν τρέχει ήδη εκεί." AlreadyRunning.LaunchAnyway="Εκκίνηση ούτως ή άλλως" + + Copy.Filters="Αντιγραφή Φίλτρων" Paste.Filters="Επικόλληση Φίλτρων" + BandwidthTest.Region="Περιοχή" BandwidthTest.Region.US="Ηνωμένες Πολιτείες" BandwidthTest.Region.EU="Ευρώπη" BandwidthTest.Region.Asia="Ασία" BandwidthTest.Region.Other="Άλλη" -Basic.FirstStartup.RunWizard="Θα θέλατε να εκτελέσετε τον Οδηγό αυτόματης ρύθμισης παραμέτρων; Μπορείτε επίσης να κάνετε ρύθμιση παραμέτρων με μη αυτόματο τρόπο, κάνοντας κλικ στο κουμπί ρυθμίσεις στο κύριο παράθυρο." -Basic.FirstStartup.RunWizard.BetaWarning="(Σημείωση: Ο οδηγός αυτόματης ρύθμισης παραμέτρων είναι επί του παρόντος σε δοκιμαστική έκδοση)" +Basic.FirstStartup.RunWizard="Θα θέλατε να εκτελέσετε τον Οδηγό αυτόματης ρύθμισης παραμέτρων; Μπορείτε επίσης να κάνετε ρύθμιση παραμέτρων χειροκίνητα, κάνοντας κλικ στο κουμπί ρυθμίσεις στο κύριο παράθυρο." Basic.FirstStartup.RunWizard.NoClicked="Εάν αλλάξετε γνώμη, μπορείτε να εκτελέσετε τον Οδηγό αυτόματης ρύθμισης παραμέτρων οποιαδήποτε στιγμή ξανά, από το μενού Εργαλεία." Basic.AutoConfig="Οδηγός αυτόματης ρύθμισης παραμέτρων" -Basic.AutoConfig.Beta="Οδηγός αυτόματης ρύθμισης παραμέτρων (Δοκιμαστική Έκδοση)" Basic.AutoConfig.ApplySettings="Εφαρμογή ρυθμίσεων" Basic.AutoConfig.StartPage="Πληροφορίες χρήσης" -Basic.AutoConfig.StartPage.SubTitle="Καθορίστε για ποιό λόγο θέλετε να χρησιμοποιήσετε το πρόγραμμα" -Basic.AutoConfig.StartPage.PrioritizeStreaming="Βελτιστοποίηση για streaming, η εγγραφή είναι δευτερεύουσα" -Basic.AutoConfig.StartPage.PrioritizeRecording="Βελτιστοποίηση μόνο για εγγραφή, δεν θα κάνω streaming" +Basic.AutoConfig.StartPage.SubTitle="Προσδιορίστε το σκοπό χρήσης του προγράμματος" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Βελτιστοποίηση για ροή, η καταγραφή είναι δευτερεύουσα" +Basic.AutoConfig.StartPage.PrioritizeRecording="Βελτιστοποίηση μόνο για καταγραφή, όχι για ροή" Basic.AutoConfig.VideoPage="Ρυθμίσεις βίντεο" Basic.AutoConfig.VideoPage.SubTitle="Καθορίστε τις επιθυμητές ρυθμίσεις βίντεο που θα θέλατε να χρησιμοποιήσετε" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Χρήση Παρούσας (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Χρήση Τρέχουσας (%1x%2)" Basic.AutoConfig.VideoPage.BaseResolution.Display="Οθόνη %1 (%2x%3)" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="Χρήση Παρόντων (%1)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Χρήση Τρεχόντων (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Είτε 60 είτε 30, αλλά προτίμηση 60 όταν είναι δυνατόν" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Είτε 60 είτε 30, αλλά προτίμηση υψηλής ανάλυσης" -Basic.AutoConfig.VideoPage.CanvasExplanation="Σημείωση: Η (βασική) ανάλυση του καμβά δεν είναι αναγκαστικά η ίδια με την ανάλυση στην οποία θα κάνετε stream ή εγγραφή. Η πραγματική ανάλυση stream/εγγραφής μπορεί να ελλατωθεί απο την ανάλυση του καμβά προς μείωση της χρήσης πόρων ή αναγκών bitrate." -Basic.AutoConfig.StreamPage="Πληροφορίες Stream" -Basic.AutoConfig.StreamPage.SubTitle="Παρακαλώ εισάγετε τις πληροφορίες του Stream σας" +Basic.AutoConfig.VideoPage.CanvasExplanation="Σημείωση: Η (βασική) ανάλυση του καμβά δεν είναι αναγκαστικά η ίδια με την ανάλυση που θα κάνετε ροή ή καταγραφή. Η πραγματική ανάλυση ροής/καταγραφής μπορεί να ελαττωθεί απο την ανάλυση του καμβά για να μειωθεί η χρήση πόρων ή οι ανάγκες ρυθμού μετάδοσης bits." +Basic.AutoConfig.StreamPage="Πληροφορίες Ροής" +Basic.AutoConfig.StreamPage.SubTitle="Παρακαλώ εισάγετε τις πληροφορίες της ροής σας" Basic.AutoConfig.StreamPage.Service="Υπηρεσία" Basic.AutoConfig.StreamPage.Service.ShowAll="Εμφάνιση Όλων..." Basic.AutoConfig.StreamPage.Server="Διακομιστής" -Basic.AutoConfig.StreamPage.StreamKey="Κλειδί Stream" +Basic.AutoConfig.StreamPage.StreamKey="Κλειδί Ροής" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Σύνδεσμος)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="Εκτίμηση bitrate (ροής δεδομένων) με δοκιμή εύρους ζώνης (ενδέχεται να χρειαστούν μερικά λεπτά)" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Προτίμηση κωδικοποίησης υποβοηθούμενης από το υλικό" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Η υποβοηθούμενη από το υλικό κωδικοποίηση εξαλείφει την περισσότερη χρήση της CPU, αλλά μπορεί να χρειαστεί υψυλότερο bitrate για την επίτευξη του ίδιου επιπέδου ποιότητας." -Basic.AutoConfig.StreamPage.StreamWarning.Title="Προειδοποίηση Stream" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Η δοκιμή του εύρους ζώνης πρόκειται να μεταδόσει τυχαιοποιημένα δεδομένα βίντεο χωρίς ήχο, στο κανάλι σας. Εάν μπορείτε, προτείνεται να απενεργοποιήσετε προσωρινά την αποθήκευση των βίντεο των streams σας και να θέσετε το stream σας σε ιδιωτικό, μέχρι την ολοκλήρωση της δοκιμής. Να συνεχίσω;" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Εκτίμηση ρυθμού μετάδοσης δεδομένων με δοκιμή εύρους ζώνης (ενδέχεται να χρειαστούν μερικά λεπτά)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Προτίμηση κωδικοποίησης υποβοηθούμενης από το υλισμικό" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Η υποβοηθούμενη από το υλισμικό απαιτεί την περισσότερη χρήση της CPU, αλλά μπορεί να χρειαστεί υψηλότερο ρυθμό μετάδοσης bits για την επίτευξη του ίδιου επιπέδου ποιότητας." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Προειδοποίηση Ροής" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Η δοκιμή του εύρους ζώνης πρόκειται να μεταδόσει τυχαιοποιημένα δεδομένα βίντεο χωρίς ήχο, στο κανάλι σας. Εάν μπορείτε, συνιστάται να απενεργοποιήσετε προσωρινά την αποθήκευση των βίντεο ροής σας και να θέσετε τη ροή σας σε ιδιωτική, μέχρι την ολοκλήρωση της δοκιμής. Συνέχεια;" Basic.AutoConfig.TestPage="Τελικά αποτελέσματα" Basic.AutoConfig.TestPage.SubTitle.Testing="Το πρόγραμμα εκτελεί τώρα ένα σύνολο από δοκιμές, για να εκτιμήσει τις πιο ιδανικές ρυθμίσεις" Basic.AutoConfig.TestPage.SubTitle.Complete="Οι δοκιμές ολοκληρώθηκαν" @@ -136,28 +139,28 @@ Basic.AutoConfig.TestPage.TestingRes="Δοκιμή ανάλυσης, αυτό μ Basic.AutoConfig.TestPage.TestingRes.Fail="Αποτυχία έναρξης του κωδικοποιητή" Basic.AutoConfig.TestPage.TestingRes.Resolution="Δοκιμή σε %1x%2 με %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Κωδικοποιητής Ροής" -Basic.AutoConfig.TestPage.Result.RecordingEncoder="Κωδικοποιητής Εγγραφής" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Κωδικοποιητής Καταγραφής" Basic.AutoConfig.TestPage.Result.Header="Το πρόγραμμα έχει καθορίσει πως οι ακόλουθες ρυθμίσεις είναι οι πιο ιδανικές για σας:" Basic.AutoConfig.TestPage.Result.Footer="Για χρήση αυτών των ρυθμίσεων, κάντε κλικ στο κουμπί Εφαρμογή Ρυθμίσεων. Για να ξαναρυθμίσετε τις παραμέτρους του οδηγού και να προσπαθήσετε ξανά, κάντε κλικ στο κουμπί Πίσω. Για να ρυθμίσετε χειροκίνητα οι ίδιοι τις ρυθμίσεις, κάντε κλικ στο κουμπί Άκυρο και ανοίξτε τις ρυθμίσεις." Basic.Stats="Στατιστικά" Basic.Stats.CPUUsage="Χρήση της CPU" -Basic.Stats.HDDSpaceAvailable="Διαθέσιμος χώρος στο σκληρό δίσκο" Basic.Stats.MemoryUsage="Χρήση Mνήμης" -Basic.Stats.AverageTimeToRender="Μέσος χρόνος για να αποδοθεί ένα καρέ" -Basic.Stats.SkippedFrames="Υπερπηδημένα καρέ λόγω καθυστέρησης κωδικοποίησης" +Basic.Stats.AverageTimeToRender="Μέσος χρόνος απόδοσης καρέ" +Basic.Stats.SkippedFrames="Παραλειπόμενα καρέ λόγω καθυστέρησης κωδικοποίησης" Basic.Stats.MissedFrames="Χαμένα καρέ λόγω καθυστέρησης απόδοσης" -Basic.Stats.Output.Stream="Stream" -Basic.Stats.Output.Recording="Εγγραφή" +Basic.Stats.Output.Stream="Ροή" +Basic.Stats.Output.Recording="Καταγραφή" Basic.Stats.Status="Κατάσταση" -Basic.Stats.Status.Recording="Γίνεται εγγραφή" -Basic.Stats.Status.Live="ΖΩΝΤΑΝO" +Basic.Stats.Status.Recording="Γίνεται καταγραφή" +Basic.Stats.Status.Live="ΖΩΝΤΑΝΑ" Basic.Stats.Status.Reconnecting="Επανασύνδεση" Basic.Stats.Status.Inactive="Ανενεργό" -Basic.Stats.DroppedFrames="Καρέ που απορρίφθηκαν (Δίκτυο)" -Basic.Stats.MegabytesSent="Συνολικά δεδομένα εξόδου" +Basic.Stats.DroppedFrames="Κομμένα Καρέ (Δίκτυο)" +Basic.Stats.MegabytesSent="Συνολικά Δεδομένα Εξόδου" Basic.Stats.Bitrate="Ρυθμός μετάδοσης bit" + Updater.Title="Νέα έκδοση διαθέσιμη" Updater.Text="Υπάρχει διαθέσιμη μια νέα έκδοση:" Updater.UpdateNow="Ενημέρωση Τώρα" @@ -169,7 +172,7 @@ Updater.NoUpdatesAvailable.Title="Δεν υπάρχουν διαθέσιμες Updater.NoUpdatesAvailable.Text="Δεν υπάρχουν διαθέσιμες ενημερώσεις αυτή τη στιγμή" Updater.FailedToLaunch="Αποτυχία εκκίνησης της υπηρεσίας ενημέρωσης" Updater.GameCaptureActive.Title="Καταγραφή παιχνιδιού ενεργή" -Updater.GameCaptureActive.Text="Η βιβλιοθήκη προσάρτησης της εγγραφής παιχνιδιού χρησιμοποιείται ήδη. Παρακαλούμε κλέιστε όλα τα παιχνίδια/προγράμματα που καταγράφονται (ή επανεκκινήστε τα Windows) και προσπαθήστε ξανά." +Updater.GameCaptureActive.Text="Η βιβλιοθήκη προσάρτησης της εγγραφής παιχνιδιού χρησιμοποιείται ήδη. Παρακαλούμε κλείστε όλα τα παιχνίδια/προγράμματα που καταγράφονται (ή επανεκκινήστε τα Windows) και προσπαθήστε ξανά." QuickTransitions.SwapScenes="Εναλλαγή των σκηνών Προεπισκόπησης/Εξόδου μετά τη μετάβαση" QuickTransitions.SwapScenesTT="Εναλλάσσει τις σκηνές της προεπισκόπησης και της εξόδου μετά τη μετάβαση (εάν η αρχική σκηνή της εξόδου υφίσταται ακόμα). \nΑυτό δεν πρόκειται να ανεραίσει όποιες αλλαγές μπορεί να έχουν γίνει στην αρχική σκηνή της εξόδου." @@ -177,7 +180,7 @@ QuickTransitions.DuplicateScene="Διπλότυπο Σκηνής" QuickTransitions.DuplicateSceneTT="Κατά την επεξεργασία της ίδιας σκηνής, επιτρέπει την επεξεργασία μετασχηματισμού/ορατότητας των πηγών χωρίς τροποποίηση της εξόδου.\nΓια να επεξεργαστείτε τις ιδιότητες των πηγών χωρίς να αλλάξετε την έξοδο, ενεργοποιήστε τις \"Διπλότυπες Πηγές\".\nΗ αλλαγή αυτής της τιμής θα επαναφέρει την τρέχουσα σκηνή εξόδου (αν υπάρχει ακόμη)." QuickTransitions.EditProperties="Διπλότυπες Πηγές" QuickTransitions.EditPropertiesTT="Όταν επεξεργάζεστε την ίδια σκηνή, επιτρέπει την επεξεργασία ιδιοτήτων των πηγών χωρίς να τροποποιήσετε την έξοδο.\nΑυτό μπορεί να χρησιμοποιηθεί μόνο εάν είναι ενεργοποιημένη η λειτουργία \"Διπλότυπες Πηγές\".\nΟρισμένες πηγές (όπως πηγές καταγραφής ή πολυμέσων) δεν το υποστηρίζουν και δεν μπορούν να επεξεργαστούν ξεχωριστά.\nΗ αλλαγή αυτής της τιμής θα επαναφέρει την τρέχουσα σκηνή εξόδου (αν υπάρχει ακόμη).\n\nΠροειδοποίηση: Επειδή οι πηγές θα διπλασιαστούν, μπορεί να χρειαστούν πρόσθετοι πόροι συστήματος ή βίντεο." -QuickTransitions.HotkeyName="Γρήγορη μετάβαση: %1" +QuickTransitions.HotkeyName="Γρήγορη Μετάβαση: %1" Basic.AddTransition="Προσθήκη Προσαρμόσιμης Μετάβασης" Basic.RemoveTransition="Αφαίρεση Προσαρμόσιμης Μετάβασης" @@ -199,38 +202,41 @@ NoNameEntered.Title="Πληκτρολογήστε ένα έγκυρο όνομα NoNameEntered.Text="Δεν μπορείτε να χρησιμοποιήσετε κενά ονόματα." ConfirmStart.Title="Εκκίνηση Ροής (Steam);" -ConfirmStart.Text="Είστε σίγουροι οτι θέλετε να ξεκινήσετε το stream;" +ConfirmStart.Text="Είστε σίγουροι οτι θέλετε να ξεκινήσετε τη ροή;" + +ConfirmStop.Title="Τερματισμός Ροής;" +ConfirmStop.Text="Είστε σίγουροι οτι θέλετε να διακόψετε τη ροή;" -ConfirmStop.Title="Διακοπή Ροής (Stream);" -ConfirmStop.Text="Είστε σίγουροι οτι θέλετε να διακόψετε το stream;" ConfirmExit.Title="Έξοδος από το OBS;" -ConfirmExit.Text="Το OBS είναι προσωρινά ενεργό. Όλες οι ροές (Streams)/εγγραφές θα τερματιστούν. Είστε σίγουροι ότι επιθυμείτε να το κλείσετε;" +ConfirmExit.Text="Το OBS είναι προσωρινά ενεργό. Όλες οι ροές/καταγραφές θα τερματιστούν. Είστε σίγουροι ότι επιθυμείτε να το κλείσετε;" -ConfirmRemove.Title="Επιβεβαίωση Αφαίρεσης" +ConfirmRemove.Title="Επιβεβαίωση Κατάργησης" ConfirmRemove.Text="Είστε βέβαιοι ότι θέλετε να καταργήσετε \"$1\";" -ConfirmRemove.TextMultiple="Είστε βέβαιοι ότι θέλετε να αφαιρέσετε %1 επιλογές;" +ConfirmRemove.TextMultiple="Είστε βέβαιοι ότι θέλετε να καταργήσετε %1 επιλογές;" -Output.StartStreamFailed="Αποτυχία εκκίνησης της ροής (streaming)" -Output.StartRecordingFailed="Αποτυχία εκκίνησης της εγγραφής" +Output.StartStreamFailed="Αποτυχία εκκίνησης της ροής" +Output.StartRecordingFailed="Αποτυχία εκκίνησης της καταγραφής" Output.StartReplayFailed="Αποτυχία εκκίνησης της προσωρινής μνήμης των επαναλήψεων" -Output.StartFailedGeneric="Αποτυχία εκκίνησης εξόδου. Παρακαλούμε ελέγξτε το αρχείο καταγραγής (log) για λεπτομέρειες.\n\nΣημείωση: Εάν χρησιμοποιείτε τους κωδικοποιητές NVENC ή AMD, βεβαιωθείτε ότι τα προγράμματα οδήγησης της κάρτας γραφικών σας είναι ενημερωμένα." +Output.StartFailedGeneric="Αποτυχία εκκίνησης εξόδου. Παρακαλούμε ελέγξτε το αρχείο καταγραφής για λεπτομέρειες.\n\nΣημείωση: Εάν χρησιμοποιείτε τους κωδικοποιητές NVENC ή AMD, βεβαιωθείτε ότι τα προγράμματα οδήγησης της κάρτας γραφικών σας είναι ενημερωμένα." + Output.ConnectFail.Title="Η σύνδεση απέτυχε" -Output.ConnectFail.BadPath="Μη έγκυρη Διαδρομή ή URL Σύνδεσης. Παρακαλώ ελέγξτε τις ρυθμίσεις σας και επιβεβαιώστε ότι είναι έγκυρες." +Output.ConnectFail.BadPath="Μη έγκυρη Διαδρομή ή URL Σύνδεσης. Παρακαλώ ελέγξτε τις ρυθμίσεις σας και επιβεβαιώστε ότι είναι έγκυρες." Output.ConnectFail.ConnectFailed="Απέτυχε η σύνδεση στον διακομιστή" Output.ConnectFail.InvalidStream="Δεν μπορέσαμε να αποκτήσουμε πρόσβαση στο συγκεκριμένο κανάλι ή κλειδί ροής, παρακαλούμε ελέγξτε ξανά το κλειδί ροής σας. Εάν είναι σωστό, μπορεί να υπάρχει πρόβλημα στη σύνδεση με τον διακομιστή." -Output.ConnectFail.Error="Παρουσιάστηκε μη αναμενόμενο σφάλμα κατα την προσπάθεια σύνδεσης με τον διακομιστή. Περισσότερες πληροφορίες στο αρχείο καταγραφής." +Output.ConnectFail.Error="Παρουσιάστηκε μη αναμενόμενο σφάλμα κατά την προσπάθεια σύνδεσης με τον διακομιστή. Περισσότερες πληροφορίες στο αρχείο καταγραφής." Output.ConnectFail.Disconnected="Αποσυνδεθήκατε από τον διακομιστή." + Output.RecordFail.Title="Αποτυχία εκκίνησης της καταγραφής" -Output.RecordFail.Unsupported="Η μορφή εξόδου είτε δεν υποστηρίζεται ή δεν υποστηρίζει παραπάνω από ένα κομμάτι ήχου. Παρακαλώ ελέγξτε τις ρυθμίσεις σας και δοκιμάστε ξανά." +Output.RecordFail.Unsupported="Η μορφή εξόδου είτε δεν υποστηρίζεται ή δεν υποστηρίζει παραπάνω από ένα κομμάτι ήχου. Παρακαλώ ελέγξτε τις ρυθμίσεις σας και δοκιμάστε ξανά." Output.RecordNoSpace.Title="Ανεπαρκής χώρος στον δίσκο" -Output.RecordNoSpace.Msg="Δεν υπάρχει επαρκής χώρος στο δίσκο για να συνεχιστεί η εγγραφή." -Output.RecordError.Title="Σφάλμα εγγραφής" -Output.RecordError.Msg="Παρουσιάστηκε ένα αδιευκρίνιστο σφάλμα κατά την εγγραφή." -Output.ReplayBuffer.NoHotkey.Title="Δεν έχει επιλεχθεί hotkey!" -Output.ReplayBuffer.NoHotkey.Msg="Καμμία αποθήκευση συντόμευσης για επανάληψη buffer. Παρακαλώ ορίστε την συντόμευση για «Αποθήκευση» καί χρήση για την αποθήκευση επανάληψης ηχογραφήσεων." +Output.RecordNoSpace.Msg="Δεν υπάρχει επαρκής χώρος στο δίσκο για να συνεχιστεί η καταγραφή." +Output.RecordError.Title="Σφάλμα καταγραφής" +Output.RecordError.Msg="Παρουσιάστηκε ένα αδιευκρίνιστο σφάλμα κατά την καταγραφή." +Output.ReplayBuffer.NoHotkey.Title="Δεν έχουν επιλεγεί πλήκτρα συντόμευσης!" +Output.ReplayBuffer.NoHotkey.Msg="Δεν έχει οριστεί πλήκτρο συντόμευσης για την επανάληψη προσωρινής μνήμης. Παρακαλώ ορίστε συντόμευση για «Αποθήκευση» και χρήση για την αποθήκευση επανάληψης καταγραφών." Output.BadPath.Title="Λάθος Διαδρομή Αρχείου" Output.BadPath.Text="Η προκαθορισμένη διαδρομή αρχείου δεν ειναι έγκυρη. Παρακαλώ ελέγξτε τις ρυθμίσεις σας για να επιβεβαιώσετε ότι έχει οριστεί μια έγκυρη διαδρομή αρχείου." @@ -239,25 +245,20 @@ LogReturnDialog="Ανέβασμα αρχείου καταγραφής επιτυ LogReturnDialog.CopyURL="Αντιγραφή Διεύθυνσης" LogReturnDialog.ErrorUploadingLog="Απέτυχε η μεταφόρτωση αρχείου καταγραφής" -LicenseAgreement="Άδεια Χρήσης" -LicenseAgreement.PleaseReview="Παρακαλούμε διαβάστε τους όρους της άδειας χρήσης πριν από τη χρήση του OBS. Χρησιμοποιώντας αυτό το πρόγραμμα, αναγνωρίζετε ότι έχετε διαβάσει και συμφωνείτε με τους όρους της άδειας GNU/GPL v2.0. Παρακαλούμε διαβάστε παρακάτω το υπόλοιπο της συμφωνίας." -LicenseAgreement.ClickIAgreeToContinue="Εάν αποδέχεστε τους όρους της συμφωνίας, κάντε κλικ στο κουμπί Συμφωνώ να συνεχίσετε. Πρέπει να αποδεχτείτε την συμφωνία να χρησιμοποιήσετε το OBS." -LicenseAgreement.IAgree="Συμφωνώ" -LicenseAgreement.Exit="Έξοδος" - Remux.SourceFile="OBS Καταγραφή" Remux.TargetFile="Αρχείο Προορισμού" Remux.Remux="Μετατροπή" -Remux.OBSRecording="Εγγραφή OBS" -Remux.FinishedTitle="Η μετατροπή τελείωσε" +Remux.ClearFinished="Εκκαθάριση Ολοκληρωμένων Στοιχείων" +Remux.ClearAll="Εκκαθάριση Όλων" +Remux.OBSRecording="Καταγραφή OBS" +Remux.FinishedTitle="Η μετατροπή ολοκληρώθηκε" Remux.Finished="Η καταγραφή μετατράπηκε" -Remux.FinishedError="Η καταγραφή μετατράπηκε, άλλα ενδέχεται το αρχείο να είναι ελλιπής" -Remux.SelectRecording="Επιλέξτε καταγραφή OBS …" -Remux.SelectTarget="Επιλέξτε το αρχείο προορισμού …" -Remux.FileExistsTitle="Το αρχείο προορισμού υπάρχει" -Remux.FileExists="Το αρχείο προορισμού υπάρχει, θέλετε να το αντικαταστήσετε;" +Remux.FinishedError="Η καταγραφή μετατράπηκε, άλλα ενδέχεται το αρχείο να είναι ελλιπές" +Remux.FileExistsTitle="Τα αρχεία προορισμού υπάρχουν" +Remux.FileExists="Τα παρακάτω αρχεία προορισμού υπάρχουν ήδη. Θέλετε να τα αντικαταστήσετε;" Remux.ExitUnfinishedTitle="Μετατροπή σε εξέλιξη" -Remux.ExitUnfinished="Η Μετατροπή δεν τελείωσε, η διακοπή τώρα μπορεί να καταστήσει το αρχείο προορισμού άρχηστο.\nΕίστε βέβαιοι ότι θέλετε να διακόψετε την μετατροπή;" +Remux.ExitUnfinished="Η Μετατροπή δεν τελείωσε, η διακοπή τώρα μπορεί να καταστήσει το αρχείο προορισμού άχρηστο.\nΕίστε βέβαιοι ότι θέλετε να τερματίσετε την μετατροπή;" +Remux.HelpText="Αποθέστε τα αρχεία σε αυτό το παράθυρο για να τα μετατρέψετε, ή επιλέξτε ένα άδειο πεδίο \"Kαταγραφή OBS\" για αναζήτηση αρχείου." UpdateAvailable="Νέα Διαθέσιμη Ενημέρωση" UpdateAvailable.Text="Η έκδοση %1.%2.%3 είναι τώρα διαθέσιμη. Κάντε κλικ εδώ για να την κατεβάσετε" @@ -270,11 +271,12 @@ Basic.AuxDevice3="Μικρόφωνο/Aux 3" Basic.AuxDevice4="Μικρόφωνο/Aux 4" Basic.Scene="Σκηνή" -Basic.DisplayCapture="Σύλληψη Οθόνης" +Basic.DisplayCapture="Αποτύπωση Οθόνης" Basic.Main.PreviewConextMenu.Enable="Ενεργοποίηση Προεπισκόπησης" -ScaleFiltering="Φίλτρο Κλίμακας" + +ScaleFiltering="Κλίμακα Φίλτρου" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" @@ -289,8 +291,8 @@ Deinterlacing.Linear="Γραμμικό" Deinterlacing.Linear2x="Γραμμικό 2x" Deinterlacing.Yadif="Yadif" Deinterlacing.Yadif2x="Yadif 2x" -Deinterlacing.TopFieldFirst="Αρχικό Πεδίο Πρώτα" -Deinterlacing.BottomFieldFirst="Τελευταίο Πεδίο Πρώτα" +Deinterlacing.TopFieldFirst="Επάνω Πεδίο Πρώτα" +Deinterlacing.BottomFieldFirst="Κάτω Πεδίο Πρώτα" VolControl.SliderUnmuted="Ρυθμιστής έντασης για '%1': %2" VolControl.SliderMuted="Ρυθμιστής έντασης για '%1': %2 (προσωρινά σε σίγαση)" @@ -319,7 +321,7 @@ Basic.Main.MixerRename.Text="Παρακαλώ εισάγετε το όνομα Basic.Main.PreviewDisabled="Η προεπισκόπηση είναι απενεργοποιημένη" Basic.SourceSelect="Δημιουργία/Επιλογή Πηγής" -Basic.SourceSelect.CreateNew="Δημιουργία νέων" +Basic.SourceSelect.CreateNew="Δημιουργία νέας" Basic.SourceSelect.AddExisting="Προσθήκη Υπάρχουσας" Basic.SourceSelect.AddVisible="Να γίνει η πηγή ορατή" @@ -328,10 +330,10 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (αυτόματη επιλογή: %2 Basic.PropertiesWindow.SelectColor="Επιλέξτε χρώμα" Basic.PropertiesWindow.SelectFont="Επιλέξτε γραμματοσειρά" Basic.PropertiesWindow.ConfirmTitle="Άλλαξαν οι Ρυθμίσεις" -Basic.PropertiesWindow.Confirm="Υπάρχουν μη αποθηκευμένες αλλαγές. Θέλετε να τις κρατήσετε;" +Basic.PropertiesWindow.Confirm="Υπάρχουν μη αποθηκευμένες αλλαγές. Θέλετε να τις κρατήσετε;" Basic.PropertiesWindow.NoProperties="Δεν υπάρχουν διαθέσιμες ιδιότητες" Basic.PropertiesWindow.AddFiles="Προσθήκη Αρχείων" -Basic.PropertiesWindow.AddDir="Προσθήκη φακέλου" +Basic.PropertiesWindow.AddDir="Προσθήκη Φακέλου" Basic.PropertiesWindow.AddURL="Προσθήκη Διαδρομής/URL" Basic.PropertiesWindow.AddEditableListDir="Προσθήκη φακέλου στο '%1'" Basic.PropertiesWindow.AddEditableListFiles="Προσθήκη αρχείων στο '%1'" @@ -389,76 +391,79 @@ Basic.TransformWindow.BoundsType.ScaleToHeight="Κλιμάκωση στο ύψο Basic.TransformWindow.BoundsType.Stretch="Κλιμάκωση στα όρια" Basic.Main.AddSourceHelp.Title="Αδύνατη Προσθήκη Πηγής" -Basic.Main.AddSourceHelp.Text="Πρέπει να έχετε τουλάχιστον 1 σκηνή να προσθέσετε μια πηγή." +Basic.Main.AddSourceHelp.Text="Πρέπει να έχετε τουλάχιστον 1 σκηνή για να προσθέσετε μια πηγή." Basic.Main.Scenes="Σκηνές" Basic.Main.Sources="Πηγές" Basic.Main.Controls="Πλήκτρα ελέγχου" Basic.Main.Connecting="Σύνδεση..." Basic.Main.StartRecording="Έναρξη Καταγραφής" -Basic.Main.StartReplayBuffer="Έναρξη Buffer επανάληψης" -Basic.Main.StartStreaming="Έναρξη Μετάδοσης" +Basic.Main.StartReplayBuffer="Έναρξη επανάληψης προσωρινής μνήμης" +Basic.Main.StartStreaming="Έναρξη Ροής" Basic.Main.StopRecording="Διακοπή Καταγραφής" -Basic.Main.StoppingRecording="Διακοπή Εγγραφής..." -Basic.Main.StopReplayBuffer="Διακοπή Buffer επανάληψης" -Basic.Main.StoppingReplayBuffer="Διακοπή Buffer επανάληψης..." -Basic.Main.StopStreaming="Διακοπή Μετάδοσης" -Basic.Main.StoppingStreaming="Διακοπή Stream..." -Basic.Main.ForceStopStreaming="Διακοπή Stream (απόρριψη καθυστέρησης)" +Basic.Main.StoppingRecording="Διακοπή Καταγραφής..." +Basic.Main.StopReplayBuffer="Διακοπή Επανάληψης Προσωρινής Μνήμης" +Basic.Main.StoppingReplayBuffer="Διακοπή Επανάληψης Προσωρινής Μνήμης..." +Basic.Main.StopStreaming="Διακοπή Ροής" +Basic.Main.StoppingStreaming="Διακοπή Ροής..." +Basic.Main.ForceStopStreaming="Διακοπή Ροής(απόρριψη καθυστέρησης)" +Basic.Main.Group="Ομάδα %1" +Basic.Main.GroupItems="Ομάδα Επιλεγμένων Στοιχείων" +Basic.Main.Ungroup="Κατάργηση Ομάδας" Basic.MainMenu.File="Αρχείο(&F)" Basic.MainMenu.File.Export="Εξαγωγή(&E)" -Basic.MainMenu.File.Import="Εισαγωγή(&Ι)" -Basic.MainMenu.File.ShowRecordings="Εμφάνιση Ηχογραφίσεων(&R)" -Basic.MainMenu.File.Remux="Μετατροπή Ηχογραφών(&Re)" +Basic.MainMenu.File.Import="Εισαγωγή(Ι) (&I)" +Basic.MainMenu.File.ShowRecordings="Εμφάνιση Καταγραφών(&R)" +Basic.MainMenu.File.Remux="Μετατροπή Καταγραφών(&M)" Basic.MainMenu.File.Settings="Ρυθμίσεις(&S)" Basic.MainMenu.File.ShowSettingsFolder="Προβολή Φακέλου Ρυθμίσεων" Basic.MainMenu.File.ShowProfileFolder="Προβολή Φακέλου Προφίλ" -Basic.MainMenu.AlwaysOnTop="&Πάντα από πάνω" -Basic.MainMenu.File.Exit="Έξοδος(&E)" +Basic.MainMenu.AlwaysOnTop="Πάντα Στην Επιφάνεια(&A)" +Basic.MainMenu.File.Exit="Έξοδος(&X)" Basic.MainMenu.Edit="Επεξεργασία(&E)" Basic.MainMenu.Edit.Undo="Αναίρεση(&U)" Basic.MainMenu.Edit.Redo="Ακύρωση Αναίρεσης(&R)" Basic.MainMenu.Edit.UndoAction="Αναίρεση(&U) $1" Basic.MainMenu.Edit.RedoAction="Ακύρωση Αναίρεσης(&R) $1" -Basic.MainMenu.Edit.LockPreview="&Κλείδωμα προεπισκόπησης" -Basic.MainMenu.Edit.Scale="Προεπισκόπηση &Κλιμάκωσης" +Basic.MainMenu.Edit.LockPreview="Κλείδωμα Προεπισκόπησης(&L)" +Basic.MainMenu.Edit.Scale="Προεπισκόπηση Κλιμάκωσης(&S)" Basic.MainMenu.Edit.Scale.Window="Κλιμάκωση σε Παράθυρο" Basic.MainMenu.Edit.Scale.Canvas="Καμβάς (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Έξοδος (%1x%2)" Basic.MainMenu.Edit.Transform="Μετασχηματισμός(&T)" -Basic.MainMenu.Edit.Transform.EditTransform="Επεξεργασία(&E) Μετασχηματισμόυ" +Basic.MainMenu.Edit.Transform.EditTransform="Επεξεργασία Μετασχηματισμού(&E)..." Basic.MainMenu.Edit.Transform.CopyTransform="Αντιγραφή Μετασχηματισμού" Basic.MainMenu.Edit.Transform.PasteTransform="Επικόλληση Μετασχηματισμού" -Basic.MainMenu.Edit.Transform.ResetTransform="Επαναφορά(&E) Μετασχηματισμού" +Basic.MainMenu.Edit.Transform.ResetTransform="Επαναφορά Μετασχηματισμού(&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Περιστροφή κατά 90 μοίρες CW" Basic.MainMenu.Edit.Transform.Rotate90CCW="Περιστροφή κατά 90 μοίρες CCW" Basic.MainMenu.Edit.Transform.Rotate180="Περιστροφή 180 μοίρες" Basic.MainMenu.Edit.Transform.FlipHorizontal="Οριζόντια Αναστροφή(&H)" Basic.MainMenu.Edit.Transform.FlipVertical="Κατακόρυφη Αναστροφή(&V)" -Basic.MainMenu.Edit.Transform.FitToScreen="Προσαρμογή(&F) στην οθόνη" -Basic.MainMenu.Edit.Transform.StretchToScreen="Τέντωμα(&S) στην οθόνη" -Basic.MainMenu.Edit.Transform.CenterToScreen="Κεντράρισμα(&C) στην οθόνη" +Basic.MainMenu.Edit.Transform.FitToScreen="Προσαρμογή στην οθόνη(&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Έκταση στην οθόνη(&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Κεντράρισμα στην οθόνη(&C)" Basic.MainMenu.Edit.Order="Σειρά(&O)" Basic.MainMenu.Edit.Order.MoveUp="Μετακίνηση Πάνω(&U)" Basic.MainMenu.Edit.Order.MoveDown="Μετακίνηση Κάτω(&D)" Basic.MainMenu.Edit.Order.MoveToTop="Μετακίνηση στην Κορυφή(&T)" -Basic.MainMenu.Edit.Order.MoveToBottom="Μετακίνηση τελέιως Κάτω(&B)" -Basic.MainMenu.Edit.AdvAudio="Ιδιότητες(&A) Ήχου για Προχωρημένους" +Basic.MainMenu.Edit.Order.MoveToBottom="Μετακίνηση στη Βάση(&B)" +Basic.MainMenu.Edit.AdvAudio="Ιδιότητες Ήχου για Προχωρημένους(&A)" -Basic.MainMenu.View="&Προβολή" -Basic.MainMenu.View.Toolbars="&Γραμμές εργαλείων" +Basic.MainMenu.View="Προβολή (&V)" +Basic.MainMenu.View.Toolbars="Γραμμές εργαλείων (&T)" Basic.MainMenu.View.Docks="Μπάρες εφαρμογών" Basic.MainMenu.View.Docks.ResetUI="Επαναφορά περιβάλλοντος χρήστη" Basic.MainMenu.View.Docks.LockUI="Κλείδωμα περιβάλλοντος χρήστη" -Basic.MainMenu.View.Toolbars.Listboxes="&Κουτιά Λίστας" -Basic.MainMenu.View.SceneTransitions="&Μεταβάσεις Σκηνών" -Basic.MainMenu.View.StatusBar="&Γραμμή κατάστασης" +Basic.MainMenu.View.Toolbars.Listboxes="Κουτιά Λίστας (&L)" +Basic.MainMenu.View.SceneTransitions="Μεταβάσεις Σκηνών(&C)" +Basic.MainMenu.View.StatusBar="Γραμμή κατάστασης(&S)" Basic.MainMenu.View.Fullscreen.Interface="Διεπαφή Πλήρους Οθόνης" -Basic.MainMenu.SceneCollection="&Συλλογή Σκηνών" -Basic.MainMenu.Profile="&Προφίλ" +Basic.MainMenu.SceneCollection="Συλλογή Σκηνών(&S)" +Basic.MainMenu.Profile="Προφίλ(&P)" Basic.MainMenu.Profile.Import="Εισαγωγή Προφίλ" Basic.MainMenu.Profile.Export="Εξαγωγή Προφίλ" Basic.MainMenu.SceneCollection.Import="Εισαγωγή Συλλογής Σκηνών" @@ -466,95 +471,107 @@ Basic.MainMenu.SceneCollection.Export="Εξαγωγή Συλλογής Σκην Basic.MainMenu.Profile.Exists="Το προφίλ υπάρχει ήδη" Basic.MainMenu.SceneCollection.Exists="Η συλλογή σκήνων υπάρχει ήδη" -Basic.MainMenu.Tools="&Εργαλεία" +Basic.MainMenu.Tools="Εργαλεία(&T)" Basic.MainMenu.Help="Βοήθεια(&H)" -Basic.MainMenu.Help.HelpPortal="Πύλη βοήθειας" -Basic.MainMenu.Help.Website="Μετάβαση στην &Ιστοσελίδα" -Basic.MainMenu.Help.Logs="Αρχεία(&) Καταγραφής" -Basic.MainMenu.Help.Logs.ShowLogs="Εμφάνιση(&S) Αρχείων Καταγραφής" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Μεταφορτώστε το Τρέχον(&C) Αρχείο Καταγραφής" -Basic.MainMenu.Help.Logs.UploadLastLog="Μεταφορτώστε το Τελευταίο(&L) Αρχείο Καταγραφής" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Προβολή τρέχοντος αρχείου καταγραφής" +Basic.MainMenu.Help.HelpPortal="Πύλη Βοήθειας(&P)" +Basic.MainMenu.Help.Website="Μετάβαση στην Ιστοσελίδα(&W)" +Basic.MainMenu.Help.Discord="Βρείτε μας στο &Discord" +Basic.MainMenu.Help.Logs="Αρχεία Καταγραφής(&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Εμφάνιση Αρχείων Καταγραφής(&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Μεταφορτώστε το Τρέχον Αρχείο Καταγραφής(&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Μεταφορτώστε το Τελευταίο Αρχείο Καταγραφής(&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Προβολή Τρέχοντος Αρχείου Καταγραφής(&V)" Basic.MainMenu.Help.CheckForUpdates="Ελέγχος Για Ενημερώσεις" +Basic.MainMenu.Help.CrashLogs="Αναφορές Σφαλμάτων(&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Εμφάνιση Αναφοράς Σφαλμάτων(&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Μεταφόρτωση Τελευταίας Αναφοράς Σφάλματος(&L)" +Basic.MainMenu.Help.About="Σχετικά(&A)" Basic.Settings.ProgramRestart="Το πρόγραμμα πρέπει να επανεκκινηθεί για να εφαρμοστούν αυτές οι ρυθμίσεις." Basic.Settings.ConfirmTitle="Επιβεβαίωση Αλλαγών" -Basic.Settings.Confirm="Έχετε μη αποθηκευμένες αλλαγές. Αποθήκευση αλλαγών;" +Basic.Settings.Confirm="Έχετε μη αποθηκευμένες αλλαγές. Αποθήκευση αλλαγών;" Basic.Settings.General="Γενικά" Basic.Settings.General.Theme="Θέμα" Basic.Settings.General.Language="Γλώσσα" Basic.Settings.General.EnableAutoUpdates="Αυτόματος έλεγχος ενημερώσεων κατά την εκκίνηση" Basic.Settings.General.OpenStatsOnStartup="Άνοιγμα παραθύρου στατιστικών κατά την εκκίνηση" -Basic.Settings.General.WarnBeforeStartingStream="Εμφάνιση παραθύρου επιβεβαίωσης κατά την εκκίνηση των streams" -Basic.Settings.General.WarnBeforeStoppingStream="Εμφάνιση παραθύρου επιβεβαίωσης κατά τη διακοπή των streams" +Basic.Settings.General.WarnBeforeStartingStream="Εμφάνιση παραθύρου επιβεβαίωσης κατά την εκκίνηση των ροών" +Basic.Settings.General.WarnBeforeStoppingStream="Εμφάνιση παραθύρου επιβεβαίωσης κατά τον τερματισμό των ροών" Basic.Settings.General.Projectors="Προβολείς" Basic.Settings.General.HideProjectorCursor="Απόκρυψη τού δρομέα πάνω από τούς προβολείς" -Basic.Settings.General.ProjectorAlwaysOnTop="Προβολείς πάντα στην κορυφή" -Basic.Settings.General.Snapping="Ευθυγράμμιση πηγής" +Basic.Settings.General.ProjectorAlwaysOnTop="Προβολείς πάντα στην επιφάνεια" +Basic.Settings.General.Snapping="Προσκόλληση στην Ευθυγράμμιση Πηγής" Basic.Settings.General.ScreenSnapping="Προσκόλληση πηγών στην άκρη της οθόνης" -Basic.Settings.General.CenterSnapping="Προσκόλληση πηγών οριζόντια και κάθετα στο κέντρο" +Basic.Settings.General.CenterSnapping="Προσκόλληση πηγών οριζόντια και κατακόρυφα στο κέντρο" Basic.Settings.General.SourceSnapping="Προσκόλληση πηγών σε άλλες πηγές" Basic.Settings.General.SnapDistance="Ευαισθησία προσκόλλησης" Basic.Settings.General.RecordWhenStreaming="Αυτόματη καταγραφή κατά την ροή" -Basic.Settings.General.KeepRecordingWhenStreamStops="Διατηρήσετε καταγραφών όταν σταματά η ροή" -Basic.Settings.General.ReplayBufferWhileStreaming="Αυτόματη εκκίνηση replay buffer κατά τη ροή" -Basic.Settings.General.KeepReplayBufferStreamStops="Διατήρηση επανάληψης buffer όταν σταματά η ροή" -Basic.Settings.General.SysTray="System Tray" -Basic.Settings.General.SysTrayWhenStarted="Ελαχιστοποίηση στο System Tray κατά την εκκίνηση" -Basic.Settings.General.SystemTrayHideMinimize="Συνεχής ελαχιστοποίηση στο System Tray αντί στην γραμμή εργασιών" +Basic.Settings.General.KeepRecordingWhenStreamStops="Διατήρηση καταγραφής όταν τερματίζεται η ροή" +Basic.Settings.General.ReplayBufferWhileStreaming="Αυτόματη εκκίνηση επανάληψης προσωρινής μνήμης κατά τη ροή" +Basic.Settings.General.KeepReplayBufferStreamStops="Διατήρηση ενεργής επανάληψης προσωρινής μνήμης όταν τερματίζεται η ροή" +Basic.Settings.General.SysTray="Γραμμή Εργαλείων" +Basic.Settings.General.SysTrayWhenStarted="Ελαχιστοποίηση στη Γραμμή Εργαλείων κατά την εκκίνηση" +Basic.Settings.General.SystemTrayHideMinimize="Συνεχής ελαχιστοποίηση στη γραμμή εργαλείων αντί για τη γραμμή εργασιών" Basic.Settings.General.SaveProjectors="Αποθήκευση προβολής στην έξοδο" Basic.Settings.General.SwitchOnDoubleClick="Μετάβαση στην σκηνή με διπλό κλικ" Basic.Settings.General.StudioPortraitLayout="Ενεργοποίηση πορτρέτου/κατακόρυφης διάταξης" -Basic.Settings.General.MultiviewLayout="MultiView διάταξη" +Basic.Settings.General.Multiview="Multiview" +Basic.Settings.General.Multiview.MouseSwitch="Κάντε κλικ για εναλλαγή μεταξύ σκηνών" +Basic.Settings.General.Multiview.DrawSourceNames="Εμφάνιση ονομάτων σκηνών" +Basic.Settings.General.Multiview.DrawSafeAreas="Εμφάνιση ασφαλών περιοχών (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Διάταξη MultiView" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Οριζόντια, Επάνω (8 Σκηνές)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Οριζόντια, Κάτω (8 Σκηνές)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Κατακόρυφα, Αριστερά (8 Σκηνές)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Κατακόρυφα, Δεξιά (8 Σκηνές)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Οριζόντια, Επάνω (24 Σκηνές)" -Basic.Settings.Stream="Μετάδοση" -Basic.Settings.Stream.StreamType="Τύπος Μετάδοσης" +Basic.Settings.Stream="Ροή" +Basic.Settings.Stream.StreamType="Τύπος Ροής" Basic.Settings.Output="Έξοδος" Basic.Settings.Output.Format="Μορφή Καταγραφής" Basic.Settings.Output.Encoder="Κωδικοποιητής" -Basic.Settings.Output.SelectDirectory="Επιλέξτε κατάλογο καταγραφής" -Basic.Settings.Output.SelectFile="Επιλέξτε αρχείο καταγραφής" -Basic.Settings.Output.EnforceBitrate="Επιβολή ροής υπηρεσία bitrate ορίων" +Basic.Settings.Output.SelectDirectory="Επιλέξτε Φάκελο Καταγραφής" +Basic.Settings.Output.SelectFile="Επιλέξτε Αρχείο Καταγραφής" +Basic.Settings.Output.EnforceBitrate="Επιβολή υπηρεσίας ροής στα όρια ρυθμού μετάδοσης bits" Basic.Settings.Output.Mode="Λειτουργία Εξόδου" Basic.Settings.Output.Mode.Simple="Απλό" -Basic.Settings.Output.Mode.Adv="Σύνθετες επιλογές" +Basic.Settings.Output.Mode.Adv="Για Προχωρημένους" Basic.Settings.Output.Mode.FFmpeg="Έξοδος FFmpeg" -Basic.Settings.Output.UseReplayBuffer="Ενεργοποίηση επανάληψης Buffer" +Basic.Settings.Output.UseReplayBuffer="Ενεργοποίηση Επανάληψης Προσωρινής Μνήμης" Basic.Settings.Output.ReplayBuffer.SecondsMax="Μέγιστος Χρόνος Επανάληψης (Δευτερόλεπτα)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Μέγιστη Μνήμη (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Εκτιμώμενη χρήση μνήμης: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Δεν είναι δυνατή η εκτίμηση της χρήσης μνήμης. Ορίστε μέγιστο όριο μνήμης." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Σημείωση: Βεβαιωθείτε ότι ορίσατε μία συντόμευση για το buffer στην ενότητα συντομέυσεων)" -Basic.Settings.Output.ReplayBuffer.Prefix="Πρόθεμα ονόματος αρχείου Buffer Replay" +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Σημείωση: Βεβαιωθείτε ότι ορίσατε μία συντόμευση για την επανάληψη προσωρινής μνήμης στην ενότητα πλήκτρων συντόμευσης)" +Basic.Settings.Output.ReplayBuffer.Prefix="Πρόθεμα ονόματος αρχείου Επανάληψης Προσωρινής Μνήμης" Basic.Settings.Output.ReplayBuffer.Suffix="Επίθεμα" Basic.Settings.Output.Simple.SavePath="Διαδρομή Καταγραφής" -Basic.Settings.Output.Simple.RecordingQuality="Ποιότητα Εγγραφής" +Basic.Settings.Output.Simple.RecordingQuality="Ποιότητα Καταγραφής" Basic.Settings.Output.Simple.RecordingQuality.Stream="Ίδιο με την ροή" Basic.Settings.Output.Simple.RecordingQuality.Small="Υψηλής Ποιότητας, Μεσαίου Μεγέθους Αρχείο" Basic.Settings.Output.Simple.RecordingQuality.HQ="Δυσδιάκριτης Ποιότητας, Μεγάλου Μεγέθους Αρχείο" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Ποιότητας Χωρίς Απώλειες, Εξαιρετικά Μεγάλου Μεγέθους Αρχείο" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Προειδοποίηση: Το streaming βίντεο bitrate θα οριστεί %1, που είναι το ανώτερο όριο για την τρέχουσα υπηρεσία συνεχούς ροής. Εάν είστε βέβαιοι ότι θέλετε να πάτε πάνω από %1, Ενεργοποίηση επιλογών προηγμένο κωδικοποιητή και uncheck «Επιβολή streaming υπηρεσία bitrate όρια»." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Προειδοποίηση: Η ροή ήχου bitrate θα οριστεί %1, που είναι το ανώτερο όριο για την τρέχουσα υπηρεσία συνεχούς ροής. Εάν είστε βέβαιοι ότι θέλετε να πάτε πάνω από %1, Ενεργοποίηση επιλογών προηγμένο κωδικοποιητή και uncheck «Επιβολή streaming υπηρεσία bitrate όρια»." -Basic.Settings.Output.Simple.Warn.Encoder="Προσοχή: Η εγγραφή με έναν κωδικοποιητή λογισμικού σε διαφορετική ποιότητα από την ροή θα απαιτήσει πρόσθετη χρήση της CPU, αν μπορείτε να πραγματοποιήσετε την ροή και την εγγραφή την ίδια στιγμή." -Basic.Settings.Output.Simple.Warn.Lossless="Προειδοποίηση: Η μη απωλεστική ποιότητα δημιουργεί τρομερά μεγάλο μέγεθος των αρχείων! Η ποιότητα χωρίς απώλειες ποιότητας θα καταλάβει 7 gigabyte χώρο στον σκληρό δίσκο ανά λεπτό, σε υψηλές αναλύσεις και framerates. Χωρίς απώλειες δεν συνιστάται για μεγάλες ηχογραφήσεις, εκτός αν έχετε πολύ χώρο στον σκληρό δίσκο." -Basic.Settings.Output.Simple.Warn.Lossless.Msg="Είστε σίγουρος ότι θέλετε να το χρησιμοποιήσετε χωρίς απώλειες ποιότητας;" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Χωρίς απώλειες ποιότητας προειδοποίηση!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Προειδοποίηση: Δεν μπορείτε να χρησιμοποιήσετε πολλαπλούς ξεχωριστούς QSV κωδικοποιητές κατά την ροή και την εγγραφή την ίδια στιγμή. Αν θέλετε κάνετε stream και να καταγράψετε ταυτόχρονα, παρακαλείστε να αλλάξετε είτε την εγγραφή η την ροή τού κωδικοποιητή." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Προειδοποίηση: Το βίντεο ροής ρυθμού μετάδοσης bit θα οριστεί σε %1, που είναι το ανώτερο όριο για την τρέχουσα υπηρεσία συνεχούς ροής. Εάν είστε βέβαιοι ότι θέλετε να υπερβείτε το %1, ενεργοποιήστε τις επιλογές του κωδικοποιητή για προχωρημένους και αποεπιλέξτε την επιλογή «Επιβολή υπηρεσίας ροής στα όρια ρυθμού μετάδοσης bit»." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Προειδοποίηση: Ο ρυθμος μετάδοσης bit του ήχου ροής θα οριστεί στο %1, που είναι το ανώτατο όριο για την τρέχουσα υπηρεσία συνεχούς ροής. Εάν είστε βέβαιοι ότι θέλετε να υπερβείτε το %1, ενεργοποιήστε τις επιλογές του κωδικοποιητή για προχωρημένους και αποεπιλέξτε την επιλογή «Επιβολή υπηρεσίας ροής στα όρια ρυθμού μετάδοσης bit»." +Basic.Settings.Output.Simple.Warn.Encoder="Προειδοποίηση: Η καταγραφή με χρήση κωδικοποιητή λογισμικού σε διαφορετική ποιότητα από την ροή θα απαιτήσει πρόσθετη χρήση της CPU, αν πραγματοποιήσετε ταυτόχρονα μετάδοση ροής και καταγραφή." +Basic.Settings.Output.Simple.Warn.Lossless="Προειδοποίηση: Η ποιότητα χωρίς απώλειες αυξάνει πολύ το μέγεθος των αρχείων! Η ποιότητα χωρίς απώλειες ποιότητας θα καταλάβει 7 gigabyte χώρο στον σκληρό δίσκο ανά λεπτό, σε υψηλές αναλύσεις και ρυθμό καρέ. Η επιλογή χωρίς απώλειες δεν συνιστάται για μεγάλες σε διάρκεια καταγραφές, εκτός και αν έχετε πολύ ελεύθερο χώρο διαθέσιμο στο σκληρό σας δίσκο." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Είστε σίγουρος ότι θέλετε να χρησιμοποιήσετε την επιλογή ποιότητα χωρίς απώλειες;" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Προειδοποίηση ποιότητας χωρίς απώλειες!" Basic.Settings.Output.Simple.Encoder.Software="Λογισμικό (x264)" -Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Υλικού (QSV)" -Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Υλικού (AMD)" -Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Υλικού (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Λογισμικό (x264 χαμηλή χρήση CPU preset, αυξάνει το μέγεθος τού αρχείου)" -Basic.Settings.Output.VideoBitrate="Ρυθμός Bit του Βίντεο" -Basic.Settings.Output.AudioBitrate="Ρυθμός Bit του Ήχου" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Υλισμικό (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Υλισμικό (AMD)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Υλισμικό (NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Λογισμικό (προεπιλογή x264 χαμηλής χρήσης CPU, αυξάνει το μέγεθος αρχείου)" +Basic.Settings.Output.VideoBitrate="Ρυθμός Μετάδοσης Bit του Βίντεο" +Basic.Settings.Output.AudioBitrate="Ρυθμός Μετάδοσης Bit του Ήχου" Basic.Settings.Output.Reconnect="Αυτόματη Επανασύνδεση" Basic.Settings.Output.RetryDelay="Καθυστέρηση Επανάληψης (δευτερόλεπτα)" Basic.Settings.Output.MaxRetries="Μέγιστος Αριθμός Επαναλήψεων" -Basic.Settings.Output.Advanced="Ενεργοποίηση Ρυθμίσεις Κωδικοποιήτη Για Προχωρημένους" -Basic.Settings.Output.EncoderPreset="Προφίλ Κωδικοποιητή (υψηλότερο = λιγότερη CPU)" +Basic.Settings.Output.Advanced="Ενεργοποίηση Ρυθμίσεων Κωδικοποιητή Για Προχωρημένους" Basic.Settings.Output.CustomEncoderSettings="Προσαρμοσμένες Ρυθμίσεις Κωδικοποιητή" Basic.Settings.Output.CustomMuxerSettings="Προσαρμοσμένες Ρυθμίσεις Πολυπλέκτη" Basic.Settings.Output.NoSpaceFileName="Δημιουργία Ονόματος Αρχείου χωρίς Κενό" @@ -562,7 +579,7 @@ Basic.Settings.Output.NoSpaceFileName="Δημιουργία Ονόματος Α Basic.Settings.Output.Adv.Rescale="Κλιμάκωση Εξόδου" Basic.Settings.Output.Adv.AudioTrack="Κομμάτι ήχου" Basic.Settings.Output.Adv.Streaming="Ροή" -Basic.Settings.Output.Adv.ApplyServiceSettings="Επιβολή ρυθμίσεων κωδικοποιητή της υπηρεσίας streaming" +Basic.Settings.Output.Adv.ApplyServiceSettings="Επιβολή ρυθμίσεων κωδικοποιητή της υπηρεσίας ροής" Basic.Settings.Output.Adv.Audio.Track1="Κομμάτι 1" Basic.Settings.Output.Adv.Audio.Track2="Κομμάτι 2" Basic.Settings.Output.Adv.Audio.Track3="Κομμάτι 3" @@ -570,17 +587,17 @@ Basic.Settings.Output.Adv.Audio.Track4="Κομμάτι 4" Basic.Settings.Output.Adv.Audio.Track5="Κομμάτι 5" Basic.Settings.Output.Adv.Audio.Track6="Κομμάτι 6" -Basic.Settings.Output.Adv.Recording="Εγγραφή" +Basic.Settings.Output.Adv.Recording="Καταγραφή" Basic.Settings.Output.Adv.Recording.Type="Τύπος" Basic.Settings.Output.Adv.Recording.Type.Standard="Κανονικός" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Προσαρμοσμένη Έξοδος (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Χρήση κωδικοποιητή ροής)" -Basic.Settings.Output.Adv.Recording.Filename="Μορφοποίηση ονόματος αρχείου" +Basic.Settings.Output.Adv.Recording.Filename="Μορφοποίηση Ονόματος Αρχείου" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Αντικατάσταση εάν το αρχείο υπάρχει" Basic.Settings.Output.Adv.FFmpeg.Type="Τύπος εξόδου FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Έξοδος σε διεύθυνση URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Έξοδος σε αρχείο" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Κοινή μορφές εγγραφής" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Κοινές μορφές καταγραφής" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Όλα τα αρχεία" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Διαδρομή αρχείου ή URL" Basic.Settings.Output.Adv.FFmpeg.Format="Μορφή Περιέκτη" @@ -588,7 +605,7 @@ Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Ήχος" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Βίντεο" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Προεπιλεγμένη Μορφή" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Περιγραφή Περιέκτη Μορφής" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Codec Ήχου/Βίντεο μαντεύθηκε από τη Διαδρομή Αρχείου ή το URL" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Το Codec Ήχου/Βίντεο μαντεύθηκε από τη Διαδρομή Αρχείου ή το URL" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Προεπιλεγμένος Κωδικοποιητής" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Απενεργοποίηση Κωδικοποιητή" Basic.Settings.Output.Adv.FFmpeg.VEncoder="Κωδικοποιητής Βίντεο" @@ -597,25 +614,24 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoder="Κωδικοποιητής Ήχου" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Ρυθμίσεις Κωδικοποιητή Ήχου (αν υπάρχουν)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ρυθμίσεις Πολυπλέκτη (αν υπάρχει)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="Διάστημα καρέ-κλειδιού (σε καρέ)" -Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Προβολή όλων των codecs (ακόμα και αν είναι πιθανών μη συμβατοί)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Προβολή όλων των codecs (ακόμα και αν δεν είναι συμβατοί)" -FilenameFormatting.completer="%AAXX-%MM-%ΗΗ %ωω-%λλ-%δδ\n%ΧΧ-%ΜΜ-%ΗΗ %ωω-%λλ-%δδ\n%Χ-%μ-%η %Ω-%Λ-%Δ\n%χ-%μ-%η %Ω-%Λ-%Δ\n%α %Χ-%μ-%η %Ω-%Λ-%Δ\n%Α %Χ-%μ-%η %Ω-%Λ-%Δ\n%Χ-%μ-%η %Ω-%Λ-%Δ\n%Χ-%Μ-%η %Ω-%Λ-%Δ\n%Χ-%μ-%η %Ω-%Λ-%Δ-%p\n%Χ-%μ-%μ %Ω-%Λ-%Δ-%ζ\n%Χ-%μ-%η %Ω-%Λ-%Δ-%Ζ" -FilenameFormatting.TT="%CCYY έτους, τέσσερις digits\n%YY έτος, τα δύο τελευταία ψηφία (00-99) \n%MM μήνα ως ένα δεκαδικό αριθμό (01-12) \n%DD ημέρα του μήνα, μηδέν επένδυση (01-31)\n%hh ώρα στο 24h μορφή (00-23) \n%mm λεπτό (00-59) \n%ss δεύτερος (00-61) \n%% μια%a sign\n % συντετμημένη καθημερινές name\n%A πλήρη ημέρα της εβδομάδας name\n%b συντετμημένη μήνα name\n%B πλήρη μήνα name\n%d ημέρα του μήνα, μηδέν-γεμισμένος (01-31) \n%H ώρα στο 24h μορφή (00-23) \n%I ώρα σε μορφή 12h (01-12)\n%m μήνας ως δεκαδικός αριθμός (01-12)\n%M λεπτά (00-59) \n%p π. μ. ή μ. μ. designation\n%S δεύτερο (00-61) \n%y έτος, τελευταία δύο ψηφία (00-99)\n%Y Year\n%z ISO 8601 μετατόπιση από UTC ή timezone\n όνομα ή όνομα ζώνης ώρας%Z abbreviation\n ή abbreviation\n" +FilenameFormatting.TT="%CCYY Έτος, τέσσερα ψηφία\n%YY Έτος, τα δύο τελευταία ψηφία (00-99) \n%MM Μήνας ως ένας δεκαδικός αριθμός (01-12) \n%DD Ημέρα του μήνα, μηδέν αποκοπή (01-31)\n%hh Ώρα σε 24ωρη μορφή (00-23) \n%mm Λεπτό (00-59) \n%ss Δευτερόλεπτο (00-61) \n%% Ένα % σύμβολο\n%a Συντετμημένη ημέρα εβδομάδας\n%A Πλήρης ημέρα της εβδομάδας \n%b Συντετμημένο όνομα μήνα\n%B Πλήρες όνομα μήνα \n%d Ημέρα του μήνα, μηδέν-αποκοπή (01-31)\n%H Ώρα σε 24ωρη μορφή (00-23) \n%I Ώρα σε μορφή 12ωρη (01-12)\n%m Μήνας ως δεκαδικός αριθμός (01-12)\n%M Λεπτό (00-59)\n%p π. μ. ή μ. μ. προσδιορισμός\n%S Δευτερόλεπτο (00-61) \n%y Έτος, τελευταία δύο ψηφία (00-99)\n%Y Έτος\n%z ISO 8601 μετατόπιση από UTC ή ζώνη ώρας\n όνομα ή συντόμευση\n%Z Όνομα ζώνης ώρας ή συντόμευση\n" Basic.Settings.Video="Βίντεο" -Basic.Settings.Video.Adapter="Προσαρμογέας Βίντεο:" -Basic.Settings.Video.BaseResolution="Βάση (Καμβάς) Ανάλυση" -Basic.Settings.Video.ScaledResolution="Ανάλυση εξόδου (κλίμακα)" -Basic.Settings.Video.DownscaleFilter="Φίλτρο Σμίκρυνσης:" +Basic.Settings.Video.Adapter="Προσαρμογέας Βίντεο" +Basic.Settings.Video.BaseResolution="Ανάλυση Βάσης (Καμβάς)" +Basic.Settings.Video.ScaledResolution="Ανάλυση Εξόδου (Κλίμακα)" +Basic.Settings.Video.DownscaleFilter="Φίλτρο Σμίκρυνσης" Basic.Settings.Video.DisableAeroWindows="Απενεργοποίηση Aero (Windows μόνο)" -Basic.Settings.Video.FPS="Καρέ ανά δευτερόλεπτο (FPS):" +Basic.Settings.Video.FPS="Καρέ ανά δευτερόλεπτο (FPS)" Basic.Settings.Video.FPSCommon="Κοινές Τιμές FPS" Basic.Settings.Video.FPSInteger="Ακέραια Τιμή FPS" Basic.Settings.Video.FPSFraction="Κλασματική Τιμή FPS" -Basic.Settings.Video.Numerator="Αριθμητής:" -Basic.Settings.Video.Denominator="Παρονομαστής:" -Basic.Settings.Video.Renderer="Renderer:" +Basic.Settings.Video.Numerator="Αριθμητής" +Basic.Settings.Video.Denominator="Παρονομαστής" +Basic.Settings.Video.Renderer="Απόδοση" Basic.Settings.Video.InvalidResolution="Μη έγκυρη τιμή ανάλυσης. Πρέπει να είναι [width]x[height] (π.χ. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Δεν υπάρχει ενεργή έξοδος βίντεο. Παρακαλώ απενεργοποιήστε κάθε έξοδο για να αλλάξετε τις ρυθμίσεις βίντεο." Basic.Settings.Video.DisableAero="Απενεργοποίηση του Aero" @@ -627,43 +643,37 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Οξυμμένη κλιμ Basic.Settings.Audio="Ήχος" Basic.Settings.Audio.SampleRate="Ρυθμός Δειγματοληψίας" Basic.Settings.Audio.Channels="Κανάλια" -Basic.Settings.Audio.MeterDecayRate="Συντελεστής απόσβεσης ήχου μέτρησης" Basic.Settings.Audio.MeterDecayRate.Fast="Γρήγορος" Basic.Settings.Audio.MeterDecayRate.Medium="Μεσαίος (τύπος Ι PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Αργός (Τύπος ΙΙ PPM)" +Basic.Settings.Audio.PeakMeterType="Τύπος Μέτρησης Αιχμής" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Δείγμα Αιχμής" +Basic.Settings.Audio.PeakMeterType.TruePeak="Πραγματική Αιχμή (Υψηλότερη χρήση της CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Προειδοποίηση: Ο ήχος Surround είναι ενεργοποιημένος." -Basic.Settings.Audio.MultichannelWarning="Κατά το streaming, ελέγξτε αν η υπηρεσία streaming υποστηρίζει ήχο surround δύο ηχείων και ήχο surround αναπαραγωγής. Το Twitch, το Facebook 360 Live, το μίξερ RTMP καί το Smashcast αποτελούν παραδείγματα όπου ο surround ήχος υποστηρίζεται πλήρως. Αν και το Facebook Live και το YouTube Live αποδέχεστε τον ήχο surround, το Facebook Live κατεβάζει τον σε stereo, και το YouTube Live υποστηρίζει μόνο δύο φίλτρα ήχου.\n\nΤο OBS είναι συμβατό με ήχο surround, αν καί δεν είναι εγγυημένη η υποστήριξη για plugins VST." +Basic.Settings.Audio.MultichannelWarning="Κατά τη ροή, ελέγξτε αν η υπηρεσία ροής υποστηρίζει ήχο surround και ήχο surround αναπαραγωγής. Το Twitch, το Facebook 360 Live, το Mixer RTMP καί το Smashcast αποτελούν παραδείγματα όπου ο surround ήχος υποστηρίζεται πλήρως. Αν και το Facebook Live και το YouTube Live αποδέχονται τον ήχο surround, το Facebook Live τον υποβιβάζει σε stereo, και το YouTube Live παίζει μόνο σε δύο κανάλια.\n\nΤα φίλτρα ήχου του OBS είναι συμβατά με ήχο surround, αν καί δεν είναι εγγυημένη η υποστήριξη για plugins VST." Basic.Settings.Audio.MultichannelWarning.Title="Ενεργοποίηση ήχου surround;" -Basic.Settings.Audio.MultichannelWarning.Confirm="Είναι βέβαιοι ότι θέλετε να ενεργοποιήσετε τον ήχο surround;" -Basic.Settings.Audio.DesktopDevice="Συσκευή Ήχου Επιφάνειας" -Basic.Settings.Audio.DesktopDevice2="Συσκευή Ήχου Επιφάνειας 2" -Basic.Settings.Audio.AuxDevice="Μικρόφωνο/Αuxillary Συσκευή Ήχου" -Basic.Settings.Audio.AuxDevice2="Μικρόφωνο/Αuxillary Συσκευή Ήχου 2" -Basic.Settings.Audio.AuxDevice3="Μικρόφωνο/Αuxillary Συσκευή Ήχου 3" -Basic.Settings.Audio.EnablePushToMute="Ενεργοποίηση της ώθησης-γιά-σίγαση" -Basic.Settings.Audio.PushToMuteDelay="Καθυστέρηση ώθησης-γιά-σίγαση" -Basic.Settings.Audio.EnablePushToTalk="Ενεργοποίηση Push-to-talk" +Basic.Settings.Audio.MultichannelWarning.Confirm="Είστε βέβαιοι ότι θέλετε να ενεργοποιήσετε τον ήχο surround;" +Basic.Settings.Audio.EnablePushToMute="Ενεργοποίηση της Πίεσης-για-σίγαση" +Basic.Settings.Audio.PushToMuteDelay="Καθυστέρηση Πίεσης-για-σίγαση" +Basic.Settings.Audio.EnablePushToTalk="Ενεργοποίηση Πίεσης-για-ομιλία" Basic.Settings.Audio.PushToTalkDelay="Push-to-talk καθυστέρηση" -Basic.Settings.Audio.UnknownAudioDevice="[Η συσκευή δεν είναι συνδεδεμένη η δεν είναι διαθέσιμη]" +Basic.Settings.Audio.UnknownAudioDevice="[Η συσκευή δεν είναι συνδεδεμένη ή δεν είναι διαθέσιμη]" -Basic.Settings.Advanced="Σύνθετες επιλογές" -Basic.Settings.Advanced.General.ProcessPriority="Προτεραιότητα διαδικασίας" +Basic.Settings.Advanced="Για Προχωρημένους" +Basic.Settings.Advanced.General.ProcessPriority="Προτεραιότητα Διαδικασίας" Basic.Settings.Advanced.General.ProcessPriority.High="Υψηλή" -Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Πάνω από το φυσιολογικό" +Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Πάνω από την Κανονική" Basic.Settings.Advanced.General.ProcessPriority.Normal="Κανονική" -Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Κάτω από την κανονική" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Κάτω από την Κανονική" Basic.Settings.Advanced.General.ProcessPriority.Idle="Σε αδράνεια" -Basic.Settings.Advanced.FormatWarning="Προσοχή: Μορφές χρώματος εκτός του NV12 προορίζονται κυρίως για καταγραφή, και δεν συνιστώνται κατά τη μετάδοση. Ενδέχεται να υπάρξει αυξημένη χρήση της CPU λόγω μετατροπής μορφής χρώματος." -Basic.Settings.Advanced.Audio.BufferingTime="Χρόνος buffering ήχου" +Basic.Settings.Advanced.FormatWarning="Προειδοποίηση: Μορφές χρώματος εκτός του NV12 προορίζονται κυρίως για καταγραφή, και δεν συνιστώνται κατά τη ροή. Ενδέχεται να υπάρξει αυξημένη χρήση της CPU λόγω μετατροπής μορφής χρώματος." +Basic.Settings.Advanced.Audio.BufferingTime="Χρόνος Προσωρινής Μνήμης Ήχου" Basic.Settings.Advanced.Video.ColorFormat="Μορφή Χρώματος" -Basic.Settings.Advanced.Video.ColorSpace="Χώρος χρωμάτων YUV" -Basic.Settings.Advanced.Video.ColorRange="Ποικιλία χρωμάτων YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Μερικό" Basic.Settings.Advanced.Video.ColorRange.Full="Πλήρες" -Basic.Settings.Advanced.Audio.MonitoringDevice="Συσκευή παρακολούθησης ήχου" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Προεπιλεγμένη" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Απενεργοποίηση σίγασης ήχου" -Basic.Settings.Advanced.StreamDelay="Καθυστέρηση ροής" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Απενεργοποίηση Σίγασης Ήχου Windows" +Basic.Settings.Advanced.StreamDelay="Καθυστέρηση Ροής" Basic.Settings.Advanced.StreamDelay.Duration="Διάρκεια (δευτερόλεπτα)" Basic.Settings.Advanced.StreamDelay.Preserve="Διατήρηση σημείου αποκοπής (αύξηση καθυστέρησης) κατά την επανασύνδεση" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Εκτιμώμενη Χρήση Μνήμης: %1 MB" @@ -671,31 +681,34 @@ Basic.Settings.Advanced.Network="Δίκτυο" Basic.Settings.Advanced.Network.BindToIP="Σύνδεση με IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Ενεργοποίηση νέου κώδικα δικτύωσης" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Λειτουργία χαμηλής καθυστέρησης" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Απενεργοποίηση πλήκτρων συντόμευσης όταν το κύριο παράθυρο βρίσκεται στο προσκήνιο" +Basic.Settings.Advanced.AutoRemux="Αυτόματη μετατροπή σε mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(καταγραφή ως mkv)" Basic.AdvAudio="Ιδιότητες Ήχου για Προχωρημένους" Basic.AdvAudio.Name="Όνομα" -Basic.AdvAudio.Volume="Ένταση (%)" -Basic.AdvAudio.Mono="Αποκωδικοποίηση σε Mono" -Basic.AdvAudio.Panning="Πανοραμικό" +Basic.AdvAudio.Mono="Υποβίβαση σε Μονοφωνικό" +Basic.AdvAudio.Balance="Εξισορρόπηση" Basic.AdvAudio.SyncOffset="Μετατόπιση Συγχρονισμού (ms)" -Basic.AdvAudio.Monitoring="Ηχητική παρακολούθηση" -Basic.AdvAudio.Monitoring.None="Monitor Off" -Basic.AdvAudio.Monitoring.MonitorOnly="Μόνο η οθόνη (σίγαση εξόδου)" -Basic.AdvAudio.Monitoring.Both="Παρακολούθηση και έξοδος" +Basic.AdvAudio.Monitoring="Ηχητική Παρακολούθηση" +Basic.AdvAudio.Monitoring.None="Τερματισμός Παρακολούθησης" +Basic.AdvAudio.Monitoring.MonitorOnly="Παρακολούθηση Μόνο (σίγαση εξόδου)" +Basic.AdvAudio.Monitoring.Both="Παρακολούθηση και Έξοδος" Basic.AdvAudio.AudioTracks="Κομμάτια" Basic.Settings.Hotkeys="Πλήκτρα συντόμευσης" Basic.Settings.Hotkeys.Pair="Συνδυασμοί πλήκτρων που μοιράζεται με το «%1» που ενεργούν ως εναλλαγή" +Basic.Settings.Hotkeys.Filter="Φίλτρο" Basic.Hotkeys.SelectScene="Μετάβαση σε σκηνή" Basic.SystemTray.Show="Εμφάνιση" Basic.SystemTray.Hide="Απόκρυψη" -Basic.SystemTray.Message.Reconnecting="Έγινε αποσύνδεση. Γίνεται επανασύνδεση..." +Basic.SystemTray.Message.Reconnecting="Έγινε αποσύνδεση. Γίνεται επανασύνδεση..." Hotkeys.Insert="Insert" -Hotkeys.Delete="Delete" +Hotkeys.Delete="Διαγραφή" Hotkeys.Home="Home" Hotkeys.End="End" Hotkeys.PageUp="Page Up" @@ -725,26 +738,42 @@ Hotkeys.AppleKeypadNum="%1 (Keypad)" Hotkeys.AppleKeypadMultiply="* (Keypad)" Hotkeys.AppleKeypadDivide="/ (Keypad)" Hotkeys.AppleKeypadAdd="+ (Keypad)" -Hotkeys.AppleKeypadSubtract="- (Αριθμητικό πληκτρολόγιο)" -Hotkeys.AppleKeypadDecimal=". (Πληκτρολόγιο)" -Hotkeys.AppleKeypadEqual="= (Αριθμητικό πληκτρολόγιο)" -Hotkeys.MouseButton="%1 ποντίκι" +Hotkeys.AppleKeypadSubtract="- (Keypad)" +Hotkeys.AppleKeypadDecimal=". (Keypad)" +Hotkeys.AppleKeypadEqual="= (Keypad)" +Hotkeys.MouseButton="Mouse %1" Mute="Σίγαση" Unmute="Κατάργηση σίγασης" -Push-to-mute="Ώθηση-για-σίγαση" -Push-to-talk="Πίεση και ομιλία" +Push-to-mute="Πίεση-για-σίγαση" +Push-to-talk="Πίεση-για-ομολία" SceneItemShow="Εμφάνιση '%1'" SceneItemHide="Απόκρυψη '%1'" OutputWarnings.NoTracksSelected="Πρέπει να επιλέξετε τουλάχιστον ένα κομμάτι" OutputWarnings.MultiTrackRecording="Προειδοποίηση: Ορισμένες μορφές (όπως FLV) δεν υποστηρίζουν πολλαπλά κομμάτια ανά εγγραφή" -OutputWarnings.MP4Recording="Προειδοποίηση: Οι ηχογραφήσεις που έχουν αποθηκευτεί σε MP4 θα είναι αδιόρθωτες, αν το αρχείο δεν είναι δυνατόν να ολοκληρωθεί (π.χ. λόγω BSODs, απώλεια ισχύος, κλπ.). Αν θέλετε να καταγράψετε πολλαπλά κομμάτια ήχου χρησιμοποιήστε το MKV και remux καταγραφής για mp4, αφού τελειώσει (αρχείο-> Remux ηχογραφήσεις)" FinalScene.Title="Διαγραφή σκηνής" FinalScene.Text="Πρέπει να υπάρχει τουλάχιστον μία σκηνή." - +NoSources.Title="Δεν Υπάρχουν Πηγές" +NoSources.Text="Δεν έχετε προσθέσει καμία πηγή βίντεο, επομένως θα εξαχθεί μία κενή οθόνη. Σίγουρα επιθυμείτε να συνεχίσετε;" +NoSources.Text.AddSource="Μπορείτε να προσθέσετε πηγές οποιαδήποτε στιγμή κάνοντας κλικ στο εικονίδιο + κάτω από το πλαίσιο Πηγές στο κύριο παράθυρο." + +ChangeBG="Ορίστε Χρώμα" +CustomColor="Προσαρμοσμένο Χρώμα" + +BrowserSource.EnableHardwareAcceleration="Ενεργοποίηση Επιτάχυνσης Υλικού Πηγής του Προγράμματος Περιήγησης" + +About="Σχετικά" +About.Info="Το OBS Studio είναι ένα ελεύθερο και ανοικτού κώδικα λογισμικό καταγραφής βίντεο και ζωντανής μετάδοσης." +About.GetInvolved="Συμμετάσχετε" +About.Authors="Δημιουργοί" +About.License="Άδεια" + +ResizeOutputSizeOfSource="Αλλαγή διαστάσεων εξόδου (διαστάσεις πηγής)" +ResizeOutputSizeOfSource.Text="Η βασική ανάλυση και η ανάλυση εξόδου θα μεταβληθούν σύμφωνα με τις διαστάσεις της τρέχουσας πηγής." +ResizeOutputSizeOfSource.Continue="Θέλετε να συνεχίσετε;" diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini index ca6d6a7..2400d1f 100644 --- a/UI/data/locale/en-US.ini +++ b/UI/data/locale/en-US.ini @@ -1,5 +1,5 @@ # Note to translators: *DO NOT* translate this file directly. Instead, visit http://crowdin.com/project/obs-studio and submit your translations there. -# Pull requests for translations outside of CrowdIn will not be accepted. +# Pull requests for translations outside of Crowdin will not be accepted. # Read this forum post for more instructions on submitting translations: https://obsproject.com/forum/threads/how-to-contribute-translations-for-obs.16327/ # Language and language region of this file @@ -54,7 +54,7 @@ Duplicate="Duplicate" Enable="Enable" DisableOSXVSync="Disable OSX V-Sync" ResetOSXVSyncOnExit="Reset OSX V-Sync on Exit" -HighResourceUsage="Encoding overloaded! Consider turning down video settings or using a faster encoding preset." +HighResourceUsage="Encoding overloaded! Consider turning down video settings or using a faster encoding preset." Transition="Transition" QuickTransitions="Quick Transitions" Left="Left" @@ -85,16 +85,45 @@ StudioMode.Program="Program" ShowInMultiview="Show in Multiview" VerticalLayout="Vertical Layout" Group="Group" +DoNotShowAgain="Do not show again" +Default="(Default)" +Calculating="Calculating..." # warning if program already open AlreadyRunning.Title="OBS is already running" -AlreadyRunning.Text="OBS is already running! Unless you meant to do this, please shut down any existing instances of OBS before trying to run a new instance. If you have OBS set to minimize to the system tray, please check to see if it's still running there." +AlreadyRunning.Text="OBS is already running! Unless you meant to do this, please shut down any existing instances of OBS before trying to run a new instance. If you have OBS set to minimize to the system tray, please check to see if it's still running there." AlreadyRunning.LaunchAnyway="Launch Anyway" +# warning when closing docks. it's frustrating that we actually need this. +DockCloseWarning.Title="Closing Dockable Window" +DockCloseWarning.Text="You just closed a dockable window. If you'd like to show it again, use the View → Docks menu on the menu bar." + +# Auth +Auth.Authing.Title="Authenticating..." +Auth.Authing.Text="Authenticating with %1, please wait..." +Auth.AuthFailure.Title="Authentication Failure" +Auth.AuthFailure.Text="Failed to authenticate with %1:\n\n%2: %3" +Auth.InvalidScope.Title="Authentication Required" +Auth.InvalidScope.Text="The authentication requirements for %1 have changed. Some features may not be available." +Auth.LoadingChannel.Title="Loading channel information..." +Auth.LoadingChannel.Text="Loading channel information for %1, please wait..." +Auth.ChannelFailure.Title="Failed to load channel" +Auth.ChannelFailure.Text="Failed to load channel information for %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Stream Information" +TwitchAuth.Stats="Twitch Stats" +TwitchAuth.Feed="Twitch Activity Feed" +TwitchAuth.TwoFactorFail.Title="Could not query stream key" +TwitchAuth.TwoFactorFail.Text="OBS was unable to connect to your Twitch account. Please make sure two-factor authentication is set up in your Twitch security settings as this is required to stream." + # copy filters Copy.Filters="Copy Filters" Paste.Filters="Paste Filters" +# browser initialization dialog +BrowserPanelInit.Title="Initializing Browser..." +BrowserPanelInit.Text="Initializing browser, please wait..." + # bandwidth test BandwidthTest.Region="Region" BandwidthTest.Region.US="United States" @@ -103,13 +132,11 @@ BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Other" # first time startup -Basic.FirstStartup.RunWizard="Would you like to run the auto-configuration wizard? You can also manually configure your settings by clicking the Settings button in the main window." -Basic.FirstStartup.RunWizard.BetaWarning="(Note: The auto-configuration wizard is currently in beta)" +Basic.FirstStartup.RunWizard="Would you like to run the auto-configuration wizard? You can also manually configure your settings by clicking the Settings button in the main window." Basic.FirstStartup.RunWizard.NoClicked="If you change your mind, you can run the auto-configuration wizard any time again from the Tools menu." # auto config wizard Basic.AutoConfig="Auto-Configuration Wizard" -Basic.AutoConfig.Beta="Auto-Configuration Wizard (Beta)" Basic.AutoConfig.ApplySettings="Apply Settings" Basic.AutoConfig.StartPage="Usage Information" Basic.AutoConfig.StartPage.SubTitle="Specify what you want to use the program for" @@ -122,11 +149,17 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Display %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Use Current (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Either 60 or 30, but prefer 60 when possible" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Either 60 or 30, but prefer high resolution" -Basic.AutoConfig.VideoPage.CanvasExplanation="Note: The canvas (base) resolution is not necessarily the same as the resolution you will stream or record with. Your actual stream/recording resolution may be scaled down from the canvas resolution to reduce resource usage or bitrate requirements." +Basic.AutoConfig.VideoPage.CanvasExplanation="Note: The canvas (base) resolution is not necessarily the same as the resolution you will stream or record with. Your actual stream/recording resolution may be scaled down from the canvas resolution to reduce resource usage or bitrate requirements." Basic.AutoConfig.StreamPage="Stream Information" Basic.AutoConfig.StreamPage.SubTitle="Please enter your stream information" +Basic.AutoConfig.StreamPage.ConnectAccount="Connect Account (optional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Disconnect Account" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Disconnect Account?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="This change will apply immediately. Are you sure you want to disconnect your account?" +Basic.AutoConfig.StreamPage.UseStreamKey="Use Stream Key" Basic.AutoConfig.StreamPage.Service="Service" Basic.AutoConfig.StreamPage.Service.ShowAll="Show All..." +Basic.AutoConfig.StreamPage.Service.Custom="Custom..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Stream Key" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" @@ -134,14 +167,14 @@ Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimate bitrate with bandwidt Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Prefer hardware encoding" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardware Encoding eliminates most CPU usage, but may require more bitrate to obtain the same level of quality." Basic.AutoConfig.StreamPage.StreamWarning.Title="Stream warning" -Basic.AutoConfig.StreamPage.StreamWarning.Text="The bandwidth test is about to stream randomized video data without audio to your channel. If you're able, it's recommended to temporarily turn off saving videos of streams and set the stream to private until after the test has completed. Continue?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="The bandwidth test is about to stream randomized video data without audio to your channel. If you're able, it's recommended to temporarily turn off saving videos of streams and set the stream to private until after the test has completed. Continue?" Basic.AutoConfig.TestPage="Final Results" Basic.AutoConfig.TestPage.SubTitle.Testing="The program is now executing a set of tests to estimate the most ideal settings" Basic.AutoConfig.TestPage.SubTitle.Complete="Testing complete" Basic.AutoConfig.TestPage.TestingBandwidth="Performing bandwidth test, this may take a few minutes..." -Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Connecting to: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Connecting to: %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Failed to connect to any servers, please check your internet connection and try again." -Basic.AutoConfig.TestPage.TestingBandwidth.Server="Testing bandwidth for: %1" +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Testing bandwidth for: %1" Basic.AutoConfig.TestPage.TestingStreamEncoder="Testing stream encoder, this may take a minute..." Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testing recording encoder, this may take a minute..." Basic.AutoConfig.TestPage.TestingRes="Testing resolutions, this may take a few minutes..." @@ -150,12 +183,12 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="Testing %1x%2 %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streaming Encoder" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Recording Encoder" Basic.AutoConfig.TestPage.Result.Header="The program has determined that these estimated settings are the most ideal for you:" -Basic.AutoConfig.TestPage.Result.Footer="To use these settings, click Apply Settings. To reconfigure the wizard and try again, click Back. To manually configure settings yourself, click Cancel and open Settings." +Basic.AutoConfig.TestPage.Result.Footer="To use these settings, click Apply Settings. To reconfigure the wizard and try again, click Back. To manually configure settings yourself, click Cancel and open Settings." # stats Basic.Stats="Stats" Basic.Stats.CPUUsage="CPU Usage" -Basic.Stats.HDDSpaceAvailable="HDD space available" +Basic.Stats.HDDSpaceAvailable="Disk space available" Basic.Stats.MemoryUsage="Memory Usage" Basic.Stats.AverageTimeToRender="Average time to render frame" Basic.Stats.SkippedFrames="Skipped frames due to encoding lag" @@ -170,6 +203,10 @@ Basic.Stats.Status.Inactive="Inactive" Basic.Stats.DroppedFrames="Dropped Frames (Network)" Basic.Stats.MegabytesSent="Total Data Output" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Disk full in (approx.)" + +ResetUIWarning.Title="Are you sure you want to reset the UI?" +ResetUIWarning.Text="Resetting the UI will hide additional docks. You will need to unhide these docks from the view menu if you want them to be visible.\n\nAre you sure you want to reset the UI?" # updater Updater.Title="New update available" @@ -183,7 +220,7 @@ Updater.NoUpdatesAvailable.Title="No updates available" Updater.NoUpdatesAvailable.Text="No updates are currently available" Updater.FailedToLaunch="Failed to launch updater" Updater.GameCaptureActive.Title="Game capture active" -Updater.GameCaptureActive.Text="Game capture hook library is currently in use. Please close any games/programs being captured (or restart windows) and try again." +Updater.GameCaptureActive.Text="Game capture hook library is currently in use. Please close any games/programs being captured (or restart Windows) and try again." # quick transitions QuickTransitions.SwapScenes="Swap Preview/Output Scenes After Transitioning" @@ -225,9 +262,13 @@ ConfirmStart.Text="Are you sure you want to start the stream?" ConfirmStop.Title="Stop Stream?" ConfirmStop.Text="Are you sure you want to stop the stream?" +# confirm bandwidth test dialog box +ConfirmBWTest.Title="Start Bandwidth Test?" +ConfirmBWTest.Text="You have OBS configured in bandwidth test mode. This mode allows for network testing without your channel going live. Once you are done testing, you will need to disable it in order for viewers to be able to see your stream.\n\nDo you want to continue?" + # confirm exit dialog box ConfirmExit.Title="Exit OBS?" -ConfirmExit.Text="OBS is currently active. All streams/recordings will be shut down. Are you sure you wish to exit?" +ConfirmExit.Text="OBS is currently active. All streams/recordings will be shut down. Are you sure you wish to exit?" # confirm delete dialog box ConfirmRemove.Title="Confirm Remove" @@ -238,60 +279,63 @@ ConfirmRemove.TextMultiple="Are you sure you wish to remove %1 items?" Output.StartStreamFailed="Failed to start streaming" Output.StartRecordingFailed="Failed to start recording" Output.StartReplayFailed="Failed to start replay buffer" -Output.StartFailedGeneric="Starting the output failed. Please check the log for details.\n\nNote: If you are using the NVENC or AMD encoders, make sure your video drivers are up to date." +Output.StartFailedGeneric="Starting the output failed. Please check the log for details.\n\nNote: If you are using the NVENC or AMD encoders, make sure your video drivers are up to date." + # output connect messages Output.ConnectFail.Title="Failed to connect" -Output.ConnectFail.BadPath="Invalid Path or Connection URL. Please check your settings to confirm that they are valid." +Output.ConnectFail.BadPath="Invalid Path or Connection URL. Please check your settings to confirm that they are valid." Output.ConnectFail.ConnectFailed="Failed to connect to server" -Output.ConnectFail.InvalidStream="Could not access the specified channel or stream key, please double-check your stream key. If it is correct, there may be a problem connecting to the server." -Output.ConnectFail.Error="An unexpected error occurred when trying to connect to the server. More information in the log file." +Output.ConnectFail.InvalidStream="Could not access the specified channel or stream key, please double-check your stream key. If it is correct, there may be a problem connecting to the server." +Output.ConnectFail.Error="An unexpected error occurred when trying to connect to the server. More information in the log file." Output.ConnectFail.Disconnected="Disconnected from server." +# output streaming-related messages +Output.StreamEncodeError.Title="Encoding error" +Output.StreamEncodeError.Msg="An encoder error occurred while streaming." + # output recording-related messages Output.RecordFail.Title="Failed to start recording" -Output.RecordFail.Unsupported="The output format is either unsupported or does not support more than one audio track. Please check your settings and try again." +Output.RecordFail.Unsupported="The output format is either unsupported or does not support more than one audio track. Please check your settings and try again." Output.RecordNoSpace.Title="Insufficient disk space" Output.RecordNoSpace.Msg="There is not sufficient disk space to continue recording." Output.RecordError.Title="Recording error" Output.RecordError.Msg="An unspecified error occurred while recording." +Output.RecordError.EncodeErrorMsg="An encoder error occurred while recording." Output.ReplayBuffer.NoHotkey.Title="No hotkey set!" -Output.ReplayBuffer.NoHotkey.Msg="No save hotkey set for replay buffer. Please set the \"Save\" hotkey to use for saving replay recordings." +Output.ReplayBuffer.NoHotkey.Msg="No save hotkey set for replay buffer. Please set the \"Save\" hotkey to use for saving replay recordings." # output recording messages Output.BadPath.Title="Bad File Path" -Output.BadPath.Text="The configured file output path is invalid. Please check your settings to confirm that a valid file path has been set." +Output.BadPath.Text="The configured file output path is invalid. Please check your settings to confirm that a valid file path has been set." # log upload dialog text and messages LogReturnDialog="Log Upload Successful" LogReturnDialog.CopyURL="Copy URL" LogReturnDialog.ErrorUploadingLog="Error uploading log file" -# license agreement dialog -LicenseAgreement="License Agreement" -LicenseAgreement.PleaseReview="Please review the license terms before using OBS. By using this program, you acknowledge that you have read and agree to the terms of the GNU General Public License v2.0. Please scroll down to see the rest of the agreement." -LicenseAgreement.ClickIAgreeToContinue="If you accept the terms of the agreement, click I Agree to continue. You must accept the agreement to use OBS." -LicenseAgreement.IAgree="I Agree" -LicenseAgreement.Exit="Exit" - # remux dialog Remux.SourceFile="OBS Recording" Remux.TargetFile="Target File" Remux.Remux="Remux" +Remux.Stop="Stop Remuxing" +Remux.ClearFinished="Clear Finished Items" +Remux.ClearAll="Clear All Items" Remux.OBSRecording="OBS Recording" Remux.FinishedTitle="Remuxing finished" Remux.Finished="Recording remuxed" Remux.FinishedError="Recording remuxed, but the file may be incomplete" -Remux.SelectRecording="Select OBS Recording …" -Remux.SelectTarget="Select target file …" -Remux.FileExistsTitle="Target file exists" -Remux.FileExists="Target file exists, do you want to replace it?" +Remux.SelectRecording="Select OBS Recording..." +Remux.SelectTarget="Select target file..." +Remux.FileExistsTitle="Target files exist" +Remux.FileExists="The following target files already exist. Do you want to replace them?" Remux.ExitUnfinishedTitle="Remuxing in progress" Remux.ExitUnfinished="Remuxing is not finished, stopping now may render the target file unusable.\nAre you sure you want to stop remuxing?" +Remux.HelpText="Drop files in this window to remux, or select an empty \"OBS Recording\" cell to browse for a file." # update dialog UpdateAvailable="New Update Available" -UpdateAvailable.Text="Version %1.%2.%3 is now available. Click here to download" +UpdateAvailable.Text="Version %1.%2.%3 is now available. Click here to download" # audio device names Basic.DesktopDevice1="Desktop Audio" @@ -308,12 +352,16 @@ Basic.DisplayCapture="Display Capture" # display context menu Basic.Main.PreviewConextMenu.Enable="Enable Preview" +# disable preview +Basic.Main.Preview.Disable="Disable Preview" + # scale filtering ScaleFiltering="Scale Filtering" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Area" # deinterlacing Deinterlacing="Deinterlacing" @@ -375,7 +423,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselect: %2)" Basic.PropertiesWindow.SelectColor="Select color" Basic.PropertiesWindow.SelectFont="Select font" Basic.PropertiesWindow.ConfirmTitle="Settings Changed" -Basic.PropertiesWindow.Confirm="There are unsaved changes. Do you want to keep them?" +Basic.PropertiesWindow.Confirm="There are unsaved changes. Do you want to keep them?" Basic.PropertiesWindow.NoProperties="No properties available" Basic.PropertiesWindow.AddFiles="Add Files" Basic.PropertiesWindow.AddDir="Add Directory" @@ -499,6 +547,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="Flip &Vertical" Basic.MainMenu.Edit.Transform.FitToScreen="&Fit to screen" Basic.MainMenu.Edit.Transform.StretchToScreen="&Stretch to screen" Basic.MainMenu.Edit.Transform.CenterToScreen="&Center to screen" +Basic.MainMenu.Edit.Transform.VerticalCenter="Center Vertically" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Center Horizontally" Basic.MainMenu.Edit.Order="&Order" Basic.MainMenu.Edit.Order.MoveUp="Move &Up" Basic.MainMenu.Edit.Order.MoveDown="Move &Down" @@ -544,11 +594,12 @@ Basic.MainMenu.Help.CheckForUpdates="Check For Updates" Basic.MainMenu.Help.CrashLogs="Crash &Reports" Basic.MainMenu.Help.CrashLogs.ShowLogs="&Show Crash Reports" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Upload &Last Crash Report" +Basic.MainMenu.Help.About="&About" # basic mode settings dialog Basic.Settings.ProgramRestart="The program must be restarted for these settings to take effect." Basic.Settings.ConfirmTitle="Confirm Changes" -Basic.Settings.Confirm="You have unsaved changes. Save changes?" +Basic.Settings.Confirm="You have unsaved changes. Save changes?" # basic mode 'general' settings Basic.Settings.General="General" @@ -574,8 +625,13 @@ Basic.Settings.General.SysTray="System Tray" Basic.Settings.General.SysTrayWhenStarted="Minimize to system tray when started" Basic.Settings.General.SystemTrayHideMinimize="Always minimize to system tray instead of task bar" Basic.Settings.General.SaveProjectors="Save projectors on exit" +Basic.Settings.General.Preview="Preview" +Basic.Settings.General.OverflowHidden="Hide overflow" +Basic.Settings.General.OverflowAlwaysVisible="Overflow always visible" +Basic.Settings.General.OverflowSelectionHidden="Show overflow even when source is invisible" Basic.Settings.General.SwitchOnDoubleClick="Transition to scene when double-clicked" Basic.Settings.General.StudioPortraitLayout="Enable portrait/vertical layout" +Basic.Settings.General.TogglePreviewProgramLabels="Show preview/program labels" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Click to switch between scenes" Basic.Settings.General.Multiview.DrawSourceNames="Show scene names" @@ -590,6 +646,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, Top # basic mode 'stream' settings Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream Type" +Basic.Settings.Stream.Custom.UseAuthentication="Use authentication" +Basic.Settings.Stream.Custom.Username="Username" +Basic.Settings.Stream.Custom.Password="Password" +Basic.Settings.Stream.BandwidthTestMode="Enable Bandwidth Test Mode" # basic mode 'output' settings Basic.Settings.Output="Output" @@ -606,7 +666,7 @@ Basic.Settings.Output.UseReplayBuffer="Enable Replay Buffer" Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximum Replay Time (Seconds)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximum Memory (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Estimated memory usage: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Cannot estimate memory usage. Please set maximum memory limit." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Cannot estimate memory usage. Please set maximum memory limit." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Note: Make sure to set a hotkey for the replay buffer in the hotkeys section)" Basic.Settings.Output.ReplayBuffer.Prefix="Replay Buffer Filename Prefix" Basic.Settings.Output.ReplayBuffer.Suffix="Suffix" @@ -616,10 +676,10 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Same as stream" Basic.Settings.Output.Simple.RecordingQuality.Small="High Quality, Medium File Size" Basic.Settings.Output.Simple.RecordingQuality.HQ="Indistinguishable Quality, Large File Size" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless Quality, Tremendously Large File Size" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Warning: The streaming video bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Warning: The streaming audio bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Warning: The streaming video bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Warning: The streaming audio bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"." Basic.Settings.Output.Simple.Warn.Encoder="Warning: Recording with a software encoder at a different quality than the stream will require extra CPU usage if you stream and record at the same time." -Basic.Settings.Output.Simple.Warn.Lossless="Warning: Lossless quality generates tremendously large file sizes! Lossless quality can use upward of 7 gigabytes of disk space per minute at high resolutions and framerates. Lossless is not recommended for long recordings unless you have a very large amount of disk space available." +Basic.Settings.Output.Simple.Warn.Lossless="Warning: Lossless quality generates tremendously large file sizes! Lossless quality can use upward of 7 gigabytes of disk space per minute at high resolutions and framerates. Lossless is not recommended for long recordings unless you have a very large amount of disk space available." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Are you sure you want to use lossless quality?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless quality warning!" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" @@ -633,7 +693,7 @@ Basic.Settings.Output.Reconnect="Automatically Reconnect" Basic.Settings.Output.RetryDelay="Retry Delay (seconds)" Basic.Settings.Output.MaxRetries="Maximum Retries" Basic.Settings.Output.Advanced="Enable Advanced Encoder Settings" -Basic.Settings.Output.EncoderPreset="Encoder Preset (higher = less CPU)" +Basic.Settings.Output.EncoderPreset="Encoder Preset" Basic.Settings.Output.CustomEncoderSettings="Custom Encoder Settings" Basic.Settings.Output.CustomMuxerSettings="Custom Muxer Settings" Basic.Settings.Output.NoSpaceFileName="Generate File Name without Space" @@ -684,7 +744,7 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Show all codecs (even if pot FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" # basic mode 'output' settings - advanced section - recording subsection - TT -FilenameFormatting.TT="%CCYY Year, four digits\n%YY Year, last two digits (00-99)\n%MM Month as a decimal number (01-12)\n%DD Day of the month, zero-padded (01-31)\n%hh Hour in 24h format (00-23)\n%mm Minute (00-59)\n%ss Second (00-61)\n%% A % sign\n%a Abbreviated weekday name\n%A Full weekday name\n%b Abbreviated month name\n%B Full month name\n%d Day of the month, zero-padded (01-31)\n%H Hour in 24h format (00-23)\n%I Hour in 12h format (01-12)\n%m Month as a decimal number (01-12)\n%M Minute (00-59)\n%p AM or PM designation\n%S Second (00-61)\n%y Year, last two digits (00-99)\n%Y Year\n%z ISO 8601 offset from UTC or timezone\n name or abbreviation\n%Z Timezone name or abbreviation\n" +FilenameFormatting.TT="%CCYY Year, four digits\n%YY Year, last two digits (00-99)\n%MM Month as a decimal number (01-12)\n%DD Day of the month, zero-padded (01-31)\n%hh Hour in 24h format (00-23)\n%mm Minute (00-59)\n%ss Second (00-61)\n%% A % sign\n%a Abbreviated weekday name\n%A Full weekday name\n%b Abbreviated month name\n%B Full month name\n%d Day of the month, zero-padded (01-31)\n%H Hour in 24h format (00-23)\n%I Hour in 12h format (01-12)\n%m Month as a decimal number (01-12)\n%M Minute (00-59)\n%p AM or PM designation\n%S Second (00-61)\n%y Year, last two digits (00-99)\n%Y Year\n%z ISO 8601 offset from UTC in timezone\n%Z Timezone name or abbreviation\n" # basic mode 'video' settings Basic.Settings.Video="Video" @@ -700,8 +760,8 @@ Basic.Settings.Video.FPSFraction="Fractional FPS Value" Basic.Settings.Video.Numerator="Numerator" Basic.Settings.Video.Denominator="Denominator" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Invalid resolution value. Must be [width]x[height] (i.e. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Video output is currently active. Please turn off any outputs to change video settings." +Basic.Settings.Video.InvalidResolution="Invalid resolution value. Must be [width]x[height] (i.e. 1920x1080)" +Basic.Settings.Video.CurrentlyActive="Video output is currently active. Please turn off any outputs to change video settings." Basic.Settings.Video.DisableAero="Disable Aero" # scale filters @@ -713,7 +773,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 32 sam Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Sample Rate" Basic.Settings.Audio.Channels="Channels" -Basic.Settings.Audio.MeterDecayRate="Audio Meter Decay Rate" +Basic.Settings.Audio.Meters="Meters" +Basic.Settings.Audio.MeterDecayRate="Decay Rate" Basic.Settings.Audio.MeterDecayRate.Fast="Fast" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Slow (Type II PPM)" @@ -721,19 +782,22 @@ Basic.Settings.Audio.PeakMeterType="Peak Meter Type" Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample Peak" Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (Higher CPU usage)" Basic.Settings.Audio.MultiChannelWarning.Enabled="WARNING: Surround sound audio is enabled." -Basic.Settings.Audio.MultichannelWarning="If streaming, check to see if your streaming service supports both surround sound ingest and surround sound playback. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast are examples where surround sound is fully supported. Although Facebook Live and YouTube Live both accept surround ingest, Facebook Live downmixes to stereo, and YouTube Live plays only two channels.\n\nOBS audio filters are compatible with surround sound, though VST plugin support isn't guaranteed." +Basic.Settings.Audio.MultichannelWarning="If streaming, check to see if your streaming service supports both surround sound ingest and surround sound playback. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast are examples where surround sound is fully supported. Although Facebook Live and YouTube Live both accept surround ingest, Facebook Live downmixes to stereo, and YouTube Live plays only two channels.\n\nOBS audio filters are compatible with surround sound, though VST plugin support isn't guaranteed." Basic.Settings.Audio.MultichannelWarning.Title="Enable surround sound audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Are you sure you want to enable surround sound audio?" -Basic.Settings.Audio.DesktopDevice="Desktop Audio Device" -Basic.Settings.Audio.DesktopDevice2="Desktop Audio Device 2" -Basic.Settings.Audio.AuxDevice="Mic/Auxiliary Audio Device" -Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary Audio Device 2" -Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary Audio Device 3" +Basic.Settings.Audio.Devices="Devices" +Basic.Settings.Audio.DesktopDevice="Desktop Audio" +Basic.Settings.Audio.DesktopDevice2="Desktop Audio 2" +Basic.Settings.Audio.AuxDevice="Mic/Auxiliary Audio" +Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary Audio 2" +Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary Audio 3" +Basic.Settings.Audio.AuxDevice4="Mic/Auxiliary Audio 4" Basic.Settings.Audio.EnablePushToMute="Enable Push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Push-to-mute delay" Basic.Settings.Audio.EnablePushToTalk="Enable Push-to-talk" Basic.Settings.Audio.PushToTalkDelay="Push-to-talk delay" Basic.Settings.Audio.UnknownAudioDevice="[Device not connected or not available]" +Basic.Settings.Audio.Disabled="Disabled" # basic mode 'advanced' settings Basic.Settings.Advanced="Advanced" @@ -743,14 +807,14 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Above Normal" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Below Normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Idle" -Basic.Settings.Advanced.FormatWarning="Warning: Color formats other than NV12 are primarily intended for recording, and are not recommended when streaming. Streaming may incur increased CPU usage due to color format conversion." +Basic.Settings.Advanced.FormatWarning="Warning: Color formats other than NV12 are primarily intended for recording, and are not recommended when streaming. Streaming may incur increased CPU usage due to color format conversion." Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffering Time" Basic.Settings.Advanced.Video.ColorFormat="Color Format" -Basic.Settings.Advanced.Video.ColorSpace="YUV Color Space" -Basic.Settings.Advanced.Video.ColorRange="YUV Color Range" +Basic.Settings.Advanced.Video.ColorSpace="Color Space" +Basic.Settings.Advanced.Video.ColorRange="Color Range" Basic.Settings.Advanced.Video.ColorRange.Partial="Partial" Basic.Settings.Advanced.Video.ColorRange.Full="Full" -Basic.Settings.Advanced.Audio.MonitoringDevice="Audio Monitoring Device" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring Device" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Disable Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Stream Delay" @@ -762,13 +826,15 @@ Basic.Settings.Advanced.Network.BindToIP="Bind to IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Enable new networking code" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Low latency mode" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Disable hotkeys when main window is in focus" +Basic.Settings.Advanced.AutoRemux="Automatically remux to mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(record as mkv)" # advanced audio properties Basic.AdvAudio="Advanced Audio Properties" Basic.AdvAudio.Name="Name" -Basic.AdvAudio.Volume="Volume (%)" +Basic.AdvAudio.Volume="Volume" Basic.AdvAudio.Mono="Downmix to Mono" -Basic.AdvAudio.Panning="Panning" +Basic.AdvAudio.Balance="Balance" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.Monitoring="Audio Monitoring" Basic.AdvAudio.Monitoring.None="Monitor Off" @@ -779,6 +845,7 @@ Basic.AdvAudio.AudioTracks="Tracks" # basic mode 'hotkeys' settings Basic.Settings.Hotkeys="Hotkeys" Basic.Settings.Hotkeys.Pair="Key combinations shared with '%1' act as toggles" +Basic.Settings.Hotkeys.Filter="Filter" # basic mode hotkeys Basic.Hotkeys.SelectScene="Switch to scene" @@ -788,7 +855,7 @@ Basic.SystemTray.Show="Show" Basic.SystemTray.Hide="Hide" # system tray messages -Basic.SystemTray.Message.Reconnecting="Disconnected. Reconnecting..." +Basic.SystemTray.Message.Reconnecting="Disconnected. Reconnecting..." # hotkeys that may lack translation on certain operating systems Hotkeys.Insert="Insert" @@ -826,6 +893,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Mouse %1" +Hotkeys.Escape="Esc" # audio hotkeys Mute="Mute" @@ -840,7 +908,7 @@ SceneItemHide="Hide '%1'" # Output warnings OutputWarnings.NoTracksSelected="You must select at least one track" OutputWarnings.MultiTrackRecording="Warning: Certain formats (such as FLV) do not support multiple tracks per recording" -OutputWarnings.MP4Recording="Warning: Recordings saved to MP4 will be unrecoverable if the file cannot be finalized (e.g. as a result of BSODs, power losses, etc.). If you want to record multiple audio tracks consider using MKV and remux the recording to mp4 after it is finished (File->Remux Recordings)" +OutputWarnings.MP4Recording="Warning: Recordings saved to MP4/MOV will be unrecoverable if the file cannot be finalized (e.g. as a result of BSODs, power losses, etc.). If you want to record multiple audio tracks consider using MKV and remux the recording to MP4/MOV after it is finished (File → Remux Recordings)" # deleting final scene FinalScene.Title="Delete Scene" @@ -850,6 +918,7 @@ FinalScene.Text="There needs to be at least one scene." NoSources.Title="No Sources" NoSources.Text="It looks like you haven't added any video sources yet, so you will only be outputting a blank screen. Are you sure you want to do this?" NoSources.Text.AddSource="You can add sources by clicking the + icon under the Sources box in the main window at any time." +NoSources.Label="You don't have any sources.\nClick the + button below,\nor right click here to add one." # Scene item color selection ChangeBG="Set Color" @@ -857,3 +926,19 @@ CustomColor="Custom Color" # Global settings for the browser source BrowserSource.EnableHardwareAcceleration="Enable Browser Source Hardware Acceleration" + +# about dialog +About="About" +About.Info="OBS Studio is a free and open source video recording and live streaming software." +About.Donate="Make a Contribution" +About.GetInvolved="Get Involved" +About.Authors="Authors" +About.License="License" +About.Contribute="Support the OBS Project" + +# Dynamic output size +ResizeOutputSizeOfSource="Resize output (source size)" +ResizeOutputSizeOfSource.Text="The base and output resolutions will be resized to the size of the current source." +ResizeOutputSizeOfSource.Continue="Do you want to continue?" + +PreviewTransition="Preview Transition" diff --git a/UI/data/locale/es-ES.ini b/UI/data/locale/es-ES.ini index df65678..9640af6 100644 --- a/UI/data/locale/es-ES.ini +++ b/UI/data/locale/es-ES.ini @@ -7,19 +7,19 @@ Apply="Aplicar" Cancel="Cancelar" Close="Cerrar" Save="Guardar" -Discard="Guardar" +Discard="Descartar" Disable="Deshabilitar" Yes="Sí" No="No" Add="Agregar" -Remove="Quitar" +Remove="Eliminar" Rename="Renombrar" Interact="Interactuar" Filters="Filtros" Properties="Propiedades" -MoveUp="Mover arriba" -MoveDown="Mover abajo" -Settings="Configuración" +MoveUp="Mover Arriba" +MoveDown="Mover Abajo" +Settings="Ajustes" Display="Pantalla" Name="Nombre" Exit="Salir" @@ -30,13 +30,13 @@ Stereo="Estéreo" DroppedFrames="Fotogramas Perdidos %1 (%2%)" StudioProgramProjector="Proyector de pantalla completa (Programa)" PreviewProjector="Proyector de pantalla completa (Previsualización)" -SceneProjector="Proyector de pantalla completa (escena)" -SourceProjector="Proyector de pantalla completa (fuente)" +SceneProjector="Proyector de pantalla completa (Escena)" +SourceProjector="Proyector de pantalla completa (Fuente)" StudioProgramWindow="Proyector con ventana (Programa)" -PreviewWindow="Proyector con ventana (Pre-visualización)" +PreviewWindow="Proyector con ventana (Previsualización)" SceneWindow="Proyector con ventana (Escena)" SourceWindow="Proyector con ventana (Fuente)" -MultiviewProjector="Vista múltiple (pantalla completa)" +MultiviewProjector="Vista múltiple (Pantalla completa)" MultiviewWindowed="Vista múltiple (Ventana)" Clear="Borrar" Revert="Revertir" @@ -46,10 +46,10 @@ UnhideAll="Mostrar todos" Untitled="Sin Título" New="Nuevo" Duplicate="Duplicar" -Enable="Habilitado" +Enable="Habilitar" DisableOSXVSync="Desahabilitar V-Sync en OSX" ResetOSXVSyncOnExit="Resetear V-Sync de OSX a la salida" -HighResourceUsage="¡Sobrecarga al codificar! Considera bajar los ajustes de vídeo o usa una configuración del codificador mas rapida." +HighResourceUsage="¡Sobrecarga al codificar! Considera bajar los ajustes de vídeo o usa una configuración del codificador más rápida." Transition="Transición" QuickTransitions="Transiciones rápidas" Left="Izquierda" @@ -66,28 +66,54 @@ Import="Importar" Export="Exportar" Copy="Copiar" Paste="Pegar" -PasteReference="Pegar (referencia)" -PasteDuplicate="Pegar (duplicado)" +PasteReference="Pegar (Referencia)" +PasteDuplicate="Pegar (Duplicado)" RemuxRecordings="Grabaciones Convertidas" Next="Siguiente" Back="Atrás" Defaults="Predeterminados" -HideMixer="Ocultar en el mezclador" +HideMixer="Ocultar en el Mezclador" TransitionOverride="Anulación de la transición" None="Ninguno" -StudioMode.Preview="Vista previa" +StudioMode.Preview="Vista Previa" StudioMode.Program="Programa" ShowInMultiview="Mostrar en vista múltiple" VerticalLayout="Interfaz Vertical" Group="Grupo" +DoNotShowAgain="No mostrar de nuevo" +Default="(Por defecto)" +Calculating="Calculando..." AlreadyRunning.Title="OBS ya se está ejecutando" -AlreadyRunning.Text="¡OBS ya se está ejecutando! A no ser que quieras hacer esto, por favor, cierra todas las ventanas de OBS antes de intentar iniciar una nueva. Si tienes configurado OBS para que se minimize a la barra de tareas, prueba a ver si sigue ejecutándose ahí." +AlreadyRunning.Text="¡OBS ya se está ejecutando! A no ser que quieras hacer esto, por favor, cierra todas las ventanas de OBS antes de intentar iniciar una nueva. Si tienes configurado OBS para que se minimice a la barra de tareas, comprueba si sigue ejecutándose ahí." AlreadyRunning.LaunchAnyway="Lanzar de todas maneras" +DockCloseWarning.Title="Cerrando ventana acoplable" +DockCloseWarning.Text="Acabas de cerrar una ventana acoplable. Si quieres mostrarla de nuevo, usa Vista → Acoplar en la barra de menús." + +Auth.Authing.Title="Autentificando..." +Auth.Authing.Text="Autentificando con %1, por favor espera..." +Auth.AuthFailure.Title="Fallo de autenticación" +Auth.AuthFailure.Text="Error al autentificar con %1:\n\n%2: %3" +Auth.InvalidScope.Title="Se requiere autentificación" +Auth.InvalidScope.Text="Los requisitos de autenticación para %1 han cambiado. Algunas características pueden no estar disponibles." +Auth.LoadingChannel.Title="Cargando información del canal..." +Auth.LoadingChannel.Text="Cargando información del canal para %1, por favor espere..." +Auth.ChannelFailure.Title="Error al cargar canal" +Auth.ChannelFailure.Text="Error al cargar la información del canal para %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Información de Stream" +TwitchAuth.Stats="Estadísticas de Twitch" +TwitchAuth.Feed="Fuente de actividades de Twitch" +TwitchAuth.TwoFactorFail.Title="No se pudo obtener la clave de transmisión" +TwitchAuth.TwoFactorFail.Text="OBS no pudo conectarse a su cuenta de Twitch. Por favor, asegúrese de que la autenticación en dos pasos está configurada en su configuración de seguridad Configuración de seguridad de Twitch ya que esto es necesario para transmitir." + Copy.Filters="Copiar filtros" Paste.Filters="Pegar filtros" +BrowserPanelInit.Title="Iniciando navegador..." +BrowserPanelInit.Text="Iniciando navegador, por favor espere..." + BandwidthTest.Region="Región" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Otros" Basic.FirstStartup.RunWizard="¿Deseas ejecutar el asistente de configuración automática? También puedes configurar tus ajustes manualmente al hacer clic en el botón \"Configuración\" de la ventana principal." -Basic.FirstStartup.RunWizard.BetaWarning="(Nota: El asistente de configuración automática está en beta)" -Basic.FirstStartup.RunWizard.NoClicked="Si cambias tu mente, puede ejecutar al asistente de configuración automática cualquier momento desde el menú \"Herramientas\"." +Basic.FirstStartup.RunWizard.NoClicked="Si cambia de opinión, puede ejecutar al asistente de configuración automática en cualquier momento desde el menú \"Herramientas\"." Basic.AutoConfig="Asistente de configuración automática" -Basic.AutoConfig.Beta="Asistente de configuración automática (Beta)" Basic.AutoConfig.ApplySettings="Aplicar configuración" Basic.AutoConfig.StartPage="Información sobre el uso" Basic.AutoConfig.StartPage.SubTitle="Especifique para que quiere usar el programa" @@ -115,18 +139,24 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, pero usar alta resolució Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: La resolución del lienzo (base) no es necesariamente la misma que la resolución de la transmisión o grabación. La resolución actual puede ser reducida del lienzo para reducir el uso de los recursos o del bitrate." Basic.AutoConfig.StreamPage="Información de servicio de Stream" Basic.AutoConfig.StreamPage.SubTitle="Por favor, introduce información sobre tu servicio de stream" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar cuenta (opcional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar cuenta" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="¿Desconectar cuenta?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Este cambio se aplicará inmediatamente. ¿Está seguro de que desea desconectar su cuenta?" +Basic.AutoConfig.StreamPage.UseStreamKey="Usar clave de emisión" Basic.AutoConfig.StreamPage.Service="Servicio" Basic.AutoConfig.StreamPage.Service.ShowAll="Mostrar todos..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizado..." Basic.AutoConfig.StreamPage.Server="Servidor" Basic.AutoConfig.StreamPage.StreamKey="Clave de retransmisión" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Enlace)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimar bitrate con una prueba de ancho de banda (puede tardar unos minutos)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferir codificación por hardware" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Codificación por hardware elimina la mayoría del uso de la CPU, pero puede requerir mas bitrate para obtener el mismo nivel de calidad." +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="La codificación por hardware elimina la mayoría del uso de la CPU, pero puede requerir más bitrate para obtener el mismo nivel de calidad." Basic.AutoConfig.StreamPage.StreamWarning.Title="Advertencia de transmisión" -Basic.AutoConfig.StreamPage.StreamWarning.Text="La prueba de ancho de banda esta a punto de transmitir datos de video aleatorios sin audio a tu canal. Si puedes, es recomendable desactivar temporalmente el que se guarden los videos de las transmisiones y hacer la transmisión privada después de que la prueba haya finalizado. ¿Desea continuar?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="La prueba de ancho de banda esta a punto de transmitir datos de vídeo aleatorios sin audio a tu canal. Si puedes, es recomendable desactivar temporalmente el que se guarden los vídeos de las transmisiones y hacer la transmisión privada después de que la prueba haya finalizado. ¿Desea continuar?" Basic.AutoConfig.TestPage="Resultado final" -Basic.AutoConfig.TestPage.SubTitle.Testing="El programa ahora esta ejecutando un conjunto de pruebas para estimar los ajustes óptimos" +Basic.AutoConfig.TestPage.SubTitle.Testing="El programa ahora está ejecutando un conjunto de pruebas para estimar los ajustes óptimos" Basic.AutoConfig.TestPage.SubTitle.Complete="Prueba completada" Basic.AutoConfig.TestPage.TestingBandwidth="Ejecutando prueba de ancho de banda, esto puede tardar unos minutos..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Conectando a: %1..." @@ -139,15 +169,15 @@ Basic.AutoConfig.TestPage.TestingRes.Fail="No se pudo iniciar el codificador" Basic.AutoConfig.TestPage.TestingRes.Resolution="Probando %1x%2 %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codificador de transmisión" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codificador de grabación" -Basic.AutoConfig.TestPage.Result.Header="El programa ha determinado que estos ajustes estimados son los mas óptimos para ti:" +Basic.AutoConfig.TestPage.Result.Header="El programa ha determinado que estos ajustes estimados son los ideales para ti:" Basic.AutoConfig.TestPage.Result.Footer="Para utilizar estos ajustes, haga clic en \"Aplicar Configuración\". Para volver a configurar el asistente, haga clic en Atrás. Para configurar los ajustes por ti mismo, haga clic en Cancelar y abra los ajustes." Basic.Stats="Estadísticas" Basic.Stats.CPUUsage="Uso de CPU" -Basic.Stats.HDDSpaceAvailable="Espacio disponible en disco" +Basic.Stats.HDDSpaceAvailable="Espacio en disco disponible" Basic.Stats.MemoryUsage="Uso de memoria" Basic.Stats.AverageTimeToRender="Tiempo de media para procesar un fotograma" -Basic.Stats.SkippedFrames="Fotogramas saltados por retraso de procesamiento" +Basic.Stats.SkippedFrames="Fotogramas omitidos por retraso en la codificación" Basic.Stats.MissedFrames="Fotogramas perdidos por retraso de procesamiento" Basic.Stats.Output.Stream="Transmisión" Basic.Stats.Output.Recording="Grabación" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Inactivo" Basic.Stats.DroppedFrames="Fotogramas Perdidos (Red)" Basic.Stats.MegabytesSent="Salida de datos total" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Disco lleno en (aprox.)" + +ResetUIWarning.Title="¿Está seguro de que desea restablecer la interfáz?" +ResetUIWarning.Text="Restablecer la interfaz ocultará los docks adicionales. Necesitarás eliminar estos docks del menú de vista si quieres que sean visibles.\n\n¿Estás seguro de que quieres restablecer la interfaz?" Updater.Title="Nueva actualización disponible" Updater.Text="Hay una nueva versión disponible:" @@ -171,14 +205,14 @@ Updater.NoUpdatesAvailable.Title="No hay actualizaciones disponibles" Updater.NoUpdatesAvailable.Text="No hay actualizaciones disponibles actualmente" Updater.FailedToLaunch="No se pudo iniciar el actualizador" Updater.GameCaptureActive.Title="Captura de juego activa" -Updater.GameCaptureActive.Text="La libreria de captura de juegos esta actualmente en uso. Por favor, cierra cualquier juego/programa que este siendo capturado (o reinicia windows) e intentalo de nuevo." +Updater.GameCaptureActive.Text="La biblioteca de captura de juegos está actualmente en uso. Cierre los juegos o programas que se capturan (o reinicie Windows) e inténtelo de nuevo." -QuickTransitions.SwapScenes="Cambiar vista previa y salida escenas después de la transición" -QuickTransitions.SwapScenesTT="Cambia la vista previa y salida escenas después de la transición (si todavía existe la escena original de la salida). \nEsto no deshará cualquier cambio que pueda haber hecho a la escena original de la salida." +QuickTransitions.SwapScenes="Cambiar las escenas Vista previa/Programa después de la transición" +QuickTransitions.SwapScenesTT="Intercambia las escenas vista previa y programa después de la transición (si todavía existe la escena original de programa).\nEsto no deshará cualquier cambio que pueda haber hecho a la escena original de programa." QuickTransitions.DuplicateScene="Duplicar escena" -QuickTransitions.DuplicateSceneTT="Al editar la misma escena, permite la edición transformar/visibilidad de fuentes sin modificar las salida. \nPara editar propiedades de fuentes sin modificar la salida, permite 'Duplicar Fuentes'. \n Cambiando este valor restablecerá la escena actual de salida (si todavía existe)." +QuickTransitions.DuplicateSceneTT="Al editar la misma escena, permite editar la transformación/visibilidad de las fuentes sin modificar la salida.\nPara editar propiedades de fuentes sin modificar la salida, habilita 'Duplicar fuentes'.\nCambiando este valor restablecerá la escena actual de salida (si todavía existe)." QuickTransitions.EditProperties="Duplicar fuentes" -QuickTransitions.EditPropertiesTT="Al editar la misma escena, permite editar propiedades de fuentes sin modificar la salida. \n Esto sólo se puede utilizar si está activado 'Escena de duplicar'. \nCiertas fuentes (tales como fuentes de captura o los medios de comunicación) no son compatibles con esto y no se pueden editar por separado. \nCambiando este valor restablecerá la escena actual de salida (si todavía existe).\n\nAdvertencia: porque se duplicarán las fuentes, esto puede requerir extra sistema o recursos de vídeo." +QuickTransitions.EditPropertiesTT="Al editar la misma escena, permite editar propiedades de fuentes sin modificar la salida.\nEsto sólo se puede utilizar si está activado 'Duplicar escena'.\nCiertas fuentes (de captura o multimedia) no son compatibles y no se pueden editar por separado.\nCambiando este valor restablecerá la escena actual de salida (si todavía existe).\n\nAdvertencia: Debido a que las fuentes se duplicarán, esto puede requerir recursos adicionales del sistema o de vídeo." QuickTransitions.HotkeyName="Transición Rápida: %1" Basic.AddTransition="Añadir transición configurable" @@ -198,7 +232,7 @@ NameExists.Title="Ese nombre ya existe" NameExists.Text="Este nombre ya está en uso." NoNameEntered.Title="Por favor, introduzca un nombre válido" -NoNameEntered.Text="No puede utilizar nombres de vacíos." +NoNameEntered.Text="No puede dejar el nombre vacío." ConfirmStart.Title="¿Iniciar Transmisión?" ConfirmStart.Text="¿Está seguro que desea iniciar la transmisión?" @@ -206,6 +240,9 @@ ConfirmStart.Text="¿Está seguro que desea iniciar la transmisión?" ConfirmStop.Title="¿Parar Transmisión?" ConfirmStop.Text="¿Está seguro que desea parar la transmisión?" +ConfirmBWTest.Title="¿Iniciar prueba de ancho de banda?" +ConfirmBWTest.Text="Tienes OBS configurado en modo de prueba de ancho de banda. Este modo permite pruebas de red sin que tu canal esté en vivo. Una vez que hayas terminado de probar, necesitarás desactivarlo para que los espectadores puedan ver tu stream.\n\n¿Quieres continuar?" + ConfirmExit.Title="¿Cerrar OBS?" ConfirmExit.Text="OBS esta siendo usado. Todas las transmisiones/grabaciones serán paradas. ¿Está seguro que quiere salir?" @@ -218,51 +255,54 @@ Output.StartRecordingFailed="No se pudo iniciar grabación" Output.StartReplayFailed="No se pudo iniciar el buffer de replay" Output.StartFailedGeneric="No se pudo iniciar la salida. Por favor compruebe los logs para mas detalles. \n\nNota: Si estas usando los codificadores de NVENC o AMD, asegúrate que tus drivers de vídeo están actualizados." + Output.ConnectFail.Title="Error al conectarse" -Output.ConnectFail.BadPath="URL ruta de acceso o conexión no válida. Por favor, compruebe su configuración para confirmar que está correcta." +Output.ConnectFail.BadPath="URL ruta de acceso o conexión no válida. Por favor, compruebe su configuración para confirmar que está correcta." Output.ConnectFail.ConnectFailed="No se pudo conectar al servidor" -Output.ConnectFail.InvalidStream="No puede acceder a la llave del canal especificado o de la trasmisión, por favor comprobar dos veces su llave de trasmisión. Si es correcto, puede haber un problema conectándose al servidor." -Output.ConnectFail.Error="Se ha producido un error inesperado al intentar conectar con el servidor. Más información en el archivo de registro." +Output.ConnectFail.InvalidStream="No se pudo acceder al canal especificado o clave de transmisión, por favor compruebe su clave de transmisión. Si es correcta, puede haber un problema al conectar al servidor." +Output.ConnectFail.Error="Se ha producido un error inesperado al intentar conectar con el servidor. Más información en el archivo de registro." Output.ConnectFail.Disconnected="Desconectado del servidor." +Output.StreamEncodeError.Title="Error de codificación" +Output.StreamEncodeError.Msg="Un error de codificación se produjo durante el Streaming." + Output.RecordFail.Title="No se pudo iniciar grabación" -Output.RecordFail.Unsupported="El formato de salida es o no es compatible o no soporta más de una pista de audio. Por favor, compruebe su configuración e intente otra ves." +Output.RecordFail.Unsupported="El formato de salida no está soportado o no soporta más de una pista de audio. Por favor, comprueba tus ajustes e inténtalo de nuevo." Output.RecordNoSpace.Title="No hay suficiente espacio en disco" Output.RecordNoSpace.Msg="No hay suficiente espacio en disco para continuar grabando." Output.RecordError.Title="Error en la grabación" Output.RecordError.Msg="Se ha producido un error no especificado durante la grabación." +Output.RecordError.EncodeErrorMsg="Un error de codificación se produjo mientras se grababa." Output.ReplayBuffer.NoHotkey.Title="¡Sin tecla de acceso rápido!" Output.ReplayBuffer.NoHotkey.Msg="Sin tecla de acceso rápido establecida para el búfer de reproducción. Configure la tecla de acceso \"Guardar\" para guardar las grabaciones de reproducción." Output.BadPath.Title="Ruta de archivo incorrecta" -Output.BadPath.Text="La ruta de salida de archivos establecida no es válida. Por favor, compruebe su configuración para confirmar que se ha establecido una ruta de archivos válida." +Output.BadPath.Text="La ruta de salida de archivos establecida no es válida. Por favor, compruebe su configuración para confirmar que se ha establecido una ruta de archivos válida." LogReturnDialog="Carga de registro exitosa" LogReturnDialog.CopyURL="Copiar dirección URL" LogReturnDialog.ErrorUploadingLog="Error al cargar el archivo de registro" -LicenseAgreement="Acuerdo de Licencia" -LicenseAgreement.PleaseReview="Por favor revise los términos de licencia antes de utilizar OBS. Al usar este programa, usted reconoce que ha leído y acepta los términos de la Licencia Pública General de GNU v2.0. Por favor, desplácese hacia abajo para ver el resto del acuerdo." -LicenseAgreement.ClickIAgreeToContinue="Si usted acepta los términos del acuerdo, haga clic en aceptar para continuar. Debe aceptar el acuerdo para utilizar OBS." -LicenseAgreement.IAgree="Estoy conforme" -LicenseAgreement.Exit="Salir" - Remux.SourceFile="Grabación OBS" Remux.TargetFile="Archivo de destino" Remux.Remux="Convertir" +Remux.Stop="Detener conversión" +Remux.ClearFinished="Borrar los elementos finalizados" +Remux.ClearAll="Borrar todos los elementos" Remux.OBSRecording="Grabación OBS" Remux.FinishedTitle="Conversión finalizada" Remux.Finished="Grabando conversión" Remux.FinishedError="Grabación convertida, pero el archivo podría estar incompleto" -Remux.SelectRecording="Seleccione grabación OBS…" -Remux.SelectTarget="Seleccione el archivo de destino…" -Remux.FileExistsTitle="Archivo de destino existe" -Remux.FileExists="Archivo de destino existe, ¿desea reemplazarlo?" +Remux.SelectRecording="Seleccione grabación de OBS..." +Remux.SelectTarget="Seleccione archivo de destino..." +Remux.FileExistsTitle="Los archivos de destino ya existen" +Remux.FileExists="Los siguientes archivos de destino ya existen. ¿Quieres reemplazarlos?" Remux.ExitUnfinishedTitle="Conversión en curso" -Remux.ExitUnfinished="La conversión no ha acabado, para ahora podría hacer que el archivo final quede inusable.\n¿Estás seguro de querer parar la conversión?" +Remux.ExitUnfinished="La conversión no ha finalizado, detenerla ahora puede inutilizar el archivo de destino.\n¿Estás seguro de querer parar la conversión?" +Remux.HelpText="Suelta los archivos en esta ventana para convertirlos, o selecciona una celda vacía \"OBS Recording\" para buscar un archivo." UpdateAvailable="Nueva actualización disponible" -UpdateAvailable.Text="Versión %1.%2.%3 disponible. Haga clic aquí para descargarla" +UpdateAvailable.Text="Versión %1.%2.%3 disponible. Haga clic aquí para descargarla" Basic.DesktopDevice1="Audio del escritorio" Basic.DesktopDevice2="Audio del escritorio 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Captura de pantalla" Basic.Main.PreviewConextMenu.Enable="Habilitar previsualización" +Basic.Main.Preview.Disable="Deshabilitar previsualización" + ScaleFiltering="Escala de filtrado" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilineal" ScaleFiltering.Bicubic="Bicúbico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" Deinterlacing="Desentrelazado" Deinterlacing.Discard="Descartar" @@ -304,8 +347,8 @@ Basic.Main.AddSceneDlg.Text="Por favor, introduzca el nombre de la escena" Basic.Main.DefaultSceneName.Text="Escena %1" -Basic.Main.AddSceneCollection.Title="Agregar coleccion de escenas" -Basic.Main.AddSceneCollection.Text="Por favor Escriba el nombre de la colección de escena" +Basic.Main.AddSceneCollection.Title="Agregar colección de escenas" +Basic.Main.AddSceneCollection.Text="Por favor escriba el nombre de la colección de escenas" Basic.Main.RenameSceneCollection.Title="Cambiar el nombre de colección de escenas" @@ -321,7 +364,7 @@ Basic.Main.MixerRename.Text="Por favor, introduzca el nombre de la fuente de aud Basic.Main.PreviewDisabled="Vista previa desactivada" Basic.SourceSelect="Crear/seleccionar fuente" -Basic.SourceSelect.CreateNew="Crear un nuevo" +Basic.SourceSelect.CreateNew="Crear nuevo" Basic.SourceSelect.AddExisting="Añadir existentes" Basic.SourceSelect.AddVisible="Hacer visible la fuente" @@ -411,24 +454,24 @@ Basic.Main.Group="Grupo %1" Basic.Main.GroupItems="Agrupar los elementos seleccionados" Basic.Main.Ungroup="Desagrupar" -Basic.MainMenu.File="&Archivo" +Basic.MainMenu.File="Archivo (&F)" Basic.MainMenu.File.Export="&Exportar" Basic.MainMenu.File.Import="&Importar" Basic.MainMenu.File.ShowRecordings="Mostrar G&rabaciones" Basic.MainMenu.File.Remux="Convertir Grabaciones (&M)" -Basic.MainMenu.File.Settings="&Configuración" +Basic.MainMenu.File.Settings="Configuración (&S)" Basic.MainMenu.File.ShowSettingsFolder="Mostrar carpeta de configuración" Basic.MainMenu.File.ShowProfileFolder="Mostrar carpeta de perfiles" -Basic.MainMenu.AlwaysOnTop="&Siempre al frente" -Basic.MainMenu.File.Exit="&Salir" +Basic.MainMenu.AlwaysOnTop="Siempre &al frente" +Basic.MainMenu.File.Exit="Salir (&X)" -Basic.MainMenu.Edit="E&ditar" -Basic.MainMenu.Edit.Undo="Des&hacer" -Basic.MainMenu.Edit.Redo="Reh&acer" -Basic.MainMenu.Edit.UndoAction="&Deshacer $1" +Basic.MainMenu.Edit="&Editar" +Basic.MainMenu.Edit.Undo="Deshacer (&U)" +Basic.MainMenu.Edit.Redo="&Rehacer" +Basic.MainMenu.Edit.UndoAction="Deshacer $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Rehacer $1" -Basic.MainMenu.Edit.LockPreview="&Bloquear vista previa" -Basic.MainMenu.Edit.Scale="Vista previa y escala" +Basic.MainMenu.Edit.LockPreview="B&loquear vista previa" +Basic.MainMenu.Edit.Scale="Vi&sta previa y escala" Basic.MainMenu.Edit.Scale.Window="Ajustar a la ventana" Basic.MainMenu.Edit.Scale.Canvas="Lienzo (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Salida (%1x%2)" @@ -442,27 +485,29 @@ Basic.MainMenu.Edit.Transform.Rotate90CCW="Girar 90 grados contra el sentido de Basic.MainMenu.Edit.Transform.Rotate180="Girar 180 grados" Basic.MainMenu.Edit.Transform.FlipHorizontal="Rotar &horizontalmente" Basic.MainMenu.Edit.Transform.FlipVertical="Rotar &verticalmente" -Basic.MainMenu.Edit.Transform.FitToScreen="Ajustar a la pantalla" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Estirar a la pantalla" +Basic.MainMenu.Edit.Transform.FitToScreen="Ajustar a la pantalla (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="E&stirar a la pantalla" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrar en la pantalla" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrar Verticalmente" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrar Horizontalmente" Basic.MainMenu.Edit.Order="&Ordenar" -Basic.MainMenu.Edit.Order.MoveUp="Mover &arriba" -Basic.MainMenu.Edit.Order.MoveDown="Mover &abajo" -Basic.MainMenu.Edit.Order.MoveToTop="Mover a la &cima" -Basic.MainMenu.Edit.Order.MoveToBottom="Mover al &fondo" +Basic.MainMenu.Edit.Order.MoveUp="Mover arriba (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Mover abajo (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Mover a la cima (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Mover al fondo (&B)" Basic.MainMenu.Edit.AdvAudio="Propiedades de &Audio avanzadas" -Basic.MainMenu.View="Vista" -Basic.MainMenu.View.Toolbars="&Barra de Herramientas" +Basic.MainMenu.View="&Vista" +Basic.MainMenu.View.Toolbars="Barra de Herramien&tas" Basic.MainMenu.View.Docks="Acoplar" Basic.MainMenu.View.Docks.ResetUI="Reestablecer Interfaz de Usuario" Basic.MainMenu.View.Docks.LockUI="Bloquear Interfaz de Usuario" -Basic.MainMenu.View.Toolbars.Listboxes="&Cuadro de Lista" -Basic.MainMenu.View.SceneTransitions="&Transición de Escenas" -Basic.MainMenu.View.StatusBar="&Barra de Estado" +Basic.MainMenu.View.Toolbars.Listboxes="Cuadro de &Lista" +Basic.MainMenu.View.SceneTransitions="Transi&ción de Escenas" +Basic.MainMenu.View.StatusBar="Barra de E&stado" Basic.MainMenu.View.Fullscreen.Interface="Pantalla completa" -Basic.MainMenu.SceneCollection="&Colección de Escenas" +Basic.MainMenu.SceneCollection="Colección de E&scenas" Basic.MainMenu.Profile="&Perfil" Basic.MainMenu.Profile.Import="Importar perfil" Basic.MainMenu.Profile.Export="Exportar perfil" @@ -471,25 +516,26 @@ Basic.MainMenu.SceneCollection.Export="Exportar colección de escenas" Basic.MainMenu.Profile.Exists="El perfil ya existe" Basic.MainMenu.SceneCollection.Exists="La colección de escenas ya existe" -Basic.MainMenu.Tools="&Herramientas" +Basic.MainMenu.Tools="Herramien&tas" -Basic.MainMenu.Help="&Ayuda" +Basic.MainMenu.Help="Ayuda (&H)" Basic.MainMenu.Help.HelpPortal="Ayuda (&P)" Basic.MainMenu.Help.Website="Visitar Sitio &Web" -Basic.MainMenu.Help.Discord="Unirse a un servidor &Discord" -Basic.MainMenu.Help.Logs="&Archivos de registro" +Basic.MainMenu.Help.Discord="Unirse al servidor de &Discord" +Basic.MainMenu.Help.Logs="Archivos de registro (&L)" Basic.MainMenu.Help.Logs.ShowLogs="Mostrar archivo&s de registro" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Carga &de archivo de registro actual" -Basic.MainMenu.Help.Logs.UploadLastLog="Carga del &último archivo de registro" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Carga de archivo de registro actual" +Basic.MainMenu.Help.Logs.UploadLastLog="Carga de&l último archivo de registro" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver registro actual" Basic.MainMenu.Help.CheckForUpdates="Comprobar Actualizaciones" -Basic.MainMenu.Help.CrashLogs="Informes de &error" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Mostrar informes de error" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Subir el &último informe de error" +Basic.MainMenu.Help.CrashLogs="Informes de e&rror" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Mo&strar informes de error" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Subir e&l último informe de error" +Basic.MainMenu.Help.About="&Acerca de" Basic.Settings.ProgramRestart="El programa debe reiniciarse para que esta configuración surta efecto." Basic.Settings.ConfirmTitle="Confirmar cambios" -Basic.Settings.Confirm="Hay cambios sin guardar. ¿Guardar los cambios?" +Basic.Settings.Confirm="Hay cambios sin guardar. ¿Guardar los cambios?" Basic.Settings.General="General" Basic.Settings.General.Theme="Tema" @@ -514,28 +560,37 @@ Basic.Settings.General.SysTray="Bandeja del sistema" Basic.Settings.General.SysTrayWhenStarted="Minimizar a la bandeja del sistema al iniciar" Basic.Settings.General.SystemTrayHideMinimize="Minimizar siempre en la bandeja del sistema en lugar de la barra de tareas" Basic.Settings.General.SaveProjectors="Guardar los proyectores al salir" +Basic.Settings.General.Preview="Previsualizar" +Basic.Settings.General.OverflowHidden="Ocultar desborde" +Basic.Settings.General.OverflowAlwaysVisible="Desborde siempre visible" +Basic.Settings.General.OverflowSelectionHidden="Mostrar desborde incluso cuando la fuente sea invisible" Basic.Settings.General.SwitchOnDoubleClick="Transición a la escena cuando se hace doble clic" Basic.Settings.General.StudioPortraitLayout="Habilitar la disposición horizontal/vertical" +Basic.Settings.General.TogglePreviewProgramLabels="Mostrar las etiquetas vista previa/programa" Basic.Settings.General.Multiview="Vista Múltiple" Basic.Settings.General.Multiview.MouseSwitch="Click para cambiar entre escenas" Basic.Settings.General.Multiview.DrawSourceNames="Mostrar nombres de las escenas" Basic.Settings.General.Multiview.DrawSafeAreas="Dibujar áreas seguras (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Prueba de multivisión" +Basic.Settings.General.MultiviewLayout="Disposición de la vista múltiple" Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, superior (8 Escenas)" Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, inferior (8 Escenas)" Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, izquierda (8 Escenas)" Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, derecha (8 Escenas)" Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, superior (24 Escenas)" -Basic.Settings.Stream="Emision" -Basic.Settings.Stream.StreamType="Tipo de Emision" +Basic.Settings.Stream="Emisión" +Basic.Settings.Stream.StreamType="Tipo de Emisión" +Basic.Settings.Stream.Custom.UseAuthentication="Usar la autentificación" +Basic.Settings.Stream.Custom.Username="Nombre de usuario" +Basic.Settings.Stream.Custom.Password="Contraseña" +Basic.Settings.Stream.BandwidthTestMode="Activar modo de prueba de ancho de banda" Basic.Settings.Output="Salida" Basic.Settings.Output.Format="Formato de grabación" Basic.Settings.Output.Encoder="Codificador" Basic.Settings.Output.SelectDirectory="Seleccione Directorio de grabación" Basic.Settings.Output.SelectFile="Seleccione archivo de grabación" -Basic.Settings.Output.EnforceBitrate="Forzar limites de bitrate en el servicio de streaming" +Basic.Settings.Output.EnforceBitrate="Aplicar los límites de bitrate del servicio de streaming" Basic.Settings.Output.Mode="Modo de salida" Basic.Settings.Output.Mode.Simple="Sencillo" Basic.Settings.Output.Mode.Adv="Avanzado" @@ -550,17 +605,16 @@ Basic.Settings.Output.ReplayBuffer.Prefix="Prefijo del nombre de archivo del bú Basic.Settings.Output.ReplayBuffer.Suffix="Sufijo" Basic.Settings.Output.Simple.SavePath="Ruta de grabación" Basic.Settings.Output.Simple.RecordingQuality="Calidad de grabación" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Igual a la emision" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Igual a la emisión" Basic.Settings.Output.Simple.RecordingQuality.Small="Alta calidad, tamaño de archivo medio" Basic.Settings.Output.Simple.RecordingQuality.HQ="Tamaño de archivo grande, calidad indistinguible" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Tamaño del archivo sin pérdida de calidad, tremendamente grande" -Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTENCIA: El streaming de vídeo se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTENCIA: El streaming de audio se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." +Basic.Settings.Output.Simple.Warn.VideoBitrate="ADVERTENCIA: El streaming de vídeo se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="ADVERTENCIA: El streaming de audio se establecerá a %1, que es el límite superior para el servicio de streaming actual. Si estás seguro que quieres ir por encima de %1, active las opciones avanzadas del codificador y desactive \"Forzar limites de bitrate en el servicio de streaming\"." Basic.Settings.Output.Simple.Warn.Encoder="ADVERTENCIA: Grabar con un codificador de software de una calidad diferente a la de la transmisión requerirá un uso adicional de la CPU si transmite y graba al mismo tiempo." -Basic.Settings.Output.Simple.Warn.Lossless="ADVERTENCIA: ¡La calidad sin perdidas genera tamaños de archivo muy grandes! La calidad sin pérdidas puede utilizar más de 7 gigabytes de espacio en disco por minuto en alta resolución y con alta tasa de fotogramas. La calidad sin pérdidas no se recomienda para grabaciones largas, a menos que tenga una gran cantidad de espacio en disco disponible." +Basic.Settings.Output.Simple.Warn.Lossless="ADVERTENCIA: ¡La calidad sin perdidas genera tamaños de archivo muy grandes! La calidad sin pérdidas puede utilizar más de 7 gigabytes de espacio en disco por minuto en alta resolución y con alta tasa de fotogramas. La calidad sin pérdidas no se recomienda para grabaciones largas, a menos que tenga una gran cantidad de espacio en disco disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="¿Confirma que desea utilizar calidad sin perdidas?" Basic.Settings.Output.Simple.Warn.Lossless.Title="¡Atención de calidad sin pérdidas!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Advertencia: No se pueden usar varios codificadores QSV separados al transmitir y grabar al mismo tiempo. Si desea transmitir y grabar al mismo tiempo, por favor cambíelos, ya sea el codificador de grabación o el codificador de trasmisión." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" @@ -572,14 +626,14 @@ Basic.Settings.Output.Reconnect="Reconectar automáticamente" Basic.Settings.Output.RetryDelay="Retardo al re-intentar (segundos)" Basic.Settings.Output.MaxRetries="Reintentos máximos" Basic.Settings.Output.Advanced="Habilitar la configuración de codificador avanzada" -Basic.Settings.Output.EncoderPreset="Perfil de Codificador (más rapido = menos CPU)" +Basic.Settings.Output.EncoderPreset="Preajuste del codificador" Basic.Settings.Output.CustomEncoderSettings="Configuración del codificador personalizada" Basic.Settings.Output.CustomMuxerSettings="Configuración personalizada de Muxer" Basic.Settings.Output.NoSpaceFileName="Generar el nombre del archivo sin espacio" Basic.Settings.Output.Adv.Rescale="Cambiar la escala de salida" Basic.Settings.Output.Adv.AudioTrack="Pista de audio" -Basic.Settings.Output.Adv.Streaming="Emision en directo" +Basic.Settings.Output.Adv.Streaming="Emisión" Basic.Settings.Output.Adv.ApplyServiceSettings="Aplicar ajustes de codificador de servicio streaming" Basic.Settings.Output.Adv.Audio.Track1="Pista 1" Basic.Settings.Output.Adv.Audio.Track2="Pista 2" @@ -612,7 +666,7 @@ Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Desactivar el codificador" Basic.Settings.Output.Adv.FFmpeg.VEncoder="Codificador de vídeo" Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Configuración de codificador de vídeo (si existe)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de audio" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuración de codificador de vídeo (si existe)" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Configuración de codificador de audio (si existe)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Ajustes de Muxer (en caso de que haya)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervalo de fotogramas clave (en Fotogramas)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Mostrar todos los codecs (aunque sean potencialmente incompatibles)" @@ -634,18 +688,19 @@ Basic.Settings.Video.FPSFraction="Valor fraccional de FPS" Basic.Settings.Video.Numerator="Numerador" Basic.Settings.Video.Denominator="Denominador" Basic.Settings.Video.Renderer="Renderizador" -Basic.Settings.Video.InvalidResolution="Valor de la resolución no válido. Debe ser [ancho] x [altura] (por ejemplo, 1920 x 1080)" -Basic.Settings.Video.CurrentlyActive="La salida de vídeo está actualmente activa. Por favor apague cualquier salida para cambiar la configuración de vídeo." +Basic.Settings.Video.InvalidResolution="Valor de la resolución no válido. Debe ser [ancho] x [altura] (por ejemplo, 1920 x 1080)" +Basic.Settings.Video.CurrentlyActive="La salida de vídeo está actualmente activa. Por favor apague cualquier salida para cambiar la configuración de vídeo." Basic.Settings.Video.DisableAero="Deshabilitar Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineal (más rápido, pero borroso si se escala la imagen)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (Escalado fino, 16 muestras)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scalado fino, 32 muestras)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Escalado fino, 32 muestras)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Frecuencia de muestreo" Basic.Settings.Audio.Channels="Canales" -Basic.Settings.Audio.MeterDecayRate="Tasa de decaimiento del medidor de audio" +Basic.Settings.Audio.Meters="Medidores" +Basic.Settings.Audio.MeterDecayRate="Velocidad de descomposición" Basic.Settings.Audio.MeterDecayRate.Fast="Rápida" Basic.Settings.Audio.MeterDecayRate.Medium="Media (PPM de tipo I)" Basic.Settings.Audio.MeterDecayRate.Slow="Lenta (PPM de tipo II)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="ADVERTENCIA: el audio de sonid Basic.Settings.Audio.MultichannelWarning="Si se está transmitiendo, compruebe si su servicio de transmisión admite la ingesta de sonido envolvente y la reproducción de sonido envolvente. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast son ejemplos en los que el sonido envolvente es totalmente compatible. Aunque Facebook Live y YouTube Live aceptan la ingesta surround, Facebook Live mezcla a estéreo y YouTube Live solo reproduce dos canales.\n\nLos filtros de audio OBS son compatibles con sonido envolvente, aunque no se garantiza el soporte de complementos VST." Basic.Settings.Audio.MultichannelWarning.Title="¿Habilitar el audio de sonido envolvente?" Basic.Settings.Audio.MultichannelWarning.Confirm="¿Seguro que quiere habilitar el audio de sonido envolvente?" -Basic.Settings.Audio.DesktopDevice="Dispositivo de audio de escritorio" -Basic.Settings.Audio.DesktopDevice2="Dispositivo de audio de escritorio 2" +Basic.Settings.Audio.Devices="Dispositivos" +Basic.Settings.Audio.DesktopDevice="Audio del escritorio" +Basic.Settings.Audio.DesktopDevice2="Audio del escritorio 2" Basic.Settings.Audio.AuxDevice="Dispositivo de audio Mic/auxiliar" Basic.Settings.Audio.AuxDevice2="Dispositivo de audio Mic/auxiliar 2" Basic.Settings.Audio.AuxDevice3="Dispositivo de audio Mic/auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Dispositivo de audio Mic/auxiliar 4" Basic.Settings.Audio.EnablePushToMute="Habilitar Pulsar para Silenciar" Basic.Settings.Audio.PushToMuteDelay="Retardo de Presionar para Silenciar" Basic.Settings.Audio.EnablePushToTalk="Habilitar Pulsar para Hablar" Basic.Settings.Audio.PushToTalkDelay="Retardo de Pulsar para Hablar" Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo no conectado o no está disponible]" +Basic.Settings.Audio.Disabled="Deshabilitado" Basic.Settings.Advanced="Avanzado" Basic.Settings.Advanced.General.ProcessPriority="Proceso prioritario" @@ -674,11 +732,11 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Mayor a Normal" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normal" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Por debajo de lo normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactiva" -Basic.Settings.Advanced.FormatWarning="ADVERTENCIA: Formatos de Color que no sean NV12 están diseñados principalmente para la grabación y no se recomiendan al retransmitir. La retransmisión puede incurrir en mayor uso de la CPU debido a la conversión de formato de color." +Basic.Settings.Advanced.FormatWarning="ADVERTENCIA: Formatos de Color que no sean NV12 están diseñados principalmente para la grabación y no se recomiendan al retransmitir. La retransmisión puede incurrir en mayor uso de la CPU debido a la conversión de formato de color." Basic.Settings.Advanced.Audio.BufferingTime="Tiempo de búfer de audio" Basic.Settings.Advanced.Video.ColorFormat="Formato de color" -Basic.Settings.Advanced.Video.ColorSpace="Espacio de color YUV" -Basic.Settings.Advanced.Video.ColorRange="Gama de Color YUV" +Basic.Settings.Advanced.Video.ColorSpace="Espacio de color" +Basic.Settings.Advanced.Video.ColorRange="Gama de colores" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" Basic.Settings.Advanced.Video.ColorRange.Full="Completo" Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitorización de audio" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Enlazar con IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Habilitar el nuevo código de red" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baja latencia" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Deshabilitar teclas de acceso rápido cuando la ventana principal se encuentre activa" +Basic.Settings.Advanced.AutoRemux="Convertir automáticamente a mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(grabar como mkv)" Basic.AdvAudio="Propiedades de Audio avanzadas" Basic.AdvAudio.Name="Nombre" -Basic.AdvAudio.Volume="Volumen (%)" +Basic.AdvAudio.Volume="Volumen" Basic.AdvAudio.Mono="Remezclar a Mono" -Basic.AdvAudio.Panning="Panorámica" +Basic.AdvAudio.Balance="Balance" Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)" Basic.AdvAudio.Monitoring="Monitorización de audio" Basic.AdvAudio.Monitoring.None="Monitorización desactivada" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Pistas" Basic.Settings.Hotkeys="Atajos" Basic.Settings.Hotkeys.Pair="Combinaciones de teclas con '%1' actúan como interruptores" +Basic.Settings.Hotkeys.Filter="Filtro" Basic.Hotkeys.SelectScene="Cambiar a la escena" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Teclado)" Hotkeys.AppleKeypadDecimal=". (Teclado)" Hotkeys.AppleKeypadEqual="= (Teclado)" Hotkeys.MouseButton="Ratón %1" +Hotkeys.Escape="Esc" Mute="Silenciar" Unmute="Quitar silencio" @@ -762,7 +824,7 @@ SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Debe seleccionar al menos una pista" OutputWarnings.MultiTrackRecording="ADVERTENCIA: Ciertos formatos (como FLV) no admiten varias pistas por grabación" -OutputWarnings.MP4Recording="ADVERTENCIA: Las grabaciones guardadas en MP4 será irrecuperables si el archivo no puede finalizarse (e.g. como resultado de BSODs, pérdidas de potencia, etcetera). Si quieres grabar varias pistas de audio utiliza MKV y reune la grabación a mp4 después de que termine (archivo-> Remux de grabaciones)" +OutputWarnings.MP4Recording="Advertencia: Las grabaciones guardadas en MP4/MOV serán irrecuperables si el archivo no puede finalizarse (e.g. como resultado de BSODs, cortes eléctricos, etc.). Si quieres grabar múltiples pistas de audio considera usar MKV y convierte la grabación a MP4/MOV después de finalizar (Archivo → Convertir Grabaciones)" FinalScene.Title="Eliminar escena" FinalScene.Text="Debe haber al menos una escena." @@ -770,9 +832,24 @@ FinalScene.Text="Debe haber al menos una escena." NoSources.Title="Sin recursos" NoSources.Text="Parece que no has añadido ningún recurso de vídeo aún, así que estarás emitiendo una pantalla en blanco. ¿Estás seguro de que quieres hacer esto?" NoSources.Text.AddSource="Puedes añadir recursos haciendo click en el icono de \"+\" debajo del menú Recursos en la ventana principal en cualquier momento." +NoSources.Label="No tienes ninguna fuente.\nHaz clic en el botón +,\no haz clic derecho aquí para añadir una." ChangeBG="Establecer color" CustomColor="Color personalizado" BrowserSource.EnableHardwareAcceleration="Habilitar Aceleración de Hardware de Recurso en el Navegador" +About="Acerca de" +About.Info="OBS Studio es un software libre y gratuito de grabación de vídeo y transmisión en directo." +About.Donate="Haz una contribución" +About.GetInvolved="Entra Ahora" +About.Authors="Autores" +About.License="Licencia" +About.Contribute="Apoya el proyecto OBS" + +ResizeOutputSizeOfSource="Ajustar salida (tamaño de la fuente)" +ResizeOutputSizeOfSource.Text="La resolución base y de salida serán ajustadas al tamaño de la fuente actual." +ResizeOutputSizeOfSource.Continue="¿Quieres continuar?" + +PreviewTransition="Vista previa de la Transición" + diff --git a/UI/data/locale/et-EE.ini b/UI/data/locale/et-EE.ini index 694f6ad..a3460e5 100644 --- a/UI/data/locale/et-EE.ini +++ b/UI/data/locale/et-EE.ini @@ -68,6 +68,9 @@ StudioMode.Preview="Eelvaade" AlreadyRunning.Title="OBS juba töötab" + + + BandwidthTest.Region.US="Ameerika Ühendriigid" BandwidthTest.Region.EU="Euroopa" BandwidthTest.Region.Asia="Aasia" @@ -85,6 +88,7 @@ Basic.Stats.CPUUsage="CPU kasutus" Basic.Stats.Status.Inactive="Inaktiivne" Basic.Stats.Bitrate="Bitikiirus" + Updater.Title="Uus värskendus saadaval" Updater.Text="Uus värskendus on saadaval:" Updater.UpdateNow="Värskenda kohe" @@ -128,6 +132,7 @@ ConfirmStart.Text="Kas soovid kindlasti voogedastust alustada?" ConfirmStop.Title="Lõpetada voogedastus?" ConfirmStop.Text="Kas soovid kindlasti voogedastust lõpetada?" + ConfirmExit.Title="Kas väljuda OBS-ist?" ConfirmExit.Text="OBS on hetkel aktiivne. Kõik voogedastused ja salvestused peatatakse. Kas soovid kindlasti väljuda?" @@ -138,10 +143,12 @@ ConfirmRemove.TextMultiple="Kas soovite kindlasti eemaldada %1 üksust?" Output.StartStreamFailed="Voogedastuse alustamine nurjus" Output.StartRecordingFailed="Salvestamise alustamine nurjus" + Output.ConnectFail.Title="Ühendamine ei õnnestunud" Output.ConnectFail.BadPath="Vigane rada või ühenduse URL. Palun veendu, et valitud sätted on õiged." Output.ConnectFail.ConnectFailed="Serveriga ühendamine ebaõnnestus" + Output.RecordFail.Title="Salvestamise alustamine nurjus" Output.RecordNoSpace.Title="Kettaruumi pole piisavalt" Output.RecordNoSpace.Msg="Pole piisavalt kettaruumi, et jätkata salvestamist." @@ -157,12 +164,6 @@ LogReturnDialog="Logi üleslaadimine õnnestus" LogReturnDialog.CopyURL="Kopeeri aadress" LogReturnDialog.ErrorUploadingLog="Esines viga logifaili üleslaadimisel" -LicenseAgreement="Litsentsileping" -LicenseAgreement.PleaseReview="Palun vaadake üle lisentsi tingimused enne OBS-i kasutamist. Selle programmi kasutamisega tunnistate, et olete antud tingimused läbilugenud ja nõustute GNU General Public License v2.0 tingimustega. Palun kerige alla, et näha tervet lepingut." -LicenseAgreement.ClickIAgreeToContinue="Kui nõustute lepingu tingimustega, klõpsake nõustun, et jätkata. Te peate nõustuma, et kasutada OBS-i." -LicenseAgreement.IAgree="Nõustun" -LicenseAgreement.Exit="Välju" - Remux.SourceFile="OBS-i salvestus" Remux.TargetFile="Sihtfail" Remux.Remux="Konverteeri" @@ -170,15 +171,11 @@ Remux.OBSRecording="OBS-i salvestus" Remux.FinishedTitle="Konverteerimine valmis" Remux.Finished="Salvestus on ümber kodeeritud" Remux.FinishedError="Salvestus on ümber kodeeritud, aga fail võib olla poolik" -Remux.SelectRecording="Vali OBS-i salvestus…" -Remux.SelectTarget="Vali sihtfail…" -Remux.FileExistsTitle="Sihtfail on olemas" -Remux.FileExists="Sihtfail on juba olemas, kas soovid selle asendada?" Remux.ExitUnfinishedTitle="Kodeerimine on pooleli" Remux.ExitUnfinished="Kodeerimine ei ole veel lõpetatud. Kui kodeerimine peatada, siis võib sihtfail olla kasutuskõlbmatu.\nKas soovid kindlasti kodeerimise peatada?" UpdateAvailable="Värskendus on saadaval" -UpdateAvailable.Text="Saadaval on version %1.%2.%3. Allalaadimiseks vajuta siia" +UpdateAvailable.Text="Saadaval on version %1.%2.%3. Allalaadimiseks vajuta siia" Basic.DesktopDevice1="Töölaua heli" Basic.DesktopDevice2="Töölaua heli 2" @@ -192,6 +189,7 @@ Basic.DisplayCapture="Kuvari hõive" Basic.Main.PreviewConextMenu.Enable="Lülita eelvaade sisse" + ScaleFiltering.Point="Punkt" Deinterlacing.Retro="Retro" @@ -227,7 +225,7 @@ Basic.SourceSelect.AddVisible="Tee allikas nähtavaks" Basic.PropertiesWindow="'%1' omadused" Basic.PropertiesWindow.SelectColor="Vali värv" Basic.PropertiesWindow.SelectFont="Vali font" -Basic.PropertiesWindow.Confirm="On salvestamata muutusi. Kas soovite neid säilitada?" +Basic.PropertiesWindow.Confirm="On salvestamata muutusi. Kas soovite neid säilitada?" Basic.PropertiesWindow.AddFiles="Lisa failid" Basic.PropertiesWindow.AddDir="Lisa kataloog" Basic.PropertiesWindow.AddURL="Lisa tee/URL" @@ -294,26 +292,26 @@ Basic.MainMenu.File.Exit="Välju (&X)" Basic.MainMenu.Edit="Muuda (&E)" Basic.MainMenu.Edit.Undo="Võta tagasi (&U)" -Basic.MainMenu.Edit.UndoAction="&Võta tagasi $1" +Basic.MainMenu.Edit.UndoAction="Võta tagasi $1 (&U)" Basic.MainMenu.Edit.LockPreview="&Lukusta eelvaade" Basic.MainMenu.Edit.Scale.Canvas="Lõuend (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Väljund (%1x%2)" Basic.MainMenu.Edit.Transform.Rotate90CW="Pööra 90 kraadi paremale" Basic.MainMenu.Edit.Transform.Rotate90CCW="Pööra 90 kraadi vasakule" Basic.MainMenu.Edit.Transform.Rotate180="Pööra 180 kraadi" -Basic.MainMenu.Edit.Transform.FitToScreen="&Sobita ekraanile" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Venita ekraanile" -Basic.MainMenu.Edit.Order="&Järjekord" -Basic.MainMenu.Edit.Order.MoveUp="Liiguta &Üles" -Basic.MainMenu.Edit.Order.MoveDown="Liiguta &Alla" -Basic.MainMenu.Edit.Order.MoveToTop="Liiguta &Esimeseks" -Basic.MainMenu.Edit.Order.MoveToBottom="Liiguta &Viimaseks" -Basic.MainMenu.Edit.AdvAudio="&Täpsemad Heliatribuudid" +Basic.MainMenu.Edit.Transform.FitToScreen="Sobita ekraanile (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Venita ekraanile (&S)" +Basic.MainMenu.Edit.Order="Järjek&ord" +Basic.MainMenu.Edit.Order.MoveUp="Liig&uta Üles" +Basic.MainMenu.Edit.Order.MoveDown="Liiguta Alla (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Liigu&ta Esimeseks" +Basic.MainMenu.Edit.Order.MoveToBottom="Liiguta Viimaseks (&B)" +Basic.MainMenu.Edit.AdvAudio="Täpsem&ad Heliatribuudid" Basic.MainMenu.View="&Vaade" Basic.MainMenu.View.Toolbars="&Tööriistaribad" -Basic.MainMenu.View.SceneTransitions="S&tseeni üleminekud" -Basic.MainMenu.View.StatusBar="&Olekuriba" +Basic.MainMenu.View.SceneTransitions="Stseeni üleminekud (&C)" +Basic.MainMenu.View.StatusBar="Olekuriba (&S)" Basic.MainMenu.SceneCollection="&Stseeni kogumik" Basic.MainMenu.Profile="&Profiil" @@ -326,18 +324,18 @@ Basic.MainMenu.SceneCollection.Exists="Stseeni kollektsioon on juba olemas" Basic.MainMenu.Tools="&Tööriistad" -Basic.MainMenu.Help="&Abi" -Basic.MainMenu.Help.Website="Külasta &Kodulehte" +Basic.MainMenu.Help="Abi (&H)" +Basic.MainMenu.Help.Website="Külasta Kodulehte (&W)" Basic.MainMenu.Help.Logs="&Logifailid" -Basic.MainMenu.Help.Logs.ShowLogs="&Näita logifaile" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Lae ülesse &praegune logifail" -Basic.MainMenu.Help.Logs.UploadLastLog="Lae ülesse &viimatine logifail" +Basic.MainMenu.Help.Logs.ShowLogs="Näita logifaile (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Lae ülesse praegune logifail (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="&Lae ülesse viimatine logifail" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vaata praegust logifaili" Basic.MainMenu.Help.CheckForUpdates="Otsi värskendusi" Basic.Settings.ProgramRestart="Nende sätete jõustumiseks tuleb taaskäivitada programm." Basic.Settings.ConfirmTitle="Kinnita muudatused" -Basic.Settings.Confirm="Teil on salvestamata muutusi. Salvestame muudatused?" +Basic.Settings.Confirm="Teil on salvestamata muutusi. Salvestame muudatused?" Basic.Settings.General="Üldine" Basic.Settings.General.Theme="Teema" @@ -360,9 +358,9 @@ Basic.Settings.Output.Mode="Väljundrežiim" Basic.Settings.Output.Mode.Simple="Lihtne" Basic.Settings.Output.Mode.Adv="Täpsemad seaded" Basic.Settings.Output.Mode.FFmpeg="FFmpeg väljund" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ei saa hinnata mälukasutust. Palun määrake maksimaalne piir." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Ei saa hinnata mälukasutust. Palun määrake maksimaalne piir." Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kadudeta kvaliteet, tohutult suur failimaht" -Basic.Settings.Output.Simple.Warn.Lossless="Hoiatus: Kadudeta kvaliteet tekitab tohutult suuri faile! Kadudeta kvaliteet võib kasutada kuni 7 Gb kettaruumi minuti kohta, kõrge eraldusvõime ja kaadrisagedusega. Kadudeta kvaliteeti ei ole soovitatav kasutada pikkade salvestiste jaoks, kui teil just ei ole väga palju vaba kettaruumi." +Basic.Settings.Output.Simple.Warn.Lossless="Hoiatus: Kadudeta kvaliteet tekitab tohutult suuri faile! Kadudeta kvaliteet võib kasutada kuni 7 Gb kettaruumi minuti kohta, kõrge eraldusvõime ja kaadrisagedusega. Kadudeta kvaliteeti ei ole soovitatav kasutada pikkade salvestiste jaoks, kui teil just ei ole väga palju vaba kettaruumi." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Kas soovite kindlasti kasutada kadudeta kvaliteeti?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Kadudeta kvaliteedi hoiatus!" Basic.Settings.Output.Simple.Encoder.Software="Tarkvara (x264)" @@ -373,7 +371,6 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Tarkvara (x264 madal CPU ka Basic.Settings.Output.VideoBitrate="Video bitikiirus" Basic.Settings.Output.AudioBitrate="Audio bitikiirus" Basic.Settings.Output.Reconnect="Taasühendu automaatselt" -Basic.Settings.Output.EncoderPreset="Kodeerija eelseadistus(kõrgem = vähem CPU)" Basic.Settings.Output.Adv.AudioTrack="Helirada" Basic.Settings.Output.Adv.Streaming="Voogedastus" @@ -412,18 +409,16 @@ Basic.Settings.Output.Adv.FFmpeg.GOPSize="Võtmekaadri intervall (kaadrit)" Basic.Settings.Video="Video" -Basic.Settings.Video.Adapter="Kuvaadapter:" -Basic.Settings.Video.BaseResolution="Alus (lõuendi) resolutsioon:" -Basic.Settings.Video.FPS="FPS:" -Basic.Settings.Video.Numerator="Lugeja:" -Basic.Settings.Video.Denominator="Nimetaja:" +Basic.Settings.Video.Adapter="Kuvaadapter" +Basic.Settings.Video.BaseResolution="Alus (lõuendi) resolutsioon" +Basic.Settings.Video.FPS="FPS" +Basic.Settings.Video.Numerator="Lugeja" +Basic.Settings.Video.Denominator="Nimetaja" Basic.Settings.Video.InvalidResolution="Eraldusvõime ei sobi. See peab olema kujul [width]x[height] (nt 1920x1080)" Basic.Settings.Audio="Heli" Basic.Settings.Audio.Channels="Kanalid" -Basic.Settings.Audio.DesktopDevice="Töölaua heliseade" -Basic.Settings.Audio.DesktopDevice2="Töölaua heliseade 2" Basic.Settings.Audio.UnknownAudioDevice="[Seade ühendamata või pole saadaval]" Basic.Settings.Advanced.General.ProcessPriority.High="Kõrge" @@ -431,7 +426,6 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Normaalsest kõrgem Basic.Settings.Advanced.General.ProcessPriority.Normal="Normaalne" Basic.Settings.Advanced.General.ProcessPriority.Idle="Tegevusetu" Basic.Settings.Advanced.Video.ColorFormat="Värvi formaat" -Basic.Settings.Advanced.Video.ColorRange="YUV värviruumi vahemik" Basic.Settings.Advanced.Video.ColorRange.Partial="Osaline" Basic.Settings.Advanced.Video.ColorRange.Full="Täielik" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Vaikeseade" @@ -442,7 +436,6 @@ Basic.Settings.Advanced.Network="Võrk" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Madal-viivitus režiim" Basic.AdvAudio.Name="Nimi" -Basic.AdvAudio.Volume="Helitugevus (%)" Basic.AdvAudio.Monitoring.None="Välja lülitatud" Basic.AdvAudio.AudioTracks="Rajad" @@ -479,3 +472,6 @@ Mute="Vaigista" + + + diff --git a/UI/data/locale/eu-ES.ini b/UI/data/locale/eu-ES.ini index 51e163d..4c3ea08 100644 --- a/UI/data/locale/eu-ES.ini +++ b/UI/data/locale/eu-ES.ini @@ -4,19 +4,19 @@ Region="Euskal Herria" OK="Ados" Apply="Aplikatu" -Cancel="Ezeztatu" +Cancel="Utzi" Close="Itxi" Save="Gorde" Discard="Baztertu" -Disable="Ezgaitu" +Disable="Desgaitu" Yes="Bai" No="Ez" Add="Gehitu" Remove="Kendu" -Rename="Berrizendatu" +Rename="Aldatu izena" Interact="Elkarreragin" Filters="Iragazkiak" -Properties="Ezaugarriak" +Properties="Propietateak" MoveUp="Mugitu gora" MoveDown="Mugitu behera" Settings="Ezarpenak" @@ -33,7 +33,7 @@ PreviewProjector="Pantaila osoko proiektorea (aurrebista)" SceneProjector="Pantaila osoko proiektorea (eszena)" SourceProjector="Pantaila osoko proiektorea (iturburua)" StudioProgramWindow="Leihoko proiektorea (programa)" -PreviewWindow="Leihodun proiektorea (aurrebista)" +PreviewWindow="Leiho proiektorea (aurrebista)" SceneWindow="Leihodun proiektorea (Eszena)" SourceWindow="Leihodun proiektorea (iturburua)" MultiviewProjector="Ikuspegi anitza (pantaila osoan)" @@ -47,7 +47,7 @@ Untitled="Izengabea" New="Berria" Duplicate="Bikoiztu" Enable="Gaitu" -DisableOSXVSync="Ezgaitu OSX V-Sync" +DisableOSXVSync="Desgaitu OSX V-Sync" ResetOSXVSyncOnExit="Berrezarri OSX V-Sync-a Irtetean" HighResourceUsage="Kodeketa gainzamatuta! Kontuan hartu bideo ezarpenak jaistea edo kodeketa-aurrezarpen azkarragoa erabiltzea." Transition="Trantsizioa" @@ -71,23 +71,49 @@ PasteDuplicate="Itsatsi (Bikoiztu)" RemuxRecordings="Birmultiplexatu grabazioak" Next="Hurrengoa" Back="Atzera" -Defaults="Lehenetsiak" +Defaults="Lehenespenak" HideMixer="Ezkutatu nahasgailuan" TransitionOverride="Trantsizio mota" None="Gabe" -StudioMode.Preview="Aurreikusi" +StudioMode.Preview="Aurrebista" StudioMode.Program="Programa" ShowInMultiview="Erakutsi ikuspegi anitzean" VerticalLayout="Diseinu bertikala" Group="Taldea" +DoNotShowAgain="Ez erakutsi berriro" +Default="(Lehenetsia)" +Calculating="Kalkulatzen..." AlreadyRunning.Title="OBS dagoeneko martxan dago" AlreadyRunning.Text="OBS dagoeneko martxan dago! Bestelakorik nahi ez baduzu Itxi irekita dagoen saioa beste saio bat ireki baino lehen. Ezarri baduzu OBS agertzea minimizatua sistemaren erretiluan begiratu eta oraindik exekutatzen ari den bertan." AlreadyRunning.LaunchAnyway="Abiarazi hala ere" +DockCloseWarning.Title="Leiho moldagarria ixten" +DockCloseWarning.Text="Leiho moldagarri bat itxi berri duzu. Berriro bistaratu nahi baduzu, erabili menu barrako Ikusi → Leiho moldagarriak menua." + +Auth.Authing.Title="Egiaztatzen..." +Auth.Authing.Text="%1(r) ekin egiaztatzen, itxaron..." +Auth.AuthFailure.Title="Autentifikazioak huts egin du" +Auth.AuthFailure.Text="Huts egin du %1:\n\n%2: %3 bidezko autentifikazioa" +Auth.InvalidScope.Title="Autentifikazioa derrigorrezkoa" +Auth.InvalidScope.Text="%1 autentifikatzeko eskakizunak aldatu dira. Eginbide batzuk ezingo dira erabili." +Auth.LoadingChannel.Title="Kanalaren informazioa kargatzen..." +Auth.LoadingChannel.Text="1% (e) tik kanalaren informazioa kargatzen, itxaron..." +Auth.ChannelFailure.Title="Huts egin du kanala kargatzen" +Auth.ChannelFailure.Text="Huts egin du %1\n\n%2: %3 kanalaren informazioa kargatzen" +Auth.Chat="Txata" +Auth.StreamInfo="Transmisioaren informazioa" +TwitchAuth.Stats="Twitch-estatistikak" +TwitchAuth.Feed="Twich aktibitateen jarioa" +TwitchAuth.TwoFactorFail.Title="Ezin izan da transmisioaren gakoa galdetu" +TwitchAuth.TwoFactorFail.Text="OBS-ek ez du lortu konektatzea zure Twitch kontuarekin. Egiazta ezazu bi urratsetako identifikazioa ezarrita dagoela zure Twitch-eko segurtasun ezarpenetan transmisiorako beharrezkoa da eta." + Copy.Filters="Kopiatu iragazkiak" Paste.Filters="Itsatsi iragazkiak" +BrowserPanelInit.Title="Nabigatzailea irekitzen..." +BrowserPanelInit.Text="Nabigatzailea irekitzen, itxaron..." + BandwidthTest.Region="Eskualdea" BandwidthTest.Region.US="Estatu Batuak" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Beste bat" Basic.FirstStartup.RunWizard="Martxan jarri nahi duzu ezarpen automatikoen morroia? Bestela eskuz konfigura dezakezu zure ezarpenak leiho nagusiko Ezarpenak botoia klikatuta." -Basic.FirstStartup.RunWizard.BetaWarning="(Oharra: ezarpen automatikoen morroia beta egoeran dago une honetan)" Basic.FirstStartup.RunWizard.NoClicked="Iritziz aldatzen baduzu, martxan jar dezakezu ezarpen automatikoen morroia berriro Tresnen menuan." Basic.AutoConfig="Ezarpen automatikoen morroia" -Basic.AutoConfig.Beta="Ezarpen automatikoen morroia (Beta)" Basic.AutoConfig.ApplySettings="Aplikatu ezarpenak" Basic.AutoConfig.StartPage="Erabilera-informazioa" Basic.AutoConfig.StartPage.SubTitle="Zehaztu zertarako erabili nahi duzun programa" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Izan daiteke 60 edo 30, baina nahi Basic.AutoConfig.VideoPage.CanvasExplanation="Oharra: grabaziorako erabiliko duzun bereizmena ez du zertan oihalaren (oinarriaren) bereizmen berdina. Uneko transmisioaren/grabazioaren bereizmena behera eskalatu daiteke txikiagotzeko baliabideen erabilera edo bit emariaren eskakizuna." Basic.AutoConfig.StreamPage="Transmisioaren informazioa" Basic.AutoConfig.StreamPage.SubTitle="Sartu transmisioaren informazioa" +Basic.AutoConfig.StreamPage.ConnectAccount="Konektatu kontua (aukerazkoa)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Deskonektatu kontua" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Kontua deskonektatu?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Aldaketa hau berehalakoan aplika daiteke. Ziur zaude kontua deskonektatu nahi duzula?" +Basic.AutoConfig.StreamPage.UseStreamKey="Erabili transmisio giltza" Basic.AutoConfig.StreamPage.Service="Zerbitzua" Basic.AutoConfig.StreamPage.Service.ShowAll="Erakutsi denak..." +Basic.AutoConfig.StreamPage.Service.Custom="Pertsonalizatuta..." Basic.AutoConfig.StreamPage.Server="Zerbitzaria" Basic.AutoConfig.StreamPage.StreamKey="Transmisio giltza" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Esteka)" @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="Ezarpen hauek onartzeko, klika Aplikatu Basic.Stats="Estatistikak" Basic.Stats.CPUUsage="PUZ erabilpena" -Basic.Stats.HDDSpaceAvailable="Toki erabilgarria disko gogorrean" +Basic.Stats.HDDSpaceAvailable="Toki erabilgarria diskoan" Basic.Stats.MemoryUsage="Memoria erabilpena" Basic.Stats.AverageTimeToRender="Fotograma errendatzeko batez besteko denbora" Basic.Stats.SkippedFrames="Kodetze atzerapena dela eta saltatutako fotogramak" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Inaktiboa" Basic.Stats.DroppedFrames="Jaregindako fotogramak (Sarean)" Basic.Stats.MegabytesSent="Datu irteera denetara" Basic.Stats.Bitrate="Bit-emaria" +Basic.Stats.DiskFullIn="Disko betea (gutxi gora behera)" + +ResetUIWarning.Title="Ziur zaude interfaze grafikoa berrabiarazi nahi duzula?" +ResetUIWarning.Text="Interfaze grafikoa berrezartzeak ezkuta ditzake atrake gehigarriak. Atrakeak bistaratu nahi baduzu menuko Ikusi atalean agerrarazi beharko dituzu.\n\nZiur zaude interfaze grafikoa berrezarri nahi duzula?" Updater.Title="Eguneraketa berria eskuragarri" Updater.Text="Eguneraketa berri bat eskuragarri dago:" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="Ez dago eguneraketarik eskuragarri" Updater.NoUpdatesAvailable.Text="Une honetan ez dago eguneraketarik eskuragarri" Updater.FailedToLaunch="Huts egin du eguneratzailea abiarazten" Updater.GameCaptureActive.Title="Jolasen kaptura aktiboa" -Updater.GameCaptureActive.Text="Jolasen kapturaren liburutegia erabiltzen ari da. Itxi kapturatzen ari den jolasa/programa (edo berrabiarazi Windows) eta saiatu berriro." +Updater.GameCaptureActive.Text="Jolasen kapturaren liburutegia erabiltzen ari da. Itxi kapturatzen ari den jolasa/programa (edo berrabiarazi Windows) eta saiatu berriro." QuickTransitions.SwapScenes="Trukatu Aurrebista/Irteera-eszenak trantsizioen ondoren" QuickTransitions.SwapScenesTT="Trukatu aurrebistak eta irteera-eszenak trantsizioen ondoren (baldin eta irteerakoaren jatorrizkoa eszena badago).\n Honek ez du desegingo irteerakoaren jatorrizko eszenari egindako aldaketak." @@ -186,7 +220,7 @@ Basic.RemoveTransition="Kendu trantsizio konfiguragarria" Basic.TransitionProperties="Trantsizioaren ezaugarriak" Basic.SceneTransitions="Eszena-trantsizioak" Basic.TransitionDuration="Iraupena" -Basic.TogglePreviewProgramMode="Estudio Modua" +Basic.TogglePreviewProgramMode="Estudio modua" TransitionNameDlg.Text="Sartu trantsizioaren izena" TransitionNameDlg.Title="Trantsizioaren Izena" @@ -206,18 +240,22 @@ ConfirmStart.Text="Ziur zaude transmisioa hasi nahi duzula?" ConfirmStop.Title="Gelditu transmisioa?" ConfirmStop.Text="Ziur zaude transmisioa gelditu nahi duzula?" +ConfirmBWTest.Title="Banda zabaleraren azterketa hasi?" +ConfirmBWTest.Text="OBS banda zabalera azterketa moduan duzu konfiguratua. Modu honek sareko azterketak egiteko aukera ematen du zure kanala aktibatu gabe. Behin azterketa egin ondoren, desaktibatu behar duzu ikusleek zure transmisioa ikus dezaten.\n\nJarraitu nahi duzu?" + ConfirmExit.Title="Irten OBS-tik?" -ConfirmExit.Text="OBS jardunean dago. Transmisio/grabazio guztiak itzaliko dira. Ziur zaude irten nahi duzula?" +ConfirmExit.Text="OBS jardunean dago. Transmisio/grabazio guztiak itzaliko dira. Ziur zaude irten nahi duzula?" ConfirmRemove.Title="Baieztatu kentzea" ConfirmRemove.Text="Ziur zaude '$1' kendu nahi duzula?" -ConfirmRemove.TextMultiple="Seguru zaude %1 elementuak ezabatu nahi dituzula?" +ConfirmRemove.TextMultiple="Seguru zaude %1 elementu ezabatu nahi dituzula?" Output.StartStreamFailed="Huts egin du transmisioak" Output.StartRecordingFailed="Huts egin du grabazioak" Output.StartReplayFailed="Huts egin du erreprodukzio bufferrak" Output.StartFailedGeneric="Huts egin du irteeraren abioak. Begiratu erregistroa zehaztasunak ikusteko.\n\nOharra: NVENC edo AMD kodetzaileak erabiltzen ari bazara segurtatu haien kontrolatzaileak eguneratuta daudela." + Output.ConnectFail.Title="Huts egin du konektatzean" Output.ConnectFail.BadPath="Helburu edo konexio-URL okerra. Egiaztatu zure ezarpenak baliozkoak direla baieztatzeko." Output.ConnectFail.ConnectFailed="Huts egin du zerbitzariarekin konektatzean" @@ -225,14 +263,18 @@ Output.ConnectFail.InvalidStream="Ezin da atzitu kanala edo transmisioaren gakoa Output.ConnectFail.Error="Ustekabeko akats bat gertatu da zerbitzariarekin konektatzen saiatzerakoan. Argibide gehiago egunkari-fitxategian." Output.ConnectFail.Disconnected="Zerbitzaritik deskonektatuta." -Output.RecordFail.Title="Ezin izan da grabaketa hasi" +Output.StreamEncodeError.Title="Kodeketa errorea" +Output.StreamEncodeError.Msg="Kodetzailearen errore bat gertatu da transmititzean." + +Output.RecordFail.Title="Huts egin du grabazioa hastean" Output.RecordFail.Unsupported="Irteera formatua ez da onartzen edo ez du audio pista bat baino gehiago onartzen. Egiaztatu zure ezarpenak eta saiatu berriro." Output.RecordNoSpace.Title="Ez dago nahiko tokirik diskoan" Output.RecordNoSpace.Msg="Ez dago nahikoa tokirik diskoan grabatzen jarraitzeko." Output.RecordError.Title="Grabazio akatsa" Output.RecordError.Msg="Zehaztugabeko akats bat gertatu da grabatzerakoan." +Output.RecordError.EncodeErrorMsg="Kodetzailearen errore bat gertatu da grabatzean." Output.ReplayBuffer.NoHotkey.Title="Laster tekla ezarri gabe!" -Output.ReplayBuffer.NoHotkey.Msg="Ez da ezarri gordetzeko laster teklarik erreprodukzio bufferrerako. Ezarri \"Gorde\" laster tekla erreprodukzio bufferrak gordetzeko." +Output.ReplayBuffer.NoHotkey.Msg="Ez da ezarri gordetzeko laster teklarik erreprodukzio bufferrerako. Ezarri \"Gorde\" laster tekla erreprodukzio bufferrak gordetzeko." Output.BadPath.Title="Fitxategi-bide okerra" Output.BadPath.Text="Ezarritako fitxategiaren irteera-bidea baliogabea da. Egiaztatu zure ezarpenak baieztatzeko baliozko fitxategi-bidea ezarri dela." @@ -241,28 +283,26 @@ LogReturnDialog="Egunkaria ongi kargatu da" LogReturnDialog.CopyURL="Kopiatu URL-a" LogReturnDialog.ErrorUploadingLog="Errorea egunkari-fitxategia kargatzean" -LicenseAgreement="Lizentzia-kontratua" -LicenseAgreement.PleaseReview="Berrikusi lizentziaren baldintzak OBS erabili aurretik. Programa hau erabiltzean, adierazten duzu GNU General Public License v2.0-ren baldintzak irakurri eta onartzen dituzula. Korritu behera itun osoa ikusteko." -LicenseAgreement.ClickIAgreeToContinue="Lizentziaren baldintzak onartzen badituzu, klikatu Onartzen dut jarraitzeko. Lizentzia onartu behar duzu OBS erabiltzeko." -LicenseAgreement.IAgree="Onartzen dut" -LicenseAgreement.Exit="Irten" - -Remux.SourceFile="OBS Grabazioa" +Remux.SourceFile="OBS grabazioa" Remux.TargetFile="Helburu-fitxategia" Remux.Remux="Multiplexatu" +Remux.Stop="Gelditu bihurtzea" +Remux.ClearFinished="Garbitu bukatutako elementuak" +Remux.ClearAll="Garbitu elementu guztiak" Remux.OBSRecording="OBS grabazioa" Remux.FinishedTitle="Bihurketa amaituta" Remux.Finished="Grabazioa bihurtuta" Remux.FinishedError="Grabazioa bihurtua, baina fitxategia osatu gabe egon daiteke" -Remux.SelectRecording="Hautatu OBS grabazioa…" -Remux.SelectTarget="Hautatu helburu-fitxategia…" -Remux.FileExistsTitle="Helburu-fitxategia badago" -Remux.FileExists="Helburu-fitxategia badago, ordeztea nahi duzu?" +Remux.SelectRecording="OBS grabazio modua aukeratu..." +Remux.SelectTarget="Helburu-fitxategia aukeratu..." +Remux.FileExistsTitle="Helburu-fitxategiak badaude" +Remux.FileExists="Dagoeneko ondorengo helburu-fitxategiak existitzen dira. Ordezkatu nahi dituzu?" Remux.ExitUnfinishedTitle="Multiplexazioa martxan" Remux.ExitUnfinished="Bihurketa ez da amaitu, orain gelditzeak fitxategi-helburua erabiltezin bihur dezake.\nZiur zaude bihurtzea gelditu nahi duzula?" +Remux.HelpText="Jaregin itzazu fitxategiak leiho honetan aldatzeko, edo hauta ezazu \"OBS Grabazioa\"-gelaxka huts bat fitxategia arakatzeko." UpdateAvailable="Eguneraketa eskuragarria" -UpdateAvailable.Text="%1.%2.%3 bertsioa eskuragarri dago. Klikatu hemen deskargatzeko" +UpdateAvailable.Text="%1.%2.%3 bertsioa eskuragarri dago. Klikatu hemen deskargatzeko" Basic.DesktopDevice1="Mahaigaineko audioa" Basic.DesktopDevice2="Mahaigaineko audioa 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Pantaila-kaptura" Basic.Main.PreviewConextMenu.Enable="Gaitu aurrebista" +Basic.Main.Preview.Disable="Desgaitu aurrebista" + ScaleFiltering="Eskalaren iragazketa" ScaleFiltering.Point="Puntua" ScaleFiltering.Bilinear="Bilineala" ScaleFiltering.Bicubic="Bikubikoa" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Area" Deinterlacing="Desgurutzelarkatzea" Deinterlacing.Discard="Baztertu" @@ -312,7 +355,7 @@ Basic.Main.RenameSceneCollection.Title="Berrizendatu eszena-bilduma" AddProfile.Title="Gehitu profila" AddProfile.Text="Sartu profilaren izena" -RenameProfile.Title="Berrizendatu profila" +RenameProfile.Title="Aldatu izena profilari" Basic.Main.MixerRename.Title="Berrizendatu audio iturburua" Basic.Main.MixerRename.Text="Sartu audio iturburuaren izena" @@ -356,10 +399,10 @@ Basic.StatusBar.DelayStartingStoppingIn="Atzerapena (gelditzea %1 seg-tan, hasie Basic.Filters="Iragazkiak" Basic.Filters.AsyncFilters="Audio/Bideo Iragazkiak" -Basic.Filters.AudioFilters="Audio Iragazkiak" +Basic.Filters.AudioFilters="Audio iragazkiak" Basic.Filters.EffectFilters="Efektu Iragazkiak" Basic.Filters.Title="Iragazkiak '%1'-rako" -Basic.Filters.AddFilter.Title="Iragazkiaren Izena" +Basic.Filters.AddFilter.Title="Iragazkiaren izena" Basic.Filters.AddFilter.Text="Adierazi iragazkiaren izena" Basic.TransformWindow="Eszenaren elementuaren eraldaketa" @@ -402,7 +445,7 @@ Basic.Main.StartReplayBuffer="Abiatu erreprodukzio bufferra" Basic.Main.StartStreaming="Hasi transmisioa" Basic.Main.StopRecording="Gelditu grabazioa" Basic.Main.StoppingRecording="Grabazioa gelditzen..." -Basic.Main.StopReplayBuffer="Gelditu erreprodukzio buferra" +Basic.Main.StopReplayBuffer="Gelditu erreprodukzio bufferra" Basic.Main.StoppingReplayBuffer="Erreprodukzio bufferra gelditzen..." Basic.Main.StopStreaming="Gelditu transmisioa" Basic.Main.StoppingStreaming="Transmisioa gelditzen..." @@ -414,55 +457,57 @@ Basic.Main.Ungroup="Banatu" Basic.MainMenu.File="&Fitxategia" Basic.MainMenu.File.Export="&Esportatu" Basic.MainMenu.File.Import="&Inportatu" -Basic.MainMenu.File.ShowRecordings="Erakutsi &grabazioak" -Basic.MainMenu.File.Remux="Multiplexatu grabazioak" -Basic.MainMenu.File.Settings="&Ezarpenak" +Basic.MainMenu.File.ShowRecordings="E&rakutsi grabazioak" +Basic.MainMenu.File.Remux="&Multiplexatu grabazioak" +Basic.MainMenu.File.Settings="Ezarpenak (&S)" Basic.MainMenu.File.ShowSettingsFolder="Erakutsi ezarpenen karpeta" Basic.MainMenu.File.ShowProfileFolder="Erakutsi profilaren karpeta" -Basic.MainMenu.AlwaysOnTop="&Beti gainean" -Basic.MainMenu.File.Exit="I&rten" +Basic.MainMenu.AlwaysOnTop="Beti g&ainean" +Basic.MainMenu.File.Exit="Irten (&X)" Basic.MainMenu.Edit="&Editatu" -Basic.MainMenu.Edit.Undo="&Desegin" -Basic.MainMenu.Edit.Redo="&Berregin" -Basic.MainMenu.Edit.UndoAction="&Desegin $1" -Basic.MainMenu.Edit.RedoAction="&Berregin $1" -Basic.MainMenu.Edit.LockPreview="Blokeatu aurrebista" -Basic.MainMenu.Edit.Scale="Aurrebistaren eskala" +Basic.MainMenu.Edit.Undo="Desegin (&U)" +Basic.MainMenu.Edit.Redo="Be&rregin" +Basic.MainMenu.Edit.UndoAction="Desegin $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Be&rregin $1" +Basic.MainMenu.Edit.LockPreview="B&lokeatu aurrebista" +Basic.MainMenu.Edit.Scale="Aurrebi&staren eskala" Basic.MainMenu.Edit.Scale.Window="Eskalatu leihora" Basic.MainMenu.Edit.Scale.Canvas="Oihala (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Irteera (%1x%2)" -Basic.MainMenu.Edit.Transform="&Eraldatu" -Basic.MainMenu.Edit.Transform.EditTransform="E&ditatu eraldaketa..." +Basic.MainMenu.Edit.Transform="Eralda&tu" +Basic.MainMenu.Edit.Transform.EditTransform="&Editatu eraldaketa..." Basic.MainMenu.Edit.Transform.CopyTransform="Kopiatu eraldaketa" Basic.MainMenu.Edit.Transform.PasteTransform="Itsatsi eraldaketa" -Basic.MainMenu.Edit.Transform.ResetTransform="&Berrezarri eraldaketa" +Basic.MainMenu.Edit.Transform.ResetTransform="Be&rrezarri eraldaketa" Basic.MainMenu.Edit.Transform.Rotate90CW="Biratu 90 gradu erlojuaren norabidean" Basic.MainMenu.Edit.Transform.Rotate90CCW="Biratu 90 gradu erlojuaren kontrako norabidean" Basic.MainMenu.Edit.Transform.Rotate180="Biratu 180 gradu" Basic.MainMenu.Edit.Transform.FlipHorizontal="Irauli &horizontala" -Basic.MainMenu.Edit.Transform.FlipVertical="Irauli &bertikala" -Basic.MainMenu.Edit.Transform.FitToScreen="&Doitu pantailara" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Luzatu pantailara" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Erdiratu pantailan" +Basic.MainMenu.Edit.Transform.FlipVertical="Irauli bertikala (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Doitu pantailara (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Luzatu pantailara (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Erdiratu pantailan (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Erdiratu bertikalki" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Erdiratu horizontalki" Basic.MainMenu.Edit.Order="&Ordenatu" -Basic.MainMenu.Edit.Order.MoveUp="Mugitu &Gora" -Basic.MainMenu.Edit.Order.MoveDown="Mugitu &behera" -Basic.MainMenu.Edit.Order.MoveToTop="Mugitu &goraino" +Basic.MainMenu.Edit.Order.MoveUp="M&ugitu gora" +Basic.MainMenu.Edit.Order.MoveDown="Mugitu behera (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Mugi&tu goraino" Basic.MainMenu.Edit.Order.MoveToBottom="Mugitu &beheraino" Basic.MainMenu.Edit.AdvAudio="&Audio ezarpen aurreratuak" -Basic.MainMenu.View="&Ikusi" +Basic.MainMenu.View="Ikusi (&V)" Basic.MainMenu.View.Toolbars="&Tresna barrak" -Basic.MainMenu.View.Docks="Atrakagarriak" +Basic.MainMenu.View.Docks="Leiho moldagarriak" Basic.MainMenu.View.Docks.ResetUI="Berrabiarazi erabiltzaile-interfazea" Basic.MainMenu.View.Docks.LockUI="Blokeatu erabiltzaile-interfazea" -Basic.MainMenu.View.Toolbars.Listboxes="&Zerrenda-kutxak" -Basic.MainMenu.View.SceneTransitions="&Eszenen trantsizioak" -Basic.MainMenu.View.StatusBar="Egoera-barra" +Basic.MainMenu.View.Toolbars.Listboxes="Zerrenda-kutxak (&L)" +Basic.MainMenu.View.SceneTransitions="Eszenen trantsizioak (&C)" +Basic.MainMenu.View.StatusBar="Egoera-barra (&S)" Basic.MainMenu.View.Fullscreen.Interface="Pantaila osoa" -Basic.MainMenu.SceneCollection="&Eszena-bilduma" +Basic.MainMenu.SceneCollection="E&szena-bilduma" Basic.MainMenu.Profile="&Profila" Basic.MainMenu.Profile.Import="Inportatu profila" Basic.MainMenu.Profile.Export="Esportatu profila" @@ -473,19 +518,20 @@ Basic.MainMenu.SceneCollection.Exists="Eszena bilduma lehendik ere badago" Basic.MainMenu.Tools="&Tresnak" -Basic.MainMenu.Help="&Laguntza" -Basic.MainMenu.Help.HelpPortal="Laguntza ataria" +Basic.MainMenu.Help="Laguntza (&H)" +Basic.MainMenu.Help.HelpPortal="Laguntza ataria (&P)" Basic.MainMenu.Help.Website="Ikusi &webgunea" -Basic.MainMenu.Help.Discord="Bat egin Discord zerbitzariarekin" -Basic.MainMenu.Help.Logs="&Egunkari-fitxategiak" -Basic.MainMenu.Help.Logs.ShowLogs="&Erakutsi egunkari-fitxategiak" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Kargatu &uneko egunkari-fitxategiak" -Basic.MainMenu.Help.Logs.UploadLastLog="Kargatu &azken egunkari-fitxategia" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ikusi uneko egunkari-fitxategia" +Basic.MainMenu.Help.Discord="Bat egin &Discord zerbitzariarekin" +Basic.MainMenu.Help.Logs="Egunkari-fitxategiak (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Erakut&si egunkari-fitxategiak" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Kargatu uneko egunkari-fitxategiak (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Kargatu azken egunkari-fitxategia (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Ikusi uneko egunkari-fitxategia (&V)" Basic.MainMenu.Help.CheckForUpdates="Begiratu eguneraketak" -Basic.MainMenu.Help.CrashLogs="Matxuren jakinarazpenak" -Basic.MainMenu.Help.CrashLogs.ShowLogs="Erakutsi matxuren jakinarazpenak" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Kargatu azken matxura jakinarazpena" +Basic.MainMenu.Help.CrashLogs="Matxuren jakinarazpenak (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Erakut&si matxuren jakinarazpenak" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Kargatu azken matxura jakinarazpena (&L)" +Basic.MainMenu.Help.About="Honi buruz (&A)" Basic.Settings.ProgramRestart="Programa berrabiarazi egin behar da ezarpen hauek eragina izateko." Basic.Settings.ConfirmTitle="Baieztatu aldaketak" @@ -497,7 +543,7 @@ Basic.Settings.General.Language="Hizkuntza" Basic.Settings.General.EnableAutoUpdates="Abiaraztean begiratu automatikoki eguneraketarik ba ote dagoen" Basic.Settings.General.OpenStatsOnStartup="Ireki estatistikak abiatzean" Basic.Settings.General.WarnBeforeStartingStream="Erakutsi baieztapen elkarrizketa transmisioak hasterakoan" -Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzean" +Basic.Settings.General.WarnBeforeStoppingStream="Erakutsi baieztapen elkarrizketa transmisioak gelditzerakoan" Basic.Settings.General.Projectors="Proiektoreak" Basic.Settings.General.HideProjectorCursor="Ezkutatu kurtsorea proiekzioetan" Basic.Settings.General.ProjectorAlwaysOnTop="Proiektoreak beti gainean" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Sistemaren erretilua" Basic.Settings.General.SysTrayWhenStarted="Minimizatu sistemaren erretilura hastean" Basic.Settings.General.SystemTrayHideMinimize="Minimizatu beti sistemaren erretilura ataza barrara egin ordez" Basic.Settings.General.SaveProjectors="Gorde proiekzioak irtetean" +Basic.Settings.General.Preview="Aurrebista" +Basic.Settings.General.OverflowHidden="Ezkutatu gainezkatzea" +Basic.Settings.General.OverflowAlwaysVisible="Gainezkatzea beti begi-bistan" +Basic.Settings.General.OverflowSelectionHidden="Erakutsi gainezkatzea baita iturburua ezkutuan dagoenean ere" Basic.Settings.General.SwitchOnDoubleClick="Aldatu eszena klik bikoitza egitean" Basic.Settings.General.StudioPortraitLayout="Gaitu diseinu horizontala/bertikala" +Basic.Settings.General.TogglePreviewProgramLabels="Erakutsi aurrebista/programa etiketak" Basic.Settings.General.Multiview="Ikuspegi anitza" Basic.Settings.General.Multiview.MouseSwitch="Klikatu eszena batetik bestera pasatzeko" Basic.Settings.General.Multiview.DrawSourceNames="Erakutsi eszenen izenak" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontala, goi Basic.Settings.Stream="Transmisioa" Basic.Settings.Stream.StreamType="Transmisio-mota" +Basic.Settings.Stream.Custom.UseAuthentication="Erabili autentifikazioa" +Basic.Settings.Stream.Custom.Username="Erabiltzaile izena" +Basic.Settings.Stream.Custom.Password="Pasahitza" +Basic.Settings.Stream.BandwidthTestMode="Gaitu banda zabalaren azterketa modua" Basic.Settings.Output="Irteera" Basic.Settings.Output.Format="Grabazio-formatua" @@ -537,7 +592,7 @@ Basic.Settings.Output.SelectDirectory="Hautatu grabazioaren karpeta" Basic.Settings.Output.SelectFile="Hautatu grabazioaren fitxategia" Basic.Settings.Output.EnforceBitrate="Behartu transmisio zerbitzuaren bit-tasaren mugak" Basic.Settings.Output.Mode="Irteera-modua" -Basic.Settings.Output.Mode.Simple="Arrunta" +Basic.Settings.Output.Mode.Simple="Sinplea" Basic.Settings.Output.Mode.Adv="Aurreratua" Basic.Settings.Output.Mode.FFmpeg="FFmpeg irteera" Basic.Settings.Output.UseReplayBuffer="Gaitu erreprodukzio bufferra" @@ -557,10 +612,9 @@ Basic.Settings.Output.Simple.RecordingQuality.Lossless="Galerarik gabeko kalitat Basic.Settings.Output.Simple.Warn.VideoBitrate="Kontuz: transmisioaren bideoaren bit-tasa %1 ean ezarriko da; hau izango da oraingo transmisio zerbitzuaren goiko muga. Seguru bazaude %1 aren gainetik nahi duzula, gaitu kodetze aukera aurreratuak eta desautatu \"Behartu transmisio zerbitzuaren bit-tasaren mugak\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Kontuz: transmisioaren audioaren bit-tasa %1 ean ezarriko da; hau izango da oraingo transmisio zerbitzuaren goiko muga. Seguru bazaude %1 aren gainetik nahi duzula, gaitu kodetze aukera aurreratuak eta desautatu \"Behartu transmisio zerbitzuaren bit-tasaren mugak\"." Basic.Settings.Output.Simple.Warn.Encoder="Oharra: Transmisioak duen kalitatea ez bestelako kalitate batez grabatzeak PUZ-ren aparteko erabilera eskatzen du une berean transmititzen eta grabatzen baduzu." -Basic.Settings.Output.Simple.Warn.Lossless="Oharra: Galerarik gabeko kalitateak neurri izugarri handiko fitxategiak sortzen ditu! Galerarik gabeko kalitateak minutuko 7 gigabytetik gorako tokia erabili dezake diskoan bereizmen eta fotograma-emari handietan. Galerarik gabeko kalitatea ez dago gomendatua grabazio luzeetarako disko toki eskuragarri oso handi bat ez baduzu." +Basic.Settings.Output.Simple.Warn.Lossless="Oharra: Galerarik gabeko kalitateak neurri izugarri handiko fitxategiak sortzen ditu! Galerarik gabeko kalitateak minutuko 7 gigabytetik gorako tokia erabili dezake diskoan bereizmen eta fotograma-emari handietan. Galerarik gabeko kalitatea ez dago gomendatua grabazio luzeetarako disko toki eskuragarri oso handi bat ez baduzu." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ziur zaude galerarik gabeko kalitatea erabili nahi duzula?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Galerarik gabeko kalitateaz oharra!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Kontuz: Ezin dituzu QSV kodeatzaile ugari bananduta erabili aldiberean jariotu eta grabatzerakoan. Aldiberean jariotu eta grabatzea nahi baduzu, mesedez aldatu bietako bat, grabaketa kodeatzailea edo jariotze kodeatzailea." Basic.Settings.Output.Simple.Encoder.Software="Softwarea (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardwarea (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardwarea (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Automatikoki birkonektatu" Basic.Settings.Output.RetryDelay="Saiakera-atzerapena (segundoak)" Basic.Settings.Output.MaxRetries="Gehienezko saiakerak" Basic.Settings.Output.Advanced="Gaitu Kodetzaile aurreratuaren ezarpenak" -Basic.Settings.Output.EncoderPreset="Kodetzailearen aurre-ezarpena (handiagoa = PUZ gutxiago)" +Basic.Settings.Output.EncoderPreset="Aurrez ezarritako kodetzea" Basic.Settings.Output.CustomEncoderSettings="Kodetzailearen ezarpen pertsonalizatuak" Basic.Settings.Output.CustomMuxerSettings="Bihurtzailearen ezarpen pertsonalizatuak" Basic.Settings.Output.NoSpaceFileName="Sortu tarterik gabeko fitxategi-izena" @@ -594,7 +648,7 @@ Basic.Settings.Output.Adv.Recording.Type.Standard="Estandarra" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Irteera pertsonalizatua (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Erabili transmisio kodetzailea)" Basic.Settings.Output.Adv.Recording.Filename="Fitxategi-izenaren formatua" -Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Gainidatzi fitxategia" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Gainidatzi fitxategia badago" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg Irteera-mota" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Irteera URL-ra" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Irteera fitxategira" @@ -631,8 +685,8 @@ Basic.Settings.Video.FPS="FPS:" Basic.Settings.Video.FPSCommon="FPS balio arruntak" Basic.Settings.Video.FPSInteger="FPS balio osoa" Basic.Settings.Video.FPSFraction="FPS zatikizko balioa" -Basic.Settings.Video.Numerator="Zenbakitzailea:" -Basic.Settings.Video.Denominator="Izendatzailea:" +Basic.Settings.Video.Numerator="Zenbakitzailea" +Basic.Settings.Video.Denominator="Izendatzailea" Basic.Settings.Video.Renderer="Errendatzailea:" Basic.Settings.Video.InvalidResolution="Bereizmen baliogabea. Izan behar da [width]x[height] (adib. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Bideo irteera gaituta dago une honetan. Eten irteera guztiak bideo ezarpenak aldatzeko." @@ -644,8 +698,9 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (eskalatze zorrotza, 32 la Basic.Settings.Audio="Audioa" Basic.Settings.Audio.SampleRate="Lagin-maiztasuna" -Basic.Settings.Audio.Channels="Bideak" -Basic.Settings.Audio.MeterDecayRate="Audio neurtzailearen gutxiagotze-tasa" +Basic.Settings.Audio.Channels="Kanalak" +Basic.Settings.Audio.Meters="Neurgailuak" +Basic.Settings.Audio.MeterDecayRate="Desintegrazio-tasa" Basic.Settings.Audio.MeterDecayRate.Fast="Azkarra" Basic.Settings.Audio.MeterDecayRate.Medium="Tartekoa (I motako PPMa)" Basic.Settings.Audio.MeterDecayRate.Slow="Geldoa (II motako PPMa)" @@ -653,19 +708,22 @@ Basic.Settings.Audio.PeakMeterType="Gailurren neurgailu mota" Basic.Settings.Audio.PeakMeterType.SamplePeak="Lagin-gailurra" Basic.Settings.Audio.PeakMeterType.TruePeak="Benetako gailurra (CPUaren erabilera handiagoa)" Basic.Settings.Audio.MultiChannelWarning.Enabled="Kontu: soinu inguratzailea aktibatuta dago." -Basic.Settings.Audio.MultichannelWarning="Transmititzen ari bazara, begiratu ea zure transmisio zerbitzuak onartzen duen soinu inguratzailea sarrerako soinuan zein irteerakoan. Twitch, Facebook 360 LIve, Mixer RTMP, Samashcast esate baterako guztiz onartzen dute soinu inguratzailea. Facebook Live eta Youtube Live sarrerako soinu inguratzailea onartzen badute ere, Facebook Livek estereo bihurtzen du, eta Youtube Livek bakarrik bi kanal erreproduzitzen ditu.\n\nOBS audio iragazkiak soinu inguratzailearekin bateragarriak badira ere, ezin da bermatu VST pluginaren bateragarritasuna." +Basic.Settings.Audio.MultichannelWarning="Transmititzen ari bazara, begiratu ea zure transmisio zerbitzuak onartzen duen soinu inguratzailea sarrerako soinuan zein irteerakoan. Twitch, Facebook 360 LIve, Mixer RTMP, Samashcast esate baterako guztiz onartzen dute soinu inguratzailea. Facebook Live eta Youtube Live sarrerako soinu inguratzailea onartzen badute ere, Facebook Livek estereo bihurtzen du, eta Youtube Livek bakarrik bi kanal erreproduzitzen ditu.\n\nOBS audio iragazkiak soinu inguratzailearekin bateragarriak badira ere, ezin da bermatu VST pluginaren bateragarritasuna." Basic.Settings.Audio.MultichannelWarning.Title="Nahi duzu soinu inguratzailea aktibatzea?" Basic.Settings.Audio.MultichannelWarning.Confirm="Seguru zaude soinu inguratzailea aktibatu nahi duzula?" -Basic.Settings.Audio.DesktopDevice="Mahaigaineko audio gailua" -Basic.Settings.Audio.DesktopDevice2="Mahaigaineko audio gailua 2" -Basic.Settings.Audio.AuxDevice="Mik/Osagarri audio gailua" -Basic.Settings.Audio.AuxDevice2="Mik/Osagarri audio gailua 2" -Basic.Settings.Audio.AuxDevice3="Mik/Osagarri audio gailua 3" +Basic.Settings.Audio.Devices="Gailuak" +Basic.Settings.Audio.DesktopDevice="Mahaigaineko audioa" +Basic.Settings.Audio.DesktopDevice2="Mahaigaineko audioa 2" +Basic.Settings.Audio.AuxDevice="Mik/Audio osagarria" +Basic.Settings.Audio.AuxDevice2="Mik/Audio osagarria 2" +Basic.Settings.Audio.AuxDevice3="Mik/Audio osagarria 3" +Basic.Settings.Audio.AuxDevice4="Mik/Audio osagarria 4" Basic.Settings.Audio.EnablePushToMute="Gaitu Sakatu-mututzeko" Basic.Settings.Audio.PushToMuteDelay="Sakatu-mututzeko atzerapena" Basic.Settings.Audio.EnablePushToTalk="Gaitu Sakatu-hitz-egiteko" Basic.Settings.Audio.PushToTalkDelay="Sakatu-hitz-egiteko atzerapena" Basic.Settings.Audio.UnknownAudioDevice="[Gailua konektatu gabe edo ez dago eskuragarri]" +Basic.Settings.Audio.Disabled="Desaktibatua" Basic.Settings.Advanced="Aurreratua" Basic.Settings.Advanced.General.ProcessPriority="Prozesuaren lehentasuna" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inaktiboa" Basic.Settings.Advanced.FormatWarning="Oharra: NV12 ez diren kolore formatuak grabaziorako dira gehienbat, eta ez daude gomendatuta transmisiorako. Transmisioak PUZ erabilpena handitu dezake kolore formatu bihurketa dela medio." Basic.Settings.Advanced.Audio.BufferingTime="Audio bufferratze denbora" Basic.Settings.Advanced.Video.ColorFormat="Kolore formatua" -Basic.Settings.Advanced.Video.ColorSpace="YUV kolore-espazioa" -Basic.Settings.Advanced.Video.ColorRange="YUV kolore-barrutia" +Basic.Settings.Advanced.Video.ColorSpace="Kolore-espazioa" +Basic.Settings.Advanced.Video.ColorRange="Kolore tartea" Basic.Settings.Advanced.Video.ColorRange.Partial="Partziala" Basic.Settings.Advanced.Video.ColorRange.Full="Osoa" -Basic.Settings.Advanced.Audio.MonitoringDevice="Audioa kontrolatzeko gailua" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorizazio gailua" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Lehenetsia" Basic.Settings.Advanced.Audio.DisableAudioDucking="Ezgaitu Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Transmisio-atzerapena" @@ -692,22 +750,25 @@ Basic.Settings.Advanced.Network="Sarea" Basic.Settings.Advanced.Network.BindToIP="IP bidez lotu" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Gaitu sare kode berria" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Latentzia txikiko modua" -Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Desgaitu laster-teklak leiho nagusia fokuan dagoenean" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Ezgaitu laster-teklak leiho nagusia fokuan dagoenean" +Basic.Settings.Advanced.AutoRemux="Bihurtu automatikoki mp4-ra" +Basic.Settings.Advanced.AutoRemux.MP4="(grabatu mkv bezala)" Basic.AdvAudio="Audio propietate aurreratuak" Basic.AdvAudio.Name="Izena" -Basic.AdvAudio.Volume="Bolumena (%)" +Basic.AdvAudio.Volume="Bolumena" Basic.AdvAudio.Mono="Nahasketa monora murriztu" -Basic.AdvAudio.Panning="Panoramika" +Basic.AdvAudio.Balance="Balantzea" Basic.AdvAudio.SyncOffset="Sinkronizazioaren desplazamendua (ms)" -Basic.AdvAudio.Monitoring="Adioaren kontrola" -Basic.AdvAudio.Monitoring.None="Audioa itzalita" -Basic.AdvAudio.Monitoring.MonitorOnly="Kontrola bakarrik (irteera mututua)" -Basic.AdvAudio.Monitoring.Both="Kontrola eta irteera" +Basic.AdvAudio.Monitoring="Adioaren monitorizazioa" +Basic.AdvAudio.Monitoring.None="Ez monitorizatu" +Basic.AdvAudio.Monitoring.MonitorOnly="Monitorea bakarrik (irteera mututua)" +Basic.AdvAudio.Monitoring.Both="Monitorea eta irteera" Basic.AdvAudio.AudioTracks="Pistak" Basic.Settings.Hotkeys="Laster-teklak" Basic.Settings.Hotkeys.Pair="'%1'-rekin egindako tekla konbinazioek txandakatze moduan jokatzen dute" +Basic.Settings.Hotkeys.Filter="Iragazkia" Basic.Hotkeys.SelectScene="Aldatu eszenara" @@ -737,11 +798,11 @@ Hotkeys.Windows="Windows" Hotkeys.Super="Super" Hotkeys.Menu="Menua" Hotkeys.Space="Zuriunea" -Hotkeys.NumpadNum="Zenb-teklatua %1" +Hotkeys.NumpadNum="Zenbaki-teklatua %1" Hotkeys.NumpadMultiply="Zenb-teklatuko biderketa" -Hotkeys.NumpadDivide="Zenb-teklatuaren Zatiketa" +Hotkeys.NumpadDivide="Zenbaki-teklatuaren zatiketa" Hotkeys.NumpadAdd="Zenb-teklatuaren gehiketa" -Hotkeys.NumpadSubtract="Zenb-teklatuaren kenketa" +Hotkeys.NumpadSubtract="Zenbaki-teklatuaren kenketa" Hotkeys.NumpadDecimal="Zenb-teklatuaren hamartarra" Hotkeys.AppleKeypadNum="%1 (tekla)" Hotkeys.AppleKeypadMultiply="* (tekla)" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (tekla)" Hotkeys.AppleKeypadDecimal=". (tekla)" Hotkeys.AppleKeypadEqual="= (tekla)" Hotkeys.MouseButton="Sagua %1" +Hotkeys.Escape="Esc" Mute="Mututu" Unmute="Ez mututu" @@ -762,7 +824,7 @@ SceneItemHide="Ezkutatu '%1'" OutputWarnings.NoTracksSelected="Gutxienez pista bat hautatu behar duzu" OutputWarnings.MultiTrackRecording="Oharra: Zenbait formatuk (esaterako FLV-k) ez ditu pista anitzak onartzen grabazioan" -OutputWarnings.MP4Recording="Kontuz: MP4 formatuz gordetako grabazioak izan daitezke berreskuraezinak fitxategia ezin bada bukatu (esate baterako energia etenagatik). Hainbat audio pista grabatu nahi baduzu erabil dezakezu MKV formatua eta mp4 bihurtu grabazioa bukatu ondoren (Fitxategia->Bihurtu grabazioak)" +OutputWarnings.MP4Recording="Kontuz: MP4 formatuz gordetako grabazioak izan daitezke berreskuraezinak fitxategia ezin bada bukatu (esate baterako BSODs-ren emaitza bat, energia etenak eta abar). Hainbat audio pista grabatu nahi baduzu erabil dezakezu MKV formatua eta mp4 bihurtu grabazioa bukatu ondoren (Fitxategia->Bihurtu grabazioak)" FinalScene.Title="Ezabatu eszena" FinalScene.Text="Gutxienez eszena bat egon behar du." @@ -770,9 +832,24 @@ FinalScene.Text="Gutxienez eszena bat egon behar du." NoSources.Title="Iturbururik ez dago" NoSources.Text="Badirudi ez duzula gehitu bideo iturbururik oraindik, beraz emaitza pantaila huts bat izango da. Ziur zaude hau egin nahi duzula?" NoSources.Text.AddSource="Gehitzen ahal duzu iturburuak Iturburuak kutxako azpiko aldeko + ikonoa klikatuz edozein unetan." +NoSources.Label="Ez duzu iturbururik aukeratu.\nEgin klik beheko + botoian,\nedo eskuin klik bat gehitzeko." ChangeBG="Ezarri kolorea" CustomColor="Kolore pertsonalizatua" BrowserSource.EnableHardwareAcceleration="Gaitu nabigatzailearen iturburuko hardware azelerazioa" +About="Honi buruz" +About.Info="OBS Studio bideoa grabazioak eta zuzeneko transmisioak egiteko software libreko doako aplikazioa da." +About.Donate="Egin diru ekarpen bat" +About.GetInvolved="Parte hartu" +About.Authors="Egileak" +About.License="Lizentzia" +About.Contribute="Sostengatu OBS proiektua" + +ResizeOutputSizeOfSource="Irteerari tamaina aldatu (iturburuaren tamaina)" +ResizeOutputSizeOfSource.Text="Oinarrizko eta irteerako bereizmena uneko iturriaren tamainara egokituko da." +ResizeOutputSizeOfSource.Continue="Jarraitu nahi duzu?" + +PreviewTransition="Aurreikusi trantsizioa" + diff --git a/UI/data/locale/fa-IR.ini b/UI/data/locale/fa-IR.ini index 8593961..210ddaf 100644 --- a/UI/data/locale/fa-IR.ini +++ b/UI/data/locale/fa-IR.ini @@ -1,4 +1,6 @@ +Language="انگلیسی" +Region="ایالات متحده" OK="باشه" Apply="اعمال تغییرات" @@ -48,19 +50,66 @@ Enable="فعال کردن" DisableOSXVSync="غیرفعال کردن OSX V-Sync" ResetOSXVSyncOnExit="تنظیم مجدد OSX V-Sync هنگام خروج" HighResourceUsage="کد گذاری بیش از حد ! توجه کنید که تنظیمات ویدئویی را تغییر بدهید یا از یک پریست کد گذاری سریع تر استفاده کنید ." +Transition="انتقال" +QuickTransitions="جا به جایی سریع" +Left="چپ" +Right="راست" +Top="بالا" +Bottom="پایین" +Reset="تنظیم مجدد" +Hours="ساعت" +Minutes="دقیقه" +Seconds="ثانیه" +Deprecated="منسوخ شده" +Import="وارد کردن" +Export="خروجی گرفتن" +Copy="کپی" +Paste="جای گذاری" +Next="بعدی" +Back="قبلی" +Defaults="پیش فرض ها" +None="هیچ‌کدام" +StudioMode.Preview="پیش نمایش" +StudioMode.Program="برنامه" +ShowInMultiview="نمایش در چندپنجره" +VerticalLayout="چیدمان عمودی" +Group="گروه" +DoNotShowAgain="دوباره نشان داده نشود" + +AlreadyRunning.Title="OBS از قبل در حال اجراست" +AlreadyRunning.Text="OBS از قبل در حال اجراست! در صورتی که به صورت عمد این کار را کرده اید، لطفاً قبل از اجرای یک نمونه جدید سایر نمونه های باز شده‌ی OBS را ببندید. اگر OBS را در حالت کوچک کردن در system try قرار داده اید، لطفاً چک کنید که آیا در آن جا هنوز در حال اجراست." +AlreadyRunning.LaunchAnyway="در هر حال اجرا کن" +Auth.Chat="چت" +Auth.StreamInfo="اطلاعات پخش زنده" +TwitchAuth.Stats="وضعیت توییچ" + +Copy.Filters="کپی فیلتر ها" +Paste.Filters="بازنشانی فیلتر ها" +BandwidthTest.Region="منطقه" +BandwidthTest.Region.US="ایالات متحده" +BandwidthTest.Region.EU="اروپا" +BandwidthTest.Region.Asia="آسیا" +BandwidthTest.Region.Other="سایر" +Basic.FirstStartup.RunWizard="آیا مایل به اجرای پیکربندی-خودکار هستید؟ شما همچنین می‌توانید تنظیمات خود را با کلیک بر روی دکمه تنظیمات در پنجره اصلی به صورت دستی پیکربندی کنید." +Basic.FirstStartup.RunWizard.NoClicked="اگر نظر شما تغییر کرد، می توانید پیکربندی-خودکار را در هر زمانی از منوی ابزار اجرا کنید." + +Basic.AutoConfig.ApplySettings="اعمال تنظیمات" +Basic.AutoConfig.StartPage="اطلاعات نحوه استفاده" +Basic.AutoConfig.StartPage.SubTitle="تعیین کنید که از برنامه برای چه کاری می‌خواهید استفاده کنید" Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="استفاده از فعلی (%1x%2)" Basic.AutoConfig.VideoPage.BaseResolution.Display="صفحه نمایش %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="استفاده از فعلی (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="یا ۶۰ یا ۳۰ ، اما ۶۰ را ترجیح می دهم" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="یا ۶۰ یا ۳۰ ، اما وضوح بالا را ترجیح می دهم" -Basic.AutoConfig.VideoPage.CanvasExplanation="نکته : اندازه محیط (پایه) لزوما همان اندازه ای نیست که با آن پخش زنده یا ضبط می کنید . اندازه واقعی پخش زنده/ضبط شما ممکن است برای کاهش استفاده از منابع و یا میزان درخواست بیت بر ثانیه (بیت ریت) کمتر باشد ." +Basic.AutoConfig.VideoPage.CanvasExplanation="نکته : اندازه محیط (پایه) لزوما همان اندازه ای نیست که با آن پخش زنده یا ضبط می کنید . اندازه واقعی پخش زنده/ضبط شما ممکن است برای کاهش استفاده از منابع و یا میزان درخواست بیت بر ثانیه (بیت ریت) کمتر باشد ." Basic.AutoConfig.StreamPage="اطلاعات پخش زنده" Basic.AutoConfig.StreamPage.SubTitle="لطفا اطلاعات پخش زنده خود را وارد کنید" +Basic.AutoConfig.StreamPage.UseStreamKey="کلید پخش زنده" Basic.AutoConfig.StreamPage.Service="سرویس" Basic.AutoConfig.StreamPage.Service.ShowAll="نمایش همه..." Basic.AutoConfig.StreamPage.Server="سرور" @@ -68,21 +117,58 @@ Basic.AutoConfig.StreamPage.StreamKey="کلید پخش زنده" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(لینک)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="برآورد میزان بیت بر ثانیه (بیت ریت) با تست پهنای باند (ممکن است چند دقیقه طول بکشد)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="کد گذاری سخت افزاری را ترجیح می دهم" +Basic.AutoConfig.TestPage="نتایج نهایی" +Basic.Stats.CPUUsage="میزان استفاده CPU" +Basic.Stats.MemoryUsage="میزان استفاده حافظه" +Basic.Stats.AverageTimeToRender="متوسط زمان ارائه فریم" +Basic.Stats.Output.Stream="پخش جریانی" +Basic.Stats.Output.Recording="درحال ضبط" +Basic.Stats.Status="وضعیت" +Basic.Stats.Status.Recording="درحال ضبط" +Basic.Stats.Status.Live="زنده" +Basic.Stats.Status.Reconnecting="اتصال مجدد" +Basic.Stats.Status.Inactive="غیر فعال" +Basic.Stats.DroppedFrames="فریم های از دست رفته (شبکه)" +Basic.Stats.MegabytesSent="مجموع خروجی داده ها" +Basic.Stats.Bitrate="نرخ بیت" +Updater.Title="بروزرسانی جدید موجود است" +Updater.Text="نسخه جدیدی در دسترس است:" +Updater.UpdateNow="اکنون بروزرسانی شود" +Updater.RemindMeLater="بعدا یادآوری کن" +Updater.NoUpdatesAvailable.Title="بروزرسانی موجود نیست" +Updater.NoUpdatesAvailable.Text="در حال حاظر بروزرسانی در دسترس نیست" +Updater.FailedToLaunch="اجرای بروزرسانی کننده ناموفق بود" +Basic.TransitionDuration="مدت زمان" +Basic.TogglePreviewProgramMode="حالت استودیو" +TitleBar.Profile="پروفایل" +NameExists.Title="نام از قبل وجود دارد" +NameExists.Text="نام از قبل در حال استفاده است." +NoNameEntered.Title="لطفاً یک نام معتبر وارد کنید" +NoNameEntered.Text="شما نمی توانید از نام های خالی استفاده کنید." +ConfirmStart.Title="شروع استریم؟" +ConfirmStart.Text="آیا مطمئنید که می‌خواهید استریم را شروع کنید؟" +ConfirmStop.Title="قطع استریم؟" +ConfirmStop.Text="آیا مطمئنید که می‌خواهید استریم را قطع کنید؟" +ConfirmExit.Title="خروج از OBS؟" +ConfirmExit.Text="OBS در حال حاظر فعال است. تمامی استریم/ضبط ها قطع خاموش خواهند شد. آیا مطمئنید که می‌خواهید خارج شوید؟" +ConfirmRemove.Title="تایید حذف" +Output.StartStreamFailed="شروع استریم ناموفق بود" +Output.StartRecordingFailed="شروع ضبط ناموفق بود" @@ -90,8 +176,13 @@ Basic.AutoConfig.StreamPage.PreferHardwareEncoding="کد گذاری سخت اف +Remux.FileExistsTitle="فایل های مورد نظر وجود دارند" +Remux.FileExists="فایل های زیر از قبل وجود دارند. آیا می‌خوهید آن‌ها را جایگزین کنید؟" +UpdateAvailable="بروزرسانی جدید در دسترس است" +Basic.DesktopDevice1="صدای دسکتاپ" +Basic.DesktopDevice2="صدای دسکتاپ 2" @@ -103,17 +194,30 @@ Basic.AutoConfig.StreamPage.PreferHardwareEncoding="کد گذاری سخت اف +AddProfile.Title="افزودن پروفایل" +RenameProfile.Title="تغییر نام پروفایل" +Basic.PropertiesWindow.SelectColor="انتخاب رنگ" +Basic.PropertiesWindow.SelectFont="انتخاب فونت" +Basic.PropertiesWindow.ConfirmTitle="تنظیمات تغییر یافت" +Basic.PropertiesWindow.Confirm="تغییرات ذخیره نشده‌ای وجود دارند، آیا می‌خواهید آن‌ها را نگه دارید؟" +Basic.PropertiesWindow.AddFiles="افزودن فایل ها" +Basic.PropertiesWindow.AddDir="افزودن پوشه" +Basic.PropertiesWindow.AddURL="اضافه کردن مسیر/آدرس اینترنتی" +Basic.Filters="فیلتر ها" +Basic.Filters.AsyncFilters="فلیتر های صوتی/ویدیویی" +Basic.Filters.AudioFilters="فیلتر های صوتی" +Basic.TransformWindow.Size="اندازه" @@ -144,5 +248,13 @@ Basic.AutoConfig.StreamPage.PreferHardwareEncoding="کد گذاری سخت اف + + + + + + + +ResizeOutputSizeOfSource.Continue="آیا مایلید ادامه دهید؟" diff --git a/UI/data/locale/fi-FI.ini b/UI/data/locale/fi-FI.ini index 8e72cbc..5e2d700 100644 --- a/UI/data/locale/fi-FI.ini +++ b/UI/data/locale/fi-FI.ini @@ -68,7 +68,7 @@ Copy="Kopioi" Paste="Liitä" PasteReference="Liitä (viite)" PasteDuplicate="Liitä (Kopio)" -RemuxRecordings="Muunna tallenteet" +RemuxRecordings="Muunna tallenteita" Next="Seuraava" Back="Edellinen" Defaults="Oletukset" @@ -80,14 +80,38 @@ StudioMode.Program="Ohjelma" ShowInMultiview="Näytä moninäkymässä" VerticalLayout="Pystynäkymä" Group="Ryhmitä" +DoNotShowAgain="Älä näytä uudestaan" +Default="(Oletus)" +Calculating="Lasketaan..." AlreadyRunning.Title="OBS on jo käynnissä" AlreadyRunning.Text="OBS on jo käynnissä! Ellet tarkoittanut tehdä näin, ole hyvä ja sulje aikaisemmat OBS-prosessit ennen uuden käynnistämistä. Jos olet asettanut OBS:n pienentymään ilmaisinalueelle, varmista ettei se ole siellä yhä päällä." AlreadyRunning.LaunchAnyway="Käynnistä joka tapauksessa" +DockCloseWarning.Title="Telakoitu ikkuna suljettu" +DockCloseWarning.Text="Suljit juuri telakoidun ikkunan. Jos haluat sen takaisin näkyviin, löydät sen Näkymät → Telakat -valikosta työkaluriviltä." + +Auth.Authing.Title="Todennetaan..." +Auth.Authing.Text="Todennetaan %1, ole hyvä ja odota..." +Auth.AuthFailure.Title="Varmennusvirhe" +Auth.AuthFailure.Text="Varmennus epäonnistui %1:n kanssa:\n\n%2: %3" +Auth.InvalidScope.Title="Varmennus vaaditaan" +Auth.InvalidScope.Text="Todennus vaatimukset %1:iin ovat muuttuneet. Jotkin ominaisuuksista eivät välttämättä ole käytössä." +Auth.LoadingChannel.Title="Ladataan kanavan tietoja..." +Auth.LoadingChannel.Text="Ladataan kanavan tietoja %1:stä, ole hyvä ja odota..." +Auth.ChannelFailure.Title="Kanavan lataus epäonnistui" +Auth.ChannelFailure.Text="Kanavan tietojen lataaminen epäonnistui %1:sta\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Lähetyksen tiedot" +TwitchAuth.Stats="Twitch-tilastot" +TwitchAuth.Feed="Twitch tapahtumasyöte" + Copy.Filters="Kopioi suodattimet" Paste.Filters="Liitä suodattimet" +BrowserPanelInit.Title="Valmistellaan selainta..." +BrowserPanelInit.Text="Valmistellaan selainta, ole hyvä ja odota..." + BandwidthTest.Region="Alue" BandwidthTest.Region.US="Yhdysvallat" BandwidthTest.Region.EU="Eurooppa" @@ -95,11 +119,9 @@ BandwidthTest.Region.Asia="Aasia" BandwidthTest.Region.Other="Muu" Basic.FirstStartup.RunWizard="Haluatko määrittää asetukset automaattisesti? Voit myös määrittää asetukset käsin painamalla \"Asetukset\" -painiketta päänäkymässä." -Basic.FirstStartup.RunWizard.BetaWarning="(Huomautus: automaattinen määritystoiminto on tällä hetkellä beta)" Basic.FirstStartup.RunWizard.NoClicked="Jos muutat mielesi, voit käynnistää automaattisen määritystoiminnon milloin tahansa \"Työkalut\" -valikosta." Basic.AutoConfig="Automaattinen määritystoiminto" -Basic.AutoConfig.Beta="Automaattinen määritystoiminto (Beta)" Basic.AutoConfig.ApplySettings="Ota käyttöön" Basic.AutoConfig.StartPage="Käyttötiedot" Basic.AutoConfig.StartPage.SubTitle="Määrittele kuinka haluat käyttää ohjelmaa" @@ -115,8 +137,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Joko 60 tai 30, mutta suositaan su Basic.AutoConfig.VideoPage.CanvasExplanation="Huomautus: Piirtoalueen resoluutio ei välttämättä ole sama kuin resoluutio jolla lähetetään tai tallennetaan. Lähetyksen/tallennuksen resoluutio saatetaan skaalata piirtoalueesta pienemmäksi resurssien käytön vähentämiseksi tai bitrate vaatimusten vuoksi." Basic.AutoConfig.StreamPage="Lähetyksen tiedot" Basic.AutoConfig.StreamPage.SubTitle="Ole hyvä ja syötä lähetyksen tiedot" +Basic.AutoConfig.StreamPage.ConnectAccount="Yhdistä tili (valinnainen)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Katkaise yhteys tiliin" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Katkaise yhteys tiliin?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Tämä muutos tulee voimaan välittömästi. Oletko varma että haluat katkaista yhteyden tiliin?" +Basic.AutoConfig.StreamPage.UseStreamKey="Käytä striimiavainta" Basic.AutoConfig.StreamPage.Service="Palvelu" Basic.AutoConfig.StreamPage.Service.ShowAll="Näytä kaikki..." +Basic.AutoConfig.StreamPage.Service.Custom="Mukautettu..." Basic.AutoConfig.StreamPage.Server="Palvelin" Basic.AutoConfig.StreamPage.StreamKey="Striimiavain" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Linkki)" @@ -159,6 +187,10 @@ Basic.Stats.Status.Inactive="Ei käytössä" Basic.Stats.DroppedFrames="Pudotettuja frameja (verkko)" Basic.Stats.MegabytesSent="Datan ulostulo yhteensä" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Levy täynnä ajassa (arvio)" + +ResetUIWarning.Title="Haluatko varmasti nollata käyttöliittymän?" +ResetUIWarning.Text="Käyttöliittymän nollaus piilottaa lisätyt telakat. Sinun täytyy laittaa telakat näkyviin \"Näkymät\" -valikosta jos tahdot ne näkyviin.\n\nHaluatko varmasti nollata käyttöliittymän?" Updater.Title="Uusi päivitys on saatavilla" Updater.Text="Uusi päivitys on saatavilla:" @@ -171,7 +203,7 @@ Updater.NoUpdatesAvailable.Title="Päivityksiä ei ole saatavilla" Updater.NoUpdatesAvailable.Text="Päivityksiä ei ole tällä hetkellä saatavilla" Updater.FailedToLaunch="Päivittäjän käynnistäminen epäonnistui" Updater.GameCaptureActive.Title="Game capture on aktiivinen" -Updater.GameCaptureActive.Text="Game capture -kirjasto on yhä käytössä. Sulje kaikki pelit/ohjelmat, joita on kaapattu tai käynnistä tietokone uudelleen." +Updater.GameCaptureActive.Text="Game capture -kirjasto on yhä käytössä. Sulje kaikki pelit/ohjelmat, joita on kaapattu (tai käynnistä Windows uudelleen) ja yritä uudelleen." QuickTransitions.SwapScenes="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen" QuickTransitions.SwapScenesTT="Vaihda esikatselu- ja ulostulo-skenet siirtymän jälkeen (jos ulostulon alkuperäinen skene on yhä olemassa).\nTämä ei peruuta muutoksia joita on tehty alkuperäiseen skeneen." @@ -206,8 +238,11 @@ ConfirmStart.Text="Haluatko varmasti aloittaa lähetyksen?" ConfirmStop.Title="Pysäytä lähetys?" ConfirmStop.Text="Haluatko varmasti pysäyttää lähetyksen?" +ConfirmBWTest.Title="Aloita kaistan nopeustesti?" +ConfirmBWTest.Text="OBS on asetettu kaistan nopeustestitilaan. Tämä tila antaa sinun testata verkkoa ilman että kanava menee Live-tilaan. Kun olet valmis testauksen kanssa, sinun täytyy ottaa se pois käytöstä, jotta muut voivat nähdä lähetyksesi.\n\nHaluatko jatkaa?" + ConfirmExit.Title="Sulje OBS?" -ConfirmExit.Text="OBS on aktiivinen. Kaikki lähetykset/tallennukset suljetaan. Haluatko varmasti sulkea ohjelman?" +ConfirmExit.Text="OBS on aktiivinen. Kaikki lähetykset/tallennukset suljetaan. Haluatko varmasti sulkea ohjelman?" ConfirmRemove.Title="Vahvista poisto" ConfirmRemove.Text="Haluatko varmasti poistaa '$1'?" @@ -218,13 +253,15 @@ Output.StartRecordingFailed="Tallennuksen aloittaminen epäonnistui" Output.StartReplayFailed="Toistopuskurin käynnistäminen epäonnistui" Output.StartFailedGeneric="Ulostulon käynnistäminen epäonnistui. Tarkista loki lisätietoja varten.\n\nHuomio: Jos käytät NVENC tai AMD -enkoodereita, varmista, että näytönohjaimen ajurit on päivitetty ajantasalle." + Output.ConnectFail.Title="Yhdistäminen epäonnistui" -Output.ConnectFail.BadPath="Viallinen polku tai yhteysosoite. Tarkista, että asetuksesi ovat kunnossa." +Output.ConnectFail.BadPath="Viallinen polku tai yhteysosoite. Tarkista, että asetuksesi ovat kunnossa." Output.ConnectFail.ConnectFailed="Palvelimelle yhdistäminen epäonnistui" Output.ConnectFail.InvalidStream="Kanavaa tai lähetysavainta ei voida käyttää. Tarkista lähetysavain varmuuden vuoksi. Jos se kuitenkin on oikein, vika saattaa olla yhdistettävässä palvelimessa." -Output.ConnectFail.Error="Odottamaton virhe ilmeni palvelimeen yhdistäessä. Lisää tietoa saat lokitiedostosta." +Output.ConnectFail.Error="Odottamaton virhe ilmeni palvelimeen yhdistäessä. Lisää tietoa saat lokitiedostosta." Output.ConnectFail.Disconnected="Yhteys palvelimeen katkaistiin." + Output.RecordFail.Title="Tallennuksen aloittaminen epäonnistui" Output.RecordFail.Unsupported="Ulostulon muoto ei ole tuettu tai se ei tue useampaa kuin yhtä ääniraitaa. Tarkista asetuksesi ja yritä uudelleen." Output.RecordNoSpace.Title="Liian vähän levytilaa" @@ -235,31 +272,29 @@ Output.ReplayBuffer.NoHotkey.Title="Pikanäppäintä ei ole asetettu!" Output.ReplayBuffer.NoHotkey.Msg="Tallennuksen pikanäppäintä ei ole asetettu toistopuskurille. Aseta \"Tallenna\"-pikanäppäin tallentaaksesi uusinnat." Output.BadPath.Title="Viallinen tiedostopolku" -Output.BadPath.Text="Asetettu tiedostopolku on viallinen. Tarkista asetuksistasi, että tiedostopolku on asetettu oikein." +Output.BadPath.Text="Asetettu tiedostopolku on viallinen. Tarkista asetuksistasi, että tiedostopolku on asetettu oikein." LogReturnDialog="Lokitiedoston lähetys onnistui" LogReturnDialog.CopyURL="Kopioi osoite" LogReturnDialog.ErrorUploadingLog="Lokitiedoston lähetyksessä tapahtui virhe" -LicenseAgreement="Käyttöoikeussopimus" -LicenseAgreement.PleaseReview="Lukaise lisenssin ehdot ennen kuin käytät OBS-ohjelmistoa. Käyttämällä tätä ohjelmaa tunnustat, että olet lukenut ja hyväksynyt GNU General Public License v2.0 ehdot. Vieritä alas nähdäksesi loput sopimuksesta." -LicenseAgreement.ClickIAgreeToContinue="Jos hyväksyt sopimuksen ehdot, klikkaa 'Hyväksyn' jatkaaksesi. Sinun täytyy hyväksyä sopimus käyttääksesi OBS-ohjelmistoa." -LicenseAgreement.IAgree="Hyväksyn" -LicenseAgreement.Exit="Sulje" - Remux.SourceFile="OBS-tallenne" Remux.TargetFile="Kohdetiedosto" Remux.Remux="Muunna" +Remux.Stop="Pysäytä muuntaminen" +Remux.ClearFinished="Poista valmistuneet kohteet" +Remux.ClearAll="Poista kaikki kohteet" Remux.OBSRecording="OBS-tallenne" Remux.FinishedTitle="Muunto on valmistunut" Remux.Finished="Tallenne muunnettu" Remux.FinishedError="Tallenne on muunnettu, mutta tiedosto saattaa olla keskeneräinen" -Remux.SelectRecording="Valitse OBS-tallenne …" -Remux.SelectTarget="Valitse kohdetiedosto ..." -Remux.FileExistsTitle="Kohdetiedosto on jo olemassa" -Remux.FileExists="Kohdetiedosto on jo olemassa, haluatko korvata sen?" +Remux.SelectRecording="Valitse OBS-tallenne..." +Remux.SelectTarget="Valitse kohdetiedosto..." +Remux.FileExistsTitle="Kohdetiedostot ovat jo olemassa" +Remux.FileExists="Seuraavat tiedostot ovat jo olemassa. Haluatko ylikirjoittaa ne?" Remux.ExitUnfinishedTitle="Muunto on käynnissä" Remux.ExitUnfinished="Muunto ei ole valmis. Jos keskeytät nyt, kohdetiedostosta saattaa tulla käyttökelvoton.\nHaluatko varmasti pysäyttää muunnon?" +Remux.HelpText="Pudota tiedostoja tähän ikkunaan muuntaaksesi ne tai valitse tyhjä \"OBS-tallenne\" -sarake selataksesi tiedoston." UpdateAvailable="Uusi päivitys saatavilla" UpdateAvailable.Text="Versio %1.%2.%3 on nyt saatavilla. Lataa tästä" @@ -276,11 +311,14 @@ Basic.DisplayCapture="Monitori" Basic.Main.PreviewConextMenu.Enable="Näytä esikatselu" +Basic.Main.Preview.Disable="Poista esikatselu käytöstä" + ScaleFiltering="Asteikko suodatus" ScaleFiltering.Point="Piste" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Alue" Deinterlacing="Lomituksen poisto (Deinterlace)" Deinterlacing.Discard="Ohita" @@ -411,55 +449,57 @@ Basic.Main.Group="Ryhmitä %1" Basic.Main.GroupItems="Ryhmitä valitut lähteet" Basic.Main.Ungroup="Poista ryhmästä" -Basic.MainMenu.File="&Tiedosto" -Basic.MainMenu.File.Export="&Vie" -Basic.MainMenu.File.Import="T&uo" -Basic.MainMenu.File.ShowRecordings="Näytä &tallenteet" -Basic.MainMenu.File.Remux="Mu&unna tallenne" -Basic.MainMenu.File.Settings="&Asetukset" +Basic.MainMenu.File="Tiedosto (&F)" +Basic.MainMenu.File.Export="Vi&e" +Basic.MainMenu.File.Import="Tuo (&I)" +Basic.MainMenu.File.ShowRecordings="Näytä tallenteet (&R)" +Basic.MainMenu.File.Remux="&Muunna tallenne" +Basic.MainMenu.File.Settings="A&setukset" Basic.MainMenu.File.ShowSettingsFolder="Avaa asetuskansio" Basic.MainMenu.File.ShowProfileFolder="Avaa profiilikansio" -Basic.MainMenu.AlwaysOnTop="Aina &päällimmäisenä" -Basic.MainMenu.File.Exit="&Sulje" +Basic.MainMenu.AlwaysOnTop="&Aina päällimmäisenä" +Basic.MainMenu.File.Exit="Sulje (&X)" -Basic.MainMenu.Edit="&Muokkaa" -Basic.MainMenu.Edit.Undo="&Kumoa" -Basic.MainMenu.Edit.Redo="&Tee uudelleen" -Basic.MainMenu.Edit.UndoAction="Kum&oa $1" -Basic.MainMenu.Edit.RedoAction="T&ee uudelleen $1" +Basic.MainMenu.Edit="Muokkaa (&E)" +Basic.MainMenu.Edit.Undo="K&umoa" +Basic.MainMenu.Edit.Redo="Tee uudelleen (&R)" +Basic.MainMenu.Edit.UndoAction="K&umoa $1" +Basic.MainMenu.Edit.RedoAction="Tee uudelleen $1 (&R)" Basic.MainMenu.Edit.LockPreview="&Lukitse esikatselu" Basic.MainMenu.Edit.Scale="Esikatselun &skaalaus" Basic.MainMenu.Edit.Scale.Window="Skaalaa ikkunaan" Basic.MainMenu.Edit.Scale.Canvas="Kanvaasi (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Ulostulo (%1x%2)" -Basic.MainMenu.Edit.Transform="Muu&nna" -Basic.MainMenu.Edit.Transform.EditTransform="M&uokkaa muunnosta..." +Basic.MainMenu.Edit.Transform="Muunna (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Muokkaa muunnosta... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Kopioi muunnos" Basic.MainMenu.Edit.Transform.PasteTransform="Liitä muunnos" -Basic.MainMenu.Edit.Transform.ResetTransform="&Nollaa muunnos" +Basic.MainMenu.Edit.Transform.ResetTransform="Nollaa muunnos (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Kierrä 90 astetta myötäpäivään" Basic.MainMenu.Edit.Transform.Rotate90CCW="Kierrä 90 astetta vastapäivään" Basic.MainMenu.Edit.Transform.Rotate180="Kierrä 180 astetta" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Käännä &vaakatasossa" -Basic.MainMenu.Edit.Transform.FlipVertical="Käännä &pystytasossa" -Basic.MainMenu.Edit.Transform.FitToScreen="&Sovita ikkunaan" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Venytä ikkunaan" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Keskitä ikkunaan" -Basic.MainMenu.Edit.Order="&Järjestä" -Basic.MainMenu.Edit.Order.MoveUp="Siirrä &ylös" -Basic.MainMenu.Edit.Order.MoveDown="Siirrä &alas" -Basic.MainMenu.Edit.Order.MoveToTop="Siirrä &ylimmäksi" -Basic.MainMenu.Edit.Order.MoveToBottom="Siirrä &alimmaksi" -Basic.MainMenu.Edit.AdvAudio="&Äänen lisäominaisuudet" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Käännä vaakatasossa (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Käännä pystytasossa (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Sovita ikkunaan (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Venytä ikkunaan (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Keskitä ikkunaan (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Keskitä pystysuunnassa" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Keskitä vaakasuunnassa" +Basic.MainMenu.Edit.Order="Järjestä (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Siirrä ylös (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Siirrä alas (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Siirrä ylimmäksi (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Siirrä alimmaksi (&B)" +Basic.MainMenu.Edit.AdvAudio="Äänen lisäomin&aisuudet" -Basic.MainMenu.View="&Näkymät" +Basic.MainMenu.View="Näkymät (&V)" Basic.MainMenu.View.Toolbars="&Työkalurivit" Basic.MainMenu.View.Docks="Telakat" Basic.MainMenu.View.Docks.ResetUI="Palauta käyttöliittymä" Basic.MainMenu.View.Docks.LockUI="Lukitse käyttöliittymä" Basic.MainMenu.View.Toolbars.Listboxes="&Luetteluruudut" -Basic.MainMenu.View.SceneTransitions="&Skene-siirtymät" -Basic.MainMenu.View.StatusBar="&Tilapalkki" +Basic.MainMenu.View.SceneTransitions="Skene-siirtymät (&C)" +Basic.MainMenu.View.StatusBar="Tilapalkki (&S)" Basic.MainMenu.View.Fullscreen.Interface="Kokoruudun käyttöliittymä" Basic.MainMenu.SceneCollection="&Skene-kokoelma" @@ -471,25 +511,26 @@ Basic.MainMenu.SceneCollection.Export="Vie skene-kokoelma" Basic.MainMenu.Profile.Exists="Profiili on jo olemassa" Basic.MainMenu.SceneCollection.Exists="Skene-kokoelma on jo olemassa" -Basic.MainMenu.Tools="T&yökalut" +Basic.MainMenu.Tools="&Työkalut" -Basic.MainMenu.Help="&Apua" -Basic.MainMenu.Help.HelpPortal="&Apukeskus" -Basic.MainMenu.Help.Website="Käy &verkkosivulla" +Basic.MainMenu.Help="Apua (&H)" +Basic.MainMenu.Help.HelpPortal="A&pukeskus" +Basic.MainMenu.Help.Website="Käy verkkosivulla (&W)" Basic.MainMenu.Help.Discord="Liity &Discord-palvelimelle" Basic.MainMenu.Help.Logs="&Lokitiedostot" -Basic.MainMenu.Help.Logs.ShowLogs="&Näytä lokitiedostot" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Lähetä n&ykyinen lokitiedosto" -Basic.MainMenu.Help.Logs.UploadLastLog="Lähetä edellinen lokitiedosto" -Basic.MainMenu.Help.Logs.ViewCurrentLog="Näytä ny&kyinen loki" +Basic.MainMenu.Help.Logs.ShowLogs="Näytä lokitiedo&stot" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Lähetä nykyinen lokitiedosto (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="&Lähetä edellinen lokitiedosto" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Näytä nykyinen loki (&V)" Basic.MainMenu.Help.CheckForUpdates="Tarkista päivitykset" -Basic.MainMenu.Help.CrashLogs="&Kaatumisraportit" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Näytä kaatumisraportit" +Basic.MainMenu.Help.CrashLogs="Kaatumis&raportit" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Näytä kaatumi&sraportit" Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Lähetä kaatumisraportti" +Basic.MainMenu.Help.About="Tietoj&a" Basic.Settings.ProgramRestart="Ohjelma on käynnistettävä uudelleen, jotta asetukset tulevat voimaan." Basic.Settings.ConfirmTitle="Vahvista muutokset" -Basic.Settings.Confirm="Sinulla on tallentamattomia muutoksia. Tallennetaanko?" +Basic.Settings.Confirm="Sinulla on tallentamattomia muutoksia. Tallennetaanko?" Basic.Settings.General="Yleiset" Basic.Settings.General.Theme="Teema" @@ -514,8 +555,13 @@ Basic.Settings.General.SysTray="Ilmaisinalue" Basic.Settings.General.SysTrayWhenStarted="Pienennä ilmaisinalueelle käynnistyessä" Basic.Settings.General.SystemTrayHideMinimize="Pienennä aina tilapalkkiin tehtäväpalkin sijaan" Basic.Settings.General.SaveProjectors="Tallenna peilaus poistuessa" +Basic.Settings.General.Preview="Esikatselu" +Basic.Settings.General.OverflowHidden="Piilota ylivuoto" +Basic.Settings.General.OverflowAlwaysVisible="Näytä ylivuoto aina" +Basic.Settings.General.OverflowSelectionHidden="Näytä ylivuoto myös silloin kun lähde on näkymätön" Basic.Settings.General.SwitchOnDoubleClick="Siirtymä skeneen tuplaklikattaessa" Basic.Settings.General.StudioPortraitLayout="Ota pystyasettelu käyttöön" +Basic.Settings.General.TogglePreviewProgramLabels="Näytä esikatselu/ohjelma nimet" Basic.Settings.General.Multiview="Moninäkymä" Basic.Settings.General.Multiview.MouseSwitch="Klikkaa vaihtaaksesi skenejen välillä" Basic.Settings.General.Multiview.DrawSourceNames="Näytä skenejen nimet" @@ -529,6 +575,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Vaakasuunta, ylh Basic.Settings.Stream="Lähetys" Basic.Settings.Stream.StreamType="Lähetystyyppi" +Basic.Settings.Stream.Custom.UseAuthentication="Käytä todennusta" +Basic.Settings.Stream.Custom.Username="Käyttäjätunnus" +Basic.Settings.Stream.Custom.Password="Salasana" +Basic.Settings.Stream.BandwidthTestMode="Ota kaistan nopeustestitila käyttöön" Basic.Settings.Output="Ulostulo" Basic.Settings.Output.Format="Tallennuksen muoto" @@ -544,7 +594,7 @@ Basic.Settings.Output.UseReplayBuffer="Ota toistopuskuri käyttöön" Basic.Settings.Output.ReplayBuffer.SecondsMax="Uusinnan pisin aika (Sekunteina)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Muistiraja (Megatavuja)" Basic.Settings.Output.ReplayBuffer.Estimate="Arvioitu muistinkäyttö: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Muistin käyttöä ei voida arvioida. Valitse muistiraja." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Muistin käyttöä ei voida arvioida. Valitse muistiraja." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Huomio: Varmista että toistopuskurin pikanäppäin on asetettuna asetuksista)" Basic.Settings.Output.ReplayBuffer.Prefix="Toistopuskurin tiedostonimen etuliite" Basic.Settings.Output.ReplayBuffer.Suffix="Pääte" @@ -560,7 +610,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Varoitus: Tallentaminen lähetyksest Basic.Settings.Output.Simple.Warn.Lossless="Varoitus: Häviötön laatu luo järjettömän kokoisia tiedostoja! Häviötön laatu saattaa käyttää jopa 7 gigatavua levytilastasi minuutissa, mikäli käytät suuria resoluutioita ja korkeita FPS-arvoja. Häviötöntä pakkausta ei suositella pitkiin tallennuksiin ellei sinulla ole todella paljon tallennustilaa käytettävissäsi." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Haluatko varmasti käyttää häviötöntä laatua?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Häviötön laatu!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Varoitus: Et voi käyttää useampaa QSV-enkooderia lähettäessä ja tallentaessa samaan aikaan. Jos haluat tehdä molempia yhtä aikaa, vaihda lähetys tai tallennus-enkooderi." Basic.Settings.Output.Simple.Encoder.Software="Ohjelmistopohjainen (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Laitteistopohjainen (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Laitteisto (AMD)" @@ -572,7 +621,7 @@ Basic.Settings.Output.Reconnect="Automaattinen uudelleenyhdistys" Basic.Settings.Output.RetryDelay="Uudelleenyrityksen viive (sekunteja)" Basic.Settings.Output.MaxRetries="Uudelleenyhdistyksien määrä" Basic.Settings.Output.Advanced="Käytä enkooderin lisäasetuksia" -Basic.Settings.Output.EncoderPreset="Enkooderin asetus (hitaampi asetus lisää suorittimen käyttöä)" +Basic.Settings.Output.EncoderPreset="Enkooderin esiasetus" Basic.Settings.Output.CustomEncoderSettings="Valinnaiset enkooderin asetukset" Basic.Settings.Output.CustomMuxerSettings="Valinnaiset muuntajan asetukset" Basic.Settings.Output.NoSpaceFileName="Luo tiedostonimi ilman välilyöntejä" @@ -619,23 +668,23 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Näytä kaikki koodekit (my FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY vuosi, neljä numeroa\n%YY Vuosi, kaksi viimeistä numeroa (00-99)\n%MM Kuukausi, kymmenlukuna (01-12) \n%DD Päivä, nolla-etuliitteellä (01-31)\n%hh Tunti, 24-tunnin muodossa (00-23)\n%mm Minuutti (00-59) \n%ss Sekunti (00-61) \n%% %-merkki\n%a Lyhennetty viikonpäivän nimi\n%A Täysi viikonpäivän nimi\n%b Lyhennetty kuukauden nimi\n%B Täysi kuukauden nimi\n%d Kuukauden päivä, nolla-etuliitteellä (01-31)\n%H Tunti, 24-tunnin muodossa (00-23) \n%I Tunti, 12-tunnin muodossa (01-12)\n%m Kuukausi, kymmenlukuna (01-12)\n%M Minuutti (00-59) \n%p AM tai PM merkintä\n%S Sekunti (00-61)\n%y Vuosi, kaksi viimeistä numeroa (00-99)\n%Y Vuosi\n%z ISO 8601 standardin mukainen ajan esittämistapa, UTC tai aikavyöhykkeestä\n Nimi tai lyhennne\n%Z Aikavyöhykkeen nimi tai lyhenne\n" +FilenameFormatting.TT="%CCYY Vuosi, neljä numeroa\n%YY Vuosi, kaksi viimeistä numeroa (00-99)\n%MM Vuosi desimaalilukuna (01-12)\n%DD Päivä, nolla-etuliitteellä (01-31)\n%hh Tunti 24-tunnin muodossa (00-23)\n%mm Minuutti (00-59)\n%ss Sekunti (00-61)\n%% %-merkki\n%a Viikonpäivä lyhennettynä\n%A Viikonpäivä\n%b Lyhennetty kuukausi\n%B Kuukausi\n%d Päivä, nolla-etuliitteellä (01-31)\n%H Tunti 24-tunnin muodossa (00-23)\n%I Tunti 12-tunnin muodossa (01-12)\n%m Kuukausi desimaalilukuna (01-12)\n%M Minuutti (00-59)\n%p AM tai PM määritys\n%S Sekunti (00-61)\n%y Vuosi, kaksi viimeistä numeroa (00-99)\n%Y Vuosi\n%z ISO 8601 standardin mukainen ajan esittämistapa, UTC tai aikavyöhykkeestä\n%Z Aikavyöhykkeen nimi tai lyhenne\n" Basic.Settings.Video="Kuva" -Basic.Settings.Video.Adapter="Näytönohjain:" -Basic.Settings.Video.BaseResolution="Piirtoalueen resoluutio:" -Basic.Settings.Video.ScaledResolution="Ulostulon (skaalattu) resoluutio:" -Basic.Settings.Video.DownscaleFilter="Skaalaussuodatin:" +Basic.Settings.Video.Adapter="Näytönohjain" +Basic.Settings.Video.BaseResolution="Piirtoalueen resoluutio" +Basic.Settings.Video.ScaledResolution="Ulostulon (skaalattu) resoluutio" +Basic.Settings.Video.DownscaleFilter="Skaalaussuodatin" Basic.Settings.Video.DisableAeroWindows="Poista Aero käytöstä (Vain Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Yleiset FPS-arvot" Basic.Settings.Video.FPSInteger="Kokonaislukuinen FPS-arvo" Basic.Settings.Video.FPSFraction="Murtoluvullinen FPS-arvo" -Basic.Settings.Video.Numerator="Osoittaja:" -Basic.Settings.Video.Denominator="Nimittäjä:" -Basic.Settings.Video.Renderer="Renderoija:" -Basic.Settings.Video.InvalidResolution="Vialliset resoluution asetus. Muodon pitää olla [leveys]x[korkeus] (esim. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Kuvan ulostulo on tällä hetkellä käytössä. Kytke pois kaikki ulostulot vaihtaaksesi kuva-asetuksia." +Basic.Settings.Video.Numerator="Osoittaja" +Basic.Settings.Video.Denominator="Nimittäjä" +Basic.Settings.Video.Renderer="Renderoija" +Basic.Settings.Video.InvalidResolution="Vialliset resoluution asetus. Muodon pitää olla [leveys]x[korkeus] (esim. 1920x1080)" +Basic.Settings.Video.CurrentlyActive="Kuvan ulostulo on tällä hetkellä käytössä. Kytke pois kaikki ulostulot vaihtaaksesi kuva-asetuksia." Basic.Settings.Video.DisableAero="Poista Aero käytöstä" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (nopein, mutta epätarkka skaalattaessa)" @@ -645,7 +694,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Terävöity skaalaus, 32 Basic.Settings.Audio="Ääni" Basic.Settings.Audio.SampleRate="Näytteenottotaajuus" Basic.Settings.Audio.Channels="Kanavat" -Basic.Settings.Audio.MeterDecayRate="Äänimittarin putoamisnopeus" +Basic.Settings.Audio.Meters="Mittarit" +Basic.Settings.Audio.MeterDecayRate="Madaltumisnopeus" Basic.Settings.Audio.MeterDecayRate.Fast="Nopea" Basic.Settings.Audio.MeterDecayRate.Medium="Keskinopea (Tyyppi I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Hidas (Tyyppi II PPM)" @@ -653,19 +703,22 @@ Basic.Settings.Audio.PeakMeterType="Huippuarvo-mittarin tyyppi" Basic.Settings.Audio.PeakMeterType.SamplePeak="Huippuarvon näyte" Basic.Settings.Audio.PeakMeterType.TruePeak="Todellinen huippuarvo (Korkeampi CPU:n käyttö)" Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROITUS: Monikanavaääni on käytössä." -Basic.Settings.Audio.MultichannelWarning="Varmista lähettäessä että palvelu tukee sekä monikanavaäänen lähettämistä, että toistamista. Twitch, Facebook 360 Live, Mixer RTMP ja Smashcast ovat esimerkkejä palveluista joissa monikanavaääni on täysin tuettu. Vaikka Facebook Live ja YouTube Live hyväksyvät monikanavaäänen lähettämisen, Facebook Live miksaa äänen stereoksi ja YouTube Live toistaa vain kaksi kanavaa.\n\nOBS:n äänisuodattimet tukevat monikanavaääntä, mutta VST-liitännäiset eivät välttämättä tue." +Basic.Settings.Audio.MultichannelWarning="Varmista lähettäessä että palvelu tukee sekä monikanavaäänen lähettämistä, että toistamista. Twitch, Facebook 360 Live, Mixer RTMP ja Smashcast ovat esimerkkejä palveluista joissa monikanavaääni on täysin tuettu. Vaikka Facebook Live ja YouTube Live hyväksyvät monikanavaäänen lähettämisen, Facebook Live miksaa äänen stereoksi ja YouTube Live toistaa vain kaksi kanavaa.\n\nOBS:n äänisuodattimet tukevat monikanavaääntä, mutta VST-liitännäiset eivät välttämättä tue." Basic.Settings.Audio.MultichannelWarning.Title="Käytä monikanava-ääntä?" Basic.Settings.Audio.MultichannelWarning.Confirm="Haluatko varmasti käyttää monikanavaista ääntä?" +Basic.Settings.Audio.Devices="Laitteet" Basic.Settings.Audio.DesktopDevice="Äänentoistolaite" Basic.Settings.Audio.DesktopDevice2="Äänentoistolaite 2" Basic.Settings.Audio.AuxDevice="Mic/Aux -äänilaite" Basic.Settings.Audio.AuxDevice2="Mic/Aux -äänilaite 2" Basic.Settings.Audio.AuxDevice3="Mic/Aux -äänilaite 3" +Basic.Settings.Audio.AuxDevice4="Mic/Aux -äänilaite 4" Basic.Settings.Audio.EnablePushToMute="Ota Push-to-mute käyttöön" Basic.Settings.Audio.PushToMuteDelay="Push-to-muten viive" Basic.Settings.Audio.EnablePushToTalk="Ota Push-to-talk käyttöön" Basic.Settings.Audio.PushToTalkDelay="Push-to-talkin viive" Basic.Settings.Audio.UnknownAudioDevice="[Laitetta ei ole yhdistetty tai se ei ole saatavissa]" +Basic.Settings.Audio.Disabled="Pois käytöstä" Basic.Settings.Advanced="Lisäasetukset" Basic.Settings.Advanced.General.ProcessPriority="Prosessin prioriteetti" @@ -674,11 +727,11 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Suurempi kuin norma Basic.Settings.Advanced.General.ProcessPriority.Normal="Normaali" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Alle normaalin" Basic.Settings.Advanced.General.ProcessPriority.Idle="Pieni" -Basic.Settings.Advanced.FormatWarning="Varoitus: Muut kuin NV12 väriformaatit ovat tarkoitettuja tallentamiseen, eikä niitä suositella lähettämiseen. Väriformaation konversio saattaa johtaa korkeampaan suorittimen käyttöön lähettämisessä." +Basic.Settings.Advanced.FormatWarning="Varoitus: Muut kuin NV12 väriformaatit ovat tarkoitettuja tallentamiseen, eikä niitä suositella lähettämiseen. Väriformaation konversio saattaa johtaa korkeampaan suorittimen käyttöön lähettämisessä." Basic.Settings.Advanced.Audio.BufferingTime="Äänen puskurointiaika" Basic.Settings.Advanced.Video.ColorFormat="Väriformaatti" -Basic.Settings.Advanced.Video.ColorSpace="YUV väriavaruus" -Basic.Settings.Advanced.Video.ColorRange="YUV värialue" +Basic.Settings.Advanced.Video.ColorSpace="Väriavaruus" +Basic.Settings.Advanced.Video.ColorRange="Värialue" Basic.Settings.Advanced.Video.ColorRange.Partial="Osittainen" Basic.Settings.Advanced.Video.ColorRange.Full="Täysi" Basic.Settings.Advanced.Audio.MonitoringDevice="Äänen monitorointilaite" @@ -693,12 +746,13 @@ Basic.Settings.Advanced.Network.BindToIP="Liitä IP:seen" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Käytä uutta verkkokoodia" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Alhaisen latenssin tila" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Poista pikanäppäimet käytöstä, kun pääikkuna on aktiivisena" +Basic.Settings.Advanced.AutoRemux="Muunna automaattisesti mp4-muotoon" +Basic.Settings.Advanced.AutoRemux.MP4="(tallenna mkv-muotoon)" Basic.AdvAudio="Äänen lisäominaisuudet" Basic.AdvAudio.Name="Nimi" -Basic.AdvAudio.Volume="Äänenvoimakkuus (%)" Basic.AdvAudio.Mono="Miksaa yksikanavaiseksi" -Basic.AdvAudio.Panning="Balanssi" +Basic.AdvAudio.Balance="Balanssi" Basic.AdvAudio.SyncOffset="Synkronoinnin viivästys (ms)" Basic.AdvAudio.Monitoring="Äänen monitorointi" Basic.AdvAudio.Monitoring.None="Monitorointi pois" @@ -708,6 +762,7 @@ Basic.AdvAudio.AudioTracks="Raidat" Basic.Settings.Hotkeys="Pikanäppäimet" Basic.Settings.Hotkeys.Pair="Yhteiset näppäinyhdistelmät '%1':n kanssa toimivat 'togglena'" +Basic.Settings.Hotkeys.Filter="Suodatin" Basic.Hotkeys.SelectScene="Vaihda skeneen" @@ -751,6 +806,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Hiiren %1" +Hotkeys.Escape="Esc" Mute="Mykistä" Unmute="Poista mykistys" @@ -762,7 +818,7 @@ SceneItemHide="Piilota '%1'" OutputWarnings.NoTracksSelected="Sinun täytyy valita ainakin yksi raita" OutputWarnings.MultiTrackRecording="Varoitus: Jotkin muodot (kuten FLV), eivät tue useampaa raitaa per tallennus" -OutputWarnings.MP4Recording="Varoitus: MP4-muotoon tallentaessa tiedostoista tulee lukukelvottomia, mikäli niitä ei voi viimeistellä. (esim. johtuen BSOD:sta, sähkökatkosta jne.) Jos haluat tallentaa useampaa ääniraitaa, kannattaa käyttää MKV-muotoa ja muuntaa jälkikäteen MP4:ksi. (Tiedosto->Muunna tallenne)" +OutputWarnings.MP4Recording="Varoitus: MP4/MOV-muotoon tallentaessa tiedostoista tulee lukukelvottomia, mikäli niitä ei voi viimeistellä. (esim. johtuen BSOD:sta, sähkökatkosta jne.) Jos haluat tallentaa useampaa ääniraitaa, kannattaa käyttää MKV-muotoa ja muuntaa jälkikäteen MP4/MOV-muotoon. (Tiedosto → Muunna tallenteita)" FinalScene.Title="Poista skene" FinalScene.Text="Ainakin yksi skene pitää olla olemassa." @@ -770,9 +826,23 @@ FinalScene.Text="Ainakin yksi skene pitää olla olemassa." NoSources.Title="Ei lähteitä" NoSources.Text="Näyttää siltä ettet ole vielä lisännyt yhtään kuvalähdettä, joten kuva on musta. Haluatko varmasti tehdä näin?" NoSources.Text.AddSource="Voit lisätä lähteitä klikkaamalla \"+\"-kuvaketta \"Lähteet\"-alueen alapuolella." +NoSources.Label="Sinulla ei ole lähteitä.\nKlikkaa + painiketta alapuolella,\ntai klikkaa tästä hiiren oikealla painikkeella lisätäksesi yhden." ChangeBG="Aseta väri" CustomColor="Mukautettu väri" BrowserSource.EnableHardwareAcceleration="Käytä laitteistokiihdytystä \"Selain\"-lähteessä" +About="Tietoja" +About.Info="OBS Studio on ilmainen ja avoimen lähdekoodin ohjelmisto videotallennuksiin ja live-lähetyksiin." +About.Donate="Tee lahjoitus" +About.GetInvolved="Osallistu" +About.Authors="Tekijät" +About.License="Lisenssi" +About.Contribute="Tue OBS Projektia" + +ResizeOutputSizeOfSource="Muuta ulostulon kokoa (lähteen kokoon)" +ResizeOutputSizeOfSource.Text="Piirtoalueen ja ulostulon resoluutio muutetaan valitun lähteen kokoiseksi." +ResizeOutputSizeOfSource.Continue="Haluatko jatkaa?" + + diff --git a/UI/data/locale/fil-PH.ini b/UI/data/locale/fil-PH.ini index 80ec529..e71fbe5 100644 --- a/UI/data/locale/fil-PH.ini +++ b/UI/data/locale/fil-PH.ini @@ -83,9 +83,12 @@ AlreadyRunning.Title="Tumatakbo na ngayon ang OBS" AlreadyRunning.Text="Tumatakbo na ang OBS! Maliban na lamang kung gusto mong gawin ito, pakiusap patayin ang anomang nabubuhay na mga mungkahi ng OBS bago subukang magpatakbo ng panibagong mungkahi. Kung meron kang OBS set para mabawasan ang sistemang tray, pakiusap magsiyasat para makita kung ito ay tumatakbo parin." AlreadyRunning.LaunchAnyway="Maglunsad parin" + + Copy.Filters="Kopyahin ang mga panala" Paste.Filters="I-paste ang mga panala" + BandwidthTest.Region="Rehiyon" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" @@ -93,11 +96,9 @@ BandwidthTest.Region.Asia="Asya" BandwidthTest.Region.Other="Iba pa" Basic.FirstStartup.RunWizard="Gusto mo bang mapatakbo ang dalubhasa sa kusang pagkonpigurasyon? Maaari mo ring mano-manuhin ang pagkonpigura ng iyong settings sa pagpindot ng Settings button sa pangunahing window." -Basic.FirstStartup.RunWizard.BetaWarning="(Tandaan: Ang dalubhasang kusang pagkonpigurasyon ay kasalukuyang nasa beta)" Basic.FirstStartup.RunWizard.NoClicked="Kung magbabago ka ng isip mo, pwede mong patakbuhin ang dalubhasang kusang konpigurasyon anomang oras ulit mula sa mga kasangkapan sa menu." Basic.AutoConfig="Dalubhasang Kusang Konpigurasyon" -Basic.AutoConfig.Beta="Dalubhasang Kusang Konpigurasyon (Beta)" Basic.AutoConfig.ApplySettings="Ilapat ang mga Pagtatakda" Basic.AutoConfig.StartPage="Paggamit ng Impormasyon" Basic.AutoConfig.StartPage.SubTitle="Tukuyin ang tamang program na gusto mong gamitin" @@ -142,7 +143,6 @@ Basic.AutoConfig.TestPage.Result.Footer="Para sa pag gamit ng settings, pindutin Basic.Stats="Ang mga Statisktika" Basic.Stats.CPUUsage="Ang nagamit na CPU" -Basic.Stats.HDDSpaceAvailable="Ang magagamit na espasyo ng HDD" Basic.Stats.MemoryUsage="Ang nagamit na Memory" Basic.Stats.AverageTimeToRender="Ang average time para ma render ang frame" Basic.Stats.SkippedFrames="Laktawin ang frames dahil sa encoding lag" @@ -158,7 +158,8 @@ Basic.Stats.DroppedFrames="Naihulog na Frames (Network)" Basic.Stats.MegabytesSent="Ang total na Data Output" Basic.Stats.Bitrate="Bitrate" -Updater.Title="May bagong update na available" + +Updater.Title="Available ang bagong pag-update" Updater.Text="May bagong update na magagamit:" Updater.UpdateNow="Mag update ngayon" Updater.RemindMeLater="Paalalahanan mo ako mamaya" @@ -169,7 +170,6 @@ Updater.NoUpdatesAvailable.Title="Walang magagamit na mga update" Updater.NoUpdatesAvailable.Text="Walang mga update ang kasalukuyang magagamit" Updater.FailedToLaunch="Nabigong ilunsad ang updater" Updater.GameCaptureActive.Title="Kumuha ng laro na aktibo" -Updater.GameCaptureActive.Text="Kasalukuyang nakukuha sa library ang pagkuha ng hook library. Mangyaring isara ang anumang mga laro / programa na nakukuha (o i-restart ang mga bintana) at subukang muli." QuickTransitions.SwapScenes="Swap Preview / Output Scenes Pagkatapos Transitioning" QuickTransitions.SwapScenesTT="Mag swap ng mga preview at output scenes matapos ang transitioning (Kung may orihinal na output scene na umiiral).\nIto ay hindi pwede baguhin ang orihinal na eksena." @@ -204,6 +204,7 @@ ConfirmStart.Text="Sigurado ka ba na simulang ang pag stream?" ConfirmStop.Title="Itigil ba ang Steam?" ConfirmStop.Text="Sigurado ka itigil ang pag i-stream?" + ConfirmExit.Title="Lumabas sa OBS?" ConfirmExit.Text="Ang OBS ay kasulukuyang aktibo. Lahat ng streams/recordings ay magsasara. Sigurado ka ba gusto mong mag exit?" @@ -216,6 +217,7 @@ Output.StartRecordingFailed="Bigong simulan ang pag record" Output.StartReplayFailed="Bigong simulang ang replay buffer" Output.StartFailedGeneric="Bigong simulang ang output. Pakitingnan ang talaan ng mga detalye.\n\nNote: kung ikaw ay gumagamit ng NVENC or AMD encoders, siguraduhin na nag video drivers ay naka update." + Output.ConnectFail.Title="Bigung kumunekta" Output.ConnectFail.BadPath="Hindi wasto ang Path or ang Connection URL. Pakitingnan ang settings para ma kumpirma na ito ay pwede." Output.ConnectFail.ConnectFailed="Bigong kumunekta sa serber" @@ -223,6 +225,7 @@ Output.ConnectFail.InvalidStream="Di maka pasok sa tinutukoy na channel or strea Output.ConnectFail.Error="Isang di-inaasahang error ng subukang kumunekta sa serber. Karagdagang impormasyon ay nasa log file." Output.ConnectFail.Disconnected="Nadiskonek mula sa serber." + Output.RecordFail.Title="Bigong simulang ang pag record" Output.RecordFail.Unsupported="Ang output format ay maaring di suportado or di sinusuportahan ang higit sa isang audio track. Pakitingnan ang iyong settings at simulan ulet." Output.RecordNoSpace.Title="Hindi sapat ang iyong espasyo" @@ -237,13 +240,7 @@ Output.BadPath.Text="Ang na configured na file output path ay di di-wasto. Pakit LogReturnDialog="Ang na i-uload na log ay tagumpay" LogReturnDialog.CopyURL="Kupyahin ang URL" -LogReturnDialog.ErrorUploadingLog="Error sa pag-upload ng log file" - -LicenseAgreement="Ang lisensya ng kasunduan" -LicenseAgreement.PleaseReview="Pakitingnan ang lisensya bago gumamit ng OBS. Sa pag gamit ng program, kinikilala mo na nabasa at sumasang-ayon ka sa mga tuntunin nito GNU General Public License v2.0. Maaaring mag scroll down para makita ang ibang bahagi ng kasunduan." -LicenseAgreement.ClickIAgreeToContinue="Kung iyong tinatanggap ang termino ng kasunuduan, pindutin ang I Agree to continue. Dapat sumang-ayon sa kasunduan sa pag-gamit ng OBS." -LicenseAgreement.IAgree="Sumasang-ayon Ako" -LicenseAgreement.Exit="Lumabas" +LogReturnDialog.ErrorUploadingLog="Error sa pag upload ng log file" Remux.SourceFile="Obs Recording" Remux.TargetFile="Target File" @@ -252,15 +249,11 @@ Remux.OBSRecording="OBS Recording" Remux.FinishedTitle="Tapos na ang Remuxing" Remux.Finished="Ang Recording remuxed" Remux.FinishedError="Ang Recording Remuxed, pero ang file ay hindi kumpleto" -Remux.SelectRecording="Pumuli ng OBS Recording…" -Remux.SelectTarget="Piliin ang gustong file …" -Remux.FileExistsTitle="Ang napiling file any umiiral na" -Remux.FileExists="Ang napiling file any umiiral na, gusto mo ba itong palitan?" Remux.ExitUnfinishedTitle="Ang remuxing ay naka progress" Remux.ExitUnfinished="Di pa tapos ang Remuxing, pag itigil ang render ang napiling file ay di magagamit.\nGusto mo bang huminto sa pag remuxing?" UpdateAvailable="May bagong update na available" -UpdateAvailable.Text="Ang Version %1.%2.%3 ay available na. Pindutin para i-download" +UpdateAvailable.Text="Ang Version %1.%2.%3 ay available na. Pindutin para i-download" Basic.DesktopDevice1="Ang Desktop Audio" Basic.DesktopDevice2="Ang Desktop Audio 2" @@ -274,6 +267,7 @@ Basic.DisplayCapture="Ang nakunan na display" Basic.Main.PreviewConextMenu.Enable="Ipakita muli ang Larawan" + ScaleFiltering="I-filter iskala" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilinear" @@ -408,9 +402,9 @@ Basic.Main.Group="Grupo %1" Basic.Main.GroupItems="I-grupo ang napiling mga aytem" Basic.Main.Ungroup="Alisin sa Grupo" -Basic.MainMenu.File="&Talaksan" -Basic.MainMenu.File.Export="&I-export" -Basic.MainMenu.File.Import="&Angkat" +Basic.MainMenu.File="Talaksan (&F)" +Basic.MainMenu.File.Export="I-&export" +Basic.MainMenu.File.Import="Angkat (&I)" Basic.MainMenu.File.ShowRecordings="Ipakita at Pag-&record" Basic.MainMenu.File.Remux="Re&mux Recordings" Basic.MainMenu.File.Settings="Mga &Setting" @@ -420,17 +414,17 @@ Basic.MainMenu.AlwaysOnTop="L&aging Nasa Tuktok" Basic.MainMenu.File.Exit="E&xit" Basic.MainMenu.Edit="I-&edit" -Basic.MainMenu.Edit.Undo="&Pawalang-bisa" -Basic.MainMenu.Edit.Redo="&Mag-redo" +Basic.MainMenu.Edit.Undo="Pawalang-bisa (&U)" +Basic.MainMenu.Edit.Redo="Mag-&redo" Basic.MainMenu.Edit.UndoAction="I-&undo ang $1" Basic.MainMenu.Edit.RedoAction="&Redo $1" -Basic.MainMenu.Edit.LockPreview="&I-preview ang I-preview" +Basic.MainMenu.Edit.LockPreview="I-preview ang I-preview (&L)" Basic.MainMenu.Edit.Scale="Preview &Scaling" Basic.MainMenu.Edit.Scale.Window="Scale to Window" Basic.MainMenu.Edit.Scale.Canvas="Kanbas (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)" Basic.MainMenu.Edit.Transform="&Transform" -Basic.MainMenu.Edit.Transform.EditTransform="&Baguhin ang Transform..." +Basic.MainMenu.Edit.Transform.EditTransform="Baguhin ang Transform... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Kopyahin ang Transform" Basic.MainMenu.Edit.Transform.PasteTransform="I-paste ang Transform" Basic.MainMenu.Edit.Transform.ResetTransform="I-&reset ang Transform" @@ -468,17 +462,17 @@ Basic.MainMenu.SceneCollection.Export="Magluwas ng Nakolektang Eksena" Basic.MainMenu.Profile.Exists="Ang Profile ay umiiral na ngayon" Basic.MainMenu.SceneCollection.Exists="Ang Nakolektang Eksena ay umiiral na ngayon" -Basic.MainMenu.Tools="&Mga Kasangkapan" +Basic.MainMenu.Tools="Mga Kasangkapan (&T)" -Basic.MainMenu.Help="&Tulong" -Basic.MainMenu.Help.HelpPortal="Tulong &lagusan" +Basic.MainMenu.Help="Tulong (&H)" +Basic.MainMenu.Help.HelpPortal="Tulong lagusan (&P)" Basic.MainMenu.Help.Website="Pagbisita &website" Basic.MainMenu.Help.Discord="Sumali sa &Discord Server" Basic.MainMenu.Help.Logs="Mag-&log ng mga File" -Basic.MainMenu.Help.Logs.ShowLogs="&ipakita ang Pag-log ng mga File" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Mag-upload &Kasalukuyang Mag-log ng File" -Basic.MainMenu.Help.Logs.UploadLastLog="Mag-upload &Huling pagla-log ng File" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Tignan ang Kasalukuyang pagla-log" +Basic.MainMenu.Help.Logs.ShowLogs="ipakita ang Pag-log ng mga File (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Mag-upload Kasalukuyang Mag-log ng File (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Mag-up&load Huling pagla-log ng File" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Tignan ang Kasalukuyang pagla-log (&V)" Basic.MainMenu.Help.CheckForUpdates="Magsiyasat para sa mga update" Basic.Settings.ProgramRestart="Ang mga programa ay dapat na-restart para sa mga maaapektuhan na setting." @@ -545,7 +539,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Babala: Ang pagrekord sa isang encode Basic.Settings.Output.Simple.Warn.Lossless="Babala: Hindi mawawalan ng kalidad ang bumubuo ng napakalaking malalaking sukat ng file! Maaaring gumamit ng walang humpay na kalidad ng hanggang 7 gigabytes ng puwang ng disk kada minuto sa mataas na resolution at framerates. Ang hindi nawawala ay hindi inirerekomenda para sa mahabang pag-record maliban kung mayroon kang isang napakalaking halaga ng disk space na magagamit." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sigurado ka bang gusto mong gumamit ng kalidad na walang pagkawala?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless quality warning!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Babala: Hindi ka maaaring gumamit ng maraming magkahiwalay na mga encoder ng QSV kapag nag-stream at nagre-record nang sabay. Kung nais mong i-stream at i-record nang sabay-sabay, mangyaring baguhin ang alinman sa encoder ng pag-record o stream encoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" @@ -557,7 +550,6 @@ Basic.Settings.Output.Reconnect="Awtomatikong mag-reconnect" Basic.Settings.Output.RetryDelay="Retry Delay (segundo)" Basic.Settings.Output.MaxRetries="Pinakamataas na Retries" Basic.Settings.Output.Advanced="Paganahin ang Mga Setting ng Advanced Encoder" -Basic.Settings.Output.EncoderPreset="Encoder Preset (mas mataas = mas CPU)" Basic.Settings.Output.CustomEncoderSettings="Mga Setting ng Custom Encoder" Basic.Settings.Output.CustomMuxerSettings="Mga Setting ng Custom Muxer" Basic.Settings.Output.NoSpaceFileName="Bumuo ng Pangalan ng File nang walang Space" @@ -619,7 +611,7 @@ Basic.Settings.Video.FPSFraction="Balyo ng Fractional FPS" Basic.Settings.Video.Numerator="Numerator" Basic.Settings.Video.Denominator="Denominator" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Ang Balyo ng resolusyong ay imbalido. Dapat ito [width]x[height] (i.e. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Ang Balyo ng resolusyong ay imbalido. Dapat ito [width]x[height] (i.e. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Ang kasulukuyang Bidyo output ay aktibo. Paki turn off ang anumang output para mabago ang bidyo settings." Basic.Settings.Video.DisableAero="Hindi paganahin ang Aero" @@ -630,7 +622,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened scaling, 32 mga Basic.Settings.Audio="Tunog" Basic.Settings.Audio.SampleRate="Halimbawa ng Antas" Basic.Settings.Audio.Channels="Mga Channel" -Basic.Settings.Audio.MeterDecayRate="Ang Audio Meter Decay Rate" Basic.Settings.Audio.MeterDecayRate.Fast="Pabilisin" Basic.Settings.Audio.MeterDecayRate.Medium="Katamtaman (Tipo I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Mabagal (Tipo II PPM)" @@ -638,11 +629,6 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Babala: Ang Surround sound aud Basic.Settings.Audio.MultichannelWarning="Kung nag streaming, paki tignan kung ang iyong streaming service ay parehong supportado ang surround sound ingest at surround sound playback. Twitch, Facebook, 360 Live, Mixer RTMP, Smashcast ay ang mga halimbawa kung saan ang surround sound ay ganap na suportado, pati YouTube Live umaandar lamang sa dawalang channels.\n\nOBS audio filters ay kompatibol lamang sa surround sound, pero hindi siguradong supportado ang VST plugin." Basic.Settings.Audio.MultichannelWarning.Title="Paganahin ang surround sound audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sigurado ka ba gusto mong paganahin ang surround sound audio?" -Basic.Settings.Audio.DesktopDevice="Ang Kagamitan sa Desktop Audio" -Basic.Settings.Audio.DesktopDevice2="Ang 2 Kagamitan sa Desktop Audio" -Basic.Settings.Audio.AuxDevice="Mic / Auxiliary Audio Device" -Basic.Settings.Audio.AuxDevice2="Mic / Auxiliary Audio Device 2" -Basic.Settings.Audio.AuxDevice3="Mic / Auxiliary Audio Device 3" Basic.Settings.Audio.EnablePushToMute="Paganahin ang Push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Push-to-mute delay" Basic.Settings.Audio.EnablePushToTalk="Paganahin ang Push-to-talk" @@ -659,11 +645,8 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Walang ginagawa" Basic.Settings.Advanced.FormatWarning="Babala: Ang mga format ng kulay maliban sa NV12 ay pangunahing inilaan para sa pag-record, at hindi inirerekomenda kapag nag-stream. Maaaring mapalawak ng streaming ang paggamit ng CPU dahil sa conversion ng format ng kulay." Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffering Time" Basic.Settings.Advanced.Video.ColorFormat="Format ng Kulay" -Basic.Settings.Advanced.Video.ColorSpace="Ang espasyong kulay ng YUV" -Basic.Settings.Advanced.Video.ColorRange="Ang saklaw ng kulay ng YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Bahagyang" Basic.Settings.Advanced.Video.ColorRange.Full="Buo" -Basic.Settings.Advanced.Audio.MonitoringDevice="Ang kagamitan para sa Audio Monitoring" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="I-Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Huwag paganahin ang Windows audio ducking" Basic.Settings.Advanced.StreamDelay="Ang Antala ng Stream" @@ -677,9 +660,7 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mababang latency mode" Basic.AdvAudio="Ang aria-arian ng Advanced Audio" Basic.AdvAudio.Name="Pangalan" -Basic.AdvAudio.Volume="Kalakasan (%)" Basic.AdvAudio.Mono="Downmix ito sa Mono" -Basic.AdvAudio.Panning="Ang Panning" Basic.AdvAudio.SyncOffset="Ang Sync Offset (ms)" Basic.AdvAudio.Monitoring="Ang subaybay ng Audio" Basic.AdvAudio.Monitoring.None="I-Off ang Monitor" @@ -743,7 +724,6 @@ SceneItemHide="Itago '%1'" OutputWarnings.NoTracksSelected="Dapat pumili ka ng kahit isang track" OutputWarnings.MultiTrackRecording="Babala: Tiyak na pormat (gaya ng FLV) hindi suportado ang maraming tracks kada recording" -OutputWarnings.MP4Recording="Babala: Ang Recording na naka-save sa MP4 ay hindi unrecoverable kung ang file any hindi tinapos (e.g bilang resulta nito BSODs, power losses, atbp.). Kung gusto mo i-record ng maraming audio tracks isaalang-alang ang paggamit ng MKV at remux ang recording para sa mp4 pagkatapos nitong matapos (File->Remux Recordings)" FinalScene.Title="Tanggaling ang Eksena" FinalScene.Text="Doon kailangan ng kahit isang eksena." @@ -751,3 +731,6 @@ FinalScene.Text="Doon kailangan ng kahit isang eksena." + + + diff --git a/UI/data/locale/fr-FR.ini b/UI/data/locale/fr-FR.ini index 0e12f98..74dce7b 100644 --- a/UI/data/locale/fr-FR.ini +++ b/UI/data/locale/fr-FR.ini @@ -23,11 +23,11 @@ Settings="Paramètres" Display="Affichage" Name="Nom" Exit="Quitter OBS" -Mixer="Mixage audio" +Mixer="Mixeur audio" Browse="Parcourir" Mono="Mono" Stereo="Stéréo" -DroppedFrames="Images perdues : %1 (%2%)" +DroppedFrames="Images perdues (réseau) : %1 (%2%)" StudioProgramProjector="Projecteur plein écran (programme)" PreviewProjector="Projecteur plein écran (aperçu)" SceneProjector="Projecteur plein écran (scène)" @@ -36,8 +36,8 @@ StudioProgramWindow="Projecteur fenêtré (programme)" PreviewWindow="Projecteur fenêtré (aperçu)" SceneWindow="Projecteur fenêtré (scène)" SourceWindow="Projecteur fenêtré (source)" -MultiviewProjector="Multivues (Plein écran)" -MultiviewWindowed="Multivues (Fenêtré)" +MultiviewProjector="Multi-aperçu (Plein écran)" +MultiviewWindowed="Multi-aperçu (Fenêtré)" Clear="Effacer" Revert="Annuler" Show="Afficher" @@ -47,9 +47,9 @@ Untitled="Sans nom" New="Nouveau" Duplicate="Dupliquer" Enable="Activer" -DisableOSXVSync="Désactiver le V-Sync d'OSX" -ResetOSXVSyncOnExit="Réinitialiser le V-Sync d'OSX en quittant" -HighResourceUsage="Encodage en surcharge ! Pensez à désactiver des paramètres vidéo ou à utiliser un préréglage d'encodage plus rapide." +DisableOSXVSync="Désactiver la synchronisation verticale de macOS" +ResetOSXVSyncOnExit="Réinitialiser la synchronisation verticale de macOS en quittant" +HighResourceUsage="Encodage en surcharge ! Pensez à revoir vos paramètres vidéo à la baisse ou utilisez un préréglage d'encodage plus rapide." Transition="Transition" QuickTransitions="Transitions rapides" Left="À gauche" @@ -72,62 +72,92 @@ RemuxRecordings="Convertir les enregistrements" Next="Suivant" Back="Retour" Defaults="Valeurs par défaut" -HideMixer="Cacher dans la table de mixage" +HideMixer="Cacher dans le mixeur" TransitionOverride="Forcer une transition" None="Aucune" StudioMode.Preview="Aperçu" StudioMode.Program="Programme" -ShowInMultiview="Montrer en Multivues" +ShowInMultiview="Afficher dans le multi-aperçu" VerticalLayout="Disposition Verticale" Group="Groupe" +DoNotShowAgain="Ne plus afficher" +Default="(Défaut)" +Calculating="Calcul en cours..." AlreadyRunning.Title="OBS est déjà en cours d'exécution" -AlreadyRunning.Text="OBS est déjà en cours d'exécution, merci de bien fermer toute autre instances existantes d'OBS avant d'en exécuter une nouvelle. Vérifiez dans votre barre d'état s'il n'est pas réduit et en cours d’exécution." +AlreadyRunning.Text="OBS est déjà en cours d'exécution. À moins que cela soit délibéré, veuillez quitter toute autre instance active d'OBS (y compris celles minimisées dans la zone de notifications) avant d'en ouvrir une nouvelle." AlreadyRunning.LaunchAnyway="Démarrer tout de même" +DockCloseWarning.Title="Fermer une fenêtre dockable" +DockCloseWarning.Text="Vous venez de fermer une fenêtre dockable. Si vous souhaitez l'afficher à nouveau, utilisez le menu Afficher → Docks dans la barre de menus." + +Auth.Authing.Title="Connexion en cours ..." +Auth.Authing.Text="Connexion sur %1 en cours, veuillez patienter ..." +Auth.AuthFailure.Title="Échec d'authentification" +Auth.AuthFailure.Text="Échec de l'authentification avec %1 :\n\n%2 : %3" +Auth.InvalidScope.Title="Authentification requise" +Auth.InvalidScope.Text="Les exigences d'authentification pour %1 ont changé. Certaines fonctionnalités peuvent être indisponibles." +Auth.LoadingChannel.Title="Chargement des informations de la Chaîne ..." +Auth.LoadingChannel.Text="Chargement des informations de la Chaîne sur %1, veuillez patienter ..." +Auth.ChannelFailure.Title="Échec du chargement de la chaîne" +Auth.ChannelFailure.Text="Échec du chargement des informations de la chaîne pour %1\n\n%2 : %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informations de la diffusion" +TwitchAuth.Stats="Statistiques de Twitch" +TwitchAuth.Feed="Flux d'activité Twitch" +TwitchAuth.TwoFactorFail.Title="Impossible de trouver la clé de stream" +TwitchAuth.TwoFactorFail.Text="OBS n'a pas pu se connecter à votre compte Twitch. Veuillez vous assurer que l'authentification à deux facteurs est configurée dans vos paramètres de sécurité Twitch car cela est nécessaire pour lancer un stream." + Copy.Filters="Copier les filtres" Paste.Filters="Coller les filtres" +BrowserPanelInit.Title="Initialisation du Navigateur ..." +BrowserPanelInit.Text="Initialisation du Navigateur, veuillez patienter ..." + BandwidthTest.Region="Région" BandwidthTest.Region.US="États-Unis" BandwidthTest.Region.EU="Europe" BandwidthTest.Region.Asia="Asie" BandwidthTest.Region.Other="Autre" -Basic.FirstStartup.RunWizard="Exécuter l'Assistant de configuration ? Vous pouvez configurer manuellement vos paramètres en cliquant sur le bouton des Paramètres situé dans la fenêtre principale." -Basic.FirstStartup.RunWizard.BetaWarning="(Remarque : l’Assistant de configuration automatique est actuellement en version bêta)" -Basic.FirstStartup.RunWizard.NoClicked="Si vous changez d’avis, vous pouvez réexécuter l’Assistant de configuration automatique n’importe quel moment dans le menu outils." +Basic.FirstStartup.RunWizard="Souhaitez-vous lancer l'Assistant de configuration ? Vous pouvez aussi configurer manuellement vos paramètres en cliquant sur le bouton \"Paramètres\" situé dans la fenêtre principale." +Basic.FirstStartup.RunWizard.NoClicked="Si vous changez d’avis, vous pouvez ré-exécuter l’Assistant de configuration automatique à n’importe quel moment depuis le menu Outils." Basic.AutoConfig="Assistant de Configuration automatique" -Basic.AutoConfig.Beta="Assistant de Configuration automatique (version bêta)" Basic.AutoConfig.ApplySettings="Appliquer les paramètres" Basic.AutoConfig.StartPage="Informations sur l’utilisation" -Basic.AutoConfig.StartPage.SubTitle="Spécifiez ce que vous voulez utiliser le programme pour" -Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimiser pour diffusion, l’enregistrement est secondaire" +Basic.AutoConfig.StartPage.SubTitle="Sélectionnez le cas ci-dessous qui vous corresponds le mieux" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimiser pour la diffusion en direct, l’enregistrement est secondaire" Basic.AutoConfig.StartPage.PrioritizeRecording="Optimiser pour l’enregistrement, je ne diffuse pas" Basic.AutoConfig.VideoPage="Paramètres vidéo" Basic.AutoConfig.VideoPage.SubTitle="Spécifiez les réglages vidéo que vous souhaitez utiliser" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Courant (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Garder tel quel (%1x%2)" Basic.AutoConfig.VideoPage.BaseResolution.Display="Écran %1 (%2x%3)_" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="Courant (%1)" -Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ou 30, mais préférez 60" -Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, mais préfèrent haute résolution" -Basic.AutoConfig.VideoPage.CanvasExplanation="Remarque : la résolution (de base) du canevas n'est pas nécessairement la même que la résolution avec laquelle vous allez diffuser (stream) ou enregistrer. La résolution actuelle de stream/enregistrement peut être réduite à partir de la résolution du canevas afin de diminuer l'utilisation des ressources et de la bande passante." -Basic.AutoConfig.StreamPage="Information de flux" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Garder tel quel (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ou 30, mais préférer 60 si possible" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, mais favoriser une résolution élevée" +Basic.AutoConfig.VideoPage.CanvasExplanation="Remarque : la résolution (de base) du canevas n'est pas nécessairement la même que la résolution avec laquelle vous allez diffuser (stream) ou enregistrer. La résolution actuelle de stream/enregistrement peut être réduite à partir de la résolution du canevas afin de diminuer l'utilisation des ressources et de la bande passante." +Basic.AutoConfig.StreamPage="Informations de flux" Basic.AutoConfig.StreamPage.SubTitle="Entrez vos informations de stream" +Basic.AutoConfig.StreamPage.ConnectAccount="Connecter un compte (optionnel)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Déconnecter le compte" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Déconnecter le compte ?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Cette modification s'appliquera immédiatement. Êtes-vous sûr de vouloir déconnecter votre compte ?" +Basic.AutoConfig.StreamPage.UseStreamKey="Utiliser la clé de stream" Basic.AutoConfig.StreamPage.Service="Service" Basic.AutoConfig.StreamPage.Service.ShowAll="Afficher tout..." +Basic.AutoConfig.StreamPage.Service.Custom="Personnalisé..." Basic.AutoConfig.StreamPage.Server="Serveur" Basic.AutoConfig.StreamPage.StreamKey="Clé de stream" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Lien)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Test de la bande passantes pour estimer le débit (peut prendre quelques minutes)" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Préférez l’encodage matériel" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="L'encodage matériel minimise l'utilisation du processeur (CPU), mais peut nécessiter un débit vidéo plus élevé pour obtenir le même niveau de qualité." +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Préférer l’encodage matériel" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="L'encodage matériel minimise l'utilisation du processeur (CPU), mais peut nécessiter un débit vidéo plus élevé pour obtenir une niveau de qualité équivalent." Basic.AutoConfig.StreamPage.StreamWarning.Title="Avertissement de diffusion" Basic.AutoConfig.StreamPage.StreamWarning.Text="Le test de bande passante est sur le point de diffuser (stream) des données vidéo aléatoire sans audio sur votre chaîne. Si vous avez la possibilité, il est recommandé de désactiver temporairement l'enregistrement des diffusions et de configurer le stream en privé jusqu'à ce que le test soit terminé. Continuer ?" Basic.AutoConfig.TestPage="Résultat final" -Basic.AutoConfig.TestPage.SubTitle.Testing="Le programme s’exécute maintenant une série de tests pour estimer les paramètres idéaux" -Basic.AutoConfig.TestPage.SubTitle.Complete="Test complet" +Basic.AutoConfig.TestPage.SubTitle.Testing="Le programme exécute maintenant une série de tests pour estimer vos paramètres idéaux" +Basic.AutoConfig.TestPage.SubTitle.Complete="Tests terminés" Basic.AutoConfig.TestPage.TestingBandwidth="Test de la bande passante en cours, cela peut prendre quelques minutes..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Connection à : %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Impossible de se connecter aux serveurs, veuillez vérifier votre connexion internet et réessayez." @@ -137,28 +167,32 @@ Basic.AutoConfig.TestPage.TestingRecordingEncoder="Test de l'encodeur d'enregist Basic.AutoConfig.TestPage.TestingRes="Tests de résolutions, cela peut prendre quelques minutes..." Basic.AutoConfig.TestPage.TestingRes.Fail="Échec lors du démarrage de l'encodeur" Basic.AutoConfig.TestPage.TestingRes.Resolution="Test FPS %1x%2 %3..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="Encodeur de diffusion" +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Encodeur de streaming" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Erreur d'enregistrement" -Basic.AutoConfig.TestPage.Result.Header="Le programme a déterminé que ces estimations de paramètres sont idéales pour vous :" -Basic.AutoConfig.TestPage.Result.Footer="Pour utiliser ces paramètres, cliquez sur « appliquer les paramètres ». Pour reconfigurer l’Assistant et essayer de nouveau, cliquez sur « précédent ». Pour configurer les paramètres vous-même, cliquez sur « Annuler et ouvrir les paramètres »." +Basic.AutoConfig.TestPage.Result.Header="Le programme vous recommande ces paramètres :" +Basic.AutoConfig.TestPage.Result.Footer="Pour utiliser ces paramètres, cliquez sur « Appliquer les paramètres ». Pour reconfigurer l’Assistant et essayer de nouveau, cliquez sur « Précédent ». Pour configurer les paramètres vous-même, cliquez sur « Annuler » et rendez-vous dans les Paramètres." Basic.Stats="Statistiques" -Basic.Stats.CPUUsage="Utilisation CPU" -Basic.Stats.HDDSpaceAvailable="Espace disque dur disponible" +Basic.Stats.CPUUsage="Utilisation Processeur" +Basic.Stats.HDDSpaceAvailable="Espace disque disponible" Basic.Stats.MemoryUsage="Utilisation de la mémoire" -Basic.Stats.AverageTimeToRender="Temps moyen de génération d'image" -Basic.Stats.SkippedFrames="Sauts d'image dû à la latence d'encodage" -Basic.Stats.MissedFrames="Images manqués en raison du retard de rendu" -Basic.Stats.Output.Stream="Flux" +Basic.Stats.AverageTimeToRender="Temps moyen de rendu d'image" +Basic.Stats.SkippedFrames="Sauts d'image dû à un retard d'encodage" +Basic.Stats.MissedFrames="Images manquées en raison d'un retard de rendu" +Basic.Stats.Output.Stream="Diffusion (Streaming)" Basic.Stats.Output.Recording="Enregistrement" Basic.Stats.Status="État" Basic.Stats.Status.Recording="Enregistrement en cours" -Basic.Stats.Status.Live="DIRECT" -Basic.Stats.Status.Reconnecting="Reconnexion" +Basic.Stats.Status.Live="EN DIRECT" +Basic.Stats.Status.Reconnecting="Reconnexion en cours" Basic.Stats.Status.Inactive="Inactif" Basic.Stats.DroppedFrames="Images perdues (réseau)" -Basic.Stats.MegabytesSent="Sortie Total des Données" +Basic.Stats.MegabytesSent="Données transmises (total)" Basic.Stats.Bitrate="Débit" +Basic.Stats.DiskFullIn="Disque plein dans (env.)" + +ResetUIWarning.Title="Êtes-vous sûr de vouloir réinitialiser l'interface graphique ?" +ResetUIWarning.Text="Réinitialiser l'interface masquera vos docks supplémentaires. Vous devrez les réactiver depuis le menu Afficher si vous voulez qu'ils soient visibles.\n\nÊtes-vous sûr de vouloir réinitialiser l'interface ?" Updater.Title="Nouvelle mise à jour disponible" Updater.Text="Une nouvelle mise à jour est disponible :" @@ -166,19 +200,19 @@ Updater.UpdateNow="Mettre à jour maintenant" Updater.RemindMeLater="Me le rappeler ultérieurement" Updater.Skip="Ignorer la version" Updater.Running.Title="Programme actuellement en cours d’exécution" -Updater.Running.Text="Des sorties sont actuellement actives, veuillez fermer toutes les sorties actives avant d'essayer de mettre à jour" +Updater.Running.Text="Des sorties sont actuellement actives, veuillez couper toutes les sorties actives avant d'essayer de mettre à jour" Updater.NoUpdatesAvailable.Title="Aucune mise à jour disponible" Updater.NoUpdatesAvailable.Text="Aucune mise à jour n’est actuellement disponible" Updater.FailedToLaunch="Impossible de démarrer la mise à jour" Updater.GameCaptureActive.Title="Capture de jeu active" -Updater.GameCaptureActive.Text="La bibliothèque « hook » de capture de jeu est actuellement active. Veuillez fermer tous les jeux/programmes en cours de capture (ou redémarrez Windows) et réessayez." +Updater.GameCaptureActive.Text="La bibliothèque de capture de jeu (« hook ») est en cours d'utilisation. Veuillez fermer tous les jeux/programmes en cours de capture (ou redémarrez Windows) et réessayez." QuickTransitions.SwapScenes="Permuter les scènes d'aperçu et de sortie après la transition" QuickTransitions.SwapScenesTT="Permute les scènes d'aperçu et de sortie après la transition (si la scène d'origine de la sortie existe toujours). \nCela n'annulera pas les modifications qui auront pu être faites sur la scène d'origine de la sortie." QuickTransitions.DuplicateScene="Dupliquer la scène" -QuickTransitions.DuplicateSceneTT="Lors de l'édition d'une même scène, permet de modifier les transformations et la visibilité des sources sans modifier la sortie. \nPour modifier les propriétés des sources sans modifier la sortie, activez \"Dupliquer les sources\". \nModifier ce paramètre réinitialisera la scène actuelle de sortie (si elle existe encore)." +QuickTransitions.DuplicateSceneTT="Lors de l'édition d'une même scène, cela permet de modifier les transformations et la visibilité des sources sans modifier la sortie. \nPour modifier les propriétés des sources sans modifier la sortie, activez \"Dupliquer les sources\". \nModifier ce paramètre réinitialisera la scène actuelle de sortie (si elle existe encore)." QuickTransitions.EditProperties="Dupliquer les sources" -QuickTransitions.EditPropertiesTT="Lors de l'édition d'une même scène, permet de modifier les propriétés des sources sans modification de la sortie. \nCela ne peut être utilisé que si \"Dupliquer la scène\" est activé. \nCertaines sources (telles que les captures ou sources médias) ne supportent pas cela et ne peuvent être modifiés séparément. \nModifier ce paramètre réinitialisera la scène actuelle de sortie (si elle existe encore).\n\nAttention : parce que les sources seront dupliquées , cela peut nécessiter des ressources système ou vidéo supplémentaires." +QuickTransitions.EditPropertiesTT="Lors de l'édition d'une même scène, cela permet de modifier les propriétés des sources sans modifier la sortie. \nCela ne peut être utilisé que si \"Dupliquer la scène\" est activé. \nCertaines sources (telles que les captures ou sources médias) ne supportent pas cela et ne peuvent être modifiées séparément. \nModifier ce paramètre réinitialisera la scène actuelle de sortie (si elle existe encore).\n\nAttention : puisque que les sources seront dupliquées, cela peut nécessiter des ressources système ou vidéo supplémentaires." QuickTransitions.HotkeyName="Transition rapide : %1" Basic.AddTransition="Ajouter une transition configurable" @@ -206,8 +240,11 @@ ConfirmStart.Text="Êtes-vous sûr de vouloir démarrer le stream ?" ConfirmStop.Title="Arrêter le stream ?" ConfirmStop.Text="Êtes-vous sûr de vouloir arrêter le stream ?" +ConfirmBWTest.Title="Démarrer le test de bande passante ?" +ConfirmBWTest.Text="Vous avez configuré OBS en mode \"test de bande passante\". Ce mode permet de tester le réseau sans que votre chaîne ne soit en direct. Une fois que vous aurez effectué les tests, vous devrez le désactiver afin que les spectateurs puissent voir votre stream.\n\nVoulez-vous continuer ?" + ConfirmExit.Title="Quitter OBS ?" -ConfirmExit.Text="OBS est actuellement actif. Tous les streams/enregistrements vont être arrêtés. Êtes-vous sûr de vouloir quitter ?" +ConfirmExit.Text="OBS est actuellement actif. Tous les streams/enregistrements vont être arrêtés. Êtes-vous sûr de vouloir quitter ?" ConfirmRemove.Title="Confirmer la suppression" ConfirmRemove.Text="Êtes-vous sûr de vouloir supprimer « $1 » ?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="Impossible de démarrer l'enregistrement" Output.StartReplayFailed="Impossible de démarrer le tampon de relecture" Output.StartFailedGeneric="Le démarrage de la sortie a échoué. Veuillez consulter le journal pour plus de détails.\n\nRemarque : si vous utilisez les encodeurs NVENC ou AMD, assurez-vous que vos pilotes vidéo soient à jour." + Output.ConnectFail.Title="Échec de la connexion" Output.ConnectFail.BadPath="Adresse de connexion ou chemin invalide. Veuillez vérifier vos paramètres afin de confirmer leur validité." Output.ConnectFail.ConnectFailed="Échec de la connexion au serveur" @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="Impossible d'accéder à la chaîne ou à la c Output.ConnectFail.Error="Une erreur inattendue s'est produite en essayant de se connecter au serveur. Plus d'informations dans le fichier journal." Output.ConnectFail.Disconnected="Déconnecté du serveur." +Output.StreamEncodeError.Title="Erreur d'encodage" +Output.StreamEncodeError.Msg="L'encodeur a rencontré une erreur pendant la diffusion." + Output.RecordFail.Title="Impossible de démarrer l'enregistrement" -Output.RecordFail.Unsupported="Le format de sortie n'est pas pris en charge ou ne supporte pas plus d'une piste audio. Veuillez vérifier vos paramètres et réessayez." +Output.RecordFail.Unsupported="Le format de sortie n'est pas pris en charge ou ne supporte qu'une piste audio. Veuillez vérifier vos paramètres et réessayez." Output.RecordNoSpace.Title="Espace disque insuffisant" -Output.RecordNoSpace.Msg="Il n'y a pas suffisamment d'espace disque pour continuer l'enregistrement." +Output.RecordNoSpace.Msg="Il n'y a pas suffisamment d'espace disque pour poursuivre l'enregistrement." Output.RecordError.Title="Erreur d'enregistrement" Output.RecordError.Msg="Une erreur non spécifiée s'est produite lors de l'enregistrement." +Output.RecordError.EncodeErrorMsg="L'encodeur a rencontré une erreur pendant l'enregistrement." Output.ReplayBuffer.NoHotkey.Title="Aucun raccourci clavier défini !" Output.ReplayBuffer.NoHotkey.Msg="Aucun raccourci clavier défini pour le tampon de relecture. Veuillez en définir un pour utiliser cette fonction." @@ -241,46 +283,47 @@ LogReturnDialog="Mise en ligne du journal réussie" LogReturnDialog.CopyURL="Copier l'adresse" LogReturnDialog.ErrorUploadingLog="Échec de la mise en ligne du journal" -LicenseAgreement="Contrat de licence" -LicenseAgreement.PleaseReview="Merci de revoir les termes de la licence avant d'utiliser OBS. En utilisant ce programme, vous reconnaissez avoir pris connaissance et acceptez les conditions de la Licence Publique Générale GNU v2.0 (en anglais) Veuillez faire défiler vers le bas pour voir le reste de l'accord." -LicenseAgreement.ClickIAgreeToContinue="Si vous acceptez les termes de l'accord, cliquez sur \"J'accepte\" pour continuer. Vous devez accepter l'accord pour utiliser OBS." -LicenseAgreement.IAgree="J'accepte" -LicenseAgreement.Exit="Quitter" - Remux.SourceFile="Enregistrement OBS" Remux.TargetFile="Fichier cible" Remux.Remux="Convertir" +Remux.Stop="Arrêter la conversion" +Remux.ClearFinished="Effacer les éléments terminés" +Remux.ClearAll="Effacer tous les éléments" Remux.OBSRecording="Enregistrement OBS" Remux.FinishedTitle="Conversion terminée" Remux.Finished="L'enregistrement a été converti" Remux.FinishedError="L'enregistrement a été converti, mais le fichier peut être incomplet" -Remux.SelectRecording="Choisir un enregistrement OBS …" -Remux.SelectTarget="Choisir le fichier cible …" +Remux.SelectRecording="Choisir l'enregistrement d'OBS ..." +Remux.SelectTarget="Choisir le fichier de Destination ..." Remux.FileExistsTitle="Fichier cible déjà existant" -Remux.FileExists="Le fichier cible est déjà existant, voulez-vous le remplacer ?" +Remux.FileExists="Les fichiers suivants existent déjà, voulez-vous les remplacer ?" Remux.ExitUnfinishedTitle="Conversion en cours" -Remux.ExitUnfinished="La conversion n'est pas terminée, arrêter maintenant peut rendre le fichier cible inutilisable.\nVoulez-vous vraiment arrêter la conversion ?" +Remux.ExitUnfinished="La conversion n'est pas terminée, arrêter maintenant peut rendre le fichier final inutilisable.\nVoulez-vous vraiment arrêter la conversion ?" +Remux.HelpText="Déposez des fichiers dans cette fenêtre pour les convertir, ou sélectionnez une cellule « Enregistrement OBS » vide pour rechercher un fichier." UpdateAvailable="Nouvelle mise à jour disponible" UpdateAvailable.Text="La version %1.%2.%3 est désormais disponible. Cliquez ici pour la télécharger" -Basic.DesktopDevice1="Audio du bureau" -Basic.DesktopDevice2="Audio du bureau 2" +Basic.DesktopDevice1="Audio du Bureau" +Basic.DesktopDevice2="Audio du Bureau 2" Basic.AuxDevice1="Mic/Aux" Basic.AuxDevice2="Mic/Aux 2" Basic.AuxDevice3="Mic/Aux 3" Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="Scène" -Basic.DisplayCapture="Afficher la capture" +Basic.DisplayCapture="Capture d'Ecran" Basic.Main.PreviewConextMenu.Enable="Activer l'aperçu" -ScaleFiltering="Échelle de filtrage" +Basic.Main.Preview.Disable="Désactiver l'aperçu" + +ScaleFiltering="Filtre de mise à l'échelle" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinéaire" ScaleFiltering.Bicubic="Bicubique" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Zone" Deinterlacing="Désentrelacement" Deinterlacing.Discard="Abandonner" @@ -367,9 +410,9 @@ Basic.TransformWindow.Position="Position" Basic.TransformWindow.Rotation="Rotation" Basic.TransformWindow.Size="Taille" Basic.TransformWindow.Alignment="Position de l'alignement" -Basic.TransformWindow.BoundsType="Type de la fenêtre" -Basic.TransformWindow.BoundsAlignment="Alignement de la fenêtre" -Basic.TransformWindow.Bounds="Taille de la fenêtre" +Basic.TransformWindow.BoundsType="Type de Cadre" +Basic.TransformWindow.BoundsAlignment="Alignement à l'intérieur du Cadre" +Basic.TransformWindow.Bounds="Taille du Cadre" Basic.TransformWindow.Crop="Rogner" Basic.TransformWindow.Alignment.TopLeft="En haut à gauche" @@ -384,11 +427,11 @@ Basic.TransformWindow.Alignment.BottomRight="En bas à droite" Basic.TransformWindow.BoundsType.None="Sans contours" Basic.TransformWindow.BoundsType.MaxOnly="Taille maximale uniquement" -Basic.TransformWindow.BoundsType.ScaleInner="Mettre à l'échelle par les dimensions intérieurs" -Basic.TransformWindow.BoundsType.ScaleOuter="Mettre à l'échelle par les dimensions extérieurs" +Basic.TransformWindow.BoundsType.ScaleInner="Mettre à l'échelle à partir des dimensions intérieures" +Basic.TransformWindow.BoundsType.ScaleOuter="Mettre à l'échelle à partir des dimensions extérieures" Basic.TransformWindow.BoundsType.ScaleToWidth="Mettre à l'échelle par la largeur" Basic.TransformWindow.BoundsType.ScaleToHeight="Mettre à l'échelle par la hauteur" -Basic.TransformWindow.BoundsType.Stretch="Étirer aux dimensions" +Basic.TransformWindow.BoundsType.Stretch="Étirer aux dimensions du Cadre" Basic.Main.AddSourceHelp.Title="Impossible d'ajouter la source" Basic.Main.AddSourceHelp.Text="Vous devez avoir au moins une scène pour ajouter une source." @@ -414,52 +457,54 @@ Basic.Main.Ungroup="Dissocier" Basic.MainMenu.File="&Fichier" Basic.MainMenu.File.Export="&Exporter" Basic.MainMenu.File.Import="&Importer" -Basic.MainMenu.File.ShowRecordings="&Afficher les enregistrements" -Basic.MainMenu.File.Remux="&Convertir un enregistrement" -Basic.MainMenu.File.Settings="&Paramètres" +Basic.MainMenu.File.ShowRecordings="Afficher les enregistrements (&R)" +Basic.MainMenu.File.Remux="Convertir un enregistre&ment" +Basic.MainMenu.File.Settings="Paramètre&s" Basic.MainMenu.File.ShowSettingsFolder="Afficher le dossier des paramètres" Basic.MainMenu.File.ShowProfileFolder="Afficher le dossier du profil" Basic.MainMenu.AlwaysOnTop="Toujours &au-dessus" -Basic.MainMenu.File.Exit="&Quitter" +Basic.MainMenu.File.Exit="Quitter (&X)" Basic.MainMenu.Edit="&Editer" -Basic.MainMenu.Edit.Undo="&Annuler" +Basic.MainMenu.Edit.Undo="Ann&uler" Basic.MainMenu.Edit.Redo="&Rétablir" -Basic.MainMenu.Edit.UndoAction="&Annuler $1" +Basic.MainMenu.Edit.UndoAction="Ann&uler $1" Basic.MainMenu.Edit.RedoAction="&Rétablir $1" -Basic.MainMenu.Edit.LockPreview="Verrouiller la prévisualisation" +Basic.MainMenu.Edit.LockPreview="Verroui&ller la prévisualisation" Basic.MainMenu.Edit.Scale="Mi&se à l'échelle de l'aperçu" Basic.MainMenu.Edit.Scale.Window="Adapter à la fenêtre" Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Sortie (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformer" -Basic.MainMenu.Edit.Transform.EditTransform="Éditer la transformation..." +Basic.MainMenu.Edit.Transform.EditTransform="Édit&er la transformation..." Basic.MainMenu.Edit.Transform.CopyTransform="Copier la transformation" Basic.MainMenu.Edit.Transform.PasteTransform="Coller la transformation" -Basic.MainMenu.Edit.Transform.ResetTransform="Réinitialiser la transformation" +Basic.MainMenu.Edit.Transform.ResetTransform="&Réinitialiser la transformation" Basic.MainMenu.Edit.Transform.Rotate90CW="Rotation de 90° sens horaire" Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotation de 90° sens antihoraire" Basic.MainMenu.Edit.Transform.Rotate180="Rotation de 180°" Basic.MainMenu.Edit.Transform.FlipHorizontal="Inverser &horizontalement" Basic.MainMenu.Edit.Transform.FlipVertical="Inverser &verticalement" -Basic.MainMenu.Edit.Transform.FitToScreen="&Adapter à l'écran" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Étirer à l'écran" +Basic.MainMenu.Edit.Transform.FitToScreen="Adapter à l'écran (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Étirer à l'écran (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrer à l'écran" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrer Verticalement" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrer Horizontalement" Basic.MainMenu.Edit.Order="&Ordonner" -Basic.MainMenu.Edit.Order.MoveUp="&Monter d'un cran" +Basic.MainMenu.Edit.Order.MoveUp="Monter d'&un cran" Basic.MainMenu.Edit.Order.MoveDown="&Descendre d'un cran" -Basic.MainMenu.Edit.Order.MoveToTop="Déplacer tout en &haut" +Basic.MainMenu.Edit.Order.MoveToTop="Déplacer &tout en haut" Basic.MainMenu.Edit.Order.MoveToBottom="Déplacer tout en &bas" -Basic.MainMenu.Edit.AdvAudio="Propriétés audio &avancées" +Basic.MainMenu.Edit.AdvAudio="Propriétés &audio avancées" -Basic.MainMenu.View="&Afficher" -Basic.MainMenu.View.Toolbars="&Barres d'outils" +Basic.MainMenu.View="Afficher (&V)" +Basic.MainMenu.View.Toolbars="Barres d'ou&tils" Basic.MainMenu.View.Docks="Docks" -Basic.MainMenu.View.Docks.ResetUI="Réinitialiser" -Basic.MainMenu.View.Docks.LockUI="Verrouiller" +Basic.MainMenu.View.Docks.ResetUI="Réinitialiser l'Interface" +Basic.MainMenu.View.Docks.LockUI="Verrouiller l'Interface" Basic.MainMenu.View.Toolbars.Listboxes="&Listes" -Basic.MainMenu.View.SceneTransitions="&Transition de scènes" -Basic.MainMenu.View.StatusBar="&Barre d'état" +Basic.MainMenu.View.SceneTransitions="Transition de s&cènes" +Basic.MainMenu.View.StatusBar="Barre d'état (&S)" Basic.MainMenu.View.Fullscreen.Interface="Interface plein écran" Basic.MainMenu.SceneCollection="Collection de &scènes" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Exporter une collection de scènes" Basic.MainMenu.Profile.Exists="Ce profil existe déjà" Basic.MainMenu.SceneCollection.Exists="Cette collection de scène existe déjà" -Basic.MainMenu.Tools="Outils" +Basic.MainMenu.Tools="Ou&tils" -Basic.MainMenu.Help="&Aide" +Basic.MainMenu.Help="Aide (&H)" Basic.MainMenu.Help.HelpPortal="&Portail d'aide" Basic.MainMenu.Help.Website="Consulter le site &Web" Basic.MainMenu.Help.Discord="Rejoindre le serveur &Discord" -Basic.MainMenu.Help.Logs="&Fichiers journaux" -Basic.MainMenu.Help.Logs.ShowLogs="Afficher les &fichiers de log" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Mettre en ligne le fichier journal &actuel" -Basic.MainMenu.Help.Logs.UploadLastLog="Mettre en ligne le &dernier fichier journal" +Basic.MainMenu.Help.Logs="Fichiers journaux (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Afficher le&s fichiers de log" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Mettre en ligne le fi&chier journal actuel" +Basic.MainMenu.Help.Logs.UploadLastLog="Mettre en &ligne le dernier fichier journal" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Voir le journal actuel" Basic.MainMenu.Help.CheckForUpdates="Rechercher des mises à jour" -Basic.MainMenu.Help.CrashLogs="Rapports d'e&rreurs" -Basic.MainMenu.Help.CrashLogs.ShowLogs="Montrer les rapport&s d'erreur" +Basic.MainMenu.Help.CrashLogs="&Rapports d'erreurs" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Montrer le&s rapports d'erreur" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Envoyer &le Dernier Rapport d'Erreur" +Basic.MainMenu.Help.About="À propos (&A)" Basic.Settings.ProgramRestart="Le programme doit être redémarré pour que les paramètres prennent effet." Basic.Settings.ConfirmTitle="Valider les modifications" @@ -514,21 +560,30 @@ Basic.Settings.General.SysTray="Zone de notifications" Basic.Settings.General.SysTrayWhenStarted="Réduire dans la zone de notification dès le démarrage" Basic.Settings.General.SystemTrayHideMinimize="Toujours réduire dans la zone de notification au lieu de la barre des tâches" Basic.Settings.General.SaveProjectors="Enregistrer les projecteurs en quittant" +Basic.Settings.General.Preview="Aperçu" +Basic.Settings.General.OverflowHidden="Masquer le débordement" +Basic.Settings.General.OverflowAlwaysVisible="Débordement toujours visible" +Basic.Settings.General.OverflowSelectionHidden="Afficher le débordement même si la source est invisible" Basic.Settings.General.SwitchOnDoubleClick="Effectuer la transition vers la scène en cas de double clic" Basic.Settings.General.StudioPortraitLayout="Activer la mise en page portrait/verticale" -Basic.Settings.General.Multiview="Multivues" +Basic.Settings.General.TogglePreviewProgramLabels="Afficher les étiquettes d'aperçu ou de programme" +Basic.Settings.General.Multiview="Multi-aperçu" Basic.Settings.General.Multiview.MouseSwitch="Cliquez pour changer de scène" Basic.Settings.General.Multiview.DrawSourceNames="Montrer les noms des scènes" Basic.Settings.General.Multiview.DrawSafeAreas="Afficher les zones sûres (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Disposition de la multivue" +Basic.Settings.General.MultiviewLayout="Disposition du multi-aperçu" Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, Haut (8 Scènes)" Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, Bas (8 Scènes)" Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, Gauche (8 Scènes)" Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, Droite (8 Scènes)" Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, Haut (24 Scènes)" -Basic.Settings.Stream="Flux" -Basic.Settings.Stream.StreamType="Type de diffusion" +Basic.Settings.Stream="Stream (flux)" +Basic.Settings.Stream.StreamType="Type de Streaming" +Basic.Settings.Stream.Custom.UseAuthentication="Utiliser l'authentification" +Basic.Settings.Stream.Custom.Username="Nom d'utilisateur" +Basic.Settings.Stream.Custom.Password="Mot de passe" +Basic.Settings.Stream.BandwidthTestMode="Activer le mode Test de bande passante" Basic.Settings.Output="Sortie" Basic.Settings.Output.Format="Format d'enregistrement" @@ -536,7 +591,7 @@ Basic.Settings.Output.Encoder="Encodeur" Basic.Settings.Output.SelectDirectory="Sélectionnez le répertoire d'enregistrement" Basic.Settings.Output.SelectFile="Sélectionnez le fichier cible" Basic.Settings.Output.EnforceBitrate="Imposer les limites de débit du service de streaming" -Basic.Settings.Output.Mode="Mode de sortie" +Basic.Settings.Output.Mode="Mode de Sortie" Basic.Settings.Output.Mode.Simple="Simple" Basic.Settings.Output.Mode.Adv="Avancé" Basic.Settings.Output.Mode.FFmpeg="Sortie FFmpeg" @@ -557,27 +612,26 @@ Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualité sans perte, én Basic.Settings.Output.Simple.Warn.VideoBitrate="Attention: le débit vidéo de streaming va être fixé à %1, qui est la limite maximale pour le service de streaming actuel. Si vous êtes surs de vouloir aller au delà de %1, activez les options avancées de l'encodeur & décochez \"Imposer les limites de débit du service de streaming\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Attention: le débit audio de streaming va être fixé à %1, qui est la limite maximale pour le service de streaming actuel. Si vous êtes surs de vouloir aller au delà de %1, activez les options avancées de l'encodeur & décochez \"Imposer les limites de débit du service de streaming\"." Basic.Settings.Output.Simple.Warn.Encoder="Attention : enregistrer via un encodeur logiciel avec une qualité autre que celle du stream sollicitera encore plus le CPU si vous streamez et enregistrez simultanément." -Basic.Settings.Output.Simple.Warn.Lossless="Attention: la qualité sans perte génère des fichiers de taille énorme ! Elle peut utiliser jusqu'à 7 gigaoctets d'espace disque par minute pour de hautes résolutions et fréquences d'image. Cette qualité n'est pas recommandée pour de longs enregistrements à moins d'avoir énormément d'espace disque disponible." +Basic.Settings.Output.Simple.Warn.Lossless="Attention: la qualité sans perte génère des fichiers de taille énorme ! Elle peut utiliser jusqu'à 7 gigaoctets d'espace disque par minute pour de hautes résolutions et fréquences d'image. Cette qualité n'est pas recommandée pour de longs enregistrements à moins d'avoir énormément d'espace disque disponible." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Êtes-vous certain de vouloir utiliser la qualité sans perte ?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Avertissement de qualité sans perte" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Attention : Vous ne pouvez pas utiliser plusieurs encodeurs QSV distincts lorsque vous streamez et enregistrez en même temps. Si vous voulez streamer et enregistrer en même temps, veuillez changer soit l'encodeur d'enregistrement, soit l'encodeur de streaming." Basic.Settings.Output.Simple.Encoder.Software="Logiciel (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Matériel (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Matériel (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Matériel (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Logiciel (préréglage x264 \"faible utilisation du CPU\", augmente la taille du fichier)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Logiciel (pré-réglage x264 \"faible utilisation du CPU\", augmente la taille du fichier)" Basic.Settings.Output.VideoBitrate="Débit vidéo" Basic.Settings.Output.AudioBitrate="Débit audio" Basic.Settings.Output.Reconnect="Reconnexion automatique" Basic.Settings.Output.RetryDelay="Délai avant la tentative de reconnexion (en secondes)" Basic.Settings.Output.MaxRetries="Nombres de tentatives maximales" Basic.Settings.Output.Advanced="Activer les paramètres avancés d'encodage" -Basic.Settings.Output.EncoderPreset="Préréglage de l'encodeur (élevé = charge CPU plus faible)" +Basic.Settings.Output.EncoderPreset="Pré-réglage d'encodeur" Basic.Settings.Output.CustomEncoderSettings="Paramètres personnalisés de l'encodeur" Basic.Settings.Output.CustomMuxerSettings="Paramètres personnalisés du muxer" Basic.Settings.Output.NoSpaceFileName="Générer le nom du fichier sans espace" -Basic.Settings.Output.Adv.Rescale="Mise à l'échelle" +Basic.Settings.Output.Adv.Rescale="Mise à l'échelle pour la Sortie" Basic.Settings.Output.Adv.AudioTrack="Piste audio" Basic.Settings.Output.Adv.Streaming="Streaming" Basic.Settings.Output.Adv.ApplyServiceSettings="Imposer les paramètres d'encodage du service de streaming" @@ -591,11 +645,11 @@ Basic.Settings.Output.Adv.Audio.Track6="Piste 6" Basic.Settings.Output.Adv.Recording="Enregistrement" Basic.Settings.Output.Adv.Recording.Type="Type " Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Sortie personnalisée (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utiliser l'encodeur de flux)" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Sortie Personnalisée (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utiliser le même encodeur que pour le stream)" Basic.Settings.Output.Adv.Recording.Filename="Format du nom de fichier" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Écraser si le fichier existe" -Basic.Settings.Output.Adv.FFmpeg.Type="Type de sortie FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type="Type de Sortie FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Sortie vers une URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Sortie vers un fichier" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formats d'enregistrement courants" @@ -619,53 +673,57 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Afficher tous les codecs (m FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY Année, 4 chiffres\n%YY Année, 2 derniers chiffres (00-99)\n%MM Mois en nombre (01-12)\n%DD Jour du mois(01-31)\n%hh Heure au format 24h (00-23)\n%mm Minute (00-59)\n%ss Seconde (00-61)\n%% Symbole %\n%a Jour de la semaine en abrégé\n%A Jour de la semaine\n%b Mois abrégé\n%B Mois\n%d Jour du mois (01-31)\n%H Heure au format 24h (00-23)\n%I Heure au format 12h (01-12)\n%m Mois en nombre (01-12)\n%M Minute (00-59)\n%p Désignation AM ou PM\n%S Seconde (00-61)\n%y Année, 2 derniers chiffres (00-99)\n%Y Année\n%z Nom ou abbréviation du fuseau horaire/n ou décalage ISO 8601 par rapport à l'UTC\n%Z Nom ou abbréviation du fuseau horaire\n" +FilenameFormatting.TT="%CCYY Année, 4 chiffres\n%YY Année, 2 derniers chiffres (00-99)\n%MM Mois en nombre (01-12)\n%DD Jour du mois avec zéro d'alignement (01-31)\n%hh Heure au format 24 heures (00-23)\n%mm Minute (00-59)\n%ss Seconde (00-61)\n%% Symbole %\n%a Jour de la semaine en abrégé\n%A Jour de la semaine\n%b Mois en abrégé\n%B Mois\n%d Jour du mois avec zéro d'alignement (01-31)\n%H Heure au format 24 heures (00-23)\n%I Heure au format 12 heures (01-12)\n%m Mois en nombre (01-12)\n%M Minute (00-59)\n%p Désignation AM ou PM\n%S Seconde (00-61)\n%y Année, 2 derniers chiffres (00-99)\n%Y Année\n%z Décalage ISO 8601 par rapport à l'UTC\n%Z Nom ou abréviation du fuseau horaire\n" Basic.Settings.Video="Vidéo" -Basic.Settings.Video.Adapter="Périphérique vidéo :" -Basic.Settings.Video.BaseResolution="Résolution de base (canvas) :" -Basic.Settings.Video.ScaledResolution="Résolution de sortie (mise à l'échelle) :" -Basic.Settings.Video.DownscaleFilter="Filtrage de la mise à l'échelle :" +Basic.Settings.Video.Adapter="Périphérique vidéo" +Basic.Settings.Video.BaseResolution="Résolution de base (canevas)" +Basic.Settings.Video.ScaledResolution="Résolution de Sortie (mise à l'échelle)" +Basic.Settings.Video.DownscaleFilter="Filtrage de la mise à l'échelle" Basic.Settings.Video.DisableAeroWindows="Désactiver Aero (Windows uniquement)" -Basic.Settings.Video.FPS="FPS :" -Basic.Settings.Video.FPSCommon="Valeur des FPS communes" -Basic.Settings.Video.FPSInteger="Valeur des FPS intégrales" -Basic.Settings.Video.FPSFraction="Valeurs des FPS fractionelles" -Basic.Settings.Video.Numerator="Numérateur :" -Basic.Settings.Video.Denominator="Dénominateur :" -Basic.Settings.Video.Renderer="Rendu :" -Basic.Settings.Video.InvalidResolution="Valeurs de résolution invalides. Elles doivent être au format [largeur]x[hauteur] (par exemple 1920x1080)" +Basic.Settings.Video.FPS="FPS (débit d'images)" +Basic.Settings.Video.FPSCommon="Valeurs courantes pour le débit d'images (FPS)" +Basic.Settings.Video.FPSInteger="Valeurs entières pour le débit d'images (FPS)" +Basic.Settings.Video.FPSFraction="Débit d'images (FPS) sous forme de fraction" +Basic.Settings.Video.Numerator="Numérateur" +Basic.Settings.Video.Denominator="Dénominateur" +Basic.Settings.Video.Renderer="Rendu" +Basic.Settings.Video.InvalidResolution="Valeurs de résolution non-valides. Elles doivent être au format [largeur]x[hauteur] (par exemple 1920x1080)" Basic.Settings.Video.CurrentlyActive="La sortie vidéo est actuellement active. Veuillez éteindre toutes les sorties avant de modifier vos paramètres vidéo." Basic.Settings.Video.DisableAero="Désactiver Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinéaire (plus rapide, mais flou en cas de mise à l'échelle)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubique (redimensionnement affiné, 16 échantillons)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (redimensionnement affiné, 32 échantillons)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubique (mise à l'échelle avec netteté accentuée, 16 échantillons)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (mise à l'échelle avec netteté accentuée, 32 échantillons)" Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Fréquence d'échantillonnage" Basic.Settings.Audio.Channels="Canaux" -Basic.Settings.Audio.MeterDecayRate="Vitesse de dégradation audiométrique" +Basic.Settings.Audio.Meters="Mesures" +Basic.Settings.Audio.MeterDecayRate="Vitesse de relâche" Basic.Settings.Audio.MeterDecayRate.Fast="Rapide" Basic.Settings.Audio.MeterDecayRate.Medium="Moyenne (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Lente (Type II PPM)" Basic.Settings.Audio.PeakMeterType="Type de crête-mètre" -Basic.Settings.Audio.PeakMeterType.SamplePeak="Pic d'échantillon" -Basic.Settings.Audio.PeakMeterType.TruePeak="Crête vraie (plus grande utilisation du CPU)" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Pic d'échantillon audio" +Basic.Settings.Audio.PeakMeterType.TruePeak="Crête exacte (plus grande utilisation du CPU)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ATTENTION : le son multicanal est activé." -Basic.Settings.Audio.MultichannelWarning="Pour de besoins de diffusion, vérifiez que votre service de diffusion supporte l'intégration et la lecture du son multicanal. Twitch, Facebook 360 Live, Mixer RTMP ou Smashcast sont des exemples de services où le son multicanal est entièrement supporté. Bien que Facebook Live et YouTube Live acceptent l'intégration de son multicanal, Facebook Live transcode en stéréo, et YouTube Live ne lit que deux canaux.\n\nLes filtres audio d'OBS sont compatibles avec le son multicanal, toutefois le support du plugin VST n'est pas garanti." +Basic.Settings.Audio.MultichannelWarning="Pour de besoins de diffusion, vérifiez que votre service de diffusion supporte l'intégration et la lecture du son multicanal. Twitch, Facebook 360 Live, Mixer RTMP ou Smashcast sont des exemples de services où le son multicanal est entièrement supporté. Bien que Facebook Live et YouTube Live acceptent l'intégration de son multicanal, Facebook Live transcode en stéréo, et YouTube Live ne lit que deux canaux.\n\nLes filtres audio d'OBS sont compatibles avec le son multicanal, toutefois le support des plugins VST n'est pas garanti." Basic.Settings.Audio.MultichannelWarning.Title="Activer le son multicanal ?" Basic.Settings.Audio.MultichannelWarning.Confirm="Êtes vous sûr de vouloir activer le son multicanal ?" -Basic.Settings.Audio.DesktopDevice="Périphérique audio du bureau" -Basic.Settings.Audio.DesktopDevice2="Périphérique audio du bureau 2" -Basic.Settings.Audio.AuxDevice="Périphérique audio micro/auxiliaire" -Basic.Settings.Audio.AuxDevice2="Périphérique audio micro/auxiliaire 2" -Basic.Settings.Audio.AuxDevice3="Périphérique audio micro/auxiliaire 3" -Basic.Settings.Audio.EnablePushToMute="Activer le Push-to-mute" -Basic.Settings.Audio.PushToMuteDelay="Délai du Push-to-mute" -Basic.Settings.Audio.EnablePushToTalk="Activer le Push-to-talk" -Basic.Settings.Audio.PushToTalkDelay="Délai du Push-to-talk" +Basic.Settings.Audio.Devices="Périphériques" +Basic.Settings.Audio.DesktopDevice="Audio du Bureau" +Basic.Settings.Audio.DesktopDevice2="Audio du Bureau 2" +Basic.Settings.Audio.AuxDevice="Audio Micro/Auxiliaire" +Basic.Settings.Audio.AuxDevice2="Audio Micro/Auxiliaire 2" +Basic.Settings.Audio.AuxDevice3="Audio Micro/Auxiliaire 3" +Basic.Settings.Audio.AuxDevice4="Audio Micro/Auxiliaire 4" +Basic.Settings.Audio.EnablePushToMute="Activer \"Appuyer-pour-désactiver\" (Push-to-mute)" +Basic.Settings.Audio.PushToMuteDelay="Délai du \"Appuyer-pour-désactiver\" (Push-to-mute)" +Basic.Settings.Audio.EnablePushToTalk="Activer le \"Appuyer-pour-parler\" (Push-to-talk)" +Basic.Settings.Audio.PushToTalkDelay="Délai du \"Appuyer-pour-parler\" (Push-to-talk)" Basic.Settings.Audio.UnknownAudioDevice="[Périphérique non connecté ou non disponible]" +Basic.Settings.Audio.Disabled="Désactivé" Basic.Settings.Advanced="Avancé" Basic.Settings.Advanced.General.ProcessPriority="Priorité du processus" @@ -677,13 +735,13 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Basse" Basic.Settings.Advanced.FormatWarning="Attention : les formats de couleur autres que NV12 sont principalement destinés à l'enregistrement, et ne sont pas recommandés pour le streaming. Le streaming peut pâtir d'une utilisation élevée du CPU due à la conversion de format de couleur." Basic.Settings.Advanced.Audio.BufferingTime="Temps de mise en mémoire tampon audio" Basic.Settings.Advanced.Video.ColorFormat="Format de couleur" -Basic.Settings.Advanced.Video.ColorSpace="Espace de couleur YUV" +Basic.Settings.Advanced.Video.ColorSpace="Espace de couleurs YUV" Basic.Settings.Advanced.Video.ColorRange="Gamme de couleurs YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Partielle" Basic.Settings.Advanced.Video.ColorRange.Full="Complète" -Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositif de surveillance audio" +Basic.Settings.Advanced.Audio.MonitoringDevice="Périphérique de Monitoring Audio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Par défaut" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Désactiver l'atténuation audio de Windows" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Désactiver l'atténuation audio de Windows (ducking)" Basic.Settings.Advanced.StreamDelay="Retard du stream" Basic.Settings.Advanced.StreamDelay.Duration="Durée (en secondes)" Basic.Settings.Advanced.StreamDelay.Preserve="Préserver le point de coupure (augmente le retard) lors d'une reconnexion" @@ -693,21 +751,24 @@ Basic.Settings.Advanced.Network.BindToIP="Lier à :" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activer le nouveau code réseau" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode faible latence" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Désactiver les raccourcis clavier lorsque la fenêtre principale est au premier plan" +Basic.Settings.Advanced.AutoRemux="Convertir automatiquement en MP4" +Basic.Settings.Advanced.AutoRemux.MP4="(enregistrer en MKV)" -Basic.AdvAudio="Propriétés audio avancées" +Basic.AdvAudio="Propriétés Audio Avancées" Basic.AdvAudio.Name="Nom" -Basic.AdvAudio.Volume="Volume (%)" -Basic.AdvAudio.Mono="Passer en mono" -Basic.AdvAudio.Panning="Panoramique polyphonique" +Basic.AdvAudio.Volume="Volume" +Basic.AdvAudio.Mono="Convertir en mono" +Basic.AdvAudio.Balance="Balance" Basic.AdvAudio.SyncOffset="Décalage de la synchronisation (ms)" -Basic.AdvAudio.Monitoring="Surveillance audio" -Basic.AdvAudio.Monitoring.None="Désactivé" -Basic.AdvAudio.Monitoring.MonitorOnly="Surveillance uniquement (couper la sortie)" -Basic.AdvAudio.Monitoring.Both="Surveillance et sortie" +Basic.AdvAudio.Monitoring="Monitoring Audio" +Basic.AdvAudio.Monitoring.None="Monitoring Désactivé" +Basic.AdvAudio.Monitoring.MonitorOnly="Monitoring uniquement (couper la sortie)" +Basic.AdvAudio.Monitoring.Both="Monitoring et Sortie" Basic.AdvAudio.AudioTracks="Pistes" Basic.Settings.Hotkeys="Raccourcis clavier" -Basic.Settings.Hotkeys.Pair="Les combinaisons de touches partagées avec '%1' agissent comme déclancheur" +Basic.Settings.Hotkeys.Pair="Les combinaisons de touches partagées avec '%1' agissent comme déclencheur" +Basic.Settings.Hotkeys.Filter="Filtre" Basic.Hotkeys.SelectScene="Passer à la scène" @@ -751,28 +812,44 @@ Hotkeys.AppleKeypadSubtract="- (Pavé numérique)" Hotkeys.AppleKeypadDecimal=". (Pavé numérique)" Hotkeys.AppleKeypadEqual="= (Pavé numérique)" Hotkeys.MouseButton="Souris %1" +Hotkeys.Escape="Esc" -Mute="Rendre muet" -Unmute="Rendre parlant" +Mute="Couper l'Audio" +Unmute="Restaurer l'Audio" Push-to-mute="Push-to-mute" -Push-to-talk="Push-to-talk" +Push-to-talk="Appuyer-pour-parler" SceneItemShow="Afficher '%1'" SceneItemHide="Cacher '%1'" OutputWarnings.NoTracksSelected="Vous devez sélectionner au moins une piste" OutputWarnings.MultiTrackRecording="Attention : Certains formats (comme FLV) ne supportent pas les pistes multiples pour un même enregistrement" -OutputWarnings.MP4Recording="Avertissement : les enregistrements sauvegardés en MP4 seront irrécupérables si le fichier ne peut pas être finalisé (ex. : à cause des BSOD, coupure de l'alimentation, etc...). Si vous voulez enregistrer plusieurs pistes audio, pensez à utiliser MKV et convertir l'enregistrement en mp4 après qu'il soit terminé (Fichier -> Convertir un enregistrement)" +OutputWarnings.MP4Recording="Avertissement : les enregistrements sauvegardés en MP4/MOV seront irrécupérables si le fichier ne peut pas être finalisé (ex. : à cause des BSOD, pannes de l'alimentation, etc...). Si vous voulez enregistrer plusieurs pistes audio, pensez à utiliser le format MKV et à convertir l'enregistrement en MP4/MOV après avoir terminé (Fichier → Convertir un enregistrement)" FinalScene.Title="Supprimer la scène" FinalScene.Text="Il doit y avoir au moins une scène." NoSources.Title="Aucune source" NoSources.Text="Il semble que vous n'ayez pas ajouté de source vidéo pour le moment, vous aurez donc un écran noir. Êtes-vous sûr de vouloir continuer ?" -NoSources.Text.AddSource="Vous pouvez à tout moment ajouter des sources en cliquant sur l'icone + sous le bloc Sources de la fenêtre principale." +NoSources.Text.AddSource="Vous pouvez à tout moment ajouter des sources en cliquant sur l'icone + en bas du cadre Sources de la fenêtre principale." +NoSources.Label="Vous n'avez aucune source.\nCliquez sur le bouton \"+\" ci-dessous,\nou cliquez avec le bouton droit ici pour en ajouter une." ChangeBG="Définir la couleur" CustomColor="Couleur personnalisée" -BrowserSource.EnableHardwareAcceleration="Activer l’accélération matériel de la source navigateur" +BrowserSource.EnableHardwareAcceleration="Activer l’accélération matérielle de la source « navigateur »" + +About="À propos" +About.Info="OBS Studio est un logiciel libre open source pour l'enregistrement vidéo et le streaming en direct." +About.Donate="Aider le Projet" +About.GetInvolved="Contribuer" +About.Authors="Auteurs" +About.License="Licence" +About.Contribute="Soutenir le Projet d'OBS" + +ResizeOutputSizeOfSource="Redimensionner la sortie (taille de la source)" +ResizeOutputSizeOfSource.Text="Les résolutions de base et de sortie seront redimensionnées à la taille de la source actuelle." +ResizeOutputSizeOfSource.Continue="Voulez-vous continuer ?" + +PreviewTransition="Prévisualiser la transition" diff --git a/UI/data/locale/gd-GB.ini b/UI/data/locale/gd-GB.ini index 0ea4d86..301e4e1 100644 --- a/UI/data/locale/gd-GB.ini +++ b/UI/data/locale/gd-GB.ini @@ -61,6 +61,7 @@ Hours="Uair" Minutes="Mionaid" Seconds="Diog" Deprecated="Cha mholar seo tuilleadh" +ReplayBuffer="Bufair na h-ath-chluiche" Import="Ion-phortaich" Export="Às-phortaich" Copy="Dèan lethbhreac" @@ -79,14 +80,35 @@ StudioMode.Program="Prògram" ShowInMultiview="Seall san ioma-shealladh" VerticalLayout="Co-dhealbhachd inghearach" Group="Buidhnich" +DoNotShowAgain="Na seall seo a-rithist" AlreadyRunning.Title="Tha OBS ’ga ruith mar-thà" AlreadyRunning.Text="Tha OBS ’ga ruith mar-thà! Mur ann gun robh thu airson seo a dhèanamh, dùin sìos gach ionstans de dh’OBS mus fheuch thu ri ionstans eile dheth a ruith. Ma shuidhich thu OBS ach an dèid fhìor-lùghdachadh gu treidhe an t-siostaim thoir sùil a bheil e ’ga ruith an-siud fhathast." AlreadyRunning.LaunchAnyway="Cuir gu dol e co-dhiù" +DockCloseWarning.Title="A’ dùnadh uinneag doca" +DockCloseWarning.Text="Tha thu air uinneag doca a dhùnadh. Nam gu toigh leat a sealltainn a-rithist, cleachd clàr-taice “Seall” → “Docaichean” air bàr a’ chlàir-thaice." + +Auth.Authing.Title="’Gad dhearbhadh…" +Auth.Authing.Text="’Gad dhearbhadh le %1, fuirich greiseag…" +Auth.AuthFailure.Title="Dh’fhàillig an dearbhadh" +Auth.AuthFailure.Text="Dh’fhàillig an dearbhadh le %1:\n\n%2: %3" +Auth.InvalidScope.Title="Feum air dearbhadh" +Auth.InvalidScope.Text="Chaidh riatanasan dearbhaidh air %1 atharrachadh. Dh’fhaoidte nach bi gach gleus ri làimh dhut." +Auth.LoadingChannel.Title="A’ luchdadh fiosrachadh an t-seanail…" +Auth.LoadingChannel.Text="A’ luchdadh fiosrachadh an t-seanail airson %1, fuirich greiseag…" +Auth.ChannelFailure.Title="Dh’fhàillig le luchdadh an t-seanail" +Auth.ChannelFailure.Text="Dh’fhàillig le luchdadh fiosrachadh an t-seanail airson %1\n\n%2: %3" +Auth.Chat="Cabadaich" +Auth.StreamInfo="Fiosrachadh an t-sruthaidh" +TwitchAuth.Stats="Stadastaireachd Twitch" + Copy.Filters="Dèan lethbhreac dhe na criathragan" Paste.Filters="Cuir ann criathragan" +BrowserPanelInit.Title="A’ tòiseachadh a’ bhrabhsair…" +BrowserPanelInit.Text="A’ tòiseachadh a’ bhrabhsair, fuirich greiseag…" + BandwidthTest.Region="Roinn-dùthcha" BandwidthTest.Region.US="Na Stàitean Aonaichte" BandwidthTest.Region.EU="An Roinn-Eòrpa" @@ -94,11 +116,9 @@ BandwidthTest.Region.Asia="Àisia" BandwidthTest.Region.Other="Roinn-dùthcha eile" Basic.FirstStartup.RunWizard="A bheil thu airson draoidh an fhèin-rèiteachaidh a ruith? ’S urrainn dhut na roghainnean agad a rèiteachadh a làimh cuideachd ’s tu a’ briogadh air a’ phutan “Roghainnean” sa phrìomh-uinneag." -Basic.FirstStartup.RunWizard.BetaWarning="(An aire: Tha draoidh an fhèin-rèiteachaidh ’na thionndadh beta fhathast)" Basic.FirstStartup.RunWizard.NoClicked="Ma chuireas tu an caochladh romhad, ’s urrainn dhut draoidh an fhèin-rèiteachaidh a ruith a-rithist on chlàr-taice “Innealan” uair sam bith." Basic.AutoConfig="Draoidh an fhèin-rèiteachaidh" -Basic.AutoConfig.Beta="Draoidh an fhèin-rèiteachaidh (beta)" Basic.AutoConfig.ApplySettings="Cuir na roghainnean an sàs" Basic.AutoConfig.StartPage="Fiosrachadh a’ chleachdaidh" Basic.AutoConfig.StartPage.SubTitle="Sònraich na h-adhbharan air an cleachd thu am prògram" @@ -111,11 +131,17 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Uidheam-taisbeanaidh %1 (%2x% Basic.AutoConfig.VideoPage.FPS.UseCurrent="An roghainn làithreach (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="An dà chuid 60 no 30 ach b’ fhearr leam 60" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="An dà chuid 60 no 30 ach b’ fhearr leam dùmhlachd-bhreacaidh àrd" -Basic.AutoConfig.VideoPage.CanvasExplanation="An aire: Cha bhi dùmhlachd-bhreacaidh bhunasach (a’ chanabhais) co-ionnan ris an dùmhlachd-bhreacaidh a thèid a chlàradh no a shruthadh an-còmhnaidh. Dh’fhaoidte gun dèid an dùbhlachd-bhreacaidh air sruthadh no clàradh ìsleachadh o dhùmhlachd-bhreacaidh a’ chanabhais airson freagairt ri feumalachdan cleachdaidh no reat bhiotaichean." +Basic.AutoConfig.VideoPage.CanvasExplanation="An aire: Cha bhi dùmhlachd-bhreacaidh bhunasach (a’ chanabhais) co-ionnan ris an dùmhlachd-bhreacaidh a thèid a chlàradh no a shruthadh an-còmhnaidh. Dh’fhaoidte gun dèid an dùmhlachd-bhreacaidh air sruthadh no clàradh ìsleachadh o dhùmhlachd-bhreacaidh a’ chanabhais airson freagairt ri feumalachdan cleachdaidh no reat bhiotaichean." Basic.AutoConfig.StreamPage="Fiosrachadh an t-sruthaidh" Basic.AutoConfig.StreamPage.SubTitle="Cuid a-steach fiosrachadh an t-sruthaidh agad" +Basic.AutoConfig.StreamPage.ConnectAccount="Dèan ceangal ri cunntas (roghainneil)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Bris an ceangal ris a’ chunntas" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="A bheil thu airson an ceangal ris a’ chunntas a bhriseadh?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Thèid an t-atharradh seo a chur an sàs sa bhad. A bheil thu cinnteach gu bheil thu airson an ceangal ris a’ chunntas agad a bhriseadh?" +Basic.AutoConfig.StreamPage.UseStreamKey="Cleachd iuchair sruthaidh" Basic.AutoConfig.StreamPage.Service="Seirbheis" Basic.AutoConfig.StreamPage.Service.ShowAll="Seall na h-uile…" +Basic.AutoConfig.StreamPage.Service.Custom="Gnàthaichte…" Basic.AutoConfig.StreamPage.Server="Frithealaiche" Basic.AutoConfig.StreamPage.StreamKey="Iuchair an t-sruthaidh" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Ceangal)" @@ -143,7 +169,6 @@ Basic.AutoConfig.TestPage.Result.Footer="Airson na roghainnean seo a chleachdadh Basic.Stats="Stadastaireachd" Basic.Stats.CPUUsage="Cleachdadh a’ CPU" -Basic.Stats.HDDSpaceAvailable="Àite ri fhaighinn air a’ chlàr-chruaidh" Basic.Stats.MemoryUsage="Cleachdadh a’ chuimhne" Basic.Stats.AverageTimeToRender="Ùine cuibheasach air reandaradh frèama" Basic.Stats.SkippedFrames="Na frèamaichean air an leigeil seachad ri linn dàil còdachaidh" @@ -159,6 +184,9 @@ Basic.Stats.DroppedFrames="Frèamaichean a thuit: (lìonra)" Basic.Stats.MegabytesSent="Às-chur dàta iomlan" Basic.Stats.Bitrate="Reat bhiotaichean" +ResetUIWarning.Title="A bheil thu cinnteach gu bheil thu airson an eadar-aghaidh ath-shuidheachadh?" +ResetUIWarning.Text="Thèid gach doca a bharrachd fhalach nuair a nì thu ath-shuidheachadh air an eadar-aghaidh. Feumaidh tu na docaichean ud a nochdadh a-rithist on clàr-taice “Seall” ma tha thu airson am faicinn.\n\nA bheil thu cinnteach gu bheil thu airson an eadar-aghaidh ath-shuidheachadh?" + Updater.Title="Tha ùrachadh ri fhaighinn" Updater.Text="Tha ùrachadh ri fhaighinn:" Updater.UpdateNow="Ùraich an-dràsta" @@ -170,7 +198,7 @@ Updater.NoUpdatesAvailable.Title="Chan eil ùrachadh ri fhaighinn" Updater.NoUpdatesAvailable.Text="Chan eil ùrachadh ri fhaighinn an-dràsta" Updater.FailedToLaunch="Cha deach leinn an t-inneal-ùrachaidh a chur gu dol" Updater.GameCaptureActive.Title="Tha glacadh geama gnìomhach" -Updater.GameCaptureActive.Text="Tha leabharlann glacaidh geama ’ga chleachdadh. Dùin gad geama no prògram a tha ’ga ghlacadh (no ath-thòisich Windows) is feuch ris a-rithist." +Updater.GameCaptureActive.Text="Tha leabharlann huca glacadh geama ’ga chleachdadh. Dùin gach geama no prògram a tha ’ga ghlacadh (no ath-thòisich Windows) is feuch ris a-rithist." QuickTransitions.SwapScenes="Dèan iomlaid air seallaidhean an ro-sheallaidh ’s an às-chuir às dèid an tar-mhùthaidh" QuickTransitions.SwapScenesTT="Nì seo iomlaid air seallaidhean an ro-sheallaidh ’s an às-chuir às dèidh an tar-mhùthaidh (ma tha sealladh tùsail an às-chuir ann fhathast).\nCha neo-dhèan seo atharrachadh sam bith a chaidh a dhèanamh air sealladh tùsail an às-chuir." @@ -205,6 +233,7 @@ ConfirmStart.Text="A bheil thu cinnteach gu bheil thu airson tòiseachadh air an ConfirmStop.Title="A bheil thu airson stad a chur air an t-sruthadh?" ConfirmStop.Text="A bheil thu cinnteach gu bheil thu airson stad a chur air an t-sruthadh?" + ConfirmExit.Title="A bheil thu airson OBS fhàgail?" ConfirmExit.Text="Tha OBS gnìomhach an-dràsta. Thèid gach sruthadh no clàradh a chur gu crìch. A bheil thu cinnteach gu bheil thu airson fhàgail?" @@ -217,6 +246,7 @@ Output.StartRecordingFailed="Cha deach leinn tòiseachadh air a’ chlàradh" Output.StartReplayFailed="Cha deach leinn tòiseachadh air bufair na h-ath-chluiche" Output.StartFailedGeneric="Cha deach leinn tòiseachadh air an às-chur. Thoir sùil air an loga airson barrachd fiosrachaidh.\n\nAn aire: Ma tha thu a’ cleachdadh inneal-còdachaidh NVENC no AMD, dèan cinneach gu bheil na draibhearan video agad cho ùr ’s a ghabhas." + Output.ConnectFail.Title="Cha deach leinn ceangal a dhèanamh" Output.ConnectFail.BadPath="Tha slighe no URL a’ cheangail mì-dhligheach. Thoir sùil air na roghainnean agad feuch a bheil iad mar bu chòir." Output.ConnectFail.ConnectFailed="Dh’fhàillig an ceangal ris an fhrithealaiche" @@ -224,6 +254,7 @@ Output.ConnectFail.InvalidStream="Bha b’ urrainn dhuinn an t-seanail no an iuc Output.ConnectFail.Error="Thachair mearachd ris nach robh dùil nuair a dh’fheuch sinn ri ceangal ris an fhrithealaiche. Tha barrachd fiosrachaidh ann am faidhle an loga." Output.ConnectFail.Disconnected="Chaidh an ceangal dhan fhrithealaiche a bhriseadh." + Output.RecordFail.Title="Cha deach leinn tòiseachadh air a’ chlàradh" Output.RecordFail.Unsupported="Cha chuirear taic ri fòrmat an às-chuir no cha chuir e taic ri corr is aon traca fuaime. Thoir sùil air na roghainnean agad is feuch ris a-rithist." Output.RecordNoSpace.Title="Chan eil àite gu leòr air an diosga" @@ -240,25 +271,21 @@ LogReturnDialog="Chaidh an loga a luchdadh suas" LogReturnDialog.CopyURL="Dèan lethbhreac dhen URL" LogReturnDialog.ErrorUploadingLog="Mearachd le luchdadh suas an loga" -LicenseAgreement="Aonta ceadachais" -LicenseAgreement.PleaseReview="Thoir sùil air teirmichean a’ cheadachais mus cleachd thu OBS. Le cleachdadh a’ phrògraim seo, aidichidh tu gun do leugh thu is gun aontaich thu ri teirmichean ceadachas GNU General Public License v2.0. Sgrolaich sìos airson an corr dhen aonta fhaicinn." -LicenseAgreement.ClickIAgreeToContinue="Ma ghabhas tu ri teirmichean an aonta, briog air “Gabhaidh mi ris” airson leantainn air adhart. Feumaidh tu gabhail ris an aonta airson OBS a chleachdadh." -LicenseAgreement.IAgree="Gabhaidh mi ris" -LicenseAgreement.Exit="Fàg an-seo" - Remux.SourceFile="Clàradh OBS" Remux.TargetFile="Faidhle amais" Remux.Remux="Iompaich" +Remux.Stop="Cuir stad air an iompachadh" +Remux.ClearFinished="Falamhaich na nithean coileanta" +Remux.ClearAll="Falamhaich a h-uile nì" Remux.OBSRecording="Clàradh OBS" Remux.FinishedTitle="Tha an t-iompachadh deiseil" Remux.Finished="Chaidh an clàradh iompachadh" Remux.FinishedError="Chaidh an clàradh iompachadh ach ’s ma dh’fhaoidte nach eil am faidhle coileanta" -Remux.SelectRecording="Tagh clàradh OBS…" -Remux.SelectTarget="Tagh faidhle amais…" -Remux.FileExistsTitle="Tha am faidhle amais ann" -Remux.FileExists="Tha am faidhle amais ann mu thràth, a bheil thu airson seo a chur ’na àite?" +Remux.FileExistsTitle="Tha faidhlichean amais ann" +Remux.FileExists="Tha na faidhlichean amais seo ann mu thràth. A bheil thu airson an fheadhainn ùra a chur ’na àite?" Remux.ExitUnfinishedTitle="’Ga iompachadh" Remux.ExitUnfinished="Chan eil an t-iompachadh deiseil agus dh’fhaoidte nach gabh am faidhle amais a cleachdadh ma chuireas tu stad air an-dràsta.\nA bheil thu cinnteach gu bheil thu airson stad a chur air an iompachadh?" +Remux.HelpText="Leig às faidhlichean san uinneag seo airson an iompachadh no tagh cealla “Clàradh OBS” falamh ach an dèan thu brabhsadh airson faidhle." UpdateAvailable="Tha ùrachadh ri fhaighinn" UpdateAvailable.Text="Tha tionndadh %1.%2.%3 ri fhaighinn a-nis. Briog an-seo gus a luchdadh a-nuas" @@ -275,6 +302,7 @@ Basic.DisplayCapture="Glacadh an uidheim-taisbeanaidh" Basic.Main.PreviewConextMenu.Enable="Cuir an ro-shealladh an comas" + ScaleFiltering="Criathradh sgèilidh" ScaleFiltering.Point="Puing" ScaleFiltering.Bilinear="Dà-loidhneach" @@ -411,21 +439,21 @@ Basic.Main.GroupItems="Buidhnich na thagh thu" Basic.Main.Ungroup="Sgaoil am buidheann" Basic.MainMenu.File="&Faidhle" -Basic.MainMenu.File.Export="Às-phor&taich" +Basic.MainMenu.File.Export="Às-phortaich (&E)" Basic.MainMenu.File.Import="&Ion-phortaich" -Basic.MainMenu.File.ShowRecordings="Seall na &clàraidhean" +Basic.MainMenu.File.ShowRecordings="Seall na clà&raidhean" Basic.MainMenu.File.Remux="Io&mpaich na clàraidhean" -Basic.MainMenu.File.Settings="&Roghainnean" +Basic.MainMenu.File.Settings="Roghainnean (&S)" Basic.MainMenu.File.ShowSettingsFolder="Seall pasgan nan roghainnean" Basic.MainMenu.File.ShowProfileFolder="Seall pasgan na pròifil" Basic.MainMenu.AlwaysOnTop="&Air uachdar an-còmhnaidh" -Basic.MainMenu.File.Exit="&Fàg an-seo" +Basic.MainMenu.File.Exit="Fàg an-seo (&X)" Basic.MainMenu.Edit="D&easaich" -Basic.MainMenu.Edit.Undo="&Neo-dhèan" -Basic.MainMenu.Edit.Redo="Ath-&dhèan" -Basic.MainMenu.Edit.UndoAction="&Neo-dhèan $1" -Basic.MainMenu.Edit.RedoAction="Ath-&dhèan $1" +Basic.MainMenu.Edit.Undo="Neo-dhèan (&U)" +Basic.MainMenu.Edit.Redo="Ath-dhèan (&R)" +Basic.MainMenu.Edit.UndoAction="Neo-dhèan $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Ath-dhèan $1 (&R)" Basic.MainMenu.Edit.LockPreview="G&lais an ro-shealladh" Basic.MainMenu.Edit.Scale="&Sgèileadh an ro-sheallaidh" Basic.MainMenu.Edit.Scale.Window="Sgèilich ris an uinneag" @@ -435,30 +463,30 @@ Basic.MainMenu.Edit.Transform="&Tar-mhùth" Basic.MainMenu.Edit.Transform.EditTransform="D&easaich an tar-mhùthadh…" Basic.MainMenu.Edit.Transform.CopyTransform="Dèan lethbhreac dhen tar-mhùthadh" Basic.MainMenu.Edit.Transform.PasteTransform="Cuir ann tar-mhùthadh" -Basic.MainMenu.Edit.Transform.ResetTransform="Ath-&shuidhich an tar-mhùthadh" +Basic.MainMenu.Edit.Transform.ResetTransform="Ath-shuidhich an ta&r-mhùthadh" Basic.MainMenu.Edit.Transform.Rotate90CW="Cuairtich gu deiseil le 90 ceum" Basic.MainMenu.Edit.Transform.Rotate90CCW="Cuairtich gu tuathail le 90 ceum" Basic.MainMenu.Edit.Transform.Rotate180="Cuairtich le 180 ceum" Basic.MainMenu.Edit.Transform.FlipHorizontal="T&hoir flip air a’ chòmhnard" -Basic.MainMenu.Edit.Transform.FlipVertical="&Thoir flip gu h-inghearach" +Basic.MainMenu.Edit.Transform.FlipVertical="Thoir flip gu h-inghearach (&V)" Basic.MainMenu.Edit.Transform.FitToScreen="Co-&fhreagair ri meud na sgrìn" Basic.MainMenu.Edit.Transform.StretchToScreen="&Sìn gu meud na sgrìn" -Basic.MainMenu.Edit.Transform.CenterToScreen="Cuir air &meadhan na sgrìn" -Basic.MainMenu.Edit.Order="Òrdu&gh" +Basic.MainMenu.Edit.Transform.CenterToScreen="&Cuir air meadhan na sgrìn" +Basic.MainMenu.Edit.Order="Òrdugh (&O)" Basic.MainMenu.Edit.Order.MoveUp="Gluais s&uas" -Basic.MainMenu.Edit.Order.MoveDown="Gluais &sìos" -Basic.MainMenu.Edit.Order.MoveToTop="Gluais gun bh&arr" +Basic.MainMenu.Edit.Order.MoveDown="Gluais sìos (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Gluais gun bharr (&T)" Basic.MainMenu.Edit.Order.MoveToBottom="Gluais gun &bhonn" Basic.MainMenu.Edit.AdvAudio="Roghainnean &adhartach na fuaime" -Basic.MainMenu.View="&Seall" -Basic.MainMenu.View.Toolbars="&Bàraichean-inneal" +Basic.MainMenu.View="Seall (&V)" +Basic.MainMenu.View.Toolbars="Bàraichean-inneal (&T)" Basic.MainMenu.View.Docks="Docaichean" Basic.MainMenu.View.Docks.ResetUI="Ath-shuidhich an eadar-aghaidh" Basic.MainMenu.View.Docks.LockUI="Glais an eadar-aghaidh" Basic.MainMenu.View.Toolbars.Listboxes="Bogsaichean-&liosta" -Basic.MainMenu.View.SceneTransitions="Tar-&mhùthaidhean an t-seallaidh" -Basic.MainMenu.View.StatusBar="Bàr-s&taide" +Basic.MainMenu.View.SceneTransitions="Tar-mhùthaidhean an t-seallaidh (&C)" +Basic.MainMenu.View.StatusBar="Bàr-&staide" Basic.MainMenu.View.Fullscreen.Interface="Eadar-aghaidh làn-sgrìn" Basic.MainMenu.SceneCollection="Cruinneachadh &sheallaidhean" @@ -470,20 +498,22 @@ Basic.MainMenu.SceneCollection.Export="Às-phortaich cruinneachadh sheallaidhean Basic.MainMenu.Profile.Exists="Tha a’ phròifil ann mu thràth" Basic.MainMenu.SceneCollection.Exists="Tha an cruinneachadh sheallaidhean ann mu thràth" -Basic.MainMenu.Tools="Innea&lan" +Basic.MainMenu.Tools="Innealan (&T)" Basic.MainMenu.Help="Cob&hair" Basic.MainMenu.Help.HelpPortal="&Portal na cobharach" -Basic.MainMenu.Help.Website="&Tadhail air an làrach-lìn" +Basic.MainMenu.Help.Website="Tadhail air an làrach-lìn (&W)" +Basic.MainMenu.Help.Discord="Gabh pàirt ann am frithealaiche &Discord" Basic.MainMenu.Help.Logs="Faidhlichean an &loga" Basic.MainMenu.Help.Logs.ShowLogs="&Seall faidhlichean an loga" Basic.MainMenu.Help.Logs.UploadCurrentLog="Luchdai&ch suas faidhle an loga làithrich" Basic.MainMenu.Help.Logs.UploadLastLog="&Luchdaich suas faidhle an loga mu dheireadh" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Seall an loga làithreach" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Seall an loga làithreach (&V)" Basic.MainMenu.Help.CheckForUpdates="Thoir sùil airson ùrachaidhean" -Basic.MainMenu.Help.CrashLogs="Aithis&gean tuislidh" +Basic.MainMenu.Help.CrashLogs="Aithisgean tuislidh (&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="&Seall na h-aithisgean tuislidh" Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Luchdaich suas an aithisg tuislidh mu dheireadh" +Basic.MainMenu.Help.About="Mu dhèidhinn (&A)" Basic.Settings.ProgramRestart="Feumaidh tu am prògram ath-thòiseachadh gus na roghainnean seo a chur an sàs." Basic.Settings.ConfirmTitle="Dearbh na h-atharraichean" @@ -512,8 +542,13 @@ Basic.Settings.General.SysTray="Treidhe an t-siostaim" Basic.Settings.General.SysTrayWhenStarted="Fìor-lùghdaich gu treidhe an t-siostaim aig an toiseach" Basic.Settings.General.SystemTrayHideMinimize="Fìor-lùghdaich gu treidhe an t-siostaim seach bàr nan saothair an-còmhnaidh" Basic.Settings.General.SaveProjectors="Sàbhail na proiseactaran nuair a thèid fàgail an-seo" +Basic.Settings.General.Preview="Ro-shealladh" +Basic.Settings.General.OverflowHidden="Falaich an taomadh" +Basic.Settings.General.OverflowAlwaysVisible="Seall an taomadh an-còmhnaidh" +Basic.Settings.General.OverflowSelectionHidden="Seall an taomadh fiù ma tha an tùs falaichte" Basic.Settings.General.SwitchOnDoubleClick="Tar-mhùth gu sealladh le briogadh dùbailte" Basic.Settings.General.StudioPortraitLayout="Cuir an comas co-dhealbhachd portraid/inghearach" +Basic.Settings.General.TogglePreviewProgramLabels="Seall na leubailean ro-sheallaidh/prògraim" Basic.Settings.General.Multiview="Ioma-shealladh" Basic.Settings.General.Multiview.MouseSwitch="Briog airson leum a ghearradh eadar seallaidhean" Basic.Settings.General.Multiview.DrawSourceNames="Seall ainmean nan seallaidhean" @@ -527,6 +562,9 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Còmhnard, barr Basic.Settings.Stream="Sruthadh" Basic.Settings.Stream.StreamType="Seòrsa an t-sruthaidh" +Basic.Settings.Stream.Custom.UseAuthentication="Cleachd dearbh-aithneachadh" +Basic.Settings.Stream.Custom.Username="Ainm-cleachdaiche" +Basic.Settings.Stream.Custom.Password="Facal-faire " Basic.Settings.Output="Às-chur" Basic.Settings.Output.Format="Fòrmat a’ chlàraidh" @@ -558,7 +596,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Rabhadh: Ma nì thu clàradh le innea Basic.Settings.Output.Simple.Warn.Lossless="Rabhadh: Cruthaichidh càileachd gun chall faidhlichean uabhasach mòr! Faodaidh càileachd gun chall corr is 7 giga-baidht a dh’àite a chleachdadh air an diosg gach mionaid ma tha an dùmhlachd-bhreacaidh agus an reat fhrèamaichean àrd. Cha mholamaid càileachd gun chall airson clàraidhean fada ach ma tha torr àite agad air an diosg." Basic.Settings.Output.Simple.Warn.Lossless.Msg="A bheil thu cinnteach gu bheil thu airson càileachd gun chall a chleachdadh?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Rabhadh a thaobh càileachd gun chall!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Rabhadh: Chan urrainn dhut iomadh inneal-còdachaidh QSV fa leth a chleachdadh nuair a bhios tu a’ sruthadh ’s a clàradh aig an aon àm. Nam bu toigh leat sruthadh is clàradh aig an aon àm, feuch an atharraich thu inneal-còdachaidh a’ chlàraidh no an t-sruthaidh." Basic.Settings.Output.Simple.Encoder.Software="Bathar-bog (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Bathar-cruaidh (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Bathar-cruaidh (AMD)" @@ -570,7 +607,7 @@ Basic.Settings.Output.Reconnect="Ath-cheangail gu fèin-obrachail" Basic.Settings.Output.RetryDelay="Dàil na feuchainn a-rithist (diog)" Basic.Settings.Output.MaxRetries="Oidhirpean as motha" Basic.Settings.Output.Advanced="Cuir an comas roghainnean adhartach an inneil-chòdachaidh" -Basic.Settings.Output.EncoderPreset="Ro-shuidheachadh an inneil-chòdachaidh (nas àirde = nas lugha dhen CPU)" +Basic.Settings.Output.EncoderPreset="Ro-sheata an inneil-chòdachaidh" Basic.Settings.Output.CustomEncoderSettings="Roghainnean gnàthaichte an inneil-chòdachaidh" Basic.Settings.Output.CustomMuxerSettings="Roghainnean gnàthaichte an iompaicheir" Basic.Settings.Output.NoSpaceFileName="Gin ainm faidhle gun spàs" @@ -643,7 +680,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (sgèileachadh geuraichte, Basic.Settings.Audio="Fuaim" Basic.Settings.Audio.SampleRate="Reat shampallan" Basic.Settings.Audio.Channels="Seanailean" -Basic.Settings.Audio.MeterDecayRate="Reat crìonaidh a’ mheidheadair-fhuaime" Basic.Settings.Audio.MeterDecayRate.Fast="Luath" Basic.Settings.Audio.MeterDecayRate.Medium="Meadhanach (PPM seòrsa I)" Basic.Settings.Audio.MeterDecayRate.Slow="Slaodach (PPM seòrsa II)" @@ -654,16 +690,12 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="RABHADH: Tha fuaim cuairteacha Basic.Settings.Audio.MultichannelWarning="Ma tha thu a’ dèanamh sruthadh, dearbh gun doir an t-seirbheis sruthaidh agad taic an dà chuid ri ion-chur is cluich fuaime cuairteachaidh. Mar eisimpleir, cuiridh Twitch, Facebook 360 Live, Mixer RTMP is Smashcast làn-taic ri fuaim cuairteachaidh. Ged a ghabhas Facebook Live is youTube Live ri sruthan fuaime cuairteachaidh, nì Facebook Live measgachadh sìos stereo dheth agus cha chluich YouTube live ach dà sheanail.\n\nTha criathragan fuaime OBS co-chòrdail ri fuaim cuairteachaidh ged nach doir sinn barantas gun obraich plugain VST." Basic.Settings.Audio.MultichannelWarning.Title="A bheil thu airson fuaim cuairteachaidh a chur an comas?" Basic.Settings.Audio.MultichannelWarning.Confirm="A bheil thu cinnteach gu bheil thu airson fuaim cuairteachaidh a chur an comas?" -Basic.Settings.Audio.DesktopDevice="Uidheam fuaime an deasg" -Basic.Settings.Audio.DesktopDevice2="Uidheam fuaime an deasg 2" -Basic.Settings.Audio.AuxDevice="Uidheam fuaime micreofoin/taice" -Basic.Settings.Audio.AuxDevice2="Uidheam fuaime micreofoin/taice 2" -Basic.Settings.Audio.AuxDevice3="Uidheam fuaime micreofoin/taice 3" Basic.Settings.Audio.EnablePushToMute="Cuir an comas brùth-airson-mùchadh" Basic.Settings.Audio.PushToMuteDelay="Dàil air brùth-airson-mùchadh" Basic.Settings.Audio.EnablePushToTalk="Cuir an comas brùth-airson-bruidhinn" Basic.Settings.Audio.PushToTalkDelay="Dàil air brùth-airson-bruidhinn" Basic.Settings.Audio.UnknownAudioDevice="[Chan eil uidheam ceangailte no ri fhaighinn]" +Basic.Settings.Audio.Disabled="À comas" Basic.Settings.Advanced="Adhartach" Basic.Settings.Advanced.General.ProcessPriority="Prìomhachas a’ phròiseis" @@ -672,14 +704,11 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Nas àirde na àbha Basic.Settings.Advanced.General.ProcessPriority.Normal="Àbhaisteach" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Nas ìsle na àbhaisteach" Basic.Settings.Advanced.General.ProcessPriority.Idle="’Na tàmh" -Basic.Settings.Advanced.FormatWarning="Rabhadh: Chaidh fòrmatan datha seach NV12 a dhealbhachadh a chum clàraidh agus cha molamaid airson sruthadh iad. Cleachdaidh an sruthadh barrachd dhen CPU ri linn iompachadh air fòrmat nan dathan." +Basic.Settings.Advanced.FormatWarning="Rabhadh: Chaidh fòrmatan datha seach NV12 a dhealbhachadh a chum clàraidh agus cha molamaid airson sruthadh iad. Cleachdaidh an sruthadh barrachd dhen CPU ri linn iompachadh air fòrmat nan dathan." Basic.Settings.Advanced.Audio.BufferingTime="Ùine bufair na fuaime" Basic.Settings.Advanced.Video.ColorFormat="Fòrmat nan dathan" -Basic.Settings.Advanced.Video.ColorSpace="Spàs dhathan YUV" -Basic.Settings.Advanced.Video.ColorRange="Rainse dhathan YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Leth-phàirteach" Basic.Settings.Advanced.Video.ColorRange.Full="Làn" -Basic.Settings.Advanced.Audio.MonitoringDevice="Uidheam sgrùdadh fuaime" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Tùsail" Basic.Settings.Advanced.Audio.DisableAudioDucking="Cuir à comas tumadh fuaime Windows" Basic.Settings.Advanced.StreamDelay="Dàil an t-sruthaidh" @@ -691,12 +720,13 @@ Basic.Settings.Advanced.Network.BindToIP="Nasg ri IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Cuir an comas an còd lìonraidh ùr" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modh foillidheachd ìosail" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Cuir à comas na grad-iuchraichean nuair a bhios am fòcas air a’ phrìomh-uinneag" +Basic.Settings.Advanced.AutoRemux="Iompaich gu mp4 gu fèin-obrachail" +Basic.Settings.Advanced.AutoRemux.MP4="(clàraich mar mkv)" Basic.AdvAudio="Roghainnean adhartach na fuaime" Basic.AdvAudio.Name="Ainm" -Basic.AdvAudio.Volume="Àirde (%)" Basic.AdvAudio.Mono="Measgaich sìos gu mono" -Basic.AdvAudio.Panning="Panachadh" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Frìth-àireamh an t-sioncronachaidh (ms)" Basic.AdvAudio.Monitoring="Sgrùdadh fuaime" Basic.AdvAudio.Monitoring.None="Gun sgrùdadh" @@ -706,6 +736,7 @@ Basic.AdvAudio.AudioTracks="Tracaichean" Basic.Settings.Hotkeys="Grad-iuchraichean" Basic.Settings.Hotkeys.Pair="Nì na co-iuchraichean a tha ’gan co-roinneadh le “%1” toglachadh" +Basic.Settings.Hotkeys.Filter="Criathrag" Basic.Hotkeys.SelectScene="Gearr leum dhan t-sealladh" @@ -760,11 +791,29 @@ SceneItemHide="Falaich “%1”" OutputWarnings.NoTracksSelected="Feumaidh tu traca no dhà a thaghadh" OutputWarnings.MultiTrackRecording="Rabhadh: Tha fòrmatan ann (can FLV) nach cuir taic ri iomadh traca sa chlàradh" -OutputWarnings.MP4Recording="Rabhadh: Cha ghabh clàraidhean a thèid a shàbhaladh gu MP4 aiseag mura gabh am faidhle a thoirt gu crìch (can ri linn tuisleachaidh, call cumhachd is msaa.). Nam bu toigh leat iomadh traca fuaime a chlàradh, mholamaid gun cleachd thu MKV agus gun iompaich thu an clàradh gu mp4 nuair a bhios e deiseil (Faidhle->Iompaich clàraidhean)" FinalScene.Title="Sguab às an sealladh" FinalScene.Text="Feumaidh do shealladh a bhith ann." - +NoSources.Title="Gun tùs" +NoSources.Text="Tha coltas nach do chuir thu tùs video ris fhathast ’s mar sin chan fhaigh thu ach sgrìn bhàn. A bheil thu cinnteach gu bheil thu airson seo a dhèanamh?" +NoSources.Text.AddSource="’S urrainn dhut tùsan a chur ris uair sam bith ’s tu a’ briogadh air an ìomhaigheag “+” fon bhogsa “Tùsan” air a’ phrìomh-uinneag." + +ChangeBG="Suidhich an dath" +CustomColor="Dath gnàthaichte" + +BrowserSource.EnableHardwareAcceleration="Cuir an comas an luathachadh bathair-chruaidh aig tùs a’ bhrabhsair" + +About="Mu dhèidhinn" +About.Info="’S e bathar-bog saor is open source airson clàradh video is sruthadh beò a th’ ann an OBS Studio." +About.Donate="Thoir tìodhlac dhuinn" +About.GetInvolved="Gabh pàirt" +About.Authors="Ùghdaran" +About.License="Ceadachas" +About.Contribute="Cuidich am pròiseact OBS" + +ResizeOutputSizeOfSource="Atharraich meud an às-chuir (meud an tùis)" +ResizeOutputSizeOfSource.Text="Thèid meud na dùmhlachd-bhreacaidh bunasaich ’s tè an às-chuir a shuidheachadh air meud an tùis làithrich." +ResizeOutputSizeOfSource.Continue="A bheil thu airson leantainn air adhart?" diff --git a/UI/data/locale/gl-ES.ini b/UI/data/locale/gl-ES.ini index c90dfc7..7792f47 100644 --- a/UI/data/locale/gl-ES.ini +++ b/UI/data/locale/gl-ES.ini @@ -54,6 +54,10 @@ Bottom="Abaixo" + + + + Basic.AddTransition="Engadir transición configurable" Basic.RemoveTransition="Eliminar transición configurable" Basic.TransitionProperties="Propiedades da transición" @@ -77,18 +81,21 @@ ConfirmStart.Title="Iniciar transmisión?" ConfirmStop.Title="Deter transmisión?" ConfirmStop.Text="Tes a certeza de querer deter a transmisión?" + ConfirmExit.Title="Saír de OBS?" ConfirmRemove.Title="Confirmar a eliminación" ConfirmRemove.Text="Tes a certeza de querer eliminar '$1'?" + Output.ConnectFail.Title="Erro ao se conectar" Output.ConnectFail.BadPath="Camiño ou URL de conexión non válidos. Por favor, comproba a configuración para confirmar de que son correctos." Output.ConnectFail.ConnectFailed="Erro ao conectar co servidor" Output.ConnectFail.Error="Produciuse un erro inesperado ao tentar conectar co servidor. Máis información no ficheiro de rexistro." Output.ConnectFail.Disconnected="Desconectado do servidor." + Output.RecordFail.Title="Erro ao iniciar a gravación" Output.BadPath.Title="Camiño do ficheiro incorrecto" @@ -98,27 +105,17 @@ LogReturnDialog="Carga de rexistro satisfactoria" LogReturnDialog.CopyURL="Copiar URL" LogReturnDialog.ErrorUploadingLog="Erro ao cargar o ficheiro de rexistro" -LicenseAgreement="Acordo de licenza" -LicenseAgreement.PleaseReview="Por favor, revisa os termos da licenza antes de usar OBS. Ao usares este programa, admites que liches e aceptas os termos da GNU General Public License v2.0. Desprázate cara a abaixo para ver o resto do acordo." -LicenseAgreement.ClickIAgreeToContinue="Se aceptas estes termos, preme en Estou de acordo para continuar. Debes aceptar o acordo para poder usar OBS." -LicenseAgreement.IAgree="Estou de acordo" -LicenseAgreement.Exit="Saír" - Remux.SourceFile="Gravación OBS" Remux.TargetFile="Ficheiro de destino" Remux.Remux="Converter" Remux.FinishedTitle="Conversión rematada" Remux.Finished="Gravando conversión" Remux.FinishedError="Gravación convertida, mais o ficheiro podería estar incompleto" -Remux.SelectRecording="Seleccionar gravación OBS…" -Remux.SelectTarget="Seleccionar ficheiro de destino…" -Remux.FileExistsTitle="O ficheiro de destino xa existe" -Remux.FileExists="O ficheiro de destino xa existe, queres substituílo?" Remux.ExitUnfinishedTitle="Conversión en marcha" Remux.ExitUnfinished="A conversión non rematou, detela agora podería provocar que o ficheiro final fose inutilizable.\nTes a certeza de querer deter a conversión?" UpdateAvailable="Nova actualización dispoñible" -UpdateAvailable.Text="Versión %1.%2.%3 xa dispoñible. Preme aquí para descargala" +UpdateAvailable.Text="Versión %1.%2.%3 xa dispoñible. Preme aquí para descargala" Basic.DesktopDevice1="Audio do escritorio" Basic.DesktopDevice2="Audio do escritorio 2" @@ -135,6 +132,7 @@ Basic.Main.PreviewConextMenu.Enable="Habilitar vista previa" + Basic.Main.AddSceneDlg.Title="Engadir escena" Basic.Main.AddSceneDlg.Text="Por favor, insire un nome para a escena" @@ -226,15 +224,15 @@ Basic.Main.StopStreaming="Deter retransmisión" Basic.MainMenu.File="&Ficheiro" Basic.MainMenu.File.Export="&Exportar" Basic.MainMenu.File.Import="&Importar" -Basic.MainMenu.File.ShowRecordings="Mostrar &gravacións" -Basic.MainMenu.File.Remux="Conversións gardadas" -Basic.MainMenu.File.Settings="&Axustes" -Basic.MainMenu.File.Exit="&Saír" +Basic.MainMenu.File.ShowRecordings="Most&rar gravacións" +Basic.MainMenu.File.Remux="Conversións gardadas (&M)" +Basic.MainMenu.File.Settings="Axu&stes" +Basic.MainMenu.File.Exit="Saír (&X)" Basic.MainMenu.Edit="&Editar" -Basic.MainMenu.Edit.Undo="&Desfacer" +Basic.MainMenu.Edit.Undo="Desfacer (&U)" Basic.MainMenu.Edit.Redo="&Refacer" -Basic.MainMenu.Edit.UndoAction="&Desfacer $1" +Basic.MainMenu.Edit.UndoAction="Desfacer $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Refacer $1" Basic.MainMenu.Edit.Transform="&Transformar" Basic.MainMenu.Edit.Transform.EditTransform="&Editar transformación..." @@ -244,27 +242,27 @@ Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotar 90 graos contra o sentido das a Basic.MainMenu.Edit.Transform.Rotate180="Rotar 180 graos" Basic.MainMenu.Edit.Transform.FlipHorizontal="Virar &horizontalmente" Basic.MainMenu.Edit.Transform.FlipVertical="Virar &verticalmente" -Basic.MainMenu.Edit.Transform.FitToScreen="&Axustar á pantalla" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Estricar á pantalla" +Basic.MainMenu.Edit.Transform.FitToScreen="Axustar á pantalla (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="E&stricar á pantalla" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrar na pantalla" Basic.MainMenu.Edit.Order="&Ordenar" -Basic.MainMenu.Edit.Order.MoveUp="Subir" -Basic.MainMenu.Edit.Order.MoveDown="Baixar" -Basic.MainMenu.Edit.Order.MoveToTop="Levar para a cima" -Basic.MainMenu.Edit.Order.MoveToBottom="Levar para abaixo" +Basic.MainMenu.Edit.Order.MoveUp="S&ubir" +Basic.MainMenu.Edit.Order.MoveDown="Baixar (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Levar para a cima (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Levar para a&baixo" Basic.MainMenu.Edit.AdvAudio="Propiedades de audio &avanzadas" -Basic.MainMenu.SceneCollection="&Colección de escenas" +Basic.MainMenu.SceneCollection="Colección de e&scenas" Basic.MainMenu.Profile="&Perfil" -Basic.MainMenu.Help="&Axuda" +Basic.MainMenu.Help="Axuda (&H)" Basic.MainMenu.Help.Website="Visitar sitio &web" -Basic.MainMenu.Help.Logs="&Ficheiros de rexistro" +Basic.MainMenu.Help.Logs="Ficheiros de rexistro (&L)" Basic.MainMenu.Help.Logs.ShowLogs="Mostrar ficheiro&s de rexistro" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Subir &ficheiro de rexistro actual" -Basic.MainMenu.Help.Logs.UploadLastLog="Subir o &último ficheiro de rexistro" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Subir fi&cheiro de rexistro actual" +Basic.MainMenu.Help.Logs.UploadLastLog="Subir o ú<imo ficheiro de rexistro" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver rexistro actual" Basic.MainMenu.Help.CheckForUpdates="Comprobar se hai actualizacións" @@ -295,7 +293,6 @@ Basic.Settings.Output.Reconnect="Reconectar automaticamente" Basic.Settings.Output.RetryDelay="Retardo da nova tentativa (segundos)" Basic.Settings.Output.MaxRetries="Número máximo de tentativas" Basic.Settings.Output.Advanced="Activar a configuración do codificador avanzada" -Basic.Settings.Output.EncoderPreset="Perfil de codificador (máis rápido = menos CPU)" Basic.Settings.Output.CustomEncoderSettings="Axustes do codificador personalizados" Basic.Settings.Output.Adv.Rescale="Cambiar a escala de saída" @@ -330,18 +327,18 @@ Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Axustes do codificador de aud Basic.Settings.Video="Vídeo" -Basic.Settings.Video.Adapter="Adaptador de vídeo:" -Basic.Settings.Video.DownscaleFilter="Filtro de redución:" +Basic.Settings.Video.Adapter="Adaptador de vídeo" +Basic.Settings.Video.DownscaleFilter="Filtro de redución" Basic.Settings.Video.DisableAeroWindows="Desactivar Aero (só Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valores comúns de FPS" Basic.Settings.Video.FPSInteger="Valor enteiro de FPS" Basic.Settings.Video.FPSFraction="Valor fraccional de FPS" -Basic.Settings.Video.Numerator="Numerador:" -Basic.Settings.Video.Denominator="Denominador:" -Basic.Settings.Video.Renderer="Procesador:" -Basic.Settings.Video.InvalidResolution="Valor da resolución non válido. Debe ser [width] x [height] (por exemplo, 1920 x 1080)" -Basic.Settings.Video.CurrentlyActive="A saída de vídeo está actualmente activa. Por favor, apaga calquera saída para cambiar a configuración de vídeo." +Basic.Settings.Video.Numerator="Numerador" +Basic.Settings.Video.Denominator="Denominador" +Basic.Settings.Video.Renderer="Procesador" +Basic.Settings.Video.InvalidResolution="Valor da resolución non válido. Debe ser [width] x [height] (por exemplo, 1920 x 1080)" +Basic.Settings.Video.CurrentlyActive="A saída de vídeo está actualmente activa. Por favor, apaga calquera saída para cambiar a configuración de vídeo." Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (máis rápido, pero borroso de se escalar a imaxe)" Basic.Settings.Video.DownscaleFilter.Bicubic="Bicúbico (escalamento fino, 16 mostras)" @@ -350,25 +347,16 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento fino, 32 most Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Intervalo da mostra" Basic.Settings.Audio.Channels="Canles" -Basic.Settings.Audio.DesktopDevice="Dispositivo de audio de escritorio" -Basic.Settings.Audio.DesktopDevice2="Dispositivo de audio de escritorio 2" -Basic.Settings.Audio.AuxDevice="Dispositivo de audio mic./auxiliar" -Basic.Settings.Audio.AuxDevice2="Dispositivo de audio mic./auxiliar 2" -Basic.Settings.Audio.AuxDevice3="Dispositivo de audio mic./auxiliar 3" Basic.Settings.Advanced="Avanzado" Basic.Settings.Advanced.Audio.BufferingTime="Tempo do búfer de audio" Basic.Settings.Advanced.Video.ColorFormat="Formato da cor" -Basic.Settings.Advanced.Video.ColorSpace="Espazo de cor YUV" -Basic.Settings.Advanced.Video.ColorRange="Gama de cor YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" Basic.Settings.Advanced.Video.ColorRange.Full="Completo" Basic.AdvAudio="Propiedades de audio avanzadas" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Volume="Volume (%)" Basic.AdvAudio.Mono="Remesturar a mono" -Basic.AdvAudio.Panning="Panorámica" Basic.AdvAudio.SyncOffset="Sincronización Offset (ms)" Basic.AdvAudio.AudioTracks="Pistas" @@ -416,3 +404,6 @@ OutputWarnings.MultiTrackRecording="Aviso: certos formatos (caso de FLV) non adm + + + diff --git a/UI/data/locale/he-IL.ini b/UI/data/locale/he-IL.ini index 0f8e6a0..5cf71f4 100644 --- a/UI/data/locale/he-IL.ini +++ b/UI/data/locale/he-IL.ini @@ -49,7 +49,7 @@ Duplicate="שכפל" Enable="אפשר" DisableOSXVSync="בטל סנכרון אנכי OSX" ResetOSXVSyncOnExit="איפוס סנכרון אנכי OSX ביציאה" -HighResourceUsage="קידוד עמוס מידי! שקול להנמיך הגדרות וידאו או שימוש בקידוד מהיר יותר." +HighResourceUsage="קידוד עמוס מידי! שקול להנמיך הגדרות וידאו או שימוש בקידוד מהיר יותר." Transition="מעבר" QuickTransitions="מעברים מהירים" Left="שמאל" @@ -78,26 +78,33 @@ None="ללא" StudioMode.Preview="תצוגה מקדימה" StudioMode.Program="תוכנה" ShowInMultiview="הראה בתצוגה מרובה" +Group="קבוצה" AlreadyRunning.Title="OBS פועל כבר" -AlreadyRunning.Text="OBS פועל כבר! אלא אם התכוונת לעשות את זה, אנא סגור כל מופע קיים לפני נסיון להפעיל מופע חדש. אנא בדוק אם קיים מופע הגדר ממוזער במגש המערכת." +AlreadyRunning.Text="OBS פועל כבר! אלא אם התכוונת לעשות את זה, אנא סגור כל מופע קיים לפני נסיון להפעיל מופע חדש. אנא בדוק אם קיים מופע הגדר ממוזער במגש המערכת." AlreadyRunning.LaunchAnyway="הפעל בכל מקרה" + +Auth.AuthFailure.Title="האימות נכשל" +Auth.InvalidScope.Title="דרושה הזדהות" +Auth.ChannelFailure.Title="נכשל בטעינת הערוצים" +Auth.Chat="צ'אט" +Auth.StreamInfo="מידע על הזרם" + Copy.Filters="העתק מסננים" Paste.Filters="הדבק מסננים" + BandwidthTest.Region="אזור" BandwidthTest.Region.US="ארצות הברית" BandwidthTest.Region.EU="אירופה" BandwidthTest.Region.Asia="אסיה" BandwidthTest.Region.Other="אחר" -Basic.FirstStartup.RunWizard="האם ברצונך להפעיל את אשף קביעת התצורה האוטומטית? באפשרותך להגדיר את ההגדרות באופן ידני על ידי לחיצה על הלחצן ' קביעות ' בחלון הראשי." -Basic.FirstStartup.RunWizard.BetaWarning="(הערה: אשף קביעת התצורה האוטומטית הוא כרגע בגרסת ביתא)" +Basic.FirstStartup.RunWizard="האם ברצונך להפעיל את אשף קביעת התצורה האוטומטית? באפשרותך להגדיר את ההגדרות באופן ידני על ידי לחיצה על הלחצן ' קביעות ' בחלון הראשי." Basic.FirstStartup.RunWizard.NoClicked="אם תשנה את דעתך, באפשרותך להפעיל שוב את אשף קביעת התצורה האוטומטית בכל עת מתפריט הכלים." Basic.AutoConfig="אשף תצורה אוטומטית" -Basic.AutoConfig.Beta="אשף קביעת התצורה האוטומטית (ביתא)" Basic.AutoConfig.ApplySettings="החל הגדרות" Basic.AutoConfig.StartPage="מידע אודות השימוש" Basic.AutoConfig.StartPage.SubTitle="ציין עבור מה ברצונך להשתמש בתוכנית" @@ -110,9 +117,14 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="תצוגה %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="השתמש בנוכחי (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 או 30, אבל העדף 60 כאשר אפשרי" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 או 30, אבל העדף רזולוציה גבוהה" -Basic.AutoConfig.VideoPage.CanvasExplanation="הערה: רזוליית הבד (בסיס) הוא לא בהכרח זהה לרזולוצי ההזרמה או הקלטה. ייתכן שרזולוציית הזרמה/הקלטה תוקטן בכדי להפחית את דרישות קצב הנתונים או המשאבים." +Basic.AutoConfig.VideoPage.CanvasExplanation="הערה: רזוליית הבד (בסיס) הוא לא בהכרח זהה לרזולוצי ההזרמה או הקלטה. ייתכן שרזולוציית הזרמה/הקלטה תוקטן בכדי להפחית את דרישות קצב הנתונים או המשאבים." Basic.AutoConfig.StreamPage="מידע על הזרם" Basic.AutoConfig.StreamPage.SubTitle="אנא הזן את פרטי הזרם" +Basic.AutoConfig.StreamPage.ConnectAccount="התחבר לחשבון (אופציונלי)" +Basic.AutoConfig.StreamPage.DisconnectAccount="נתק את חשבון" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="נתק את חשבון?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="שינוי זה יחול באופן מיידי. האם אתה בטוח שברצונך לנתק את החשבון שלך?" +Basic.AutoConfig.StreamPage.UseStreamKey="השתמש במפתח הזרמת נתונים" Basic.AutoConfig.StreamPage.Service="שירות" Basic.AutoConfig.StreamPage.Service.ShowAll="הצג הכל..." Basic.AutoConfig.StreamPage.Server="שרת" @@ -138,11 +150,10 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="בדיקת %1x%2 %3 מסגרו Basic.AutoConfig.TestPage.Result.StreamingEncoder="מקודד זרימה" Basic.AutoConfig.TestPage.Result.RecordingEncoder="מקודד הקלטה" Basic.AutoConfig.TestPage.Result.Header="התוכנית קבעה כי אלה ההגדרות המיטביות עבורך:" -Basic.AutoConfig.TestPage.Result.Footer="כדי להשתמש בהגדרות אלה, לחץ על החל הגדרות. כדי להגדיר מחדש את האשף ולנסות שוב, לחץ על אחורה. להגדיר ידנית את הגדרות, לחץ על ביטול ולאחר מכן פתח את הגדרות." +Basic.AutoConfig.TestPage.Result.Footer="כדי להשתמש בהגדרות אלה, לחץ על החל הגדרות. כדי להגדיר מחדש את האשף ולנסות שוב, לחץ על אחורה. להגדיר ידנית את הגדרות, לחץ על ביטול ולאחר מכן פתח את הגדרות." Basic.Stats="סטטיסטיקות" Basic.Stats.CPUUsage="שימוש במעבד" -Basic.Stats.HDDSpaceAvailable="שטח דיסק קשיח זמין" Basic.Stats.MemoryUsage="שימוש בזיכרון" Basic.Stats.AverageTimeToRender="הזמן הממוצע לעיבוד מסגרת" Basic.Stats.SkippedFrames="המערכת דילגה על מסגרות עקב השהית קידוד" @@ -158,6 +169,7 @@ Basic.Stats.DroppedFrames="השמטת מסגרות (רשת)" Basic.Stats.MegabytesSent="פלט נתונים כולל" Basic.Stats.Bitrate="קצב נתונים" + Updater.Title="עידכון חדש זמין" Updater.Text="יש עדכון חדש זמין:" Updater.UpdateNow="עדכן עכשיו" @@ -169,7 +181,6 @@ Updater.NoUpdatesAvailable.Title="אין עדכונים זמינים" Updater.NoUpdatesAvailable.Text="אין עדכונים זמינים כעת" Updater.FailedToLaunch="נכשלה הפעלת העידכון" Updater.GameCaptureActive.Title="לכידת משחק פעיל" -Updater.GameCaptureActive.Text="לכידת משחק נמצאת כעת בשימוש. בבקשה סגור את המשחקים/תוכנות שנמצאים בלכידה (או הפעל מחדש את ווינדוס) ונסה שינת." QuickTransitions.SwapScenes="החלף סצינות תצוגה מקדימה/פלט לאחר המעבר" QuickTransitions.SwapScenesTT="החלף הסצינות של התצוגה המקדימה ושל הפלט לאחר המעבר (באם הסצינה המקורית של הפלט עדיין קיימת). \n פעולה זו לא תבטל כל שינוי שייתכן ובוצע לסצינה המקורית של הפלט." @@ -204,8 +215,9 @@ ConfirmStart.Text="האם אתה בטוח שברצונך להפעיל את הז ConfirmStop.Title="עצור את הזרמת הנתונים?" ConfirmStop.Text="האם אתה בטוח שברצונך להפסיק את הזרמת הנתונים?" + ConfirmExit.Title="יציאה מ-OBS?" -ConfirmExit.Text="תוכנת OBS פעילה כעת. כל הזרמת נתונים/הקלטות ייסגרו. האם אתה בטוח שאתה רוצה לצאת?" +ConfirmExit.Text="תוכנת OBS פעילה כעת. כל הזרמת נתונים/הקלטות ייסגרו. האם אתה בטוח שאתה רוצה לצאת?" ConfirmRemove.Title="אשר הסרה" ConfirmRemove.Text="האם אתה בטוח שברצונך להסיר את '$1'?" @@ -216,15 +228,17 @@ Output.StartRecordingFailed="נכשלה הפעלת הקלטה" Output.StartReplayFailed="נכשלה הפעלת מאגר החוזר" Output.StartFailedGeneric="הפלט נכשל. בבקשה בדוק את הרישומים עבור. \n\nNote: אם אתה משתמש בNVNEC או AMD מקודדים, הקפד שמנהלי ההתקן של הכרטיס מסך מעודכנים." + Output.ConnectFail.Title="ההתחברות נכשלה" -Output.ConnectFail.BadPath="URL לא חוקי של נתיב או חיבור. נא בדוק את ההגדרות שלך כדי לוודא כי הם נכונים." +Output.ConnectFail.BadPath="URL לא חוקי של נתיב או חיבור. נא בדוק את ההגדרות שלך כדי לוודא כי הם נכונים." Output.ConnectFail.ConnectFailed="ההתחברות לשרת נכשלה" Output.ConnectFail.InvalidStream="לא ניתן להתחבר לערוץ שצויין או למפתח זרם הנתונים, נא בדוק שנית את מפתח זרם הנתונים. אם הוא נכון, ככל הנראה יש בעיה בהתחברות לשרת." -Output.ConnectFail.Error="אירעה שגיאה בלתי צפויה בעת ניסיון להתחבר לשרת. מידע נוסף בקובץ יומן הרישום." +Output.ConnectFail.Error="אירעה שגיאה בלתי צפויה בעת ניסיון להתחבר לשרת. מידע נוסף בקובץ יומן הרישום." Output.ConnectFail.Disconnected="התנתקת מהשרת." + Output.RecordFail.Title="התחלת ההקלטה נכשלה" -Output.RecordFail.Unsupported="תבנית הפלט לא נתמכת או לא תומכת ביותר מרצועת שמע אחת. נא בדוק את ההגדרות ונסה שוב." +Output.RecordFail.Unsupported="תבנית הפלט לא נתמכת או לא תומכת ביותר מרצועת שמע אחת. נא בדוק את ההגדרות ונסה שוב." Output.RecordNoSpace.Title="אין די שטח דיסק" Output.RecordNoSpace.Msg="אין די שטח דיסק כדי להמשיך הקלטה." Output.RecordError.Title="שגיאה הקלטה" @@ -233,18 +247,12 @@ Output.ReplayBuffer.NoHotkey.Title="אין מקש קיצור שנבחר!" Output.ReplayBuffer.NoHotkey.Msg="אין hotkey שמור למאגר החוזר. בבקשה הגדר את \"שמור\" hotkey לשימוש עבור שמירת מאגר חוזר להקלטות." Output.BadPath.Title="נתיב קובץ לא תקין" -Output.BadPath.Text="נתיב פלט הקובץ שהוגדר אינו חוקי. נא בדוק את הגדרות כדי לוודא שנתיב קובץ תקני נקבע." +Output.BadPath.Text="נתיב פלט הקובץ שהוגדר אינו חוקי. נא בדוק את הגדרות כדי לוודא שנתיב קובץ תקני נקבע." LogReturnDialog="עידכון יומן הצליח" LogReturnDialog.CopyURL="העתק קישור" LogReturnDialog.ErrorUploadingLog="עידכון קובץ יומן נכשל" -LicenseAgreement="הסכם רשיון" -LicenseAgreement.PleaseReview="אנא קרא את תנאי רשיון לפני השימוש בתוכנית זו.בשימוש בתוכנית אתה מכיר בעובדה כי יש לקרוא ולהסכים לתנאים המופיעים ב הרישיון הציבורי הכללי של גנו v 2.0. נא גלול למטה כדי לראות את שאר ההסכם." -LicenseAgreement.ClickIAgreeToContinue="אם אתה מקבל את תנאי ההסכם, לחץ על אני מסכים בכדי להמשיך. עליך לקבל ההסכם בכדי להשתמש בתוכנת OBS." -LicenseAgreement.IAgree="אני מסכים" -LicenseAgreement.Exit="יציאה" - Remux.SourceFile="הקלטת OBS" Remux.TargetFile="קובץ היעד" Remux.Remux="המרה" @@ -252,15 +260,11 @@ Remux.OBSRecording="הקלטת OBS" Remux.FinishedTitle="המרה הסתיימה" Remux.Finished="הקלטה הומרה" Remux.FinishedError="הקלטה הומרה, אבל הקובץ עשוי להיות לא שלם" -Remux.SelectRecording="בחר הקלטת OBS…" -Remux.SelectTarget="בחר קובץ יעד…" -Remux.FileExistsTitle="קובץ היעד קיים" -Remux.FileExists="קובץ היעד קיים, האם ברצונך להחליפו?" Remux.ExitUnfinishedTitle="המרה בתהליך" Remux.ExitUnfinished="ההמרה לא הסתיימה, עצירה עכשיו עלולה להפוך את קובץ היעד לא שמיש. \n אתה בטוח שאתה רוצה לעצור את ההמרה?" UpdateAvailable="עידכון חדש זמין" -UpdateAvailable.Text="גירסה %1.%2.%3 זמין כעת. לחץ כאן כדי להוריד" +UpdateAvailable.Text="גירסה %1.%2.%3 זמין כעת. לחץ כאן כדי להוריד" Basic.DesktopDevice1="אודיו שולחן עבודה" Basic.DesktopDevice2="אודיו שולחן עבודה 2" @@ -274,6 +278,7 @@ Basic.DisplayCapture="הצג לכידת מסך" Basic.Main.PreviewConextMenu.Enable="אפשר תצוגה מקדימה" + ScaleFiltering="מסנן קנה מידה" ScaleFiltering.Point="נקודה" ScaleFiltering.Bilinear="ביליניארי" @@ -328,7 +333,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (בחירה אוטומטית: %2)" Basic.PropertiesWindow.SelectColor="בחר צבע" Basic.PropertiesWindow.SelectFont="בחר גופן" Basic.PropertiesWindow.ConfirmTitle="הגדרות שונו" -Basic.PropertiesWindow.Confirm="יש שינויים שלא נשמרו. האם ברצונך לשמור אותם?" +Basic.PropertiesWindow.Confirm="יש שינויים שלא נשמרו. האם ברצונך לשמור אותם?" Basic.PropertiesWindow.NoProperties="אין מאפיינים זמינים" Basic.PropertiesWindow.AddFiles="הוסף קבצים" Basic.PropertiesWindow.AddDir="הוסף ספריה" @@ -405,6 +410,9 @@ Basic.Main.StoppingReplayBuffer="עצירת מאגר החוזר..." Basic.Main.StopStreaming="עצור זרם נתונים" Basic.Main.StoppingStreaming="עוצר זרם נתונים..." Basic.Main.ForceStopStreaming="עצור זרם נתונים (בטל השהייה)" +Basic.Main.Group="קבוצה %1" +Basic.Main.GroupItems="קבץ פריטים נבחרים" +Basic.Main.Ungroup="פירוק קבוצה" Basic.MainMenu.File="קובץ(&F)" Basic.MainMenu.File.Export="ייצא(&E)" @@ -415,15 +423,15 @@ Basic.MainMenu.File.Settings="הגדרות(&S)" Basic.MainMenu.File.ShowSettingsFolder="הצג תיקיית הגדרות" Basic.MainMenu.File.ShowProfileFolder="הצג תיקיית פרופיל" Basic.MainMenu.AlwaysOnTop="תמיד עליון(&A)" -Basic.MainMenu.File.Exit="יציאה(&E)" +Basic.MainMenu.File.Exit="יציאה(E) (&X)" Basic.MainMenu.Edit="ערוך(&E)" Basic.MainMenu.Edit.Undo="בטל(&U)" Basic.MainMenu.Edit.Redo="בצע שוב(&R)" Basic.MainMenu.Edit.UndoAction="בטל $1(&U)" Basic.MainMenu.Edit.RedoAction="בצע שוב $1(&R)" -Basic.MainMenu.Edit.LockPreview="&נעילת תצוגה מקדימה" -Basic.MainMenu.Edit.Scale="תצוגה מקדימה & שינוי קנה מידה" +Basic.MainMenu.Edit.LockPreview="נעילת תצוגה מקדימה (&L)" +Basic.MainMenu.Edit.Scale="תצוגה מקדימה שינוי קנה מידה (&S)" Basic.MainMenu.Edit.Scale.Window="שינוי קנה מידה לחלון" Basic.MainMenu.Edit.Scale.Canvas="בד (%1x%2)" Basic.MainMenu.Edit.Scale.Output="פלט (%1x%2)" @@ -447,14 +455,14 @@ Basic.MainMenu.Edit.Order.MoveToTop="הזז לקצה עליון(&T)" Basic.MainMenu.Edit.Order.MoveToBottom="הזז לקצה תחתון(&B)" Basic.MainMenu.Edit.AdvAudio="מאפייני קול מתקדמים(&A)" -Basic.MainMenu.View="&מבט" -Basic.MainMenu.View.Toolbars="&סרגלי כלים" +Basic.MainMenu.View="מבט (&V)" +Basic.MainMenu.View.Toolbars="סרגלי כלים (&T)" Basic.MainMenu.View.Docks="עגינה" Basic.MainMenu.View.Docks.ResetUI="איפוס UI" Basic.MainMenu.View.Docks.LockUI="נעילת UI" -Basic.MainMenu.View.Toolbars.Listboxes="&תיבות רשימה" -Basic.MainMenu.View.SceneTransitions="&מעברי סצינות" -Basic.MainMenu.View.StatusBar="&שורת מצב" +Basic.MainMenu.View.Toolbars.Listboxes="תיבות רשימה (&L)" +Basic.MainMenu.View.SceneTransitions="מעברי סצינות (&C)" +Basic.MainMenu.View.StatusBar="שורת מצב (&S)" Basic.MainMenu.View.Fullscreen.Interface="ממשק מסך מלא" Basic.MainMenu.SceneCollection="אוסף סצינות(&S)" @@ -466,21 +474,23 @@ Basic.MainMenu.SceneCollection.Export="ייצא אוסף סצנות" Basic.MainMenu.Profile.Exists="הפרופיל קיים כבר" Basic.MainMenu.SceneCollection.Exists="אוסף הסצנות כבר קיים" -Basic.MainMenu.Tools="& כלים" +Basic.MainMenu.Tools="כלים (&T)" Basic.MainMenu.Help="עזרה(&H)" -Basic.MainMenu.Help.HelpPortal="עזרה & פורטל" -Basic.MainMenu.Help.Website="בקר אתר(&W)" +Basic.MainMenu.Help.HelpPortal="עזרה פורטל (&P)" +Basic.MainMenu.Help.Website="בקר באתר(&W)" +Basic.MainMenu.Help.Discord="הצטרף לשרת דיסקורד (&D)" Basic.MainMenu.Help.Logs="קבצי יומן רישום(&L)" Basic.MainMenu.Help.Logs.ShowLogs="הצג קבצי יומן רישום(&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="העלה קובץ יומן רישום נוכחי(&C)" Basic.MainMenu.Help.Logs.UploadLastLog="העלה קובץ יומן רישום אחרון(&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="הצג את יומן הרישום הנוכחי(&V)" Basic.MainMenu.Help.CheckForUpdates="בדוק עדכונים" +Basic.MainMenu.Help.About="אודות (&A)" Basic.Settings.ProgramRestart="יש להפעיל מחדש את התוכנה בכדי שהגדרות האלה ייכנסו לתוקף." Basic.Settings.ConfirmTitle="אשר את השינויים" -Basic.Settings.Confirm="קיימים שינויים שלא נשמרו. האם לשמור שינויים?" +Basic.Settings.Confirm="קיימים שינויים שלא נשמרו. האם לשמור שינויים?" Basic.Settings.General="כללי" Basic.Settings.General.Theme="ערכת עיצוב" @@ -505,8 +515,10 @@ Basic.Settings.General.SysTray="מגש המערכת" Basic.Settings.General.SysTrayWhenStarted="מזער למגש המערכת בתחילה" Basic.Settings.General.SystemTrayHideMinimize="מזער תמיד למגש המערכת במקום שורת המשימות" Basic.Settings.General.SaveProjectors="שמור את המקרנים ביציאה" +Basic.Settings.General.Preview="תצוגה מקדימה" Basic.Settings.General.SwitchOnDoubleClick="מעבר לסצנה על ידי הקלקה כפולה" Basic.Settings.General.StudioPortraitLayout="אפשר פריסה אנכית/דיוקן" +Basic.Settings.General.Multiview.DrawSourceNames="הצג שמות סצנה" Basic.Settings.General.MultiviewLayout="פריסת תצוגה מרובה" Basic.Settings.Stream="זרם נתונים" @@ -526,7 +538,7 @@ Basic.Settings.Output.UseReplayBuffer="הפעלת מאגר החוזר" Basic.Settings.Output.ReplayBuffer.SecondsMax="זמן החוזר המרבי (בשניות)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="זיכרון מרבי (מגה-בתים)" Basic.Settings.Output.ReplayBuffer.Estimate="הערך שימוש בזיכרון: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="אין אפשרות להעריך את השימוש בזיכרון. נא הגדר מגבלת זיכרון מירבי." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="אין אפשרות להעריך את השימוש בזיכרון. נא הגדר מגבלת זיכרון מירבי." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(הערה: הקפד להגדיר hotkey עבור מאגר החוזר במקטע מקשי הקיצור)" Basic.Settings.Output.ReplayBuffer.Prefix="קידומת שם קובץ מאגר החוזר" Basic.Settings.Output.ReplayBuffer.Suffix="סיומת" @@ -539,10 +551,9 @@ Basic.Settings.Output.Simple.RecordingQuality.Lossless="ללא אובדן איכ Basic.Settings.Output.Simple.Warn.VideoBitrate="אזהרה: קצב הזרמת הוידאו יוגדר ל %1, כאשר זה הגבול העליון עבור שירות הזרמת הנתונים הנוכחי. אם אתה בטוח שאתה רוצה לעבור מעל %1, אפשר את אפשרויות קידוד מתקדמות ובטל סימון \"אכוף הגבלות קצב הזרמת נתונים\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="אזהרה: קצב הזרמת האודיו יוגדר ל %1, כאשר זה הגבול העליון עבור שירות הזרמת הנתונים הנוכחי. אם אתה בטוח שאתה רוצה לעבור מעל %1, אפשר את אפשרויות קידוד מתקדמות ובטל סימון \"אכוף הגבלות קצב הזרמת נתונים\"." Basic.Settings.Output.Simple.Warn.Encoder="אזהרה: הקלטה עם מקודד תוכנה באיכות שונה מאשר זרם הנתונים ידרוש שימוש במשאבי מעבד נוספים אם מתבצעת הקלטה וזרם נתונים במקביל." -Basic.Settings.Output.Simple.Warn.Lossless="אזהרה: איכות ללא אובדן יוצר גדלי קבצים גדולים מאוד! איכות ללא אובדן נתונים יכול להשתמש ביותר מ-7 ג'יגה-בתים של שטח דיסק לדקה ברזולוציות גבוהות ופריימים. שימוש באיכות ללא אובדן אינו מומלץ להקלטות ארוכות אלא אם קיים שטח דיסק פנוי גדול מאד." +Basic.Settings.Output.Simple.Warn.Lossless="אזהרה: איכות ללא אובדן יוצר גדלי קבצים גדולים מאוד! איכות ללא אובדן נתונים יכול להשתמש ביותר מ-7 ג'יגה-בתים של שטח דיסק לדקה ברזולוציות גבוהות ופריימים. שימוש באיכות ללא אובדן אינו מומלץ להקלטות ארוכות אלא אם קיים שטח דיסק פנוי גדול מאד." Basic.Settings.Output.Simple.Warn.Lossless.Msg="האם אתה בטוח שברצונך להשתמש באיכות ללא אובדן איכות?" Basic.Settings.Output.Simple.Warn.Lossless.Title="אזהרה איכות ללא אובדן איכות!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="אזהרה: לא ניתן להשתמש במקודדי QSV נפרדים מרובים בעת הזרמת נתונים והקלטה במקביל. אם ברצונך להזרים ולהקליט בו זמנית, נא בצע שינוי במקודד ההקלטה או מקודד זרם הנתונים." Basic.Settings.Output.Simple.Encoder.Software="תוכנה (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="חומרה (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="חומרה (AMD)" @@ -554,7 +565,6 @@ Basic.Settings.Output.Reconnect="חיבור מחדש באופן אוטומטי" Basic.Settings.Output.RetryDelay="נסה שנית השהייה (שניות)" Basic.Settings.Output.MaxRetries="מרב נסינות" Basic.Settings.Output.Advanced="אפשר הגדרות מקודד מתקדמות" -Basic.Settings.Output.EncoderPreset="מקודד קבוע מראש (גבוה = מעט מעבד)" Basic.Settings.Output.CustomEncoderSettings="הגדרות מקודד מותאמות אישית" Basic.Settings.Output.CustomMuxerSettings="הגדרות ממיר מותאמות אישית" Basic.Settings.Output.NoSpaceFileName="צור שם קובץ ללא רווחים" @@ -604,20 +614,20 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY שנה,ארבע ספרות\n%YY שנה,שתי ספרות אחרונות (00-99)\n%MM חודש כ מספר עשרוני (01-12)\n%DD יום בחודש,ללא ריפוד (01-31)\n%hh שעה בפורמט 24 שעות פורמט (00-23)\n%mm דקה (00-59)\n%ss שניה (00-61)\n%% A % סימן\n%a שם יום מקוצר\n%A שם יום מלא\n%b שם חודש מקוצר\n%B שם חודש מלא\n%d יום בחודש,ללא ריפוד (01-31)\n%H שעה בפורמט 24 שעות (00-23)\n%I שעה בפורמט 12 שעות (01-12)\n%m חודש כעשרוני מספר (01-12)\n%M דקה (00-59)\n%p AM או PM ציון\n%S שניה (00-61)\n%y שנה,שתי ספרות אחרונות (00-99)\n%Y שנה\n%z ISO 8601 הסט מזמן UTC או אזור זמן\n שם או קיצור\n%Z שם אזור זמן או קיצור\n" Basic.Settings.Video="וידאו" -Basic.Settings.Video.Adapter="מתאם תצוגה:" -Basic.Settings.Video.BaseResolution="רזולציית (קנבס) בסיס:" -Basic.Settings.Video.ScaledResolution="רזולוציית (קנה מידה) פלט:" -Basic.Settings.Video.DownscaleFilter="מסנן מצמצם:" +Basic.Settings.Video.Adapter="מתאם תצוגה" +Basic.Settings.Video.BaseResolution="רזולציית (קנבס) בסיס" +Basic.Settings.Video.ScaledResolution="רזולוציית (קנה מידה) פלט" +Basic.Settings.Video.DownscaleFilter="מסנן מצמצם" Basic.Settings.Video.DisableAeroWindows="בטל את Aero (Windows בלבד)" -Basic.Settings.Video.FPS="פריימים לשנייה:" +Basic.Settings.Video.FPS="פריימים לשנייה" Basic.Settings.Video.FPSCommon="ערכים משותפים לפריימים לשניה" Basic.Settings.Video.FPSInteger="ערך מספר שלם של פריימים לשניה" Basic.Settings.Video.FPSFraction="ערך שברים של פריימים לשניה" -Basic.Settings.Video.Numerator="מונה:" -Basic.Settings.Video.Denominator="מכנה:" -Basic.Settings.Video.Renderer="מעבד:" +Basic.Settings.Video.Numerator="מונה" +Basic.Settings.Video.Denominator="מכנה" +Basic.Settings.Video.Renderer="מעבד" Basic.Settings.Video.InvalidResolution="ערך רזולוציה לא חוקי. חייב להיות [width]x[height] (לדוגמה 1920x1080)" -Basic.Settings.Video.CurrentlyActive="פלט וידאו פעיל כעת. נא כבה את כל הפלטים בכדי לשנות הגדרות וידאו." +Basic.Settings.Video.CurrentlyActive="פלט וידאו פעיל כעת. נא כבה את כל הפלטים בכדי לשנות הגדרות וידאו." Basic.Settings.Video.DisableAero="בטל את ממשק Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="דו-ליניארי (מהיר ביותר, מטושטש בשינוי קנה מידה)" @@ -627,7 +637,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (חד בשינוי קנה Basic.Settings.Audio="אודיו" Basic.Settings.Audio.SampleRate="קצב דגימה" Basic.Settings.Audio.Channels="ערוצים" -Basic.Settings.Audio.MeterDecayRate="קצב דעיכה ממד שמע" Basic.Settings.Audio.MeterDecayRate.Fast="מהיר" Basic.Settings.Audio.MeterDecayRate.Medium="בינוני (סוג I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="איטי (סוג II PPM)" @@ -635,11 +644,6 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="אזהרה: שמע צליל ה Basic.Settings.Audio.MultichannelWarning="אם הזרימה, בדוק את הזרמת השירות תומך בסראונד סאונד להבלע ואת היקפי הסראונד פלייבק. טוויץ',פייסבוק,360 Liev, מיקסר RTMP, Smashcast דוגמאות לאיפה שסראונד סאונד הוא נתמך. למרות פייסבוק לייב ויוטיוב לייב שניהם מאפשרים סראונד להבלע, פייסבוק לייב משנה לסטריאו ויוטיוב לייב מפעיל בשני ערוצים. \n\nOBS Studio מסנן עם הסראונד סאונד, למרות תמיכת תוסף VST אינו מאובטח." Basic.Settings.Audio.MultichannelWarning.Title="האם להפעיל שמע צליל היקפי?" Basic.Settings.Audio.MultichannelWarning.Confirm="אתה בטוח שאתה רוצה לאפשר קול שמע מקיף?" -Basic.Settings.Audio.DesktopDevice="התקן שמע בשולחן עבודה" -Basic.Settings.Audio.DesktopDevice2="התקן שמע בשולחן עבודה 2" -Basic.Settings.Audio.AuxDevice="התקן שמע מיקרופון/עזר" -Basic.Settings.Audio.AuxDevice2="התקן שמע מיקרופון/עזר 2" -Basic.Settings.Audio.AuxDevice3="התקן שמע מיקרופון/עזר 3" Basic.Settings.Audio.EnablePushToMute="אפשר לחץ-להשתקה" Basic.Settings.Audio.PushToMuteDelay="השהיית לחץ-להשתקה" Basic.Settings.Audio.EnablePushToTalk="הפעל לחץ-כדי-לדבר" @@ -653,14 +657,11 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="מעל לרגיל" Basic.Settings.Advanced.General.ProcessPriority.Normal="רגיל" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="מתחת לעדיפות רגילה" Basic.Settings.Advanced.General.ProcessPriority.Idle="לא פעיל" -Basic.Settings.Advanced.FormatWarning="אזהרה: תבניות צבע שונות מ-NV12 נועדו בעיקר עבור הקלטה, והם אינם מומלצות בעת הזרמת נתונים. הזרמת נתונים עלולה לגרום למשאבי עיבוד מוגברים כתוצאה מהמרת תבנית צבע." +Basic.Settings.Advanced.FormatWarning="אזהרה: תבניות צבע שונות מ-NV12 נועדו בעיקר עבור הקלטה, והם אינם מומלצות בעת הזרמת נתונים. הזרמת נתונים עלולה לגרום למשאבי עיבוד מוגברים כתוצאה מהמרת תבנית צבע." Basic.Settings.Advanced.Audio.BufferingTime="זמן אוגר שמע" Basic.Settings.Advanced.Video.ColorFormat="תבנית צבע" -Basic.Settings.Advanced.Video.ColorSpace="מרחב צבע YUV" -Basic.Settings.Advanced.Video.ColorRange="טווח צבעים YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="חלקי" Basic.Settings.Advanced.Video.ColorRange.Full="מלא" -Basic.Settings.Advanced.Audio.MonitoringDevice="מכשיר ניטור אודיו" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="ברירת מחדל" Basic.Settings.Advanced.Audio.DisableAudioDucking="בטל צימוד השמע של Windows" Basic.Settings.Advanced.StreamDelay="השהיית זרם נתונים" @@ -674,9 +675,8 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="מצב השהיה נמוך Basic.AdvAudio="מאפייני קול מתקדמים" Basic.AdvAudio.Name="שם" -Basic.AdvAudio.Volume="עוצמת קול (%)" Basic.AdvAudio.Mono="הפוך למונו" -Basic.AdvAudio.Panning="איזון" +Basic.AdvAudio.Balance="איזון" Basic.AdvAudio.SyncOffset="היסט סינכרון (מילישניות)" Basic.AdvAudio.Monitoring="ניטור אודיו" Basic.AdvAudio.Monitoring.None="בטל ניתור" @@ -686,13 +686,14 @@ Basic.AdvAudio.AudioTracks="ערוצים" Basic.Settings.Hotkeys="מקשי קיצור" Basic.Settings.Hotkeys.Pair="צירופי מקשים משותים עם '%1' משמשים כמחליפים" +Basic.Settings.Hotkeys.Filter="סינון" Basic.Hotkeys.SelectScene="עבור לסצנה" Basic.SystemTray.Show="הצג" Basic.SystemTray.Hide="הסתר" -Basic.SystemTray.Message.Reconnecting="ההתקשרות נותקה. התחברות מחדש..." +Basic.SystemTray.Message.Reconnecting="ההתקשרות נותקה. התחברות מחדש..." Hotkeys.Insert="הוסף" Hotkeys.Delete="מחק" @@ -740,11 +741,21 @@ SceneItemHide="הסתר '%1'" OutputWarnings.NoTracksSelected="עליך לבחור ערוץ אחד לפחות" OutputWarnings.MultiTrackRecording="אזהרה: תבניות מסוימות (כגון FLV) אינם תומכים במספר רצועות להקלטה" -OutputWarnings.MP4Recording="אזהרה: הקלטות שנשמרו MP4 תהיה בלתי שמישה במידה ולא ניתן להשלים את הקובץ (למשל כתוצאה מחלון כחול, אובדן כוח, וכו '). אם אתה רוצה להקליט מספר רצועות שמע, שקול להשתמש ב- MKV ובצע רימיקס ל- mp4 לאחר סיומה (קובץ-> Remux הקלטות)" FinalScene.Title="מחק סצינה" FinalScene.Text="נדרשת סצנה אחת לפחות." +NoSources.Title="אין מקורות" + +ChangeBG="קבע צבע" +CustomColor="צבע מותאם אישית" +About="אודות" +About.GetInvolved="הייה מעורב" +About.Authors="מחברים" +About.License="רישיון" + +ResizeOutputSizeOfSource.Continue="האם אתה רוצה להמשיך?" + diff --git a/UI/data/locale/hi-IN.ini b/UI/data/locale/hi-IN.ini index 16c8600..481828e 100644 --- a/UI/data/locale/hi-IN.ini +++ b/UI/data/locale/hi-IN.ini @@ -41,6 +41,9 @@ Back="वापस" + + + BandwidthTest.Region.Asia="एशिया" @@ -114,6 +117,13 @@ BandwidthTest.Region.Asia="एशिया" + + + + + + + diff --git a/UI/data/locale/hr-HR.ini b/UI/data/locale/hr-HR.ini index 744d7c6..168b819 100644 --- a/UI/data/locale/hr-HR.ini +++ b/UI/data/locale/hr-HR.ini @@ -4,7 +4,7 @@ Region="Croatia" OK="U redu" Apply="Primijeni" -Cancel="Odustani" +Cancel="Otkaži" Close="Zatvori" Save="Spremi" Discard="Odbaci" @@ -28,12 +28,15 @@ Browse="Pretraži" Mono="Mono" Stereo="Stereo" DroppedFrames="Ispušteni frejmovi %1 (%2%)" +StudioProgramProjector="Projektor cijelog zaslona (scena)" PreviewProjector="Projektor cijelog zaslona (pregled)" SceneProjector="Projektor cijelog zaslona (scena)" SourceProjector="Projektor cijelog zaslona (izvor)" PreviewWindow="Projektor zaslona (pretpregled)" SceneWindow="Projektor zaslona (Scena)" SourceWindow="Projektor zaslona (Izvor)" +MultiviewProjector="Multi-prikaz (Fullscreen)" +MultiviewWindowed="Multi-prikaz (u prozoru)" Clear="Poništi" Revert="Povrati" Show="Prikaži" @@ -57,6 +60,7 @@ Hours="Sati" Minutes="Minuta" Seconds="Sekundi" Deprecated="Zastarjelo" +ReplayBuffer="Buffer za replay" Import="Uvezi" Export="Izvezi" Copy="Kopiraj" @@ -68,36 +72,72 @@ Next="Sljedeće" Back="Prethodno" Defaults="Zadano" HideMixer="Sakriti u Mikser" +None="Nijedan" +StudioMode.Preview="Pregled" +StudioMode.Program="Program" +ShowInMultiview="Prikaži u Multi-prikazu" +VerticalLayout="Okomito sučelje" +Group="Grupa" AlreadyRunning.Title="OBS je već pokrenut" -AlreadyRunning.Text="OBS je već pokrenut! Osim ako si mislio da biste to učinili, isključite sve postojeće pojave OBS prije nego što pokušate pokrenuti novu instancu. Ako imate OBS postavljen na smanjivanje u traku sustava, provjerite ako to još uvijek radi tamo." +AlreadyRunning.Text="OBS je već pokrenut! Osim ako si mislio da biste to učinili, isključite sve postojeće pojave OBS prije nego što pokušate pokrenuti novu instancu. Ako imate OBS postavljen na smanjivanje u traku sustava, provjerite ako to još uvijek radi tamo." AlreadyRunning.LaunchAnyway="Svejedno pokreni" + +Auth.Authing.Title="Autentikacija..." +Auth.Authing.Text="Autentikacija na %1, molimo pričekajte..." +Auth.AuthFailure.Title="Greška kod autentikacije" +Auth.AuthFailure.Text="Greška autentikacije s %1:\n\n%2: %3" +Auth.InvalidScope.Title="Potrebna autentikacija" + Copy.Filters="Kopiraj filtere" Paste.Filters="Zalijepi filtere" + BandwidthTest.Region="Regija" BandwidthTest.Region.US="Sjedinjene Američke Države" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Azija" BandwidthTest.Region.Other="Ostalo" -Basic.FirstStartup.RunWizard="Želite li pokrenuti čarobnjak za automatsku konfiguraciju? Možete također ručno konfigurirati postavke tako da kliknete gumb Postavke u glavnom prozoru." -Basic.FirstStartup.RunWizard.BetaWarning="(Napomena: Automatsko postavljanje je trenutno u beti)" +Basic.FirstStartup.RunWizard="Želite li pokrenuti čarobnjak za automatsku konfiguraciju? Možete također ručno konfigurirati postavke tako da kliknete gumb Postavke u glavnom prozoru." Basic.FirstStartup.RunWizard.NoClicked="Ako se predomislite, možete pokrenuti čarobnjaka za automatsku konfiguraciju bilo kada opet u Alat meni." Basic.AutoConfig="Čarobnjak za automatske konfiguraciju" -Basic.AutoConfig.Beta="Čarobnjak za automatsku konfiguraciju (u razvoju)" Basic.AutoConfig.ApplySettings="Primjeni postavke" Basic.AutoConfig.StartPage="Informacije o korištenju" Basic.AutoConfig.StartPage.SubTitle="Navedite što želite da koristite program za" Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimiziraj za streaming, snimanje je drugo" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimiziraj samo za snimanje, neću prenositi uživo" Basic.AutoConfig.VideoPage="Video postavke" +Basic.AutoConfig.VideoPage.SubTitle="Navedite željene postavke videozapisa koje želite koristiti" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Koristi trenutnu (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Prikaži %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Koristi trenutnu (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ili 30, ali radije 60 kada je to moguće" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ili 30, ali radije visoke rezolucije" +Basic.AutoConfig.StreamPage.Service="Usluga" Basic.AutoConfig.StreamPage.Service.ShowAll="Prikaži sve..." Basic.AutoConfig.StreamPage.Server="Server" +Basic.AutoConfig.StreamPage.StreamKey="Stream ključ" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Poveznica)" +Basic.AutoConfig.TestPage="Završni rezultat" Basic.AutoConfig.TestPage.SubTitle.Complete="Testiranje završeno" Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Povezivanje na: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Ne može se spojiti na nijedan server. Provjerite jeste li povezani na internet i pokušajte kasnije." +Basic.AutoConfig.TestPage.TestingStreamEncoder="Testiranje kodiranja streama. Ovo bi moglo potrajati..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testiranje kodiranja za snimanje. Ovo bi moglo potrajati..." +Basic.AutoConfig.TestPage.TestingRes="Testiranje rezolucija. Ovo može potrajati nekoliko minuta..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Ne uspjelo pokretanje kodiranja" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Testiranje %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Koder Streama" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Greška pri kodiranju" +Basic.AutoConfig.TestPage.Result.Header="Program je utvrdio da su ove predložene postavke idealne za tebe:" + +Basic.Stats="Statistika" +Basic.Stats.CPUUsage="Koristenje CPU-a" +Basic.Stats.MemoryUsage="Korištenje memorije" +Basic.Stats.SkippedFrames="Preskočeni okviri zbog zaostajanja kodiranja" @@ -134,6 +174,7 @@ ConfirmStart.Text="Jeste li sigurni da želite započeti stream?" ConfirmStop.Title="Zaustavi stream?" ConfirmStop.Text="Jeste li sigurni da želite zaustaviti stream?" + ConfirmExit.Title="Napustiti OBS?" ConfirmExit.Text="OBS je trenutačno aktivan. Svi streamovi/snimanja bit će ugašeni. Jeste li sigurni da želite izaći?" @@ -142,6 +183,7 @@ ConfirmRemove.Text="Jeste li sigurni da želite ukloniti '$1'?" ConfirmRemove.TextMultiple="Jeste li sigurni da želite ukloniti %1 stavke?" + Output.ConnectFail.Title="Neuspješno povezivanje" Output.ConnectFail.BadPath="Neispravna putanja ili URL veze. Provjerite jesu li Vam postavke ispravne." Output.ConnectFail.ConnectFailed="Neuspješno povezivanje s poslužiteljem" @@ -149,6 +191,7 @@ Output.ConnectFail.InvalidStream="Ne mogu pristupiti navedenom kanalu ili stream Output.ConnectFail.Error="Neočekivana greška u povezivanju s poslužiteljem. Više informacija nalazi se u zapisniku." Output.ConnectFail.Disconnected="Prekinuta veza s poslužiteljem." + Output.RecordFail.Title="Neuspješno započinjanje snimanja" Output.RecordFail.Unsupported="Izlazni format ili nije podržan ili ne podržava više od jedne zvučne trake. Provjerite postavke i pokušajte ponovno." Output.RecordNoSpace.Title="Nedovoljno prostora na disku" @@ -163,28 +206,20 @@ LogReturnDialog="Slanje zapisnika uspješno" LogReturnDialog.CopyURL="Kopiraj URL" LogReturnDialog.ErrorUploadingLog="Greška u slanju zapisnika" -LicenseAgreement="Uvjeti korištenja" -LicenseAgreement.PleaseReview="Provjerite uvjete korištenja prije uporabe OBS-a. Upotrebom ovog programa smatra se da ste pročitali i prihvatili uvjete licence GNU General Public License v2.0. Povucite kotačić miša ka dolje da biste vidjeli ostatak ugovora." -LicenseAgreement.ClickIAgreeToContinue="Ako prihvaćate uvjete korištenja, kliknite na \"Prihvaćam\" da nastavite. Morate ih prihvatiti da biste mogli koristili OBS." -LicenseAgreement.IAgree="Prihvaćam" -LicenseAgreement.Exit="Izlaz" - Remux.SourceFile="OBS-snimak" Remux.TargetFile="Datoteka" Remux.Remux="Remux" +Remux.ClearAll="Očisti sve stavke" Remux.OBSRecording="OBS-snimak" Remux.FinishedTitle="Remux završen" Remux.Finished="Završen remux snimka" Remux.FinishedError="Remux završen, ali datoteka možda nije dovršena" -Remux.SelectRecording="Odaberite OBS-snimak…" -Remux.SelectTarget="Odaberite ciljnu datoteku…" -Remux.FileExistsTitle="Ciljna datoteka postoji" -Remux.FileExists="Ciljna datoteka već postoji. Želite li ju zamijeniti?" +Remux.FileExistsTitle="Ciljana datoteka postoji" Remux.ExitUnfinishedTitle="Remux u tijeku" Remux.ExitUnfinished="Remux nije završen, ako sada zaustavite proces datoteka može biti neupotrebljiva.\nJeste li sigurni da želite zaustaviti remux?" UpdateAvailable="Dostupno je novo ažuriranje" -UpdateAvailable.Text="Verzija %1.%2.%3 je dostupna. Kliknite ovdje da ju preuzmete" +UpdateAvailable.Text="Verzija %1.%2.%3 je dostupna. Kliknite ovdje da ju preuzmete" Basic.DesktopDevice1="Zvuk s računala" Basic.DesktopDevice2="Zvuk s računala 2" @@ -198,6 +233,7 @@ Basic.DisplayCapture="Prikaži ulaz" Basic.Main.PreviewConextMenu.Enable="Omogući pregled" + ScaleFiltering="Filter uvećanja" ScaleFiltering.Point="Točka" ScaleFiltering.Bilinear="Bilinearno" @@ -362,31 +398,47 @@ Basic.MainMenu.Edit.AdvAudio="N&apredne postavke zvuka" Basic.MainMenu.View="Prikaz (&V)" Basic.MainMenu.View.Toolbars="Alatne &trake" +Basic.MainMenu.View.Docks.ResetUI="Resetiraj korisničko sučelje" +Basic.MainMenu.View.Docks.LockUI="Zaključaj korisničko sučelje" Basic.MainMenu.View.Toolbars.Listboxes="Popis stavki (&L)" Basic.MainMenu.View.SceneTransitions="S&censki prijelazi" Basic.MainMenu.View.StatusBar="Traka &stanja" +Basic.MainMenu.View.Fullscreen.Interface="Sučelje preko cijelog zaslona" Basic.MainMenu.SceneCollection="Zbirka &scena" Basic.MainMenu.Profile="&Profil" +Basic.MainMenu.Profile.Import="Uvoz profila" +Basic.MainMenu.Profile.Export="Izvoz profila" +Basic.MainMenu.SceneCollection.Import="Dodaj zbirku scena" +Basic.MainMenu.SceneCollection.Export="Izvezi zbirku scena" +Basic.MainMenu.Profile.Exists="Profil već postoji" +Basic.MainMenu.SceneCollection.Exists="Zbirka scena već postoji" Basic.MainMenu.Tools="Ala&ti" Basic.MainMenu.Help="Pomoć (&H)" +Basic.MainMenu.Help.HelpPortal="Centar za &pomoć" Basic.MainMenu.Help.Website="Posjeti stranicu (&W)" +Basic.MainMenu.Help.Discord="Pridruži se &Discord serveru" Basic.MainMenu.Help.Logs="Zapisnici (&L)" Basic.MainMenu.Help.Logs.ShowLogs="Prikaži zapisnike (&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="Pošalji trenutačni zapisnik (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Pošalji pos&ljednji zapisnik" Basic.MainMenu.Help.Logs.ViewCurrentLog="Prikaži trenutačni zapisnik (&V)" Basic.MainMenu.Help.CheckForUpdates="Proveri verziju programa" +Basic.MainMenu.Help.CrashLogs="Izvješča o prekidu &rada" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Prikaži izvješča o prekidu rada (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Učitaj zadnje izvješče o prekidu rada (&L)" +Basic.MainMenu.Help.About="Više o &aplikaciji" Basic.Settings.ProgramRestart="Program se mora ponovno pokrenuti da bi ova postavka stupila na snagu." Basic.Settings.ConfirmTitle="Potvrdite promjene" -Basic.Settings.Confirm="Niste spremili sve promjene. Spremiti?" +Basic.Settings.Confirm="Niste spremili sve promjene. Spremiti?" Basic.Settings.General="Općenito" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Jezik" +Basic.Settings.General.EnableAutoUpdates="Automatski provjeri za nadogradnje pri pokretanju programa" Basic.Settings.General.WarnBeforeStartingStream="Prikaži prozor za potvrdu kad se započinju streamovi" Basic.Settings.General.WarnBeforeStoppingStream="Prikaži prozor za potvrdu kad se zaustavljaju streamovi" Basic.Settings.General.Projectors="Projektori" @@ -426,7 +478,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Upozorenje: Snimanje sa softverskim e Basic.Settings.Output.Simple.Warn.Lossless="Upozorenje: Kvalitet bez gubitka stvara izričito velike datoteke! Kvalitet bez gubitka može koristiti više od 7 gigabajta prostora na disku po minutu pri visokim rezolucijama i framerate-om. Kvalitet bez gubitka nije preporučen za duže snimanje osim ako imate veliku količinu slobodnog prostora na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Da li ste sigurni da želite koristiti kvalitet bez gubitka?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gubitka!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja." Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Mašinski (AMD)" @@ -438,7 +489,6 @@ Basic.Settings.Output.Reconnect="Automatski poveži ponovo" Basic.Settings.Output.RetryDelay="Pauza pre ponovnog pokušaja (sekunde)" Basic.Settings.Output.MaxRetries="Maksimalan broj ponovnih pokušaja" Basic.Settings.Output.Advanced="Omogući napredna podešavanja kompresora" -Basic.Settings.Output.EncoderPreset="Šablon enkodera (veće = manje CPU)" Basic.Settings.Output.CustomEncoderSettings="Prilagođena enkoder podešavanja" Basic.Settings.Output.CustomMuxerSettings="Posebna podešavanja muksera" Basic.Settings.Output.NoSpaceFileName="Stvori ime datoteke bez razmaka" @@ -484,18 +534,18 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY Godina, četiri cifre\n%YY Godina, poslednje dve cifre (00-99)\n%MM Mesec kao decimalni broj (01-12)\n%DD Dan u mesecu, sa nulom ispred (01-31)\n%hh Sat u 24-časovnom zapisu (00-23)\n%mm Minut (00-59)\n%ss Sekunda (00-61)\n%% Znak procenta\n%a Skraćeno ime dana u nedelji\n%A Puno ime dana u nedelji\n%b Skraćeno ime meseca\n%B Puno ime meseca\n%d Dan u mesecu, sa nulom ispred (01-31)\n%H Sat u 24-časovnom zapisu (00-23)\n%I Sat u 12-časovnom zapisu (01-12)\n%m Mesec kao decimalni broj (01-12)\n%M Minut (00-59)\n%p Oznaka za pre ili posle podne\n%S Sekunda (00-61)\n%y Godina, poslednje dve cifre (00-99)\n%Y Godina\n%z ISO 8601 odstupanje od UTC ili ime\n vremenske zone ili skraćenica\n%Z Ime vremenske zone ili skraćenica\n" Basic.Settings.Video="Video" -Basic.Settings.Video.Adapter="Video adapter:" -Basic.Settings.Video.BaseResolution="Osnovna (površinska) rezolucija:" -Basic.Settings.Video.ScaledResolution="Izlazna (skalirana) rezolucija:" -Basic.Settings.Video.DownscaleFilter="Filter za skaliranje:" +Basic.Settings.Video.Adapter="Video adapter" +Basic.Settings.Video.BaseResolution="Osnovna (površinska) rezolucija" +Basic.Settings.Video.ScaledResolution="Izlazna (skalirana) rezolucija" +Basic.Settings.Video.DownscaleFilter="Filter za skaliranje" Basic.Settings.Video.DisableAeroWindows="Isključi Aero (samo za Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Uobičakene FPS vrednosti" Basic.Settings.Video.FPSInteger="Brojevna FPS vrednost" Basic.Settings.Video.FPSFraction="Brojevna FPS vrednost sa decimalama" -Basic.Settings.Video.Numerator="Brojilac:" -Basic.Settings.Video.Denominator="Imenilac:" -Basic.Settings.Video.Renderer="Renderer:" +Basic.Settings.Video.Numerator="Brojilac" +Basic.Settings.Video.Denominator="Imenilac" +Basic.Settings.Video.Renderer="Renderer" Basic.Settings.Video.InvalidResolution="Neispravna vrednost rezolucije. Mora biti [width]x[height] (npr. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Video izlaz je trenutno aktivan. Molim isključite sve izlaze da promenite video podešavanja." Basic.Settings.Video.DisableAero="Onemogući Aero" @@ -507,11 +557,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 32 u Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Protok" Basic.Settings.Audio.Channels="Kanali" -Basic.Settings.Audio.DesktopDevice="Zvuk sa računara" -Basic.Settings.Audio.DesktopDevice2="Zvuk sa računara 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/Ulaz" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Ulaz 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Ulaz 3" Basic.Settings.Audio.EnablePushToMute="Omogući stisni-za-mutiranje" Basic.Settings.Audio.PushToMuteDelay="Stisni-za-mutiranje pauza" Basic.Settings.Audio.EnablePushToTalk="Omogući Stisni-za-govor" @@ -527,8 +572,6 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Besposleni" Basic.Settings.Advanced.FormatWarning="Upozorenje: Formati boja različiti od NV12 su prvenstveno namenjeni za snimanje i nisu preporučeni za strimovanje. Strimovanje može prouzrokovati povišeno zauzeće procesora zbog pretvaranja formata boja." Basic.Settings.Advanced.Audio.BufferingTime="Vreme baferovanja zvuka" Basic.Settings.Advanced.Video.ColorFormat="Format boja" -Basic.Settings.Advanced.Video.ColorSpace="YUV prostor boja" -Basic.Settings.Advanced.Video.ColorRange="YUV raspon boja" Basic.Settings.Advanced.Video.ColorRange.Partial="Delimično" Basic.Settings.Advanced.Video.ColorRange.Full="Potpuno" Basic.Settings.Advanced.StreamDelay="Odlaganje strima" @@ -540,9 +583,7 @@ Basic.Settings.Advanced.Network.BindToIP="Veži se za IP" Basic.AdvAudio="Napredna podešavanja zvuka" Basic.AdvAudio.Name="Ime" -Basic.AdvAudio.Volume="Glasnoća (%)" Basic.AdvAudio.Mono="Spoji u mono" -Basic.AdvAudio.Panning="Pomeranje" Basic.AdvAudio.SyncOffset="Razlika u sinhronizaciji (ms)" Basic.AdvAudio.AudioTracks="Izvori" @@ -607,3 +648,6 @@ OutputWarnings.MultiTrackRecording="Upozorenje: Određeni formati (kao što je F + + + diff --git a/UI/data/locale/hu-HU.ini b/UI/data/locale/hu-HU.ini index 6413a55..cdb851d 100644 --- a/UI/data/locale/hu-HU.ini +++ b/UI/data/locale/hu-HU.ini @@ -80,14 +80,40 @@ StudioMode.Program="Program" ShowInMultiview="Mutatás Multiviewban" VerticalLayout="Függőleges elrendezés" Group="Csoport" +DoNotShowAgain="Ne jelenjen meg többet" +Default="(Alapértelmezett)" +Calculating="Számítás..." AlreadyRunning.Title="Az OBS már fut" AlreadyRunning.Text="Az OBS már fut! Ha nem teljesen biztos benne mit tesz, akkor állítsa le az összes már futó OBS programot. Ha a programot úgy állította be, hogy rendszertálcára minimalizálódjon, akkor ellenőrizze, hogy ott megtalálható e." AlreadyRunning.LaunchAnyway="Indítás mégis" +DockCloseWarning.Title="Dokkolható ablak bezárása" +DockCloseWarning.Text="Most zárt be egy dokkolható ablakot. Ha szeretné újra felfedni, akkor használja a Nézet -> Dokkolás menüt." + +Auth.Authing.Title="Hitelesítés..." +Auth.Authing.Text="Hitelesítés %1 platformmal, kérjük várjon..." +Auth.AuthFailure.Title="Hitelesítési hiba" +Auth.AuthFailure.Text="Nem sikerült a hitelesítés: %1:\n\n%2: %3" +Auth.InvalidScope.Title="Hitelesítés szükséges" +Auth.InvalidScope.Text="%1 hitelesítési követelményei megváltoztak. Egyes funkciók nem állnak rendelkezésre." +Auth.LoadingChannel.Title="Csatornainformációk betöltése..." +Auth.LoadingChannel.Text="%1 csatornaadatok betöltése, kis türelmet..." +Auth.ChannelFailure.Title="Nem sikerült betölteni a csatornát" +Auth.ChannelFailure.Text="Nem sikerült betölteni a csatornaadatokat: %1\n\n%2: %3" +Auth.Chat="Csevegő" +Auth.StreamInfo="Stream információ" +TwitchAuth.Stats="Twitch statisztika" +TwitchAuth.Feed="Twitch Tevékenységnapló" +TwitchAuth.TwoFactorFail.Title="Nem lehetett a stream kulcsot lekérni" +TwitchAuth.TwoFactorFail.Text="Az OBS nem tudott kapcsolódni a Twitch felhasználódhoz. Kérem ellenőrizze, hogy a kétfaktoros authentikációja be van állítva a Twitch biztonsági beállítások között, hiszen az szükséges az adáshoz." + Copy.Filters="Szűrők másolása" Paste.Filters="Szűrők beillesztése" +BrowserPanelInit.Title="Böngésző indítása..." +BrowserPanelInit.Text="Böngésző indítása, kis türelmet..." + BandwidthTest.Region="Régió" BandwidthTest.Region.US="Egyesült Államok" BandwidthTest.Region.EU="Európa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Ázsia" BandwidthTest.Region.Other="Egyéb" Basic.FirstStartup.RunWizard="Kívánja futtatni az automatikus konfiguráció varázslót? Természetesen manuálisan is konfigurálhatja a beállításokat a Beállítások gombra kattintva a fő ablakban." -Basic.FirstStartup.RunWizard.BetaWarning="(Megjegyzés: az automatikus konfiguráció varázsló jelenleg béta fázisban van)" Basic.FirstStartup.RunWizard.NoClicked="Ha meggondolja magát, bármikor futtathatja az automatikus konfiguráció varázslót az eszközök menüből." Basic.AutoConfig="Automatikus konfiguráció varázsló" -Basic.AutoConfig.Beta="Automatikus konfiguráció varázsló (Béta)" Basic.AutoConfig.ApplySettings="Beállítások alkalmazása" Basic.AutoConfig.StartPage="Használati tudnivalók" Basic.AutoConfig.StartPage.SubTitle="Adja meg, hogy mire szeretné használni a programot" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 vagy 30, de inkább nagyobb fel Basic.AutoConfig.VideoPage.CanvasExplanation="Megjegyzés: A vászon (alap) felbontása nem feltétlenül ugyanaz, mint a stream vagy felvétel felbontása. A tényleges stream/felvétel felbontása esetlegesen lefele lesz skálázva az erőforrások leterheltsége vagy a bitsebesség követelmények elérése érdekében." Basic.AutoConfig.StreamPage="Stream információ" Basic.AutoConfig.StreamPage.SubTitle="Adja meg a stream információit" +Basic.AutoConfig.StreamPage.ConnectAccount="Felhasználó csatlakoztatása (Opcionális)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Felhasználó szétkapcsolása" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Felhasználó szétkapcsolása?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ez a változtatás azonnal érvénybe lép. Biztosan megszakítja a kapcsolatot a fiókjával?" +Basic.AutoConfig.StreamPage.UseStreamKey="Stream kulcs használata" Basic.AutoConfig.StreamPage.Service="Szolgáltató" Basic.AutoConfig.StreamPage.Service.ShowAll="Összes megjelenítése..." +Basic.AutoConfig.StreamPage.Service.Custom="Egyedi..." Basic.AutoConfig.StreamPage.Server="Szerver" Basic.AutoConfig.StreamPage.StreamKey="Stream kulcs" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="A beállítások használatához kattin Basic.Stats="Statisztika" Basic.Stats.CPUUsage="Processzorhasználat" -Basic.Stats.HDDSpaceAvailable="Szabad merevlemez terület" +Basic.Stats.HDDSpaceAvailable="Szabad lemezterület" Basic.Stats.MemoryUsage="Memóriahasználat" Basic.Stats.AverageTimeToRender="Átlagos képkocka feldolgozási idő" Basic.Stats.SkippedFrames="Kihagyott képkockák kódolási lag miatt" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Inaktív" Basic.Stats.DroppedFrames="Képkockák ejtve (Hálózat)" Basic.Stats.MegabytesSent="Összes kimeneti adat" Basic.Stats.Bitrate="Bitsebesség" +Basic.Stats.DiskFullIn="Megtelt a lemez (Körülbelül...)" + +ResetUIWarning.Title="Biztosan alaphelyzetbe állítja a felületet?" +ResetUIWarning.Text="Az UI visszaállítása lefedi a további dokkokat. Önnek fel kell fednie ezeket a dokkokat a nézet menüből, amennyiben láthatóvá tenné ezeket.\n\nBiztos benne, hogy visszaállítja az UI-t?" Updater.Title="Új frissítés elérhető" Updater.Text="Új frissítés elérhető:" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="Nincs elérhető frissítés" Updater.NoUpdatesAvailable.Text="Jelenleg nincs elérhető frissítés" Updater.FailedToLaunch="Frissítő alkalmazás indítása sikertelen" Updater.GameCaptureActive.Title="Játék felvétel aktív" -Updater.GameCaptureActive.Text="Játékfelvétel hook könyvtár jelenleg használatban. Zárjon be minden játékot/programot, amelyet felvesz (vagy indítsa újra a számítógépét) és próbálkozzon újra." +Updater.GameCaptureActive.Text="Játék felvétel kapcsolódó könyvtár még használatban van. Kérem zárjon be valamennyi játékot/programot, amely felvétel alatt áll (vagy indítsa újra a Windowst) és próbálja újra." QuickTransitions.SwapScenes="Előnézeti/Kimeneti Jelenetek cseréje átmenet után" QuickTransitions.SwapScenesTT="Az előnézet és a kimeneti jelenet cseréje átmenet után (ha a kimenet eredeti jelenete még létezik).\nEz nincs kihatással a kimenet eredeti jelenetére." @@ -206,6 +240,9 @@ ConfirmStart.Text="Biztos benne, hogy elindítja a streamet?" ConfirmStop.Title="Stream megállítása?" ConfirmStop.Text="Biztos benne, hogy leállítja a streamet?" +ConfirmBWTest.Title="Sávszélesség teszt indítása?" +ConfirmBWTest.Text="Az OBS sávszélességteszt módra van konfigurálva. Ez a mód hálózattesztelésre van, anélkül működik, hogy élő adást kezdeményezne. Amint a vizsgálat lezajlott, úgy kikapcsolásra van szükség, hogy az adás a nézők számára is megjelenjen.\n\nSzeretné folytatni?" + ConfirmExit.Title="Kilép a programból?" ConfirmExit.Text="Az OBS jelenleg aktív. Minden stream és/vagy felvétel le fog állni. Biztosan kilép?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="Felvétel indítása sikertelen" Output.StartReplayFailed="Visszajátszás puffer indítása sikertelen" Output.StartFailedGeneric="Kimenet indítása sikertelen. Kérem ellenőrizze az eseménynaplóban a részleteket.\n\nMegjegyzés: NVENC vagy AMD kódoló használata esetén, győződjön meg róla, hogy az illesztőprogramok naprakészek!" + Output.ConnectFail.Title="Csatlakozás sikertelen" Output.ConnectFail.BadPath="Érvénytelen elérési út vagy kapcsolati URL cím. Kérem, ellenőrizze a beállításokat és győződjön meg az érvényességükről." Output.ConnectFail.ConnectFailed="Nem sikerült kapcsolódni a szerverhez" @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="Nem lehet hozzáférni a megadott csatornához Output.ConnectFail.Error="A szerverhez való kapcsolódás során váratlan hiba történt. További információért tekintse meg a naplófájlt." Output.ConnectFail.Disconnected="Kiszolgálóról lecsatlakoztatva." +Output.StreamEncodeError.Title="Kódolási hiba" +Output.StreamEncodeError.Msg="Kódolási hiba történt közvetítés közben." + Output.RecordFail.Title="Felvétel indítása sikertelen" Output.RecordFail.Unsupported="A kimeneti formátum vagy nem támogatott, vagy nem támogatja az egynél több hangsávot. Kérem, ellenőrizze a beállításait és próbálkozzon újra." Output.RecordNoSpace.Title="Nincs elég szabad lemezterület" Output.RecordNoSpace.Msg="Nincs elegendő lemezterület a felvétel folytatásához." Output.RecordError.Title="Felvételi hiba" Output.RecordError.Msg="Ismeretlen hiba lépett fel a felvétel során." +Output.RecordError.EncodeErrorMsg="Kódolási hiba történt felvétel készítése közben." Output.ReplayBuffer.NoHotkey.Title="Nincs gyorsbillentyű beállítva!" Output.ReplayBuffer.NoHotkey.Msg="Nincs mentés gyorsbillentyű a visszajátszási pufferhez. Kérem állítson be egy \"Mentés\" gyorsbillentyűt a visszajátszások felvételeinek mentésére." @@ -241,25 +283,23 @@ LogReturnDialog="Napló feltöltése sikeres" LogReturnDialog.CopyURL="URL másolása" LogReturnDialog.ErrorUploadingLog="Naplófájl feltöltésekor hiba lépett fel" -LicenseAgreement="Licencmegállapodás" -LicenseAgreement.PleaseReview="Kérjük, olvassa el a licencfeltételeket, mielőtt az OBS használatába kezdene. A program használatával Ön elismeri, hogy elolvasta és elfogadta a GNU General Public License 2.0 feltételeit. Kérjük tekintse át a teljes megállapodást." -LicenseAgreement.ClickIAgreeToContinue="Amennyiben elfogadja a megállapodás feltételeit, kattintson az Elfogadom gombra a folytatáshoz. El kell fogadnia a megállapodást az OBS használatához." -LicenseAgreement.IAgree="Elfogadom" -LicenseAgreement.Exit="Kilépés" - Remux.SourceFile="OBS felvétel" Remux.TargetFile="Célfájl" Remux.Remux="Remux" +Remux.Stop="Remux megállítása" +Remux.ClearFinished="Elkészült elemek törlése" +Remux.ClearAll="Összes elem törlése" Remux.OBSRecording="OBS felvétel" Remux.FinishedTitle="Remux kész" Remux.Finished="Felvétel remuxolva" Remux.FinishedError="Felvétel remuxolva, de a fájl hiányos lehet" -Remux.SelectRecording="Válassza az OBS Felvételt …" -Remux.SelectTarget="Válasszon célfájlt …" +Remux.SelectRecording="OBS Felvétel kijelölése..." +Remux.SelectTarget="Célfájl kiválasztása..." Remux.FileExistsTitle="A célfájl létezik" -Remux.FileExists="A célfájl létezik, kívánja cserélni?" +Remux.FileExists="Az alábbi célfájlok már léteznek. Lecseréli őket?" Remux.ExitUnfinishedTitle="Remuxolás folyamatban" Remux.ExitUnfinished="A Remux nem fejeződött be, a megállítása a célfájlt használhatatlanná teheti.\nBiztosan megállítja?" +Remux.HelpText="Dobja a fájlokat ebbe az ablakba a remuxoláshoz, vagy válasszon egy üres \"OBS felvétel\" cellát fájlok tallózásához." UpdateAvailable="Elérhető újabb programváltozat" UpdateAvailable.Text="Verzió: %1. %2. %3 most elérhető. Kattintson ide a letöltéshez" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Képernyő felvétel" Basic.Main.PreviewConextMenu.Enable="Előnézet bekapcsolása" +Basic.Main.Preview.Disable="Előnézet kikapcsolása" + ScaleFiltering="Skála-szűrés" ScaleFiltering.Point="Pont" ScaleFiltering.Bilinear="Bilineáris" ScaleFiltering.Bicubic="Kettős köbös" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Terület" Deinterlacing="Váltottsorosság" Deinterlacing.Discard="Elvetés" @@ -414,55 +457,57 @@ Basic.Main.Ungroup="Csoport megszüntetése" Basic.MainMenu.File="&Fájl" Basic.MainMenu.File.Export="&Exportálás" Basic.MainMenu.File.Import="&Importálás" -Basic.MainMenu.File.ShowRecordings="&Felvételek megjelenítése" +Basic.MainMenu.File.ShowRecordings="Felvételek megjelenítése (&R)" Basic.MainMenu.File.Remux="Felvételek re&muxolása" -Basic.MainMenu.File.Settings="&Beállítások" +Basic.MainMenu.File.Settings="Beállítá&sok" Basic.MainMenu.File.ShowSettingsFolder="Beállítási mappa megjelenítése" Basic.MainMenu.File.ShowProfileFolder="Profilmappa megjelenítése" -Basic.MainMenu.AlwaysOnTop="&Mindig legfelül" -Basic.MainMenu.File.Exit="K&ilépés" +Basic.MainMenu.AlwaysOnTop="Mindig legfelül (&A)" +Basic.MainMenu.File.Exit="Kilépés (&X)" -Basic.MainMenu.Edit="&Szerkesztés" -Basic.MainMenu.Edit.Undo="&Visszavonás" -Basic.MainMenu.Edit.Redo="&Ismét" -Basic.MainMenu.Edit.UndoAction="&Visszavonás $1" -Basic.MainMenu.Edit.RedoAction="&Ismét $1" -Basic.MainMenu.Edit.LockPreview="&Előnézet zárolás" -Basic.MainMenu.Edit.Scale="Előnézet &méretezés" +Basic.MainMenu.Edit="Sz&erkesztés" +Basic.MainMenu.Edit.Undo="Visszavonás (&U)" +Basic.MainMenu.Edit.Redo="Ismét (&R)" +Basic.MainMenu.Edit.UndoAction="Visszavonás $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Ismét $1 (&R)" +Basic.MainMenu.Edit.LockPreview="E&lőnézet zárolás" +Basic.MainMenu.Edit.Scale="Előnézet méretezé&s" Basic.MainMenu.Edit.Scale.Window="Ablakhoz igazítás" Basic.MainMenu.Edit.Scale.Canvas="Vászon (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Kimenet (%1x%2)" -Basic.MainMenu.Edit.Transform="&Alakítás" -Basic.MainMenu.Edit.Transform.EditTransform="&Alakítás átszerkesztése..." +Basic.MainMenu.Edit.Transform="Alakí&tás" +Basic.MainMenu.Edit.Transform.EditTransform="Alakítás átsz&erkesztése..." Basic.MainMenu.Edit.Transform.CopyTransform="Alakítás másolása" Basic.MainMenu.Edit.Transform.PasteTransform="Átalakítás beillesztése" -Basic.MainMenu.Edit.Transform.ResetTransform="&Alakítás visszaállítása" +Basic.MainMenu.Edit.Transform.ResetTransform="Alakítás visszaállítása (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Forgatás 90 fokkal balra" Basic.MainMenu.Edit.Transform.Rotate90CCW="Forgatás 90 fokkal jobbra" Basic.MainMenu.Edit.Transform.Rotate180="Forgatás 180 fokkal" -Basic.MainMenu.Edit.Transform.FlipHorizontal="&Vízszintes tükrözés" -Basic.MainMenu.Edit.Transform.FlipVertical="&Függőleges tükrözés" -Basic.MainMenu.Edit.Transform.FitToScreen="&Képernyőhöz igazítás" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Képernyőhöz nyújtás" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Képernyő középpontjához" -Basic.MainMenu.Edit.Order="&Rendezés" -Basic.MainMenu.Edit.Order.MoveUp="Mozgatás &Fel" -Basic.MainMenu.Edit.Order.MoveDown="Mozgatás &Le" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Vízszintes tükrözés (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Függőleges tükrözés (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Képernyőhöz igazítás (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Képernyőhöz nyújtá&s" +Basic.MainMenu.Edit.Transform.CenterToScreen="Képernyő középpontjához (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Függőleges közép" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Vízszintes közép" +Basic.MainMenu.Edit.Order="Rendezés (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Mozgatás Fel (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Mozgatás Le (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Mozgatás a &Tetejére" -Basic.MainMenu.Edit.Order.MoveToBottom="Mozgatás az &Aljára" -Basic.MainMenu.Edit.AdvAudio="&Speciális hangtulajdonságok" +Basic.MainMenu.Edit.Order.MoveToBottom="Mozgatás az Aljára (&B)" +Basic.MainMenu.Edit.AdvAudio="Speciális h&angtulajdonságok" -Basic.MainMenu.View="&Nézet" -Basic.MainMenu.View.Toolbars="&Eszköztárak" +Basic.MainMenu.View="Nézet (&V)" +Basic.MainMenu.View.Toolbars="Eszköz&tárak" Basic.MainMenu.View.Docks="Dokkolás" Basic.MainMenu.View.Docks.ResetUI="Felület újraindítása" Basic.MainMenu.View.Docks.LockUI="Felület zárása" -Basic.MainMenu.View.Toolbars.Listboxes="&Gombsor" -Basic.MainMenu.View.SceneTransitions="&Jelenet átmenetek" -Basic.MainMenu.View.StatusBar="&Állapotsor" +Basic.MainMenu.View.Toolbars.Listboxes="Gombsor (&L)" +Basic.MainMenu.View.SceneTransitions="Jelenet átmenetek (&C)" +Basic.MainMenu.View.StatusBar="Állapot&sor" Basic.MainMenu.View.Fullscreen.Interface="Teljes képernyős felület" -Basic.MainMenu.SceneCollection="&Jelenet gyűjtemény" +Basic.MainMenu.SceneCollection="Jelenet gyűjtemény (&S)" Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Profile.Import="Profil importálása" Basic.MainMenu.Profile.Export="Profil exportálása" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Jelenet gyűjtemény exportálása" Basic.MainMenu.Profile.Exists="A profil már létezik" Basic.MainMenu.SceneCollection.Exists="A jelenet gyűjtemény már létezik" -Basic.MainMenu.Tools="&Eszközök" +Basic.MainMenu.Tools="Eszközök (&T)" -Basic.MainMenu.Help="&Segítség" +Basic.MainMenu.Help="Segítség (&H)" Basic.MainMenu.Help.HelpPortal="Segítség &Portál" -Basic.MainMenu.Help.Website="Weboldal megtekintése" +Basic.MainMenu.Help.Website="&Weboldal megtekintése" Basic.MainMenu.Help.Discord="Csatlakozás &Discord szerverre" -Basic.MainMenu.Help.Logs="&Naplófájlok" -Basic.MainMenu.Help.Logs.ShowLogs="&Naplófájlok megjelenítése" -Basic.MainMenu.Help.Logs.UploadCurrentLog="&Aktuális Naplófájl feltöltése" -Basic.MainMenu.Help.Logs.UploadLastLog="&Utolsó Naplófájl feltöltése" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Jelenlegi Naplófájl megtekintése" +Basic.MainMenu.Help.Logs="Nap&lófájlok" +Basic.MainMenu.Help.Logs.ShowLogs="Naplófájlok megjeleníté&se" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Aktuális Naplófájl feltöltése (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Uto&lsó Naplófájl feltöltése" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Jelenlegi Naplófájl megtekintése (&V)" Basic.MainMenu.Help.CheckForUpdates="Frissítések ellenőrzése" Basic.MainMenu.Help.CrashLogs="Hibajelentések (&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="Hibajelentések megjelenítése (&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Utolsó Hibajelentés feltöltése (&L)" +Basic.MainMenu.Help.About="Névjegy (&A)" Basic.Settings.ProgramRestart="A beállítások érvénybe lépéséhez a program újraindítása szükséges." Basic.Settings.ConfirmTitle="Változtatások megerősítése" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Tálca" Basic.Settings.General.SysTrayWhenStarted="Indításkor ikonként a tálcán" Basic.Settings.General.SystemTrayHideMinimize="Mindig a rendszertálcára minimalizálás tálca helyett" Basic.Settings.General.SaveProjectors="Projektorok mentése kilépéskor" +Basic.Settings.General.Preview="Előnézet" +Basic.Settings.General.OverflowHidden="Túlcsordulás elrejtése" +Basic.Settings.General.OverflowAlwaysVisible="Túlcsordulás mindig látható" +Basic.Settings.General.OverflowSelectionHidden="Túlcsordulás mutatása, akkor is, ha a forrás láthatatlan" Basic.Settings.General.SwitchOnDoubleClick="Átmenet a jelenetre dupla kattintás esetén" Basic.Settings.General.StudioPortraitLayout="Portré/függőleges elrendezés engedélyezése" +Basic.Settings.General.TogglePreviewProgramLabels="Előnézet/programcímek mutatása" Basic.Settings.General.Multiview="MultiView" Basic.Settings.General.Multiview.MouseSwitch="Kattintás a jelenetek közötti váltáshoz" Basic.Settings.General.Multiview.DrawSourceNames="Jelenetek neveinek megjelenítése" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Vízszintes, fel Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream típusa" +Basic.Settings.Stream.Custom.UseAuthentication="Hitelesítés használata" +Basic.Settings.Stream.Custom.Username="Felhasználónév" +Basic.Settings.Stream.Custom.Password="Jelszó" +Basic.Settings.Stream.BandwidthTestMode="Sávszélességteszt üzemmód engedélyezése" Basic.Settings.Output="Kimenet" Basic.Settings.Output.Format="Felvétel formátuma" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Figyelem: A streamtől eltérő minő Basic.Settings.Output.Simple.Warn.Lossless="Figyelem: A veszteségmentes minőséggel történő felvétel hatalmas fájlméretet generál. Ezzel a minőséggel percenként akár 7 gigabájt adatot is generálhat nagy felbontáson és képkockasebességen. Ez az eljárás nem ajánlott hosszú felvételekhez, kivéve ha hatalmas lemezterület áll rendelkezésre." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Biztos benne, hogy veszteségmentes minőséget kíván használni?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Veszteségmentes minőség figyelem!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Figyelem: Nem használható több különálló QSV kódoló streamelésre és felvételre egyidejűleg. Ha ön egyidejűleg kíván streamet és felvételt készíteni, akkor váltsa le a felvevő vagy a stream kódolóját." Basic.Settings.Output.Simple.Encoder.Software="Szoftver (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardver (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardver (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Automatikus újracsatlakozás" Basic.Settings.Output.RetryDelay="Újrapróbálkozás késleltetése (másodperc)" Basic.Settings.Output.MaxRetries="Újrapróbálkozások maximális száma" Basic.Settings.Output.Advanced="Speciális kódoló beállítások engedélyezése" -Basic.Settings.Output.EncoderPreset="Kódoló készlet (magasabb = kevesebb CPU igény)" +Basic.Settings.Output.EncoderPreset="Kódoló készlet" Basic.Settings.Output.CustomEncoderSettings="Egyéni kódolási beállítások" Basic.Settings.Output.CustomMuxerSettings="Egyéni Muxer beállítások" Basic.Settings.Output.NoSpaceFileName="Fájlnév generálása helyfoglalás nélkül" @@ -622,18 +676,18 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY Év, négy számjegy\n%YY Év, utolsó két számjegy (00-99)\n%MM Hónap mint tizedes szám (01-12)\n%DD Hónap napja, nulla kitöltéssel (01-31)\n%hh Óra 24ó formátumban (00-23)\n%mm Perc (00-59)\n%ss Másodperc (00-61)\n%% A % sign\n%a Rövidített hétköznap neve\n%A Teljes hétköznap neve\n%b Rövidített hónap neve\n%B Teljes hónap neve\n%d Hónap napja, nulla kitöltéssel (01-31)\n%H Óra 24ó formátumban (00-23)\n%I Óra 12ó formátumban (01-12)\n%m Hónap mint decimális szám (01-12)\n%M Perc (00-59)\n%p DE vagy DU megjelölés\n%S Másodperc (00-61)\n%y Év, utolsó két számjegy (00-99)\n%Y Év\n%z ISO 8601 eltolással UTC-hez képest vagy időzóna\n név vagy rövidítés\n%Z Időzóna neve vagy rövidítése\n" Basic.Settings.Video="Videó" -Basic.Settings.Video.Adapter="Videó adapter:" -Basic.Settings.Video.BaseResolution="Alap (Vászon) felbontás:" -Basic.Settings.Video.ScaledResolution="Kimeneti (Skálázott) felbontás:" -Basic.Settings.Video.DownscaleFilter="Leskálázás szűrő:" +Basic.Settings.Video.Adapter="Videó adapter" +Basic.Settings.Video.BaseResolution="Alap (Vászon) felbontás" +Basic.Settings.Video.ScaledResolution="Kimeneti (Skálázott) felbontás" +Basic.Settings.Video.DownscaleFilter="Leskálázás szűrő" Basic.Settings.Video.DisableAeroWindows="Aero Letiltása (csak Windows esetén)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Átlagos FPS érték" Basic.Settings.Video.FPSInteger="Egész FPS érték" Basic.Settings.Video.FPSFraction="Tört FPS érték" -Basic.Settings.Video.Numerator="Számláló:" -Basic.Settings.Video.Denominator="Nevező:" -Basic.Settings.Video.Renderer="Megjelenítő:" +Basic.Settings.Video.Numerator="Számláló" +Basic.Settings.Video.Denominator="Nevező" +Basic.Settings.Video.Renderer="Megjelenítő" Basic.Settings.Video.InvalidResolution="Érvénytelen felbontás érték. [szélesség] x [magasság]-nak kell lennie (pl.: 1920 x 1080)" Basic.Settings.Video.CurrentlyActive="Video kimenet jelenleg aktív. Kérem, kapcsoljon ki minden kimeneti forrást a video beállítások módosításához." Basic.Settings.Video.DisableAero="Aero kikapcsolása" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (élesített méretezés, Basic.Settings.Audio="Hang" Basic.Settings.Audio.SampleRate="Mintavételezés" Basic.Settings.Audio.Channels="Csatornák" -Basic.Settings.Audio.MeterDecayRate="Hangmérő halkulási aránya" +Basic.Settings.Audio.Meters="Mérték" +Basic.Settings.Audio.MeterDecayRate="Halkulási ráta" Basic.Settings.Audio.MeterDecayRate.Fast="Gyors" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Típus | PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Lassú (Típus II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Figyelmeztetés: Surround soun Basic.Settings.Audio.MultichannelWarning="Ha közvetít, ellenőrizze, hogy a stream szolgáltatója támogatja mind a surround sound kezelést, mind pedig a surround sound lejátszást. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast a legjobb példa, hogy mely platformokon van teljes támogatás. Ellenben a Facebook Live és a YouTube Live minden elfogadja a térhangzású hangot, a Facebook Live lekeveri stereora és a YouTube Live csak két csatornát játszik le.\n\nOBS audio szűrők kompatibilisek a térhangzású hanggal, viszont a VST bővítmények támogatása nem garantált." Basic.Settings.Audio.MultichannelWarning.Title="Engedélyezi a surround hangzást?" Basic.Settings.Audio.MultichannelWarning.Confirm="Biztos benne, hogy engedélyezi a surround hangzást?" -Basic.Settings.Audio.DesktopDevice="Asztali hangeszköz" -Basic.Settings.Audio.DesktopDevice2="Asztali hangeszköz 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/Aux hangeszköz" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux hangeszköz 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux hangeszköz 3" +Basic.Settings.Audio.Devices="Eszközök" +Basic.Settings.Audio.DesktopDevice="Asztal audio" +Basic.Settings.Audio.DesktopDevice2="Asztal audio 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/Aux hang" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux hang 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux hang 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/Aux hang 4" Basic.Settings.Audio.EnablePushToMute="Push-to-mute engedélyezése" Basic.Settings.Audio.PushToMuteDelay="Push-to-mute késleltetés" Basic.Settings.Audio.EnablePushToTalk="Push-to-talk engedélyezése" Basic.Settings.Audio.PushToTalkDelay="Push-to-talk késleltetés" Basic.Settings.Audio.UnknownAudioDevice="[Eszköz nincs csatlakoztatva vagy nem elérhető]" +Basic.Settings.Audio.Disabled="Letiltva" Basic.Settings.Advanced="Haladó" Basic.Settings.Advanced.General.ProcessPriority="Folyamat Prioritás szintje" @@ -677,8 +735,8 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Tétlen" Basic.Settings.Advanced.FormatWarning="Figyelem: Az NV12-től eltérő színformátumok elsősorban felvételhez vannak és nem ajánlott a használatuk streamekhez. Adás közben megnövekedett processzor igényt okozhat a színkonverzió." Basic.Settings.Advanced.Audio.BufferingTime="Audio pufferelési idő" Basic.Settings.Advanced.Video.ColorFormat="Színformátum" -Basic.Settings.Advanced.Video.ColorSpace="YUV színtér" -Basic.Settings.Advanced.Video.ColorRange="YUV színtartomány" +Basic.Settings.Advanced.Video.ColorSpace="Színtér" +Basic.Settings.Advanced.Video.ColorRange="Színtartomány" Basic.Settings.Advanced.Video.ColorRange.Partial="Részleges" Basic.Settings.Advanced.Video.ColorRange.Full="Teljes" Basic.Settings.Advanced.Audio.MonitoringDevice="Hangfigyelő eszköz" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="IP-hez rendelés" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Új hálózatkezelő kód engedélyezése" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Alacsony késleltetésű mód" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Gyorsbillentyűk letiltása, ha a fő ablak fókuszban van" +Basic.Settings.Advanced.AutoRemux="Automatikus remux MP4-re" +Basic.Settings.Advanced.AutoRemux.MP4="(mkv-ként mentés)" Basic.AdvAudio="Speciális hangtulajdonságok" Basic.AdvAudio.Name="Név" -Basic.AdvAudio.Volume="Hangerő (%)" +Basic.AdvAudio.Volume="Hangerő" Basic.AdvAudio.Mono="Monora lekeverés" -Basic.AdvAudio.Panning="Keverő" +Basic.AdvAudio.Balance="Egyensúly" Basic.AdvAudio.SyncOffset="Szinkron eltolás (ms)" Basic.AdvAudio.Monitoring="Hangfigyelés" Basic.AdvAudio.Monitoring.None="Figyelés kikapcsolása" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Sávok" Basic.Settings.Hotkeys="Gyorsbillentyűk" Basic.Settings.Hotkeys.Pair="Azonos billentyűkombináció a '%1' mezővel, ezért kapcsolóként működik" +Basic.Settings.Hotkeys.Filter="Szűrő" Basic.Hotkeys.SelectScene="Jelenethez kapcsolás" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Billentyűzet)" Hotkeys.AppleKeypadDecimal=". (Billentyűzet)" Hotkeys.AppleKeypadEqual="= (Billentyűzet)" Hotkeys.MouseButton="Egér %1" +Hotkeys.Escape="Esc" Mute="Némítás" Unmute="Némítás megszüntetése" @@ -762,7 +824,7 @@ SceneItemHide="Elrejti '%1'" OutputWarnings.NoTracksSelected="Ki kell jelölnie legalább egy sávot!" OutputWarnings.MultiTrackRecording="Figyelem: Bizonyos formátumok (mint az FLV) nem támogatják a több sávot felvételenként" -OutputWarnings.MP4Recording="Figyelem: Az MP4-be mentett állományok javíthatatlanok, ha a fájl nem kerül lezárásra (pl: BSOD vagy áramkimaradás esetén, stb.). Ha mindenképpen több hangsávval kíván felvételt készíteni, akkor használja az MKV állományt és remuxolja a felvételt MP4-be, miután elkészült. (Fájl->Felvételek remuxolása)" +OutputWarnings.MP4Recording="Figyelem: Az MP4/MOV-ban mentett állományok javíthatatlanok, ha a fájl nem kerül lezárásra (pl: BSOD vagy áramkimaradás esetén, stb.). Ha mindenképpen több hangsávval kíván felvételt készíteni, akkor használja az MKV állományt és remuxolja a felvételt MP4/MOV-ba, miután elkészült. (Fájl -> Felvételek remuxolása)" FinalScene.Title="Jelenet törlése" FinalScene.Text="Legalább egy jelenetnek lennie kell." @@ -770,9 +832,24 @@ FinalScene.Text="Legalább egy jelenetnek lennie kell." NoSources.Title="Nincsenek Források" NoSources.Text="Úgy fest, hogy nem adott hozzá valamilyen videoforrást, úgyhogy fekete képet fog adni. Biztos benne, hogy ezt kívánja tenni?" NoSources.Text.AddSource="Hozzáadhat forrásokat bármikor a + ikonra kattintva a Források doboz alatt a fő ablakban." +NoSources.Label="Önnek nincsenek forrásai.\nKattintson alul a + gombra,\nvagy jobbklikkeljen ide, hogy hozzáadjon egyet." ChangeBG="Szín megadása" CustomColor="Egyedi szín" BrowserSource.EnableHardwareAcceleration="Böngészőforrás hardveres támogatásának engedélyezése" +About="Névjegy" +About.Info="Az OBS Studio egy ingyenes és nyílt forráskódú videofelvevő és livestream szoftver." +About.Donate="Hozzájárulás" +About.GetInvolved="Részvétel" +About.Authors="Készítők" +About.License="Licensz" +About.Contribute="Támogasd az OBS Projektet" + +ResizeOutputSizeOfSource="Kimenet átméretezése (Forrásméret)" +ResizeOutputSizeOfSource.Text="Az alap és a kimeneti felbontás átméretezése a jelenlegi forrásra." +ResizeOutputSizeOfSource.Continue="Kívánja folytatni?" + +PreviewTransition="Átmenet előnézete" + diff --git a/UI/data/locale/it-IT.ini b/UI/data/locale/it-IT.ini index 2a121b4..3845148 100644 --- a/UI/data/locale/it-IT.ini +++ b/UI/data/locale/it-IT.ini @@ -7,17 +7,17 @@ Apply="Applica" Cancel="Annulla" Close="Chiudi" Save="Salva" -Discard="Ignora" -Disable="Disabilita" +Discard="Non salvare" +Disable="Disattiva" Yes="Sì" No="No" Add="Aggiungi" Remove="Rimuovi" Rename="Rinomina" -Interact="Interazione" +Interact="Interagisci" Filters="Filtri" Properties="Proprietà" -MoveUp="Sposta in alto" +MoveUp="Sposta su" MoveDown="Sposta giù" Settings="Impostazioni" Display="Schermo" @@ -28,17 +28,17 @@ Browse="Sfoglia" Mono="Mono" Stereo="Stereo" DroppedFrames="Fotogrammi persi %1 (%2%)" -StudioProgramProjector="Proiettore a schermo intero (anteprima)" +StudioProgramProjector="Proiettore a schermo intero (programma)" PreviewProjector="Proiettore a schermo intero (anteprima)" SceneProjector="Proiettore a schermo intero (scena)" SourceProjector="Proiettore a schermo intero (fonte)" -StudioProgramWindow="Proiettore a finestra (fonte)" +StudioProgramWindow="Proiettore a finestra (programma)" PreviewWindow="Proiettore a finestra (anteprima)" SceneWindow="Proiettore a finestra (scena)" SourceWindow="Proiettore a finestra (fonte)" -MultiviewProjector="Vista-Multipla (Schermo Intero)" -MultiviewWindowed="Vista-Multipla (Finestra)" -Clear="Svuota" +MultiviewProjector="Visualizzazione multipla (a schermo intero)" +MultiviewWindowed="Visualizzazione multipla (in finestra)" +Clear="Rimuovi" Revert="Ripristina" Show="Mostra" Hide="Nascondi" @@ -46,10 +46,10 @@ UnhideAll="Mostra tutto" Untitled="Senza titolo" New="Nuovo" Duplicate="Duplica" -Enable="Abilita" -DisableOSXVSync="Disabilita V-Sync OSX" -ResetOSXVSyncOnExit="Reimposta V-Sync OSX in uscita" -HighResourceUsage="Codifica in sovraccarico! È consigliabile abbassare le impostazioni video o utilizzare una impostazione di codifica predefinita più veloce." +Enable="Attiva" +DisableOSXVSync="Disattiva il V-Sync di OSX" +ResetOSXVSyncOnExit="Ripristina il V-Sync di OSX alla chiusura" +HighResourceUsage="Codifica in sovraccarico! È consigliabile abbassare le impostazioni video o utilizzare un preset di codifica più veloce." Transition="Transizione" QuickTransitions="Transizioni rapide" Left="Sinistra" @@ -60,7 +60,7 @@ Reset="Ripristina" Hours="Ore" Minutes="Minuti" Seconds="Secondi" -Deprecated="Deprecato" +Deprecated="Obsoleto" ReplayBuffer="Buffer di replay" Import="Importa" Export="Esporta" @@ -68,128 +68,162 @@ Copy="Copia" Paste="Incolla" PasteReference="Incolla (riferimento)" PasteDuplicate="Incolla (duplicato)" -RemuxRecordings="Remux registrazioni" +RemuxRecordings="Converti le registrazioni" Next="Avanti" Back="Indietro" -Defaults="Predefinite" -HideMixer="Nascondi nel Mixer" -TransitionOverride="Sovrascrivi transizione" +Defaults="Valori predefiniti" +HideMixer="Nascondi nel mixer" +TransitionOverride="Sovrascrivi la transizione" None="Nessuno" StudioMode.Preview="Anteprima" StudioMode.Program="Programma" -ShowInMultiview="Mostra in Vista-Multipla" -VerticalLayout="Layout verticale" +ShowInMultiview="Mostra in visualizzazione multipla" +VerticalLayout="Disposizione verticale" Group="Gruppo" +DoNotShowAgain="Non mostrare più" +Default="(predefinito)" +Calculating="Calcolo..." AlreadyRunning.Title="OBS è già in esecuzione" -AlreadyRunning.Text="OBS è già in esecuzione! A meno che non si intendeva effettuare questa operazione, chiudere tutte le istanze esistenti di OBS prima di provare a eseguirne una nuova. Se avete OBS impostato per minimizzarsi nell'area di notifica, si prega di controllare per vedere se è ancora in esecuzione." +AlreadyRunning.Text="OBS è già in esecuzione! A meno che non intendevi effettuare questa operazione, ricordati sempre di chiudere tutte le istanze esistenti di OBS prima di eseguirne una nuova. Se hai impostato OBS per ridursi nell'area di notifica, controlla che non sia ancora in esecuzione." AlreadyRunning.LaunchAnyway="Avvia comunque" -Copy.Filters="Filtri di copia" -Paste.Filters="Filtri di incollamento" +DockCloseWarning.Title="Hai chiuso la finestra di un pannello" +DockCloseWarning.Text="Hai appena chiuso la finestra di un pannello. Se vuoi mostrarlo di nuovo, vai sul menù Visualizza → Pannelli, nella barra multifunzione in alto." + +Auth.Authing.Title="Accesso in corso..." +Auth.Authing.Text="Accesso in corso con %1, attendi..." +Auth.AuthFailure.Title="Accesso fallito" +Auth.AuthFailure.Text="Impossibile eseguire l'accesso con %1:\n\n%2: %3" +Auth.InvalidScope.Title="Accesso richiesto" +Auth.InvalidScope.Text="I requisiti di accesso per %1 sono cambiati. Alcune funzionalità potrebbero non essere disponibili." +Auth.LoadingChannel.Title="Caricamento delle informazioni del canale in corso..." +Auth.LoadingChannel.Text="Caricamento delle informazioni del canale per %1, attendi..." +Auth.ChannelFailure.Title="Impossibile caricare il canale" +Auth.ChannelFailure.Text="Impossibile caricare le informazioni del canale per %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informazioni della diretta" +TwitchAuth.Stats="Statistiche di Twitch" +TwitchAuth.Feed="Feed attività di Twitch" +TwitchAuth.TwoFactorFail.Title="Impossibile interrogare il codice della diretta" +TwitchAuth.TwoFactorFail.Text="OBS non è stato in grado di connettersi al tuo account di Twitch. Assicurati che l'autenticazione a due fattori sia impostata nelle tue impostazioni di sicurezza di Twitch perché è necessaria per lo stream." + +Copy.Filters="Copia i filtri" +Paste.Filters="Incolla i filtri" + +BrowserPanelInit.Title="Avvio del browser in corso..." +BrowserPanelInit.Text="Avvio del browser, attendi..." BandwidthTest.Region="Regione" BandwidthTest.Region.US="Stati Uniti" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asia" -BandwidthTest.Region.Other="Altro" +BandwidthTest.Region.Other="Altre" -Basic.FirstStartup.RunWizard="Vuoi eseguire la procedura guidata di configurazione automatica? È possibile configurare manualmente le impostazioni facendo clic sul pulsante Impostazioni nella finestra principale." -Basic.FirstStartup.RunWizard.BetaWarning="(Nota: la procedura guidata di configurazione automatica è attualmente in beta)" -Basic.FirstStartup.RunWizard.NoClicked="Se cambi idea, è possibile eseguire la procedura guidata di configurazione automatica qualsiasi momento nuovamente dal menu strumenti." +Basic.FirstStartup.RunWizard="Vuoi eseguire la procedura di configurazione guidata? È possibile configurare manualmente le impostazioni facendo clic sul pulsante «Impostazioni» nella finestra principale." +Basic.FirstStartup.RunWizard.NoClicked="Se cambi idea, è possibile rieseguire la procedura guidata di configurazione automatica in qualsiasi momento dal menu strumenti." -Basic.AutoConfig="Auto-configurazione guidata" -Basic.AutoConfig.Beta="Auto-configurazione guidata (Beta)" -Basic.AutoConfig.ApplySettings="Applica impostazioni" +Basic.AutoConfig="Configurazione guidata automatica" +Basic.AutoConfig.ApplySettings="Applica le impostazioni" Basic.AutoConfig.StartPage="Informazioni sull'utilizzo" -Basic.AutoConfig.StartPage.SubTitle="Specificare ciò per cui si desidera utilizzare il programma" -Basic.AutoConfig.StartPage.PrioritizeStreaming="Ottimizza per lo streaming, la registrazione è secondaria" -Basic.AutoConfig.StartPage.PrioritizeRecording="Ottimizza solo per la registrazione, non farò streaming" -Basic.AutoConfig.VideoPage="Impostazioni Video" -Basic.AutoConfig.VideoPage.SubTitle="Specificare le impostazioni video desiderate e che desideri utilizzare" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Attuale (%1x%2)" -Basic.AutoConfig.VideoPage.BaseResolution.Display="Display %1 (%2x%3)" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="Attuale (%1)" +Basic.AutoConfig.StartPage.SubTitle="Specifica per cosa desideri utilizzare il programma" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Ottimizza per le dirette, le registrazioni sono meno importanti" +Basic.AutoConfig.StartPage.PrioritizeRecording="Ottimizza solo per le registrazioni, non faccio dirette" +Basic.AutoConfig.VideoPage="Impostazioni video" +Basic.AutoConfig.VideoPage.SubTitle="Specifica le impostazioni video che desideri utilizzare" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Usa quella attuale (%1×%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Schermo %1 (%2×%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Usa quelli attuali (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 o 30, ma preferisco 60 quando possibile" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 o 30, ma preferisco un'alta risoluzione" -Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: La risoluzione di base non è necessariamente la stessa risoluzione che sarà per le dirette o per le registrazioni. La risoluzione di dirette/registrazioni effettiva può essere scalata dalla risoluzione base per ridurre le risorse utilizzate o i requisiti della velocità di trasmissione." -Basic.AutoConfig.StreamPage="Informazioni stream" -Basic.AutoConfig.StreamPage.SubTitle="Per favore inserisci le informazioni sullo stream" +Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: la risoluzione (di base) dell'inquadratura non sarà necessariamente la stessa risoluzione per le dirette o per le registrazioni. La risoluzione delle dirette/registrazioni effettiva potrebbe essere scalata dalla risoluzione dell'inquadratura per ridurre le risorse utilizzate o i requisiti di velocità in bit." +Basic.AutoConfig.StreamPage="Informazioni per le dirette" +Basic.AutoConfig.StreamPage.SubTitle="Per favore inserisci le informazioni per le dirette" +Basic.AutoConfig.StreamPage.ConnectAccount="Collega l'account (facoltativo)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Disconnetti l'account" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Vuoi disconnettere l'account?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Questa modifica verrà applicata immediatamente. Sei sicuro di voler disconnettere il tuo account?" +Basic.AutoConfig.StreamPage.UseStreamKey="Utilizza il codice delle dirette" Basic.AutoConfig.StreamPage.Service="Servizio" -Basic.AutoConfig.StreamPage.Service.ShowAll="Mostra tutto..." +Basic.AutoConfig.StreamPage.Service.ShowAll="Mostra tutti..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizzato..." Basic.AutoConfig.StreamPage.Server="Server" -Basic.AutoConfig.StreamPage.StreamKey="Chiave Stream" -Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="Stima il bitrate con test di larghezza di banda (può richiedere alcuni minuti)" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferisci la codifica hardware" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="La codifica hardware elimina la maggior parte dell'utilizzo della CPU, ma può richiedere più bitrate per ottenere lo stesso livello di qualità." -Basic.AutoConfig.StreamPage.StreamWarning.Title="Avviso stream" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Il test di larghezza di banda consiste di trasmettere dati video casuali senza audio sul tuo canale. Se possibile, è raccomandabile di disattivare temporaneamente il salvataggio degli stream e di metterli privati fino a quando non finisce il test. Continuare?" +Basic.AutoConfig.StreamPage.StreamKey="Codice delle dirette" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(link)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Calcola la velocità in bit tramite un test di larghezza di banda (richiede alcuni minuti)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferisco la codifica hardware" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="La codifica hardware elimina la maggior parte dell'utilizzo della CPU, ma può richiedere più velocità in bit per ottenere lo stesso livello di qualità." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Avviso per la diretta" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Il test di larghezza di banda consiste nel trasmettere dati video casuali senza audio sul tuo canale. Se possibile, è consigliabile disattivare temporaneamente il salvataggio delle dirette e di impostare le dirette in modalità privata fino a quando non finisce il test. Vuoi continuare?" Basic.AutoConfig.TestPage="Risultato finale" -Basic.AutoConfig.TestPage.SubTitle.Testing="Il programma sta ora eseguendo una serie di test per stimare le impostazioni più ideali" -Basic.AutoConfig.TestPage.SubTitle.Complete="Test completo" -Basic.AutoConfig.TestPage.TestingBandwidth="Esecuzione di test di larghezza di banda, questo potrebbe richiedere alcuni minuti..." +Basic.AutoConfig.TestPage.SubTitle.Testing="Il programma sta ora eseguendo una serie di test per stimare le impostazioni ideali" +Basic.AutoConfig.TestPage.SubTitle.Complete="Test completato" +Basic.AutoConfig.TestPage.TestingBandwidth="Esecuzione del test della larghezza di banda in corso, potrebbe richiedere alcuni minuti..." Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Connessione a: %1..." -Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Impossibile connettersi ad alcun server, per favore verifica la tua connessione internet e riprova." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Impossibile connettersi a qualunque server, per favore verifica la tua connessione internet e riprova." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Test della larghezza di banda per: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="Test streaming encoder, questo può richiedere un minuto..." -Basic.AutoConfig.TestPage.TestingRecordingEncoder="Test encoder di registrazione, questo può richiedere un minuto..." -Basic.AutoConfig.TestPage.TestingRes="Test di risoluzioni, questo potrebbe richiedere alcuni minuti..." -Basic.AutoConfig.TestPage.TestingRes.Fail="Impossibile avviare l'encoder" -Basic.AutoConfig.TestPage.TestingRes.Resolution="Testando %1x%2 %3 FPS..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="Streaming Encoder" -Basic.AutoConfig.TestPage.Result.RecordingEncoder="Encoder di registrazione" -Basic.AutoConfig.TestPage.Result.Header="Il programma ha determinato che queste impostazioni siano le più ideali per te:" -Basic.AutoConfig.TestPage.Result.Footer="Per utilizzare queste impostazioni, fare clic su Applica impostazioni. Per riconfigurare la procedura guidata e provare di nuovo, fare clic su Indietro. Per configurare manualmente le impostazioni, fare clic su Annulla e aprire le impostazioni." +Basic.AutoConfig.TestPage.TestingStreamEncoder="Test della codifica delle dirette, può richiedere circa un minuto..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Test della codifica di registrazione, può richiedere circa un minuto..." +Basic.AutoConfig.TestPage.TestingRes="Test delle risoluzioni, potrebbe richiedere alcuni minuti..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Impossibile avviare la codifica" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Test della risoluzione %1×%2 a %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codifica per le dirette" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codifica per le registrazioni" +Basic.AutoConfig.TestPage.Result.Header="Il programma ha rilevato che queste impostazioni sono le più adatte per questo dispositivo:" +Basic.AutoConfig.TestPage.Result.Footer="Per utilizzare queste impostazioni, fai clic su «Applica le impostazioni». Per riprovare a configurare la procedura guidata, fai clic su «Indietro». Per configurare manualmente le impostazioni, fai clic su «Annulla» e apri le «Impostazioni»." Basic.Stats="Statistiche" -Basic.Stats.CPUUsage="Utilizzo CPU" -Basic.Stats.HDDSpaceAvailable="Spazio HDD disponibile" -Basic.Stats.MemoryUsage="Memoria occupata" -Basic.Stats.AverageTimeToRender="Tempo medio per il rendering frame" +Basic.Stats.CPUUsage="Utilizzo della CPU" +Basic.Stats.HDDSpaceAvailable="Spazio su disco disponibile" +Basic.Stats.MemoryUsage="Memoria utilizzata" +Basic.Stats.AverageTimeToRender="Tempo medio per il render di un fotogramma" Basic.Stats.SkippedFrames="Fotogrammi saltati a causa del lag della codifica" -Basic.Stats.MissedFrames="Perdita frame a causa del lag del rendering" -Basic.Stats.Output.Stream="Stream" +Basic.Stats.MissedFrames="Fotogrammi persi a causa del lag del rendering" +Basic.Stats.Output.Stream="Diretta streaming" Basic.Stats.Output.Recording="Registrazione" Basic.Stats.Status="Stato" Basic.Stats.Status.Recording="Registrazione in corso" Basic.Stats.Status.Live="IN DIRETTA" Basic.Stats.Status.Reconnecting="Riconnessione in corso" -Basic.Stats.Status.Inactive="Inattivo" +Basic.Stats.Status.Inactive="Inattiva" Basic.Stats.DroppedFrames="Perdita di fotogrammi (rete)" Basic.Stats.MegabytesSent="Uscita dati totale" -Basic.Stats.Bitrate="Bitrate" +Basic.Stats.Bitrate="Velocità in bit" +Basic.Stats.DiskFullIn="Disco pieno in (appross.)" + +ResetUIWarning.Title="Sei sicuro di voler ripristinare l'interfaccia utente?" +ResetUIWarning.Text="Se ripristini l'interfaccia utente, verranno nascosti dei pannelli. Dovrai rimostrare questi pannelli dal menù visualizza se vuoi che siano visibili.\n\nSei sicuro di voler ripristinare l'interfaccia utente?" Updater.Title="Nuovo aggiornamento disponibile" -Updater.Text="C'è un nuovo aggiornamento disponibile:" +Updater.Text="È disponibile un nuovo aggiornamento:" Updater.UpdateNow="Aggiorna ora" Updater.RemindMeLater="Ricordamelo più tardi" Updater.Skip="Salta versione" Updater.Running.Title="Programma attualmente attivo" -Updater.Running.Text="Uscite sono attualmente attive, chiudi qualsiasi uscita attiva prima di tentare l'aggiornamento" +Updater.Running.Text="La registrazione o la diretta è ancora in corso. Prima di tentare un aggiornamento, disattiva la registrazione o la diretta" Updater.NoUpdatesAvailable.Title="Nessun aggiornamento disponibile" Updater.NoUpdatesAvailable.Text="Nessun aggiornamento attualmente disponibile" Updater.FailedToLaunch="Avvio dello strumento di aggiornamento non riuscito" Updater.GameCaptureActive.Title="Cattura gioco attivo" -Updater.GameCaptureActive.Text="L'hook della libreria di cattura gioco è attualmente in uso. Chiudi qualsiasi gioco/programma oggetto di acquisizione (o riavvia Windows) e prova ancora." +Updater.GameCaptureActive.Text="L'hook della libreria di cattura gioco è attualmente in uso. Chiudi qualsiasi gioco/programma che viene catturato (o riavvia Windows) e riprova." QuickTransitions.SwapScenes="Scambia scene di anteprima/uscita dopo la transizione" -QuickTransitions.SwapScenesTT="Scambia le scene di uscita con quella in anteprima dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale." -QuickTransitions.DuplicateScene="Duplica scena" -QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità delle fonti senza modificare l'uscita.\nPer modificare le proprietà delle fonti senza modificare l'uscita, abilità 'Fonti duplicate'.\nCambiare questo valore ripristinerà la scena di uscita attuale (se esiste ancora)." -QuickTransitions.EditProperties="Duplica fonte" -QuickTransitions.EditPropertiesTT="Quando si modifica la stessa scena, consente la modifica di fonti senza modificarne l'uscita. \nQuesto può essere usato solo se 'Scene doppia' è attivo.\nCerte fonti (come media o catture) non lo supportano e devono essere modificate separatamente.\nCambiare questo valore ripristinerà l'attuale scena di uscita (se esiste ancora).\n\nAttenzione: dato che la fonte verrà duplicata, questo potrebbe richiedere risorse video o di sistema aggiuntive." -QuickTransitions.HotkeyName="Transizioni rapide: %1" +QuickTransitions.SwapScenesTT="Scambia le scene di uscita con quelle in anteprima dopo la transizione (ammesso che la scena in uscita originale ci sia ancora).\nQuesto non modificherà eventuali cambiamenti apportati alla scena di uscita originale." +QuickTransitions.DuplicateScene="Duplica la scena" +QuickTransitions.DuplicateSceneTT="Quando si modifica la stessa scena, permette di modificare la trasformazione/visibilità delle fonti senza modificare l'uscita.\nPer modificare le proprietà delle fonti senza modificare l'uscita, attiva «Duplica le fonti».\nCambiare questo valore ripristinerà la scena di uscita attuale (se esiste ancora)." +QuickTransitions.EditProperties="Duplica le fonti" +QuickTransitions.EditPropertiesTT="Durante la modifica della stessa scena, permette la modifica delle proprietà delle fonti senza modificarne l'uscita.\nQuesto può essere usato solo se «Duplica la scena» è attivato.\nCerte fonti (come file multimediali o catture) non supportano questo e devono essere modificate separatamente.\nCambiare questo valore ripristinerà l'attuale scena di uscita (se esiste ancora).\n\nAttenzione: dato che la fonte verrà duplicata, potrebbe richiedere risorse video o di sistema aggiuntive." +QuickTransitions.HotkeyName="Transizione rapida «%1»" -Basic.AddTransition="Aggiungi transizione configurabile" -Basic.RemoveTransition="Rimuovi transizione configurabile" +Basic.AddTransition="Aggiungi una transizione configurabile" +Basic.RemoveTransition="Rimuovi una transizione configurabile" Basic.TransitionProperties="Proprietà di transizione" Basic.SceneTransitions="Transizioni di scena" Basic.TransitionDuration="Durata" Basic.TogglePreviewProgramMode="Modalità studio" TransitionNameDlg.Text="Inserisci il nome della transizione" -TransitionNameDlg.Title="Nome transizione" +TransitionNameDlg.Title="Nome della transizione" TitleBar.Profile="Profilo" TitleBar.Scenes="Scene" @@ -200,122 +234,131 @@ NameExists.Text="Il nome è già in uso." NoNameEntered.Title="Inserisci un nome valido" NoNameEntered.Text="Non è possibile utilizzare nomi vuoti." -ConfirmStart.Title="Vuoi iniziare la trasmissione?" -ConfirmStart.Text="Sei sicuro di voler iniziare una trasmissione?" +ConfirmStart.Title="Vuoi avviare la diretta?" +ConfirmStart.Text="Sei sicuro di voler avviare una diretta?" -ConfirmStop.Title="Vuoi fermare la trasmissione?" -ConfirmStop.Text="Sei sicuro di voler interrompere questa trasmissione?" +ConfirmStop.Title="Vuoi interrompere la diretta?" +ConfirmStop.Text="Sei sicuro di voler interrompere questa diretta?" + +ConfirmBWTest.Title="Vuoi avviare il test della larghezza di banda?" +ConfirmBWTest.Text="Hai configurato OBS in modalità di test di larghezza di banda. Questa modalità ti permette di eseguire i test della rete senza dover avviare una diretta. Quando hai finito di eseguire i test, ricordati di disattivare la modalità per permettere ai tuoi spettatori di guardare la diretta.\n\nVuoi continuare?" ConfirmExit.Title="Vuoi uscire da OBS?" -ConfirmExit.Text="OBS è attualmente attivo. Tutte le trasmissioni/registrazioni saranno fermate. Sei sicuro di voler uscire?" +ConfirmExit.Text="OBS è attualmente attivo. Tutte le dirette/registrazioni saranno interrotte. Sei sicuro di voler uscire?" ConfirmRemove.Title="Conferma la rimozione" -ConfirmRemove.Text="Sei sicuro di voler rimuovere '$1'?" -ConfirmRemove.TextMultiple="Sei sicuro di volere rimuovere %1 elementi?" +ConfirmRemove.Text="Sei sicuro di voler rimuovere «$1»?" +ConfirmRemove.TextMultiple="Sei sicuro di voler rimuovere %1 elementi?" + +Output.StartStreamFailed="Impossibile avviare la diretta" +Output.StartRecordingFailed="Impossibile avviare la registrazione" +Output.StartReplayFailed="Impossibile avviare il buffer di replay" +Output.StartFailedGeneric="Impossibile creare il file di uscita. Controlla il log per i dettagli.\n\nNota: se utilizzi la codifica NVENC o AMD, assicurati che i driver video siano aggiornati all'ultima versione." -Output.StartStreamFailed="Avvio della trasmissione non riuscito" -Output.StartRecordingFailed="Avvio della registrazione non riuscito" -Output.StartReplayFailed="Avvio del buffer di riproduzione non riuscito" -Output.StartFailedGeneric="L'avvio dell'uscita non è riuscito. Controlla il log per i dettagli.\n\nNote: se utilizzi i codificatori NVENC o AMD, assicurati che i driver video siano aggiornati." Output.ConnectFail.Title="Impossibile connettersi" Output.ConnectFail.BadPath="Percorso o URL di connessione non valido. Controlla le tue impostazioni per confermare che siano valide." Output.ConnectFail.ConnectFailed="Connessione al server fallita" -Output.ConnectFail.InvalidStream="Impossibile accedere al canale o alla chiave di trasmissione specificata, controlla di nuovo la tua chiave di trasmissione. Se è corretta, potrebbe esserci un problema con la connessione con il server." +Output.ConnectFail.InvalidStream="Impossibile accedere al canale o al codice delle dirette specificato, controlla di aver inserito il codice delle dirette correttamente. Se è corretto, potrebbe esserci un problema con la connessione con al server." Output.ConnectFail.Error="Si è verificato un errore non previsto durante la connessione al server. Controlla il file di log per più informazioni." Output.ConnectFail.Disconnected="Disconnesso dal server." +Output.StreamEncodeError.Title="Errore di codifica" +Output.StreamEncodeError.Msg="Si è verificato un errore di codifica durante lo streaming." + Output.RecordFail.Title="Impossibile avviare la registrazione" -Output.RecordFail.Unsupported="Il formato output non è supportato o non supporta più di una traccia audio. Per favore controlla i tuoi settaggi e riprova." +Output.RecordFail.Unsupported="Il formato del file di uscita non è supportato o non supporta più di una traccia audio. Per favore, controlla le tue impostazioni e riprova." Output.RecordNoSpace.Title="Spazio su disco insufficiente" -Output.RecordNoSpace.Msg="Non c'è abbastanza spazio su disco per continuazre la registrazione." +Output.RecordNoSpace.Msg="Non c'è abbastanza spazio su disco per continuare la registrazione." Output.RecordError.Title="Errore di registrazione" Output.RecordError.Msg="Si è verificato un errore non specificato durante la registrazione." +Output.RecordError.EncodeErrorMsg="Si è verificato un errore di codifica durante la registrazione." Output.ReplayBuffer.NoHotkey.Title="Nessuna scorciatoia assegnata!" -Output.ReplayBuffer.NoHotkey.Msg="Nessuna scorciatoia impostata per salvare il buffer di replay. Imposta la scorciatoia \"Salva\" per poter salvare le registrazioni in replay." +Output.ReplayBuffer.NoHotkey.Msg="Nessuna scorciatoia impostata per salvare il buffer di replay. Imposta la scorciatoia «Salva» per poter salvare le registrazioni dei replay." -Output.BadPath.Title="Percorso di file invalido" -Output.BadPath.Text="Il percorso configurato per il file di output non è valido. Controlla le tue impostazioni per confermare che un percorso di file valido è stato impostato." +Output.BadPath.Title="Percorso del file non valido" +Output.BadPath.Text="Il percorso configurato per il file di uscita non è valido. Controlla le tue impostazioni per confermare che un percorso dei file valido è stato impostato." LogReturnDialog="Caricamento del file di log avvenuto con successo" -LogReturnDialog.CopyURL="Copia URL" -LogReturnDialog.ErrorUploadingLog="Errore di caricamento del file di log" +LogReturnDialog.CopyURL="Copia l'URL" +LogReturnDialog.ErrorUploadingLog="Errore nel caricamento del file di log" -LicenseAgreement="Accordo di licenza" -LicenseAgreement.PleaseReview="Si prega di rivedere le condizioni di licenza prima di usare obs. Tramite questo programma, l'utente riconosce di avere letto e accettare i termini della GNU General Public License v 2.0. Si prega di scorrere verso il basso per vedere il resto dell'accordo." -LicenseAgreement.ClickIAgreeToContinue="Se si accettano i termini dell'accordo, fare clic su Accetta per continuare. Devi accettare l'accordo per utilizzare obs." -LicenseAgreement.IAgree="Accetto" -LicenseAgreement.Exit="Esci" - -Remux.SourceFile="Registrazione OBS" +Remux.SourceFile="Registrazioni di OBS" Remux.TargetFile="File di destinazione" Remux.Remux="Converti" -Remux.OBSRecording="Registrazione OBS" -Remux.FinishedTitle="Conversione finita" -Remux.Finished="Registrazione convertita" -Remux.FinishedError="Registrazione convertita, ma il file potrebbe essere incompleto" -Remux.SelectRecording="Selezionare registrazione OBS…" -Remux.SelectTarget="Selezionare il file di destinazione…" -Remux.FileExistsTitle="Il file di destinazione esiste" -Remux.FileExists="Il file di destinazione esiste, si desidera sostituirlo?" +Remux.Stop="Interrompi la conversione" +Remux.ClearFinished="Rimuovi gli elementi completati" +Remux.ClearAll="Rimuovi tutti gli elementi" +Remux.OBSRecording="Registrazioni di OBS" +Remux.FinishedTitle="Conversione completata" +Remux.Finished="La registrazione è stata convertita" +Remux.FinishedError="La registrazione è stata convertita, ma il file potrebbe essere incompleto" +Remux.SelectRecording="Seleziona una registrazione di OBS…" +Remux.SelectTarget="Seleziona il file di destinazione…" +Remux.FileExistsTitle="Il file di destinazione è già presente" +Remux.FileExists="I seguenti file di destinazione sono già presenti. Vuoi sostituirli?" Remux.ExitUnfinishedTitle="Conversione in corso" -Remux.ExitUnfinished="La conversione non è finita, fermandosi ora può rendere il file di destinazione inutilizzabile.\nÈ sicuro di voler interrompere la conversione?" +Remux.ExitUnfinished="La conversione non è finita, interromperla ora potrebbe rendere il file di destinazione inutilizzabile.\nSei sicuro di voler interrompere la conversione?" +Remux.HelpText="Trascina i file da convertire in questa finestra, oppure seleziona una casella «Registrazioni di OBS» vuota per sfogliare i file." -UpdateAvailable="Nuovo aggiornamento disponibile" -UpdateAvailable.Text="Versione %1.%2.%3 è ora disponibile. Clicca qui per scaricare" +UpdateAvailable="È disponibile un nuovo aggiornamento" +UpdateAvailable.Text="La versione %1.%2.%3 è ora disponibile. Fai clic qui per scaricarla" -Basic.DesktopDevice1="Audio desktop" -Basic.DesktopDevice2="Audio desktop 2" -Basic.AuxDevice1="Mic/Aux" -Basic.AuxDevice2="Mic/Aux 2" -Basic.AuxDevice3="Mic/Aux 3" -Basic.AuxDevice4="Mic/Aux 4" +Basic.DesktopDevice1="Audio del desktop" +Basic.DesktopDevice2="Audio del desktop 2" +Basic.AuxDevice1="Microfono/disp. ausiliario" +Basic.AuxDevice2="Microfono/disp. ausiliario 2" +Basic.AuxDevice3="Microfono/disp. ausiliario 3" +Basic.AuxDevice4="Microfono/disp. ausiliario 4" Basic.Scene="Scena" -Basic.DisplayCapture="Mostra cattura" +Basic.DisplayCapture="Cattura lo schermo" -Basic.Main.PreviewConextMenu.Enable="Abilita anteprima" +Basic.Main.PreviewConextMenu.Enable="Attiva l'anteprima" + +Basic.Main.Preview.Disable="Disattiva l'anteprima" ScaleFiltering="Scala di filtraggio" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilineare" ScaleFiltering.Bicubic="Bicubico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Zona" Deinterlacing="Deinterlacciamento" Deinterlacing.Discard="Scarta" Deinterlacing.Retro="Retrò" -Deinterlacing.Blend="Blend" -Deinterlacing.Blend2x="Blend 2x" -Deinterlacing.Linear="Linear" -Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Blend="Fondi" +Deinterlacing.Blend2x="Fondi ×2" +Deinterlacing.Linear="Lineare" +Deinterlacing.Linear2x="Lineare ×2" Deinterlacing.Yadif="Yadif" -Deinterlacing.Yadif2x="Yadif 2x" -Deinterlacing.TopFieldFirst="Priorità livello superiore" -Deinterlacing.BottomFieldFirst="Priorità livello inferiore" +Deinterlacing.Yadif2x="Yadif ×2" +Deinterlacing.TopFieldFirst="Priorità nei livelli superiori" +Deinterlacing.BottomFieldFirst="Priorità nei livelli inferiori" -VolControl.SliderUnmuted="Cursore del volume per '%1': %2" -VolControl.SliderMuted="Cursore del volume per '%1': %2 (attualmente silenziato)" -VolControl.Mute="Silenzia '%1'" -VolControl.Properties="Proprietà di '%1'" +VolControl.SliderUnmuted="Barra del volume per «%1»: %2" +VolControl.SliderMuted="Barra del volume per «%1»: %2 (attualmente silenziato)" +VolControl.Mute="Silenzia «%1'»" +VolControl.Properties="Proprietà di «%1»" -Basic.Main.AddSceneDlg.Title="Aggiungi scena" +Basic.Main.AddSceneDlg.Title="Aggiunta di una scena" Basic.Main.AddSceneDlg.Text="Inserisci il nome della scena" Basic.Main.DefaultSceneName.Text="Scena %1" -Basic.Main.AddSceneCollection.Title="Aggiungi collezione scene" -Basic.Main.AddSceneCollection.Text="Per favore inserisci il nome della collezione delle scene" +Basic.Main.AddSceneCollection.Title="Aggiunta di una collezione di scene" +Basic.Main.AddSceneCollection.Text="Inserisci il nome della collezione di scene" -Basic.Main.RenameSceneCollection.Title="Rinomina collezione scene" +Basic.Main.RenameSceneCollection.Title="Rinomina della collezione di scene" -AddProfile.Title="Aggiungi profilo" +AddProfile.Title="Aggiunta di un profilo" AddProfile.Text="Digita il nome del profilo" -RenameProfile.Title="Rinomina profilo" +RenameProfile.Title="Rinomina del profilo" -Basic.Main.MixerRename.Title="Rinomina fonte audio" -Basic.Main.MixerRename.Text="Inserisci il nome per la fonte audio" +Basic.Main.MixerRename.Title="Rinomina della fonte audio" +Basic.Main.MixerRename.Text="Inserisci il nome della fonte audio" Basic.Main.PreviewDisabled="L'anteprima è attualmente disattivata" @@ -325,40 +368,40 @@ Basic.SourceSelect.CreateNew="Crea una nuova fonte" Basic.SourceSelect.AddExisting="Aggiungine una esistente" Basic.SourceSelect.AddVisible="Rendi visibile la fonte" -Basic.PropertiesWindow="Proprietà di '%1'" +Basic.PropertiesWindow="Proprietà di «%1»" Basic.PropertiesWindow.AutoSelectFormat="%1 (autoseleziona: %2)" Basic.PropertiesWindow.SelectColor="Seleziona il colore" Basic.PropertiesWindow.SelectFont="Seleziona il tipo di carattere" Basic.PropertiesWindow.ConfirmTitle="Impostazioni modificate" -Basic.PropertiesWindow.Confirm="Ci sono modifiche non salvate. Le vuoi mantenere?" +Basic.PropertiesWindow.Confirm="Sono state apportate delle modifiche. Vuoi salvarle?" Basic.PropertiesWindow.NoProperties="Nessuna proprietà disponibile" -Basic.PropertiesWindow.AddFiles="Aggiungi File" -Basic.PropertiesWindow.AddDir="Aggiungi Cartella" -Basic.PropertiesWindow.AddURL="Aggiungi Percorso/URL" -Basic.PropertiesWindow.AddEditableListDir="Aggiungi cartella a '%1'" -Basic.PropertiesWindow.AddEditableListFiles="Aggiungi file a '%1'" -Basic.PropertiesWindow.AddEditableListEntry="Aggiungi voci a '%1'" -Basic.PropertiesWindow.EditEditableListEntry="Modifica voce da '%1'" +Basic.PropertiesWindow.AddFiles="Aggiungi dei file" +Basic.PropertiesWindow.AddDir="Aggiungi una cartella" +Basic.PropertiesWindow.AddURL="Aggiungi un percorso/URL" +Basic.PropertiesWindow.AddEditableListDir="Aggiungi una cartella a «%1»" +Basic.PropertiesWindow.AddEditableListFiles="Aggiungi dei file a «%1»" +Basic.PropertiesWindow.AddEditableListEntry="Aggiungi una voce a «%1»" +Basic.PropertiesWindow.EditEditableListEntry="Modifica la voce da «%1»" Basic.PropertiesView.FPS.Simple="Valori FPS semplici" Basic.PropertiesView.FPS.Rational="Valori FPS razionali" Basic.PropertiesView.FPS.ValidFPSRanges="Intervalli di FPS validi:" -Basic.InteractionWindow="Interagendo con '%1'" +Basic.InteractionWindow="Interazione con «%1»" -Basic.StatusBar.Reconnecting="Disconnesso, riconnessione in %2 secondi (tentativo%1)" -Basic.StatusBar.AttemptingReconnect="Tentativo di riconnessione... (tentativo %1)" +Basic.StatusBar.Reconnecting="Disconnesso, riconnessione in %2 secondi (tentativo %1)" +Basic.StatusBar.AttemptingReconnect="Tentativo di riconnessione in corso... (tentativo %1)" Basic.StatusBar.ReconnectSuccessful="Riconnessione eseguita" Basic.StatusBar.Delay="Ritardo (%1 sec)" -Basic.StatusBar.DelayStartingIn="Ritardo (inizio in %1 sec.)" -Basic.StatusBar.DelayStoppingIn="Ritardo (arresto in %1 sec.)" -Basic.StatusBar.DelayStartingStoppingIn="Ritardo (arresto in %1 sec., avvio in %2 sec.)" +Basic.StatusBar.DelayStartingIn="Ritardo (avvio dopo %1 sec)" +Basic.StatusBar.DelayStoppingIn="Ritardo (interruzione dopo %1 sec)" +Basic.StatusBar.DelayStartingStoppingIn="Ritardo (interruzione dopo %1 sec, avvio dopo %2 sec)" Basic.Filters="Filtri" -Basic.Filters.AsyncFilters="Filtri audio/Video" +Basic.Filters.AsyncFilters="Filtri audio/video" Basic.Filters.AudioFilters="Filtri audio" -Basic.Filters.EffectFilters="Filtri per effetti" -Basic.Filters.Title="Filtri per '%1'" +Basic.Filters.EffectFilters="Filtri degli effetti" +Basic.Filters.Title="Filtri per «%1»" Basic.Filters.AddFilter.Title="Nome del filtro" Basic.Filters.AddFilter.Text="Specifica il nome del filtro" @@ -370,7 +413,7 @@ Basic.TransformWindow.Alignment="Allinea posizioni" Basic.TransformWindow.BoundsType="Tipo di casella di delimitazione" Basic.TransformWindow.BoundsAlignment="Allineamento nel riquadro di delimitazione" Basic.TransformWindow.Bounds="Dimensione casella di delimitazione" -Basic.TransformWindow.Crop="Crop" +Basic.TransformWindow.Crop="Ritaglia" Basic.TransformWindow.Alignment.TopLeft="In alto a sinistra" Basic.TransformWindow.Alignment.TopCenter="In alto al centro" @@ -382,7 +425,7 @@ Basic.TransformWindow.Alignment.BottomLeft="In basso a sinistra" Basic.TransformWindow.Alignment.BottomCenter="In basso al centro" Basic.TransformWindow.Alignment.BottomRight="In basso a destra" -Basic.TransformWindow.BoundsType.None="Nessun bordo" +Basic.TransformWindow.BoundsType.None="Nessun limite" Basic.TransformWindow.BoundsType.MaxOnly="Soltanto la grandezza maggiore" Basic.TransformWindow.BoundsType.ScaleInner="Scala all'interno dei limiti" Basic.TransformWindow.BoundsType.ScaleOuter="Scala ai limiti esterni" @@ -391,196 +434,207 @@ Basic.TransformWindow.BoundsType.ScaleToHeight="Scala all'altezza dei limiti" Basic.TransformWindow.BoundsType.Stretch="Allungare ai limiti" Basic.Main.AddSourceHelp.Title="Impossibile aggiungere la fonte" -Basic.Main.AddSourceHelp.Text="Devi avere almeno 1 scena per aggiungere una fonte." +Basic.Main.AddSourceHelp.Text="Devi avere almeno una scena per aggiungere una fonte." Basic.Main.Scenes="Scene" Basic.Main.Sources="Fonti" Basic.Main.Controls="Controlli" -Basic.Main.Connecting="Connessione..." -Basic.Main.StartRecording="Avvia registrazione" -Basic.Main.StartReplayBuffer="Avvia buffer di replay" -Basic.Main.StartStreaming="Avvia trasmissione" -Basic.Main.StopRecording="Ferma registrazione" -Basic.Main.StoppingRecording="Arresto della registrazione..." -Basic.Main.StopReplayBuffer="Termina buffer di replay" -Basic.Main.StoppingReplayBuffer="Arresto del buffer di riproduzione in corso..." -Basic.Main.StopStreaming="Ferma trasmissione" -Basic.Main.StoppingStreaming="Arresto trasmissione..." -Basic.Main.ForceStopStreaming="Ferma trasmissione (annulla ritardo)" +Basic.Main.Connecting="Connessione in corso..." +Basic.Main.StartRecording="Avvia la registrazione" +Basic.Main.StartReplayBuffer="Avvia il buffer di replay" +Basic.Main.StartStreaming="Avvia la diretta" +Basic.Main.StopRecording="Termina la registrazione" +Basic.Main.StoppingRecording="Terminazione della registrazione in corso..." +Basic.Main.StopReplayBuffer="Termina il buffer di replay" +Basic.Main.StoppingReplayBuffer="Terminazione del buffer di replay in corso..." +Basic.Main.StopStreaming="Termina la diretta" +Basic.Main.StoppingStreaming="Terminazione della diretta in corso..." +Basic.Main.ForceStopStreaming="Termina la diretta (annulla ritardo)" Basic.Main.Group="Gruppo %1" -Basic.Main.GroupItems="Elementi selezionati" +Basic.Main.GroupItems="Raggruppa gli elementi selezionati" Basic.Main.Ungroup="Separa" Basic.MainMenu.File="&File" Basic.MainMenu.File.Export="&Esporta" Basic.MainMenu.File.Import="&Importa" -Basic.MainMenu.File.ShowRecordings="Visualizza ®istrazioni" -Basic.MainMenu.File.Remux="Converti re&gistrazioni" -Basic.MainMenu.File.Settings="&Impostazioni" -Basic.MainMenu.File.ShowSettingsFolder="Visualizza cartella impostazioni" +Basic.MainMenu.File.ShowRecordings="Visualizza le ®istrazioni" +Basic.MainMenu.File.Remux="Converti le registrazioni (&M)" +Basic.MainMenu.File.Settings="Impo&stazioni" +Basic.MainMenu.File.ShowSettingsFolder="Visualizza la cartella delle impostazioni" Basic.MainMenu.File.ShowProfileFolder="Visualizza la cartella dei profili" -Basic.MainMenu.AlwaysOnTop="&Sempre in primo piano" -Basic.MainMenu.File.Exit="E&sci" +Basic.MainMenu.AlwaysOnTop="Sempre in primo pi&ano" +Basic.MainMenu.File.Exit="Esci (&X)" -Basic.MainMenu.Edit="&Modifica" -Basic.MainMenu.Edit.Undo="&Annulla" -Basic.MainMenu.Edit.Redo="&Ripristina" -Basic.MainMenu.Edit.UndoAction="&Ripristina $1" -Basic.MainMenu.Edit.RedoAction="&Ripristina $1" -Basic.MainMenu.Edit.LockPreview="&Blocca anteprima" -Basic.MainMenu.Edit.Scale="Anteprima ridimen&sionamento" -Basic.MainMenu.Edit.Scale.Window="Scala alla finestra" -Basic.MainMenu.Edit.Scale.Canvas="Tela (%1x%2)" -Basic.MainMenu.Edit.Scale.Output="Uscita (%1x%2)" +Basic.MainMenu.Edit="Modifica (&E)" +Basic.MainMenu.Edit.Undo="Ann&ulla" +Basic.MainMenu.Edit.Redo="&Ripeti" +Basic.MainMenu.Edit.UndoAction="Ann&ulla $1" +Basic.MainMenu.Edit.RedoAction="&Ripeti $1" +Basic.MainMenu.Edit.LockPreview="B&locca l'anteprima" +Basic.MainMenu.Edit.Scale="Ridimen&sionamento dell'anteprima" +Basic.MainMenu.Edit.Scale.Window="Scala in base alle dimensioni della finestra" +Basic.MainMenu.Edit.Scale.Canvas="Inquadratura (%1×%2)" +Basic.MainMenu.Edit.Scale.Output="Uscita (%1×%2)" Basic.MainMenu.Edit.Transform="&Trasforma" -Basic.MainMenu.Edit.Transform.EditTransform="&Modifica e trasforma..." +Basic.MainMenu.Edit.Transform.EditTransform="Modifica &e trasforma..." Basic.MainMenu.Edit.Transform.CopyTransform="Copia e trasforma" Basic.MainMenu.Edit.Transform.PasteTransform="Incolla e trasforma" -Basic.MainMenu.Edit.Transform.ResetTransform="&Reset e trasforma" +Basic.MainMenu.Edit.Transform.ResetTransform="&Ripristina e trasforma" Basic.MainMenu.Edit.Transform.Rotate90CW="Ruota di 90 gradi in senso orario" Basic.MainMenu.Edit.Transform.Rotate90CCW="Ruota di 90 gradi in senso antiorario" Basic.MainMenu.Edit.Transform.Rotate180="Ruota di 180 gradi" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Ribalta &orizzontalmente" -Basic.MainMenu.Edit.Transform.FlipVertical="Ribalta &verticalmente" -Basic.MainMenu.Edit.Transform.FitToScreen="&Adatta allo schermo" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Ridimensiona come lo schermo" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Capovolgi orizzontalmente (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Capovolgi &verticalmente" +Basic.MainMenu.Edit.Transform.FitToScreen="Adatta allo schermo (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Allunga per riempire lo &schermo" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centra nello schermo" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centra verticalmente" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centra orizzontalmente" Basic.MainMenu.Edit.Order="&Ordine" Basic.MainMenu.Edit.Order.MoveUp="Sposta s&u" -Basic.MainMenu.Edit.Order.MoveDown="Sposta &giù" -Basic.MainMenu.Edit.Order.MoveToTop="Sposta in &cima" -Basic.MainMenu.Edit.Order.MoveToBottom="Sposta in &fondo" +Basic.MainMenu.Edit.Order.MoveDown="Sposta giù (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Spos&ta in cima" +Basic.MainMenu.Edit.Order.MoveToBottom="Sposta in fondo (&B)" Basic.MainMenu.Edit.AdvAudio="Proprietà audio &avanzate" Basic.MainMenu.View="&Visualizza" -Basic.MainMenu.View.Toolbars="&Barre degli strumenti" -Basic.MainMenu.View.Docks="Docks" -Basic.MainMenu.View.Docks.ResetUI="Reset UI" -Basic.MainMenu.View.Docks.LockUI="Blocca UI" -Basic.MainMenu.View.Toolbars.Listboxes="&Listboxes" -Basic.MainMenu.View.SceneTransitions="&Transizioni di scena" -Basic.MainMenu.View.StatusBar="&Barra di stato" +Basic.MainMenu.View.Toolbars="Barre degli s&trumenti" +Basic.MainMenu.View.Docks="Pannelli" +Basic.MainMenu.View.Docks.ResetUI="Ripristina l'interfaccia" +Basic.MainMenu.View.Docks.LockUI="Blocca l'interfaccia" +Basic.MainMenu.View.Toolbars.Listboxes="Pu&lsanti di navigazione" +Basic.MainMenu.View.SceneTransitions="Transizioni di s&cena" +Basic.MainMenu.View.StatusBar="Barra di &stato" Basic.MainMenu.View.Fullscreen.Interface="Interfaccia a schermo intero" -Basic.MainMenu.SceneCollection="&Collezione scene" +Basic.MainMenu.SceneCollection="Collezione &scene" Basic.MainMenu.Profile="&Profilo" -Basic.MainMenu.Profile.Import="Importa profilo" -Basic.MainMenu.Profile.Export="Esporta profilo" -Basic.MainMenu.SceneCollection.Import="Importa collezione scene" -Basic.MainMenu.SceneCollection.Export="Esporta collezione scene" +Basic.MainMenu.Profile.Import="Importa un profilo" +Basic.MainMenu.Profile.Export="Esporta il profilo" +Basic.MainMenu.SceneCollection.Import="Importa una collezione di scene" +Basic.MainMenu.SceneCollection.Export="Esporta la collezione di scene" Basic.MainMenu.Profile.Exists="Il profilo esiste già" -Basic.MainMenu.SceneCollection.Exists="La collezione di scene già esiste" +Basic.MainMenu.SceneCollection.Exists="La collezione di scene esiste già" -Basic.MainMenu.Tools="&Strumenti" +Basic.MainMenu.Tools="S&trumenti" -Basic.MainMenu.Help="&Aiuto" -Basic.MainMenu.Help.HelpPortal="Portale Aiuto" -Basic.MainMenu.Help.Website="Visita il sito" -Basic.MainMenu.Help.Discord="Join & Discord Server" +Basic.MainMenu.Help="Aiuto (&H)" +Basic.MainMenu.Help.HelpPortal="&Portale di assistenza" +Basic.MainMenu.Help.Website="Visita il sito &web" +Basic.MainMenu.Help.Discord="Unisciti al server di &Discord" Basic.MainMenu.Help.Logs="File di &log" -Basic.MainMenu.Help.Logs.ShowLogs="&Visualizza i file di Log" +Basic.MainMenu.Help.Logs.ShowLogs="Vi&sualizza i file di Log" Basic.MainMenu.Help.Logs.UploadCurrentLog="Carica file di log &corrente" -Basic.MainMenu.Help.Logs.UploadLastLog="Carica u<imo file di log" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vedi attuale file di log" -Basic.MainMenu.Help.CheckForUpdates="Controlla aggiornamenti" -Basic.MainMenu.Help.CrashLogs="Segnalazione c&rash " -Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&sualizza Segnalazione crash" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Carica l'u<imo Crash Report" +Basic.MainMenu.Help.Logs.UploadLastLog="Carica &l'ultimo file di log" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Visualizza il file di log attuale" +Basic.MainMenu.Help.CheckForUpdates="Controlla gli aggiornamenti" +Basic.MainMenu.Help.CrashLogs="&Registro dei crash" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&sualizza i registri dei crash" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Carica &l'ultimo registro di crash" +Basic.MainMenu.Help.About="Riconoscimenti (&A)" Basic.Settings.ProgramRestart="Il programma deve essere riavviato perché questi cambiamenti abbiano effetto." -Basic.Settings.ConfirmTitle="Conferma cambiamenti" +Basic.Settings.ConfirmTitle="Conferma i cambiamenti" Basic.Settings.Confirm="Hai dei cambiamenti non salvati. Vuoi salvarli?" -Basic.Settings.General="Generale" +Basic.Settings.General="Generali" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Lingua" -Basic.Settings.General.EnableAutoUpdates="Controlla aggiornamenti automaticamente all'avvio" -Basic.Settings.General.OpenStatsOnStartup="Apri finestra statistiche all'avvio" -Basic.Settings.General.WarnBeforeStartingStream="Chiedi conferma quando si avvia una trasmissione" -Basic.Settings.General.WarnBeforeStoppingStream="Chiedi conferma quando si termina una diretta" +Basic.Settings.General.EnableAutoUpdates="Controlla automaticamente gli aggiornamenti all'avvio" +Basic.Settings.General.OpenStatsOnStartup="Apri la finestra delle statistiche all'avvio" +Basic.Settings.General.WarnBeforeStartingStream="Mostra una finestra di conferma quando avvii una diretta" +Basic.Settings.General.WarnBeforeStoppingStream="Mostra una finestra di conferma quando vuoi terminare una diretta" Basic.Settings.General.Projectors="Proiettori" -Basic.Settings.General.HideProjectorCursor="Nascondi cursore sopra proiettori" -Basic.Settings.General.ProjectorAlwaysOnTop="Rendono i proiettori sempre in primo piano" -Basic.Settings.General.Snapping="Allineamento snap fonti" -Basic.Settings.General.ScreenSnapping="Snap delle fonti ai bordi dello schermo" -Basic.Settings.General.CenterSnapping="Snap delle fonti al centro della scena, orizzontalmente e verticalmente" -Basic.Settings.General.SourceSnapping="Snap di fonti con altre fonti" -Basic.Settings.General.SnapDistance="Sensibilità Snap" -Basic.Settings.General.RecordWhenStreaming="Registra automaticamente quando si trasmette" -Basic.Settings.General.KeepRecordingWhenStreamStops="Continua a registrare quando la trasmissione si interrompe" -Basic.Settings.General.ReplayBufferWhileStreaming="Avvia automaticamente il buffer di riproduzione durante la trasmissione" -Basic.Settings.General.KeepReplayBufferStreamStops="Mantieni il buffer di riproduzione attiva quando la trasmissione si interrompe" -Basic.Settings.General.SysTray="Vassoio di sistema" -Basic.Settings.General.SysTrayWhenStarted="Minimizza all'area di notifica all'avvio" -Basic.Settings.General.SystemTrayHideMinimize="Minimizza sempre nel vassoio di sistema invece che nella barra delle applicazioni" -Basic.Settings.General.SaveProjectors="Salva i proiettori all'uscita" -Basic.Settings.General.SwitchOnDoubleClick="Transizione alla scena al doppio-click" -Basic.Settings.General.StudioPortraitLayout="Attiva il layout Orizzontale/Verticale" -Basic.Settings.General.Multiview="Visualizzazione Multipla" +Basic.Settings.General.HideProjectorCursor="Nascondi il cursore sopra i proiettori" +Basic.Settings.General.ProjectorAlwaysOnTop="I proiettori devono essere sempre in primo piano?" +Basic.Settings.General.Snapping="Aggancio delle fonti" +Basic.Settings.General.ScreenSnapping="Aggancia le fonti quandi sono vicine ai bordi dello schermo" +Basic.Settings.General.CenterSnapping="Aggancia le fonti quandi sono vicine al centro orizzontale e verticale" +Basic.Settings.General.SourceSnapping="Aggancia le fonti quandi sono vicine ad altre fonti" +Basic.Settings.General.SnapDistance="Sensibilità dell'aggancio" +Basic.Settings.General.RecordWhenStreaming="Registra automaticamente quando sei in diretta" +Basic.Settings.General.KeepRecordingWhenStreamStops="Continua a registrare quando la diretta viene terminata" +Basic.Settings.General.ReplayBufferWhileStreaming="Avvia automaticamente il buffer di replay durante le dirette" +Basic.Settings.General.KeepReplayBufferStreamStops="Mantieni il buffer di replay attivo quando la diretta viene terminata" +Basic.Settings.General.SysTray="Area di notifica" +Basic.Settings.General.SysTrayWhenStarted="Avvia il programma ridotto nell'area di notifica" +Basic.Settings.General.SystemTrayHideMinimize="Riduci sempre il programma nell'area di notifica invece che nella barra delle applicazioni" +Basic.Settings.General.SaveProjectors="Salva i proiettori alla chiusura" +Basic.Settings.General.Preview="Anteprima" +Basic.Settings.General.OverflowHidden="Nascondi l'overflow" +Basic.Settings.General.OverflowAlwaysVisible="L'overflow deve essere sempre visibile" +Basic.Settings.General.OverflowSelectionHidden="Visualizza l'overflow anche quando la fonte è invisibile" +Basic.Settings.General.SwitchOnDoubleClick="Esegui la transizione quando fai doppio clic sulla scena" +Basic.Settings.General.StudioPortraitLayout="Attiva il layout verticale" +Basic.Settings.General.TogglePreviewProgramLabels="Mostra le etichette di anteprima/programma" +Basic.Settings.General.Multiview="Visualizzazione multipla" Basic.Settings.General.Multiview.MouseSwitch="Clicca per passare da una scena all'altra" -Basic.Settings.General.Multiview.DrawSourceNames="Visualizza il nome della scena" -Basic.Settings.General.Multiview.DrawSafeAreas="Evidenziare aree sicure (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Layout a viste multiple" -Basic.Settings.General.MultiviewLayout.Horizontal.Top="Orizzontale, In alto (8 scene)" -Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Orizzontale, In basso (8 scene)" -Basic.Settings.General.MultiviewLayout.Vertical.Left="Verticale, A sinistra (8 scene)" -Basic.Settings.General.MultiviewLayout.Vertical.Right="Verticale, A destra (8 scene)" -Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Orizzontale, In alto (24 scene)" +Basic.Settings.General.Multiview.DrawSourceNames="Visualizza i nomi delle scene" +Basic.Settings.General.Multiview.DrawSafeAreas="Evidenzia le aree sicure (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Disposizione della visualizzazione multipla" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Orizzontale, in alto (8 scene)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Orizzontale, in basso (8 scene)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Verticale, a sinistra (8 scene)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Verticale, a destra (8 scene)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Orizzontale, in alto (24 scene)" -Basic.Settings.Stream="Trasmissione" -Basic.Settings.Stream.StreamType="Tipo di stream" +Basic.Settings.Stream="Dirette" +Basic.Settings.Stream.StreamType="Tipo di diretta" +Basic.Settings.Stream.Custom.UseAuthentication="Utilizza l'autenticazione" +Basic.Settings.Stream.Custom.Username="Nome utente" +Basic.Settings.Stream.Custom.Password="Password" +Basic.Settings.Stream.BandwidthTestMode="Attiva la modalità test della larghezza di banda" -Basic.Settings.Output="Output" +Basic.Settings.Output="Uscita" Basic.Settings.Output.Format="Formato di registrazione" Basic.Settings.Output.Encoder="Codifica" -Basic.Settings.Output.SelectDirectory="Seleziona cartella di registrazione" -Basic.Settings.Output.SelectFile="Seleziona file di registrazione" -Basic.Settings.Output.EnforceBitrate="Forza limiti bitrate del servizio di trasmissione" -Basic.Settings.Output.Mode="Modalità di output" +Basic.Settings.Output.SelectDirectory="Seleziona la cartella di registrazione" +Basic.Settings.Output.SelectFile="Seleziona il file di registrazione" +Basic.Settings.Output.EnforceBitrate="Non superare i limiti di velocità in bit del servizio di dirette" +Basic.Settings.Output.Mode="Modalità di uscita" Basic.Settings.Output.Mode.Simple="Semplice" Basic.Settings.Output.Mode.Adv="Avanzate" Basic.Settings.Output.Mode.FFmpeg="Uscita FFmpeg" -Basic.Settings.Output.UseReplayBuffer="Abilita buffer di replay" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di replay (secondi)" -Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria massima (megabyte)" +Basic.Settings.Output.UseReplayBuffer="Attiva il buffer di replay" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo massimo di replay (in secondi)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memoria massima (in megabyte)" Basic.Settings.Output.ReplayBuffer.Estimate="Uso della memoria stimato: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Impossibile stimare la memoria utilizzata. Imposta un limite massimo di memoria." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: assicurati di aver impostato una scorciatoia per il buffer di replay nella sezione delle scorciatoie)" -Basic.Settings.Output.ReplayBuffer.Prefix="Prefisso del nome file per i buffer di replay" +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(nota: assicurati di aver impostato una scorciatoia per il buffer di replay nella sezione delle scorciatoie)" +Basic.Settings.Output.ReplayBuffer.Prefix="Prefisso del nome dei file del buffer di replay" Basic.Settings.Output.ReplayBuffer.Suffix="Suffisso" -Basic.Settings.Output.Simple.SavePath="Percorso registrazione" +Basic.Settings.Output.Simple.SavePath="Percorso di registrazione" Basic.Settings.Output.Simple.RecordingQuality="Qualità della registrazione" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Stesso della trasmissione" -Basic.Settings.Output.Simple.RecordingQuality.Small="Alta qualità, medie dimensioni del file" -Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualità Indistinguibuile, larghe dimensioni del file" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Senza perdità di qualità, dimensioni del file enormi" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Avviso: Il bitrate video della trasmissione verrà impostato su %1, che è il limite superiore per il servizio di trasmissione corrente. Se sei sicuro di che voler andare di sopra %1, abilita le opzioni avanzate del codificatore e deseleziona \"Imponi limiti bitrate del servizio di trasmissione\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Avviso: Il bitrate audio in streaming verrà impostato su %1, che è il limite superiore per il servizio di streaming corrente. Se sei sicuro di che voler andare di sopra %1, abilita le opzioni avanzate del encorder e deseleziona \"Imponi streaming limiti di servizio bitrate\"." -Basic.Settings.Output.Simple.Warn.Encoder="Attenzione: registrare con un codificatore software a una qualità diversa dalla trasmissione richiederà un utilizzo aggiuntivo della CPU se trasmetti e registri allo stesso tempo." -Basic.Settings.Output.Simple.Warn.Lossless="Attenzione: La qualità Lossless genera file estremamente grandi! La Lossless puo occupare 7 Gigabytes di spazio per minuto ad alte risoluzioni e framerate. La lossless non è consigliata per lunghe registrazione a meno che tu non abbia molto spazio disponibile sul disco rigido." +Basic.Settings.Output.Simple.RecordingQuality.Stream="La stessa della diretta" +Basic.Settings.Output.Simple.RecordingQuality.Small="Alta qualità, dimensioni dei file medie" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualità indistinguibile, dimensioni dei file elevate" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Senza perdita di qualità (lossless), dimensioni dei file enormi" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Attenzione: la velocità in bit video della diretta verrà impostata a %1, che è il limite più alto per il servizio di dirette attuale. Se sei sicuro di voler superare il valore %1, attiva le impostazioni avanzate della codifica e deseleziona «Non superare i limiti di velocità in bit del servizio di dirette»." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Attenzione: la velocità in bit audio della diretta verrà impostata a %1, che è il limite più alto per il servizio di dirette attuale. Se sei sicuro di voler superare il valore %1, attiva le impostazioni avanzate della codifica e deseleziona «Non superare i limiti di velocità in bit del servizio di dirette»." +Basic.Settings.Output.Simple.Warn.Encoder="Attenzione: registrare con una codifica software a una qualità diversa dalla diretta richiederà un utilizzo aggiuntivo della CPU se esegui dirette e registri allo stesso tempo." +Basic.Settings.Output.Simple.Warn.Lossless="Attenzione: la qualità lossless genera file estremamente grandi! Può occupare fino a 7 gigabyte di spazio al minuto con alte risoluzioni e framerate. Non è consigliata per lunghe registrazioni a meno che tu non abbia molto spazio disponibile sul disco rigido." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sei sicuro di volere utilizzare la qualità lossless?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Avviso sulla qualità lossless!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Attenzione: non è possibile usare più codificatori QSV quando si è in diretta e si registra allo stesso tempo. Se vuoi andare in diretta e registrare allo stesso tempo, cambia l'encoder per la registrazione o l'encoder per la diretta." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264 Preset con basso utilizzo della CPU, aumenta le dimensioni del file)" -Basic.Settings.Output.VideoBitrate="Bitrate video" -Basic.Settings.Output.AudioBitrate="Bitrate Audio" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (x264, preset con basso utilizzo della CPU, aumenta le dimensioni dei file)" +Basic.Settings.Output.VideoBitrate="Velocità in bit video" +Basic.Settings.Output.AudioBitrate="Velocità in bit audio" Basic.Settings.Output.Reconnect="Riconnessione automatica" -Basic.Settings.Output.RetryDelay="Ritardo dei tentativi (secondi)" +Basic.Settings.Output.RetryDelay="Ritardo dei tentativi (in secondi)" Basic.Settings.Output.MaxRetries="Tentativi massimi" -Basic.Settings.Output.Advanced="Abilita le impostazioni avanzate di codifica" -Basic.Settings.Output.EncoderPreset="Codificatore Preset (superiore = meno CPU)" -Basic.Settings.Output.CustomEncoderSettings="Impostazioni codificatore personalizzato" -Basic.Settings.Output.CustomMuxerSettings="Impostazioni Muxer personalizzate" -Basic.Settings.Output.NoSpaceFileName="Genera il nome del file senza spazi" +Basic.Settings.Output.Advanced="Attiva le impostazioni avanzate di codifica" +Basic.Settings.Output.EncoderPreset="Preset della codifica" +Basic.Settings.Output.CustomEncoderSettings="Parametri della codifica personalizzati" +Basic.Settings.Output.CustomMuxerSettings="Parametri del muxer personalizzati" +Basic.Settings.Output.NoSpaceFileName="Genera il nome dei file senza spazi" -Basic.Settings.Output.Adv.Rescale="Riscala uscita" -Basic.Settings.Output.Adv.AudioTrack="Traccia Audio" -Basic.Settings.Output.Adv.Streaming="Trasmissione" -Basic.Settings.Output.Adv.ApplyServiceSettings="Applica le impostazioni di codifica servizio streaming" +Basic.Settings.Output.Adv.Rescale="Riscala l'uscita" +Basic.Settings.Output.Adv.AudioTrack="Traccia audio" +Basic.Settings.Output.Adv.Streaming="Dirette" +Basic.Settings.Output.Adv.ApplyServiceSettings="Imponi le impostazioni di codifica del servizio delle dirette" Basic.Settings.Output.Adv.Audio.Track1="Traccia 1" Basic.Settings.Output.Adv.Audio.Track2="Traccia 2" Basic.Settings.Output.Adv.Audio.Track3="Traccia 3" @@ -588,84 +642,88 @@ Basic.Settings.Output.Adv.Audio.Track4="Traccia 4" Basic.Settings.Output.Adv.Audio.Track5="Traccia 5" Basic.Settings.Output.Adv.Audio.Track6="Traccia 6" -Basic.Settings.Output.Adv.Recording="Registrazione" +Basic.Settings.Output.Adv.Recording="Registrazioni" Basic.Settings.Output.Adv.Recording.Type="Tipo" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Output personalizzato (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Utilizzare il codificatore del flusso)" -Basic.Settings.Output.Adv.Recording.Filename="Formattazione nome del file" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Uscita personalizzata (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(utilizza la codifica delle dirette)" +Basic.Settings.Output.Adv.Recording.Filename="Formattazione del nome dei file" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Sovrascrivi il file se già esistente" -Basic.Settings.Output.Adv.FFmpeg.Type="Tipo di Output FFmpeg" -Basic.Settings.Output.Adv.FFmpeg.Type.URL="Output in URL" -Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Output su file" -Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Comuni formati di registrazione" +Basic.Settings.Output.Adv.FFmpeg.Type="Tipo di uscita FFmpeg" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="Uscita verso un URL" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Uscita verso un file" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formati di registrazione comuni" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Tutti i file" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Percorso del file o URL" -Basic.Settings.Output.Adv.FFmpeg.Format="Formato Contenitore" +Basic.Settings.Output.Adv.FFmpeg.Format="Formato del contenitore" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Formato predefinito" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descrizione Formato Contenitore" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Codec Audio/Video indovinato dal percorso del file o URL" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codificatore predefinito" -Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Encoder Disabilitato" -Basic.Settings.Output.Adv.FFmpeg.VEncoder="Encoder Video" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Impostazioni codifica video (se presente)" -Basic.Settings.Output.Adv.FFmpeg.AEncoder="Encoder Audio" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Impostazioni codifica audio (se presente)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Impostazioni Muxer (se possibile)" -Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervallo fotogrammi chiave (fotogrammi)" -Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Visualizza tutti i codec (anche se potenzialmente incompatibili)" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descrizione del formato del contenitore" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Il codec audio/video è stato intuito dal percorso del file o dall'URL" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codifica predefinita" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Codifica disattivata" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Codifica video" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Parametri di codifica video (se presenti)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codifica audio" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Parametri di codifica audio (se presenti)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Parametri del muxer (se presenti)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervallo dei fotogrammi chiave (in fotogrammi)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Mostra tutti i codec (anche se potenzialmente incompatibili)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY Anno, quattro cifre\n%YY Anno, ultime due cifre (00-99)\n%MM Mese come numero decimale (01-12)\n%DD Giorno del mese, zero-padded (01-31)\n%hh Ore in formato 24 ore (00-23)\n%mm Minuto (00-59)\n%ss Secondi (00-61)\n%% Un % segno\n%a Giorno della settimana abbreviato\n%A Un nome del giorno della settimana intero\n%b Nome del mese abbreviato\n%B Nome del mese intero\n%d Giorno del mese, zero-padded (01-31)\n%H Ore in formato 24 ore (00-23)\n%I Ore in formato 12 ore (01-12)\n%m Mese come numero decimale (01-12)\n%M Minuto (00-59)\n%p Designazione AM o PM\n%S Secondi (00-61)\n%y Anno, ultime due lettere (00-99)\n%Y Anno\n%z ISO 8601 offset da UTC o fuso orario\n Nome o abbreviazione\n%Z Nome o abbreviazione del fuso orario\n" +FilenameFormatting.TT="%CCYY Anno, quattro cifre\n%YY Anno, ultime due cifre (00-99)\n%MM Mese come numero decimale (01-12)\n%DD Giorno del mese, due cifre (01-31)\n%hh Ora in formato 24h (00-23)\n%mm Minuti (00-59)\n%ss Secondi (00-61)\n%% Un simbolo %\n%a Giorno della settimana abbreviato\n%A Giorno della settimana completo\n%b Nome del mese abbreviato\n%B Nome del mese completo\n%d Giorno del mese, due cifre (01-31)\n%H Ora in formato 24h (00-23)\n%I Ora in formato 12h (01-12)\n%m Mese come numero decimale (01-12)\n%M Minuti (00-59)\n%p Designazione AM o PM\n%S Secondi (00-61)\n%y Anno, ultime due cifre (00-99)\n%Y Anno\n%z Offset del fuso orario da UTC secondo ISO 860\n%Z Nome o abbreviazione del fuso orario\n" Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Adattatore video" -Basic.Settings.Video.BaseResolution="Risoluzione base (Canvas)" -Basic.Settings.Video.ScaledResolution="Risoluzione output (scalata)" -Basic.Settings.Video.DownscaleFilter="Filtro di rimpicciolimento" -Basic.Settings.Video.DisableAeroWindows="Disabilita Aero (solo Windows)" +Basic.Settings.Video.BaseResolution="Risoluzione di base (inquadratura)" +Basic.Settings.Video.ScaledResolution="Risoluzione effettiva di uscita (scalata)" +Basic.Settings.Video.DownscaleFilter="Filtro di ridimensionamento della scalatura" +Basic.Settings.Video.DisableAeroWindows="Disattiva Aero (solo Windows)" Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valori FPS comuni" Basic.Settings.Video.FPSInteger="Valore FPS con numero intero" Basic.Settings.Video.FPSFraction="Valore FPS con numero frazionario" Basic.Settings.Video.Numerator="Numeratore" Basic.Settings.Video.Denominator="Denominatore" -Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Valore di risoluzione invalido. Deve essere [larghezza]x[altezza] (es. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="L'output video è attualmente attivo. Spegni qualunque output per cambiare le impostazioni." -Basic.Settings.Video.DisableAero="Disabilita Aero" +Basic.Settings.Video.Renderer="Modalità di rendering" +Basic.Settings.Video.InvalidResolution="Valore della risoluzione non valido. Deve essere [larghezza]x[altezza] (ad esempio 1920x1080)" +Basic.Settings.Video.CurrentlyActive="L'uscita video è attualmente attiva. Interrompi qualunque uscita video per poter cambiare le impostazioni." +Basic.Settings.Video.DisableAero="Disattiva Aero" -Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineare (più veloce, ma sfocata se ridimensionamenta)" -Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubica (scalatura affilata, 16 campioni)" -Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (scalatura affilata, 32 campioni)" +Basic.Settings.Video.DownscaleFilter.Bilinear="Bilineare (il più veloce, ma sfocato se ridimensionato)" +Basic.Settings.Video.DownscaleFilter.Bicubic="Bicubica (scalatura accentuata, 16 campioni)" +Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (scalatura accentuata, 32 campioni)" Basic.Settings.Audio="Audio" -Basic.Settings.Audio.SampleRate="Ratio di campionamento" +Basic.Settings.Audio.SampleRate="Frequenza di campionamento" Basic.Settings.Audio.Channels="Canali" -Basic.Settings.Audio.MeterDecayRate="Tasso di decadimento audio" +Basic.Settings.Audio.Meters="Metrica" +Basic.Settings.Audio.MeterDecayRate="Tasso di decadimento" Basic.Settings.Audio.MeterDecayRate.Fast="Veloce" -Basic.Settings.Audio.MeterDecayRate.Medium="Medio (Tipo 1 PPM)" -Basic.Settings.Audio.MeterDecayRate.Slow="Lento (Tipo 2 PPM)" -Basic.Settings.Audio.PeakMeterType="Modalità Peak Meter" -Basic.Settings.Audio.PeakMeterType.SamplePeak="Sample Peak" -Basic.Settings.Audio.PeakMeterType.TruePeak="True Peak (alto utilizzo della CPU)" -Basic.Settings.Audio.MultiChannelWarning.Enabled="ATTENZIONE: L'audio Surround è attivo." -Basic.Settings.Audio.MultichannelWarning="Per lo streaming, accertati che il servizio di streaming supporti sia integrazione che riproduzione di suono surround. Twitch, Facebook 360 Live, Mixer RTMP e Smashcast sono esempi di servizi in cui il suono surround è completamente supportato. Anche se sia Facebook Live che YouTube Live implementano il suono surround, Facebook Live lo converte in stereo, mentre YouTube Live ne riproduce solo due canali.\n\nI filtri di OBS Studio sono compatibili con il suono surround, anche se il supporto per il plugin VST non è garantito." -Basic.Settings.Audio.MultichannelWarning.Title="Abilitare l'audio surround?" +Basic.Settings.Audio.MeterDecayRate.Medium="Medio (Tipo I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Lento (Tipo II PPM)" +Basic.Settings.Audio.PeakMeterType="Tipo di misuratore di picco" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Picco a campionamento" +Basic.Settings.Audio.PeakMeterType.TruePeak="Picco esatto (alto utilizzo della CPU)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="ATTENZIONE: L'audio surround è attivato." +Basic.Settings.Audio.MultichannelWarning="Se stai effettuando le modifiche per le dirette, controlla che il servizio di dirette offra l'integrazione e la riproduzione di audio surround. Twitch, Facebook 360 Live, Mixer RTMP e Smashcast sono esempi di servizi che offrono l'audio surround. Le dirette su Facebook e YouTube accettano l'audio surround, ma Facebook lo converte in stereo e YouTube riproduce solo due canali.\n\nI filtri audio di OBS sono compatibili con l'audio surround, ma il supporto al plugin VST non è garantito." +Basic.Settings.Audio.MultichannelWarning.Title="Vuoi attivare l'audio surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sei sicuro di voler attivare l'audio surround?" -Basic.Settings.Audio.DesktopDevice="Dispositivo audio desktop" -Basic.Settings.Audio.DesktopDevice2="Dispositivo audio desktop 2" -Basic.Settings.Audio.AuxDevice="Dispositivo audio mic/ausiliario" -Basic.Settings.Audio.AuxDevice2="Dispositivo audio mic/ausiliario 2" -Basic.Settings.Audio.AuxDevice3="Dispositivo audio mic/ausiliario 3" -Basic.Settings.Audio.EnablePushToMute="Abilita Push-to-mute" -Basic.Settings.Audio.PushToMuteDelay="Ritardo Push-to-mute" -Basic.Settings.Audio.EnablePushToTalk="Abilita Push-to-talk" -Basic.Settings.Audio.PushToTalkDelay="Ritardo Push-to-talk" -Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo non collegato o non disponibile]" +Basic.Settings.Audio.Devices="Dispositivi" +Basic.Settings.Audio.DesktopDevice="Audio desktop" +Basic.Settings.Audio.DesktopDevice2="Audio desktop 2" +Basic.Settings.Audio.AuxDevice="Audio mic/ausiliario" +Basic.Settings.Audio.AuxDevice2="Audio mic/ausiliario 2" +Basic.Settings.Audio.AuxDevice3="Audio mic/ausiliario 3" +Basic.Settings.Audio.AuxDevice4="Audio mic/ausiliario 4" +Basic.Settings.Audio.EnablePushToMute="Attiva il push-to-mute" +Basic.Settings.Audio.PushToMuteDelay="Ritardo del push-to-mute" +Basic.Settings.Audio.EnablePushToTalk="Attiva il push-to-talk" +Basic.Settings.Audio.PushToTalkDelay="Ritardo del push-to-talk" +Basic.Settings.Audio.UnknownAudioDevice="[il dispositivo non è collegato o non è disponibile]" +Basic.Settings.Audio.Disabled="Disattivato" Basic.Settings.Advanced="Avanzate" Basic.Settings.Advanced.General.ProcessPriority="Priorità del processo" @@ -674,100 +732,124 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Superiore al normal Basic.Settings.Advanced.General.ProcessPriority.Normal="Normale" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Inferiore al normale" Basic.Settings.Advanced.General.ProcessPriority.Idle="Bassa" -Basic.Settings.Advanced.FormatWarning="Attenzione: I formati colore diversi da NV12 sono principalmente pensati per la registrazione, e non sono consigliati durante le dirette. Lo streaming può avere un utilizzo maggiore delle CPU a causa della conversione del formato del colore." +Basic.Settings.Advanced.FormatWarning="Attenzione: i formati colore diversi da NV12 sono principalmente pensati per la registrazione, e non sono consigliati per le dirette. Le dirette richiedono un utilizzo maggiore delle CPU a causa della conversione del formato del colore." Basic.Settings.Advanced.Audio.BufferingTime="Tempo di buffer audio" Basic.Settings.Advanced.Video.ColorFormat="Formato colore" -Basic.Settings.Advanced.Video.ColorSpace="Spazio colore YUV" -Basic.Settings.Advanced.Video.ColorRange="Gamma di colore YUV" +Basic.Settings.Advanced.Video.ColorSpace="Spazio colore" +Basic.Settings.Advanced.Video.ColorRange="Gamma di colori" Basic.Settings.Advanced.Video.ColorRange.Partial="Parziale" Basic.Settings.Advanced.Video.ColorRange.Full="Intero" -Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo monitor audio" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo di monitoraggio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predefinito" -Basic.Settings.Advanced.Audio.DisableAudioDucking="Disabilita ducking audio di Windows" -Basic.Settings.Advanced.StreamDelay="Ritardo diretta" -Basic.Settings.Advanced.StreamDelay.Duration="Durata (secondi)" -Basic.Settings.Advanced.StreamDelay.Preserve="Preserva il punto di taglio (aumenta ritardo) durante la riconnessione" -Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizzo di memoria stimato: %1 MB" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Disattiva la riduzione del volume di Windows" +Basic.Settings.Advanced.StreamDelay="Ritardo delle dirette" +Basic.Settings.Advanced.StreamDelay.Duration="Durata (in secondi)" +Basic.Settings.Advanced.StreamDelay.Preserve="Mantieni il punto di taglio (aumenta il ritardo) durante la riconnessione" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizzo della memoria stimato: %1 MB" Basic.Settings.Advanced.Network="Rete" -Basic.Settings.Advanced.Network.BindToIP="Associa a IP" +Basic.Settings.Advanced.Network.BindToIP="Associa all'indirizzo IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Attiva il nuovo codice di rete" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modalità a bassa latenza" -Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Disabilitare i tasti di scelta rapida quando la finestra principale è a fuoco" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Disattiva le scorciatoie quando la finestra principale è in primo piano" +Basic.Settings.Advanced.AutoRemux="Converti automaticamente in MP4" +Basic.Settings.Advanced.AutoRemux.MP4="(registra in MKV)" Basic.AdvAudio="Proprietà audio avanzate" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Volume="Volume (%)" -Basic.AdvAudio.Mono="Downmix to Mono" -Basic.AdvAudio.Panning="Panning" -Basic.AdvAudio.SyncOffset="Sync Offset (ms)" -Basic.AdvAudio.Monitoring="Monitor audio" -Basic.AdvAudio.Monitoring.None="Monitor spento" -Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitor (uscita silenziata)" -Basic.AdvAudio.Monitoring.Both="Monitor e uscita" +Basic.AdvAudio.Volume="Volume" +Basic.AdvAudio.Mono="Trasforma in mono" +Basic.AdvAudio.Balance="Bilanciamento" +Basic.AdvAudio.SyncOffset="Ritardo per la sincronizzazione (ms)" +Basic.AdvAudio.Monitoring="Monitoraggio audio" +Basic.AdvAudio.Monitoring.None="Disattivato" +Basic.AdvAudio.Monitoring.MonitorOnly="Solo monitoraggio (uscita audio nel file disattivata)" +Basic.AdvAudio.Monitoring.Both="Monitora l'audio e invia all'uscita" Basic.AdvAudio.AudioTracks="Tracce" Basic.Settings.Hotkeys="Scorciatoie" -Basic.Settings.Hotkeys.Pair="La combinazione di chiavi condivisa con '%1' funziona da commutatore" +Basic.Settings.Hotkeys.Pair="Consigliamo di utilizzare la stessa combinazione di tasti insieme a «%1»" +Basic.Settings.Hotkeys.Filter="Filtro" -Basic.Hotkeys.SelectScene="Passa alla scena" +Basic.Hotkeys.SelectScene="Scorri tra le scene" -Basic.SystemTray.Show="Visualizza la finestra" +Basic.SystemTray.Show="Mostra la finestra" Basic.SystemTray.Hide="Nascondi la finestra" -Basic.SystemTray.Message.Reconnecting="Disconnesso. Riconnessione in corso..." +Basic.SystemTray.Message.Reconnecting="Disconnesso. Riconnessione in corso..." Hotkeys.Insert="Ins" Hotkeys.Delete="Canc" -Hotkeys.Home="Home" +Hotkeys.Home="Inizio" Hotkeys.End="Fine" -Hotkeys.PageUp="Pagina sù" +Hotkeys.PageUp="Pagina su" Hotkeys.PageDown="Pagina giù" -Hotkeys.NumLock="Bloc Num" -Hotkeys.ScrollLock="Blocco Scorr" -Hotkeys.CapsLock="Bloc Maiusc" -Hotkeys.Backspace="Backspace" +Hotkeys.NumLock="Bloc num" +Hotkeys.ScrollLock="Bloc scorr" +Hotkeys.CapsLock="Bloc maiusc" +Hotkeys.Backspace="Indietro" Hotkeys.Tab="Tab" Hotkeys.Print="Stampa" Hotkeys.Pause="Pausa" Hotkeys.Left="Sinistra" Hotkeys.Right="Destra" -Hotkeys.Up="Sù" +Hotkeys.Up="Su" Hotkeys.Down="Giù" Hotkeys.Windows="Windows" Hotkeys.Super="Super" -Hotkeys.Menu="Menu" +Hotkeys.Menu="Menù" Hotkeys.Space="Barra spaziatrice" -Hotkeys.NumpadNum="TastNum %1" -Hotkeys.NumpadMultiply="Moltiplicatore TastNum" -Hotkeys.NumpadDivide="TastNum Diviso" -Hotkeys.NumpadAdd="TastNum Più" -Hotkeys.NumpadSubtract="TastNum Meno" -Hotkeys.NumpadDecimal="Decimale TastNum" -Hotkeys.AppleKeypadNum="%1 (Tastierino)" -Hotkeys.AppleKeypadMultiply="* (Tastierino)" -Hotkeys.AppleKeypadDivide="/ (Tastierino)" -Hotkeys.AppleKeypadAdd="+ (Tastierino)" -Hotkeys.AppleKeypadSubtract="- (Tastierino)" -Hotkeys.AppleKeypadDecimal=". (Tastierino)" -Hotkeys.AppleKeypadEqual="= (Tastierino)" +Hotkeys.NumpadNum="%1 (tn)" +Hotkeys.NumpadMultiply="× (tn)" +Hotkeys.NumpadDivide="÷ (tn)" +Hotkeys.NumpadAdd="+ (tn)" +Hotkeys.NumpadSubtract="- (tn)" +Hotkeys.NumpadDecimal=", (tn)" +Hotkeys.AppleKeypadNum="%1 (tn)" +Hotkeys.AppleKeypadMultiply="× (tn)" +Hotkeys.AppleKeypadDivide="÷ (tn)" +Hotkeys.AppleKeypadAdd="+ (tn)" +Hotkeys.AppleKeypadSubtract="- (tn)" +Hotkeys.AppleKeypadDecimal=", (tn)" +Hotkeys.AppleKeypadEqual="= (tn)" Hotkeys.MouseButton="Mouse %1" +Hotkeys.Escape="Esc" Mute="Silenzia" Unmute="Riattiva" Push-to-mute="Push-to-mute" Push-to-talk="Push-to-talk" -SceneItemShow="Mostra '%1'" -SceneItemHide="Nascondi '%1'" +SceneItemShow="Mostra «%1»" +SceneItemHide="Nascondi «%1»" OutputWarnings.NoTracksSelected="Devi selezionare almeno una traccia" -OutputWarnings.MultiTrackRecording="Attenzione: Alcuni formati (come FLV) non supportano più di una traccia per registrazione" -OutputWarnings.MP4Recording="Avviso: le registrazioni salvate in MP4 non saranno recuperabili se il file non può essere finalizzato (ad es. a seguito di BSOD, perdite di potenza, ecc.). Se desideri registrare più tracce audio prendi in considerazione l'utilizzo di MKV e esegui il remux della registrazione in mp4 dopo che è finito (File-> Remux registrazioni)" +OutputWarnings.MultiTrackRecording="Attenzione: alcuni formati (come FLV) supportano solo una traccia" +OutputWarnings.MP4Recording="Attenzione: le registrazioni salvate in MP4/MOV non saranno recuperabili se il file non può essere completato (ad es. a seguito di un BSOD, perdite di corrente, ecc.). Se desideri registrare più tracce audio, consigliamo l'utilizzo di MKV e, una volta terminato, eseguire la conversione della registrazione in MP4/MOV (File → Converti le registrazioni)" -FinalScene.Title="Elimina scena" +FinalScene.Title="Eliminazione della scena" FinalScene.Text="Deve esserci almeno una scena." -NoSources.Title="Nessuna sorgente" +NoSources.Title="Nessuna fonte" +NoSources.Text="Sembra che tu non abbia ancora aggiunto alcuna fonte video, quindi vedrai solo una schermata nera. Sei sicuro di voler proseguire?" +NoSources.Text.AddSource="Puoi aggiungere fonti cliccando l'icona + sotto il pannello delle fonti nella finestra principale in qualsiasi momento." +NoSources.Label="Non hai nessuna fonte.\nClicca il pulsante + qui sotto,\no clicca col tasto destro per aggiungerne una." +ChangeBG="Imposta un colore" +CustomColor="Colore personalizzato" +BrowserSource.EnableHardwareAcceleration="Attiva l'accelerazione hardware per la fonte browser" + +About="Riconoscimenti" +About.Info="OBS Studio è un software gratuito e open source per la registrazione di video e dirette streaming." +About.Donate="Effettua una donazione" +About.GetInvolved="Partecipa allo sviluppo" +About.Authors="Autori" +About.License="Licenza" +About.Contribute="Sostieni il progetto OBS" + +ResizeOutputSizeOfSource="Ridimensionamento dell'uscita (alle dimensioni della fonte)" +ResizeOutputSizeOfSource.Text="La risoluzione di base e quella effettiva verranno ridimensionate in base alla dimensione della fonte attuale." +ResizeOutputSizeOfSource.Continue="Vuoi continuare?" + +PreviewTransition="Anteprima transizione" diff --git a/UI/data/locale/ja-JP.ini b/UI/data/locale/ja-JP.ini index 6dc4ddc..adf76fb 100644 --- a/UI/data/locale/ja-JP.ini +++ b/UI/data/locale/ja-JP.ini @@ -49,7 +49,7 @@ Duplicate="複製" Enable="有効にする" DisableOSXVSync="OSX の V-Sync を無効にする" ResetOSXVSyncOnExit="終了時に OSX の V-Sync をリセットする" -HighResourceUsage="エンコードが高負荷です! 映像設定を下げるかより高速のエンコードプリセットの使用を検討してください。" +HighResourceUsage="エンコードが高負荷です! 映像設定を下げるかより高速のエンコードプリセットの使用を検討してください。" Transition="トランジション" QuickTransitions="クイックトランジション" Left="左" @@ -61,7 +61,7 @@ Hours="時間" Minutes="分" Seconds="秒" Deprecated="非推奨" -ReplayBuffer="リプレイバッファー" +ReplayBuffer="リプレイバッファ" Import="インポート" Export="エクスポート" Copy="コピー" @@ -80,14 +80,40 @@ StudioMode.Program="番組" ShowInMultiview="マルチビューで表示" VerticalLayout="垂直レイアウト" Group="グループ化" +DoNotShowAgain="次回から表示しない" +Default="(既定)" +Calculating="計算中..." AlreadyRunning.Title="OBSは既に実行中です" -AlreadyRunning.Text="OBSは既に実行されています! この操作を行うつもりがない限り、新しいインスタンスを実行する前に既存のOBSインスタンスを終了してください。OBSがシステムトレイに最小化されるように設定されている場合は、まだ実行中であるかどうかを確認してください。" +AlreadyRunning.Text="OBSは既に実行されています! この操作を行うつもりがない限り、新しいインスタンスを実行する前に既存のOBSインスタンスを終了してください。OBSがシステムトレイに最小化されるように設定されている場合は、まだ実行中であるかどうかを確認してください。" AlreadyRunning.LaunchAnyway="とにかく起動する" +DockCloseWarning.Title="ドッキング可能ウィンドウを閉じる" +DockCloseWarning.Text="ドッキング可能なウィンドウを閉じました。もう一度表示したい場合は、メニューバーの表示 → ドックメニューを使用してください。" + +Auth.Authing.Title="認証中..." +Auth.Authing.Text="%1で認証中、お待ちください..." +Auth.AuthFailure.Title="認証失敗" +Auth.AuthFailure.Text="%1の認証に失敗しました:\n\n%2: %3" +Auth.InvalidScope.Title="認証が必要" +Auth.InvalidScope.Text="%1の認証要件が変更されました。 いくつかの機能は利用できないかもしれません。" +Auth.LoadingChannel.Title="チャンネル情報を読み込み中..." +Auth.LoadingChannel.Text="%1のチャンネル情報を読み込み中、しばらくお待ちください..." +Auth.ChannelFailure.Title="チャンネルの読み込みに失敗" +Auth.ChannelFailure.Text="%1のチャネル情報の読み込みに失敗しました\n\n%2: %3" +Auth.Chat="チャット" +Auth.StreamInfo="配信情報" +TwitchAuth.Stats="Twitch統計" +TwitchAuth.Feed="Twitch アクティビティフィード" +TwitchAuth.TwoFactorFail.Title="ストリームキーを照会できませんでした" +TwitchAuth.TwoFactorFail.Text="OBSはあなたのTwitchアカウントに接続できませんでした。 これは配信に必要なので、Twitchセキュリティ設定で2要素認証が設定されていることを確認してください。" + Copy.Filters="フィルタをコピーする" Paste.Filters="フィルタを貼り付ける" +BrowserPanelInit.Title="ブラウザを初期化中..." +BrowserPanelInit.Text="ブラウザを初期化中、しばらくお待ちください..." + BandwidthTest.Region="地域" BandwidthTest.Region.US="米国" BandwidthTest.Region.EU="ヨーロッパ" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="アジア" BandwidthTest.Region.Other="その他" Basic.FirstStartup.RunWizard="自動構成ウィザードを実行しますか? メインウィンドウの設定ボタンをクリックして手動で設定を構成することもできます。" -Basic.FirstStartup.RunWizard.BetaWarning="(注意: 自動構成ウィザードは現在ベータ版)" Basic.FirstStartup.RunWizard.NoClicked="あなたの気が変わったら、ツールメニューからいつでも自動構成ウィザードを実行できます。" Basic.AutoConfig="自動構成ウィザード" -Basic.AutoConfig.Beta="自動構成ウィザード (ベータ版)" Basic.AutoConfig.ApplySettings="設定を適用" Basic.AutoConfig.StartPage="使用情報" Basic.AutoConfig.StartPage.SubTitle="プログラムの使用目的を指定する" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60または30のいずれか、高 Basic.AutoConfig.VideoPage.CanvasExplanation="注: キャンバス (基本) 解像度は配信や録画の解像度と必ずしも同じではありません。 実際の配信/録画の解像度はリソース使用量やビットレート要求を減らすためにキャンバス解像度から縮小されたものを使用できます。" Basic.AutoConfig.StreamPage="配信情報" Basic.AutoConfig.StreamPage.SubTitle="配信情報を入力してください" +Basic.AutoConfig.StreamPage.ConnectAccount="アカウント接続 (オプション)" +Basic.AutoConfig.StreamPage.DisconnectAccount="アカウントを切断" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="アカウントを切断しますか?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="この変更はすぐに適用されます。 アカウントを切断してもよろしいですか?" +Basic.AutoConfig.StreamPage.UseStreamKey="ストリームキーを使用" Basic.AutoConfig.StreamPage.Service="サービス" Basic.AutoConfig.StreamPage.Service.ShowAll="すべて表示..." +Basic.AutoConfig.StreamPage.Service.Custom="カスタム..." Basic.AutoConfig.StreamPage.Server="サーバー" Basic.AutoConfig.StreamPage.StreamKey="ストリームキー" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(リンク)" @@ -124,14 +154,14 @@ Basic.AutoConfig.StreamPage.PerformBandwidthTest="帯域幅のテストでビッ Basic.AutoConfig.StreamPage.PreferHardwareEncoding="ハードウェアエンコードを優先する" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="ハードウェアエンコードは CPU 使用率がほとんどなくなりますが、同レベルの品質を得るためにはより多くのビットレートが必要になります。" Basic.AutoConfig.StreamPage.StreamWarning.Title="配信の警告" -Basic.AutoConfig.StreamPage.StreamWarning.Text="帯域幅のテストはランダム化された音声なしの映像データを自分のチャンネルに配信しようとしています。可能ならば、一時的に配信の映像保存をオフにしてテストが完了するまで配信を非公開に設定することをおすすめします。 続行しますか?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="帯域幅のテストはランダム化された音声なしの映像データを自分のチャンネルに配信しようとしています。可能ならば、一時的に配信の映像保存をオフにしてテストが完了するまで配信を非公開に設定することをおすすめします。 続行しますか?" Basic.AutoConfig.TestPage="最終結果" Basic.AutoConfig.TestPage.SubTitle.Testing="プログラムは最も理想的な設定を推定するための一連のテストを現在実行中です" Basic.AutoConfig.TestPage.SubTitle.Complete="テスト完了" Basic.AutoConfig.TestPage.TestingBandwidth="帯域幅テストの実行、これには数分かかることがあります..." -Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="接続先: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="接続先: %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="サーバーに接続できませんでした。インターネット接続を確認してからもう一度お試しください。" -Basic.AutoConfig.TestPage.TestingBandwidth.Server="帯域幅のテスト: %1" +Basic.AutoConfig.TestPage.TestingBandwidth.Server="帯域幅のテスト: %1" Basic.AutoConfig.TestPage.TestingStreamEncoder="配信エンコーダのテスト中、これには数分かかることがあります..." Basic.AutoConfig.TestPage.TestingRecordingEncoder="録画エンコーダのテスト中、これには数分かかることがあります..." Basic.AutoConfig.TestPage.TestingRes="解像度のテスト中、これには数分かかることがあります..." @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="これらの設定を使用するには Basic.Stats="統計" Basic.Stats.CPUUsage="CPU使用率" -Basic.Stats.HDDSpaceAvailable="HDDの空き容量" +Basic.Stats.HDDSpaceAvailable="ディスク空き容量" Basic.Stats.MemoryUsage="メモリ使用量" Basic.Stats.AverageTimeToRender="フレームをレンダリングする平均時間" Basic.Stats.SkippedFrames="エンコードのラグが原因でスキップされたフレーム" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="非アクティブ" Basic.Stats.DroppedFrames="ドロップフレーム (ネットワーク)" Basic.Stats.MegabytesSent="出力データの合計" Basic.Stats.Bitrate="ビットレート" +Basic.Stats.DiskFullIn="ディスクがいっぱいになるまで後(約)" + +ResetUIWarning.Title="UIをリセットしてもよろしいですか?" +ResetUIWarning.Text="UIをリセットすると追加のドックは非表示になります。表示したい場合表示メニューからこれらのドックを表示する必要があります。\n\nUIをリセットしてもよろしいですか?" Updater.Title="利用可能な更新" Updater.Text="利用可能な更新があります:" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="利用可能な更新はありません" Updater.NoUpdatesAvailable.Text="現在利用可能な更新はありません" Updater.FailedToLaunch="アップデータの起動に失敗しました" Updater.GameCaptureActive.Title="ゲームキャプチャがアクティブ" -Updater.GameCaptureActive.Text="ゲームキャプチャフックライブラリが現在使用中です。キャプチャされているすべてのゲーム/プログラムを閉じて (またはwindowsを再起動して) からもう一度やり直してください。" +Updater.GameCaptureActive.Text="ゲームキャプチャフックライブラリが現在使用中です。キャプチャされているすべてのゲーム/プログラムを閉じて (またはWindowsを再起動して) からもう一度やり直してください。" QuickTransitions.SwapScenes="トランジション後にプレビュー/出力シーンを入れ替え" QuickTransitions.SwapScenesTT="(出力のオリジナルシーンがまだ存在する場合)、トランジション後のプレビューと出力シーンを入れ替えます。\nこれは出力のオリジナルシーンに加えられた可能性があるすべての変更を元に戻しません。" @@ -206,6 +240,9 @@ ConfirmStart.Text="配信を開始しますか?" ConfirmStop.Title="配信を停止しますか?" ConfirmStop.Text="配信を停止しますか?" +ConfirmBWTest.Title="帯域幅テストを開始しますか?" +ConfirmBWTest.Text="OBSが帯域幅テストモードに設定されています。 このモードではチャンネルを配信中にしなくてもネットワークテストが可能です。 テストが終了したら、視聴者があなたの配信を見ることができるようにするために無効にする必要があります。\n\n続行しますか?" + ConfirmExit.Title="OBSを終了しますか?" ConfirmExit.Text="OBS は現在アクティブです。 すべての配信/録画をシャットダウンをします。 終了してもよろしいですか?" @@ -215,9 +252,10 @@ ConfirmRemove.TextMultiple="選択した %1 項目を削除してもよろしい Output.StartStreamFailed="配信開始に失敗しました" Output.StartRecordingFailed="録画開始に失敗しました" -Output.StartReplayFailed="リプレイバッファーの開始に失敗しました" +Output.StartReplayFailed="リプレイバッファの開始に失敗しました" Output.StartFailedGeneric="出力開始に失敗しました。詳細はログを確認してください。\n\n注: NVENCまたはAMDエンコーダを使用している場合は、ビデオドライバが最新のものであるかを確認してください。" + Output.ConnectFail.Title="接続失敗" Output.ConnectFail.BadPath="パスかURLが無効です。再確認して下さい。" Output.ConnectFail.ConnectFailed="サーバーへの接続に失敗しました" @@ -225,14 +263,18 @@ Output.ConnectFail.InvalidStream="指定したチャンネルまたはストリ Output.ConnectFail.Error="サーバー接続時に予期しないエラーが発生しました。ログファイルを確認してください。" Output.ConnectFail.Disconnected="サーバーから切断されました。" +Output.StreamEncodeError.Title="エンコードエラー" +Output.StreamEncodeError.Msg="配信中にエンコーダでエラーが発生しました。" + Output.RecordFail.Title="録画を開始できませんでした" Output.RecordFail.Unsupported="出力フォーマットがサポートされていないか複数のオーディオ トラックをサポートしていません。 設定を確認してもう一度やり直してください。" Output.RecordNoSpace.Title="ディスク領域の不足" Output.RecordNoSpace.Msg="録画を継続する十分なディスク領域がありません。" Output.RecordError.Title="録画エラー" Output.RecordError.Msg="録画中に不明なエラーが発生しました。" -Output.ReplayBuffer.NoHotkey.Title="ホットキーが設定されていません!" -Output.ReplayBuffer.NoHotkey.Msg="リプレイバッファー保存のホットキー設定がありません。 リプレイ録画保存用に使用する「保存」のホットキーを設定してください。" +Output.RecordError.EncodeErrorMsg="録画中にエンコーダでエラーが発生しました。" +Output.ReplayBuffer.NoHotkey.Title="ホットキーが設定されていません!" +Output.ReplayBuffer.NoHotkey.Msg="リプレイバッファ保存のホットキー設定がありません。 リプレイ録画保存用に使用する「保存」のホットキーを設定してください。" Output.BadPath.Title="無効なパス" Output.BadPath.Text="設定されたファイルの出力パスが無効です。有効なファイルパスが設定されていることを確認してください。" @@ -241,25 +283,23 @@ LogReturnDialog="ログの送信成功" LogReturnDialog.CopyURL="URLのコピー" LogReturnDialog.ErrorUploadingLog="ログの送信失敗" -LicenseAgreement="使用許諾契約" -LicenseAgreement.PleaseReview="OBSを使用する前に使用許諾契約条項を確認してください。このプログラムを使用して、GNU General Public License v2.0の条項を読み同意したものと認めます。下にスクロールして本契約の残りの部分をお読みください。" -LicenseAgreement.ClickIAgreeToContinue="契約の条項に同意する場合、同意するをクリックして続行してください。OBSの使用に同意する必要があります。" -LicenseAgreement.IAgree="同意する" -LicenseAgreement.Exit="終了" - Remux.SourceFile="OBS 録画" Remux.TargetFile="対象ファイル" Remux.Remux="再多重化" +Remux.Stop="再多重化を停止" +Remux.ClearFinished="完了した項目をクリア" +Remux.ClearAll="すべての項目をクリア" Remux.OBSRecording="OBS 録画" Remux.FinishedTitle="再多重化完了" Remux.Finished="録画が再多重化されました" Remux.FinishedError="録画が再多重化されましたが、ファイルが未完成の可能性があります" -Remux.SelectRecording="OBS録画の選択 ..." -Remux.SelectTarget="対象ファイルを選択 ..." -Remux.FileExistsTitle="対象ファイルが存在しています" -Remux.FileExists="対象ファイルが存在しています、置き換えますか?" +Remux.SelectRecording="OBS録画の選択..." +Remux.SelectTarget="対象ファイルを選択..." +Remux.FileExistsTitle="対象ファイルが存在します" +Remux.FileExists="次の対象ファイルはすでに存在します。 それらを置き換えますか?" Remux.ExitUnfinishedTitle="再多重化が進行中です" Remux.ExitUnfinished="再多重化が完了しておらず、今停止すると対象ファイルが使用不能になる可能性があります。\n再多重化を停止しますか?" +Remux.HelpText="再多重化するにはファイルをこのウィンドウにドロップするか、空の \"OBS 録画\"セルを選択してファイルを参照します。" UpdateAvailable="更新が利用可能" UpdateAvailable.Text="バージョン %1.%2.%3 が利用可能です。ダウンロードはこちら" @@ -276,11 +316,14 @@ Basic.DisplayCapture="画面キャプチャ" Basic.Main.PreviewConextMenu.Enable="プレビュー有効化" +Basic.Main.Preview.Disable="プレビュー無効化" + ScaleFiltering="スケールフィルタ" ScaleFiltering.Point="ポイント" ScaleFiltering.Bilinear="バイリニア" ScaleFiltering.Bicubic="バイキュービック" ScaleFiltering.Lanczos="ランチョス" +ScaleFiltering.Area="エリア" Deinterlacing="インターレース解除" Deinterlacing.Discard="破棄" @@ -398,12 +441,12 @@ Basic.Main.Sources="ソース" Basic.Main.Controls="コントロール" Basic.Main.Connecting="接続中..." Basic.Main.StartRecording="録画開始" -Basic.Main.StartReplayBuffer="リプレイバッファー開始" +Basic.Main.StartReplayBuffer="リプレイバッファ開始" Basic.Main.StartStreaming="配信開始" Basic.Main.StopRecording="録画終了" Basic.Main.StoppingRecording="録画停止処理中..." -Basic.Main.StopReplayBuffer="リプレイバッファー停止" -Basic.Main.StoppingReplayBuffer="リプレイバッファー停止処理中..." +Basic.Main.StopReplayBuffer="リプレイバッファ停止" +Basic.Main.StoppingReplayBuffer="リプレイバッファ停止処理中..." Basic.Main.StopStreaming="配信終了" Basic.Main.StoppingStreaming="配信停止処理中..." Basic.Main.ForceStopStreaming="配信停止 (遅延破棄)" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="垂直反転(&V)" Basic.MainMenu.Edit.Transform.FitToScreen="画面に合わせる(&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="画面に引き延ばして置く(&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="画面中央に置く(&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="垂直方向に中央揃え" +Basic.MainMenu.Edit.Transform.HorizontalCenter="水平方向に中央揃え" Basic.MainMenu.Edit.Order="順序(&O)" Basic.MainMenu.Edit.Order.MoveUp="上に移動(&U)" Basic.MainMenu.Edit.Order.MoveDown="下に移動(&D)" @@ -476,20 +521,21 @@ Basic.MainMenu.Tools="ツール(&T)" Basic.MainMenu.Help="ヘルプ(&H)" Basic.MainMenu.Help.HelpPortal="ヘルプポータル(&P)" Basic.MainMenu.Help.Website="ウェブサイト(&W)" -Basic.MainMenu.Help.Discord="Discordサーバーに参加(&D)" +Basic.MainMenu.Help.Discord="&Discordサーバーに参加" Basic.MainMenu.Help.Logs="ログファイル(&L)" Basic.MainMenu.Help.Logs.ShowLogs="ログファイルを表示(&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="現在のログファイルをアップロード(&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="最新のログファイルをアップロード(&L)" +Basic.MainMenu.Help.Logs.UploadLastLog="最後のログファイルをアップロード(&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="現在のログを表示(&V)" Basic.MainMenu.Help.CheckForUpdates="更新を確認" Basic.MainMenu.Help.CrashLogs="クラッシュレポート(&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="クラッシュレポートを表示(&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="最新のクラッシュレポートをアップロード(&L)" +Basic.MainMenu.Help.About="OBS Studioについて(&A)" Basic.Settings.ProgramRestart="これらの設定を有効にするためにはプログラムの再起動が必要です。" Basic.Settings.ConfirmTitle="変更確認" -Basic.Settings.Confirm="保存していない変更があります。変更を保存しますか?" +Basic.Settings.Confirm="保存していない変更があります。変更を保存しますか?" Basic.Settings.General="一般" Basic.Settings.General.Theme="テーマ" @@ -508,14 +554,19 @@ Basic.Settings.General.SourceSnapping="他のソースにソースをスナッ Basic.Settings.General.SnapDistance="スナップ感度" Basic.Settings.General.RecordWhenStreaming="配信時に自動的に録画" Basic.Settings.General.KeepRecordingWhenStreamStops="配信が停止しても録画を継続" -Basic.Settings.General.ReplayBufferWhileStreaming="配信時に自動的にリプレイバッファーを開始" -Basic.Settings.General.KeepReplayBufferStreamStops="配信停止時にリプレイバッファーをアクティブにしておく" +Basic.Settings.General.ReplayBufferWhileStreaming="配信時に自動的にリプレイバッファを開始" +Basic.Settings.General.KeepReplayBufferStreamStops="配信停止時にリプレイバッファをアクティブにしておく" Basic.Settings.General.SysTray="システムトレイ" Basic.Settings.General.SysTrayWhenStarted="起動時にシステムトレイへ最小化" Basic.Settings.General.SystemTrayHideMinimize="タスクバーの代わりにシステムトレイに常に最小化する" Basic.Settings.General.SaveProjectors="終了時にプロジェクターを保存する" +Basic.Settings.General.Preview="プレビュー" +Basic.Settings.General.OverflowHidden="オーバーフローを非表示" +Basic.Settings.General.OverflowAlwaysVisible="オーバーフローを常に表示" +Basic.Settings.General.OverflowSelectionHidden="ソースが表示されていない場合もオーバーフローを表示" Basic.Settings.General.SwitchOnDoubleClick="ダブルクリックしたときにシーンに遷移" Basic.Settings.General.StudioPortraitLayout="縦長/垂直レイアウトを有効にする" +Basic.Settings.General.TogglePreviewProgramLabels="プレビュー/番組ラベルを表示する" Basic.Settings.General.Multiview="マルチビュー" Basic.Settings.General.Multiview.MouseSwitch="クリックするとシーンを切り替える" Basic.Settings.General.Multiview.DrawSourceNames="シーン名を表示" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="水平上側 (24 Basic.Settings.Stream="配信" Basic.Settings.Stream.StreamType="配信種別" +Basic.Settings.Stream.Custom.UseAuthentication="認証を使用する" +Basic.Settings.Stream.Custom.Username="ユーザー名" +Basic.Settings.Stream.Custom.Password="パスワード" +Basic.Settings.Stream.BandwidthTestMode="帯域幅テストモードを有効にする" Basic.Settings.Output="出力" Basic.Settings.Output.Format="録画フォーマット" @@ -540,13 +595,13 @@ Basic.Settings.Output.Mode="出力モード" Basic.Settings.Output.Mode.Simple="基本" Basic.Settings.Output.Mode.Adv="詳細" Basic.Settings.Output.Mode.FFmpeg="FFmpeg の出力" -Basic.Settings.Output.UseReplayBuffer="リプレイバッファーを有効にする" +Basic.Settings.Output.UseReplayBuffer="リプレイバッファを有効にする" Basic.Settings.Output.ReplayBuffer.SecondsMax="最大リプレイ時間 (秒)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大メモリ (メガバイト)" Basic.Settings.Output.ReplayBuffer.Estimate="概算メモリ使用量: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="メモリ使用量を見積もることができません。 最大メモリ制限を設定してください。" -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注: ホットキーでリプレイバッファーのホットキーを設定してください)" -Basic.Settings.Output.ReplayBuffer.Prefix="リプレイバッファーのファイル名の接頭辞" +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注: ホットキーでリプレイバッファのホットキーを設定してください)" +Basic.Settings.Output.ReplayBuffer.Prefix="リプレイバッファのファイル名の接頭辞" Basic.Settings.Output.ReplayBuffer.Suffix="接尾辞" Basic.Settings.Output.Simple.SavePath="録画ファイルのパス" Basic.Settings.Output.Simple.RecordingQuality="録画品質" @@ -559,8 +614,7 @@ Basic.Settings.Output.Simple.Warn.AudioBitrate="警告: 配信の音声ビット Basic.Settings.Output.Simple.Warn.Encoder="警告: 配信と録画を同時に行う場合に配信と異なる品質でソフトウェアエンコーダで録画する場合にはさらなるCPU 使用率が必要になります。" Basic.Settings.Output.Simple.Warn.Lossless="警告: 無損失品質は途方もなく大きなファイルサイズになります!無損失品質は高解像度と高フレーム レートで 1 分あたり7 ギガバイト以上のディスク容量を使用します。 非常に大量のディスクの空き容量がない場合の長時間録画には無損失設定の使用はお勧めしません。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="無損失品質を使用してもよろしいですか?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="無損失品質警告!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="警告: 配信と同時に録画する場合複数の独立した QSV エンコーダは使用できません。 配信と同時に録画したい場合、配信エンコーダか録画エンコーダのどちらかを変更してください。" +Basic.Settings.Output.Simple.Warn.Lossless.Title="無損失品質警告!" Basic.Settings.Output.Simple.Encoder.Software="ソフトウェア (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="ハードウェア (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="ハードウェア (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="自動的に再接続" Basic.Settings.Output.RetryDelay="再試行の遅延 (秒)" Basic.Settings.Output.MaxRetries="最大再試行回数" Basic.Settings.Output.Advanced="高度なエンコーダの設定を有効にする" -Basic.Settings.Output.EncoderPreset="エンコーダプリセット (上にいくほど = CPU使用低い)" +Basic.Settings.Output.EncoderPreset="エンコーダプリセット" Basic.Settings.Output.CustomEncoderSettings="エンコーダのカスタム設定" Basic.Settings.Output.CustomMuxerSettings="カスタムマルチプレクサーの設定" Basic.Settings.Output.NoSpaceFileName="スペースなしのファイル名を生成" @@ -580,7 +634,7 @@ Basic.Settings.Output.NoSpaceFileName="スペースなしのファイル名を Basic.Settings.Output.Adv.Rescale="出力をリスケールする" Basic.Settings.Output.Adv.AudioTrack="音声トラック" Basic.Settings.Output.Adv.Streaming="配信" -Basic.Settings.Output.Adv.ApplyServiceSettings="ストリーミングサービスのエンコーダ設定を適用する" +Basic.Settings.Output.Adv.ApplyServiceSettings="配信サービスのエンコーダ設定を適用する" Basic.Settings.Output.Adv.Audio.Track1="トラック 1" Basic.Settings.Output.Adv.Audio.Track2="トラック 2" Basic.Settings.Output.Adv.Audio.Track3="トラック 3" @@ -619,7 +673,7 @@ Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="すべてのコーデック FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY 年, 4桁\n%YY 年, 下2桁 (00-99)\n%MM 月 数値 (01-12)\n%DD 日, 0埋め (01-31)\n%hh 時 24時間形式 (00-23)\n%mm 分 (00-59)\n%ss 秒 (00-61)\n%% A % 記号\n%a 曜日 省略名\n%A 曜日 完全名\n%b 月 省略名\n%B 月 完全名\n%d 日, 0埋め (01-31)\n%H 時 24時間形式 (00-23)\n%I 時 12時間形式 (01-12)\n%m 月 数値 (01-12)\n%M 分 (00-59)\n%p 午前または午後の指定\n%S 秒 (00-61)\n%y 年, 下2桁 (00-99)\n%Y 年\n%z ISO 8601 UTCタイムゾーンからのオフセット\n 名前または省略名\n%Z タイムゾーン名または省略名\n" +FilenameFormatting.TT="%CCYY 年, 4桁\n%YY 年, 下2桁 (00-99)\n%MM 月 数値 (01-12)\n%DD 日, 0埋め (01-31)\n%hh 時 24時間形式 (00-23)\n%mm 分 (00-59)\n%ss 秒 (00-61)\n%% A % 記号\n%a 曜日 省略名\n%A 曜日 完全名\n%b 月 省略名\n%B 月 完全名\n%d 日, 0埋め (01-31)\n%H 時 24時間形式 (00-23)\n%I 時 12時間形式 (01-12)\n%m 月 数値 (01-12)\n%M 分 (00-59)\n%p 午前または午後の指定\n%S 秒 (00-61)\n%y 年, 下2桁 (00-99)\n%Y 年\n%z ISO 8601 UTCからのオフセット\n%Z タイムゾーン名または略称\n" Basic.Settings.Video="映像" Basic.Settings.Video.Adapter="ビデオアダプター" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="ランチョス (先鋭化スケ Basic.Settings.Audio="音声" Basic.Settings.Audio.SampleRate="サンプリングレート" Basic.Settings.Audio.Channels="チャンネル" -Basic.Settings.Audio.MeterDecayRate="音声メーターの減衰率" +Basic.Settings.Audio.Meters="メーター" +Basic.Settings.Audio.MeterDecayRate="減衰率" Basic.Settings.Audio.MeterDecayRate.Fast="速い" Basic.Settings.Audio.MeterDecayRate.Medium="中 (タイプ I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="遅い (タイプ II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: サラウンド音声 Basic.Settings.Audio.MultichannelWarning="配信する場合、配信サービスがサラウンド音声の取り込みと再生の両方をサポートしているかどうかを確認してください。Twitch、Facebook 360 Live、Mixer RTMP、Smashcastは、サラウンド音声が完全にサポートされている例です。しかしFacebook LiveとYouTube Liveはどちらもサラウンド取り込みを受信しますが、Facebook Liveはステレオにダウンミックスし、YouTube Liveは2チャンネルのみしか再生できません。\n\nVSTプラグインのサポートは保証されていませんが、OBS音声フィルタはサラウンド音声と互換性があります。" Basic.Settings.Audio.MultichannelWarning.Title="サラウンド音声を有効にしますか?" Basic.Settings.Audio.MultichannelWarning.Confirm="サラウンド音声を有効にしてもよろしいですか?" -Basic.Settings.Audio.DesktopDevice="デスクトップ音声デバイス" -Basic.Settings.Audio.DesktopDevice2="デスクトップ音声デバイス 2" -Basic.Settings.Audio.AuxDevice="マイク音声デバイス" -Basic.Settings.Audio.AuxDevice2="マイク音声デバイス 2" -Basic.Settings.Audio.AuxDevice3="マイク音声デバイス 3" +Basic.Settings.Audio.Devices="デバイス" +Basic.Settings.Audio.DesktopDevice="デスクトップ音声" +Basic.Settings.Audio.DesktopDevice2="デスクトップ音声 2" +Basic.Settings.Audio.AuxDevice="マイク音声" +Basic.Settings.Audio.AuxDevice2="マイク音声 2" +Basic.Settings.Audio.AuxDevice3="マイク音声 3" +Basic.Settings.Audio.AuxDevice4="マイク音声 4" Basic.Settings.Audio.EnablePushToMute="プッシュ-ミュートを有効にする" Basic.Settings.Audio.PushToMuteDelay="プッシュ-ミュート遅延" Basic.Settings.Audio.EnablePushToTalk="プッシュ-トークを有効にする" Basic.Settings.Audio.PushToTalkDelay="プッシュ-トーク遅延" Basic.Settings.Audio.UnknownAudioDevice="[デバイスが接続されていないまたは利用不可]" +Basic.Settings.Audio.Disabled="無効" Basic.Settings.Advanced="詳細設定" Basic.Settings.Advanced.General.ProcessPriority="プロセスの優先度" @@ -675,13 +733,13 @@ Basic.Settings.Advanced.General.ProcessPriority.Normal="通常" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="通常以下" Basic.Settings.Advanced.General.ProcessPriority.Idle="低" Basic.Settings.Advanced.FormatWarning="警告: NV12以外のカラーフォーマットは主に録画を想定しており、配信には非推奨です。配信ではカラーフォーマットの変換による CPU使用率の増加が発生する可能性があります。" -Basic.Settings.Advanced.Audio.BufferingTime="音声バッファー処理時間" +Basic.Settings.Advanced.Audio.BufferingTime="音声バッファ処理時間" Basic.Settings.Advanced.Video.ColorFormat="カラーフォーマット" -Basic.Settings.Advanced.Video.ColorSpace="YUV 色空間" -Basic.Settings.Advanced.Video.ColorRange="YUV 色範囲" +Basic.Settings.Advanced.Video.ColorSpace="色空間" +Basic.Settings.Advanced.Video.ColorRange="色範囲" Basic.Settings.Advanced.Video.ColorRange.Partial="一部" Basic.Settings.Advanced.Video.ColorRange.Full="全部" -Basic.Settings.Advanced.Audio.MonitoringDevice="音声モニタリングデバイス" +Basic.Settings.Advanced.Audio.MonitoringDevice="モニタリングデバイス" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="既定" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windowsの音量を自動で下げる機能を無効にする" Basic.Settings.Advanced.StreamDelay="遅延配信" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="IP選択" Basic.Settings.Advanced.Network.EnableNewSocketLoop="新しいネットワークコードを有効にする" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低遅延モード" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="メインウィンドウにフォーカスがあるときはホットキーを無効にする" +Basic.Settings.Advanced.AutoRemux="自動的にmp4に再多重化" +Basic.Settings.Advanced.AutoRemux.MP4="(mkvとして録画)" Basic.AdvAudio="オーディオの詳細プロパティ" Basic.AdvAudio.Name="名称" -Basic.AdvAudio.Volume="音量 (%)" +Basic.AdvAudio.Volume="音量" Basic.AdvAudio.Mono="モノラルにダウンミックス" -Basic.AdvAudio.Panning="パンニング" +Basic.AdvAudio.Balance="バランス" Basic.AdvAudio.SyncOffset="同期オフセット (ミリ秒)" Basic.AdvAudio.Monitoring="音声モニタリング" Basic.AdvAudio.Monitoring.None="モニターオフ" @@ -708,13 +768,14 @@ Basic.AdvAudio.AudioTracks="トラック" Basic.Settings.Hotkeys="ホットキー" Basic.Settings.Hotkeys.Pair="'%1' との組合せでトグルスイッチとして機能します" +Basic.Settings.Hotkeys.Filter="絞り込み" Basic.Hotkeys.SelectScene="シーン切り替え" Basic.SystemTray.Show="表示" Basic.SystemTray.Hide="非表示" -Basic.SystemTray.Message.Reconnecting="切断。 再接続..." +Basic.SystemTray.Message.Reconnecting="切断。 再接続..." Hotkeys.Insert="Insertキー" Hotkeys.Delete="Deleteキー" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (キーパッド)" Hotkeys.AppleKeypadDecimal=". (キーパッド)" Hotkeys.AppleKeypadEqual="= (キーパッド)" Hotkeys.MouseButton="マウス %1" +Hotkeys.Escape="Esc キー" Mute="ミュート" Unmute="ミュート解除" @@ -762,7 +824,7 @@ SceneItemHide="'%1' を非表示" OutputWarnings.NoTracksSelected="少なくとも 1 つのトラックを選択する必要があります" OutputWarnings.MultiTrackRecording="警告: 特定のフォーマット (FLVなど) は1つの録画で複数のトラックをサポートしていません" -OutputWarnings.MP4Recording="警告: ファイルをファイナライズ出来ない場合 (例えば、BSOD、電力損失などの結果として) はMP4に保存された録画は回復不能になります。 複数の音声トラックを録画する場合はMKVの利用を検討して録画の終了後にMP4に再多重化してください。(ファイル -> 録画の再多重化)" +OutputWarnings.MP4Recording="警告: (例えば、ブルースクリーン、電力損失などの結果として)ファイルをファイナライズ出来ない場合はMP4/MOVに保存された録画は回復不能になります。 複数の音声トラックを録画する場合はMKVの利用を検討して録画の終了後にMP4/MOVに再多重化してください。(ファイル → 録画の再多重化)" FinalScene.Title="シーンを削除する" FinalScene.Text="1つ以上のシーンが必要です。" @@ -770,9 +832,24 @@ FinalScene.Text="1つ以上のシーンが必要です。" NoSources.Title="ソース無し" NoSources.Text="映像ソースをまだ追加していないようなので、空白の画面だけが出力されます。よろしいですか?" NoSources.Text.AddSource="メインウィンドウのソースボックスの下にある + アイコンをクリックすると、いつでもソースを追加することができます。" +NoSources.Label="ソースがありません。\n下の + ボタンをクリックするか、\nまたはここを右クリックして追加してください。" ChangeBG="色の設定" CustomColor="カスタム色" BrowserSource.EnableHardwareAcceleration="ブラウザソースのハードウェアアクセラレーションを有効にする" +About="OBS Studioについて" +About.Info="OBS Studioは無料でオープンソースのビデオ録画と生放送用のソフトウェアです。" +About.Donate="貢献する" +About.GetInvolved="参加する" +About.Authors="作者" +About.License="ライセンス" +About.Contribute="OBS プロジェクトを支援する" + +ResizeOutputSizeOfSource="出力サイズ変更 (ソースサイズ)" +ResizeOutputSizeOfSource.Text="基本解像度と出力解像度は、現在のソースサイズにリサイズされます。" +ResizeOutputSizeOfSource.Continue="続行しますか?" + +PreviewTransition="トランジションのプレビュー" + diff --git a/UI/data/locale/ka-GE.ini b/UI/data/locale/ka-GE.ini index eb59e36..c06dc9c 100644 --- a/UI/data/locale/ka-GE.ini +++ b/UI/data/locale/ka-GE.ini @@ -17,8 +17,8 @@ Rename="გადარქმევა" Interact="ურთიერთქმედება" Filters="ფილტრები" Properties="პარამეტრები" -MoveUp="ზევით" -MoveDown="ქვევით" +MoveUp="აწევა" +MoveDown="ჩამოწევა" Settings="პარამეტრები" Display="ეკრანი" Name="სახელი" @@ -42,10 +42,10 @@ Clear="გასუფთავება" Revert="დაბრუნება" Show="ჩვენება" Hide="დამალვა" -UnhideAll="ყველაფრის გამოჩენა" +UnhideAll="ყველას გამოჩენა" Untitled="უსათაურო" New="ახალი" -Duplicate="დუბლირება" +Duplicate="ასლის შექმნა" Enable="ჩართვა" DisableOSXVSync="OSX V-Sync-ის გამორთვა" ResetOSXVSyncOnExit="OSX V-Sync-ის გადატვირთვა გასვლისას" @@ -63,12 +63,12 @@ Seconds="წამი" Deprecated="მოძველებული" ReplayBuffer="უკან გადახვევის დრო" Import="შემოტანა" -Export="გატანა" -Copy="დაკოპირება" +Export="შენახვა" +Copy="ასლი" Paste="ჩასმა" PasteReference="ჩასმა (ბმული)" PasteDuplicate="ჩასმა (ასლი)" -RemuxRecordings="ჩანაწერების გარდაქმნა" +RemuxRecordings="ჩანაწერების გადაფუთვა" Next="შემდეგ" Back="უკან" Defaults="ნაგულისხმევი" @@ -80,14 +80,39 @@ StudioMode.Program="შედეგი" ShowInMultiview="მრავალხედიანი ჩვენება" VerticalLayout="შვეული განლაგება" Group="დაჯგუფება" +DoNotShowAgain="მომავალში ჩვენების გარეშე" +Default="(ნაგულისხმევი)" +Calculating="ითვლება..." AlreadyRunning.Title="OBS უკვე გაშვებულია" AlreadyRunning.Text="OBS უკვე გაშვებულია! გთხოვთ, ჯერ დახუროთ OBS-ის ყველა გაშვებული პროცესი, სანამ ახლის გაშვებას შეეცდებით. თუ მითითებული გაქვთ, რომ დახურვის ნაცვლად, OBS სისტემურ არეში უნდა ჩაიკეცოს, გთხოვთ მანდაც გადაამოწმოთ, დარჩენილი ხომ არაა." AlreadyRunning.LaunchAnyway="მაინც გაშვება" -Copy.Filters="ფილტრების დაკოპირება" +DockCloseWarning.Title="იერსახის ნაწილის დამალვა" +DockCloseWarning.Text="თქვენ ახლახან დამალეთ იერსახის ნაწილი. თუ გსურთ მისი კვლავ გამოჩენა, მენიუს ზოლიდან გამოიყენეთ ხედი → იერსახის ნაწილები." + +Auth.Authing.Title="ანგარიშზე შესვლა..." +Auth.Authing.Text="მიმდინარეობს შესვლა %1-ზე, გთხოვთ, მოითმინოთ..." +Auth.AuthFailure.Title="შესვლა ვერ მოხერხდა" +Auth.AuthFailure.Text="ვერ მოხერხდა შესვლა %1-ზე:\n\n%2: %3" +Auth.InvalidScope.Title="საჭიროებს ანგარიშზე შესვლას" +Auth.InvalidScope.Text="შესვლის მოთხოვნები შეცვლილია მომსახურებისთვის %1. ზოგი შესაძლებლობა, შეიძლება აღარ იყოს ხელმისაწვდომი." +Auth.LoadingChannel.Title="არხის მონაცემების ჩატვირთვა..." +Auth.LoadingChannel.Text="%1-ის არხის მონაცემები იტვირთება, გთხოვთ მოითმინოთ..." +Auth.ChannelFailure.Title="მონაცემების ჩატვირთვა ვერ მოხერხდა" +Auth.ChannelFailure.Text="%1-ის არხის მონაცემების ჩატვირთვა ვერ მოხერხდა\n\n%2: %3" +Auth.Chat="სასაუბრო" +Auth.StreamInfo="ნაკადის მონაცემები" +TwitchAuth.Stats="Twitch-ის სტატისტიკა" +TwitchAuth.Feed="Twitch მოქმედებების არხი" +TwitchAuth.TwoFactorFail.Title="ნაკადის გასაღების მოთხოვნა ვერ მოხერხდა" + +Copy.Filters="ფილტრების ასლი" Paste.Filters="ფილტრების ჩასმა" +BrowserPanelInit.Title="ეშვება ბრაუზერი..." +BrowserPanelInit.Text="ეშვება ბრაუზერი, გთხოვთ მოითმინოთ..." + BandwidthTest.Region="რეგიონი" BandwidthTest.Region.US="შეერთებული შტატები" BandwidthTest.Region.EU="ევროპა" @@ -95,11 +120,9 @@ BandwidthTest.Region.Asia="აზია" BandwidthTest.Region.Other="სხვა" Basic.FirstStartup.RunWizard="გსურთ, გაეშვას თვითგამართვის მეგზური? ამასთან, შეგიძლიათ პარამეტრების ხელით გამართვა მთავარ ფანჯარაში, პარამეტრების ღილაკზე დაწკაპებით." -Basic.FirstStartup.RunWizard.BetaWarning="(შენიშვნა: თვითგამართვის მეგზური ჯერჯერობით საცდელია)" Basic.FirstStartup.RunWizard.NoClicked="თუ გადაიფიქრებთ, თვითგამართვის გაშვება შეგეძლებათ ნებისმიერ დროს, ხელსაწყოების მენიუდან." Basic.AutoConfig="თვითგამართვის მეგზური" -Basic.AutoConfig.Beta="თვითგამართვის მეგზური (Beta)" Basic.AutoConfig.ApplySettings="პარამეტრების მიღება" Basic.AutoConfig.StartPage="გამოყენების შესახებ" Basic.AutoConfig.StartPage.SubTitle="მიუთითეთ, თუ რა მიზნით გსურთ პროგრამის გამოყენება" @@ -115,8 +138,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ან 30, თუმცა უ Basic.AutoConfig.VideoPage.CanvasExplanation="შენიშვნა: ეკრანის ფონის (ძირითადი) გაფართოება არაა აუცილებელი გაშვებული ნაკადის ან გადაღებული ვიდეოს გაფართოებას ემთხვეოდეს. ცალკეული ნაკადის/ვიდეოს ზომები შეიძლება შემცირდეს, რესურსების მოხმარების ან ბიტური სიხშირის შესამცირებლად." Basic.AutoConfig.StreamPage="ნაკადის მონაცემები" Basic.AutoConfig.StreamPage.SubTitle="გთხოვთ მიუთითოთ ნაკადის მონაცემები" +Basic.AutoConfig.StreamPage.ConnectAccount="ანგარიშის დაკავშირება (არასავალდებულო)" +Basic.AutoConfig.StreamPage.DisconnectAccount="ანგარიშიდან გამოერთება" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="გსურთ ანგარიშიდან გამოერთება?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="ცვლილება დაუყოვნებლივ აისახება. ნამდვილად გსურთ, ანგარიშიდან გამოერთება?" +Basic.AutoConfig.StreamPage.UseStreamKey="ნაკადის გასაღების გამოყენება" Basic.AutoConfig.StreamPage.Service="მომსახურება" Basic.AutoConfig.StreamPage.Service.ShowAll="ყველას ჩვენება..." +Basic.AutoConfig.StreamPage.Service.Custom="მითითებული..." Basic.AutoConfig.StreamPage.Server="სერვერი" Basic.AutoConfig.StreamPage.StreamKey="ნაკადის გასაღები" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(ბმული)" @@ -155,30 +184,34 @@ Basic.Stats.Status="მდგომარეობა" Basic.Stats.Status.Recording="მიმდინარეობს" Basic.Stats.Status.Live="ეთერშია" Basic.Stats.Status.Reconnecting="ხელახლა დაკავშირება" -Basic.Stats.Status.Inactive="არააქტიური" +Basic.Stats.Status.Inactive="უმოქმედო" Basic.Stats.DroppedFrames="გამოტოვებული კადრები (ქსელი)" Basic.Stats.MegabytesSent="საერთო მოცულობა" Basic.Stats.Bitrate="ბიტური სიხშირე" +Basic.Stats.DiskFullIn="დარჩენილი ადგილი დისკზე (დაახლ.)" + +ResetUIWarning.Title="ნამდვილად გსურთ იერსახის პარამეტრების ჩამოყრა?" +ResetUIWarning.Text="შედეგად, დამატებითი ნაწილები დაიმალება. მათი ხელახლა გამოჩენა, შესაძლებელი იქნება ხედის მენიუდან, სურვილის შემთხვევაში.\n\nნამდვილად გსურთ იერსახის პარამეტრების ჩამოყრა?" Updater.Title="ხელმისაწვდომია განახლება" Updater.Text="ხელმისაწვდომია განახლება:" -Updater.UpdateNow="განაახლე ახლა" +Updater.UpdateNow="ახლავე განახლება" Updater.RemindMeLater="მოგვიანებით შეხსენება" Updater.Skip="ვერსიის გამოტოვება" Updater.Running.Title="პროგრამა ამჟამად გაშვებულია" -Updater.Running.Text="გაშვებულია გამომავალი სიგნალები, გთხოვთ, ჯერ გამორთოთ ყველა მოქმედი გამომავალი სიგნალი, სანამ განახლებას შეეცდებით" +Updater.Running.Text="მიმდინარეობს სიგნალის გამოტანა, გთხოვთ, ჯერ გათიშოთ ყველა მოქმედი გამოტანა, სანამ განახლებას შეეცდებით" Updater.NoUpdatesAvailable.Title="განახლებები არაა ხელმისაწვდომი" Updater.NoUpdatesAvailable.Text="ამჟამად, განახლებები არაა ხელმისაწვდომი" Updater.FailedToLaunch="განახლების გაშვება ვერ მოხერხდა" Updater.GameCaptureActive.Title="მიმდინარეობს თამაშის ჩაწერა" -Updater.GameCaptureActive.Text="ამჟამად გაშვებულია თამაშის ჩამწერი ბიბლიოთეკა. გთხოვთ, შეწყვიტოთ ყველა თამაშის/პროგრამის ჩაწერა (ან თავიდან ჩართოთ windows) და სცადოთ ხელახლა." +Updater.GameCaptureActive.Text="ამჟამად გაშვებულია თამაშის ჩამწერი ბიბლიოთეკა. გთხოვთ, შეწყვიტოთ ყველა თამაშის/პროგრამის ჩაწერა (ან თავიდან ჩართოთ Windows) და სცადოთ ხელახლა." -QuickTransitions.SwapScenes="გადასვლის შემდეგ, შესათვალიერებელი და გამომავალი სცენებისთვის ადგილის გაცვლა" -QuickTransitions.SwapScenesTT="გადასვლის შემდეგ, შესათვალიერებელი და გამომავალი სცენებისთვის ადგილის გაცვლა (თუ ჯერ კიდევ არსებობს გამომავალი სცენის თავდაპირველი ასლი).\nამის შედეგად, გამომავალი სცენის თავდაპირველ ვარიანტზე გაკეთებული ცვლილებები, არ გაუქმდება." +QuickTransitions.SwapScenes="გადასვლის შემდეგ, შესათვალიერებელი და გამოტანილი სცენებისთვის ადგილის გაცვლა" +QuickTransitions.SwapScenesTT="გადასვლის შემდეგ, შესათვალიერებელი და გამოტანილი სცენებისთვის ადგილის გაცვლა (თუ ჯერ კიდევ არსებობს გამოტანის თავდაპირველი სცენა).\nგამოტანის თავდაპირველ სცენაზე გაკეთებული ცვლილებები, არ გაუქმდება." QuickTransitions.DuplicateScene="სცენის გაორკეცება" -QuickTransitions.DuplicateSceneTT="ერთი და იმავე სცენის შესწორებისას, საშუალებას იძლევა წყარო გარდაიქმნას, გამომავალი შედეგის შეცვლის გარეშე.\nწყაროს პარამეტრების ჩასასწორებლად, გამომავალი შედეგის შეცვლის გარეშე, ჩართეთ 'წყაროს გაორკეცება'\nმოცემული მნიშვნელობის ცვლილება გამოიწვევს მიმდინარე გამომავალი სცენის საწყისზე დაბრუნებას (თუ ჯერ კიდევ არსებობს)." +QuickTransitions.DuplicateSceneTT="ერთი და იმავე სცენის შესწორებისას, საშუალებას იძლევა წყაროები გარდაიქმნას, გამოტანის შეუცვლელად.\nწყაროს პარამეტრების ჩასასწორებლად, გამოტანის შეუცვლელად, ჩართეთ „წყაროს გაორკეცება“.\nამ მნიშვნელობის ცვლილება, გამოტანის მიმდინარე სცენას დააბრუნებს საწყისზე (თუ ჯერ კიდევ არსებობს)." QuickTransitions.EditProperties="წყაროს გაორკეცება" -QuickTransitions.EditPropertiesTT="ერთი და იმავე სცენის შესწორებისას, საშუალებას იძლევა წყაროს პარამეტრები ჩასწორდეს, გამომავალი შედეგის შეცვლის გარეშე.\nმისი გამოყენება შესაძლებელია, მხოლოდ 'სცენის გაორკეცების' შემთხვევაში\nცალკეული წყაროები (მათ შორის გადაღებული ან არსებული მედიაფაილები) არ იძლევა ამის საშუალებას და მათი განცალკევებით ჩასწორება შეუძლებელია.\nმოცემული მნიშვნელობის ცვლილება გამოიწვევს მიმდინარე გამომავალი სცენის საწყისზე დაბრუნებას (თუ ჯერ კიდევ არსებობს).\n\nგაფრთხილება: წყაროს გაორკეცების შედეგად, შესაძლოა სისტემის და ვიდეოდაფის დატვირთვა გაიზარდოს." +QuickTransitions.EditPropertiesTT="ერთი და იმავე სცენის შესწორებისას, საშუალებას იძლევა წყაროს პარამეტრები ჩასწორდეს, გამოტანის შეუცვლელად.\nმისი გამოყენება შესაძლებელია, მხოლოდ „სცენის გაორკეცებისას“.\nზოგიერთი წყარო (როგორიცაა მიმდინარე გადაღება ან მედიაფაილები) არ იძლევა ამის საშუალებას და ცალკე ვერ ჩასწორდება.\nამ მნიშვნელობის ცვლილება, მიმდინარე გამოტანის სცენას დააბრუნებს საწყისზე (თუ ჯერ კიდევ არსებობს).\n\nგაფრთხილება: წყაროს გაორკეცების შედეგად, შესაძლოა სისტემის და ვიდეოდაფის დატვირთვა გაიზარდოს." QuickTransitions.HotkeyName="სწრაფი გადასვლა: %1" Basic.AddTransition="გასამართი გადასვლის დამატება" @@ -206,60 +239,66 @@ ConfirmStart.Text="ნამდვილად გსურთ პირდა ConfirmStop.Title="შეწყდეს ნაკადი?" ConfirmStop.Text="ნამდვილად გსურთ პირდაპირი ეთერის შეწყვეტა?" +ConfirmBWTest.Title="შემოწმდეს ქსელის გამტარუნარიანობა?" +ConfirmBWTest.Text="OBS-ისთვის მითითებული გაქვთ ქსელის გამტარუნარიანობის რეჟიმი. ეს რეჟიმი საშუალებას გაძლევთ, შეამოწმოთ ქსელის მუშაობა, თქვენს არხზე პირდაპირ ეთერში გასვლის გარეშე. შემოწმების დასრულებისთანავე, საჭიროა მისი გათიშვა, რომ მაყურებლებმა შეძლონ გაშვებული ნაკადის ხილვა\n\nგსურთ, განაგრძოთ?" + ConfirmExit.Title="OBS-დან გასვლა?" -ConfirmExit.Text="OBS ამჟამად მოქმედია. ყველა გაშვებული ნაკადი/ჩაწერა შეწყდება. ნამდვილად გსურთ გამოსვლა?" +ConfirmExit.Text="OBS ამჟამად მოქმედია. ყველა გაშვებული ნაკადი/ჩაწერა შეწყდება. ნამდვილად გსურთ გამოსვლა?" ConfirmRemove.Title="წაშლის დადასტურება" -ConfirmRemove.Text="ნამდვილად გსურთ, წაიშალოს '$1'?" +ConfirmRemove.Text="ნამდვილად გსურთ, წაიშალოს „$1“?" ConfirmRemove.TextMultiple="ნამდვილად გსურთ, წაიშალოს %1 მათგანი?" Output.StartStreamFailed="ნაკადის გაშვება ვერ მოხერხდა" Output.StartRecordingFailed="ჩაწერის დაწყება ვერ მოხერხდა" Output.StartReplayFailed="გადახვევის ჩართვა ვერ მოხერხდა" -Output.StartFailedGeneric="სიგნალის გაშვება ვერ მოხერხდა. გთხოვთ, შეამოწმეთ აღრიცხვის ფაილი, დამატებითი ინფორმაციისთვის.\n\nშენიშვნა: თუ იყენებთ NVENC ან AMD დამშიფრავებს, დარწმუნდით რომ თქვენი ვიდეოდაფის პროგრამა განახლებულია." +Output.StartFailedGeneric="სიგნალის გაშვება ვერ მოხერხდა. გთხოვთ, შეამოწმეთ აღრიცხვის ფაილი, დამატებითი ინფორმაციისთვის.\n\nშენიშვნა: თუ იყენებთ NVENC ან AMD დამშიფრავებს, დარწმუნდით რომ თქვენი ვიდეოდაფის პროგრამა განახლებულია." + Output.ConnectFail.Title="დაკავშირება ვერ მოხერხდა" -Output.ConnectFail.BadPath="არამართებული მისამართი ან დასაკავშირებელი URL ბმული. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრების სისწორე." +Output.ConnectFail.BadPath="არამართებული მისამართი ან დასაკავშირებელი URL ბმული. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრების სისწორე." Output.ConnectFail.ConnectFailed="სერვერთან დაკავშირება ვერ მოხერხდა" -Output.ConnectFail.InvalidStream="ვერ ხერხდება მითითებულ არხთან ან ნაკადის გასაღებთან დაკავშირება, გთხოვთ, გადაამოწმოთ თქვენი ნაკადის გასაღები. თუ სწორია, მაშინ შესაძლოა ხარვეზი იყოს სერვერთან დაკავშირებისას." -Output.ConnectFail.Error="მოულოდნელი შეცდომა წარმოიქმნა სერვერთან დაკავშირებისას. დამატებითი ინფორმაციისთვის იხილეთ აღრიცხვის ფაილი." +Output.ConnectFail.InvalidStream="ვერ ხერხდება მითითებულ არხთან ან ნაკადის გასაღებთან დაკავშირება, გთხოვთ, გადაამოწმოთ თქვენი ნაკადის გასაღები. თუ სწორია, მაშინ შესაძლოა ხარვეზი იყოს სერვერთან დაკავშირებისას." +Output.ConnectFail.Error="მოულოდნელი შეცდომა წარმოიქმნა სერვერთან დაკავშირებისას. დამატებითი ინფორმაციისთვის იხილეთ აღრიცხვის ფაილი." Output.ConnectFail.Disconnected="სერვერთან კავშირი გაწყვეტილია." +Output.StreamEncodeError.Title="შეცდომა დაშიფვრისას" +Output.StreamEncodeError.Msg="დამშიფრავის შეცდომა ნაკადის გაშვებისას." + Output.RecordFail.Title="ჩაწერის დაწყება ვერ მოხერხდა" -Output.RecordFail.Unsupported="ამ სახის გამომავალი სიგნალი ან არაა მხარდაჭერილი, ან არ იძლევა ერთზე მეტი ხმოვანი ფაილის გამოყენების საშუალებას. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრები და სცადოთ ხელახლა." +Output.RecordFail.Unsupported="გამოტანის ეს სახეობა ან არაა მხარდაჭერილი, ან არ იძლევა ერთზე მეტი ხმოვანი ფაილის გამოყენების საშუალებას. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრები და სცადოთ ხელახლა." Output.RecordNoSpace.Title="არასაკმარისი ადგილი დისკზე" Output.RecordNoSpace.Msg="დისკზე აღარაა საკმარისი ადგილი ჩაწერის გასაგრძელებლად." Output.RecordError.Title="შეცდომა ჩაწერისას" Output.RecordError.Msg="ჩაწერის დროს დაუდგენელი სახის შეცდომა წარმოიშვა." +Output.RecordError.EncodeErrorMsg="დამშიფრავის შეცდომა წარმოიშვა ჩაწერისას." Output.ReplayBuffer.NoHotkey.Title="სწრაფი ღილაკი არაა მითითებული!" -Output.ReplayBuffer.NoHotkey.Msg="სწრაფი ღილაკი არაა მითითებული გადახვევისთვის. გთხოვთ, მიუთითოთ „შენახვის“ ღილაკი, გადასახვევი მასალის შესანახად." +Output.ReplayBuffer.NoHotkey.Msg="სწრაფი ღილაკი არაა მითითებული გადახვევისთვის. გთხოვთ, მიუთითოთ „შენახვის“ ღილაკი, გადასახვევი მასალის შესანახად." Output.BadPath.Title="ფაილის არამართებული მისამართი" -Output.BadPath.Text="ფაილის მითითებული მდებარეობა არასწორია. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრების სისწორე." +Output.BadPath.Text="ფაილის მითითებული მდებარეობა არასწორია. გთხოვთ, გადაამოწმოთ თქვენი პარამეტრების სისწორე." LogReturnDialog="ჩანაწერი წარმატებით აიტვირთა" -LogReturnDialog.CopyURL="ბმულის კოპირება" +LogReturnDialog.CopyURL="ბმულის ასლი" LogReturnDialog.ErrorUploadingLog="შეცდომა აღრიცხვის ფაილის ატვირთვისას" -LicenseAgreement="სალიცენზიო შეთანხმება" -LicenseAgreement.PleaseReview="გთხოვთ, გაეცნოთ ლიცენზიის დადგენილებებს OBS-ით სარგებლობამდე. ამ პროგრამის გამოყენებით თქვენ ადასტურებთ, რომ წაიკითხეთ და ეთანხმებით GNU General Public v2.0 ლიცენზიის პირობებს. გთხოვთ, გადაადგილოთ გვერდი ქვემოთ, ხელშეკრულების სრულად სანახავად." -LicenseAgreement.ClickIAgreeToContinue="თუ თანახმა ხართ, მიიღოთ ხელშეკრულების პირობები, დააწკაპეთ ღილაკს „ვეთანხმები“. OBS-ით სარგებლობისთვის, აუცილებელია წინამდებარე პირობების მიღება." -LicenseAgreement.IAgree="ვეთანხმები" -LicenseAgreement.Exit="გასვლა" - -Remux.SourceFile="OBS ჩაწერა" +Remux.SourceFile="OBS ჩანაწერი" Remux.TargetFile="საბოლოო ფაილი" -Remux.Remux="ხელახლა მულტიპლექსირება" -Remux.OBSRecording="OBS ჩაწერა" -Remux.FinishedTitle="გარდაქმნა დასრულებულია" -Remux.Finished="ჩანაწერის გარდაქმნა დასრულდა" -Remux.FinishedError="ჩანაწერის გარდაქმნა დასრულდა, თუმცა ფაილი, შესაძლოა არასრული იყოს" -Remux.SelectRecording="ფაილის არჩევა OBS ჩანაწერისთვის…" -Remux.SelectTarget="საბოლოო ფაილის არჩევა …" +Remux.Remux="გადაფუთვა" +Remux.Stop="გადაფუთვის შეწყვეტა" +Remux.ClearFinished="დასრულებულების მოცილება" +Remux.ClearAll="ყველას მოცილება" +Remux.OBSRecording="OBS ჩანაწერი" +Remux.FinishedTitle="გადაფუთვა დასრულებულია" +Remux.Finished="ჩანაწერის გადაფუთვა დასრულდა" +Remux.FinishedError="ჩანაწერის გადაფუთვა დასრულდა, თუმცა ფაილი, შესაძლოა არასრული იყოს" +Remux.SelectRecording="OBS-ის ჩანაწერის არჩევა..." +Remux.SelectTarget="საბოლოო ფაილის არჩევა..." Remux.FileExistsTitle="საბოლოო ფაილი უკვე არჩეულია" -Remux.FileExists="საბოლოო ფაილი უკვე არჩეულია, გსურთ მისი შეცვლა?" -Remux.ExitUnfinishedTitle="მიმდინარეობს გარდაქმნა" -Remux.ExitUnfinished="გარდაქმნა ჯერ არ დასრულებულა, ახლავე შეწყვეტის შედეგად, დასამუშავებელი საბოლოო ფაილი გამოუსადეგარი გახდება.\nნამდვილად გსურთ გარდაქმნის შეწყვეტა?" +Remux.FileExists="მოცემული საბოლოო ფაილები უკვე არსებობს. გსურთ მათი ჩანაცვლება?" +Remux.ExitUnfinishedTitle="მიმდინარეობს გადაფუთვა" +Remux.ExitUnfinished="გადაფუთვა ჯერ არ დასრულებულა, ახლავე შეწყვეტის შედეგად, დასამუშავებელი საბოლოო ფაილი გამოუსადეგარი გახდება.\nნამდვილად გსურთ გადაფუთვის შეწყვეტა?" +Remux.HelpText="გადმოიტანეთ ფაილები გადასაფუთად ამ ფანჯარაში ან დაწკაპეთ „OBS ჩანაწერის“ ველის მარჯვენა კიდეზე, ფაილის ასარჩევად." UpdateAvailable="განახლება ხელმისაწვდომია" UpdateAvailable.Text="ხელმისაწვდომია ვერსია %1.%2.%3. დააწკაპეთ ჩამოსატვირთად" @@ -274,13 +313,16 @@ Basic.AuxDevice4="Mic/Aux 4" Basic.Scene="სცენა" Basic.DisplayCapture="ეკრანის გადაღება" -Basic.Main.PreviewConextMenu.Enable="შეთვალიერების შესაძლებლობა" +Basic.Main.PreviewConextMenu.Enable="შეთვალიერების ჩართვა" -ScaleFiltering="მასშტაბირების ფილტრი" +Basic.Main.Preview.Disable="შეთვალიერების გამორთვა" + +ScaleFiltering="ზომის შეცვლის ფილტრი" ScaleFiltering.Point="წერტილოვანი" ScaleFiltering.Bilinear="ორხაზოვანი" ScaleFiltering.Bicubic="ბიკუბური" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="სივრცე" Deinterlacing="Deinterlacing" Deinterlacing.Discard="გაუქმება" @@ -294,10 +336,10 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="ზედა ველიდან" Deinterlacing.BottomFieldFirst="ქვედა ველიდან" -VolControl.SliderUnmuted="ხმის სამართავი '%1': %2" -VolControl.SliderMuted="ხმის სამართავი '%1': %2 (ამჟამად დადუმებული)" +VolControl.SliderUnmuted="ხმის სამართავი „%1“: %2" +VolControl.SliderMuted="ხმის სამართავი „%1“: %2 (ამჟამად დადუმებული)" VolControl.Mute="'%1' დადუმება" -VolControl.Properties="'%1' პარამეტრები" +VolControl.Properties="„%1“ – პარამეტრები" Basic.Main.AddSceneDlg.Title="სცენის დამატება" Basic.Main.AddSceneDlg.Text="გთხოვთ, მიუთითოთ სცენის დასახელება" @@ -325,12 +367,12 @@ Basic.SourceSelect.CreateNew="ახლის შექმნა" Basic.SourceSelect.AddExisting="არსებულის დამატება" Basic.SourceSelect.AddVisible="წყაროს გამოჩენა" -Basic.PropertiesWindow="'%1' პარამეტრები" +Basic.PropertiesWindow="„%1“ – პარამეტრები" Basic.PropertiesWindow.AutoSelectFormat="%1 (თვითშერჩევა: %2)" Basic.PropertiesWindow.SelectColor="ფერის შერჩევა" Basic.PropertiesWindow.SelectFont="შრიფტის შერჩევა" Basic.PropertiesWindow.ConfirmTitle="პარამეტრები შეცვლილია" -Basic.PropertiesWindow.Confirm="ცვლილებები არაა დამახსოვრებული. გსურთ მათი შენახვა?" +Basic.PropertiesWindow.Confirm="ცვლილებები არაა დამახსოვრებული. გსურთ მათი შენახვა?" Basic.PropertiesWindow.NoProperties="პარამეტრები მიუწვდომელია" Basic.PropertiesWindow.AddFiles="ფაილების დამატება" Basic.PropertiesWindow.AddDir="საქაღალდის დამატება" @@ -344,7 +386,7 @@ Basic.PropertiesView.FPS.Simple="ჩვეულებრივი FPS-მნი Basic.PropertiesView.FPS.Rational="რაციონალურ რიცხვიანი FPS-მნიშვნელობები" Basic.PropertiesView.FPS.ValidFPSRanges="დაშვებული FPS-შუალედები:" -Basic.InteractionWindow="'%1'-თან ურთიერთქმედება" +Basic.InteractionWindow="თაგვით ურთიერთქმედება ფანჯარაში – „%1“" Basic.StatusBar.Reconnecting="კავშირი გაწყვეტილია. ხელახლა დაკავშირება %2 წამში (%1 მცდელობა)" Basic.StatusBar.AttemptingReconnect="ხელახლა დაკავშირება... (%1 მცდელობა)" @@ -358,12 +400,12 @@ Basic.Filters="ფილტრები" Basic.Filters.AsyncFilters="ხმოვანი/ვიდეო ფილტრები" Basic.Filters.AudioFilters="ხმოვანი ფილტრები" Basic.Filters.EffectFilters="დასამუშავებელი ფილტრები" -Basic.Filters.Title="'%1' ფილტრები" +Basic.Filters.Title="„%1“ – ფილტრები" Basic.Filters.AddFilter.Title="ფილტრის დასახელება" Basic.Filters.AddFilter.Text="გთხოვთ, მიუთითოთ ფილტრის დასახელება" Basic.TransformWindow="სცენის ელემენტის გარდაქმნა" -Basic.TransformWindow.Position="პოზიცია" +Basic.TransformWindow.Position="მდებარეობა" Basic.TransformWindow.Rotation="მობრუნება" Basic.TransformWindow.Size="ზომა" Basic.TransformWindow.Alignment="განლაგების გასწორება" @@ -400,70 +442,72 @@ Basic.Main.Connecting="უკავშირდება..." Basic.Main.StartRecording="ჩაწერის დაწყება" Basic.Main.StartReplayBuffer="გადახვევის ჩართვა" Basic.Main.StartStreaming="ნაკადის გაშვება" -Basic.Main.StopRecording="ნაკადის შეწყვეტა" +Basic.Main.StopRecording="ჩაწერის შეწყვეტა" Basic.Main.StoppingRecording="ჩაწერის შეწყვეტა..." Basic.Main.StopReplayBuffer="გადახვევის გამორთვა" Basic.Main.StoppingReplayBuffer="გადახვევა გამოირთვება..." Basic.Main.StopStreaming="ნაკადის შეწყვეტა" Basic.Main.StoppingStreaming="ნაკადი წყდება..." -Basic.Main.ForceStopStreaming="ნაკადი წყდება (დაყოვნება უქმდება)" +Basic.Main.ForceStopStreaming="ნაკადის შეწყვეტა (დაუყოვნებლივ)" Basic.Main.Group="ჯგუფი %1" Basic.Main.GroupItems="შერჩეულების დაჯგუფება" Basic.Main.Ungroup="განჯგუფება" -Basic.MainMenu.File="&ფაილი" -Basic.MainMenu.File.Export="&გატანა" -Basic.MainMenu.File.Import="&შემოტანა" -Basic.MainMenu.File.ShowRecordings="&ჩანაწერების ჩვენება" -Basic.MainMenu.File.Remux="ჩანაწერების ხელახლა მულტი&პლექსირება" -Basic.MainMenu.File.Settings="&პარამეტრები" +Basic.MainMenu.File="ფაილი (&F)" +Basic.MainMenu.File.Export="შენახვა (&E)" +Basic.MainMenu.File.Import="შემოტანა (&I)" +Basic.MainMenu.File.ShowRecordings="ჩანაწერების ჩვენება (&R)" +Basic.MainMenu.File.Remux="ჩანაწერების გადაფუთვა (&M)" +Basic.MainMenu.File.Settings="პარამეტრები (&S)" Basic.MainMenu.File.ShowSettingsFolder="პარამეტრების საქაღალდის ჩვენება" Basic.MainMenu.File.ShowProfileFolder="პროფილის საქაღალდის ჩვენება" -Basic.MainMenu.AlwaysOnTop="&ყოველთვის წინა პლანზე" -Basic.MainMenu.File.Exit="&გამოსვლა" +Basic.MainMenu.AlwaysOnTop="ყოველთვის წინა პლანზე (&A)" +Basic.MainMenu.File.Exit="გამოსვლა (&X)" -Basic.MainMenu.Edit="&ჩასწორება" -Basic.MainMenu.Edit.Undo="&დაბრუნება" -Basic.MainMenu.Edit.Redo="&კვლავ შესრულება" -Basic.MainMenu.Edit.UndoAction="&დაბრუნება $1" -Basic.MainMenu.Edit.RedoAction="&კვლავ შესრულება $1" -Basic.MainMenu.Edit.LockPreview="შეთვალიერების &ჩაკეტვა" -Basic.MainMenu.Edit.Scale="შეთვალიერების &ზომის შეცვლა" +Basic.MainMenu.Edit="ჩასწორება (&E)" +Basic.MainMenu.Edit.Undo="დაბრუნება (&U)" +Basic.MainMenu.Edit.Redo="კვლავ შესრულება (&R)" +Basic.MainMenu.Edit.UndoAction="დაბრუნება $1 (&U)" +Basic.MainMenu.Edit.RedoAction="კვლავ შესრულება $1 (&R)" +Basic.MainMenu.Edit.LockPreview="შეთვალიერების ჩაკეტვა (&L)" +Basic.MainMenu.Edit.Scale="შეთვალიერების ზომის შეცვლა (&S)" Basic.MainMenu.Edit.Scale.Window="ფანჯრის ზომამდე" Basic.MainMenu.Edit.Scale.Canvas="ფონის ზომამდე (%1x%2)" -Basic.MainMenu.Edit.Scale.Output="გამომავალი ვიდეოს ზომამდე (%1x%2)" -Basic.MainMenu.Edit.Transform="&გარდაქმნა" -Basic.MainMenu.Edit.Transform.EditTransform="გარდაქმნის &ჩასწორება..." -Basic.MainMenu.Edit.Transform.CopyTransform="გარდაქმნის დაკოპირება" +Basic.MainMenu.Edit.Scale.Output="გამოტანა (%1x%2)" +Basic.MainMenu.Edit.Transform="გარდაქმნა (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="გარდაქმნის ჩასწორება... (&E)" +Basic.MainMenu.Edit.Transform.CopyTransform="გარდაქმნის ასლი" Basic.MainMenu.Edit.Transform.PasteTransform="გარდაქმნის ჩასმა" -Basic.MainMenu.Edit.Transform.ResetTransform="&გარდაქმნის გაუქმება" +Basic.MainMenu.Edit.Transform.ResetTransform="გარდაქმნის გაუქმება (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="მობრუნება 90 გრადუსით საათის ისრის მიმართ." Basic.MainMenu.Edit.Transform.Rotate90CCW="მობრუნება 90 გრადუსით საათის ისრის საწ. მიმართ." Basic.MainMenu.Edit.Transform.Rotate180="მობრუნება 180 გრადუსით" -Basic.MainMenu.Edit.Transform.FlipHorizontal="&თარაზულად შეტრიალება" -Basic.MainMenu.Edit.Transform.FlipVertical="&შვეულად შეტრიალება" -Basic.MainMenu.Edit.Transform.FitToScreen="ეკრანის ზომაზე &მორგება" -Basic.MainMenu.Edit.Transform.StretchToScreen="ეკრანის ზომაზე &გაწელვა" -Basic.MainMenu.Edit.Transform.CenterToScreen="ეკრანის &შუაში განთავსება" -Basic.MainMenu.Edit.Order="&დალაგება" -Basic.MainMenu.Edit.Order.MoveUp="&ზემოთ აწევა" -Basic.MainMenu.Edit.Order.MoveDown="&ქვემოთ ჩამოწევა" -Basic.MainMenu.Edit.Order.MoveToTop="&თავში გადატანა" -Basic.MainMenu.Edit.Order.MoveToBottom="&ბოლოში გადატანა" -Basic.MainMenu.Edit.AdvAudio="ხმის &გაფართოებული პარამეტრები" +Basic.MainMenu.Edit.Transform.FlipHorizontal="თარაზულად შეტრიალება (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="შვეულად შეტრიალება (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="ეკრანის ზომაზე მორგება (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="ეკრანის ზომაზე გაწელვა (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="ეკრანის შუაში განთავსება (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="შუაში შვეულად" +Basic.MainMenu.Edit.Transform.HorizontalCenter="შუაში თარაზულად" +Basic.MainMenu.Edit.Order="დალაგება (&O)" +Basic.MainMenu.Edit.Order.MoveUp="ზემოთ აწევა (&U)" +Basic.MainMenu.Edit.Order.MoveDown="ქვემოთ ჩამოწევა (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="თავში გადატანა (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="ბოლოში გადატანა (&B)" +Basic.MainMenu.Edit.AdvAudio="ხმის გაფართოებული პარამეტრები (&A)" -Basic.MainMenu.View="&ხედი" -Basic.MainMenu.View.Toolbars="&ხელსაწყოები" +Basic.MainMenu.View="ხედი (&V)" +Basic.MainMenu.View.Toolbars="ხელსაწყოები (&T)" Basic.MainMenu.View.Docks="იერსახის ნაწილები" -Basic.MainMenu.View.Docks.ResetUI="UI-ს გადატვირთვა" -Basic.MainMenu.View.Docks.LockUI="UI-ს ჩაკეტვა" -Basic.MainMenu.View.Toolbars.Listboxes="&სიები" -Basic.MainMenu.View.SceneTransitions="ს&ცენებს შორის გადასვლები" -Basic.MainMenu.View.StatusBar="&მდგომარეობის ზოლი" +Basic.MainMenu.View.Docks.ResetUI="იერსახის აღდგენა" +Basic.MainMenu.View.Docks.LockUI="იერსახის ჩაკეტვა" +Basic.MainMenu.View.Toolbars.Listboxes="სიები (&L)" +Basic.MainMenu.View.SceneTransitions="სცენებს შორის გადასვლები (&C)" +Basic.MainMenu.View.StatusBar="მდგომარეობის ზოლი (&S)" Basic.MainMenu.View.Fullscreen.Interface="სრულეკრანიანი" -Basic.MainMenu.SceneCollection="&სცენის კრებული" -Basic.MainMenu.Profile="&პროფილი" +Basic.MainMenu.SceneCollection="სცენის კრებული (&S)" +Basic.MainMenu.Profile="პროფილი (&P)" Basic.MainMenu.Profile.Import="პროფილის შემოტანა" Basic.MainMenu.Profile.Export="პროფილის შენახვა" Basic.MainMenu.SceneCollection.Import="სცენის კრებულის შემოტანა" @@ -471,39 +515,40 @@ Basic.MainMenu.SceneCollection.Export="სცენის კრებული Basic.MainMenu.Profile.Exists="ასეთი პროფილი უკვე არსებობს" Basic.MainMenu.SceneCollection.Exists="ამ სცენის კრებული უკვე არსებობს" -Basic.MainMenu.Tools="&ხელსაწყოები" +Basic.MainMenu.Tools="ხელსაწყოები (&T)" -Basic.MainMenu.Help="&დახმარება" -Basic.MainMenu.Help.HelpPortal="დახმარების &გვერდი" -Basic.MainMenu.Help.Website="ეწვიეთ &ვებსაიტს" +Basic.MainMenu.Help="დახმარება (&H)" +Basic.MainMenu.Help.HelpPortal="დახმარების გვერდი (&P)" +Basic.MainMenu.Help.Website="ეწვიეთ ვებსაიტს (&W)" Basic.MainMenu.Help.Discord="&Discord სერვერზე შესვლა" -Basic.MainMenu.Help.Logs="&აღრიცხვის ფაილები" -Basic.MainMenu.Help.Logs.ShowLogs="აღრიცხვის ფაილების &ჩვენება" -Basic.MainMenu.Help.Logs.UploadCurrentLog="&მიმდინარე აღრიცხვის ფაილის ატვირთვა" -Basic.MainMenu.Help.Logs.UploadLastLog="&ბოლო აღრიცხვის ფაილის ატვირთვა" -Basic.MainMenu.Help.Logs.ViewCurrentLog="მიმდინარე აღრიცხვის ფაილის &ნახვა" +Basic.MainMenu.Help.Logs="აღრიცხვის ფაილები (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="აღრიცხვის ფაილების ჩვენება (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="მიმდინარე აღრიცხვის ფაილის ატვირთვა (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="ბოლო აღრიცხვის ფაილის ატვირთვა (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="მიმდინარე აღრიცხვის ფაილის ნახვა (&V)" Basic.MainMenu.Help.CheckForUpdates="განახლებებზე შემოწმება" -Basic.MainMenu.Help.CrashLogs="ავარიული დახურვების &მოხსენებები" -Basic.MainMenu.Help.CrashLogs.ShowLogs="ავარიული დახურვების მოხსენებების &ჩვენება" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="&ბოლო მოხსენების ატვირთვა" +Basic.MainMenu.Help.CrashLogs="უეცარი გათიშვების მოხსენებები (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="უეცარი გათიშვების მოხსენებების ჩვენება (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="ბოლო მოხსენების ატვირთვა (&L)" +Basic.MainMenu.Help.About="შესახებ (&A)" Basic.Settings.ProgramRestart="ამ ცვლილებების ასახვისთვის, საჭიროა პროგრამის ხელახლა გაშვება." Basic.Settings.ConfirmTitle="ცვლილებების დადასტურება" -Basic.Settings.Confirm="ცვლილებები არაა დამახსოვრებული. გსურთ მათი შენახვა?" +Basic.Settings.Confirm="ცვლილებები არაა დამახსოვრებული. გსურთ მათი შენახვა?" Basic.Settings.General="მთავარი" -Basic.Settings.General.Theme="თემა" +Basic.Settings.General.Theme="იერსახე" Basic.Settings.General.Language="ენა" Basic.Settings.General.EnableAutoUpdates="განახლებებზე შემოწმება ჩართვისას" Basic.Settings.General.OpenStatsOnStartup="სტატისტიკის ფანჯრის გახსნა ჩართვისას" Basic.Settings.General.WarnBeforeStartingStream="დადასტურების ფანჯრის ჩვენება ნაკადის გაშვებისას" Basic.Settings.General.WarnBeforeStoppingStream="დადასტურების ფანჯრის ჩვენება ნაკადის შეწყვეტისას" -Basic.Settings.General.Projectors="ჩვენებები" +Basic.Settings.General.Projectors="გამოსახულების ჩვენება" Basic.Settings.General.HideProjectorCursor="მაჩვენებლის დამალვა ჩვენებებზე" -Basic.Settings.General.ProjectorAlwaysOnTop="ჩვენებების სხვა ფანჯრების ზემოთ დატოვება" +Basic.Settings.General.ProjectorAlwaysOnTop="მიღებული გამოსახულებების სხვა ფანჯრების ზემოთ დატოვება" Basic.Settings.General.Snapping="წყაროს ჩარჩოს მიზიდვა განთავსებისას" Basic.Settings.General.ScreenSnapping="წყაროს ჩარჩოს მიზიდვა ეკრანის კიდესთან" -Basic.Settings.General.CenterSnapping="წყაროს ჩარჩოს მიზიდვა შუაშია, თარაზულად და შვეულად" +Basic.Settings.General.CenterSnapping="წყაროს ჩარჩოს შუაწერტილისკენ მიზიდვა, თარაზულად და შვეულად" Basic.Settings.General.SourceSnapping="წყაროს ჩარჩოს სხვა წყაროს ჩარჩოზე მიზიდვა" Basic.Settings.General.SnapDistance="მიზიდვის ძალა" Basic.Settings.General.RecordWhenStreaming="პირდაპირი ეთერის ავტომატური ჩაწერა" @@ -511,11 +556,16 @@ Basic.Settings.General.KeepRecordingWhenStreamStops="ჩაწერის გ Basic.Settings.General.ReplayBufferWhileStreaming="გადახვევის ჩართვა ავტომატურად ნაკადის გაშვებისას" Basic.Settings.General.KeepReplayBufferStreamStops="გადახვევის შენარჩუნება, ნაკადის შეწყვეტისას" Basic.Settings.General.SysTray="სისტემის არე" -Basic.Settings.General.SysTrayWhenStarted="სისტემის არეში ჩაკეცვა დაწყებისას" +Basic.Settings.General.SysTrayWhenStarted="სისტემის არეში ჩაკეცვა გაშვებისთანავე" Basic.Settings.General.SystemTrayHideMinimize="ყოველთვის სისტემის არეში ჩაკეცვა, ამოცანათა ზოლის ნაცვლად" -Basic.Settings.General.SaveProjectors="ჩვენებების დამახსოვრება გასვლისას" +Basic.Settings.General.SaveProjectors="ჩვენების პარამეტრების დამახსოვრება გასვლისას" +Basic.Settings.General.Preview="შეთვალიერება" +Basic.Settings.General.OverflowHidden="ზედმეტი არეების დამალვა" +Basic.Settings.General.OverflowAlwaysVisible="ზედმეტი არეების ყოველთვის გამოჩენა" +Basic.Settings.General.OverflowSelectionHidden="ზედმეტი არეების გამოჩენა, უხილავი წყაროს შემთხვევაშიც" Basic.Settings.General.SwitchOnDoubleClick="სცენაზე გადასვლა ორჯერ დაწკაპებისას" Basic.Settings.General.StudioPortraitLayout="შვეული განლაგების ჩართვა" +Basic.Settings.General.TogglePreviewProgramLabels="შეთვალიერების/პროგრამის წარწერების ჩვენება" Basic.Settings.General.Multiview="მრავალხედიანი ჩვენება" Basic.Settings.General.Multiview.MouseSwitch="სცენებს შორის გადართვა დაწკაპებით" Basic.Settings.General.Multiview.DrawSourceNames="სცენის სახელების ჩვენება" @@ -529,22 +579,26 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="თარაზ Basic.Settings.Stream="ნაკადი" Basic.Settings.Stream.StreamType="ნაკადის სახეობა" +Basic.Settings.Stream.Custom.UseAuthentication="ანგარიშზე შესვლით" +Basic.Settings.Stream.Custom.Username="მომხმარებლის სახელი" +Basic.Settings.Stream.Custom.Password="პაროლი" +Basic.Settings.Stream.BandwidthTestMode="ქსელის გამტარუნარიანობის შემოწმების რეჟიმი" -Basic.Settings.Output="გამომავალი სიგნალი" +Basic.Settings.Output="გამოტანა" Basic.Settings.Output.Format="ჩაწერის ფორმატი" Basic.Settings.Output.Encoder="დამშიფრავი" Basic.Settings.Output.SelectDirectory="საქაღალდის არჩევა ჩანაწერისთვის" Basic.Settings.Output.SelectFile="ფაილის არჩევა ჩანაწერისთვის" Basic.Settings.Output.EnforceBitrate="ნაკადის გაშვების მომსახურების ბიტური სიხშირის ზღვრების დადგენა" -Basic.Settings.Output.Mode="გამომავალი სიგნალის რეჟიმი" +Basic.Settings.Output.Mode="გამოტანის რეჟიმი" Basic.Settings.Output.Mode.Simple="მარტივი" Basic.Settings.Output.Mode.Adv="გაფართოებული" -Basic.Settings.Output.Mode.FFmpeg="FFmpeg გამომავალი სიგნალი" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg-გამოტანა" Basic.Settings.Output.UseReplayBuffer="გადახვევის შესაძლებლობა" Basic.Settings.Output.ReplayBuffer.SecondsMax="გადახვევის დასაშვები დრო (წამი)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="მეხსიერების დასაშვები მოცულობა (მეგაბაიტებში)" Basic.Settings.Output.ReplayBuffer.Estimate="მეხსიერების მიახლოებითი მოხმარება: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="შეუძლებელია მეხსიერების მიახლოებითი მოხმარების დადგენა. გთხოვთ, მიუთითოთ მეხსიერების დასაშვები ზღვარი." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="შეუძლებელია მეხსიერების მიახლოებითი მოხმარების დადგენა. გთხოვთ, მიუთითოთ მეხსიერების დასაშვები ზღვარი." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(შენიშვნა: დარწმუნდით, რომ გადახვევისთვის სწრაფი ღილაკები დაყენებულია შესაბამის განყოფილებაში)" Basic.Settings.Output.ReplayBuffer.Prefix="გადასახვევი მასალის შესანახი ფაილის თავსართი" Basic.Settings.Output.ReplayBuffer.Suffix="ბოლოსართი" @@ -560,7 +614,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="გაფრთხილება: Basic.Settings.Output.Simple.Warn.Lossless="გაფრთხილება: უდანაკარგო ხარისხის მითითების შემთხვევაში, შეიქმნება მეტისმეტად დიდი ზომის ფაილები! უდანაკარგო ხარისხის ვიდეოს თითოეული წუთის მოცულობამ დისკზე, შესაძლოა 7 გიგაბაიტს გადააჭარბოს, მაღალი გარჩევადობისა და კადრის სიხშირის პირობებში. ხანგრძლივი ჩანაწერებისთვის, უდანაკარგოს არჩევა არაა მიზანშეწონილი, თუ არ გაქვთ საკმარისად დიდი მოცულობის თავისუფალი ადგილი დისკზე." Basic.Settings.Output.Simple.Warn.Lossless.Msg="ნამდვილად გსურთ უდანაკარგო ხარისხის მითითება?" Basic.Settings.Output.Simple.Warn.Lossless.Title="გაფრთხილება, უდანაკარგო ხარისხის შესახებ!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="გაფრთხილება: ერთდროულად რამდენიმე სხვადასხვა QSV დამშიფრავის გამოყენება ნაკადის გაშვებისას და ჩაწერისას, შეუძლებელია. თუ გსურთ ნაკადის გაშვება და ჩაწერა ერთდროულად, გთხოვთ შეცვალოთ ან ჩაწერის დამშიფრავი, ან ნაკადის დამშიფრავი." Basic.Settings.Output.Simple.Encoder.Software="პროგრამული (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="აპარატურული (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="აპარატურული (AMD)" @@ -572,12 +625,12 @@ Basic.Settings.Output.Reconnect="ხელახლა დაკავშირ Basic.Settings.Output.RetryDelay="გამეორების დაყოვნება (წამი)" Basic.Settings.Output.MaxRetries="გამეორების დასაშვები რაოდენობა" Basic.Settings.Output.Advanced="დამშიფრავის გაფართოებული პარამეტრების ჩართვა" -Basic.Settings.Output.EncoderPreset="დაშიფვრის მზა პარამეტრები (მაღალი = ნაკლები CPU-დატვირთვა)" +Basic.Settings.Output.EncoderPreset="დამშიფრავის მზა პარამეტრები" Basic.Settings.Output.CustomEncoderSettings="დამშიფრავის პარამეტრების მითითება" -Basic.Settings.Output.CustomMuxerSettings="მულტიპლექსორის მითითებული პარამეტრები" +Basic.Settings.Output.CustomMuxerSettings="შემფუთავის პარამეტრების მითითება" Basic.Settings.Output.NoSpaceFileName="ფაილის სახელის შექმნა, გამოტოვებული ადგილების გარეშე" -Basic.Settings.Output.Adv.Rescale="გამომავალი ვიდეოს ზომების შეცვლა" +Basic.Settings.Output.Adv.Rescale="გამოტანის ზომების შეცვლა" Basic.Settings.Output.Adv.AudioTrack="ხმოვანი ბილიკი" Basic.Settings.Output.Adv.Streaming="ნაკადი" Basic.Settings.Output.Adv.ApplyServiceSettings="ნაკადის გაშვების მომსახურების პარამეტრების გამოყენება" @@ -589,14 +642,14 @@ Basic.Settings.Output.Adv.Audio.Track5="ბილიკი 5" Basic.Settings.Output.Adv.Audio.Track6="ბილიკი 6" Basic.Settings.Output.Adv.Recording="ჩაწერა" -Basic.Settings.Output.Adv.Recording.Type="ტიპი" -Basic.Settings.Output.Adv.Recording.Type.Standard="სტანდარტული" -Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="მითითებული გამომავალი სიგნალი (FFmpeg)" +Basic.Settings.Output.Adv.Recording.Type="სახეობა" +Basic.Settings.Output.Adv.Recording.Type.Standard="ჩვეულებრივი" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="მითითებული გამოტანა (FFmpeg)" Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(გაშვებული ნაკადის დამშიფრავის გამოყენება)" Basic.Settings.Output.Adv.Recording.Filename="ფაილის დასახელების ფორმატი" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="არსებულ ფაილზე გადაწერა" -Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg გამომავალი სიგნალის სახე" -Basic.Settings.Output.Adv.FFmpeg.Type.URL="მითითებულ URL ბულზე" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg-გამოტანის სახეობა" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="მითითებულ URL-ბმულზე" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="ფაილში" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="ჩაწერის ცნობილი ფორმატები" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="ყველა ფაილი" @@ -613,29 +666,29 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoder="ვიდეოს დამშიფ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="ვიდეოს დამშიფრავის პარამეტრები (თუ არის)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="ხმის დამშიფრავი" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="ხმის დამშიფრავის პარამეტრები (თუ არის)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="მულტიპლექსორის პარამეტრები (თუ არის)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="შემფუთავის პარამეტრები (თუ არის)" Basic.Settings.Output.Adv.FFmpeg.GOPSize="საკვანძო კადრებს შორის შუალედი (კადრები)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="ყველა კოდეკის ჩვენება (მათ შორის არათავსებადებისაც)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY წელი, ოთხი ციფრი\n%YY წელი, ბოლო ორის ციფრი(00-99)\n%MM თვე, ათობითი რიცხვის სახით (01-12)\n%DD თვის რიცხვი, წინ ნულით (01-31)\n%hh საათი, 24-საათიანი ფორმატით (00-23)\n%mm წუთი(00-59)\n%ss წამი(00-61)\n%% A % ნიშანი\n%a კვირის დღე შემოკლებულად\n%A კვირის დღის სრული დასახელება\n%b თვე შემოკლებულად\n%B თვის სრული დასახელება\n%d თვის რიცხვი, წინ ნულით (01-31)\n%H საათი, 24-საათიანი ფორმატით (00-23)\n%I საათი, 12-საათიანი ფორმატით (01-12)\n%m თვე, ათობითი რიცხვის სახით (01-12)\n%M წუთი (00-59)\n%p AM ან PM აღნიშვნა\n%S წამი (00-61)\n%y წელი, ბოლო ორი ციფრი (00-99)\n%Y წელი\n%z ISO 8601 სხვაობა UTC დროსთან ან სასაათე სარტყელთან\n სრული ან შემოკლებული დასახელება\n%Z სასაათე სარტყელი ან მისი შემოკლებული დასახელება\n" +FilenameFormatting.TT="%CCYY წელიწადი, ოთხი ციფრი\n%YY წელიწადი, ბოლო ორი ციფრი (00-99)\n%MM თვე, ათობითი რიცხვის სახით (01-12)\n%DD თვის რიცხვი, წინ ნულით (01-31)\n%hh საათი, 24-საათიანი ფორმატით (00-23)\n%mm წუთი (00-59)\n%ss წამი(00-61)\n%% % პროცენტის ნიშანი\n%a კვირის დღე შემოკლებულად\n%A კვირის დღის სრული დასახელება\n%b თვე შემოკლებულად\n%B თვის სრული დასახელება\n%d თვის რიცხვი, წინ ნულით (01-31)\n%H საათი, 24-საათიანი ფორმატით (00-23)\n%I საათი, 12-საათიანი ფორმატით (01-12)\n%m თვე, ათობითი რიცხვის სახით (01-12)\n%M წუთი (00-59)\n%p AM ან PM აღნიშვნა\n%S წამი (00-61)\n%y წელიწადი, ბოლო ორი ციფრი (00-99)\n%Y წელიწადი\n%z ISO 8601 სხვაობა UTC დროსთან ან სასაათე სარტყელთან\n სრული ან შემოკლებული დასახელება\n%Z სასაათე სარტყელი ან მისი შემოკლებული დასახელება\n" Basic.Settings.Video="ვიდეო" Basic.Settings.Video.Adapter="ვიდეოდაფა" Basic.Settings.Video.BaseResolution="ეკრანის (ფონის) ძირითადი გაფართოება" -Basic.Settings.Video.ScaledResolution="გამომავალი ვიდეოს (მასშტაბირებულის) გაფართოება" -Basic.Settings.Video.DownscaleFilter="მასშტაბირების ფილტრი" +Basic.Settings.Video.ScaledResolution="გამოტანის (ზომაშეცვლილის) გაფართოება" +Basic.Settings.Video.DownscaleFilter="ზომის შემცირების ფილტრი" Basic.Settings.Video.DisableAeroWindows="Aero გაფორმების გათიშვა (მხოლოდ Windows-ზე)" Basic.Settings.Video.FPS="FPS" -Basic.Settings.Video.FPSCommon="საერთო FPS-მნიშვნელობები" +Basic.Settings.Video.FPSCommon="ჩვეულებრივი FPS-მნიშვნელობები" Basic.Settings.Video.FPSInteger="მთელრიცხვიანი FPS-მნიშვნელობები" Basic.Settings.Video.FPSFraction="წილადიანი FPS-მნიშვნელობები" Basic.Settings.Video.Numerator="მრიცხველი" Basic.Settings.Video.Denominator="მნიშვნელი" Basic.Settings.Video.Renderer="დამმუშავებელი" -Basic.Settings.Video.InvalidResolution="გაფართოების არასწორი მნიშვნელობა. უნდა იყოს [width]x[height] (მაგ. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="ვიდეო ამჟამად გაშვებულია. გთხოვთ, გამორთოთ ყველა გამომავალი სიგნალი, ვიდეოს პარამეტრების ჩასასწორებლად." +Basic.Settings.Video.InvalidResolution="გაფართოების არასწორი მნიშვნელობა. უნდა იყოს [width]x[height] (მაგ. 1920x1080)" +Basic.Settings.Video.CurrentlyActive="მიმდინარეობს ვიდეოს გამოტანა. გთხოვთ, გათიშოთ ყველა გამოტანილი სიგნალი, ვიდეოს პარამეტრების ჩასასწორებლად." Basic.Settings.Video.DisableAero="Aero გაფორმების გათიშვა" Basic.Settings.Video.DownscaleFilter.Bilinear="ორხაზოვანი (უსწრაფესი, მაგრამ ბუნდოვანი მასშტაბირება)" @@ -644,8 +697,9 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (მკვეთრი მ Basic.Settings.Audio="ხმა" Basic.Settings.Audio.SampleRate="სიხშირე" -Basic.Settings.Audio.Channels="არხები" -Basic.Settings.Audio.MeterDecayRate="ხმის ზოლის დაშვების სიჩქარე" +Basic.Settings.Audio.Channels="არხი" +Basic.Settings.Audio.Meters="საზომები" +Basic.Settings.Audio.MeterDecayRate="მილევის სიჩქარე" Basic.Settings.Audio.MeterDecayRate.Fast="სწრაფი" Basic.Settings.Audio.MeterDecayRate.Medium="საშუალო (I სახის PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="ნელი (II სახის PPM)" @@ -653,35 +707,38 @@ Basic.Settings.Audio.PeakMeterType="ხმის სიმაღლის მზ Basic.Settings.Audio.PeakMeterType.SamplePeak="უბრალო" Basic.Settings.Audio.PeakMeterType.TruePeak="ზუსტი (პროცესორის მაღალი მოხმარებით)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ყურადღება: ჩართულია მოცულობითი ხმა." -Basic.Settings.Audio.MultichannelWarning="ნაკადის გაშვებისას, გადაამოწმეთ მომსახურების მომწოდებელთან, არის თუ არა მხარდაჭერილი ორივე, მოცულობითი ხმოვანი სიგნალის მიღებაც და მოსმენაც. მაგალითად Twitch, Facebook 360 Live, Mixer RTMP, Smashcast შემთხვევებში, მოცულობითი ხმოვანი სიგნალი, სრულადაა მხარდაჭერილი. მიუხედავად იმისა, რომ Facebook Live და YouTube Live, ორივე იღებს მოცულობით ხმოვან სიგნალს, Facebook Live გარდაქმნის მას სტერეო-სიგნალად, ხოლო YouTube Live უშვებს მხოლოდ ორი არხით.\n\nOBS-ის ხმოვანი ფილტრები თავსებადია მოცულობით ხმოვან სიგნალთან, მაგრამ VST მოდულის მხარდაჭერა, შესაძლოა არ იყოს უზრუნველყოფილი." +Basic.Settings.Audio.MultichannelWarning="ნაკადის გაშვებისას გადაამოწმეთ, მომსახურების მომწოდებელი, იძლევა თუ არა მოცულობითი ხმოვანი სიგნალის როგორც მიღების, ასევე მოსმენის შესაძლებლობას. მაგალითად მომსახურებებზე, როგორიცაა Twitch, Facebook 360 Live, Mixer RTMP და Smashcast, სრულადაა მხარდაჭერილი მოცულობითი ხმოვანი სიგნალი. ხოლო Facebook Live და YouTube Live, მიუხედავად იმისა, რომ ორივე იღებს მოცულობით ხმოვან სიგნალს, Facebook Live გარდაქმნის მას სტერეო-სიგნალად, ხოლო YouTube Live უშვებს მხოლოდ ორი არხით.\n\nOBS-ის ხმოვანი ფილტრები თავსებადია მოცულობით ხმოვან სიგნალთან, მაგრამ VST-მოდულის მხარდაჭერა, შესაძლოა არ იყოს უზრუნველყოფილი." Basic.Settings.Audio.MultichannelWarning.Title="ჩაირთოს მოცულობითი ხმოვანი სიგნალი?" Basic.Settings.Audio.MultichannelWarning.Confirm="ნამდვილად გსურთ, ჩართოთ მოცულობითი ხმოვანი სიგნალი?" +Basic.Settings.Audio.Devices="მოწყობილობები" Basic.Settings.Audio.DesktopDevice="ხმის მოწყობილობა" Basic.Settings.Audio.DesktopDevice2="ხმის მოწყობილობა 2" -Basic.Settings.Audio.AuxDevice="მიკროფონი/ხმის დამატებითი მოწყობილობა" -Basic.Settings.Audio.AuxDevice2="მიკროფონი/ხმის დამატებითი მოწყობილობა 2" -Basic.Settings.Audio.AuxDevice3="მიკროფონი/ხმის დამატებითი მოწყობილობა 3" +Basic.Settings.Audio.AuxDevice="მიკროფონი/დამატებითი მოწყობილობა" +Basic.Settings.Audio.AuxDevice2="მიკროფონი/დამატებითი მოწყობილობა 2" +Basic.Settings.Audio.AuxDevice3="მიკროფონი/დამატებითი მოწყობილობა 3" +Basic.Settings.Audio.AuxDevice4="მიკროფონი/დამატებითი მოწყობილობა 4" Basic.Settings.Audio.EnablePushToMute="დაჭერით დადუმების ჩართვა" Basic.Settings.Audio.PushToMuteDelay="დაჭერით დადუმების დაყოვნება" Basic.Settings.Audio.EnablePushToTalk="დაჭერით საუბრის ჩართვა" Basic.Settings.Audio.PushToTalkDelay="დაჭერით საუბრის დაყოვნება" Basic.Settings.Audio.UnknownAudioDevice="[მოწყობილობა არაა დაკავშირებული ან მიუწვდომელია]" +Basic.Settings.Audio.Disabled="გამორთული" -Basic.Settings.Advanced="დამატებითი" +Basic.Settings.Advanced="დამატებით" Basic.Settings.Advanced.General.ProcessPriority="უპირატესობა დამუშავებისას" Basic.Settings.Advanced.General.ProcessPriority.High="მაღალი" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="საშუალოზე მაღალი" Basic.Settings.Advanced.General.ProcessPriority.Normal="საშუალო" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="საშუალოზე დაბალი" Basic.Settings.Advanced.General.ProcessPriority.Idle="უმოქმედო" -Basic.Settings.Advanced.FormatWarning="გაფრთხილება: ფერთა ფორმატები, გარდა NV12-ისა, ძირითადად განკუთვნილია ჩაწერისთვის და არა ნაკადის გაშვებისთვის. ნაკადის გაშვებისას, ფერთა ფორმატის გარდაქმნებმა შესაძლოა გამოიწვიოს პროცესორის მეტად დატვირთვა." +Basic.Settings.Advanced.FormatWarning="გაფრთხილება: ფერთა ფორმატები, გარდა NV12-ისა, ძირითადად განკუთვნილია ჩაწერისთვის და არა ნაკადის გაშვებისთვის. ნაკადის გაშვებისას, ფერთა ფორმატის გარდაქმნებმა შესაძლოა გამოიწვიოს პროცესორის მეტად დატვირთვა." Basic.Settings.Advanced.Audio.BufferingTime="ხმის ბუფერის დრო" Basic.Settings.Advanced.Video.ColorFormat="ფერთა ფორმატი" -Basic.Settings.Advanced.Video.ColorSpace="YUV ფერთა სისტემა" -Basic.Settings.Advanced.Video.ColorRange="YUV ფერთა გამა" +Basic.Settings.Advanced.Video.ColorSpace="ფერთა სივრცე" +Basic.Settings.Advanced.Video.ColorRange="ფერთა გამა" Basic.Settings.Advanced.Video.ColorRange.Partial="ნაწილობრივი" Basic.Settings.Advanced.Video.ColorRange.Full="სრული" -Basic.Settings.Advanced.Audio.MonitoringDevice="ხმის მოსასმენი მოწყობილობა" +Basic.Settings.Advanced.Audio.MonitoringDevice="მოსასმენი მოწყობილობა" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="ნაგულისხმევი" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows-ის მიერ ხმის დონის დადაბლების არიდება" Basic.Settings.Advanced.StreamDelay="ნაკადის დაყოვნება" @@ -689,25 +746,28 @@ Basic.Settings.Advanced.StreamDelay.Duration="ხანგრძლივობ Basic.Settings.Advanced.StreamDelay.Preserve="მოსაჭრელი წერტილის მომარაგება (დაყოვნების გაზრდა) ხელახლა დაკავშირებისას" Basic.Settings.Advanced.StreamDelay.MemoryUsage="მეხსიერების მიახლოებითი მოხმარება: %1 MB" Basic.Settings.Advanced.Network="ქსელი" -Basic.Settings.Advanced.Network.BindToIP="დაკავშირება IP მისამართზე" -Basic.Settings.Advanced.Network.EnableNewSocketLoop="ახალი ქსელის კოდის ჩართვა" +Basic.Settings.Advanced.Network.BindToIP="დაკავშირება IP-მისამართზე" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="ქსელის ახალი კოდის ჩართვა" Basic.Settings.Advanced.Network.EnableLowLatencyMode="დაყოვნების შემცირება" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="სწრაფი ღილაკების გათიშვა, მთავარ ფანჯარაზე გადასვლისას" +Basic.Settings.Advanced.AutoRemux="თვითშეფუთვა mp4-ფაილად" +Basic.Settings.Advanced.AutoRemux.MP4="(ჩაწერა mkv-ფაილად)" Basic.AdvAudio="ხმის გაფართოებული პარამეტრები" Basic.AdvAudio.Name="სახელი" -Basic.AdvAudio.Volume="ხმის სიმაღლე (%)" +Basic.AdvAudio.Volume="ხმის დონე" Basic.AdvAudio.Mono="ერთ არხში გაერთიანება" -Basic.AdvAudio.Panning="წონასწორობა" +Basic.AdvAudio.Balance="წონასწორობა" Basic.AdvAudio.SyncOffset="სინქრონიზაციის გასწორება (მწ)" Basic.AdvAudio.Monitoring="ხმის მოსმენა" Basic.AdvAudio.Monitoring.None="მოსმენის გარეშე" -Basic.AdvAudio.Monitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამომავალი სიგნალით)" +Basic.AdvAudio.Monitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამოტანა)" Basic.AdvAudio.Monitoring.Both="მოსმენა და გამოტანა" Basic.AdvAudio.AudioTracks="ბილიკები" -Basic.Settings.Hotkeys="სწრაფი ღილაკები" -Basic.Settings.Hotkeys.Pair="'%1' - ღილაკების ერთობლიობა იმუშავებს გადამრთველის სახით" +Basic.Settings.Hotkeys="ღილაკები" +Basic.Settings.Hotkeys.Pair="გადამრთველის სახით იმუშავებს ღილაკთან „%1“" +Basic.Settings.Hotkeys.Filter="გამორჩევა" Basic.Hotkeys.SelectScene="სცენაზე გადასვლა" @@ -751,28 +811,44 @@ Hotkeys.AppleKeypadSubtract="- (კლავიატურაზე)" Hotkeys.AppleKeypadDecimal=". (კლავიატურაზე)" Hotkeys.AppleKeypadEqual="= (კლავიატურაზე)" Hotkeys.MouseButton="თაგვი %1" +Hotkeys.Escape="Esc" Mute="დადუმება" Unmute="ხმის ჩართვა" Push-to-mute="დაჭერისას დადუმება" Push-to-talk="დაჭერისას საუბარი" -SceneItemShow="'%1'-ის გამოჩენა" -SceneItemHide="'%1'-ის დამალვა" +SceneItemShow="გამოჩნდეს „%1“" +SceneItemHide="დაიმალოს „%1“" OutputWarnings.NoTracksSelected="უნდა მიუთითოთ ერთი ხმოვანი ბილიკი მაინც" OutputWarnings.MultiTrackRecording="გაფრთხილება: ცალკეული სახის ფაილებში (როგორიცაა FLV), არაა მხარდაჭერილი რამდენიმე ბილიკი, თითოეული ჩაწერისას" -OutputWarnings.MP4Recording="გაფრთხილება: MP4 სახით შენახული ჩანაწერები ვეღარ აღდგება, მუშაობის შეწყვეტის შემთხვევაში (მაგ. ლურჯი ეკრანის ამოგდებისას, ძაბვის ვარდნისას და ა.შ.). თუ გსურთ რამდენიმე ხმოვანი ფაილის ჩაწერა, სასურველია ამისთვის გამოიყენოთ MKV და დასრულების შემდეგ გარდაქმნათ MP4-ად. (ფაილი->ჩანაწერების გარდაქმნა)" +OutputWarnings.MP4Recording="გაფრთხილება: MP4/MOV სახით შენახული ჩანაწერები ვეღარ აღდგება, მუშაობის შეწყვეტის შემთხვევაში (მაგ. ლურჯი ეკრანის ამოგდებისას, ძაბვის ვარდნისას და ა.შ.). თუ გსურთ რამდენიმე ხმოვანი ფაილის ჩაწერა, სასურველია ამისთვის გამოიყენოთ MKV და დასრულების შემდეგ გადაფუთოთ MP4/MOV-ფაილად. (ფაილი → ჩანაწერების გადაფუთვა)" FinalScene.Title="სცენის წაშლა" -FinalScene.Text="საჭიროებს, სულ მცირე ერთ სცენას." +FinalScene.Text="აუცილებელია სულ მცირე ერთ სცენა." NoSources.Title="წყაროები არაა" NoSources.Text="როგორც ჩანს, თქვენ ჯერ არ დაგიმატებიათ ვიდეოს არცერთი წყარო, შედეგად მიიღებთ ცარიელ ეკრანს. ნამდვილად გსურთ, განაგრძოთ?" NoSources.Text.AddSource="წყაროს დამატება შეგიძლიათ ნებისმიერ დროს + ნიშანზე დაწკაპებით, მთავარი ფანჯრის წყაროების არეში." +NoSources.Label="წყაროები არ მიგითითებიათ.\nდაწკაპეთ + ღილაკზე ქვემოთ\nან დაამატეთ მარჯვენა წკაპით." ChangeBG="ფერის დაყენება" CustomColor="ფერის მითითება" BrowserSource.EnableHardwareAcceleration="ბრაუზერის აპარატურული აჩქარების ჩართვა" +About="შესახებ" +About.Info="OBS Studio არის უფასო, ღია წყაროს მქონე პროგრამა ვიდეოების ჩასაწერად და პირდაპირი ეთერით გადასაცემად." +About.Donate="გაიღეთ შემოწირულობა" +About.GetInvolved="ჩაერთეთ შემუშავებაში" +About.Authors="შემქმნელები" +About.License="ლიცენზია" +About.Contribute="მხარი დაუჭირეთ OBS-პროექტს" + +ResizeOutputSizeOfSource="გამოტანის ზომების შეცვლა (წყაროს ზომები)" +ResizeOutputSizeOfSource.Text="ეკრანის ძირითადი და გამოტანილი ვიდეოს გაფართოება ჩანაცვლდება მიმდინარე წყაროს ზომებით." +ResizeOutputSizeOfSource.Continue="გსურთ, განაგრძოთ?" + +PreviewTransition="გადასვლის შეთვალიერება" + diff --git a/UI/data/locale/ko-KR.ini b/UI/data/locale/ko-KR.ini index 4abb6a2..3d579f6 100644 --- a/UI/data/locale/ko-KR.ini +++ b/UI/data/locale/ko-KR.ini @@ -80,14 +80,40 @@ StudioMode.Program="프로그램" ShowInMultiview="다중화면으로 표시" VerticalLayout="수직으로 배치" Group="하나로 묶기" +DoNotShowAgain="다시 표시하지 않기" +Default="(기본)" +Calculating="계산 중.." AlreadyRunning.Title="OBS가 이미 실행 중입니다" AlreadyRunning.Text="OBS가 이미 실행 중입니다! 의도한 것이 아니라면 새로운 OBS를 실행하기 전에 이미 동작 중인 프로그램을 종료하십시오. OBS가 시스템 트레이에 최소화되어 있는지도 확인하십시오." AlreadyRunning.LaunchAnyway="경고를 무시하고 실행" +DockCloseWarning.Title="도킹 가능한 창을 닫는 중입니다" +DockCloseWarning.Text="도킹 가능한 창을 닫았습니다. 이 창을 다시 보려면 상단 메뉴에서 보기 -> 독을 확인하세요." + +Auth.Authing.Title="인증 처리 중..." +Auth.Authing.Text="%1 인증 처리 중, 잠시만 기다려 주세요..." +Auth.AuthFailure.Title="인증 실패" +Auth.AuthFailure.Text="%1:\n\n%2: %3 에서 인증을 실패했습니다." +Auth.InvalidScope.Title="권한 인증이 필요합니다" +Auth.InvalidScope.Text="%1 의 인증 요구사항이 변경되었습니다. 일부 기능이 제한될 수 있습니다." +Auth.LoadingChannel.Title="채널 정보를 읽는 중..." +Auth.LoadingChannel.Text="%1 채널 정보를 읽고 있습니다, 잠시만 기다려 주세요..." +Auth.ChannelFailure.Title="채널을 불러오지 못했습니다" +Auth.ChannelFailure.Text="%1\n\n%2: %3 의 채널 정보를 불러오는 데 실패했습니다" +Auth.Chat="채팅" +Auth.StreamInfo="방송 정보" +TwitchAuth.Stats="트위치 통계" +TwitchAuth.Feed="트위치 활동 피드" +TwitchAuth.TwoFactorFail.Title="스트림 키를 질의할 수 없었습니다" +TwitchAuth.TwoFactorFail.Text="OBS가 사용자의 트위치 계정에 접속할 수 없었습니다. 트위치 보안 설정 에서 이중 인증을 거쳐야 방송이 가능합니다." + Copy.Filters="필터를 복사" Paste.Filters="필터를 붙여넣기" +BrowserPanelInit.Title="브라우저를 시작합니다..." +BrowserPanelInit.Text="브라우저를 준비 중입니다, 잠시만 기다려 주세요..." + BandwidthTest.Region="지역" BandwidthTest.Region.US="미국" BandwidthTest.Region.EU="유럽" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="아시아" BandwidthTest.Region.Other="기타" Basic.FirstStartup.RunWizard="구성 마법사를 실행하겠습니까? 설정 창에서 수동으로 설정할 수도 있습니다." -Basic.FirstStartup.RunWizard.BetaWarning="(참고: 구성 마법사는 현재 베타 시험 중입니다)" Basic.FirstStartup.RunWizard.NoClicked="언제든지 도구 창에서 구성 마법사를 실행할 수 있습니다." Basic.AutoConfig="구성 마법사" -Basic.AutoConfig.Beta="구성 마법사 (베타)" Basic.AutoConfig.ApplySettings="설정 적용" Basic.AutoConfig.StartPage="사용 정보" Basic.AutoConfig.StartPage.SubTitle="이 프로그램으로 무엇을 할지 알려주세요" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 혹은 30, 하지만 높은 해 Basic.AutoConfig.VideoPage.CanvasExplanation="참고: 캔버스 (기본) 해상도는 방송 혹은 녹화하려는 해상도와 반드시 같을 필요는 없습니다. 실제 방송/녹화 해상도는 Pc 사양을 낮추거나 비트레이트 제한에 맞추기 위해 이 캔버스 해상도를 기준으로 축소할 수 있습니다." Basic.AutoConfig.StreamPage="방송 정보" Basic.AutoConfig.StreamPage.SubTitle="방송 정보를 입력하세요" +Basic.AutoConfig.StreamPage.ConnectAccount="계정 연결 (필수 아님)" +Basic.AutoConfig.StreamPage.DisconnectAccount="계정 연결끊기" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="해당 계정과 연결을 끊겠습니까?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="이 변경 사항은 즉시 적용됩니다. 정말로 계정과 연결을 중단하겠습니까?" +Basic.AutoConfig.StreamPage.UseStreamKey="스트림 키 사용" Basic.AutoConfig.StreamPage.Service="서비스" Basic.AutoConfig.StreamPage.Service.ShowAll="모두 보기..." +Basic.AutoConfig.StreamPage.Service.Custom="사용자 지정..." Basic.AutoConfig.StreamPage.Server="서버" Basic.AutoConfig.StreamPage.StreamKey="스트림 키" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(링크)" @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="이 설정을 사용하려면 설정 Basic.Stats="통계" Basic.Stats.CPUUsage="CPU 이용률" -Basic.Stats.HDDSpaceAvailable="저장장치 공간 충분" +Basic.Stats.HDDSpaceAvailable="저장장치 공간 확보" Basic.Stats.MemoryUsage="메모리 사용" Basic.Stats.AverageTimeToRender="프레임을 렌더링하는데 필요한 평균 시간" Basic.Stats.SkippedFrames="인코딩 작업이 지연되어 생략된 프레임" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="작동 중지" Basic.Stats.DroppedFrames="드롭된 프레임 (네트워크)" Basic.Stats.MegabytesSent="데이터 출력 합계" Basic.Stats.Bitrate="비트레이트" +Basic.Stats.DiskFullIn="디스크가 꽉차기 전까지 (추정)" + +ResetUIWarning.Title="정말로 모든 UI를 초기화하겠습니까?" +ResetUIWarning.Text="UI를 초기화하면 추가한 독이 안보일 것입니다. '보기' 메뉴에서 다시 나타나게 설정할 수 있습니다.\n\nUI를 초기화하겠습니까?" Updater.Title="사용가능한 판올림이 있습니다" Updater.Text="새 판올림이 준비되었습니다:" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="가능한 판올림이 없습니다" Updater.NoUpdatesAvailable.Text="현재 사용가능한 판올림이 없습니다" Updater.FailedToLaunch="판올림 도우미를 실행할 수 없습니다" Updater.GameCaptureActive.Title="게임 캡쳐 기능이 활성화 중" -Updater.GameCaptureActive.Text="게임 캡쳐 기능을 현재 사용 중입니다. 캡쳐 중인 게임이나 프로그램을 종료(혹은 윈도우를 재시작) 한 다음 다시 시도하세요." +Updater.GameCaptureActive.Text="게임 캡쳐 라이브러리가 현재 사용 중입니다. 캡쳐 중인 게임/프로그램 혹은 윈도우를 종료 후 다시 시작하세요." QuickTransitions.SwapScenes="전환 후 미리 보기/출력 장면을 교체" QuickTransitions.SwapScenesTT="(만약 출력 쪽 원본 장면이 있을 때) 전환 작업 이후 미리 보기와 출력 장면을 교체합니다. \n출력 쪽 원본 장면에서 변경한 내용은 사라지지 않습니다." @@ -206,6 +240,9 @@ ConfirmStart.Text="정말로 방송을 시작할까요?" ConfirmStop.Title="방송 중지?" ConfirmStop.Text="정말로 방송을 중단할까요?" +ConfirmBWTest.Title="대역폭을 점검하겠습니까?" +ConfirmBWTest.Text="OBS가 대역폭 시험 상태입니다. 방송을 송출하지 않고 네트워크를 점검할 수 있습니다. 시험을 종료해야 시청자가 방송을 볼 수 있습니다.\n\n계속하겠습니까?" + ConfirmExit.Title="OBS를 종료합니까?" ConfirmExit.Text="OBS가 현재 작동 중입니다. 모든 방송/녹화가 중단됩니다. 정말로 종료하시겠습니까?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="녹화를 시작하지 못했습니다" Output.StartReplayFailed="리플레이 버퍼를 시작하지 못했습니다" Output.StartFailedGeneric="출력을 시작하지 못했습니다. 기록 파일을 확인하십시오.\n\n참고: NVENC 혹은 AMD 인코더를 사용하고 있다면 드라이버를 최신 버전으로 유지하십시오." + Output.ConnectFail.Title="연결에 실패했음" Output.ConnectFail.BadPath="잘못된 경로 혹은 연결 주소입니다. 유효한 값인지 설정을 확인하시기 바랍니다. " Output.ConnectFail.ConnectFailed="서버에 연결하지 못했습니다" @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="지정한 채널 혹은 스트림 키에 접 Output.ConnectFail.Error="예기치 않은 오류가 서버에 접속을 시도하는 과정에서 발생했습니다. 자세한 정보는 기록 파일을 조회하십시오. " Output.ConnectFail.Disconnected="서버로부터 접속이 끊겼습니다. " +Output.StreamEncodeError.Title="인코딩 오류" +Output.StreamEncodeError.Msg="방송 중 인코더 오류가 발생했습니다." + Output.RecordFail.Title="녹화에 실패했습니다" Output.RecordFail.Unsupported="이 출력 형식은 지원하지 않거나 하나 이상의 오디오 트랙을 지원하지 않습니다. 설정을 확인하여 다시 시도하십시오." Output.RecordNoSpace.Title="디스크 공간 부족" Output.RecordNoSpace.Msg="녹화를 계속하기 위한 디스크 공간이 부족합니다." Output.RecordError.Title="녹화 오류" Output.RecordError.Msg="녹화 중 예기치 못한 오류가 발생했습니다." +Output.RecordError.EncodeErrorMsg="녹화 중 인코더 오류가 발생했습니다." Output.ReplayBuffer.NoHotkey.Title="단축키가 없습니다!" Output.ReplayBuffer.NoHotkey.Msg="리플레이를 저장하는 단축키를 지정하지 않았습니다. 리플레이 녹화 기능을 사용하려면 \"저장\" 단축키를 지정하십시오." @@ -241,25 +283,23 @@ LogReturnDialog="기록 업로드 성공" LogReturnDialog.CopyURL="주소 복사" LogReturnDialog.ErrorUploadingLog="업로드하는 기록 파일 오류" -LicenseAgreement="사용권 계약" -LicenseAgreement.PleaseReview="OBS를 사용하기에 앞서 사용권 약관을 검토하시기 바랍니다. 이 프로그램을 사용하는 행위는 이에 따른 본 사용권의 내용을 숙지하고 있으며, GNU General Public License v2.0에 동의한다는 것을 의미합니다. 글을 내려 사용권의 나머지 부분도 읽어주십시오." -LicenseAgreement.ClickIAgreeToContinue="명시된 사용권의 약관에 동의한다면, 동의를 누르고 계속하십시오. OBS를 사용하기 위해서는 해당 약관에 반드시 동의해야 합니다." -LicenseAgreement.IAgree="동의합니다" -LicenseAgreement.Exit="끝내기" - Remux.SourceFile="OBS 녹화" Remux.TargetFile="대상 파일" Remux.Remux="재다중화" +Remux.Stop="재다중화 중단" +Remux.ClearFinished="종료한 항목 삭제" +Remux.ClearAll="모든 항목 삭제" Remux.OBSRecording="OBS 녹화" Remux.FinishedTitle="재다중화 작업 완료" Remux.Finished="녹화가 재다중화 처리되었음" Remux.FinishedError="녹화가 재다중화 처리되었으나 파일이 완성되지 않을 수 있습니다" -Remux.SelectRecording="OBS 녹화 선택 ..." -Remux.SelectTarget="대상 파일 선택 ..." -Remux.FileExistsTitle="대상 파일이 존재" -Remux.FileExists="대상 파일이 존재합니다. 이 것으로 대체하겠습니까?" +Remux.SelectRecording="OBS 녹화를 선택합니다..." +Remux.SelectTarget="대상 파일을 지정합니다..." +Remux.FileExistsTitle="대상 파일이 존재합니다" +Remux.FileExists="다음 대상 파일들이 이미 존재합니다. 대체하시겠습니까?" Remux.ExitUnfinishedTitle="재다중화 작업 중" Remux.ExitUnfinished="재다중화 작업이 끝나지 않았습니다. 지금 멈추면 대상 파일은 사용할 수 없는 상태가 됩니다.\n정말로 작업을 중단하겠습니까?" +Remux.HelpText="재다중화 작업을 하려면 파일을 이 창에 드롭하거나 비어있는 \"OBS 녹화\" 셀을 눌러 대상을 지정하세요." UpdateAvailable="새 판올림 사용 가능" UpdateAvailable.Text="버전 %1. %2. %3이 나왔습니다. 다운로드" @@ -276,11 +316,14 @@ Basic.DisplayCapture="캡처 표시" Basic.Main.PreviewConextMenu.Enable="미리보기 활성화" +Basic.Main.Preview.Disable="미리보기 끄기" + ScaleFiltering="비율 필터링" ScaleFiltering.Point="점" ScaleFiltering.Bilinear="이중선형" ScaleFiltering.Bicubic="쌍삼차" ScaleFiltering.Lanczos="란초스" +ScaleFiltering.Area="영역" Deinterlacing="디인터레이싱" Deinterlacing.Discard="저장 안함" @@ -414,7 +457,7 @@ Basic.Main.Ungroup="묶음 해체" Basic.MainMenu.File="파일(&F)" Basic.MainMenu.File.Export="내보내기(&E)" Basic.MainMenu.File.Import="가져오기(&I)" -Basic.MainMenu.File.ShowRecordings="녹화 저장 폴더 열기(R)" +Basic.MainMenu.File.ShowRecordings="녹화 저장 폴더 열기(&R)" Basic.MainMenu.File.Remux="재다중화 녹화(&M)" Basic.MainMenu.File.Settings="설정(&S)" Basic.MainMenu.File.ShowSettingsFolder="설정 폴더 보기" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="수직으로 뒤집기(&V)" Basic.MainMenu.Edit.Transform.FitToScreen="채우기(&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="늘리기(&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="가운데(&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="수직으로 정렬" +Basic.MainMenu.Edit.Transform.HorizontalCenter="수평으로 정렬" Basic.MainMenu.Edit.Order="순서(&O)" Basic.MainMenu.Edit.Order.MoveUp="위로 올리기(&U)" Basic.MainMenu.Edit.Order.MoveDown="아래로 내리기(&D)" @@ -474,11 +519,11 @@ Basic.MainMenu.SceneCollection.Exists="그 장면 모음은 이미 존재합니 Basic.MainMenu.Tools="도구(&T)" Basic.MainMenu.Help="도움말(&H)" -Basic.MainMenu.Help.HelpPortal="도움말 및 포털" +Basic.MainMenu.Help.HelpPortal="도움말 및 포털(&P)" Basic.MainMenu.Help.Website="웹사이트 방문(&W)" Basic.MainMenu.Help.Discord="공식 디스코드 참여(&D)" Basic.MainMenu.Help.Logs="기록 파일(&L)" -Basic.MainMenu.Help.Logs.ShowLogs="기록 파일 표시(S)" +Basic.MainMenu.Help.Logs.ShowLogs="기록 파일 표시(&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="현재 기록 파일 올리기(&C)" Basic.MainMenu.Help.Logs.UploadLastLog="마지막 기록 파일 올리기(&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="현재 기록 보기(&V)" @@ -486,6 +531,7 @@ Basic.MainMenu.Help.CheckForUpdates="판올림 확인" Basic.MainMenu.Help.CrashLogs="오류 보고(&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="오류 보고서 보기(&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="마지막 오류 보고서 전송하기(&L)" +Basic.MainMenu.Help.About="정보(&A)" Basic.Settings.ProgramRestart="설정을 적용하려면 프로그램을 다시 시작해야 합니다." Basic.Settings.ConfirmTitle="변경사항 확인" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="시스템 트레이" Basic.Settings.General.SysTrayWhenStarted="시작할 때 시스템 트레이로 최소화" Basic.Settings.General.SystemTrayHideMinimize="작업 표시줄 대신 시스템 트레이에 항상 최소화" Basic.Settings.General.SaveProjectors="종료 시 프로젝터 저장" +Basic.Settings.General.Preview="미리보기" +Basic.Settings.General.OverflowHidden="오버플로우 숨기기" +Basic.Settings.General.OverflowAlwaysVisible="오버플로우를 항상 표시" +Basic.Settings.General.OverflowSelectionHidden="소스가 보이지 않을 때 오버플로우를 표시" Basic.Settings.General.SwitchOnDoubleClick="더블클릭 시 장면으로 전환" Basic.Settings.General.StudioPortraitLayout="프로젝터를 수직으로 배열" +Basic.Settings.General.TogglePreviewProgramLabels="미리보기/프로그램 이름표 보기" Basic.Settings.General.Multiview="다중화면" Basic.Settings.General.Multiview.MouseSwitch="클릭으로 장면 간 전환" Basic.Settings.General.Multiview.DrawSourceNames="장면 이름 표시" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="수평, 상단 ( Basic.Settings.Stream="방송" Basic.Settings.Stream.StreamType="방송 형식" +Basic.Settings.Stream.Custom.UseAuthentication="인증 기능 사용" +Basic.Settings.Stream.Custom.Username="사용자 이름" +Basic.Settings.Stream.Custom.Password="비밀번호" +Basic.Settings.Stream.BandwidthTestMode="대역폭 시험 상태 활성화" Basic.Settings.Output="출력" Basic.Settings.Output.Format="녹화 형식" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="경고: 방송과 녹화를 동시에 Basic.Settings.Output.Simple.Warn.Lossless="경고: 무손실 품질로 녹화하면 파일 크기가 엄청나게 커집니다! 해당 설정은 높은 해상도 및 프레임에서 분당 7기가바이트 이상 필요합니다. 따라서 디스크에 아주 큰 공간을 확보하지 않는 이상 장시간 녹화에는 추천하지 않습니다." Basic.Settings.Output.Simple.Warn.Lossless.Msg="정말로 무손실 품질로 녹화하겠습니까?" Basic.Settings.Output.Simple.Warn.Lossless.Title="무손실 품질 설정 경고!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="경고: 방송과 녹화를 동시에 하고 있을 때 여러 개의 독립된 QSV 인코더를 사용할 수 없습니다. 두 작업을 동시에 하려면 녹화 혹은 방송 인코더 둘 중 하나를 바꿔야 합니다." Basic.Settings.Output.Simple.Encoder.Software="소프트웨어 (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="하드웨어 (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="하드웨어 (AMD)" @@ -572,12 +626,12 @@ Basic.Settings.Output.Reconnect="자동으로 다시 연결" Basic.Settings.Output.RetryDelay="재접속 간격 (초 단위)" Basic.Settings.Output.MaxRetries="최대 재시도 횟수" Basic.Settings.Output.Advanced="고급 인코더 설정 활성화" -Basic.Settings.Output.EncoderPreset="인코더 사전설정 (빠를수록 부담 적으나 화질 나쁨)" +Basic.Settings.Output.EncoderPreset="인코더 사전설정" Basic.Settings.Output.CustomEncoderSettings="사용자 임의 인코더 설정" Basic.Settings.Output.CustomMuxerSettings="사용자 임의 다중화 설정" Basic.Settings.Output.NoSpaceFileName="여백없이 파일 이름 짓기" -Basic.Settings.Output.Adv.Rescale="출력 배율 재조정" +Basic.Settings.Output.Adv.Rescale="출력 배율 재조정" Basic.Settings.Output.Adv.AudioTrack="오디오 트랙" Basic.Settings.Output.Adv.Streaming="방송" Basic.Settings.Output.Adv.ApplyServiceSettings="방송 서비스 인코더 설정 강제 적용" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (영상 크기 변경을 Basic.Settings.Audio="오디오" Basic.Settings.Audio.SampleRate="샘플 레이트" Basic.Settings.Audio.Channels="채널" -Basic.Settings.Audio.MeterDecayRate="오디오 측정기 감퇴 속도" +Basic.Settings.Audio.Meters="측정기" +Basic.Settings.Audio.MeterDecayRate="감쇄 속도" Basic.Settings.Audio.MeterDecayRate.Fast="빠름" Basic.Settings.Audio.MeterDecayRate.Medium="중간 (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="느림 (Type II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="경고: 서라운드 음향이 Basic.Settings.Audio.MultichannelWarning="방송 중이라면 서비스에서 서라운드 음향에 대한 입력 및 재생을 지원하는지 확인하세요. 트위치, 페이스북 360 라이브, Mixer RTMP, Smashcast 는 해당 기능을 사용할 수 있습니다. 페이스북 Live와 유튜브 Live 서비스는 입력은 할 수 있지만 스테레오로 전환하며 유튜브 Live는 오로지 2채널로만 재생합니다.\n\nOBS 오디오 필터는 서라운드 음향을 지원하지만 VST 플러그인 지원은 보장하지 않습니다." Basic.Settings.Audio.MultichannelWarning.Title="서라운드 음향을 활성화할까요?" Basic.Settings.Audio.MultichannelWarning.Confirm="정말로 서라운드 음향을 사용하겠습니까?" -Basic.Settings.Audio.DesktopDevice="데스크탑 오디오 장치" -Basic.Settings.Audio.DesktopDevice2="데스크탑 오디오 장치 2" -Basic.Settings.Audio.AuxDevice="마이크/보조 오디오 장치" -Basic.Settings.Audio.AuxDevice2="마이크/보조 오디오 장치 2" -Basic.Settings.Audio.AuxDevice3="마이크/보조 오디오 장치 3" +Basic.Settings.Audio.Devices="장치" +Basic.Settings.Audio.DesktopDevice="데스크탑 오디오" +Basic.Settings.Audio.DesktopDevice2="데스크탑 오디오 2" +Basic.Settings.Audio.AuxDevice="마이크/보조 오디오" +Basic.Settings.Audio.AuxDevice2="마이크/보조 오디오 2" +Basic.Settings.Audio.AuxDevice3="마이크/보조 오디오 3" +Basic.Settings.Audio.AuxDevice4="마이크/보조 오디오 4" Basic.Settings.Audio.EnablePushToMute="누르면 음소거 활성화" Basic.Settings.Audio.PushToMuteDelay="누르면 음소거 지연" Basic.Settings.Audio.EnablePushToTalk="누르며 말하기 활성화" Basic.Settings.Audio.PushToTalkDelay="누르며 말하기 지연" Basic.Settings.Audio.UnknownAudioDevice="[장치를 연결하지 않았거나 사용할 수 없음]" +Basic.Settings.Audio.Disabled="사용안함" Basic.Settings.Advanced="고급" Basic.Settings.Advanced.General.ProcessPriority="프로세스 우선순위 설정" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="낮음" Basic.Settings.Advanced.FormatWarning="경고: NV12 이외의 색상 형식은 주로 녹화를 위한 것이며, 방송에 적합하지 않습니다. 이대로 방송을 하게 되면 형식 전환을 위해 CPU 사용량이 증가할 수 있습니다." Basic.Settings.Advanced.Audio.BufferingTime="오디오 버퍼링 시간" Basic.Settings.Advanced.Video.ColorFormat="색상 형식" -Basic.Settings.Advanced.Video.ColorSpace="YUV 색 공간" -Basic.Settings.Advanced.Video.ColorRange="YUV 색상 범위" +Basic.Settings.Advanced.Video.ColorSpace="색 공간" +Basic.Settings.Advanced.Video.ColorRange="색상 범위" Basic.Settings.Advanced.Video.ColorRange.Partial="부분" Basic.Settings.Advanced.Video.ColorRange.Full="전체" -Basic.Settings.Advanced.Audio.MonitoringDevice="오디오 모니터링 장치" +Basic.Settings.Advanced.Audio.MonitoringDevice="감시 장치" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="기본값" Basic.Settings.Advanced.Audio.DisableAudioDucking="윈도우 오디오 더킹 비활성화" Basic.Settings.Advanced.StreamDelay="방송 지연" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="IP에 고정" Basic.Settings.Advanced.Network.EnableNewSocketLoop="새로운 네트워크 코드 활성화" Basic.Settings.Advanced.Network.EnableLowLatencyMode="짧은 지연시간 방식 사용" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="주요 창을 초점으로 둘 때 단축키를 비활성화" +Basic.Settings.Advanced.AutoRemux="mp4 형식으로 재다중화" +Basic.Settings.Advanced.AutoRemux.MP4="(녹화는 mkv 형식)" Basic.AdvAudio="오디오 고급 설정" Basic.AdvAudio.Name="이름" -Basic.AdvAudio.Volume="볼륨 (%)" +Basic.AdvAudio.Volume="음량" Basic.AdvAudio.Mono="모노로 강제 송출" -Basic.AdvAudio.Panning="패닝" +Basic.AdvAudio.Balance="균형" Basic.AdvAudio.SyncOffset="싱크 오프셋 (ms)" Basic.AdvAudio.Monitoring="오디오 모니터링" Basic.AdvAudio.Monitoring.None="모니터링 끔" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="트랙" Basic.Settings.Hotkeys="단축키" Basic.Settings.Hotkeys.Pair="'%1'과 공유하는 키 조합을 토글 형식으로 설정" +Basic.Settings.Hotkeys.Filter="필터" Basic.Hotkeys.SelectScene="장면 전환" @@ -739,10 +800,10 @@ Hotkeys.Menu="메뉴" Hotkeys.Space="스페이스" Hotkeys.NumpadNum="숫자키 패드 %1" Hotkeys.NumpadMultiply="* (숫자키 패드)" -Hotkeys.NumpadDivide="/ (숫자키 패드)" -Hotkeys.NumpadAdd="+ (숫자키 패드)" -Hotkeys.NumpadSubtract="- (숫자키 패드)" -Hotkeys.NumpadDecimal=". (숫자키 패드)" +Hotkeys.NumpadDivide="/ (숫자키 패드)" +Hotkeys.NumpadAdd="+ (숫자키 패드)" +Hotkeys.NumpadSubtract="- (숫자키 패드)" +Hotkeys.NumpadDecimal=". (숫자키 패드)" Hotkeys.AppleKeypadNum="%1 (문자판)" Hotkeys.AppleKeypadMultiply="* (문자판)" Hotkeys.AppleKeypadDivide="/ (문자판)" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (문자판)" Hotkeys.AppleKeypadDecimal=". (문자판)" Hotkeys.AppleKeypadEqual="= (문자판)" Hotkeys.MouseButton="마우스 %1" +Hotkeys.Escape="Esc" Mute="음소거" Unmute="음소거 해제" @@ -762,7 +824,7 @@ SceneItemHide="'%1' 숨기기" OutputWarnings.NoTracksSelected="최소 하나의 트랙을 선택해야 합니다" OutputWarnings.MultiTrackRecording="경고: 일부 형식(예를 들어 FLV)은 녹화 하나에 여러 개의 트랙을 지원하지 않습니다" -OutputWarnings.MP4Recording="경고: MP4로 녹화를 하면 파일이 마무리가 되지 않았을 때 (예를 들어 컴퓨터가 급작스럽게 꺼지거나 블루 스크린 오류가 일어나는 경우) 복구할 수 없습니다. 여러 개의 오디오 트랙을 녹음하고 싶다면 MKV 확장자로 녹화 한 뒤 재다중화 작업을 통해 mp4로 전환하십시오. (파일->재다중화 녹화)" +OutputWarnings.MP4Recording="경고: MP4로 녹화를 하면 파일이 마무리가 되지 않았을 때 (예를 들어, 컴퓨터가 급작스럽게 꺼지거나 블루 스크린 오류가 일어나는 경우) 복구할 수 없습니다. 여러 개의 오디오 트랙을 녹음하고 싶다면 MKV 확장자로 녹화 한 뒤 재다중화 작업을 통해 MP4/MOV로 변환하십시오. (파일 → 재다중화 녹화)" FinalScene.Title="장면 삭제" FinalScene.Text="적어도 하나의 장면은 존재해야 합니다." @@ -770,9 +832,24 @@ FinalScene.Text="적어도 하나의 장면은 존재해야 합니다." NoSources.Title="소스 없음" NoSources.Text="어떠한 영상 소스도 추가하지 않아서 빈 화면만 송출할 것입니다. 그래도 계속하시겠습니까?" NoSources.Text.AddSource="주 화면 소스 목록에 있는 + 아이콘을 누르면 소스를 추가할 수 있습니다." +NoSources.Label="방송이나 녹화에 송출할 소스가 지정되어 있지 않습니다.\n아래 + 버튼을 누르거나\n여기를 우클릭하여 소스를 추가하십시오." ChangeBG="색상 지정" CustomColor="사용자 색상" BrowserSource.EnableHardwareAcceleration="브라우저 소스에 하드웨어 가속 활성화" +About="정보" +About.Info="OBS Studio는 무료 및 오픈 소스이며 비디오 녹화와 생방송을 할 수 있는 소프트웨어입니다." +About.Donate="후원하기" +About.GetInvolved="참여하기" +About.Authors="제작자들" +About.License="라이센스" +About.Contribute="OBS 프로젝트를 후원하세요" + +ResizeOutputSizeOfSource="출력 크기 조정 (소스 크기)" +ResizeOutputSizeOfSource.Text="기본 및 출력 해상도가 현재 소스 크기로 조정됩니다." +ResizeOutputSizeOfSource.Continue="계속하시겠습니까?" + +PreviewTransition="미리보기 변환" + diff --git a/UI/data/locale/ku-TR.ini b/UI/data/locale/ku-TR.ini new file mode 100644 index 0000000..e7bbcf3 --- /dev/null +++ b/UI/data/locale/ku-TR.ini @@ -0,0 +1,190 @@ + +Language="کوردی" +Region="باشوری کوردستان" + +OK="باشە" +Apply="جێبەجێکردن" +Cancel="پاشگەزبونەوە" +Close="داخستن" +Save="پاراستن" +Discard="ڕەتکردنەوە" +Disable="ناچالاککردن" +Yes="بەڵێ" +No="نەخێر" +Add="زیادکردن" +Remove="سڕینەوە" +Rename="ناونانەوە" +Interact="کارلێکردن" +Filters="فلتەرەکان" +Properties="خاسیەتەکان" +MoveUp="بۆ سەرەوە بجوڵێ" +MoveDown="بۆ خوارەوە بجوڵێ" +Settings="ڕێکخستنەکان" +Display="پیشاندراو" +Name="ناو" +Exit="ده‌رچوون" +Mixer="میکسەر" +Browse="هێنان" +Mono="یەک بڵندگۆ" +Stereo="دوو بڵندگۆ" +Clear="پاککردنه‌وه‌" +Show="نیشاندان" +Hide="شاردنەوە" +UnhideAll="نەشارندەوەی هەموو" +Untitled="بێ ناونیشان" +New="نوێ" +Duplicate="هاوشێوەوەرگرتن" +Enable="چالاککردن" +Left="چەپ" +Right="ڕاست" +Top="سەرەوە" +Bottom="خوارەوە" +Reset="ڕێکخستنەوه" +Hours="کاژێره‌کان" +Minutes="خولەکەکان" +Seconds="چرکەکان" +Import="هێنان" +Export="ناردن" +Copy="لەبەرگرتنەوە" +Paste="دانان" +Next="دواتر" +Back="پێشتر" +Defaults="بنه‌ڕه‌تی" +None="هیچ" +StudioMode.Preview="پێشبینین" + + + +Auth.Chat="گفتوگۆکردن" + +Copy.Filters="لەبەرگرتنەوەی فلتەرەکان" +Paste.Filters="دانانی فلتەرەکان" + + +BandwidthTest.Region="ناوچه" +BandwidthTest.Region.US="ویلایەتە یەکگرتوەکانی ئەمریکا" +BandwidthTest.Region.EU="ئەوروپا" +BandwidthTest.Region.Asia="ئاسیا" +BandwidthTest.Region.Other="ئه‌وانی تر" + + +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(بەستەرە)" + +Basic.Stats="ئامار" +Basic.Stats.Output.Recording="تۆماردەکرێت" +Basic.Stats.Status.Recording="تۆماردەکرێت" +Basic.Stats.Status.Live="ڕاستەوخۆ" + + +Updater.UpdateNow="نوێکردنەوە ئێستا" + + +Basic.TransitionDuration="ماوه‌" +Basic.TogglePreviewProgramMode="شێوازی ستۆدیۆ" + + + + + + + + +ConfirmExit.Title="ده‌رچوون لە OBS" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Basic.TransformWindow.Position="شوێن" +Basic.TransformWindow.Rotation="سوڕانه‌وه‌" +Basic.TransformWindow.Size="قەبارە" +Basic.TransformWindow.Crop="قرتاندن" + +Basic.TransformWindow.Alignment.TopLeft="لای چەپی سەرەوە" +Basic.TransformWindow.Alignment.TopCenter="ناوەڕاستی سەرەوە" +Basic.TransformWindow.Alignment.TopRight="لای ڕاستی سەرەوە" +Basic.TransformWindow.Alignment.CenterLeft="ناوەڕاستی چەپ" +Basic.TransformWindow.Alignment.Center="ناوەڕاست" +Basic.TransformWindow.Alignment.CenterRight="نێوەندی ڕاست" +Basic.TransformWindow.Alignment.BottomLeft="لای چەپی خوارەوە" +Basic.TransformWindow.Alignment.BottomCenter="ناوەڕاستی خوارەوە" +Basic.TransformWindow.Alignment.BottomRight="لای ڕاستی خوارەوە" + + + +Basic.Main.StopRecording="تۆمارکردن بوەستێنە" +Basic.Main.StoppingRecording="چاوەروانبە بۆ وەستاندنی تۆمارکردن" + +Basic.MainMenu.File="پەرگە" +Basic.MainMenu.File.Exit="ده‌رچوون" + +Basic.MainMenu.Edit="دەستکاریکردن" +Basic.MainMenu.Edit.Undo="پاشگەزبوونەوە" +Basic.MainMenu.Edit.Redo="گه‌ڕانه‌وه‌ بۆ هه‌نگاوی داهاتوو" + +Basic.MainMenu.View="نیشاندان" +Basic.MainMenu.View.Toolbars="شریتی ئامرازەکان" + +Basic.MainMenu.SceneCollection="کۆکراوەی دیمەنەکان" +Basic.MainMenu.Profile="پرۆفایل" + +Basic.MainMenu.Tools="ئامرازەکان" + +Basic.MainMenu.Help="یارمەتی" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI/data/locale/lt-LT.ini b/UI/data/locale/lt-LT.ini index 97e889f..50ba99e 100644 --- a/UI/data/locale/lt-LT.ini +++ b/UI/data/locale/lt-LT.ini @@ -42,7 +42,7 @@ Duplicate="Dubliuoti" Enable="Įjungti" DisableOSXVSync="Išjungti OSX V-Sync" ResetOSXVSyncOnExit="Iš naujo nustatyti OSX V-Sync išeinant" -HighResourceUsage="Kodavimas perkrautas! Mažinkite vaizdo parametrus arba naudokite greitesnę kodavimo parengtį." +HighResourceUsage="Kodavimas perkrautas! Mažinkite vaizdo parametrus arba naudokite greitesnę kodavimo parengtį." Transition="Perėjimas" QuickTransitions="Greitieji perėjimai" Left="Iš kairės" @@ -62,6 +62,10 @@ Import="Importuoti" + + + + QuickTransitions.SwapScenes="Sukeisti Peržiūros/Išvesties scenas po Perėjimo" QuickTransitions.SwapScenesTT="Sukeičia peržiūros ir išvesties scenas po perėjimo įvykdymo (jei originali išvesties scena vis dar egzistuoja).\nTai neatšauks jokių pakeitimų kurie galima buvo atlikti originalioje išvesties scenoje." QuickTransitions.DuplicateScene="Dubliuoti Sceną" @@ -93,6 +97,7 @@ ConfirmStart.Text="Ar esate įsitikinęs, kad norite pradėti transliavimą?" ConfirmStop.Title="Stabdyti transliaciją?" ConfirmStop.Text="Ar esate įsitikinęs, kad norite stabdyti transliavimą?" + ConfirmExit.Title="Išeiti iš OBS?" ConfirmExit.Text="OBS metu yra aktyvus. Visos transliacijos/įrašymai bus išjungti. Ar tikrai norite išeiti?" @@ -100,12 +105,14 @@ ConfirmRemove.Title="Pašalinimo patvirtinimas" ConfirmRemove.Text="Ar tikrai norite pašalinti '$1'?" + Output.ConnectFail.Title="Nepavyko prisijungti" Output.ConnectFail.BadPath="Neteisingas kelias arba jungimosi URL. Prašome patikrinti nustatymus ir įsitikinti, kad jie teisingi." Output.ConnectFail.ConnectFailed="Nepavyko prisijungti prie serverio" Output.ConnectFail.Error="Netikėta klaida bandant jungtis į serverį. Daugiau informacijos žurnalo faile." Output.ConnectFail.Disconnected="Atjungtas nuo serverio." + Output.RecordFail.Title="Nepavyko pradėti įrašo" Output.RecordFail.Unsupported="Išvesties formatas nepalaikomas arba nepalaiko daugiau vieno garso takelio. Prašome patikrinti nustatymus ir bandyti vėl." Output.RecordNoSpace.Title="Nepakanka vietos diske" @@ -120,12 +127,6 @@ LogReturnDialog="Žurnalas įkeltas sėkmingai" LogReturnDialog.CopyURL="Kopijuoti adresą" LogReturnDialog.ErrorUploadingLog="Žurnalo failo įkėlimo klaida" -LicenseAgreement="Licencinė sutartis" -LicenseAgreement.PleaseReview="Prašome peržiūrėti licencijos sąlygas prieš OBS naudojimą. Naudodamasis šia programa, jūs pripažįstate, kad perskaitėte ir sutikite su GNU General Public License v2.0 (anglų k.) sąlygomis. Prašome slinkti žemyn, kad pamatytumėte likusią sutarties dalį." -LicenseAgreement.ClickIAgreeToContinue="Jei sutinkate su sutarties sąlygomis, pasirinkite Aš sutinku, kad tęsti. Jūs privalote sutikti su sutartimi, kad naudotis OBS." -LicenseAgreement.IAgree="Sutinku" -LicenseAgreement.Exit="Išeiti" - Remux.SourceFile="OBS įrašas" Remux.TargetFile="Paskirties failas" Remux.Remux="Permiksuoti" @@ -133,10 +134,6 @@ Remux.OBSRecording="OBS įrašas" Remux.FinishedTitle="Permiksavimas baigtas" Remux.Finished="Įrašas permiksuotas" Remux.FinishedError="Įrašas permiksuotas, tačiau failas gali būti neužbaigtas" -Remux.SelectRecording="Pasirinkite OBS įrašą …" -Remux.SelectTarget="Pasirinkite paskirties failą …" -Remux.FileExistsTitle="Toks paskirties failas jau yra" -Remux.FileExists="Toks paskirties failas jau yra, ar norite jį pakeisti?" Remux.ExitUnfinishedTitle="Vyksta permiksavimimas" Remux.ExitUnfinished="Permiksavimas nebaigtas. Sustabdžius dabar, paskirites failas gali būti nepanaudojamas.\nAr esate tikras, kad norite sustabdyti permiksavimą?" @@ -155,6 +152,7 @@ Basic.DisplayCapture="Ekrano perėmimas" Basic.Main.PreviewConextMenu.Enable="Įjungti peržiūrą" + ScaleFiltering="Mastelio filtras" ScaleFiltering.Point="Taškas" ScaleFiltering.Bilinear="Dvilinijinis" @@ -242,33 +240,33 @@ Basic.Main.ForceStopStreaming="Stabdyti transliavimą (atmesti vėlavimą)" Basic.MainMenu.File="&Failas" Basic.MainMenu.File.Export="&Eksportuoti" Basic.MainMenu.File.Import="&Importuoti" -Basic.MainMenu.File.ShowRecordings="Parodyti Į&rašus" +Basic.MainMenu.File.ShowRecordings="Pa&rodyti Įrašus" Basic.MainMenu.File.Remux="Per&miksuoti įrašus" Basic.MainMenu.File.Settings="Nu&statymai" Basic.MainMenu.File.ShowSettingsFolder="Parodyti nustatymų katalogą" Basic.MainMenu.File.ShowProfileFolder="Parodyti profilių katalogą" -Basic.MainMenu.AlwaysOnTop="Visuomet &viršuje" -Basic.MainMenu.File.Exit="Iš&eiti" +Basic.MainMenu.AlwaysOnTop="Visuomet viršuje (&A)" +Basic.MainMenu.File.Exit="Išeiti (&X)" -Basic.MainMenu.Edit="&Redaguoti" -Basic.MainMenu.Edit.Undo="&Atšaukti" -Basic.MainMenu.Edit.Redo="&Gražinti atšaukimą" -Basic.MainMenu.Edit.UndoAction="&Atšaukti $1" -Basic.MainMenu.Edit.RedoAction="&Gražinti atšaukimą $1" +Basic.MainMenu.Edit="R&edaguoti" +Basic.MainMenu.Edit.Undo="Atša&ukti" +Basic.MainMenu.Edit.Redo="G&ražinti atšaukimą" +Basic.MainMenu.Edit.UndoAction="Atša&ukti $1" +Basic.MainMenu.Edit.RedoAction="G&ražinti atšaukimą $1" Basic.MainMenu.Edit.Transform="&Transformuoti" -Basic.MainMenu.Edit.Transform.EditTransform="&Redaguoti transformaciją..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Atšaukti transformaciją" +Basic.MainMenu.Edit.Transform.EditTransform="R&edaguoti transformaciją..." +Basic.MainMenu.Edit.Transform.ResetTransform="Atšaukti t&ransformaciją" Basic.MainMenu.Edit.Transform.Rotate90CW="Pasukti 90 laipsnių pagal LL" Basic.MainMenu.Edit.Transform.Rotate90CCW="Pasukti 90 laipsnių prieš LL" Basic.MainMenu.Edit.Transform.Rotate180="Pasukti 180 laipsnių" Basic.MainMenu.Edit.Transform.FlipHorizontal="Apversti &horizontaliai" Basic.MainMenu.Edit.Transform.FlipVertical="Apversti &vertikaliai" -Basic.MainMenu.Edit.Transform.FitToScreen="Sutalpinti į ekraną" -Basic.MainMenu.Edit.Order="&Rikiavimas" -Basic.MainMenu.Edit.Order.MoveUp="Perkelti aukštyn" -Basic.MainMenu.Edit.Order.MoveDown="Perkelti žemyn" -Basic.MainMenu.Edit.Order.MoveToTop="Perkelti į viršų" -Basic.MainMenu.Edit.Order.MoveToBottom="Perkelti į apačią" +Basic.MainMenu.Edit.Transform.FitToScreen="Sutalpinti į ekraną (&F)" +Basic.MainMenu.Edit.Order="Rikiavimas (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Perkelti a&ukštyn" +Basic.MainMenu.Edit.Order.MoveDown="Perkelti žemyn (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Perkel&ti į viršų" +Basic.MainMenu.Edit.Order.MoveToBottom="Perkelti į apačią (&B)" @@ -292,11 +290,8 @@ Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Žemiau vidutinio" Basic.Settings.Advanced.General.ProcessPriority.Idle="Tolygus" Basic.Settings.Advanced.Audio.BufferingTime="Garso Sušvelninimo Laikas" Basic.Settings.Advanced.Video.ColorFormat="Spalvos formatas" -Basic.Settings.Advanced.Video.ColorSpace="YUV Spalvų Erdvė" -Basic.Settings.Advanced.Video.ColorRange="YUV Spalvų Diapazonas" Basic.Settings.Advanced.Video.ColorRange.Partial="Dalinis" Basic.Settings.Advanced.Video.ColorRange.Full="Pilnas" -Basic.Settings.Advanced.Audio.MonitoringDevice="Garso prietaisas" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Numatytas" Basic.Settings.Advanced.StreamDelay="Srauto Vėlavimas" Basic.Settings.Advanced.StreamDelay.Duration="Trukmė (sekundėmis)" @@ -306,7 +301,6 @@ Basic.Settings.Advanced.Network="Tinklas" Basic.Settings.Advanced.Network.BindToIP="Priskirti prie IP" Basic.AdvAudio.Name="Prietaisas" -Basic.AdvAudio.Volume="Garsumas (%)" @@ -329,3 +323,6 @@ FinalScene.Text="Turi būti bent viena scena." + + + diff --git a/UI/data/locale/mn-MN.ini b/UI/data/locale/mn-MN.ini new file mode 100644 index 0000000..8659336 --- /dev/null +++ b/UI/data/locale/mn-MN.ini @@ -0,0 +1,335 @@ + +Language="Монгол" +Region="Монгол" + +OK="За" +Apply="Хэрэглэх" +Cancel="Цуцлах" +Close="Хаах" +Save="Хадгалах" +Discard="Болих" +Disable="Хориглох" +Yes="Тийм" +No="Үгүй" +Add="Нэмэх" +Remove="Хасах" +Rename="Шинээр нэрлэх" +Interact="Харилцан ажиллах" +Filters="Шүүлтүүрүүд" +Properties="Шинж чанар" +MoveUp="Дээшээ зөө" +MoveDown="Доошоо зөө" +Settings="Тохиргоо" +Display="Харагдах байдал" +Name="Нэр" +Exit="Гарах" +Mixer="Холигч" +Browse="Хайх" +Mono="Моно" +Stereo="Стерео" +SceneProjector="Дэлгэц дүүрэн Проектор (Хөшиг)" +SceneWindow="Цонх дүүрэн Проектор (Хөшиг)" +Clear="Арилгах" +Revert="Буцаах" +Show="Харуулах" +Hide="Нуух" +UnhideAll="Бүгдийг Харуулах" +Untitled="Гарчиггүй" +New="Шинэ" +Duplicate="Хувилах" +Enable="Идэвхжүүлэх" +DisableOSXVSync="OSX V-Sync-ийг хориглох" +ResetOSXVSyncOnExit="OSX V-Sync-ийг гарахдаа хэвэнд нь оруулах" +Transition="Шилжилт" +QuickTransitions="Түргэн шилжилт" +Left="Зүүн" +Right="Баруун" +Top="Дээд хэсэг" +Bottom="Доод хэсэг" +Hours="Цаг" +Minutes="Минут" +Seconds="Секунд" +Import="Импортлох" +Export="Экспортлох" +Copy="Хуулах" +Paste="Зөөж тавих" +Next="Дараачийх" +Back="Буцах" +None="Байхгүй" +StudioMode.Program="Програм" +Group="Групп" + +AlreadyRunning.Title="OBS нь аль хэдийнээ ажиллаж байна" +AlreadyRunning.LaunchAnyway="Юутай ч эхлүүл" + + + + + +BandwidthTest.Region="Бүс нутаг" +BandwidthTest.Region.US="Нэгдсэн Улс" +BandwidthTest.Region.EU="Европ" +BandwidthTest.Region.Asia="Ази" +BandwidthTest.Region.Other="Бусад" + + +Basic.AutoConfig.ApplySettings="Тохиргоог хэрэглэх" +Basic.AutoConfig.VideoPage="Видео Тохиргоо" +Basic.AutoConfig.StreamPage.Service="Үйлчилгээ" +Basic.AutoConfig.StreamPage.Service.ShowAll="Бүгдийг харуул..." +Basic.AutoConfig.StreamPage.Server="Сервер" +Basic.AutoConfig.StreamPage.StreamKey="Цацалтын түлхүүр үгс" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Линк)" + +Basic.Stats.CPUUsage="CPU-ний хэрэглээ" +Basic.Stats.Output.Stream="Цацалт" +Basic.Stats.Output.Recording="Бичлэг хийж байна" +Basic.Stats.Status="Статус" +Basic.Stats.Status.Recording="Бичлэг хийж байна" +Basic.Stats.Status.Live="Шууд" +Basic.Stats.Status.Reconnecting="Дахин холбогдож байна" +Basic.Stats.Status.Inactive="Идэвхигүй" + + +Updater.Title="Шинж шинэчлэлт билэн байна" +Updater.Text="Шинэ шинэчлэл нь билэн байна:" +Updater.UpdateNow="Одоо шинэчлэх" +Updater.RemindMeLater="Дараа нь надад сануул" +Updater.Skip="Хувилбар алгасах" + +QuickTransitions.DuplicateScene="Давхардсан хөшиг" +QuickTransitions.HotkeyName="Түргэн шилжилт: %1" + +Basic.SceneTransitions="Хөшигний шилжилт" +Basic.TransitionDuration="Үргэлжлэх хугацаа" +Basic.TogglePreviewProgramMode="Студи Горим" + +TransitionNameDlg.Title="Шилжүүлэгчийн нэр" + +TitleBar.Profile="Профайл" +TitleBar.Scenes="Хөшиг" + +NameExists.Title="Нэр нь аль хэдийн байна" +NameExists.Text="Нэр нь аль хэдийнээ хэрэглэгдэж байна." + +NoNameEntered.Text="Та хоосон нэр ашиглах боломжгүй." + +ConfirmStart.Title="Цацаж эхлэх үү?" + +ConfirmStop.Title="Цацалтыг зогсоох?" + + +ConfirmExit.Title="OBS-ийг хаах" + +ConfirmRemove.Title="Хасалтыг батлах" +ConfirmRemove.Text="Та '$1' устгахыг хүсч байгаадаа итгэлтэй байна уу?" + +Output.StartStreamFailed="Цацалт хийж эхлэхгээд амжилтгүй болсон" + + +Output.ConnectFail.Disconnected="Серверээс салгагдсан байна." + + +Output.RecordFail.Title="Бичлэг хийх эхлэхгээд амжилтгүй болсон" +Output.RecordError.Title="Бичлэгийн алдаа" +Output.RecordError.Msg="Бичлэг хийж байх үед тодорхойгүй алдаа гарлаа." +Output.ReplayBuffer.NoHotkey.Title="Ямарч богино холбооc хийгдээгүй байна!" + + + +Remux.ClearAll="Бүх зүйлсийг арилгах" + + + +Basic.Scene="Хөшиг" + + + + + + +Basic.Main.AddSceneDlg.Title="Хөшиг нэмэх" +Basic.Main.AddSceneDlg.Text="Хөшигний нэрийг оруулна уу" + +Basic.Main.DefaultSceneName.Text="Хөшиг %1" + +Basic.Main.AddSceneCollection.Title="Хөшигний Цуглуулга Нэмэх" +Basic.Main.AddSceneCollection.Text="Хөшигний цуглуулганы нэрийг оруулна уу" + +Basic.Main.RenameSceneCollection.Title="Хөшигний цуглуулганы нэрийг өөрчлөх" + + + + + + + +Basic.PropertiesWindow.SelectColor="Өнгө сонгох" +Basic.PropertiesWindow.SelectFont="Фонт сонгох" + + + + +Basic.Filters="Шүүлтүүрүүд" + +Basic.TransformWindow="Хөшигний зүйлийг өөрчлөх" +Basic.TransformWindow.Position="Байрлал" +Basic.TransformWindow.Size="Хэмжээ" +Basic.TransformWindow.Crop="Тайрах" + +Basic.TransformWindow.Alignment.TopLeft="Зүүн дээд тал" +Basic.TransformWindow.Alignment.TopCenter="Дээтлийн Төвдөн" +Basic.TransformWindow.Alignment.TopRight="Баруун дээд тал" +Basic.TransformWindow.Alignment.CenterLeft="Зүүн төв" +Basic.TransformWindow.Alignment.Center="Төвд нь" +Basic.TransformWindow.Alignment.CenterRight="Баруун төв" +Basic.TransformWindow.Alignment.BottomLeft="Зүүн доод" +Basic.TransformWindow.Alignment.BottomCenter="Доотлын Төвдөн" +Basic.TransformWindow.Alignment.BottomRight="Баруун доод" + +Basic.TransformWindow.BoundsType.None="Хил хязгааргүй" +Basic.TransformWindow.BoundsType.MaxOnly="Зөвхөн хамгийн их хэмжээ" + +Basic.Main.AddSourceHelp.Title="Эх үүсвэр нэмэх боломжгүй" + +Basic.Main.Scenes="Хөшиг" +Basic.Main.Sources="Эх үүсвэр" +Basic.Main.Controls="Удирдлага" +Basic.Main.Connecting="Холбогдож байна..." +Basic.Main.StartRecording="Бичлэг хийж эхлэх" +Basic.Main.StartStreaming="Цацаж эхлэх" +Basic.Main.StopRecording="Бичлэгийг зогсоох" +Basic.Main.StopStreaming="Цацалтыг зогсоох" +Basic.Main.Ungroup="Груплэхгүй" + +Basic.MainMenu.File.Settings="Тохиргоо (&S)" +Basic.MainMenu.File.ShowSettingsFolder="Тохиргооны хавтасыг харуулах" +Basic.MainMenu.File.ShowProfileFolder="Профайлын хавтасыг харуулах" +Basic.MainMenu.AlwaysOnTop="Үргэлж дээд хэсэгт (&A)" +Basic.MainMenu.File.Exit="Гарах (&X)" + +Basic.MainMenu.Edit.Scale.Window="Цонх дүүрэн болгох" + + +Basic.MainMenu.SceneCollection="Хөшигний цуглуулга (&S)" +Basic.MainMenu.Profile="Профайл (&P)" +Basic.MainMenu.SceneCollection.Import="Хөшигний цуглуулга импортлох" +Basic.MainMenu.SceneCollection.Export="Хөшигний цуглуулагыг экспортлох" + +Basic.MainMenu.Tools="Багаж (&T)" + +Basic.MainMenu.Help="Тусламж (&H)" +Basic.MainMenu.Help.HelpPortal="Портал Тусламж (&P)" +Basic.MainMenu.Help.Website="Вэбсайтаар Зочлох (&W)" +Basic.MainMenu.Help.CrashLogs="Эвдрэлийн мэдээлэл (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Эвдрэлийн мэдээлэлүүдийг харуулах (&S)" +Basic.MainMenu.Help.About="Тухай (&A)" + +Basic.Settings.ConfirmTitle="Өөрчлөлтийг батлах" + +Basic.Settings.General="Ерөнхий" +Basic.Settings.General.Theme="Загвар" +Basic.Settings.General.Language="Хэл" + +Basic.Settings.Stream="Цацалт" +Basic.Settings.Stream.StreamType="Цацалтын төрөл" + +Basic.Settings.Output="Гаралт" +Basic.Settings.Output.Format="Бичлэгийн формат" +Basic.Settings.Output.Encoder="Кодлогч" +Basic.Settings.Output.SelectDirectory="Бичлэгийн Лавлахыг Сонгох" +Basic.Settings.Output.SelectFile="Бичлэгийн Файлыг Сонго" +Basic.Settings.Output.EnforceBitrate="Шууд цацалтын сервcийy хурдыг хязгаарлах" +Basic.Settings.Output.Mode="Гаралтын Горим" +Basic.Settings.Output.Mode.Simple="Энгийн" +Basic.Settings.Output.Mode.Adv="Дэвшилттэй" +Basic.Settings.Output.VideoBitrate="Видео Битийн хурд" +Basic.Settings.Output.AudioBitrate="Аудио Битийн хурд" +Basic.Settings.Output.MaxRetries="Олон удаа оролдлого хийх" + + +Basic.Settings.Output.Adv.Recording.Type="Төрөл" +Basic.Settings.Output.Adv.Recording.Type.Standard="Стандарт" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Бүх файлууд" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Аудио" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Видео" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="Видео Кодлогч" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="Аудио Кодлогч" + + + +Basic.Settings.Video="Видео" +Basic.Settings.Video.Adapter="Видео Адаптер" +Basic.Settings.Video.Numerator="Тоонжуулагч" +Basic.Settings.Video.Denominator="Деноматор" +Basic.Settings.Video.Renderer="Рэндэрлэгч" +Basic.Settings.Video.DisableAero="Aero-г идэвхгүй болгох" + + +Basic.Settings.Audio="Аудио" +Basic.Settings.Audio.Channels="Сувгууд" +Basic.Settings.Audio.EnablePushToMute="Дарж-хаахыг Идэвхжүүлэх" +Basic.Settings.Audio.EnablePushToTalk="Дарж-ярихыг Идэвхжүүлэх" + +Basic.Settings.Advanced="Дэвшилттэй" +Basic.Settings.Advanced.General.ProcessPriority="Үйл явцын чиглэл" +Basic.Settings.Advanced.General.ProcessPriority.High="Их" +Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Хэвийнээс Дээгүүр" +Basic.Settings.Advanced.General.ProcessPriority.Normal="Хэвийн" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Хэвийнээс Доогуур" +Basic.Settings.Advanced.General.ProcessPriority.Idle="Идэвхигүй" +Basic.Settings.Advanced.StreamDelay="Цацалтын хоцролт" +Basic.Settings.Advanced.Network="Сүлжээ" +Basic.Settings.Advanced.Network.BindToIP="IP холболт хийх" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Бага зэрэгийн хоцрогдолтой горим" + +Basic.AdvAudio.Name="Нэр" +Basic.AdvAudio.Balance="Тэнцвэржүүлэх" + +Basic.Settings.Hotkeys="Богино холбооc" + +Basic.Hotkeys.SelectScene="Хөшиг рүү солих" + +Basic.SystemTray.Show="Харуулах" +Basic.SystemTray.Hide="Нуух" + + +Hotkeys.Insert="Оруулах" +Hotkeys.Delete="Устгах" +Hotkeys.Home="Гэр" +Hotkeys.End="Төгсгөл" +Hotkeys.PageUp="Нэг хуудас дээш" +Hotkeys.PageDown="Нэг хуудас доош" +Hotkeys.Print="Хэвлэх" +Hotkeys.Pause="Пауз авах" +Hotkeys.Left="Зүүн" +Hotkeys.Right="Баруун" +Hotkeys.Up="Дээшээ" +Hotkeys.Down="Доошоо" +Hotkeys.Windows="Цонх" +Hotkeys.Menu="Цэс" +Hotkeys.Space="Зай" + +Mute="Хаах" +Unmute="Нээх" +Push-to-mute="Дарж хаах" +Push-to-talk="Дарж ярих" + + + +FinalScene.Title="Хөшиг устгах" + +NoSources.Title="Эх сурвалж байхгүй" + +ChangeBG="Өнгө өгөх" +CustomColor="Өөр өнгө" + + +About="Тухай" +About.Info="OBS Studio нь үнэгүй ба нээлттэй хөгжүүлэгдэж байгаа видео бичлэг хийж мөн шууд цацалт хийдэг програм хангамж юм." +About.GetInvolved="Үүнд оролцох" +About.Authors="Зохиогчид" +About.License="Лиценз" + + + diff --git a/UI/data/locale/ms-MY.ini b/UI/data/locale/ms-MY.ini index 1413cc0..23d88ba 100644 --- a/UI/data/locale/ms-MY.ini +++ b/UI/data/locale/ms-MY.ini @@ -63,6 +63,9 @@ Back="Kembali" + + + BandwidthTest.Region.EU="Eropah" BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Lain-lain" @@ -83,6 +86,7 @@ Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" + QuickTransitions.SwapScenes="Tukar Pratonton/Pengeluaran Adegan Selepas Peralihan" QuickTransitions.SwapScenesTT="Menukarkan pratonton dan pengeluaran adegan-adegan selepas peralihan(jika pengeluaran adegan mash wujud).\nIni tidak akan mengundurkan sebarang perubahan yang mungkin telah dilakukan pada pengeluaran adegan yang asal." QuickTransitions.DuplicateScene="Klonkan Adegan" @@ -116,6 +120,7 @@ ConfirmStart.Text="Adakah anda pasti anda mahu memulakan 'stream'?" ConfirmStop.Title="Berhenti 'Stream'?" ConfirmStop.Text="Adakah anda pasti anda mahu menghentikan 'stream'?" + ConfirmExit.Title="Tutup OBS?" ConfirmExit.Text="OBS kini sedang aktif. Semua 'stream'/rakaman akan ditutup. Adakah anda pasti anda mahu tutup(OBS)?" @@ -124,6 +129,7 @@ ConfirmRemove.Text="Adakah anda pasti untuk buang '$1'?" ConfirmRemove.TextMultiple="Adakah anda yakin untuk buang %1 barang?" + Output.ConnectFail.Title="Penyambungan gagal" Output.ConnectFail.BadPath="Sambungan URL atau Laluan yang tidak sah. Sila semak semula tetapan anda to mengesahkan bahawa semuanya sah." Output.ConnectFail.ConnectFailed="Penyambungan ke pelayan gagal" @@ -131,6 +137,7 @@ Output.ConnectFail.InvalidStream="Tidak dapat mencapai saluran yang ditetapkan/k Output.ConnectFail.Error="Ralat tidak dijangka berlaku sewaktu percubaan menyambung ke pelayan. Maklumat lanjut di dalam fail log." Output.ConnectFail.Disconnected="Terputus daripada pelayan." + Output.RecordFail.Title="Gagal memulakan rakaman" Output.RecordFail.Unsupported="Format pengeluaran tidak disokong atau tidak membenarkan lebih daripada satu trek audio. Sila semak tetapan anda dan cuba lagi." Output.RecordNoSpace.Title="Ruang simpanan tidak cukup" @@ -145,12 +152,6 @@ LogReturnDialog="Muat naik Log Berjaya" LogReturnDialog.CopyURL="Salin URL" LogReturnDialog.ErrorUploadingLog="Ralat memuat naikkan fail log" -LicenseAgreement="Perjanjian Lesen Penggunaan" -LicenseAgreement.PleaseReview="Sila semak syarat lesen penggunaan sebelum menggunakan OBS.Dengan menggunakan program ini,anda mengakui bahawa anda telah membaca dan bersetuju dengan syarat-syarat GNU General Public License v2.0.Sila 'scroll' ke bawah untuk baca persetujuan yang selebihnya." -LicenseAgreement.ClickIAgreeToContinue="Jika anda bersetuju dengan syarat-syarat perjanjian, klik 'Saya Setuju' untuk teruskan. Anda perlu bersetuju dengan perjanjian untuk menggunakan OBS." -LicenseAgreement.IAgree="Saya Setuju" -LicenseAgreement.Exit="Keluar" - Remux.SourceFile="Rakaman OBS" Remux.TargetFile="Fail Sasaran" Remux.Remux="Tukar format" @@ -158,10 +159,6 @@ Remux.OBSRecording="Rakaman OBS" Remux.FinishedTitle="Penukaran format selesai" Remux.Finished="Format rakaman ditukar" Remux.FinishedError="Format rakaman ditukar, tetapi fail itu mungkin tidak lengkap" -Remux.SelectRecording="Pilih Rakaman OBS …" -Remux.SelectTarget="Pilih fail sasaran …" -Remux.FileExistsTitle="Fail sasaran wujud" -Remux.FileExists="Fail sasaran wujud, adakah anda mahu gantikannya?" Remux.ExitUnfinishedTitle="Penukaran format sedang dijalankan" Remux.ExitUnfinished="Penukaran format masih belum selesai, menghentikannya sekarang boleh menyebabkan fail sasaran tidak boleh digunakan.\nAdakah anda pasti untuk memberhentikan proses ini?" @@ -180,6 +177,7 @@ Basic.DisplayCapture="Paparan Penuh" Basic.Main.PreviewConextMenu.Enable="Benarkan Pratonton" + ScaleFiltering="Skala Tapisan" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" @@ -298,30 +296,30 @@ Basic.MainMenu.File="&Fail" Basic.MainMenu.File.Export="&Export" Basic.MainMenu.File.Import="&Import" Basic.MainMenu.File.ShowRecordings="Papar &Rakaman" -Basic.MainMenu.File.Remux="Format& rakaman" -Basic.MainMenu.File.Settings="&Tetapan" +Basic.MainMenu.File.Remux="For&matrakaman" +Basic.MainMenu.File.Settings="Tetapan (&S)" Basic.MainMenu.File.ShowSettingsFolder="Tunjukkan Folder Tetapan" Basic.MainMenu.File.ShowProfileFolder="Tunjukkan Folder Profil" -Basic.MainMenu.AlwaysOnTop="&Sentiasa Di Atas" +Basic.MainMenu.AlwaysOnTop="Senti&asa Di Atas" Basic.MainMenu.File.Exit="Keluar (&X)" -Basic.MainMenu.Edit="&Sunting" +Basic.MainMenu.Edit="Sunting (&E)" Basic.MainMenu.Edit.Undo="&Ubah Balik" Basic.MainMenu.Edit.Redo="Buat Semula (&R)" Basic.MainMenu.Edit.UndoAction="&Ubah Balik $1" -Basic.MainMenu.Edit.RedoAction="&Ubah Semula $1" -Basic.MainMenu.Edit.LockPreview="&Kunci Pratonton" -Basic.MainMenu.Edit.Transform="&Ubah" -Basic.MainMenu.Edit.Transform.EditTransform="&Sunting Perubahan..." +Basic.MainMenu.Edit.RedoAction="Ubah Semula $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Kunci Pratonton (&L)" +Basic.MainMenu.Edit.Transform="Ubah (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Sunting P&erubahan..." Basic.MainMenu.Edit.Transform.Rotate90CW="Putarkan 90 darjah mengikut arah jam" Basic.MainMenu.Edit.Transform.Rotate90CCW="Putarkan 90 darjah melawan arah jam" Basic.MainMenu.Edit.Transform.Rotate180="Putarkan 180 darjah" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip secara &Mendatar" -Basic.MainMenu.Edit.Transform.FlipVertical="Flip secara &Menegak" -Basic.MainMenu.Edit.Transform.FitToScreen="&Muat di skrin" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Regangkan ke skrin" -Basic.MainMenu.Edit.Order.MoveUp="Gerakkan ke &atas" -Basic.MainMenu.Edit.Order.MoveDown="Gerakkan ke &bawah" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Flip secara Mendatar (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Flip secara Menegak (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Muat di skrin (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Regangkan ke &skrin" +Basic.MainMenu.Edit.Order.MoveUp="Gerakkan ke atas (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Gerakkan ke bawah (&D)" Basic.MainMenu.Profile="&Profil" @@ -329,10 +327,10 @@ Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Help.Website="Lawat laman &Web" Basic.MainMenu.Help.Logs="Fail &Log" -Basic.MainMenu.Help.Logs.ShowLogs="&Tunjukkan Fail-Fail Log" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Muat naik Fail Log &Kini" -Basic.MainMenu.Help.Logs.UploadLastLog="Muat naik &Fail Log Terakhir" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Paparkan Log Semasa" +Basic.MainMenu.Help.Logs.ShowLogs="Tunjukkan Fail-Fail Log (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Muat naik Fail Log Kini (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Muat naik Fai&l Log Terakhir" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Paparkan Log Semasa (&V)" Basic.MainMenu.Help.CheckForUpdates="Semak Versi Baharu" Basic.Settings.ProgramRestart="Program ini mesti dimulakan semula untuk tetapan-tetapan ini berkesan." @@ -454,3 +452,6 @@ Push-to-talk="Tekan-untuk-cakap" + + + diff --git a/UI/data/locale/nb-NO.ini b/UI/data/locale/nb-NO.ini index 35561a4..94fdd8c 100644 --- a/UI/data/locale/nb-NO.ini +++ b/UI/data/locale/nb-NO.ini @@ -36,8 +36,8 @@ StudioProgramWindow="Projektorvindu (Program)" PreviewWindow="Projektor i vindu (forhåndsvisning)" SceneWindow="Projektor i vindu (scene)" SourceWindow="Projektor i vindu (kilde)" -MultiviewProjector="Multiview (Fullskjerm)" -MultiviewWindowed="Multiview (Vindu)" +MultiviewProjector="Flervisning (Fullskjerm)" +MultiviewWindowed="Flervisning (Vindu)" Clear="Tøm" Revert="Tilbakestill" Show="Vis" @@ -73,21 +73,47 @@ Next="Neste" Back="Tilbake" Defaults="Standardinnstillinger" HideMixer="Skjul i mikser" -TransitionOverride="Tilsett Overgang" +TransitionOverride="Overgangsoverkjøring" None="Ingen" StudioMode.Preview="Forhåndsvisning" StudioMode.Program="Program" -ShowInMultiview="Vis i Multiview" +ShowInMultiview="Vis i flervisningen" VerticalLayout="Loddrett oppsett" Group="Gruppe" +DoNotShowAgain="Ikke vis denne igjen" +Default="(Standard)" +Calculating="Kalkulerer..." AlreadyRunning.Title="OBS kjører allerede" AlreadyRunning.Text="OBS kjører allerede! Med mindre du ikke mente dette, vennligst lukk alle eksisterende kjørende tilfeller av OBS før du kjører noen nye. Hvis du har satt OBS til å minimere til systemkurven, vennligst sjekk om den fortsatt kjører der." AlreadyRunning.LaunchAnyway="Start uansett" +DockCloseWarning.Title="Lukker festbart vindu" +DockCloseWarning.Text="Du stengte nettopp et festbart vindu. Hvis du vil vise det igjen, kan du gå til Vis → Festede elementer i menylinjen." + +Auth.Authing.Title="Autentiserer..." +Auth.Authing.Text="Autentiserer med %1, vennligst vent..." +Auth.AuthFailure.Title="Autentiseringsfeil" +Auth.AuthFailure.Text="Mislyktes i å autentiseres opp mot %1:\n\n%2: %3" +Auth.InvalidScope.Title="Autentisering er påkrevd" +Auth.InvalidScope.Text="Autentiseringskravene til %1 har blitt forandret. Noen egenskaper vil kanskje ikke være tilgjengelige." +Auth.LoadingChannel.Title="Laster informasjon om kanalen..." +Auth.LoadingChannel.Text="Laster kanalinformasjon for %1, vennligst vent..." +Auth.ChannelFailure.Title="Mislyktes i å laste inn kanalen" +Auth.ChannelFailure.Text="Mislyktes i å laste ned kanalinformasjon om %1\n\n%2: %3" +Auth.Chat="Nettprat" +Auth.StreamInfo="Informasjon om sendingen" +TwitchAuth.Stats="Twitch-statistikker" +TwitchAuth.Feed="Twitch-aktivitetsfeed" +TwitchAuth.TwoFactorFail.Title="Kunne ikke etterspørre strømme-nøkkel" +TwitchAuth.TwoFactorFail.Text="OBS kunne ikke koble til din Twitch-konto. Vennligst forsikre at to-faktorautentisering er satt opp i dine Twitch sikkerhetsinstillinger, siden dette er nødvendig for å strømme." + Copy.Filters="Kopier filtre" Paste.Filters="Lim inn filtre" +BrowserPanelInit.Title="Initialiserer nettleser..." +BrowserPanelInit.Text="Initialiserer nettleser, vennligst vent..." + BandwidthTest.Region="Region" BandwidthTest.Region.US="USA" BandwidthTest.Region.EU="Europa" @@ -95,15 +121,13 @@ BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Andre" Basic.FirstStartup.RunWizard="Vil du kjøre veiviseren for automatisk konfigurasjon? Du kan også manuelt konfigurere innstillingene ved å klikke på Innstillinger-knappen i hovedvinduet." -Basic.FirstStartup.RunWizard.BetaWarning="(Merk: veiviseren for automatisk konfigurasjon er i beta)" Basic.FirstStartup.RunWizard.NoClicked="Hvis du ombestemmer deg, kan du kjøre veiviseren for automatisk konfigurasjon fra Verktøy-menyen." Basic.AutoConfig="Auto-oppsettsveiviser" -Basic.AutoConfig.Beta="Auto-oppsettsveiviser (Beta)" Basic.AutoConfig.ApplySettings="Bruk innstillinger" Basic.AutoConfig.StartPage="Bruksinformasjon" Basic.AutoConfig.StartPage.SubTitle="Angi hva du vil bruke programmet til" -Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimaliser for streaming, innspilling er sekundær" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimaliser for strømming, innspilling kommer i andre rekke" Basic.AutoConfig.StartPage.PrioritizeRecording="Optimaliser for innspilling, jeg skal ikke streame" Basic.AutoConfig.VideoPage="Videoinnstillinger" Basic.AutoConfig.VideoPage.SubTitle="Velg de ønskede videoinnstillingene du ønsker å bruke" @@ -115,15 +139,21 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 eller 30, men foretrekk høy op Basic.AutoConfig.VideoPage.CanvasExplanation="NB: Oppløsningen på lerretet er ikke nødvendigvis den samme oppløsningen som du vil kringkaste eller ta opp med. Den faktiske kringkastings- eller opptaks-oppløsningen kan bli nedskalert fra størrelsen på lerretet for å redusere ressursbruken eller bitfrekvensen." Basic.AutoConfig.StreamPage="Strømmens informasjon" Basic.AutoConfig.StreamPage.SubTitle="Vennligst skriv inn strømmens informasjon" +Basic.AutoConfig.StreamPage.ConnectAccount="Koble til med konto (valgfritt)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Koble fra kontoen" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Vil du koble fra kontoen?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Endringen vil bli benyttet umiddelbart. Er du sikker på at du vil koble fra kontoen din?" +Basic.AutoConfig.StreamPage.UseStreamKey="Bruk strømmenøkkel" Basic.AutoConfig.StreamPage.Service="Tjeneste" Basic.AutoConfig.StreamPage.Service.ShowAll="Vis alle..." +Basic.AutoConfig.StreamPage.Service.Custom="Egendefinert …" Basic.AutoConfig.StreamPage.Server="Tjener" Basic.AutoConfig.StreamPage.StreamKey="Strømmenøkkel" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Lenke)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Beregn bitfrekvensen med en båndbreddetest (Kan ta noen minutter)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Foretrekk maskinvarekoding" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Maskinvarekoding reduserer mesteparten av CPU-bruken, men kan kreve mer bitrate for å få samme nivå av kvalitet." -Basic.AutoConfig.StreamPage.StreamWarning.Title="Strømmeadvarsel" +Basic.AutoConfig.StreamPage.StreamWarning.Title="Direktesendingsadvarsel" Basic.AutoConfig.StreamPage.StreamWarning.Text="Båndbreddetesten kommer til å kringkaste tilfeldig videodata uten lyd til kanalen din. Om du kan, er det anbefalt at du midlertidig skrur av alternativet for å lagre videoer, samt sette kanalen din som privat til testen er ferdig. Vil du fortsette?" Basic.AutoConfig.TestPage="Sluttresultater" Basic.AutoConfig.TestPage.SubTitle.Testing="Programmet kjører en rekke tester for å beregne de mest ideelle innstillingene" @@ -140,7 +170,7 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="Tester %1x%2 %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Kringkastingsenkoder" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Opptakskoder" Basic.AutoConfig.TestPage.Result.Header="Programmet har estimert at disse innstillingene er den mest ideelle for deg:" -Basic.AutoConfig.TestPage.Result.Footer="For å bruke disse innstillingene, klikker du Bruk innstillinger. Å konfigurere veiviseren og prøv på nytt, klikker du tilbake. For å konfigurer innstillinger manuelt selv, klikk Avbryt og åpne innstillinger." +Basic.AutoConfig.TestPage.Result.Footer="For å bruke disse innstillingene, klikker du Bruk innstillinger. Å konfigurere veiviseren og prøv på nytt, klikker du tilbake. For å konfigurer innstillinger manuelt selv, klikk Avbryt og åpne innstillinger." Basic.Stats="Statistikk" Basic.Stats.CPUUsage="CPU-bruk" @@ -159,12 +189,16 @@ Basic.Stats.Status.Inactive="Inaktiv" Basic.Stats.DroppedFrames="Tapte bilder (nettverk)" Basic.Stats.MegabytesSent="Total datamengde ut" Basic.Stats.Bitrate="Bitfrekvens" +Basic.Stats.DiskFullIn="Lagringsplass fullt om (ca.)" + +ResetUIWarning.Title="Er du sikker på at du vil tilbakestille grensesnittet?" +ResetUIWarning.Text="Å tilbakestille grensesnittet, vil skjule andre kildevisninger. Du vil måtte uskjule disse visningene fra visningsmenyen hvis du vil at de skal være synlige?\n\nEr du sikker på at du vil tilbakestille grensesnittet?" Updater.Title="Ny oppdatering tilgjengelig" Updater.Text="Det finnes en ny oppdatering:" Updater.UpdateNow="Oppdater nå" -Updater.RemindMeLater="Påminn meg senere" -Updater.Skip="Hopp over versjon" +Updater.RemindMeLater="Minn meg på det senere" +Updater.Skip="Hopp over versjonen" Updater.Running.Title="Programmet er aktivt" Updater.Running.Text="Utganger er aktive, deaktiver alle aktive utganger før du forsøker å oppdatere" Updater.NoUpdatesAvailable.Title="Ingen oppdateringer er tilgjengelig" @@ -174,10 +208,10 @@ Updater.GameCaptureActive.Title="Spillopptak aktivt" Updater.GameCaptureActive.Text="Spillopptakskrokbiblioteket er for øyeblikket i bruk. Vennligst lukk ethvert spill/program som blir tatt opp (eller start Windows på nytt), og prøv igjen." QuickTransitions.SwapScenes="Bytt forhåndsvisnings-/utgangsscener etter overgang" -QuickTransitions.SwapScenesTT="Bytter forhåndsvisnings- og utgangsscenen etter overgang, hvis den originale utgangsscenen fortsatt eksisterer.\nDette vil ikke tilbakestille endringer på den originale utgangsscenen." +QuickTransitions.SwapScenesTT="Bytter forhåndsvisnings- og utgangs-scenen etter overgang, hvis den originale utgangsscenen fortsatt eksisterer.\nDette vil ikke tilbakestille endringer på den originale utgangsscenen." QuickTransitions.DuplicateScene="Dupliser scene" QuickTransitions.DuplicateSceneTT="Når denne innstillingen er aktiv, kan du justere visningen av kilder i den samme scenen uten å endre utdataen.\nOm du vil endre kildenes innstillinger uten å endre utdataene, må du aktivere «Dupliser kilder».\nVed aktivering eller deaktivering av denne innstillingen vil utgangsscenen omstilles (om den fortsatt eksisterer)." -QuickTransitions.EditProperties="Dupliserte kilder" +QuickTransitions.EditProperties="Dupliser kilder" QuickTransitions.EditPropertiesTT="Lar deg justere kilders egenskaper i samme scene uten å endre visning i utgangsscenen.\nKan bare brukes om instillingen «duplisert scene» er aktiv.\nEnkelte kilder (som opptak eller mediekilder) støtter ikke denne funksjonen og kan ikke endres separat.\nOm du aktiverer eller deaktiverer denne instillingen vil omstille utgangsscenen om den fortsatt eksisterer.\n\nAdvarsel: kan kreve mer systemressurser ettersom alle kildene i scenen blir duplisert." QuickTransitions.HotkeyName="Hurtigovergang: %1" @@ -200,14 +234,17 @@ NameExists.Text="Dette navnet er allerede i bruk." NoNameEntered.Title="Vennligst oppgi et gyldig navn" NoNameEntered.Text="Du kan ikke bruke et tomt navn." -ConfirmStart.Title="Begynn strømming?" -ConfirmStart.Text="Er du sikker på at du vil begynne å strømme?" +ConfirmStart.Title="Vil du starte sendingen?" +ConfirmStart.Text="Er du sikker på at du vil begynne å sende?" -ConfirmStop.Title="Stans strømming?" -ConfirmStop.Text="Er du sikker på at du vil stanse strømming?" +ConfirmStop.Title="Vil du avslutte sendingen?" +ConfirmStop.Text="Er du sikker på at du vil avslutte sendingen?" + +ConfirmBWTest.Title="Start bredbåndstest?" +ConfirmBWTest.Text="Du har konfigurert OBS i bredbåndstest-modus. Denne modusen tillater nettverkstesting uten at din kanal går live. Du må deaktivere modusen når du er ferdig å teste for at seere vil kunne se din strøm. \n\nVil du fortsette?" ConfirmExit.Title="Avslutt OBS?" -ConfirmExit.Text="OBS er aktiv. Alle strømmer og opptak vil bli stoppet. Er du sikker på at du vil avslutte?" +ConfirmExit.Text="OBS-aktiviteter pågår akkurat nå. Alle sendinger og opptak vil bli stoppet. Er du sikker på at du vil avslutte?" ConfirmRemove.Title="Bekreft Fjerning" ConfirmRemove.Text="Er du sikker på at du vil fjerne '$1'?" @@ -216,7 +253,8 @@ ConfirmRemove.TextMultiple="Er du sikker du ønsker å fjerne %1 filer?" Output.StartStreamFailed="Kan ikke starte streaming" Output.StartRecordingFailed="Kan ikke starte innspillingen" Output.StartReplayFailed="Kunne ikke å starte opp omspillingsbufferen" -Output.StartFailedGeneric="Start av output har feilet. Venligst se loggen for detaljer.\n\nNote: Om du bruker NVENC eller AMD enkodere, pass på at skjerm driverene er oppdatert." +Output.StartFailedGeneric="Oppstart av utdata har mislyktes. Vennligst se loggen for detaljer.\n\nBemerk at dersom du bruker NVENC- eller AMD-enkodere, pass på at skjermdriverne er oppdatert." + Output.ConnectFail.Title="Tilkobling mislyktes" Output.ConnectFail.BadPath="Ugyldig filbane eller tilkoblings-URL. Vennligst sjekk at innstillingene dine er riktige." @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="Kunne ikke få adgang til den angitte kanalen Output.ConnectFail.Error="En uventet feil oppstod ved tilkobling til serveren. Detaljert informasjon kan du finne i loggfila." Output.ConnectFail.Disconnected="Koblet fra tjeneren." +Output.StreamEncodeError.Title="Kodingsfeil" +Output.StreamEncodeError.Msg="En kodingsfeil skjedde under strømmingen." + Output.RecordFail.Title="Kunne ikke starte opptak" Output.RecordFail.Unsupported="Utgangsformatet støttes enten ikke eller støtter ikke mer enn ett lydspor. Kontroller innstillingene og prøv igjen." Output.RecordNoSpace.Title="Ikke nok diskplass" Output.RecordNoSpace.Msg="Det er ikke nok diskplass til å fortsette opptaket." Output.RecordError.Title="Innspillingsfeil" Output.RecordError.Msg="Det oppstod en uspesifisert feil under opptaket." +Output.RecordError.EncodeErrorMsg="En kodingsfeil skjedde under opptaket." Output.ReplayBuffer.NoHotkey.Title="Ingen hurtigtast satt!" Output.ReplayBuffer.NoHotkey.Msg="Ingen lagringshurtigtast er valgt for omspillingsbufferen. Vennligst velg en \"Lagre\"-hurtigknapp, sånn at den kan brukes til å lagre opptak." @@ -241,25 +283,23 @@ LogReturnDialog="Vellykket Loggopplasting" LogReturnDialog.CopyURL="Kopiér URL" LogReturnDialog.ErrorUploadingLog="Feil ved opplasting av loggfil." -LicenseAgreement="Lisensavtale" -LicenseAgreement.PleaseReview="Vennligst les gjennom lisensvilkårene før du bruker OBS. Ved å bruke dette programmet, godtar du i at du har lest og godtar vilkårene i GNU General Public License v2.0. Vennligst bla nedover for å se resten av lisensavtalen." -LicenseAgreement.ClickIAgreeToContinue="Hvis du godtar vilkårene i lisensavtalen, klikk \"Godta\" for å fortsette. Du må godta lisensavtalen for å bruke OBS." -LicenseAgreement.IAgree="Jeg godtar" -LicenseAgreement.Exit="Avslutt" - Remux.SourceFile="OBS-opptak" Remux.TargetFile="Målfil" Remux.Remux="Remuks" +Remux.Stop="Stopp remuxing" +Remux.ClearFinished="Tøm fullførte elementer" +Remux.ClearAll="Tøm alle elementer" Remux.OBSRecording="OBS-opptak" Remux.FinishedTitle="Remuksing ferdig" Remux.Finished="Opptak remukset" Remux.FinishedError="Opptak remukset, men filen kan være ufullstendig." -Remux.SelectRecording="Velg OBS-opptak…" -Remux.SelectTarget="Velg målfil…" -Remux.FileExistsTitle="Målfilen eksisterer" -Remux.FileExists="Målfilen eksisterer, vil du erstatte den?" +Remux.SelectRecording="Velg OBS-opptak..." +Remux.SelectTarget="Velg målfil..." +Remux.FileExistsTitle="Målfiler finnes allerede" +Remux.FileExists="De følgende målfilene finnes allerede. Vil du erstatte dem?" Remux.ExitUnfinishedTitle="Remuksing pågår" Remux.ExitUnfinished="Remuks er ikke ferdig. Om du avbryter kan målfilen bli ubrukelig.\nEr du sikker på at du vil avbryte remuksingen?" +Remux.HelpText="Slipp filer ned i dette vinduet for å remukse, eller velg en tom «OBS-opptak»-celle for å lete etter en fil." UpdateAvailable="Ny oppdatering tilgjengelig" UpdateAvailable.Text="Versjon %1.%2.%3 er nå tilgjengelig. Klikk her for å laste ned" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Skjermopptak" Basic.Main.PreviewConextMenu.Enable="Aktiver forhåndsvisning" +Basic.Main.Preview.Disable="Deaktiver forhåndsvisning" + ScaleFiltering="Skaleringsfiltrering" ScaleFiltering.Point="Punkt" ScaleFiltering.Bilinear="Bilineær" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" Deinterlacing="Avsammenfletting" Deinterlacing.Discard="Forkast" @@ -290,7 +333,7 @@ Deinterlacing.Blend2x="Dobbelblanding" Deinterlacing.Linear="Lineær" Deinterlacing.Linear2x="Dobbellineær" Deinterlacing.Yadif="Yadif" -Deinterlacing.Yadif2x="Dobbelyadif" +Deinterlacing.Yadif2x="Dobbel-Yadif" Deinterlacing.TopFieldFirst="Øverste felt først" Deinterlacing.BottomFieldFirst="Nederste felt først" @@ -331,13 +374,13 @@ Basic.PropertiesWindow.SelectColor="Velg farge" Basic.PropertiesWindow.SelectFont="Velg skrifttype" Basic.PropertiesWindow.ConfirmTitle="Innstillingene er endret" Basic.PropertiesWindow.Confirm="Det er ulagrede endringer. Vil du beholde dem?" -Basic.PropertiesWindow.NoProperties="Ingen egenskaper tilgjengelige" +Basic.PropertiesWindow.NoProperties="Ingen egenskaper er tilgjengelige" Basic.PropertiesWindow.AddFiles="Legg til filer" Basic.PropertiesWindow.AddDir="Legg til mappe" Basic.PropertiesWindow.AddURL="Legg til fil- eller URL-adresse" -Basic.PropertiesWindow.AddEditableListDir="Legg mappe til «%1»" +Basic.PropertiesWindow.AddEditableListDir="Legg til mappe i «%1»" Basic.PropertiesWindow.AddEditableListFiles="Legg filer til '%1'" -Basic.PropertiesWindow.AddEditableListEntry="Lag oppføring til '%1'" +Basic.PropertiesWindow.AddEditableListEntry="Legg oppføring til '%1'" Basic.PropertiesWindow.EditEditableListEntry="Endre oppføring fra '%1'" Basic.PropertiesView.FPS.Simple="Bildefrekvens (enkel)" @@ -405,8 +448,8 @@ Basic.Main.StoppingRecording="Stanser innspilling…" Basic.Main.StopReplayBuffer="Stopp omspillingsbufferen" Basic.Main.StoppingReplayBuffer="Stopper omspillingsbufferen..." Basic.Main.StopStreaming="Stopp Strømming" -Basic.Main.StoppingStreaming="Stanser strøm…" -Basic.Main.ForceStopStreaming="Stopp strømming (forkast forsinkelse)" +Basic.Main.StoppingStreaming="Avslutter sendingen …" +Basic.Main.ForceStopStreaming="Avslutt sendingen (forkast forsinkelse)" Basic.Main.Group="Gruppe %1" Basic.Main.GroupItems="Gruppér merkede gjenstander" Basic.Main.Ungroup="Adskill" @@ -414,51 +457,53 @@ Basic.Main.Ungroup="Adskill" Basic.MainMenu.File="&Fil" Basic.MainMenu.File.Export="&Eksportér" Basic.MainMenu.File.Import="&Importér" -Basic.MainMenu.File.ShowRecordings="Vis &opptak" +Basic.MainMenu.File.ShowRecordings="Vis opptak (&R)" Basic.MainMenu.File.Remux="Re&muks opptak" Basic.MainMenu.File.Settings="Inn&stillinger" Basic.MainMenu.File.ShowSettingsFolder="Vis innstillingsmappen" Basic.MainMenu.File.ShowProfileFolder="Vis profilmappen" Basic.MainMenu.AlwaysOnTop="&Alltid synlig" -Basic.MainMenu.File.Exit="&Avslutt" +Basic.MainMenu.File.Exit="Avslutt (&X)" -Basic.MainMenu.Edit="&Redigér" -Basic.MainMenu.Edit.Undo="&Angre" -Basic.MainMenu.Edit.Redo="&Gjør om" -Basic.MainMenu.Edit.UndoAction="&Angre $1" -Basic.MainMenu.Edit.RedoAction="&Gjør om $1" -Basic.MainMenu.Edit.LockPreview="Lås Forhåndsvisning" -Basic.MainMenu.Edit.Scale="Forhåndsvisnings-skalering" +Basic.MainMenu.Edit="R&edigér" +Basic.MainMenu.Edit.Undo="Angre (&U)" +Basic.MainMenu.Edit.Redo="Gjø&r om" +Basic.MainMenu.Edit.UndoAction="Angre $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Gjø&r om $1" +Basic.MainMenu.Edit.LockPreview="&Lås Forhåndsvisning" +Basic.MainMenu.Edit.Scale="Forhånd&svisnings-skalering" Basic.MainMenu.Edit.Scale.Window="Tilpass til vindu" Basic.MainMenu.Edit.Scale.Canvas="Lerret (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Utgang (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformer" -Basic.MainMenu.Edit.Transform.EditTransform="&Redigér transformering..." +Basic.MainMenu.Edit.Transform.EditTransform="R&edigér transformering..." Basic.MainMenu.Edit.Transform.CopyTransform="Kopiere transformering" Basic.MainMenu.Edit.Transform.PasteTransform="Lim inn transformering" -Basic.MainMenu.Edit.Transform.ResetTransform="&Angre transformering" +Basic.MainMenu.Edit.Transform.ResetTransform="Ang&re transformering" Basic.MainMenu.Edit.Transform.Rotate90CW="Rotér 90 grader med klokka" Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotér 90 grader mot klokka" Basic.MainMenu.Edit.Transform.Rotate180="Rotér 180 grader" Basic.MainMenu.Edit.Transform.FlipHorizontal="Vend &horisontalt" Basic.MainMenu.Edit.Transform.FlipVertical="Vend &vertikalt" -Basic.MainMenu.Edit.Transform.FitToScreen="&Tilpass skjerm" +Basic.MainMenu.Edit.Transform.FitToScreen="Tilpass skjerm (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="&Strekk til skjerm" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Midstill på skjermen" -Basic.MainMenu.Edit.Order="A&rrangér" -Basic.MainMenu.Edit.Order.MoveUp="Flytt &opp" -Basic.MainMenu.Edit.Order.MoveDown="Flytt &ned" +Basic.MainMenu.Edit.Transform.CenterToScreen="Midstill på skjermen (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Sentrer vertikalt" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Sentrer horisontalt" +Basic.MainMenu.Edit.Order="Arrangér (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Flytt opp (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Flytt ne&d" Basic.MainMenu.Edit.Order.MoveToTop="Legg på &toppen" Basic.MainMenu.Edit.Order.MoveToBottom="Legg på &bunnen" Basic.MainMenu.Edit.AdvAudio="&Avanserte lydinnstillinger" Basic.MainMenu.View="&Vis" -Basic.MainMenu.View.Toolbars="&Verktøylinjer" +Basic.MainMenu.View.Toolbars="Verk&tøylinjer" Basic.MainMenu.View.Docks="Festede elementer" Basic.MainMenu.View.Docks.ResetUI="Omstart grensesnittet" Basic.MainMenu.View.Docks.LockUI="Lås grensesnittet" Basic.MainMenu.View.Toolbars.Listboxes="&Listebokser" -Basic.MainMenu.View.SceneTransitions="Sceneoverganger" +Basic.MainMenu.View.SceneTransitions="S&ceneoverganger" Basic.MainMenu.View.StatusBar="&Statuslinje" Basic.MainMenu.View.Fullscreen.Interface="Fullskjermsgrensesnitt" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Eksporter scenesamling" Basic.MainMenu.Profile.Exists="Profilen eksisterer allerede" Basic.MainMenu.SceneCollection.Exists="Scenesamlingen eksisterer allerede" -Basic.MainMenu.Tools="&Verktøy" +Basic.MainMenu.Tools="Verk&tøy" Basic.MainMenu.Help="&Hjelp" Basic.MainMenu.Help.HelpPortal="&Portal for hjelp" -Basic.MainMenu.Help.Website="Besøk &nettstedet" +Basic.MainMenu.Help.Website="Besøk nettstedet (&W)" Basic.MainMenu.Help.Discord="Bli med i &Discord-serveren" Basic.MainMenu.Help.Logs="&Loggfiler" -Basic.MainMenu.Help.Logs.ShowLogs="Vis &loggfiler" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Last opp &nåværende loggfil" -Basic.MainMenu.Help.Logs.UploadLastLog="Last opp &siste loggfil" +Basic.MainMenu.Help.Logs.ShowLogs="Vi&s loggfiler" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Last opp nåværende loggfil (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="&Last opp siste loggfil" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vis gjeldende logg" Basic.MainMenu.Help.CheckForUpdates="Se etter oppdateringer" -Basic.MainMenu.Help.CrashLogs="Krasjrapporter" +Basic.MainMenu.Help.CrashLogs="K&rasjrapporter" Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&s krasjrapporter" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Last opp den &nyeste krasjrapporten" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Last opp den nyeste krasjrapporten" +Basic.MainMenu.Help.About="Om (&A)" Basic.Settings.ProgramRestart="Programmet må startes på nytt for at disse innstillingene skal tre i kraft." Basic.Settings.ConfirmTitle="Bekreft endringer" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Systemstatusfeltet" Basic.Settings.General.SysTrayWhenStarted="Minimer til systemstatusfelt ved oppstart" Basic.Settings.General.SystemTrayHideMinimize="Alltid minimere til systemstatusfeltet istedet for oppgavelinjen" Basic.Settings.General.SaveProjectors="Lagre projektorer ved avslutning" +Basic.Settings.General.Preview="Forhåndsvisning" +Basic.Settings.General.OverflowHidden="Skjul overflytende områder" +Basic.Settings.General.OverflowAlwaysVisible="Overflyten skal alltid være synlig" +Basic.Settings.General.OverflowSelectionHidden="Vis overflyt selv når kilden er usynlig" Basic.Settings.General.SwitchOnDoubleClick="Dobbeltklikking vil gå til scenen" Basic.Settings.General.StudioPortraitLayout="Aktiver portrett/loddrett vindu" +Basic.Settings.General.TogglePreviewProgramLabels="Vis etikett for forhåndsvisning/program" Basic.Settings.General.Multiview="Flervisning" Basic.Settings.General.Multiview.MouseSwitch="Klikk for å bytte mellom scener" Basic.Settings.General.Multiview.DrawSourceNames="Vis scenenes navn" @@ -529,24 +580,28 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Vannrett, topp ( Basic.Settings.Stream="Strøm" Basic.Settings.Stream.StreamType="Strømmetype" +Basic.Settings.Stream.Custom.UseAuthentication="Bruk autentisering" +Basic.Settings.Stream.Custom.Username="Brukernavn" +Basic.Settings.Stream.Custom.Password="Passord" +Basic.Settings.Stream.BandwidthTestMode="Aktiver båndbreddetest-modus" Basic.Settings.Output="Utgang" Basic.Settings.Output.Format="Opptaksformat" Basic.Settings.Output.Encoder="Koder" Basic.Settings.Output.SelectDirectory="Velg opptaksmappe" Basic.Settings.Output.SelectFile="Velg opptaksfil" -Basic.Settings.Output.EnforceBitrate="Håndhev strømmingtjenestens bitrategrense" +Basic.Settings.Output.EnforceBitrate="Håndhev strømmetjenestens bitfrekvensgrense" Basic.Settings.Output.Mode="Utgangsmodus" Basic.Settings.Output.Mode.Simple="Enkel" Basic.Settings.Output.Mode.Adv="Avansert" Basic.Settings.Output.Mode.FFmpeg="FFmpeg-utgang" Basic.Settings.Output.UseReplayBuffer="Aktiver omspillingsbufferen" Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimal omspillingstid (i sekunder)" -Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimalt Minne (Megabytes)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimal minnebruk (Megabytes)" Basic.Settings.Output.ReplayBuffer.Estimate="Anslått minnebruk: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Kan ikke beregne minnebruk. Vennligst sett maksimalt minnebrukgrense." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Merk: Sørg for å angi en hurtigtast for omspillingsbufferen i hurtigtastsinnstillingene)" -Basic.Settings.Output.ReplayBuffer.Prefix="Replay Buffer Filnavn Prefiks" +Basic.Settings.Output.ReplayBuffer.Prefix="Reprisebufferens filnavnprefiks" Basic.Settings.Output.ReplayBuffer.Suffix="Suffiks" Basic.Settings.Output.Simple.SavePath="Opptaksbane" Basic.Settings.Output.Simple.RecordingQuality="Opptakskvalitet" @@ -560,19 +615,18 @@ Basic.Settings.Output.Simple.Warn.Encoder="Advarsel: Opptak med programvarekoder Basic.Settings.Output.Simple.Warn.Lossless="Advarsel: Tapsfri kvalitet resulterer i enormt store filstørrelser! Denne innstillingen kan bruke oppimot 7 GB diskplass per minutt ved opptak med høy oppløsning og bildefrekvens. Tapsfri kvalitet anbefales ikke for lange opptak med mindre du har store mengder diskplass tilgjengelig." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Er du sikker på at du vil bruke tapsfri kvalitet?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Tapsfri kvalitet advarsel!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Advarsel: du kan ikke bruke flere separate QSV-kodere når du strømmer og tar opp samtidig. Hvis du ønsker gjøre begge på samme tid må du endre strømme- eller opptakskoderen." Basic.Settings.Output.Simple.Encoder.Software="Programvare (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Maskinvare (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Maskinvare (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Maskinvare (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Programvare (Forhåndsinnstilt til x264 med lav CPU-bruk, øker filstørrelsen)" -Basic.Settings.Output.VideoBitrate="Bildeoverføringshastighet" -Basic.Settings.Output.AudioBitrate="Lydoverføringshastighet" +Basic.Settings.Output.VideoBitrate="Bilde-bitfrekvens" +Basic.Settings.Output.AudioBitrate="Lyd-bitfrekvens" Basic.Settings.Output.Reconnect="Koble automatisk til på nytt" Basic.Settings.Output.RetryDelay="Opphold mellom tilkoblingsforsøk (sekunder)" Basic.Settings.Output.MaxRetries="Høyst antall tilkoblingsforsøk" Basic.Settings.Output.Advanced="Aktiver avanserte koderinnstillinger" -Basic.Settings.Output.EncoderPreset="Koder-forhåndsinnstilling (Raskere = mindre CPU-bruk)" +Basic.Settings.Output.EncoderPreset="Kodingsinstillinger" Basic.Settings.Output.CustomEncoderSettings="Egendefinerte koderinnstillinger" Basic.Settings.Output.CustomMuxerSettings="Egendefinerte mukserinnstillinger" Basic.Settings.Output.NoSpaceFileName="Lag filnavn uten mellomrom" @@ -614,7 +668,7 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Videokoderinnstillinger (om n Basic.Settings.Output.Adv.FFmpeg.AEncoder="Lydkoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Lydkoderinnstillinger (om noen)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Mukserinnstillinger (om noen)" -Basic.Settings.Output.Adv.FFmpeg.GOPSize="Nøkkelbilde intervall (frames)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Nøkkelbildeintervall (bilder)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Vis alle kodeker (selv om potensielt ikke-kompatibel)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" @@ -622,10 +676,10 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY år, fire sifre\n%YY år, siste to sifre (00-99)\n%MM måned, som tall (01-12)\n%DD dag i måneden, forranstillt med null (01-31)\n%hh time, i tjuefiretimersformat (00-23)\n%mm minutt (00-59)\n%ss sekund (00-61)\n%% et prosenttegn\n%a forkortet ukedagsnavn\n%A helt ukedagsnavn\n%b forkortet månedsnavn\n%B helt månedsnavn\n%d dag i måneden, forranstillt med null (01-31)\n%H time, i tjuefiretimersformat (00-23)\n%I time, i tolvtimersformat (01-12)\n%m måned, som tall (01-12)\n%M minutt (00-59)\n%p formiddags- og ettermiddagsymbol (AM, PM)\n%S sekund (00-61)\n%y år, siste to sifre (00-99)\n%Y år\n%z ISO 8601 forskyvd fra UTC eller tidssone-\n navn eller -forkortelse\n%Z Tidssonenavn eller -forkortelse\n" Basic.Settings.Video="Bilde" -Basic.Settings.Video.Adapter="Bildeadapter:" -Basic.Settings.Video.BaseResolution="Grunnoppløsning (lerret):" -Basic.Settings.Video.ScaledResolution="Utgangsoppløsning (skalert):" -Basic.Settings.Video.DownscaleFilter="Nedskaleringsfilter:" +Basic.Settings.Video.Adapter="Bildeadapter" +Basic.Settings.Video.BaseResolution="Grunnoppløsning (lerret)" +Basic.Settings.Video.ScaledResolution="Utgangsoppløsning (skalert)" +Basic.Settings.Video.DownscaleFilter="Nedskaleringsfilter" Basic.Settings.Video.DisableAeroWindows="Deaktiver Aero (kun Windows)" Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="FPS samleverdi" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skjerpet skalering, 32 pr Basic.Settings.Audio="Lyd" Basic.Settings.Audio.SampleRate="Samplingsfrekvens" Basic.Settings.Audio.Channels="Kanaler" -Basic.Settings.Audio.MeterDecayRate="Audiometerets forfallsfrekvens" +Basic.Settings.Audio.Meters="Metre" +Basic.Settings.Audio.MeterDecayRate="Avfallshastighet" Basic.Settings.Audio.MeterDecayRate.Fast="Raskt" Basic.Settings.Audio.MeterDecayRate.Medium="Middels (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Tregt (Type II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Advarsel: Surroundlyd er aktiv Basic.Settings.Audio.MultichannelWarning="Hvis du strømmer, sjekk om strømmetjenesten din støtter både surround-lydinnføring og surround-lydavspilling. Twitch, Facebook 360 Live, Mixer RTMP, og Smashcast er eksempler hvor surroundlyd er full støttet. Selv om Facebook Live og YouTube Live begge støtter surround-innføring, nedmikser Facebook Live det ned til Stereo, og YouTube Live spiller bare av to kanaler.\n\nOBS-lydfiltre er kompatible med surroundlyd, selv om VST-tilleggsstøtte ikke er garantert." Basic.Settings.Audio.MultichannelWarning.Title="Vil du aktivere surround-lyd?" Basic.Settings.Audio.MultichannelWarning.Confirm="Er du sikker på at du vil aktivere surround-lyd?" +Basic.Settings.Audio.Devices="Enheter" Basic.Settings.Audio.DesktopDevice="Skrivebordslyd" Basic.Settings.Audio.DesktopDevice2="Skrivebordslyd 2" Basic.Settings.Audio.AuxDevice="Mikrofon/Aux" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux 3" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Aux" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Aux" +Basic.Settings.Audio.AuxDevice4="Mikrofon/Aux" Basic.Settings.Audio.EnablePushToMute="Aktiver demp-ved-trykk" Basic.Settings.Audio.PushToMuteDelay="Demp-ved-trykk forsinkelse" Basic.Settings.Audio.EnablePushToTalk="Aktiver snakk-ved-trykk" Basic.Settings.Audio.PushToTalkDelay="Snakk-ved-trykk forsinkelse" Basic.Settings.Audio.UnknownAudioDevice="[Enhet ikke tilkoblet eller ikke tilgjengelig]" +Basic.Settings.Audio.Disabled="Deaktivert" Basic.Settings.Advanced="Avansert" Basic.Settings.Advanced.General.ProcessPriority="Prosessprioritet" @@ -677,14 +735,14 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inaktiv" Basic.Settings.Advanced.FormatWarning="Advarsel: Fargeformater andre enn NV12 er ment for opptak. Disse formatene anbefales ikke ved strømming, da det fører til økt prosessorbruk som følge av fargeformatkonvertering." Basic.Settings.Advanced.Audio.BufferingTime="Lydbuffertid" Basic.Settings.Advanced.Video.ColorFormat="Fargeformat" -Basic.Settings.Advanced.Video.ColorSpace="YUV fargerom" -Basic.Settings.Advanced.Video.ColorRange="YUV fargespekter" +Basic.Settings.Advanced.Video.ColorSpace="Fargerom" +Basic.Settings.Advanced.Video.ColorRange="Fargespekter" Basic.Settings.Advanced.Video.ColorRange.Partial="Delvis" Basic.Settings.Advanced.Video.ColorRange.Full="Full" Basic.Settings.Advanced.Audio.MonitoringDevice="Lydenhet for overvåking" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Deaktiver Windows-lyddukking" -Basic.Settings.Advanced.StreamDelay="Strømforsinkelse" +Basic.Settings.Advanced.StreamDelay="Direktesendingsforsinkelse" Basic.Settings.Advanced.StreamDelay.Duration="Varighet (sekunder)" Basic.Settings.Advanced.StreamDelay.Preserve="Bevar avkuttingspunktet (øk forsinkelse) ved tilbakekobling" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Anslått minnebruk: %1 MB" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Bind til IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktiver den nye nettverkskoden" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lavlatens-modus" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Deaktiver hurtigtaster når hovedvinduet er i fokus" +Basic.Settings.Advanced.AutoRemux="Remuks automatisk til MP4" +Basic.Settings.Advanced.AutoRemux.MP4="(Gjør opptak som MKV)" Basic.AdvAudio="Avanserte lydinnstillinger" Basic.AdvAudio.Name="Navn" -Basic.AdvAudio.Volume="Volum (%)" +Basic.AdvAudio.Volume="Volum" Basic.AdvAudio.Mono="Nedmiks til mono" -Basic.AdvAudio.Panning="Panorering" +Basic.AdvAudio.Balance="Balanse" Basic.AdvAudio.SyncOffset="Synkroniseringsforskyvning (ms)" Basic.AdvAudio.Monitoring="Hør på kilde" Basic.AdvAudio.Monitoring.None="Ikke hør kilden" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Spor" Basic.Settings.Hotkeys="Hurtigtaster" Basic.Settings.Hotkeys.Pair="Tastekombinasjoner delt med '%1' vil veksle" +Basic.Settings.Hotkeys.Filter="Filtrer" Basic.Hotkeys.SelectScene="Bytt til scene" @@ -729,7 +790,7 @@ Hotkeys.Backspace="Backspace" Hotkeys.Tab="Tab" Hotkeys.Print="Print" Hotkeys.Pause="Pause" -Hotkeys.Left="Left" +Hotkeys.Left="Piltast venstre" Hotkeys.Right="Piltast høyre" Hotkeys.Up="Piltast opp" Hotkeys.Down="Piltast ned" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="-" Hotkeys.AppleKeypadDecimal="." Hotkeys.AppleKeypadEqual="= (talltastatur)" Hotkeys.MouseButton="Museknapp %1" +Hotkeys.Escape="Esc" Mute="Demp" Unmute="Udemp" @@ -762,7 +824,7 @@ SceneItemHide="Gjem '%1'" OutputWarnings.NoTracksSelected="Du må velge minst ett spor" OutputWarnings.MultiTrackRecording="Advarsel: enkelte formater (som FLV) støtter ikke flere spor per opptak" -OutputWarnings.MP4Recording="Advarsel: Opptak lagret i MP4 bil bli slettet hvis filen ikke kan fullføres (f.eks. som følge av BSOD, tap av strøm osv.) Hvis du vil registere flere lydspor vurder å bruke MKV og remux inspillingen til MP4 etter det er ferdig (Fil -> Remux Opptak)" +OutputWarnings.MP4Recording="Advarsel: Opptak lagret i MP4/MOV vil bli slettet dersom filen ikke kan fullføres (f.eks. som følge av BSOD, tap av strøm, osv.) Hvis du vil registere flere lydspor, vurder å bruke MKV og remuks inspillingen til MP4/MOV etter at det er ferdig (Fil → Remuks opptak)" FinalScene.Title="Slett scene" FinalScene.Text="Det må være minst én scene." @@ -770,8 +832,24 @@ FinalScene.Text="Det må være minst én scene." NoSources.Title="Ingen kilder" NoSources.Text="Det ser ut som du ikke har lagt til noen videokilder ennå, så du vil kun sende en blank skjerm. Er du sikker på at du vil gjøre dette?" NoSources.Text.AddSource="Du kan legge til kilder ved å klikke på +-ikonet under Kilder-boksen i hovedvinduet til enhver tid." +NoSources.Label="Du har ingen kilder. \nKlikk + knappen nedenfor,\neller høyre-klikk her for å legge til." ChangeBG="Velg farge" CustomColor="Egendefinert farge" +BrowserSource.EnableHardwareAcceleration="Aktiver «Nettleserkilde-maskinvareakselerasjon»" + +About="Om" +About.Info="OBS Studio er en fri og åpen-kildet videoopptaks- og direktesendings-programvare." +About.Donate="Bidra til projektet" +About.GetInvolved="Involver deg" +About.Authors="Skapere" +About.License="Lisens" +About.Contribute="Støtt OBS-prosjektet" + +ResizeOutputSizeOfSource="Endre størrelsen på utdataen (kildestørrelse)" +ResizeOutputSizeOfSource.Text="Grunn- og utdata-oppløsningene vil bli gitt samme størrelse som den nåværende kilden." +ResizeOutputSizeOfSource.Continue="Vil du fortsette?" + +PreviewTransition="Forhåndsvis overgang" diff --git a/UI/data/locale/nl-NL.ini b/UI/data/locale/nl-NL.ini index 34ceac9..922d7ec 100644 --- a/UI/data/locale/nl-NL.ini +++ b/UI/data/locale/nl-NL.ini @@ -7,7 +7,7 @@ Apply="Toepassen" Cancel="Annuleren" Close="Sluiten" Save="Opslaan" -Discard="Verwerpen" +Discard="Annuleren" Disable="Uitschakelen" Yes="Ja" No="Nee" @@ -29,9 +29,9 @@ Mono="Mono" Stereo="Stereo" DroppedFrames="Gedropte Frames %1 (%2%)" StudioProgramProjector="Full-screen Projector (Programma)" -PreviewProjector="Full-screen Projector (Preview)" -SceneProjector="Full-screen Projector (Scène)" -SourceProjector="Full-screen Projector (Bron)" +PreviewProjector="Fullscreen Projector (Preview)" +SceneProjector="Fullscreen Projector (Scène)" +SourceProjector="Fullscreen Projector (Bron)" StudioProgramWindow="Projectorvenster (Programma)" PreviewWindow="Projectorvenster (Preview)" SceneWindow="Projectorvenster (Scène)" @@ -80,14 +80,40 @@ StudioMode.Program="Programma" ShowInMultiview="Weergeven in Multiview" VerticalLayout="Verticale Lay-out" Group="Groep" +DoNotShowAgain="Niet opnieuw tonen" +Default="(Standaard)" +Calculating="Berekenen..." AlreadyRunning.Title="OBS is al actief" -AlreadyRunning.Text="OBS is al actief! Tenzij je dit wilde doen, sluit a.u.b. alle reeds draaiende instanties van OBS voor je een nieuwe instantie opstart. Als je OBS hebt ingesteld om naar het systeemvak te minimaliseren, controleer dan of hij daar nog staat." +AlreadyRunning.Text="OBS is al actief! Tenzij je dit wilde doen, sluit a.u.b. alle reeds draaiende instanties van OBS voor je een nieuwe instantie opstart. Als je OBS hebt ingesteld om naar het systeemvak te minimaliseren, controleer dan of hij daar nog uitgevoerd wordt." AlreadyRunning.LaunchAnyway="Toch Starten" +DockCloseWarning.Title="Dokbaar Venster Sluiten" +DockCloseWarning.Text="Je hebt net een dokbaar venster gesloten. Als je het opnieuw wilt zien, gebruik dan het menu Beeld → Docks in de menubalk." + +Auth.Authing.Title="Authenticeren..." +Auth.Authing.Text="Authenticeren met %1, even geduld a.u.b..." +Auth.AuthFailure.Title="Verificatiefout" +Auth.AuthFailure.Text="Gefaald te verifiëren met %1\n\n%2: %3" +Auth.InvalidScope.Title="Verificatie vereist" +Auth.InvalidScope.Text="De authenticatie vereisten voor %1 zijn gewijzigd. Sommige functies zijn mogelijk niet beschikbaar." +Auth.LoadingChannel.Title="Kanaalinformatie laden..." +Auth.LoadingChannel.Text="Kanaalinformatie voor %1 laden, even geduld a.u.b..." +Auth.ChannelFailure.Title="Fout bij het laden van kanaal" +Auth.ChannelFailure.Text="Fout bij het laden van kanaal informatie voor %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Stream-informatie" +TwitchAuth.Stats="Twitch statistieken" +TwitchAuth.Feed="Twitch activiteitenfeed" +TwitchAuth.TwoFactorFail.Title="Kon stream key niet opvragen" +TwitchAuth.TwoFactorFail.Text="OBS kon geen verbinding maken met uw Twitch account. Zorg ervoor dat er twee-factor authenticatie is ingesteld in uw Twitch beveiligingsinstellingen, omdat dit nodig is om te streamen." + Copy.Filters="Kopieer Filters" Paste.Filters="Plak filters" +BrowserPanelInit.Title="Browser Opstarten..." +BrowserPanelInit.Text="Browser opstarten, even geduld a.u.b..." + BandwidthTest.Region="Regio" BandwidthTest.Region.US="Verenigde Staten" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Azië" BandwidthTest.Region.Other="Overig" Basic.FirstStartup.RunWizard="Wil je de automatische configuratieassistent gebruiken? Je kan ook de instellingen handmatig aanpassen door op Instellingen te klikken in het hoofdscherm." -Basic.FirstStartup.RunWizard.BetaWarning="(Let op: de automatische configuratieassistent is momenteel in een beta-fase)" Basic.FirstStartup.RunWizard.NoClicked="Mocht je van gedachten veranderen, dan kun je de automatische configuratieassistent opnieuw starten vanuit het Help menu." Basic.AutoConfig="Automatische configuratieassistent" -Basic.AutoConfig.Beta="Automatische configuratieassistent (Beta)" Basic.AutoConfig.ApplySettings="Instellingen toepassen" Basic.AutoConfig.StartPage="Gebruiksinformatie" Basic.AutoConfig.StartPage.SubTitle="Waar wil je het programma voor gebruiken?" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 of 30, maar geef de voorkeur aa Basic.AutoConfig.VideoPage.CanvasExplanation="Let op: de basisresolutie (canvas) hoeft niet gelijk te zijn als de resolutie waarmee je streamt of opneemt. Je stream/opnameresolutie kan omlaag bijgeschaald worden vanaf de basisresolutie om de belasting op de computer of de benodigde bitrate te verlagen." Basic.AutoConfig.StreamPage="Stream-informatie" Basic.AutoConfig.StreamPage.SubTitle="Voer alstublieft uw stream-informatie in" +Basic.AutoConfig.StreamPage.ConnectAccount="Account verbinden (optioneel)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Account loskoppelen" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Account loskoppelen?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Deze wijziging zal onmiddellijk van toepassing zijn. Weet u zeker dat u uw account wilt loskoppelen?" +Basic.AutoConfig.StreamPage.UseStreamKey="Gebruik Stream Key" Basic.AutoConfig.StreamPage.Service="Dienst" Basic.AutoConfig.StreamPage.Service.ShowAll="Toon alles..." +Basic.AutoConfig.StreamPage.Service.Custom="Aangepast..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Stream key" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" @@ -124,7 +154,7 @@ Basic.AutoConfig.StreamPage.PerformBandwidthTest="Schat bitrate met bandbreedte Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Geef de voorkeur aan hardware-encoding" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardware-encoding elimineert het meeste CPU-gebruik, maar heeft wellicht een hogere bitrate nodig om hetzelfde kwaliteitsniveau te bereiken." Basic.AutoConfig.StreamPage.StreamWarning.Title="Streamwaarschuwing" -Basic.AutoConfig.StreamPage.StreamWarning.Text="De bandbreedte-test is bezig met het streamen van willekeurige videogegevens zonder audio naar uw kanaal. Indien mogelijk is het aanbevolen om tijdelijk het opslaan van video's van streams uit te schakelen en de stream privé te maken tot de test is voltooid. Doorgaan?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="De bandbreedte-test is bezig met het streamen van willekeurige videogegevens zonder audio naar uw kanaal. Indien mogelijk is het aanbevolen om tijdelijk het opslaan van video's van streams uit te schakelen en de stream privé te maken tot de test is voltooid. Doorgaan?" Basic.AutoConfig.TestPage="Eindresultaat" Basic.AutoConfig.TestPage.SubTitle.Testing="Het programma voert nu een reeks testen uit om de meest ideale instellingen in te schatten" Basic.AutoConfig.TestPage.SubTitle.Complete="Testen is afgerond" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Niet actief" Basic.Stats.DroppedFrames="Gedropte Frames (Netwerk)" Basic.Stats.MegabytesSent="Totale Gegevensuitvoer" Basic.Stats.Bitrate="Bitrate" +Basic.Stats.DiskFullIn="Schijf vol (ca.)" + +ResetUIWarning.Title="Weet u zeker dat u de UI wilt herstellen?" +ResetUIWarning.Text="Herstellen van de UI zal extra docks verbergen. Als u deze docks toch wilt zien, dan moet u ze in via het beeld menu weer zichtbaar maken.\n\nWeet u zeker dat u de UI wilt herstellen?" Updater.Title="Update beschikbaar" Updater.Text="Er is een update beschikbaar:" @@ -206,6 +240,9 @@ ConfirmStart.Text="Weet je zeker dat je de stream wil starten?" ConfirmStop.Title="Stop de Stream?" ConfirmStop.Text="Weet je zeker dat je de stream wil stoppen?" +ConfirmBWTest.Title="Bandbreedte test starten?" +ConfirmBWTest.Text="U heeft OBS geconfigureerd in bandbreedte test modus. Deze modus maakt het mogelijk om netwerk te testen zonder live te gaan. Zodra u klaar bent met testen, moet u deze uitschakelen om de kijkers in staat te stellen uw stream te zien.\n\nWilt u doorgaan?" + ConfirmExit.Title="OBS Afsluiten?" ConfirmExit.Text="OBS is momenteel actief. Alle streams/opnames zullen worden afgebroken. Weet je zeker dat je wil afsluiten?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="Het starten van de opname is mislukt" Output.StartReplayFailed="Het starten van de replay buffer is mislukt" Output.StartFailedGeneric="Het starten van de uitvoer is mislukt. Controleer de logbestanden voor meer informatie.\n\nLet op: Als je gebruik maakt van de NVENC of AMD encoders, controleer of de drivers up to date zijn." + Output.ConnectFail.Title="Kan geen verbinding maken" Output.ConnectFail.BadPath="Ongeldig pad of verbindings-url. Controleer a.u.b. of je instellingen geldig zijn." Output.ConnectFail.ConnectFailed="Kan geen verbinding maken met de server" @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="Kon het gespecificeerde kanaal of stream key n Output.ConnectFail.Error="Er is een onverwachte fout opgetreden bij het verbinden met de server. Meer informatie in het logbestand." Output.ConnectFail.Disconnected="verbinding met de server gesloten." +Output.StreamEncodeError.Title="Coderingsfout" +Output.StreamEncodeError.Msg="Er is een coderingsfout opgetreden tijdens het streamen." + Output.RecordFail.Title="Kon de opname niet starten" Output.RecordFail.Unsupported="Het outputformaat wordt niet ondersteund, of ondersteunt niet meer dan een audiotrack. Controleer je instellingen en probeer het opnieuw." Output.RecordNoSpace.Title="Onvoldoende schijfruimte" Output.RecordNoSpace.Msg="Er is niet voldoende schijfruimte om door te gaan met opnemen." Output.RecordError.Title="Opnamefout" Output.RecordError.Msg="Er is een onbekende fout opgetreden tijdens het opnemen." +Output.RecordError.EncodeErrorMsg="Er is een coderingsfout opgetreden tijdens het opnemen." Output.ReplayBuffer.NoHotkey.Title="Er is geen sneltoets ingesteld!" Output.ReplayBuffer.NoHotkey.Msg="Er is geen opslaan sneltoets ingesteld voor de replay buffer. Zet aub de \"Opslaan\" sneltoets voor het opslaan van replay-opnames." @@ -241,25 +283,23 @@ LogReturnDialog="Log succesvol geüpload" LogReturnDialog.CopyURL="URL kopiëren" LogReturnDialog.ErrorUploadingLog="Fout bij het uploaden van het logbestand" -LicenseAgreement="Licentieovereenkomst" -LicenseAgreement.PleaseReview="Leesa.u.b. de licentieovereenkomst voordat je OBS gebruikt. Door dit programma te gebruiken, erkent u dat u de voorwaarden van de GNU General Public License v2.0 heeft gelezen en hiermee akkoord gaat. Scroll omlaag om de rest van de overeenkomst te zien." -LicenseAgreement.ClickIAgreeToContinue="Als je de voorwaarden van de overeenkomst accepteert, klik op Akkoord om door te gaan. Je moet de voorwaarden accepteren om OBS te gebruiken." -LicenseAgreement.IAgree="Akkoord" -LicenseAgreement.Exit="Afsluiten" - Remux.SourceFile="OBS Opname" Remux.TargetFile="Doelbestand" Remux.Remux="Remuxen" +Remux.Stop="Stop remuxen" +Remux.ClearFinished="Verwijder voltooide items" +Remux.ClearAll="Alle items wissen" Remux.OBSRecording="OBS Opname" Remux.FinishedTitle="Remuxen voltooid" Remux.Finished="Opname geremuxt" Remux.FinishedError="Opname geremuxt, maar het bestand zou incompleet kunnen zijn" -Remux.SelectRecording="Selecteer OBS Opname…" -Remux.SelectTarget="Selecteer doelbestand…" -Remux.FileExistsTitle="Doelbestand bestaat al" -Remux.FileExists="Het doelbestand bestaat al, wil je het vervangen?" +Remux.SelectRecording="Kies OBS Opname..." +Remux.SelectTarget="Selecteer doelbestand..." +Remux.FileExistsTitle="Doelbestanden bestaan al" +Remux.FileExists="Het volgende bestand bestaat al. Wil je deze vervangen?" Remux.ExitUnfinishedTitle="Remuxen is bezig" Remux.ExitUnfinished="Het remuxen is nog niet compleet, als je nu stopt kan het doelbestand onbruikbaar worden.\nWeet je zeker dat je wil stoppen met remuxen?" +Remux.HelpText="Drop bestanden in dit scherm om te remuxen, of selecteer een leeg \"OBS Opname\" cell om te zoeken voor een bestand." UpdateAvailable="Nieuwe Update Beschikbaar" UpdateAvailable.Text="Versie %1.%2.%3 is nu beschikbaar. Klik hier om te downloaden" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Beeldschermcapture" Basic.Main.PreviewConextMenu.Enable="Preview inschakelen" +Basic.Main.Preview.Disable="Preview uitschakelen" + ScaleFiltering="Schaal-filter" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Gebied" Deinterlacing="Deinterlacing" Deinterlacing.Discard="Verwerpen" @@ -411,16 +454,16 @@ Basic.Main.Group="Groep %1" Basic.Main.GroupItems="Groepeer geselecteerde items" Basic.Main.Ungroup="Degroeperen" -Basic.MainMenu.File="&Bestand" +Basic.MainMenu.File="Bestand (&F)" Basic.MainMenu.File.Export="&Exporteren" Basic.MainMenu.File.Import="&Importeren" Basic.MainMenu.File.ShowRecordings="Opnames Weergeven (&R)" Basic.MainMenu.File.Remux="Re&mux Opnames" -Basic.MainMenu.File.Settings="&Instellingen" +Basic.MainMenu.File.Settings="In&stellingen" Basic.MainMenu.File.ShowSettingsFolder="Instellingenmap Openen" Basic.MainMenu.File.ShowProfileFolder="Profielmap Openen" Basic.MainMenu.AlwaysOnTop="&Altijd op voorgrond" -Basic.MainMenu.File.Exit="&Afsluiten" +Basic.MainMenu.File.Exit="Afsluiten (&X)" Basic.MainMenu.Edit="B&ewerken" Basic.MainMenu.Edit.Undo="Ongedaan maken (&U)" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="&Verticaal Spiegelen" Basic.MainMenu.Edit.Transform.FitToScreen="In scherm passen (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Uitrekken naar scherm (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="Centeren op scherm (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Verticaal centreren" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Horizontaal centreren" Basic.MainMenu.Edit.Order="V&olgorde" Basic.MainMenu.Edit.Order.MoveUp="Omhoog Schuiven (&U)" Basic.MainMenu.Edit.Order.MoveDown="Omlaag Schuiven (&D)" @@ -452,8 +497,8 @@ Basic.MainMenu.Edit.Order.MoveToTop="Naar Boven Schuiven (&T)" Basic.MainMenu.Edit.Order.MoveToBottom="Naar Onderen Schuiven (&B)" Basic.MainMenu.Edit.AdvAudio="Geavanceerde &Audioinstellingen" -Basic.MainMenu.View="&Beeld" -Basic.MainMenu.View.Toolbars="&Werkbalken" +Basic.MainMenu.View="Beeld (&V)" +Basic.MainMenu.View.Toolbars="Werkbalken (&T)" Basic.MainMenu.View.Docks="Docks" Basic.MainMenu.View.Docks.ResetUI="Herstel UI" Basic.MainMenu.View.Docks.LockUI="Zet UI Vast" @@ -476,16 +521,17 @@ Basic.MainMenu.Tools="&Tools" Basic.MainMenu.Help="&Help" Basic.MainMenu.Help.HelpPortal="Help-&portal" Basic.MainMenu.Help.Website="&Website Bezoeken" -Basic.MainMenu.Help.Discord="Wordt lid van &Discord server" +Basic.MainMenu.Help.Discord="Word lid van onze &Discord-server" Basic.MainMenu.Help.Logs="&Logbestanden" Basic.MainMenu.Help.Logs.ShowLogs="Logbe&standen Weergeven" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload &Huidige Logbestand" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Upload Huidige Logbestand (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Upload &Laatste Logbestand" Basic.MainMenu.Help.Logs.ViewCurrentLog="Toon Huidige Logbestand (&V)" Basic.MainMenu.Help.CheckForUpdates="Controleer Op Updates" Basic.MainMenu.Help.CrashLogs="Fouten&rapport" Basic.MainMenu.Help.CrashLogs.ShowLogs="Toon crashrapporten (&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="Upload &laatste crash rapport" +Basic.MainMenu.Help.About="Over (&A)" Basic.Settings.ProgramRestart="Het programma moet opnieuw worden opgestart om deze instellingen te activeren." Basic.Settings.ConfirmTitle="Wijzigingen Bevestigen" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Systeemvak" Basic.Settings.General.SysTrayWhenStarted="Naar systeemvak minimaliseren bij opstarten" Basic.Settings.General.SystemTrayHideMinimize="Altijd minimaliseren naar het systeemvak in plaats van de taakbalk" Basic.Settings.General.SaveProjectors="Projectors opslaan bij afsluiten" +Basic.Settings.General.Preview="Preview" +Basic.Settings.General.OverflowHidden="Overloop verbergen" +Basic.Settings.General.OverflowAlwaysVisible="Overloop altijd zichtbaar" +Basic.Settings.General.OverflowSelectionHidden="Overloop weergeven, zelfs wanneer bron onzichtbaar is" Basic.Settings.General.SwitchOnDoubleClick="Ga over naar scène bij dubbelklik" Basic.Settings.General.StudioPortraitLayout="Portret/verticale layout inschakelen" +Basic.Settings.General.TogglePreviewProgramLabels="Toon voorbeeld/programma labels" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Klik hier om tussen scènes te wisselen" Basic.Settings.General.Multiview.DrawSourceNames="Toon namen van scènes" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontaal, bov Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Stream Type" +Basic.Settings.Stream.Custom.UseAuthentication="Gebruik authenticatie" +Basic.Settings.Stream.Custom.Username="Gebruikersnaam" +Basic.Settings.Stream.Custom.Password="Wachtwoord" +Basic.Settings.Stream.BandwidthTestMode="Bandbreedte testmodus inschakelen" Basic.Settings.Output="Uitvoer" Basic.Settings.Output.Format="Opnameformaat" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Waarschuwing: Opname met een software Basic.Settings.Output.Simple.Warn.Lossless="Waarschuwing: Lossless kwaliteit genereert erg grote bestanden! Lossless kwaliteit kan tot wel 7 GB aan schijfruimte per minuut gebruiken bij hoge resoluties en framerates. Lossless kwaliteit is niet aanbevolen voor lange opnames tenzij er een grote hoeveelheid schijfruimte beschikbaar is." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Weet je zeker dat je lossless kwaliteit wilt gebruiken?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless kwaliteit waarschuwing!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Waarschuwing: Je kunt niet meerdere QSV encoders gebruiken wanneer je tegelijkertijd aan het streamen en opnemen bent. Als je tegelijkertijd wil streamen en opnemen, verander dan de opname- of streamencoder." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" @@ -571,8 +625,8 @@ Basic.Settings.Output.AudioBitrate="Audio Bitrate" Basic.Settings.Output.Reconnect="Automatisch Opnieuw Verbinden" Basic.Settings.Output.RetryDelay="Opnieuw proberen na (seconden)" Basic.Settings.Output.MaxRetries="Maximaal aantal pogingen" -Basic.Settings.Output.Advanced="Geavanceerde Encoderinsellingen Inschakelen" -Basic.Settings.Output.EncoderPreset="Encoderinstelling (hoger = minder CPU)" +Basic.Settings.Output.Advanced="Geavanceerde Encoderinstellingen Inschakelen" +Basic.Settings.Output.EncoderPreset="Encoder Preset" Basic.Settings.Output.CustomEncoderSettings="Aangepaste encoderinstellingen" Basic.Settings.Output.CustomMuxerSettings="Aangepaste Muxer-instellingen" Basic.Settings.Output.NoSpaceFileName="Bestandsnaam zonder spatie genereren" @@ -634,7 +688,7 @@ Basic.Settings.Video.FPSFraction="Breuk FPS-waarde" Basic.Settings.Video.Numerator="Teller" Basic.Settings.Video.Denominator="Noemer" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Ongeldige resolutiewaarde. Moet [breedte] x [hoogte] zijn (bijv. 1920 x 1080)" +Basic.Settings.Video.InvalidResolution="Ongeldige resolutiewaarde. Moet [breedte] x [hoogte] zijn (bijv. 1920 x 1080)" Basic.Settings.Video.CurrentlyActive="Video-uitvoer is momenteel actief. Schakel a.u.b. alle uitvoeren uit om video-instellingen aan te passen." Basic.Settings.Video.DisableAero="Aero uitschakelen" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scherper schalen, 32 samp Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Sample Rate" Basic.Settings.Audio.Channels="Kanalen" -Basic.Settings.Audio.MeterDecayRate="Vervalsnelheid Volumemeter" +Basic.Settings.Audio.Meters="Meters" +Basic.Settings.Audio.MeterDecayRate="Verval snelheid" Basic.Settings.Audio.MeterDecayRate.Fast="Snel" Basic.Settings.Audio.MeterDecayRate.Medium="Gemiddeld (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Traag (Type II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Waarschuwing: Surround sound a Basic.Settings.Audio.MultichannelWarning="Als je streamt, controleer dan of je streaming service zowel surround sound ingest als surround sound afspelen ondersteunt. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast zijn voorbeelden waar surround sound volledig ondersteund is. Alhoewel Facebook Live en Youtube Live beide surround ingest ondersteunen, downmixt Facebook Live het naar stereo, terwijl Youtube Live slechts twee kanalen afspeelt.\n\nOBS audio filters kunnen overweg met surround sound, maar ondersteuning bij VST plugins is niet gegarandeerd." Basic.Settings.Audio.MultichannelWarning.Title="Surround sound audio inschakelen?" Basic.Settings.Audio.MultichannelWarning.Confirm="Weet je zeker dat je surround sound audio wil inschakelen?" -Basic.Settings.Audio.DesktopDevice="Desktop Audioapparaat" -Basic.Settings.Audio.DesktopDevice2="Desktop Audioapparaat 1" +Basic.Settings.Audio.Devices="Apparaten" +Basic.Settings.Audio.DesktopDevice="Desktop Audio" +Basic.Settings.Audio.DesktopDevice2="Desktop Audio 2" Basic.Settings.Audio.AuxDevice="Mic/Aux Audioapparaat" Basic.Settings.Audio.AuxDevice2="Mic/Aux Audioapparaat 2" Basic.Settings.Audio.AuxDevice3="Mic/Aux Audioapparaat 3" +Basic.Settings.Audio.AuxDevice4="Mic/Aux Audioapparaat 4" Basic.Settings.Audio.EnablePushToMute="Push-to-mute inschakelen" Basic.Settings.Audio.PushToMuteDelay="Push-to-mute vertraging" Basic.Settings.Audio.EnablePushToTalk="Push-to-talk inschakelen" Basic.Settings.Audio.PushToTalkDelay="Push-to-talk vertraging" Basic.Settings.Audio.UnknownAudioDevice="[Apparaat niet verbonden of niet beschikbaar]" +Basic.Settings.Audio.Disabled="Uitgeschakeld" Basic.Settings.Advanced="Geavanceerd" Basic.Settings.Advanced.General.ProcessPriority="Procesprioriteit" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Laagst" Basic.Settings.Advanced.FormatWarning="Waarschuwing: Andere kleurformaten dan NV12 zijn hoofdzakelijk bedoeld voor opnemen en worden niet aanbevolen om mee te streamen. Streamen kan verhoogd CPU-gebruik opleveren vanwege kleurformaatconversie." Basic.Settings.Advanced.Audio.BufferingTime="Audio Buffertijd" Basic.Settings.Advanced.Video.ColorFormat="Kleurindeling" -Basic.Settings.Advanced.Video.ColorSpace="YUV-Kleurruimte" -Basic.Settings.Advanced.Video.ColorRange="YUV-Kleurbereik" +Basic.Settings.Advanced.Video.ColorSpace="Kleurruimte" +Basic.Settings.Advanced.Video.ColorRange="Kleurbereik" Basic.Settings.Advanced.Video.ColorRange.Partial="Partial" Basic.Settings.Advanced.Video.ColorRange.Full="Full" -Basic.Settings.Advanced.Audio.MonitoringDevice="Audio monitoring apparaat" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitoring apparaat" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standaard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Schakel Windows audio ducking uit" Basic.Settings.Advanced.StreamDelay="Streamvertraging" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Bind aan IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Schakel nieuwe netwerkcode in" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Lage latency modus" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Hotkeys uitschakelen wanneer hoofdvenster in focus is" +Basic.Settings.Advanced.AutoRemux="Remux automatisch naar mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(neem op als mvk)" Basic.AdvAudio="Geavanceerde Audioinstellingen" Basic.AdvAudio.Name="Naam" -Basic.AdvAudio.Volume="Volume (%)" +Basic.AdvAudio.Volume="Volume" Basic.AdvAudio.Mono="Downmixen naar Mono" -Basic.AdvAudio.Panning="Pannen" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.Monitoring="Audio monitoring" Basic.AdvAudio.Monitoring.None="Niet monitoren" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Sporen" Basic.Settings.Hotkeys="Sneltoetsen" Basic.Settings.Hotkeys.Pair="Toetsencombinaties gedeeld met '%1' werken als toggle" +Basic.Settings.Hotkeys.Filter="Filter" Basic.Hotkeys.SelectScene="Wissel naar scène" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Muis %1" +Hotkeys.Escape="Esc" Mute="Mute" Unmute="Unmute" @@ -762,7 +824,7 @@ SceneItemHide="Verberg '%1'" OutputWarnings.NoTracksSelected="Selecteer a.u.b. ten minste een track" OutputWarnings.MultiTrackRecording="Waarschuwing: Sommige formaten (zoals FLV) bieden geen ondersteuning voor meerdere tracks per opname" -OutputWarnings.MP4Recording="Waarschuwing: Opnames opgeslagen als MP4 zijn niet te herstellen als de opame niet correct afgerond kan worden (bijvoorbeeld door BSOD's, stroomuitval). Als je wil opnemen met meerdere audiotracks gebruik dan bij voorkeur MKV en remux de opname naar mp4 (Bestand -> Remux opnames)" +OutputWarnings.MP4Recording="Waarschuwing: Opnames opgeslagen als MP4/MOV zijn niet te herstellen als de opname niet correct afgerond kan worden (bijvoorbeeld door BSOD's, stroomuitval). Als je wil opnemen met meerdere audiotracks gebruik dan bij voorkeur MKV en remux de opname naar MP4/MOV (Bestand → Remux opnames)" FinalScene.Title="Verwijder scène" FinalScene.Text="Er moet tenminste één scène zijn." @@ -770,9 +832,24 @@ FinalScene.Text="Er moet tenminste één scène zijn." NoSources.Title="Geen bronnen" NoSources.Text="Er zijn nog geen video bronnen toegevoegd, er zal dus een leeg scherm weergegeven worden. Weet je zeker dat je dit wilt doen?" NoSources.Text.AddSource="Bronnen kunnen toegevoegd worden door op het + icoon onder het vak \"Bronnen\" in het hoofdvenster te klikken." +NoSources.Label="U heeft geen bronnen.\nKlik op de + knop hieronder\nof rechtsklik hier om er toe te voegen." ChangeBG="Kleur instellen" CustomColor="Aangepaste kleur" BrowserSource.EnableHardwareAcceleration="Browser bron hardwareversnelling inschakelen" +About="Over" +About.Info="OBS Studio is een gratis en open source video recording en live streaming software." +About.Donate="Maak een bijdrage" +About.GetInvolved="Raak betrokken" +About.Authors="Auteurs" +About.License="Licentie" +About.Contribute="Steun het OBS project" + +ResizeOutputSizeOfSource="Uitvoer grootte aanpassen (brongrootte)" +ResizeOutputSizeOfSource.Text="De basis en uitvoer resoluties worden aangepast naar de grootte van de huidige bron." +ResizeOutputSizeOfSource.Continue="Wil je doorgaan?" + +PreviewTransition="Voorbeeld overgang" + diff --git a/UI/data/locale/nn-NO.ini b/UI/data/locale/nn-NO.ini index 582e19a..cd9915b 100644 --- a/UI/data/locale/nn-NO.ini +++ b/UI/data/locale/nn-NO.ini @@ -59,6 +59,9 @@ StudioMode.Program="Program" + + + BandwidthTest.Region="Region" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asia" @@ -81,6 +84,7 @@ Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Kopler til: %1..." Basic.Stats.Bitrate="Bitfrekvens" + Updater.UpdateNow="Oppdater no" Updater.Running.Title="Programmet er aktiv for augeblikket" @@ -104,6 +108,7 @@ ConfirmStart.Title="Starting av straum?" ConfirmStop.Title="Stoppe straumen?" + ConfirmExit.Title="Avslutt OBS?" @@ -112,7 +117,7 @@ ConfirmExit.Title="Avslutt OBS?" -LicenseAgreement.Exit="Avslutt" + @@ -132,6 +137,7 @@ Basic.Scene="Scene" + AddProfile.Title="Legg til profil" @@ -157,22 +163,22 @@ Basic.Main.StartStreaming="Byrje å straume" Basic.MainMenu.File="&Fil" Basic.MainMenu.File.Export="&Eksporter" Basic.MainMenu.File.Import="&Importer" -Basic.MainMenu.File.Settings="&Innstillingar" -Basic.MainMenu.File.Exit="A&vslutt" +Basic.MainMenu.File.Settings="Inn&stillingar" +Basic.MainMenu.File.Exit="Avslutt (&X)" -Basic.MainMenu.Edit="&Rediger" -Basic.MainMenu.Edit.Undo="&Angre" -Basic.MainMenu.Edit.Redo="&Omgjere" -Basic.MainMenu.Edit.UndoAction="&Angre $1" -Basic.MainMenu.Edit.RedoAction="&Omgjer $1" +Basic.MainMenu.Edit="R&ediger" +Basic.MainMenu.Edit.Undo="Angre (&U)" +Basic.MainMenu.Edit.Redo="Omgje&re" +Basic.MainMenu.Edit.UndoAction="Angre $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Omgje&r $1" Basic.MainMenu.View="&Vis" -Basic.MainMenu.View.Toolbars="&Verktøyslinjar" +Basic.MainMenu.View.Toolbars="Verk&tøyslinjar" Basic.MainMenu.View.SceneTransitions="S&ceneovergangar" Basic.MainMenu.Profile="&Profil" -Basic.MainMenu.Tools="&Verktøy" +Basic.MainMenu.Tools="Verk&tøy" Basic.MainMenu.Help="&Hjelp" @@ -200,6 +206,9 @@ Basic.Settings.General.Language="Språk" + + + diff --git a/UI/data/locale/pa-IN.ini b/UI/data/locale/pa-IN.ini new file mode 100644 index 0000000..241c83d --- /dev/null +++ b/UI/data/locale/pa-IN.ini @@ -0,0 +1,118 @@ + +Language="ਅੰਗਰੇਜ਼ੀ" +Region="ਅਮਰੀਕਾ" + +OK="ਠੀਕ ਹੈ" +Apply="ਲਾਗੂ ਕਰੋ" +Cancel="ਰੱਦ ਕਰੋ" +Close="ਬੰਦ ਕਰੋ" +Save="ਰੱਖਓ" +Discard="ਛੱਡੋ" +Disable="ਬੰਦ ਕਰੋ" +Yes="ਹਾਂਜੀ" +No="ਨਹੀਂ" +Remove="ਮਿਟਾਓ" +Rename="ਨਾਮ ਬਦਲੋ" +Filters="ਫਿਲਟਰ" +Properties="ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ" +MoveUp="ਉੱਪਰ ਕਰੋ" +MoveDown="ਹੇਠਾਂ ਕਰੋ" +Settings="ਸੈਟਿੰਗ" +Display="ਸਕ੍ਰੀਨ" +Name="ਨਾਮ" +Exit="ਬੰਦ ਕਰੋ" +Mixer="ਆਡੀਓ ਮਿਲਾਓ" +Browse="ਖੋਜ ਕਰੋ" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UI/data/locale/pl-PL.ini b/UI/data/locale/pl-PL.ini index 3ed7ca6..66b30b0 100644 --- a/UI/data/locale/pl-PL.ini +++ b/UI/data/locale/pl-PL.ini @@ -8,7 +8,7 @@ Cancel="Anuluj" Close="Zamknij" Save="Zapisz" Discard="Odrzuć" -Disable="Wyłączone" +Disable="Wyłącz" Yes="Tak" No="Nie" Add="Dodaj" @@ -49,7 +49,7 @@ Duplicate="Utwórz duplikat" Enable="Włącz" DisableOSXVSync="Wyłącz synchronizację pionową OSX" ResetOSXVSyncOnExit="Przywróć synchronizację pionową OSX po zamknięciu aplikacji" -HighResourceUsage="Enkodowanie przeciążone! Zmień ustawienia video lub użyj szybszego presetu enkodowania." +HighResourceUsage="Enkodowanie przeciążone! Zmień ustawienia wideo lub użyj szybszego presetu kodowania." Transition="Efekt przejścia" QuickTransitions="Szybkie efekty przejścia" Left="Od lewej" @@ -61,7 +61,7 @@ Hours="Godziny" Minutes="Minuty" Seconds="Sekundy" Deprecated="Wycofywane" -ReplayBuffer="Buffer replayu" +ReplayBuffer="Nagrywanie powtórek" Import="Importuj" Export="Eksportuj" Copy="Kopiuj" @@ -80,14 +80,40 @@ StudioMode.Program="Program" ShowInMultiview="Pokaż w Multiview" VerticalLayout="Układ pionowy" Group="Grupa" +DoNotShowAgain="Nie pokazuj ponownie" +Default="(Domyślnie)" +Calculating="Obliczanie..." AlreadyRunning.Title="OBS jest już uruchomiony" AlreadyRunning.Text="OBS jest już uruchomiony! Sprawdź wszystkie uruchomione wystąpienia OBS zanim uruchomisz go jeszcze raz. Jeżeli OBS jest zminimalizowany do zasobnika systemowego, sprawdź czy nie jest uruchomiony także w tym miejscu." AlreadyRunning.LaunchAnyway="Uruchom mimo to" +DockCloseWarning.Title="Zamykanie dokowalnego okna" +DockCloseWarning.Text="Zostało zamknięte dokowalne okno/panel. Jeżeli chcesz ponownie je pokazać, wybierz Widok → Panele z głównego menu." + +Auth.Authing.Title="Uwierzytelnianie..." +Auth.Authing.Text="Proszę czekać. Trwa uwierzytelnianie w %1..." +Auth.AuthFailure.Title="Błąd uwierzytelnienia" +Auth.AuthFailure.Text="Nie można uwierzytelnić w %1:\n\n%2: %3" +Auth.InvalidScope.Title="Wymagane uwierzytelnienie" +Auth.InvalidScope.Text="Zmieniły się wymagania uwierzytelniania dla %1. Niektóre funkcje mogą nie być dostępne." +Auth.LoadingChannel.Title="Trwa ładowanie informacji o kanale..." +Auth.LoadingChannel.Text="Proszę czekaj. Trwa ładowanie informacji o kanale w serwisie %1..." +Auth.ChannelFailure.Title="Nie udało się załadować informacji o kanale" +Auth.ChannelFailure.Text="Nie udało się załadować informacji o kanale w serwisie %1\n\n%2: %3" +Auth.Chat="Czat" +Auth.StreamInfo="Informacja o streamie" +TwitchAuth.Stats="Statystyki Twitch" +TwitchAuth.Feed="Lista aktywności Twitch" +TwitchAuth.TwoFactorFail.Title="Nie można pobrać klucza strumienia" +TwitchAuth.TwoFactorFail.Text="Powiązanie Twojego konta Twitch w OBS nie udało się. Sprawdź, czy masz włączone uwierzytelnianie dwuskładnikowe w ustawieniach bezpieczeństwa Twitcha. Wymagane jest to do streamowania przez tę platformę." + Copy.Filters="Kopiuj filtry" Paste.Filters="Wklej filtry" +BrowserPanelInit.Title="Inicjowanie przeglądarki..." +BrowserPanelInit.Text="Inicjowanie przeglądarki, proszę czekać..." + BandwidthTest.Region="Region" BandwidthTest.Region.US="Stany Zjednoczone" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Azja" BandwidthTest.Region.Other="Inny" Basic.FirstStartup.RunWizard="Czy chcesz uruchomić kreatora konfiguracji automatycznej? Można również ręcznie skonfigurować ustawienia, klikając przycisk Ustawienia w oknie głównym." -Basic.FirstStartup.RunWizard.BetaWarning="(Uwaga: Kreator konfiguracji automatycznej jest obecnie w wersji beta)" Basic.FirstStartup.RunWizard.NoClicked="Jeżeli zmienisz zdanie, można uruchomić kreatora konfiguracji automatycznej każdej chwili ponownie z menu Narzędzia." Basic.AutoConfig="Kreator konfiguracji automatycznej" -Basic.AutoConfig.Beta="Kreator konfiguracji automatycznej (Beta)" Basic.AutoConfig.ApplySettings="Zastosuj ustawienia" Basic.AutoConfig.StartPage="Sposób użytkowania" Basic.AutoConfig.StartPage.SubTitle="Określ w jaki sposób chcesz używać aplikacji" @@ -115,15 +139,21 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 lub 30 ale preferuj większą r Basic.AutoConfig.VideoPage.CanvasExplanation="Rozdzielczość bazowa niekoniecznie musi być rozdzielczością wynikowego nagrania lub streamu. Ta druga może być efektem skalowania w dół w celu zmniejszenia wymagań poziomu przepływności lub dostępności zasobów potrzebnych do kompresji." Basic.AutoConfig.StreamPage="Informacja o streamie" Basic.AutoConfig.StreamPage.SubTitle="Podaj informacje o streamie" +Basic.AutoConfig.StreamPage.ConnectAccount="Połącz konto (opcjonalne)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Odłącz konto" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odłączyć konto?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ta zmiana zostanie zastosowana natychmiast. Czy na pewno chcesz odłączyć konto?" +Basic.AutoConfig.StreamPage.UseStreamKey="Użyj klucza strumienia" Basic.AutoConfig.StreamPage.Service="Serwis" Basic.AutoConfig.StreamPage.Service.ShowAll="Pokaż wszystkie..." +Basic.AutoConfig.StreamPage.Service.Custom="Własny..." Basic.AutoConfig.StreamPage.Server="Serwer" Basic.AutoConfig.StreamPage.StreamKey="Klucz strumienia" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Oszacuj bitrate przy pomocy testu prędkości łącza (może potrwać parę minut)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferuj enkodowanie sprzętowe" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Enkodowanie sprzętowe odciąża procesor ale może wymagać większej przepustowości dla osiągnięcia porównywalnej jakości." -Basic.AutoConfig.StreamPage.StreamWarning.Title=" Ostrzeżenie" +Basic.AutoConfig.StreamPage.StreamWarning.Title="Ostrzeżenie" Basic.AutoConfig.StreamPage.StreamWarning.Text="W celu przetestowania streamu na Twój kanał zostaną wysyłane losowo generowane dane wideo bez dźwięku. Jeżeli to możliwe, zaleca się na czas testu tymczasowo wyłączyć zapisywanie streamu na serwerze i ustawienie streamu w tryb prywatny. Kontynuować?" Basic.AutoConfig.TestPage="Wyniki końcowe" Basic.AutoConfig.TestPage.SubTitle.Testing="Aplikacja przeprowadza obecnie serię testów w celu ustalenia najlepszych ustawień" @@ -140,7 +170,7 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="Testuję %1x%2 %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Enkoder streamu" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Enkoder nagrywania" Basic.AutoConfig.TestPage.Result.Header="Aplikacja ustaliła poniższe ustawienia jako najbardziej idealne dla Ciebie:" -Basic.AutoConfig.TestPage.Result.Footer="Aby użyć tych ustawień, kliknij przycisk Zastosuj ustawienia. Aby ponownie skonfigurować kreatora i spróbować ponownie, kliknij przycisk Wstecz. Aby ręcznie skonfigurować ustawienia, kliknij przycisk Anuluj i otwórz Ustawienia." +Basic.AutoConfig.TestPage.Result.Footer="Aby użyć tych ustawień, kliknij przycisk Zastosuj ustawienia. Aby ponownie skonfigurować kreatora i spróbować ponownie, kliknij przycisk Wstecz. Aby ręcznie skonfigurować ustawienia, kliknij przycisk Anuluj i otwórz Ustawienia." Basic.Stats="Statystyki" Basic.Stats.CPUUsage="Użycie procesora" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Nieaktywne" Basic.Stats.DroppedFrames="Zgubione klatki (sieć)" Basic.Stats.MegabytesSent="Całkowite dane wyjściowe" Basic.Stats.Bitrate="Przepływność (bitrate)" +Basic.Stats.DiskFullIn="Dysk pełny za (około)" + +ResetUIWarning.Title="Czy na pewno chcesz zresetować wygląd aplikacji?" +ResetUIWarning.Text="Reset ustawień wyglądu aplikacji ukryje dodatkowe okienka. Wymagane będzie ich przywrócenie z menu wyglądu, jeżeli mają być widoczne.\n\nCzy na pewno chcesz zresetować wygląd aplikacji?" Updater.Title="Dostępna jest nowa aktualizacja" Updater.Text="Dostępna jest nowa aktualizacja:" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="Brak dostępnych aktualizacji" Updater.NoUpdatesAvailable.Text="Brak dostępnych aktualizacji" Updater.FailedToLaunch="Nie udało się uruchomić aktualizacji" Updater.GameCaptureActive.Title="Przechwytywanie gry aktywne" -Updater.GameCaptureActive.Text="Przechwytywanie gry jest aktywne. Proszę o zamknięcie wszelkich przechwytywanych gier/aplikacji (lub ponowne uruchomienie systemu) i spróbowanie później." +Updater.GameCaptureActive.Text="Biblioteka zaczepiająca przechwytywanie gry jest w użyciu. Proszę zamknąć wszelkie przechwytywane gry lub inne programy (ewentualnie zrestartować system) i spróbować ponownie." QuickTransitions.SwapScenes="Zamień podgląd/wyjście scen po przejściu" QuickTransitions.SwapScenesTT="Zamienia podgląd i wyjście scen po przejściu (jeżeli wyjście oryginalnej sceny istnieje).\nNie przywraca to zmian jakie zostały dokonane w oryginalnej scenie." @@ -206,6 +240,9 @@ ConfirmStart.Text="Czy na pewno chcesz uruchomić streamowanie?" ConfirmStop.Title="Zatrzymać streamowanie?" ConfirmStop.Text="Czy na pewno chcesz uruchomić streamowanie?" +ConfirmBWTest.Title="Nadawanie w trybie testu przepustowości" +ConfirmBWTest.Text="OBS skonfigurowany jest w trybie testu przepustowości. Tryb ten pozwala na test połączenia sieciowego bez streamowania \"na żywo\". Po zakończeniu testów wyłącz tryb, aby móc streamować \"na żywo\".\n\nCzy chcesz kontynuować?" + ConfirmExit.Title="Wyjść z OBS?" ConfirmExit.Text="OBS jest uruchomiony. Wszelkie transmisje czy nagrania zostaną wyłączone. Czy na pewno chcesz zakończyć?" @@ -218,21 +255,26 @@ Output.StartRecordingFailed="Nie udało się rozpocząć nagrywania" Output.StartReplayFailed="Nie udało się rozpocząć nagrywania powtórek" Output.StartFailedGeneric="Nie udało się uruchomić wyjścia. Sprawdź szczegóły w plikach dziennika.\n\nUwaga: Sprawdź, czy posiadasz aktualne sterowniki karty graficznej, jeżeli używasz enkodera NVENC lub AMD." + Output.ConnectFail.Title="Nie udało się połączyć" Output.ConnectFail.BadPath="Nieprawidłowa ścieżka lub adres URL połączenia. Sprawdź poprawność ustawień." Output.ConnectFail.ConnectFailed="Nie udało się połączyć z serwerem" Output.ConnectFail.InvalidStream="Nie można uzyskać dostępu do wybranego kanału lub klucza streamu. Proszę sprawdzić klucz streamu. Jeżeli jest poprawny, to problemem może być połączenie do serwera." -Output.ConnectFail.Error="Wystąpił nieoczekiwany błąd podczas próby połączenia z serwerem. Więcej informacji w pliku dziennika." +Output.ConnectFail.Error="Wystąpił nieoczekiwany błąd podczas próby połączenia z serwerem. Więcej informacji w pliku dziennika." Output.ConnectFail.Disconnected="Utracono połączenie z serwerem." +Output.StreamEncodeError.Title="Błąd enkodowania" +Output.StreamEncodeError.Msg="W trakcie transmisji nastąpił błąd enkodowania." + Output.RecordFail.Title="Nie udało się rozpocząć nagrywania" Output.RecordFail.Unsupported="Format wyjściowy jest nieobsługiwany lub nie obsługuje więcej niż jednej ścieżki dźwiękowej. Sprawdź ustawienia i spróbuj ponownie." Output.RecordNoSpace.Title="Za mało miejsca na dysku" Output.RecordNoSpace.Msg="Za mało miejsca na dysku, aby kontynuować nagrywanie." Output.RecordError.Title="Błąd nagrywania" Output.RecordError.Msg="Wystąpił nieokreślony błąd podczas nagrywania." +Output.RecordError.EncodeErrorMsg="W trakcie nagrywania nastąpił błąd enkodowania." Output.ReplayBuffer.NoHotkey.Title="Brak klawisza skrótu!" -Output.ReplayBuffer.NoHotkey.Msg="Klawisz skrótu nie jest zapisany dla buforu replay. Ustaw skrót \"Zapisz\" aby zapisać nagrania replay." +Output.ReplayBuffer.NoHotkey.Msg="Klawisz skrótu do zapisu nagranej powtórki nie został ustawiony. Ustaw skrót dla opcji \"Zapisz powtórkę\", aby móc używać go do zapisywania tego typu nagrań." Output.BadPath.Title="Nieprawidłowa ścieżka pliku" Output.BadPath.Text="Ustawiona ścieżka pliku wynikowego jest nieprawidłowa. Proszę sprawdzić ustawienia." @@ -241,25 +283,23 @@ LogReturnDialog="Wysłanie pliku dziennika powiodło się" LogReturnDialog.CopyURL="Skopiuj adres URL" LogReturnDialog.ErrorUploadingLog="Błąd podczas wysyłania pliku dziennika" -LicenseAgreement="Warunki użytkowania" -LicenseAgreement.PleaseReview="Zanim zaczniesz korzystać z OBS przejrzyj warunki licencji. Korzystając z programu oświadczasz, że zapoznałeś się i zgodziłeś z warunkami licencji GNU General Public License v2.0. Przewiń tekst do dołu, by zobaczyć resztę umowy." -LicenseAgreement.ClickIAgreeToContinue="Jeśli akceptujesz warunki użytkowania, kliknij \"Zgadzam się\" aby kontynuować. Zgoda jest konieczna aby móc używać OBS Studio." -LicenseAgreement.IAgree="Zgadzam się" -LicenseAgreement.Exit="Wyjście" - -Remux.SourceFile="Nagrywanie OBS" +Remux.SourceFile="Plik nagrania OBS" Remux.TargetFile="Plik docelowy" Remux.Remux="Przepakowanie (remux)" +Remux.Stop="Zatrzymaj przepakowywanie" +Remux.ClearFinished="Usuń zakończone zadania" +Remux.ClearAll="Usuń wszystkie zadania" Remux.OBSRecording="Plik nagrania z OBS" Remux.FinishedTitle="Przepakowanie zakończone" Remux.Finished="Nagranie przepakowane" Remux.FinishedError="Nagranie przepakowane ale może być niekompletne" -Remux.SelectRecording="Wybierz nagranie OBS …" -Remux.SelectTarget="Wybierz plik docelowy …" +Remux.SelectRecording="Wybierz nagranie OBS..." +Remux.SelectTarget="Wybierz plik docelowy..." Remux.FileExistsTitle="Docelowy plik istnieje" -Remux.FileExists="Docelowy plik istnieje. Czy chcesz go zastąpić?" +Remux.FileExists="Poniższe pliki już istnieją. Czy chcesz je nadpisać?" Remux.ExitUnfinishedTitle="Przepakowywanie w toku" Remux.ExitUnfinished="Przepakowywanie nie zostało zakończone. Zatrzymując operację teraz plik wynikowy może być bezużyteczny.\nCzy na pewno chcesz zatrzymać przepakowywanie?" +Remux.HelpText="Przeciągnij pliki do tego okienka by je przepakować lub kliknij w wolne pole w kolumnie \"Plik nagrania z OBS\", by wybrać plik z dysku." UpdateAvailable="Aktualizacja dostępna" UpdateAvailable.Text="Wersja %1.%2.%3 jest dostępna. Kliknij tutaj aby pobrać" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Przechwytywanie obrazu" Basic.Main.PreviewConextMenu.Enable="Włącz podgląd" +Basic.Main.Preview.Disable="Wyłącz podgląd" + ScaleFiltering="Filtrowanie skalowania" ScaleFiltering.Point="Punktowe" ScaleFiltering.Bilinear="Dwuliniowe" ScaleFiltering.Bicubic="Dwusześcienne" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Obszar" Deinterlacing="Usuwanie przeplotu" Deinterlacing.Discard="Odrzuć" @@ -346,7 +389,7 @@ Basic.PropertiesView.FPS.ValidFPSRanges="Prawidłowe zakresy FPS:" Basic.InteractionWindow="Interakcja z '%1'" -Basic.StatusBar.Reconnecting="Rozłączony, ponowne połączenie za %2 s (próba %1)" +Basic.StatusBar.Reconnecting="Rozłączono, próba ponownego połączenia za %2s (próba %1)" Basic.StatusBar.AttemptingReconnect="Próba ponownego połączenia... (próba %1)" Basic.StatusBar.ReconnectSuccessful="Ponowne podłączenie udane" Basic.StatusBar.Delay="Opóźnienie (%1 s)" @@ -360,7 +403,7 @@ Basic.Filters.AudioFilters="Filtry audio" Basic.Filters.EffectFilters="Filtry efektów" Basic.Filters.Title="Filtry dla '%1'" Basic.Filters.AddFilter.Title="Nazwa filtra" -Basic.Filters.AddFilter.Text="Proszę wpisać nazwę filtru" +Basic.Filters.AddFilter.Text="Proszę wpisać nazwę filtra" Basic.TransformWindow="Przekształcanie elementu sceny" Basic.TransformWindow.Position="Pozycja" @@ -398,12 +441,12 @@ Basic.Main.Sources="Źródła obrazu" Basic.Main.Controls="Panel sterujący" Basic.Main.Connecting="Łączenie..." Basic.Main.StartRecording="Rozpocznij nagrywanie" -Basic.Main.StartReplayBuffer="Rozpocznij bufor replayu" +Basic.Main.StartReplayBuffer="Rozpocznij nagrywanie powtórek" Basic.Main.StartStreaming="Rozpocznij stream" Basic.Main.StopRecording="Zatrzymaj nagrywanie" Basic.Main.StoppingRecording="Zatrzymywanie nagrywania..." -Basic.Main.StopReplayBuffer="Zatrzymaj bufor replayu" -Basic.Main.StoppingReplayBuffer="Zatrzymywanie buforu replay..." +Basic.Main.StopReplayBuffer="Zatrzymaj nagrywanie powtórek" +Basic.Main.StoppingReplayBuffer="Zatrzymywanie nagrywania powtórek..." Basic.Main.StopStreaming="Zatrzymaj stream" Basic.Main.StoppingStreaming="Zatrzymywanie streamowania..." Basic.Main.ForceStopStreaming="Zatrzymaj stream (anuluj opóźnienie)" @@ -411,7 +454,7 @@ Basic.Main.Group="Grupa %1" Basic.Main.GroupItems="Grupuj wybrane elementy" Basic.Main.Ungroup="Rozgrupuj" -Basic.MainMenu.File="&Plik" +Basic.MainMenu.File="Plik (&F)" Basic.MainMenu.File.Export="&Eksport" Basic.MainMenu.File.Import="&Import" Basic.MainMenu.File.ShowRecordings="Pokaż nag&rania" @@ -420,19 +463,19 @@ Basic.MainMenu.File.Settings="U&stawienia" Basic.MainMenu.File.ShowSettingsFolder="Pokaż folder z ustawieniami" Basic.MainMenu.File.ShowProfileFolder="Pokaż folder z profilami" Basic.MainMenu.AlwaysOnTop="Z&awsze na wierzchu" -Basic.MainMenu.File.Exit="&Zakończ" +Basic.MainMenu.File.Exit="Zakończ (&X)" Basic.MainMenu.Edit="&Edycja" -Basic.MainMenu.Edit.Undo="&Cofnij" -Basic.MainMenu.Edit.Redo="&Wykonaj ponownie" -Basic.MainMenu.Edit.UndoAction="&Cofnij $1" -Basic.MainMenu.Edit.RedoAction="&Wykonaj ponownie $1" +Basic.MainMenu.Edit.Undo="Cofnij (&U)" +Basic.MainMenu.Edit.Redo="Wykonaj ponownie (&R)" +Basic.MainMenu.Edit.UndoAction="Cofnij $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Wykonaj ponownie $1 (&R)" Basic.MainMenu.Edit.LockPreview="Zab&lokuj podgląd" Basic.MainMenu.Edit.Scale="&Skalowanie widoku" Basic.MainMenu.Edit.Scale.Window="Skaluj do okna" Basic.MainMenu.Edit.Scale.Canvas="Powierzchnia robocza (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Powierzchnia wyjściowa (%1x%2)" -Basic.MainMenu.Edit.Transform="&Przekształcanie obrazu" +Basic.MainMenu.Edit.Transform="Przeksz&tałcanie obrazu" Basic.MainMenu.Edit.Transform.EditTransform="&Edycja przekształceń..." Basic.MainMenu.Edit.Transform.CopyTransform="Skopiuj transformacje" Basic.MainMenu.Edit.Transform.PasteTransform="Wklej transformacje" @@ -440,30 +483,32 @@ Basic.MainMenu.Edit.Transform.ResetTransform="&Reset przekształceń" Basic.MainMenu.Edit.Transform.Rotate90CW="Obróć o 90 stopni zgodnie z ruchem wskazówkek zegara" Basic.MainMenu.Edit.Transform.Rotate90CCW="Obróć o 90 stopni przeciwnie do ruchu wskazówek zegara" Basic.MainMenu.Edit.Transform.Rotate180="Obróć o 180 stopni" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Przerzuć w po&ziomie" -Basic.MainMenu.Edit.Transform.FlipVertical="Przerzuć w &pionie" -Basic.MainMenu.Edit.Transform.FitToScreen="&Dopasuj do ekranu" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Rozciągnij do ekranu" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Wyśrodkuj na ekranie" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Przerzuć w poziomie (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Przerzuć w pionie (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Dopasuj do ekranu (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Rozciągnij do ekranu (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Wyśrodkuj na ekranie (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Wyśrodkuj w pionie" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Wyśrodkuj w poziomie" Basic.MainMenu.Edit.Order="K&olejność" -Basic.MainMenu.Edit.Order.MoveUp="Przesuń w &górę" +Basic.MainMenu.Edit.Order.MoveUp="Przes&uń w górę" Basic.MainMenu.Edit.Order.MoveDown="Przesuń w &dół" -Basic.MainMenu.Edit.Order.MoveToTop="Przesuń na samą gó&rę" -Basic.MainMenu.Edit.Order.MoveToBottom="Przesuń na sa&m dół" +Basic.MainMenu.Edit.Order.MoveToTop="Przesuń na samą górę (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Przesuń na sam dół (&B)" Basic.MainMenu.Edit.AdvAudio="Z&aawansowane ustawienia dźwięku" -Basic.MainMenu.View="&Widok" -Basic.MainMenu.View.Toolbars="Paski &narzędzi" +Basic.MainMenu.View="Widok (&V)" +Basic.MainMenu.View.Toolbars="Paski narzędzi (&T)" Basic.MainMenu.View.Docks="Panele" Basic.MainMenu.View.Docks.ResetUI="Przywróć domyślny interfejs" Basic.MainMenu.View.Docks.LockUI="Zablokuj interfejs" Basic.MainMenu.View.Toolbars.Listboxes="Panele kontrolne &list elementów" -Basic.MainMenu.View.SceneTransitions="Efekty &przejścia scen" +Basic.MainMenu.View.SceneTransitions="Efekty przejś&cia scen" Basic.MainMenu.View.StatusBar="Pasek &stanu" Basic.MainMenu.View.Fullscreen.Interface="Pełnoekranowy interfejs" Basic.MainMenu.SceneCollection="Zbiór &scen" -Basic.MainMenu.Profile="P&rofil" +Basic.MainMenu.Profile="&Profil" Basic.MainMenu.Profile.Import="Importuj profil" Basic.MainMenu.Profile.Export="Eksportuj profil" Basic.MainMenu.SceneCollection.Import="Importuj kolekcje sceny" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Exportuj kolekcje sceny" Basic.MainMenu.Profile.Exists="Profil już istnieje" Basic.MainMenu.SceneCollection.Exists="Kolekcja sceny już istnieje" -Basic.MainMenu.Tools="&Narzędzia" +Basic.MainMenu.Tools="Narzędzia (&T)" -Basic.MainMenu.Help="P&omoc" +Basic.MainMenu.Help="Pomoc (&H)" Basic.MainMenu.Help.HelpPortal="&Portal pomocy" Basic.MainMenu.Help.Website="Od&wiedź naszą stronę" Basic.MainMenu.Help.Discord="Dołącz do serwera &Discord" Basic.MainMenu.Help.Logs="P&liki dziennika" Basic.MainMenu.Help.Logs.ShowLogs="Pokaż pliki dziennika (&s)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Wyślij &aktualny plik dziennika" -Basic.MainMenu.Help.Logs.UploadLastLog="Wyślij o&statni plik dziennika" -Basic.MainMenu.Help.Logs.ViewCurrentLog="Podgląd akty&wnego pliku dziennika" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Wyślij aktualny plik dziennika (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Wyś&lij ostatni plik dziennika" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Podgląd aktywnego pliku dziennika (&V)" Basic.MainMenu.Help.CheckForUpdates="Sprawdź dostępność aktualizacji" Basic.MainMenu.Help.CrashLogs="&Raporty o awariach" Basic.MainMenu.Help.CrashLogs.ShowLogs="Pokaż raporty o awariach (&S)" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Wyślij ostatni raport o awariach (&L)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Wyś&lij ostatni raport o awariach" +Basic.MainMenu.Help.About="O progr&amie" Basic.Settings.ProgramRestart="Aby te ustawienia zaczęły obowiązywać, należy ponownie uruchomić program." Basic.Settings.ConfirmTitle="Potwierdź zmiany" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Zasobnik systemowy" Basic.Settings.General.SysTrayWhenStarted="Minimalizuj do zasobnika systemowego podczas uruchamiania" Basic.Settings.General.SystemTrayHideMinimize="Zawsze minimalizuj do zasobnika systemowego zamiast do paska zadań" Basic.Settings.General.SaveProjectors="Zapisz konfigurację podglądów na pełnym ekranie przy zamknięciu aplikacji" +Basic.Settings.General.Preview="Podgląd" +Basic.Settings.General.OverflowHidden="Ukryj elementy poza granicami widoku" +Basic.Settings.General.OverflowAlwaysVisible="Elementy poza granicami widoku zawsze widoczne" +Basic.Settings.General.OverflowSelectionHidden="Elementy poza granicami widoczne nawet, gdy źródło jest ukryte" Basic.Settings.General.SwitchOnDoubleClick="Przejdź do sceny po dwukrotnym kliknięciu" Basic.Settings.General.StudioPortraitLayout="Włącz układ pionowy" +Basic.Settings.General.TogglePreviewProgramLabels="Pokaż etykiety podglądu/programu" Basic.Settings.General.Multiview="Multiview" Basic.Settings.General.Multiview.MouseSwitch="Kliknij, aby przełączać się między scenami" Basic.Settings.General.Multiview.DrawSourceNames="Pokaż nazwy scen" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Poziomo, Góra ( Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Typ streamu" +Basic.Settings.Stream.Custom.UseAuthentication="Użyj uwierzytelniania" +Basic.Settings.Stream.Custom.Username="Nazwa użytkownika" +Basic.Settings.Stream.Custom.Password="Hasło" +Basic.Settings.Stream.BandwidthTestMode="Włącz tryb testu przepustowości" Basic.Settings.Output="Wyjście" Basic.Settings.Output.Format="Format nagrywania" @@ -540,17 +595,17 @@ Basic.Settings.Output.Mode="Tryb wyjścia" Basic.Settings.Output.Mode.Simple="Proste" Basic.Settings.Output.Mode.Adv="Zaawansowane" Basic.Settings.Output.Mode.FFmpeg="Wyjście FFmpeg" -Basic.Settings.Output.UseReplayBuffer="Włącz bufor replay" -Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksymalny czas replay (w sekundach)" +Basic.Settings.Output.UseReplayBuffer="Włącz nagrywanie powtórek" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksymalny czas nagrania (w sekundach)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksymalna ilość pamięci (w megabajtach)" Basic.Settings.Output.ReplayBuffer.Estimate="Szacowane użycie pamięci: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nie można oszacować użycie pamięci. Należy ustawić limit maksymalnej pamięci." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Uwaga: Upewnij się aby ustawić klawisz skrótu dla buforu replay w sekcji Skróty klawiszowe)" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nie można oszacować użycia pamięci. Należy ustawić limit maksymalnej pamięci." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Uwaga: Upewnij się, czy ustawiony został klawisz skrótu do zapisu powtórek w sekcji \"Skróty klawiszowe\")" Basic.Settings.Output.ReplayBuffer.Prefix="Prefiks nazwy pliku buforu replay" Basic.Settings.Output.ReplayBuffer.Suffix="Sufiks" Basic.Settings.Output.Simple.SavePath="Ścieżka pliku" Basic.Settings.Output.Simple.RecordingQuality="Jakość nagrywania" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Taki sam jak stream" +Basic.Settings.Output.Simple.RecordingQuality.Stream="Taka sama jak stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Wysoka jakość, średni rozmiar pliku" Basic.Settings.Output.Simple.RecordingQuality.HQ="Jakość nie do odróżnienia, duża wielkość pliku" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Jakość bezstratna, ogromna wielkość pliku" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Ostrzeżenie: Nagrywanie przy użyciu Basic.Settings.Output.Simple.Warn.Lossless="Ostrzeżenie: Jakość bezstratna generuje bardzo duże pliki! Przy dużych rozdzielczościach i szybkości klatek rozmiar pliku może sięgać 7GB na minutę nagrania. Jakość ta nie jest zalecana w przypadku długich nagrań, chyba że masz bardzo dużo wolnego miejsca na dysku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Czy na pewno chcesz użyć bezstratnej jakości?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Ostrzeżenie o bezstratnej jakości!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Ostrzeżenie: Korzystanie z wielu różnych enkoderów QSV do streamowania i nagrywania jest niedozwolone. Jeżeli chcesz streamować i nagrywać w tym samym czasie, zmień ustawienia enkodera nagrywania bądź streamowania." Basic.Settings.Output.Simple.Encoder.Software="Programowy (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Sprzętowy (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Sprzętowy (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Ponowne łączenie" Basic.Settings.Output.RetryDelay="Ponów połączenie (w sekundach)" Basic.Settings.Output.MaxRetries="Maksymalna liczba ponownych prób" Basic.Settings.Output.Advanced="Włącz zaawansowane ustawienia enkodera" -Basic.Settings.Output.EncoderPreset="Ustawienia enkodera (wyższe = mniej CPU)" +Basic.Settings.Output.EncoderPreset="Ustawienia enkodera" Basic.Settings.Output.CustomEncoderSettings="Ustawienia niestandardowe enkodera" Basic.Settings.Output.CustomMuxerSettings="Własne ustawienia muxera" Basic.Settings.Output.NoSpaceFileName="Generuj nazwę pliku bez spacji" @@ -634,7 +688,7 @@ Basic.Settings.Video.FPSFraction="Ułamkowe wartości FPS" Basic.Settings.Video.Numerator="Licznik" Basic.Settings.Video.Denominator="Mianownik" Basic.Settings.Video.Renderer="Renderowanie" -Basic.Settings.Video.InvalidResolution="Nieprawidłowa rozdzielczość. Wartość powinna mieć format [szerokość]x[wysokość] (np. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Nieprawidłowa rozdzielczość. Wartość powinna mieć format [szerokość]x[wysokość] (np. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Wyjście wideo jest aktywne. Należy wyłączyć wszelkie wyjścia, aby zmienić ustawienia wideo." Basic.Settings.Video.DisableAero="Wyłącz Aero" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (skalowanie ostrzejsze, 32 Basic.Settings.Audio="Dźwięk" Basic.Settings.Audio.SampleRate="Częstotliwość próbkowania" Basic.Settings.Audio.Channels="Kanały" -Basic.Settings.Audio.MeterDecayRate="Szybkość powrotu miernika audio" +Basic.Settings.Audio.Meters="Mierniki" +Basic.Settings.Audio.MeterDecayRate="Czas zanikania" Basic.Settings.Audio.MeterDecayRate.Fast="Szybko" Basic.Settings.Audio.MeterDecayRate.Medium="Średnio (PPM typu I)" Basic.Settings.Audio.MeterDecayRate.Slow="Wolno (PPM typu II)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Uwaga: Dźwięk przestrzenny j Basic.Settings.Audio.MultichannelWarning="W przypadku streamowania sprawdź, czy docelowa usługa obsługuje wielokanałowe wejście oraz odtwarzanie dźwięku surround. Twitch, Facebook, 360 Live, Mixer RTMP, Smashcast to przykłady usług obsługujących dźwięk wielokanałowy. O ile Facebook Live i Youtube Live obsługują wejście dźwięku wielokanałowego, to w przypadku odtwarzania Facebook miksuje kanału do stereo a Youtube Live odtwarza tylko dwa kanały.\n\nFiltry dźwiękowe OBS są w pełni kompatybilne z dźwiękiem kanałowym, natomiast wsparcie pluginów VST nie jest gwarantowane." Basic.Settings.Audio.MultichannelWarning.Title="Włączyć dźwięk przestrzenny?" Basic.Settings.Audio.MultichannelWarning.Confirm="Czy na pewno chcesz włączyć dźwięk przestrzenny?" -Basic.Settings.Audio.DesktopDevice="Urządzenie Audio" -Basic.Settings.Audio.DesktopDevice2="Urządzenie Audio 2" +Basic.Settings.Audio.Devices="Urządzenia" +Basic.Settings.Audio.DesktopDevice="Urządzenie audio" +Basic.Settings.Audio.DesktopDevice2="Urządzenie audio 2" Basic.Settings.Audio.AuxDevice="Mikrofon/dodatkowe urządzenie audio" Basic.Settings.Audio.AuxDevice2="Mikrofon/dodatkowe urządzenie audio 2" Basic.Settings.Audio.AuxDevice3="Mikrofon/dodatkowe urządzenie audio 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/dodatkowe urządzenie audio 4" Basic.Settings.Audio.EnablePushToMute="Włącz \"naciśnij-aby-wyciszyć\"" Basic.Settings.Audio.PushToMuteDelay="Opóźnienie \"naciśnij-aby-wyciszyć\"" Basic.Settings.Audio.EnablePushToTalk="Włącz \"naciśnij-aby-mówić\"" Basic.Settings.Audio.PushToTalkDelay="Opóźnienie \"naciśnij-aby-mówić\"" Basic.Settings.Audio.UnknownAudioDevice="[Urządzenie niedostępne lub niepodłączone]" +Basic.Settings.Audio.Disabled="Wyłączone" Basic.Settings.Advanced="Zaawansowane" Basic.Settings.Advanced.General.ProcessPriority="Priorytet procesu" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Bezczynny" Basic.Settings.Advanced.FormatWarning="Ostrzeżenie: Formaty koloru inne niż NV12 przeznaczone są głównie do nagrywania i nie są zalecane podczas przesyłania strumieniowego. Użycie innych formatów koloru podczas przesyłania strumieniowego wymagać będzie przekształcenia formatu w locie, co może znacząco zwiększyć obciążenie procesora." Basic.Settings.Advanced.Audio.BufferingTime="Czas buforowania dźwięku" Basic.Settings.Advanced.Video.ColorFormat="Format koloru" -Basic.Settings.Advanced.Video.ColorSpace="Przestrzeń kolorów YUV" -Basic.Settings.Advanced.Video.ColorRange="Zakres kolorów YUV" +Basic.Settings.Advanced.Video.ColorSpace="Przestrzeń kolorów" +Basic.Settings.Advanced.Video.ColorRange="Zakres kolorów" Basic.Settings.Advanced.Video.ColorRange.Partial="Częściowy" Basic.Settings.Advanced.Video.ColorRange.Full="Pełny" -Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorowane urządzenie audio" +Basic.Settings.Advanced.Audio.MonitoringDevice="Urządzenie do monitorowania audio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Domyślne" Basic.Settings.Advanced.Audio.DisableAudioDucking="Wyłącz systemowe obniżanie głośności innych źródeł dźwięków" Basic.Settings.Advanced.StreamDelay="Opóźnienie streamu" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Przypisane IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktywuj nowy kod sieciowy" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Tryb niskich opóźnień" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Wyłącz skróty klawiszowe, gdy główne okno programu jest aktywne na pierwszym planie" +Basic.Settings.Advanced.AutoRemux="Automatycznie przepakuj (remux) do mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(nagrywaj jako mkv)" Basic.AdvAudio="Zaawansowane ustawienia dźwięku" Basic.AdvAudio.Name="Nazwa" -Basic.AdvAudio.Volume="Głośność (%)" +Basic.AdvAudio.Volume="Głośność" Basic.AdvAudio.Mono="Downmix do Mono" -Basic.AdvAudio.Panning="Rozciągnięcie dźwięku" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Przesunięcie dźwięku (ms)" Basic.AdvAudio.Monitoring="Monitorowanie urządzenia audio" Basic.AdvAudio.Monitoring.None="Wyłączone" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Ścieżki" Basic.Settings.Hotkeys="Skróty klawiszowe" Basic.Settings.Hotkeys.Pair="Komibnacje klawiszy wspólne z '%1' działają jako przełączniki" +Basic.Settings.Hotkeys.Filter="Filtruj" Basic.Hotkeys.SelectScene="Przełącz na scenę" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Mysz %1" +Hotkeys.Escape="Esc" Mute="Wyciszenie" Unmute="Wyłącz wyciszenie" @@ -762,7 +824,7 @@ SceneItemHide="Ukryj '%1'" OutputWarnings.NoTracksSelected="Musisz wybrać przynajmniej jedną ścieżkę" OutputWarnings.MultiTrackRecording="Ostrzeżenie: Pewne formaty plików (np. FLV) nie obsługują wielu ścieżek dźwiękowych" -OutputWarnings.MP4Recording="Ostrzeżenie: Nagrania zapisanego w formacie mp4 nie będzie można odzyskać, jeśli plik nie zostanie zakończony poprawnie (np. w wyniku BSOD, braku prądu, itp.). Jeśli chcesz nagrać wiele ścieżek audio należy rozważyć użycie formatu mkv i remux nagrania do mp4 po zakończeniu (Plik -> Przepakuj nagrania)." +OutputWarnings.MP4Recording="Ostrzeżenie: Nagrania zapisanego w formacie MP4/MOV nie będzie można odzyskać, jeśli plik nie zostanie zakończony poprawnie (np. w wyniku BSOD, braku prądu, itp.). Jeśli chcesz nagrać wiele ścieżek audio należy rozważyć użycie formatu MKV i remux nagrania do MP4/MOV po zakończeniu (Plik → Przepakuj nagrania)." FinalScene.Title="Usuń scenę" FinalScene.Text="Musi być co najmniej jedna scena." @@ -770,9 +832,24 @@ FinalScene.Text="Musi być co najmniej jedna scena." NoSources.Title="Brak źródeł" NoSources.Text="Wygląda na to, że nie dodano żadnych źródeł video. Na wyjściu otrzymasz tylko czarny ekran. Czy na pewno chcesz to zrobić?" NoSources.Text.AddSource="Źródła dodać można w każdym momencie klikając przycisk + w okienku Źródła głównego ekranu aplikacji." +NoSources.Label="Nie masz żadnych źródeł.\nKliknij przycisk + poniżej lub kliknij tutaj\n prawym przyciskiem myszy, aby dodać źródło." ChangeBG="Ustaw kolor" CustomColor="Kolor niestandardowy" BrowserSource.EnableHardwareAcceleration="Włącz akcelerację sprzętową w pluginie przeglądarki" +About="O programie" +About.Info="OBS Studio to darmowe i otwarte oprogramowanie do nagrywania i transmitowania materiału wideo." +About.Donate="Wpłać donację" +About.GetInvolved="Wesprzyj nas" +About.Authors="Autorzy" +About.License="Licencja" +About.Contribute="Wesprzyj projekt" + +ResizeOutputSizeOfSource="Zmień rozdzielczość wynikową (rozmiar źródła)" +ResizeOutputSizeOfSource.Text="Rozdzielczość bazowa i docelowa zostaną zmienione do rozdzielczości bieżącego źródła." +ResizeOutputSizeOfSource.Continue="Czy chcesz kontynuować?" + +PreviewTransition="Podgląd efektu przejścia" + diff --git a/UI/data/locale/pt-BR.ini b/UI/data/locale/pt-BR.ini index 5938697..3dad406 100644 --- a/UI/data/locale/pt-BR.ini +++ b/UI/data/locale/pt-BR.ini @@ -17,8 +17,8 @@ Rename="Renomear" Interact="Interagir" Filters="Filtros" Properties="Propriedades" -MoveUp="Mover para Cima" -MoveDown="Mover para Baixo" +MoveUp="Mover para cima" +MoveDown="Mover para baixo" Settings="Configurações" Display="Monitor" Name="Nome" @@ -27,22 +27,22 @@ Mixer="Mixer" Browse="Localizar" Mono="Mono" Stereo="Estéreo" -DroppedFrames="Quadros Perdidos %1 (%2%)" -StudioProgramProjector="Projetor em tela cheia (Programa)" -PreviewProjector="Projetor em tela cheia (pré-visualização)" -SceneProjector="Projetor em tela cheia (cena)" -SourceProjector="Projetor em tela cheia (fonte)" -StudioProgramWindow="Projetor em janela (Programa)" -PreviewWindow="Projetor em janela (Pré-visualização)" -SceneWindow="Projetor em janela (Cena)" +DroppedFrames="Quadros perdidos %1 (%2%)" +StudioProgramProjector="Projetor em tela inteira (programa)" +PreviewProjector="Projetor em tela inteira (pré-visualização)" +SceneProjector="Projetor em tela inteira (cena)" +SourceProjector="Projetor em tela inteira (fonte)" +StudioProgramWindow="Projetor em janela (programa)" +PreviewWindow="Projetor em janela (pré-visualização)" +SceneWindow="Projetor em janela (cena)" SourceWindow="Projetor em janela (Fonte)" -MultiviewProjector="Multiview (Tela Cheia)" -MultiviewWindowed="Multiview (Em Janela)" +MultiviewProjector="Visualização múltipla (tela inteira)" +MultiviewWindowed="Visualização múltipla (janela)" Clear="Limpar" Revert="Desfazer" Show="Exibir" Hide="Ocultar" -UnhideAll="Mostrar Todos" +UnhideAll="Mostrar tudo" Untitled="Sem nome" New="Novo" Duplicate="Duplicar" @@ -51,7 +51,7 @@ DisableOSXVSync="Desabilitar V-Sync em OSX" ResetOSXVSyncOnExit="Redefinir V-Sync em OSX na saída" HighResourceUsage="Codificação sobrecarregada! Considere abaixar as configurações de vídeo ou usar um padrão de codificação mais rápido." Transition="Transição" -QuickTransitions="Transições Rápidas" +QuickTransitions="Transições rápidas" Left="Esquerda" Right="Direita" Top="Topo" @@ -66,9 +66,9 @@ Import="Importar" Export="Exportar" Copy="Copiar" Paste="Colar" -PasteReference="Colar (Referência)" -PasteDuplicate="Colar (Duplicar)" -RemuxRecordings="Remixar Gravações" +PasteReference="Colar (referência)" +PasteDuplicate="Colar (duplicar)" +RemuxRecordings="Converter gravações" Next="Avançar" Back="Voltar" Defaults="Padrões" @@ -77,29 +77,53 @@ TransitionOverride="Substituição de Transição" None="Nenhuma" StudioMode.Preview="Prévia" StudioMode.Program="Programa" -ShowInMultiview="Mostrar no Multiview" -VerticalLayout="Layout Vertical" +ShowInMultiview="Mostrar em visualização múltipla" +VerticalLayout="Disposição vertical" Group="Grupo" +DoNotShowAgain="Não mostrar novamente" +Default="(Padrão)" +Calculating="Calculando..." AlreadyRunning.Title="OBS já está em execução" AlreadyRunning.Text="OBS já está em execução! A menos que você tenha a intenção de fazer isso, por favor, feche todas as instâncias existentes do OBS antes de tentar executar uma nova. Se você tiver definido para minimizar o OBS na bandeja do sistema, verifique se ainda está lá em execução." AlreadyRunning.LaunchAnyway="Executar mesmo assim" +DockCloseWarning.Title="Fechar janela ancorável" +DockCloseWarning.Text="Você acabou de fechar uma janela ancorável. Se você gostaria de abri-la novamente, use o menu Mostrar → Âncoras." + +Auth.Authing.Title="Autenticando..." +Auth.Authing.Text="Autenticando com a(o) %1, aguarde..." +Auth.AuthFailure.Title="Falha na Autenticação" +Auth.AuthFailure.Text="Falha na Autenticação com a(o)%1:\n\n%2: %3" +Auth.InvalidScope.Title="Autenticação Necessária" +Auth.InvalidScope.Text="Os requisitos de autenticação para %1 foram alterados. Alguns recursos podem não estar disponíveis." +Auth.LoadingChannel.Title="Carregando informações do canal..." +Auth.LoadingChannel.Text="Carregando informações do canal para %1. Por favor, aguarde..." +Auth.ChannelFailure.Title="Erro ao carregar canal" +Auth.ChannelFailure.Text="Erro ao carregar informaões do canal da(o) %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informação da transmissão" +TwitchAuth.Stats="Estatísticas da Twitch" +TwitchAuth.Feed="Feed de Atividade do Twitch" +TwitchAuth.TwoFactorFail.Title="Não foi possível consultar a chave de transmissão" +TwitchAuth.TwoFactorFail.Text="O OBS não foi capaz de se conectar à sua conta do Twitch. Por favor, certifique-se de que a autenticação de dois fatores está configurada em suas Configurações de segurança do Twitch pois isso é necessário para transmitir." + Copy.Filters="Copiar Filtros" Paste.Filters="Colar Filtros" +BrowserPanelInit.Title="Inicializando o Navegador..." +BrowserPanelInit.Text="Inicializando o navegador, aguarde..." + BandwidthTest.Region="Região" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Ásia" BandwidthTest.Region.Other="Outro" -Basic.FirstStartup.RunWizard="Você gostaria de executar o assistente de configuração? Você também pode definir manualmente suas configurações clicando no botão \"Configurações\" na janela principal." -Basic.FirstStartup.RunWizard.BetaWarning="(Nota: O assistente de configuração está atualmente em beta)" +Basic.FirstStartup.RunWizard="Você gostaria de executar o assistente de configuração? Você também pode definir manualmente suas configurações clicando no botão \"Configurações\" na janela principal." Basic.FirstStartup.RunWizard.NoClicked="Se você mudar de ideia, você pode executar o assistente de configuração a qualquer momento no menu \"Ferramentas\"." -Basic.AutoConfig="Assistente de configuração automática" -Basic.AutoConfig.Beta="Assistente de configuração automática (Beta)" +Basic.AutoConfig="Assistente de configuração" Basic.AutoConfig.ApplySettings="Aplicar Configurações" Basic.AutoConfig.StartPage="Informações de Uso" Basic.AutoConfig.StartPage.SubTitle="Marque para que você deseja usar o programa" @@ -113,23 +137,29 @@ Basic.AutoConfig.VideoPage.FPS.UseCurrent="Usar Atual (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ou 30, mas prefiro 60 quando possível" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, mas prefiro alta resolução" Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: A resolução da tela (base) não é necessariamente a mesma resolução que você transmitirá ou gravará. Sua resolução final da transmissão/gravação pode ser redimencionada da resolução da tela para reduzir o uso de recursos ou bitrate necessário." -Basic.AutoConfig.StreamPage="Informações da Transmissão" +Basic.AutoConfig.StreamPage="Informações da transmissão" Basic.AutoConfig.StreamPage.SubTitle="Por favor, digite suas informações para a transmissão" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar Conta (opcional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar conta" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Desconectar conta?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Esta mudança será aplicada imediatamente. Tem certeza de que deseja desconectar sua conta?" +Basic.AutoConfig.StreamPage.UseStreamKey="Usar chave da transmissão" Basic.AutoConfig.StreamPage.Service="Serviço" Basic.AutoConfig.StreamPage.Service.ShowAll="Mostrar todos..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizado..." Basic.AutoConfig.StreamPage.Server="Servidor" -Basic.AutoConfig.StreamPage.StreamKey="Chave da Transmissão" +Basic.AutoConfig.StreamPage.StreamKey="Chave da transmissão" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimar taxa de bits com teste de largura de banda (pode levar uns minutos)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferir codificação por hardware" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Codificação por Hardware elimina a maioria do uso de CPU, mas pode exigir uma taxa de bits maior para obter o mesmo nível de qualidade." -Basic.AutoConfig.StreamPage.StreamWarning.Title="Aviso de Transmissão" +Basic.AutoConfig.StreamPage.StreamWarning.Title="Aviso de transmissão" Basic.AutoConfig.StreamPage.StreamWarning.Text="O teste de largura de banda está prestes a transmitir imagens aleatórias e sem áudio para o seu canal. Se for possível, é recomendável desativar temporariamente a gravação da transmissão e definir a transmissão como privada até que o teste seja concluído. Continuar?" Basic.AutoConfig.TestPage="Resultados Finais" Basic.AutoConfig.TestPage.SubTitle.Testing="O programa está executando um conjunto de testes para estimar as configurações ideais" Basic.AutoConfig.TestPage.SubTitle.Complete="Teste completo" Basic.AutoConfig.TestPage.TestingBandwidth="Executando teste de largura de banda, isso pode levar alguns minutos..." -Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Conectando a: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Conectando a: %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Falha ao se conectar a qualquer servidor, verifique sua conexão com a Internet e tente novamente." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Teste de largura de banda para: %1" Basic.AutoConfig.TestPage.TestingStreamEncoder="Testando codificador de transmissão, isto pode demorar um minuto..." @@ -137,10 +167,10 @@ Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testando codificador de grava Basic.AutoConfig.TestPage.TestingRes="Testando resoluções, isto pode levar alguns minutos..." Basic.AutoConfig.TestPage.TestingRes.Fail="Falha ao iniciar o codificador" Basic.AutoConfig.TestPage.TestingRes.Resolution="Testando %1x%2 %3 QPS..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codificador da Transmissão" +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codificador da transmissão" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codificador da Gravação" Basic.AutoConfig.TestPage.Result.Header="O programa determinou que estas configurações estimadas são as mais ideais para você:" -Basic.AutoConfig.TestPage.Result.Footer="Para usar essas configurações, clique em \"Aplicar Configurações\". Para reconfigurar o assistente e tentar novamente, clique em \"Voltar\". Para definir manualmente, clique em \"Cancelar\" e abra as \"Configurações\"." +Basic.AutoConfig.TestPage.Result.Footer="Para usar essas configurações, clique em \"Aplicar Configurações\". Para reconfigurar o assistente e tentar novamente, clique em \"Voltar\". Para definir manualmente, clique em \"Cancelar\" e abra as \"Configurações\"." Basic.Stats="Estatísticas" Basic.Stats.CPUUsage="Uso de CPU" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Inativa" Basic.Stats.DroppedFrames="Quadros Perdidos (Rede)" Basic.Stats.MegabytesSent="Saída Total de Dados" Basic.Stats.Bitrate="Taxa de bits" +Basic.Stats.DiskFullIn="Disco completo em (aprox.)" + +ResetUIWarning.Title="Tem certeza de que deseja redefinir a interface do usuário?" +ResetUIWarning.Text="Redefinir a interface irá ocultar as âncoras adicionais. Você precisará mostra-las indo no menu de visualização se quiser que elas se tornem visíveis novamente.\n\nTem certeza de que deseja redefinir a interface do usuário?" Updater.Title="Nova atualização disponível" Updater.Text="Há uma nova atualização disponível:" @@ -171,10 +205,10 @@ Updater.NoUpdatesAvailable.Title="Nenhuma atualização disponível" Updater.NoUpdatesAvailable.Text="Não há atualizações disponíveis" Updater.FailedToLaunch="Falha ao iniciar o atualizador" Updater.GameCaptureActive.Title="Captura de jogo ativa" -Updater.GameCaptureActive.Text="A biblioteca de captura de jogos está em uso. Feche todos os jogos / programas que estão sendo capturados (ou reinicie o computador) e tente novamente." +Updater.GameCaptureActive.Text="A biblioteca de captura do jogo está em uso no momento. Por favor feche qualquer jogo/programa que esteja sendo capturado (ou reinicie o Windows) e tente novamente." QuickTransitions.SwapScenes="Trocar Cenas de Prévia/Saída após a Transição" -QuickTransitions.SwapScenesTT="Troca a preview e a saída após transicionar (se a a cena original de saída ainda exisitr).\nIsto não irá desfazer nenhuma mudança que foi feita na cena original da saída." +QuickTransitions.SwapScenesTT="Troca a prévia e a saída após transicionar (se a a cena original de saída ainda exisitr).\nIsto não irá desfazer nenhuma mudança que foi feita na cena original da saída." QuickTransitions.DuplicateScene="Duplicar Cena" QuickTransitions.DuplicateSceneTT="Quando estiver editando a mesma cena, permite editar a visibilidade/transformação de fontes sem modificar a saída.\nPara editar as propriedades das fontes sem modificar a saída, habilite 'Fontes Duplicadas'.\nMudar este valor irá resetar a cena atual de saída (se ainda existir)." QuickTransitions.EditProperties="Duplicar Fontes" @@ -200,14 +234,17 @@ NameExists.Text="O Nome já está em uso." NoNameEntered.Title="Por favor, insira um nome válido" NoNameEntered.Text="Você não pode usar nomes vazios." -ConfirmStart.Title="Iniciar Transmissão?" -ConfirmStart.Text="Tens certeza de que queres iniciar a transmissão?" +ConfirmStart.Title="Iniciar transmissão?" +ConfirmStart.Text="Deseja mesmo iniciar a transmissão?" -ConfirmStop.Title="Parar Transmissão?" -ConfirmStop.Text="Tens certeza de que queres parar a transmissão?" +ConfirmStop.Title="Interromper transmissão?" +ConfirmStop.Text="Deseja mesmo interromper a transmissão?" + +ConfirmBWTest.Title="Iniciar teste de largura de banda?" +ConfirmBWTest.Text="Você com o OBS configurado no modo de teste de largura de banda. Este modo permite o teste de rede sem que o seu canal entre em funcionamento. Uma vez terminado o teste, você precisará desativá-lo para que os espectadores possam ver sua transmissão.\n\nVocê quer continuar?" ConfirmExit.Title="Sair do OBS?" -ConfirmExit.Text="OBS está ativo no momento. Todos as streams/gravações serão encerradas. Tem certeza que deseja sair?" +ConfirmExit.Text="OBS está ativo no momento. Todos as streams/gravações serão encerradas. Tem certeza que deseja sair?" ConfirmRemove.Title="Confirmar a Remoção" ConfirmRemove.Text="Tem certeza que deseja remover '$1'?" @@ -216,53 +253,56 @@ ConfirmRemove.TextMultiple="Você tem certeza que quer remover esses %1 itens?" Output.StartStreamFailed="Falha ao iniciar a transmissão" Output.StartRecordingFailed="Falha ao iniciar a gravação" Output.StartReplayFailed="Falha ao iniciar o buffer de repetição" -Output.StartFailedGeneric="Falha ao iniciar a saída. Favor verificar o log para informação detalhada do erro.\n\nAviso: Se estiver usando os codificadores NVENC ou AMD, tenha certeza de que seus drivers estão atualizados." +Output.StartFailedGeneric="Impossível criar o arquivo de saída. Verifique o registro para mais detalhes do erro.\n\nAviso: se estiver utilizando os codificadores NVENC ou AMD, certifique-se de que os seus drivers estão atualizados." + Output.ConnectFail.Title="Falha ao conectar" Output.ConnectFail.BadPath="Caminho ou URL inválida. Por favor, verifique suas configurações para confirmar que estão válidas." Output.ConnectFail.ConnectFailed="Falha ao conectar com o Servidor" -Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou a chave de transmissão, por favor, verifique sua chave de transimissão. Se estiver correta, pode haver um problema em conectar ao servidor." -Output.ConnectFail.Error="Um erro inesperado ocorreu ao tentar se conectar com o servidor. Veja o arquivo de Log para mais informações." +Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou a chave de transmissão, verifique a sua chave de transmissão. Se estiver correta, pode haver um problema de conexão com o servidor." +Output.ConnectFail.Error="Ocorreu um erro inesperado ao tentar conectar-se ao servidor. Verifique o arquivo de registro para mais informações." Output.ConnectFail.Disconnected="Desconectado do Servidor." +Output.StreamEncodeError.Title="Erro de codificação" +Output.StreamEncodeError.Msg="Ocorreu um erro de codificação durante a transmissão." + Output.RecordFail.Title="Falha ao iniciar a gravação" Output.RecordFail.Unsupported="O formato de saída ou não é compatível ou não suporta mais do que uma faixa de áudio. Por favor, verifique suas configurações e tente novamente." Output.RecordNoSpace.Title="Espaço em disco insuficiente" Output.RecordNoSpace.Msg="Não há espaço em disco suficiente para continuar a gravação." Output.RecordError.Title="Erro de gravação" Output.RecordError.Msg="Ocorreu um erro não especificado durante a gravação." -Output.ReplayBuffer.NoHotkey.Title="Tecla de Atalho não configurada!" +Output.RecordError.EncodeErrorMsg="Ocorreu um erro de codificação durante a gravação." +Output.ReplayBuffer.NoHotkey.Title="Nenhuma atalho adicionado!" Output.ReplayBuffer.NoHotkey.Msg="Tecla de Atalho para salvar o Buffer do replay não definida. Por favor, configure uma tecla de atalho para salvar gravações de replays." Output.BadPath.Title="Caminho de Arquivo Inválido" Output.BadPath.Text="O caminho do arquivo de saída é inválido. Por Favor, certifique-se de que um caminho válido foi informado." -LogReturnDialog="Log Enviado com Sucesso" +LogReturnDialog="Carregamento do arquivo de registro efetuado com êxito" LogReturnDialog.CopyURL="Copiar URL" -LogReturnDialog.ErrorUploadingLog="Erro ao enviar Log" +LogReturnDialog.ErrorUploadingLog="Erro no carregamento do arquivo de registro" -LicenseAgreement="Termos e Condições da Licença" -LicenseAgreement.PleaseReview="Por favor, reveja os termos de licença antes de usar o OBS. Usando este programa, você reconhece que leu e aceita os termos da GNU General Public License v 2.0. Por favor, role para baixo para ver o resto do acordo." -LicenseAgreement.ClickIAgreeToContinue="Se você aceitar os termos do acordo, clique em Aceito para continuar. Você deve aceitar o acordo para usar o OBS." -LicenseAgreement.IAgree="Eu Concordo" -LicenseAgreement.Exit="Sair" - -Remux.SourceFile="OBS Gravando" +Remux.SourceFile="Gravação do OBS" Remux.TargetFile="Arquivo de destino" -Remux.Remux="Remux" +Remux.Remux="Converter" +Remux.Stop="Interromper conversão" +Remux.ClearFinished="Remover elementos concluídos" +Remux.ClearAll="Remover todos os elementos" Remux.OBSRecording="Gravação do OBS" -Remux.FinishedTitle="Remux finalizado" -Remux.Finished="Remux da gravação finalizado" -Remux.FinishedError="Remux da gravação finalizado, mas o arquivo pode estar incompleto" -Remux.SelectRecording="Selecione a gravação do OBS…" -Remux.SelectTarget="Selecione o arquivo…" +Remux.FinishedTitle="Conversão finalizada" +Remux.Finished="Gravação convertida" +Remux.FinishedError="Gravação convertida, mas o arquivo pode estar incompleto" +Remux.SelectRecording="Selecione uma gravação do OBS..." +Remux.SelectTarget="Selecione o arquivo de destino..." Remux.FileExistsTitle="O arquivo de destino já existe" -Remux.FileExists="O arquivo de destino já existe, deseja substitui-lo?" -Remux.ExitUnfinishedTitle="Remux em progresso" -Remux.ExitUnfinished="Remux não foi completado, parar agora pode fazer o arquivo de destino não utilizável.\nTem certeza que deseja parar agora?" +Remux.FileExists="Os seguintes arquivos já existem. Você deseja substituí-los?" +Remux.ExitUnfinishedTitle="Conversão em curso" +Remux.ExitUnfinished="Conversão não concluída, parar agora pode tornar o arquivo de destino inutilizável.\nTem certeza que deseja parar a conversão?" +Remux.HelpText="Solte arquivos nesta janela para converter ou selecione uma célula \"Gravação do OBS\" para buscar um arquivo." UpdateAvailable="Nova Atualização Disponível" -UpdateAvailable.Text="Versão %1. %2. %3 está agora disponível. clique aqui para baixar" +UpdateAvailable.Text="Versão %1. %2. %3 está agora disponível. clique aqui para baixar" Basic.DesktopDevice1="Desktop Áudio" Basic.DesktopDevice2="Desktop Áudio 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Captura de tela" Basic.Main.PreviewConextMenu.Enable="Ativar pré-vizualização" +Basic.Main.Preview.Disable="Desativar pré-visualização" + ScaleFiltering="Filtragem de escala" ScaleFiltering.Point="Ponto" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicúbico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" Deinterlacing="Desentrelaçamento" Deinterlacing.Discard="Descartar" @@ -318,7 +361,7 @@ Basic.Main.MixerRename.Title="Renomear Fonte de Áudio" Basic.Main.MixerRename.Text="Por favor, digite o nome da fonte de áudio" -Basic.Main.PreviewDisabled="A pré-visualização esta desativada" +Basic.Main.PreviewDisabled="A prévia está desativada" Basic.SourceSelect="Criar/Selecionar Fonte" Basic.SourceSelect.CreateNew="Criar Nova" @@ -362,7 +405,7 @@ Basic.Filters.Title="Filtros para '%1'" Basic.Filters.AddFilter.Title="Nome do filtro" Basic.Filters.AddFilter.Text="Por favor, especifique o nome do filtro" -Basic.TransformWindow="Transformação de Elemento da Cena" +Basic.TransformWindow="Transformação de elemento da cena" Basic.TransformWindow.Position="Posição" Basic.TransformWindow.Rotation="Rotação" Basic.TransformWindow.Size="Tamanho" @@ -399,70 +442,72 @@ Basic.Main.Controls="Controles" Basic.Main.Connecting="Conectando..." Basic.Main.StartRecording="Iniciar gravação" Basic.Main.StartReplayBuffer="Iniciar Buffer do Replay" -Basic.Main.StartStreaming="Iniciar Transmissão" +Basic.Main.StartStreaming="Iniciar transmissão" Basic.Main.StopRecording="Parar Gravação" Basic.Main.StoppingRecording="Parando de Gravar..." Basic.Main.StopReplayBuffer="Parar Buffer do Replay" Basic.Main.StoppingReplayBuffer="Parando Buffer do Replay..." -Basic.Main.StopStreaming="Parar Transmissão" -Basic.Main.StoppingStreaming="Parando Transmissão..." +Basic.Main.StopStreaming="Interromper transmissão" +Basic.Main.StoppingStreaming="Interrompendo a transmissão..." Basic.Main.ForceStopStreaming="Pare de transmitir (descartar atraso)" Basic.Main.Group="Grupo %1" Basic.Main.GroupItems="Agrupar Itens Selecionados" Basic.Main.Ungroup="Desagrupar" -Basic.MainMenu.File="&Arquivo" +Basic.MainMenu.File="Arquivo (&F)" Basic.MainMenu.File.Export="&Exportar" Basic.MainMenu.File.Import="&Importar" -Basic.MainMenu.File.ShowRecordings="Mostrar &Gravações" -Basic.MainMenu.File.Remux="Trocar Container (&M)" -Basic.MainMenu.File.Settings="&Configurações" +Basic.MainMenu.File.ShowRecordings="Most&rar Gravações" +Basic.MainMenu.File.Remux="Converter gravações (&M)" +Basic.MainMenu.File.Settings="Configuraçõe&s" Basic.MainMenu.File.ShowSettingsFolder="Mostrar pasta de configurações" Basic.MainMenu.File.ShowProfileFolder="Mostrar pasta de perfil" -Basic.MainMenu.AlwaysOnTop="&Sempre no Topo" -Basic.MainMenu.File.Exit="&Sair" +Basic.MainMenu.AlwaysOnTop="Sempre no Topo (&A)" +Basic.MainMenu.File.Exit="Sair (&X)" Basic.MainMenu.Edit="&Editar" -Basic.MainMenu.Edit.Undo="&Desfazer" +Basic.MainMenu.Edit.Undo="Desfazer (&U)" Basic.MainMenu.Edit.Redo="&Refazer" -Basic.MainMenu.Edit.UndoAction="&Desfazer $1" +Basic.MainMenu.Edit.UndoAction="Desfazer $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Refazer $1" -Basic.MainMenu.Edit.LockPreview="&Bloquear pré-visualização" -Basic.MainMenu.Edit.Scale="Visualização e dimensionamento" +Basic.MainMenu.Edit.LockPreview="B&loquear Prévia" +Basic.MainMenu.Edit.Scale="Vi&sualização e dimensionamento" Basic.MainMenu.Edit.Scale.Window="Escala para janela" Basic.MainMenu.Edit.Scale.Canvas="Lona (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Saída (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformar" Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformação..." Basic.MainMenu.Edit.Transform.CopyTransform="Copiar Transformação" -Basic.MainMenu.Edit.Transform.PasteTransform="Colar Transformação" -Basic.MainMenu.Edit.Transform.ResetTransform="&Limpar Transformação" +Basic.MainMenu.Edit.Transform.PasteTransform="Colar e transformar" +Basic.MainMenu.Edit.Transform.ResetTransform="Limpa&r Transformação" Basic.MainMenu.Edit.Transform.Rotate90CW="Girar 90º sentido Horário" Basic.MainMenu.Edit.Transform.Rotate90CCW="Girar 90º sentido Anti-Horário" Basic.MainMenu.Edit.Transform.Rotate180="Girar 180º" Basic.MainMenu.Edit.Transform.FlipHorizontal="Inverter &Horizontalmente" Basic.MainMenu.Edit.Transform.FlipVertical="Inverter &Verticalmente" -Basic.MainMenu.Edit.Transform.FitToScreen="Ajustar à Tela" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Estender à Tela" +Basic.MainMenu.Edit.Transform.FitToScreen="Ajustar à Tela (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="E&stender à Tela" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centralizar à Tela" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centralizar Verticalmente" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centralizar Horizontalmente" Basic.MainMenu.Edit.Order="&Ordem" -Basic.MainMenu.Edit.Order.MoveUp="Mover para &Cima" -Basic.MainMenu.Edit.Order.MoveDown="Mover para &Baixo" +Basic.MainMenu.Edit.Order.MoveUp="Mover para Cima (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Mover para Baixo (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Mover para o &Topo" Basic.MainMenu.Edit.Order.MoveToBottom="Mover para a &Base" -Basic.MainMenu.Edit.AdvAudio="&Propriedades de áudio avançadas" +Basic.MainMenu.Edit.AdvAudio="Propried&ades de áudio avançadas" -Basic.MainMenu.View="Mostrar" -Basic.MainMenu.View.Toolbars="&Barras de Ferramentas" +Basic.MainMenu.View="Mostrar (&V)" +Basic.MainMenu.View.Toolbars="Barras de Ferramen&tas" Basic.MainMenu.View.Docks="Ancorar" Basic.MainMenu.View.Docks.ResetUI="Redefinir IU" Basic.MainMenu.View.Docks.LockUI="Travar IU" Basic.MainMenu.View.Toolbars.Listboxes="Caixa de &Listagem" -Basic.MainMenu.View.SceneTransitions="Transições de Cena" -Basic.MainMenu.View.StatusBar="Barra de Status" +Basic.MainMenu.View.SceneTransitions="Transições de &Cena" +Basic.MainMenu.View.StatusBar="Barra de &Status" Basic.MainMenu.View.Fullscreen.Interface="Interface em Tela Cheia" -Basic.MainMenu.SceneCollection="&Coleção de cena" +Basic.MainMenu.SceneCollection="Coleção de cena (&S)" Basic.MainMenu.Profile="&Perfil" Basic.MainMenu.Profile.Import="Importar Perfil" Basic.MainMenu.Profile.Export="Exportar Perfil" @@ -473,23 +518,24 @@ Basic.MainMenu.SceneCollection.Exists="O Grupo de Cenas já existe" Basic.MainMenu.Tools="Ferramentas (&T)" -Basic.MainMenu.Help="&Ajuda" +Basic.MainMenu.Help="Ajuda (&H)" Basic.MainMenu.Help.HelpPortal="&Portal de Ajuda" Basic.MainMenu.Help.Website="Visitar &website" Basic.MainMenu.Help.Discord="Juntar-se ao Servidor do &Discord" -Basic.MainMenu.Help.Logs="&Arquivos de Log" -Basic.MainMenu.Help.Logs.ShowLogs="&Mostrar Arquivos de Log" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Enviar &Arquivo de Log Atual" -Basic.MainMenu.Help.Logs.UploadLastLog="Enviar &Ultimo Arquivo de Log" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Exibir Log atual" +Basic.MainMenu.Help.Logs="Arquivos de registro (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Mo&strar arquivos de registro" +Basic.MainMenu.Help.Logs.UploadCurrentLog="&Carregar arquivo de registro atual" +Basic.MainMenu.Help.Logs.UploadLastLog="Carregar ú<imo arquivo de registro" +Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver arquivo de registro atual" Basic.MainMenu.Help.CheckForUpdates="Verificar se há atualizações" Basic.MainMenu.Help.CrashLogs="&Relatórios de erros" -Basic.MainMenu.Help.CrashLogs.ShowLogs="Exibir relatórios de erro&s" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Enviar ú<imo relatório de erros" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Mo&strar relatórios de erros" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Carregar ú<imo relatório de erros" +Basic.MainMenu.Help.About="Sobre (&A)" Basic.Settings.ProgramRestart="O Programa precisar ser reiniciado para que estas configurações surtam efeito." Basic.Settings.ConfirmTitle="Confirmar Alterações" -Basic.Settings.Confirm="Você tem alterações não salvas. Salvar as alterações?" +Basic.Settings.Confirm="Você tem alterações não salvas. Salvar as alterações?" Basic.Settings.General="Geral" Basic.Settings.General.Theme="Tema" @@ -514,21 +560,30 @@ Basic.Settings.General.SysTray="Bandeja do sistema" Basic.Settings.General.SysTrayWhenStarted="Minimizar para a bandeja do sistema quando iniciar" Basic.Settings.General.SystemTrayHideMinimize="Sempre minimizar para a bandeja (ignorar barra de tarefas)" Basic.Settings.General.SaveProjectors="Salvar projetores ao sair" +Basic.Settings.General.Preview="Prévia" +Basic.Settings.General.OverflowHidden="Esconder excesso" +Basic.Settings.General.OverflowAlwaysVisible="Excesso sempre visível" +Basic.Settings.General.OverflowSelectionHidden="Mostrar excesso mesmo quando a fonte estiver escondida" Basic.Settings.General.SwitchOnDoubleClick="Mudar para a cena quando clicar duas vezes" -Basic.Settings.General.StudioPortraitLayout="Ativar o layout Paisagem/Retrato" -Basic.Settings.General.Multiview="Multiview" +Basic.Settings.General.StudioPortraitLayout="Ativar a disposição horizontal/vertical" +Basic.Settings.General.TogglePreviewProgramLabels="Mostrar rótulos de prévia/programa" +Basic.Settings.General.Multiview="Visualização múltipla" Basic.Settings.General.Multiview.MouseSwitch="Clique para alternar entre cenas" Basic.Settings.General.Multiview.DrawSourceNames="Mostrar nome das cenas" Basic.Settings.General.Multiview.DrawSafeAreas="Mostrar áreas de segurança (EBU R 95)" -Basic.Settings.General.MultiviewLayout="Layout do Multiview" -Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, Acima (8 Cenas)" -Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, Abaixo (8 Cenas)" -Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, à Esquerda (8 Cenas)" -Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, à Direita (8 Cenas)" -Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, Acima (24 Cenas)" +Basic.Settings.General.MultiviewLayout="Disposição da visualização múltipla" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, acima (8 cenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, abaixo (8 cenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, à esquerda (8 cenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, à direita (8 cenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, acima (24 cenas)" -Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Tipo de Stream" +Basic.Settings.Stream="Transmissão" +Basic.Settings.Stream.StreamType="Tipo de transmissão" +Basic.Settings.Stream.Custom.UseAuthentication="Utilizar autenticação" +Basic.Settings.Stream.Custom.Username="Nome de usuário" +Basic.Settings.Stream.Custom.Password="Senha" +Basic.Settings.Stream.BandwidthTestMode="Ativar modo de teste de largura de banda" Basic.Settings.Output="Saída" Basic.Settings.Output.Format="Formato de gravação" @@ -550,17 +605,16 @@ Basic.Settings.Output.ReplayBuffer.Prefix="Prefixo do Buffer de Repetição" Basic.Settings.Output.ReplayBuffer.Suffix="Sufixo" Basic.Settings.Output.Simple.SavePath="Caminho de gravação" Basic.Settings.Output.Simple.RecordingQuality="Qualidade da gravação" -Basic.Settings.Output.Simple.RecordingQuality.Stream="Mesmo que a stream" +Basic.Settings.Output.Simple.RecordingQuality.Stream="A mesma da transmissão" Basic.Settings.Output.Simple.RecordingQuality.Small="Alta qualidade, tamanho médio" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualidade indistinguível, Tamanho grande" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Qualidade Lossless, tremendamente grande" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Aviso: O bitrate de vídeo da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Aviso: O bitrate de áudio da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Aviso: O bitrate de vídeo da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Aviso: O bitrate de áudio da transmissão será definido para %1, que é o limite superior para o serviço de transmissão atual. Se você tem certeza que quer ir acima de %1, habilite opções de codificação avançadas e desmarque \"Impor limites de bitrate do serviço de transmissão\"." Basic.Settings.Output.Simple.Warn.Encoder="Aviso: Gravar com um codificador de software em uma qualidade diferente do que a stream vai exigir mais da CPU se você transmitir e gravar ao mesmo tempo." -Basic.Settings.Output.Simple.Warn.Lossless="Aviso: Qualidade Lossless gera arquivos muito grandes! A qualidade Lossless pode usar mais de 7 gigabytes de espaço em disco por minuto em altas resoluções e framerates. Lossless não é recomendada para gravações longas, a menos que se tenha uma grande quantidade de espaço em disco disponível." +Basic.Settings.Output.Simple.Warn.Lossless="Aviso: Qualidade Lossless gera arquivos muito grandes! A qualidade Lossless pode usar mais de 7 gigabytes de espaço em disco por minuto em altas resoluções e framerates. Lossless não é recomendada para gravações longas, a menos que se tenha uma grande quantidade de espaço em disco disponível." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Tem certeza que deseja usar qualidade lossless?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Aviso de qualidade lossless!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Aviso: Você não pode usar vários codificadores QSV separados quando estiver transmitindo e gravando ao mesmo tempo. Se você deseja transmitir e gravar ao mesmo tempo, por favor altere o codificador de gravação ou o de transmissão." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Reconectar automaticamente" Basic.Settings.Output.RetryDelay="Espera para reconectar-se (segundos)" Basic.Settings.Output.MaxRetries="Número Máximo de Tentativas" Basic.Settings.Output.Advanced="Ativar as configurações avançadas do encoder" -Basic.Settings.Output.EncoderPreset="Predefinição de codificação (maior = menor uso de CPU)" +Basic.Settings.Output.EncoderPreset="Padrão de Codificação" Basic.Settings.Output.CustomEncoderSettings="Configurações de codificador personalizadas" Basic.Settings.Output.CustomMuxerSettings="Configurações personalizadas do Muxer" Basic.Settings.Output.NoSpaceFileName="Gerar Nome de Arquivo sem Espaços" @@ -622,20 +676,20 @@ FilenameFormatting.completer="%CCYY-% MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%s FilenameFormatting.TT="%CCYY Ano, quatro dígitos\n%YY Ano, dois dígitos (00-99)\n%MM Mês como um número decimal (01-12)\n%DD Dia do mês, começando com 0 (01-31)\n%hh Hora, em formato de 24h (00-23)\n%mm Minuto (00-59)\n%ss Segundo (00-61)\n%% A % sign\n%a Dia da Semana abreviado\n%A Nome da Semana completo\n%b Nome do Mês abreviado\n%B Nome do Mês completo\n%d Dia do Mês, começando com 0 (01-31)\n%H Hora, no formato de 24h (00-23)\n%I Hora no formato de 12h (01-12)\n%m Mês como um número decimal (01-12)\n%M Minuto (00-59)\n%p Designação AM ou PM\n%S Segundo (00-61)\n%y Ano, últimos dois dígitos (00-99)\n%Y Ano\n%z ISO 8601 diferença de fuso horário ou de UTC\n nome ou abreviação\n%Z Nome do Fuso Horário ou abreviação\n" Basic.Settings.Video="Vídeo" -Basic.Settings.Video.Adapter="Adaptador de Vídeo:" -Basic.Settings.Video.BaseResolution="Resolução de base (tela):" -Basic.Settings.Video.ScaledResolution="Resolução de saída (escala):" -Basic.Settings.Video.DownscaleFilter="Filtro de Redução:" +Basic.Settings.Video.Adapter="Adaptador de Vídeo" +Basic.Settings.Video.BaseResolution="Resolução de base (tela)" +Basic.Settings.Video.ScaledResolution="Resolução de saída (escala)" +Basic.Settings.Video.DownscaleFilter="Filtro de Redução" Basic.Settings.Video.DisableAeroWindows="Desativar o Aero (somente Windows)" -Basic.Settings.Video.FPS="FPS:" +Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valor de FPS Comum" Basic.Settings.Video.FPSInteger="Valor de FPS Íntegro" Basic.Settings.Video.FPSFraction="Valor de FPS Fracional" -Basic.Settings.Video.Numerator="Numerador:" -Basic.Settings.Video.Denominator="Demoninador:" -Basic.Settings.Video.Renderer="Renderizador:" +Basic.Settings.Video.Numerator="Numerador" +Basic.Settings.Video.Denominator="Demoninador" +Basic.Settings.Video.Renderer="Renderizador" Basic.Settings.Video.InvalidResolution="Resolução Inválida, Obrigatório ser [largura]x[altura] (ex. 1920x1080)" -Basic.Settings.Video.CurrentlyActive="A saída de vídeo está atualmente ativa. Por favor, desligue quaisquer saídas para alterar as configurações de vídeo." +Basic.Settings.Video.CurrentlyActive="A saída de vídeo está atualmente ativa. Por favor, desligue quaisquer saídas para alterar as configurações de vídeo." Basic.Settings.Video.DisableAero="Desativar Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear(rápido, mas embaçado se redimensionando)" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 32 a Basic.Settings.Audio="Áudio" Basic.Settings.Audio.SampleRate="Taxa de Amostragem" Basic.Settings.Audio.Channels="Canais" -Basic.Settings.Audio.MeterDecayRate="Taxa de Decaimento do Medidor de Áudio" +Basic.Settings.Audio.Meters="Metros" +Basic.Settings.Audio.MeterDecayRate="Taxa de decaimento" Basic.Settings.Audio.MeterDecayRate.Fast="Rápida" Basic.Settings.Audio.MeterDecayRate.Medium="Média (PPM Tipo I)" Basic.Settings.Audio.MeterDecayRate.Slow="Devagar (PPM Tipo II)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="AVISO: Áudio Surround está h Basic.Settings.Audio.MultichannelWarning="Antes de transmitir, verifique se o seu serviço de transmissão suporta tanto receber como reproduzir som surround. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o som surround é totalmente suportado. Embora o Facebook Live e o YouTube Live ambos aceitem receber som surround, o Facebook Live transformará para estéreo e o YouTube Live reproduz apenas dois canais.\n\nOs filtros de áudio do OBS são compatíveis com o som surround, embora o suporte do plugin VST não seja garantido." Basic.Settings.Audio.MultichannelWarning.Title="Ativar o som surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Você tem certeza de que deseja habilitar o som surround?" -Basic.Settings.Audio.DesktopDevice="Dispositivo de áudio do desktop" -Basic.Settings.Audio.DesktopDevice2="Dispositivo de áudio do desktop 2" -Basic.Settings.Audio.AuxDevice="Dispositivo de áudio/microfone auxiliar" +Basic.Settings.Audio.Devices="Dispositivos" +Basic.Settings.Audio.DesktopDevice="Áudio da Área de Trabalho" +Basic.Settings.Audio.DesktopDevice2="Áudio da Área de Trabalho 2" +Basic.Settings.Audio.AuxDevice="Dispositivo de Áudio Mic/Auxiliar" Basic.Settings.Audio.AuxDevice2="Dispositivo de áudio/microfone auxiliar 2" Basic.Settings.Audio.AuxDevice3="Dispositivo de áudio/microfone auxiliar 3" +Basic.Settings.Audio.AuxDevice4="Dispositivo de áudio/microfone auxiliar 4" Basic.Settings.Audio.EnablePushToMute="Ativar pressionar-para-mutar" Basic.Settings.Audio.PushToMuteDelay="Delay do Pressionar-para-mutar" Basic.Settings.Audio.EnablePushToTalk="Ativar pressionar-para-falar" Basic.Settings.Audio.PushToTalkDelay="Delay do pressionar-para-falar" Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo nao conectado ou não disponível]" +Basic.Settings.Audio.Disabled="Desativado" Basic.Settings.Advanced="Avançado" Basic.Settings.Advanced.General.ProcessPriority="Prioridade do Processo" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inativa" Basic.Settings.Advanced.FormatWarning="Aviso: Formatos de cor diferentes do NV12 destinam-se principalmente para gravação e não são recomendados para transmissão. Durante a transmissão pode ocorrer aumento do uso da CPU devido a conversão do formato de cor." Basic.Settings.Advanced.Audio.BufferingTime="Tempo de buffer de áudio" Basic.Settings.Advanced.Video.ColorFormat="Formato de cor" -Basic.Settings.Advanced.Video.ColorSpace="Espaço de cor YUV" -Basic.Settings.Advanced.Video.ColorRange="Gama de cores YUV" +Basic.Settings.Advanced.Video.ColorSpace="Espaço de cor" +Basic.Settings.Advanced.Video.ColorRange="Faixa de cores" Basic.Settings.Advanced.Video.ColorRange.Partial="Limitado" Basic.Settings.Advanced.Video.ColorRange.Full="Completo" -Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de Monitoramento de Áudio" +Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitoramento" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Padrão" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desativar a Oscilação de Áudio do Windows" Basic.Settings.Advanced.StreamDelay="Atraso da transmissão" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Transmitir pelo IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Habilitar o novo código de rede" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baixa latência" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Desativar teclas de atalho quando a janela principal estiver em foco" +Basic.Settings.Advanced.AutoRemux="Converter automaticamente para mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(gravar como mkv)" Basic.AdvAudio="Propriedades de áudio avançadas" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Volume="Volume (%)" +Basic.AdvAudio.Volume="Volume" Basic.AdvAudio.Mono="Downmix para Mono" -Basic.AdvAudio.Panning="Balanceamento" +Basic.AdvAudio.Balance="Balanço" Basic.AdvAudio.SyncOffset="Atraso de sincronização (ms)" Basic.AdvAudio.Monitoring="Monitoramento de Áudio" Basic.AdvAudio.Monitoring.None="Não monitorar" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Faixas" Basic.Settings.Hotkeys="Teclas de atalho" Basic.Settings.Hotkeys.Pair="Combinações de teclas compartilhadas com '%1' agem como alternaçoes" +Basic.Settings.Hotkeys.Filter="Filtro" Basic.Hotkeys.SelectScene="Mudar de cena" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="/ (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Mouse %1" +Hotkeys.Escape="Esc" Mute="Mudo" Unmute="Desmutar" @@ -762,7 +824,7 @@ SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Você deve selecionar pelo menos uma faixa" OutputWarnings.MultiTrackRecording="Aviso: Alguns formatos (como FLV) não suportam várias faixas por gravação" -OutputWarnings.MP4Recording="Atenção: Gravações salvas em arquivos MP4 se tornarão irrecuperáveis se o arquivo não puder ser finalizado (ex: tela azul, queda de energia, etc.). Caso queira gravar várias faixas de áudio, considere usar MKV e usar a ferramenta de remux no arquivo resultante da gravação (Arquivo->Remux gravações)" +OutputWarnings.MP4Recording="Atenção: as gravações salvas em MP4/MOV não serão recuperáveis se o arquivo não puder ser concluído (por exemplo, como resultado de um BSOD, perdas de energia, etc.). Se você quiser gravar várias faixas de áudio, aconselhamos utilizar o MKV e, uma vez terminado, converter a gravação para MP4/MOV (Arquivo → Converter gravações)" FinalScene.Title="Excluir cena" FinalScene.Text="É preciso haver pelo menos uma cena." @@ -770,9 +832,24 @@ FinalScene.Text="É preciso haver pelo menos uma cena." NoSources.Title="Sem Fontes" NoSources.Text="Parece que você ainda não adicionou nenhuma fonte de vídeo, portanto, você só exibirá uma tela em branco. Você tem certeza de que quer fazer isso?" NoSources.Text.AddSource="Você pode adicionar fontes clicando no ícone + sob a caixa de Fontes na janela principal, a qualquer momento." +NoSources.Label="Você não tem nenhuma fonte.\nClique no botão + abaixo,\nou clique direito aqui para adicionar uma." ChangeBG="Definir Cor" -CustomColor="Cor Personalizada" +CustomColor="Cor personalizada" BrowserSource.EnableHardwareAcceleration="Habilitar a aceleração por Hardware do Navegador" +About="Sobre" +About.Info="OBS Studio é um software livre e open source para gravação transmissão ao vivo." +About.Donate="Faça uma Contribuição" +About.GetInvolved="Participe" +About.Authors="Autores" +About.License="Licença" +About.Contribute="Apoie o Projeto OBS" + +ResizeOutputSizeOfSource="Redimensionar saída (tamanho da fonte)" +ResizeOutputSizeOfSource.Text="As resoluções base e de saída serão redimensionadas para o tamanho da fonte atual." +ResizeOutputSizeOfSource.Continue="Você quer continuar?" + +PreviewTransition="Prévia da Transição" + diff --git a/UI/data/locale/pt-PT.ini b/UI/data/locale/pt-PT.ini index 5c6cd0e..2386f3c 100644 --- a/UI/data/locale/pt-PT.ini +++ b/UI/data/locale/pt-PT.ini @@ -49,7 +49,7 @@ Duplicate="Duplicar" Enable="Ativar" DisableOSXVSync="Desabilitar o OSX V-Sync" ResetOSXVSyncOnExit="Redefinir o OSX V-Sync na saída" -HighResourceUsage="Codificação sobrecarregado! Considere diminuir a configurações de vídeo ou usar uma predefinição mais rápido de codificação." +HighResourceUsage="Codificação sobrecarregado! Considere diminuir a configurações de vídeo ou usar uma predefinição mais rápido de codificação." Transition="Transição" QuickTransitions="Transições rápidas" Left="Esquerda" @@ -77,14 +77,39 @@ TransitionOverride="Substituir Transição" None="Nenhum" StudioMode.Preview="Pré-visualização" StudioMode.Program="Programa" +ShowInMultiview="Mostrar no Multiview" +VerticalLayout="Vista Vertical" +Group="Grupo" +DoNotShowAgain="Não mostrar novamente" AlreadyRunning.Title="O OBS já está em execução" AlreadyRunning.Text="O OBS já está em execução! Tem de desligar a instância existente do OBS antes de iniciar uma nova. Se o OBS estiver definido para correr na bandeja do sistema, por favor verifique se está aberto lá." AlreadyRunning.LaunchAnyway="Executar de qualquer modo" +DockCloseWarning.Title="Janela Fechar dockável" +DockCloseWarning.Text="Acabaste de fechar uma janela acoplável. Se você quiser mostrá-la novamente, use o menu Exibir → Docks na barra de menus." + +Auth.Authing.Title="Autenticação..." +Auth.Authing.Text="Autenticando com %1, por favor espere..." +Auth.AuthFailure.Title="Falha na autenticação" +Auth.AuthFailure.Text="Falha na autenticação com %1:\n\n%2: %3" +Auth.InvalidScope.Title="Autenticação Necessária" +Auth.InvalidScope.Text="Os requisitos de autenticação para %1 mudaram. Algumas funcionalidades podem não estar disponíveis." +Auth.LoadingChannel.Title="Carregando informação do canal..." +Auth.LoadingChannel.Text="A carregar informação do canal para %1, por favor espere..." +Auth.ChannelFailure.Title="Erro ao carregar canal" +Auth.ChannelFailure.Text="Erro ao carregar informaões do canal do %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informação da Transmissão" +TwitchAuth.Stats="Estatísticas da Twitch" +TwitchAuth.Feed="Alimentação de atividade de Twitch" + Copy.Filters="Copiar filtros" Paste.Filters="Colar Filtros" +BrowserPanelInit.Title="Inicializando o Browser..." +BrowserPanelInit.Text="Inicializando o navegador, por favor espere..." + BandwidthTest.Region="Região" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" @@ -92,11 +117,9 @@ BandwidthTest.Region.Asia="Ásia" BandwidthTest.Region.Other="Outro" Basic.FirstStartup.RunWizard="Gostaria de executar o assistente de configuração automática? Pode também definir as suas configurações na janela principal." -Basic.FirstStartup.RunWizard.BetaWarning="(Nota: O assistente de configuração automática está atualmente em beta)" Basic.FirstStartup.RunWizard.NoClicked="Se muder de ideias pode correr o assistente de configuração automática a qualquer momento no menu Ferramentas." Basic.AutoConfig="Assistente de Configuração Automática" -Basic.AutoConfig.Beta="Assistente de Configuração Automática (Beta)" Basic.AutoConfig.ApplySettings="Aplicar definições" Basic.AutoConfig.StartPage="Informação de utilização" Basic.AutoConfig.StartPage.SubTitle="Especifique qual vai ser a utilização do programa" @@ -112,8 +135,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ou 30, com prioridade a alta re Basic.AutoConfig.VideoPage.CanvasExplanation="Nota: A resolução base do canvas não é necessariamente a mesma que resolução da gravação ou stream. A resolução da gravação/stream pode ser reduzida para diminuir o uso de recursos e os requisitos de bitrate." Basic.AutoConfig.StreamPage="Informação de Transmissão" Basic.AutoConfig.StreamPage.SubTitle="Por favor introduza a informação necessária" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectar Conta (opcional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Desconectar Conta" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Desconectar Conta?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Esta alteração será aplicada imediatamente. De certeza que queres desconectar a tua conta?" +Basic.AutoConfig.StreamPage.UseStreamKey="Usar Chave de Stream" Basic.AutoConfig.StreamPage.Service="Serviço" Basic.AutoConfig.StreamPage.Service.ShowAll="Mostrar Tudo..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizado..." Basic.AutoConfig.StreamPage.Server="Servidor" Basic.AutoConfig.StreamPage.StreamKey="Chave de Transmissão" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" @@ -141,7 +170,7 @@ Basic.AutoConfig.TestPage.Result.Footer="Para utilizar estas definições, carre Basic.Stats="Estados" Basic.Stats.CPUUsage="Utilização de CPU" -Basic.Stats.HDDSpaceAvailable="Espaço disponível no HDD" +Basic.Stats.HDDSpaceAvailable="Espaço em disco disponível" Basic.Stats.MemoryUsage="Utilização de Memória" Basic.Stats.AverageTimeToRender="Tempo médio para processar uma frame" Basic.Stats.SkippedFrames="Frames saltadas devido ao lag do codificador" @@ -157,6 +186,9 @@ Basic.Stats.DroppedFrames="Frames perdidas (Rede)" Basic.Stats.MegabytesSent="Total saída de dados" Basic.Stats.Bitrate="Taxa de Bits" +ResetUIWarning.Title="De certeza que queres reiniciar a interface?" +ResetUIWarning.Text="Reiniciar a interface irá esconder docks adicionais. Vais ter de as ativar outra vez a partir no menu ver se quiseres torná-las visíveis.\n\nDe certeza que queres reiniciar a interface?" + Updater.Title="Nova atualização disponível" Updater.Text="Existe uma nova atualização disponível:" Updater.UpdateNow="Atualizar Agora" @@ -171,8 +203,10 @@ Updater.GameCaptureActive.Title="Captura de Jogo ativa" Updater.GameCaptureActive.Text="Biblioteca da captura do jogo está a ser utilizada de momento. Por favor feche qualquer jogo/programa que esteja a ser capturado (ou dê restart ao Windows) e tente novamente." QuickTransitions.SwapScenes="Trocar pré-visualização/saída de cenas Depois de uma Transição" +QuickTransitions.SwapScenesTT="Troca as cenas de output e de pré-visualização após a transição (se a cena de output original ainda existir.)\nIsto não desfaz qualquer alteração que possa ter havido com a cena de output original." QuickTransitions.DuplicateScene="Duplicar cena" -QuickTransitions.EditProperties="Fontes duplicadas" +QuickTransitions.DuplicateSceneTT="Ao editar a mesma cena, permite editar a transformação/visibilidade de fontes sem modificar o output.\nPara editar as propriedades de fontes sem modificar o output, ativa o 'Duplicar Fontes'.\nMudar este valor vai reiniciar a cena atual de output (se ainda existir)." +QuickTransitions.EditProperties="Duplicar Fontes" QuickTransitions.EditPropertiesTT="Quando a editar a mesma cena, permite a edição das propriedades de fontes sem modificar a saida.\nIsto só pode ser usado se 'Duplicar Cena' está ativado.\nAlgumas fontes (como a captura e fontes de media) não suportam isto e não podem ser editados separadamente.\nModificar este valor vai redefinir a atual saída de cena (se ele ainda existir).\n\nAviso: Porque fontes vão ser duplicados, isto pode requisitar um sistema extra ou recursos de vídeo." QuickTransitions.HotkeyName="Transição rápida: %1" @@ -201,6 +235,9 @@ ConfirmStart.Text="Tem a certeza que quer começar a transmissão?" ConfirmStop.Title="Parar a transmissão?" ConfirmStop.Text="Tem a certeza que quer parar a transmissão?" +ConfirmBWTest.Title="Iniciar teste de largura de banda?" +ConfirmBWTest.Text="Você tem o OBS configurado no modo de teste de largura de banda. Este modo permite o teste de rede sem que o seu canal entre em funcionamento. Uma vez terminado o teste, você precisará desativá-lo para que os espectadores possam ver sua transmissão.\n\nVocê quer continuar?" + ConfirmExit.Title="Sair do OBS?" ConfirmExit.Text="O OBS está ligado. Todas as transmissões e gravações serão paradas. Tem a certeza de que pretende sair?" @@ -211,14 +248,17 @@ ConfirmRemove.TextMultiple="Tem a certeza de que pretende remover %1 itens?" Output.StartStreamFailed="Falha ao iniciar a stream" Output.StartRecordingFailed="Falha ao iniciar a gravação" Output.StartReplayFailed="Falha ao iniciar o buffer de repetição" +Output.StartFailedGeneric="Falha ao iniciar o output. Verifica o log para mais detalhes.\n\nNota: Se estás a usar codificadores NVENC ou AMD, certifica-te de que os drivers da placa gráfica estão atualizados." + Output.ConnectFail.Title="Falha ao ligar" Output.ConnectFail.BadPath="Caminho ou endereço de ligação inválido. Por favor, verifique as suas definições para confirmar que são válidas." Output.ConnectFail.ConnectFailed="Falhou a ligação ao servidor" -Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou chave de transmissão, por favor ré-verifique a sua chave de transmissão. Se é correto, pode haver um problema de conexão com o servidor." +Output.ConnectFail.InvalidStream="Não foi possível acessar o canal especificado ou chave de transmissão, por favor ré-verifique a sua chave de transmissão. Se é correto, pode haver um problema de conexão com o servidor." Output.ConnectFail.Error="Ocurreu um erro inesperado ao ligar-se ao servidor. Mais informação no ficheiro Log." Output.ConnectFail.Disconnected="Desligado do servidor." + Output.RecordFail.Title="Não foi possível iniciar a gravação" Output.RecordFail.Unsupported="O formato de saída ou não é suportado ou não suporta mais do que uma faixa de áudio. Por favor, verifique as suas definições e tente novamente." Output.RecordNoSpace.Title="Espaço em disco insuficiente" @@ -235,28 +275,26 @@ LogReturnDialog="Envio de Log Sucedido" LogReturnDialog.CopyURL="Copiar endereço" LogReturnDialog.ErrorUploadingLog="Erro no envio de ficheiro Log" -LicenseAgreement="Termos e condições da licença" -LicenseAgreement.PleaseReview="Por favor, reveja os termos de licença antes de usar Obs. Usando este programa, você reconhece que leu e aceita os termos da GNU General Public License v 2.0. Por favor, role para baixo para ver o resto do acordo." -LicenseAgreement.ClickIAgreeToContinue="Se você aceitar os termos do acordo, clique em Aceito para continuar. Você deve aceitar o acordo de usar Obs." -LicenseAgreement.IAgree="Aceito" -LicenseAgreement.Exit="Sair" - Remux.SourceFile="Gravação do OBS" Remux.TargetFile="Ficheiro de destino" Remux.Remux="Remisturar" +Remux.Stop="Parar Remuxing" +Remux.ClearFinished="Limpar Itens Finalizados" +Remux.ClearAll="Limpar Todos os Itens" Remux.OBSRecording="Gravação do OBS" Remux.FinishedTitle="Remistura concluída" Remux.Finished="Gravação remisturada" Remux.FinishedError="Gravação remisturada, mas o ficheiro pode estar incompleto" -Remux.SelectRecording="Selecione uma gravação do OBS…" -Remux.SelectTarget="Selecione o ficheiro de destino…" -Remux.FileExistsTitle="O ficheiro de destino já existe" -Remux.FileExists="O ficheiro de destino já existe. Pretende substituí-lo?" +Remux.SelectRecording="Selecione Gravação OBS..." +Remux.SelectTarget="Select target file..." +Remux.FileExistsTitle="O ficheiro de destino existe" +Remux.FileExists="Os seguintes ficheiros de destino já existem. Deseja substituí-los?" Remux.ExitUnfinishedTitle="Remistura em progresso" Remux.ExitUnfinished="A remistura não está concluída. Ao parar agora pode tornar o ficheiro de destino inutilizável.\nTem a certeza de que pretende para a remistura?" +Remux.HelpText="Arrasta ficheiros para esta janela para fazer remux, ou selectiona uma célula \"Gravação do OBS\" vazia para procurar por um ficheiro." UpdateAvailable="Nova atualização disponível" -UpdateAvailable.Text="Versão %1.%2.%3 está agora disponível. Clique aqui para descarregar" +UpdateAvailable.Text="Versão %1.%2.%3 está agora disponível. Clique aqui para descarregar" Basic.DesktopDevice1="Desktop Audio" Basic.DesktopDevice2="Desktop Audio 2" @@ -270,11 +308,13 @@ Basic.DisplayCapture="Captura de Ecrã" Basic.Main.PreviewConextMenu.Enable="Ativar pré-visualização" + ScaleFiltering="Filtragem de escala" ScaleFiltering.Point="Ponto" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" Deinterlacing="Desentrelaçamento" Deinterlacing.Discard="Discartar" @@ -289,6 +329,7 @@ Deinterlacing.TopFieldFirst="Campo Superior Primeiro" Deinterlacing.BottomFieldFirst="Campo Inferior Primeiro" VolControl.SliderUnmuted="Barra de volume para '%1': %2" +VolControl.SliderMuted="Barra de volume para '%1': %2 (atualmente silenciado)" VolControl.Mute="Silêncio '%1'" VolControl.Properties="Propriedades de '%1'" @@ -308,6 +349,7 @@ AddProfile.Text="Por favor, introduza o nome do perfil" RenameProfile.Title="Renomear perfil" Basic.Main.MixerRename.Title="Renomear fonte de áudio" +Basic.Main.MixerRename.Text="Introduza o nome da fonte de audio" Basic.Main.PreviewDisabled="A pré-visualização está desativada atualmente" @@ -390,30 +432,40 @@ Basic.Main.Sources="Fontes" Basic.Main.Controls="Controlos" Basic.Main.Connecting="A ligar..." Basic.Main.StartRecording="Começar Gravação" +Basic.Main.StartReplayBuffer="Iniciar Replay Buffer" Basic.Main.StartStreaming="Iniciar transmissão" Basic.Main.StopRecording="Parar Gravação" Basic.Main.StoppingRecording="A parar gravação..." +Basic.Main.StopReplayBuffer="Parar Replay Buffer" +Basic.Main.StoppingReplayBuffer="A Parar Replay Buffer..." Basic.Main.StopStreaming="Parar transmissão" Basic.Main.StoppingStreaming="A parar transmissão..." Basic.Main.ForceStopStreaming="Parar transmissão (ignorar atraso)" +Basic.Main.Group="Grupo %1" +Basic.Main.GroupItems="Agrupar Itens Selecionados" +Basic.Main.Ungroup="Desagrupar" Basic.MainMenu.File="&Ficheiro" Basic.MainMenu.File.Export="&Exportar" Basic.MainMenu.File.Import="&Importar" Basic.MainMenu.File.ShowRecordings="Most&rar gravações" Basic.MainMenu.File.Remux="Re&misturar gravações" -Basic.MainMenu.File.Settings="&Definições" +Basic.MainMenu.File.Settings="Definiçõe&s" Basic.MainMenu.File.ShowSettingsFolder="Mostrar pasta das definições" Basic.MainMenu.File.ShowProfileFolder="Mostrar pasta do perfil" -Basic.MainMenu.AlwaysOnTop="&Sempre em Cima" -Basic.MainMenu.File.Exit="&Sair" +Basic.MainMenu.AlwaysOnTop="Sempre em Cim&a" +Basic.MainMenu.File.Exit="Sair (&X)" Basic.MainMenu.Edit="&Editar" -Basic.MainMenu.Edit.Undo="Desfazer" +Basic.MainMenu.Edit.Undo="Desfazer (&U)" Basic.MainMenu.Edit.Redo="&Refazer" -Basic.MainMenu.Edit.UndoAction="Desfazer $1" +Basic.MainMenu.Edit.UndoAction="Desfazer $1 (&U)" Basic.MainMenu.Edit.RedoAction="&Refazer $1" Basic.MainMenu.Edit.LockPreview="B&loquear pré-visualização" +Basic.MainMenu.Edit.Scale="Pré-vi&sualizar Escala" +Basic.MainMenu.Edit.Scale.Window="Escalar à Janela" +Basic.MainMenu.Edit.Scale.Canvas="Canvas (%1x%2)" +Basic.MainMenu.Edit.Scale.Output="Saída (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformar" Basic.MainMenu.Edit.Transform.EditTransform="&Editar Transformação..." Basic.MainMenu.Edit.Transform.CopyTransform="Copiar e Transformar" @@ -424,14 +476,14 @@ Basic.MainMenu.Edit.Transform.Rotate90CCW="Rodar 90 graus CCW" Basic.MainMenu.Edit.Transform.Rotate180="Rodar 180 graus" Basic.MainMenu.Edit.Transform.FlipHorizontal="Inverter &Horizontalmente" Basic.MainMenu.Edit.Transform.FlipVertical="Inverter &Verticalmente" -Basic.MainMenu.Edit.Transform.FitToScreen="Escalar ao ecrã" +Basic.MainMenu.Edit.Transform.FitToScreen="Escalar ao ecrã (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="E&sticar ao ecrã" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrar ao ecrã" Basic.MainMenu.Edit.Order="&Ordem" -Basic.MainMenu.Edit.Order.MoveUp="Mover para Cima" -Basic.MainMenu.Edit.Order.MoveDown="Mover para Baixo" +Basic.MainMenu.Edit.Order.MoveUp="Mover para Cima (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Mover para Baixo (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Mover para p &Topo" -Basic.MainMenu.Edit.Order.MoveToBottom="Mover para o Fundo" +Basic.MainMenu.Edit.Order.MoveToBottom="Mover para o Fundo (&B)" Basic.MainMenu.Edit.AdvAudio="Propriedades &avançadas de áudio" Basic.MainMenu.View="&Ver" @@ -439,26 +491,36 @@ Basic.MainMenu.View.Toolbars="Barras de ferramen&tas" Basic.MainMenu.View.Docks="Âncoras" Basic.MainMenu.View.Docks.ResetUI="Reiniciar Interface" Basic.MainMenu.View.Docks.LockUI="Bloquear Interface" +Basic.MainMenu.View.Toolbars.Listboxes="&Lista de Caixas" Basic.MainMenu.View.SceneTransitions="Transições de &cenas" -Basic.MainMenu.View.StatusBar="&Barra de estado" +Basic.MainMenu.View.StatusBar="Barra de e&stado" Basic.MainMenu.View.Fullscreen.Interface="Interface de ecrã inteiro" -Basic.MainMenu.SceneCollection="Coleção de cena" +Basic.MainMenu.SceneCollection="Coleção de cena (&S)" Basic.MainMenu.Profile="&Perfil" Basic.MainMenu.Profile.Import="Importar perfil" Basic.MainMenu.Profile.Export="Exportar Perfil" +Basic.MainMenu.SceneCollection.Import="Importar Coleção de Cenas" +Basic.MainMenu.SceneCollection.Export="Exportar Coleção de Cenas" Basic.MainMenu.Profile.Exists="O perfil já existe" +Basic.MainMenu.SceneCollection.Exists="A coleção de cenas já existe" -Basic.MainMenu.Tools="&Ferramentas" +Basic.MainMenu.Tools="Ferramen&tas" -Basic.MainMenu.Help="&Ajuda" +Basic.MainMenu.Help="Ajuda (&H)" +Basic.MainMenu.Help.HelpPortal="&Portal de Ajuda" Basic.MainMenu.Help.Website="Visitar &website" +Basic.MainMenu.Help.Discord="Juntar-se ao Server de &Discord" Basic.MainMenu.Help.Logs="Ficeiros de &Log" -Basic.MainMenu.Help.Logs.ShowLogs="Most&rar ficheiros de registo" +Basic.MainMenu.Help.Logs.ShowLogs="Mo&strar ficheiros de registo" Basic.MainMenu.Help.Logs.UploadCurrentLog="Enviar Ficheiro &Currente de Log" Basic.MainMenu.Help.Logs.UploadLastLog="Enviar Ultímo Ficheiro de &Log" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Ver registo atual" Basic.MainMenu.Help.CheckForUpdates="Procurar atualizações" +Basic.MainMenu.Help.CrashLogs="&Relatórios de Erro" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Mo&strar Relatórios de Erro" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Submeter Ú<imo Relatório de Erro" +Basic.MainMenu.Help.About="&Acerca" Basic.Settings.ProgramRestart="O programa necessita de ser reinicializado para estas alterações terem efeito." Basic.Settings.ConfirmTitle="Confirmar Alterações" @@ -472,15 +534,45 @@ Basic.Settings.General.OpenStatsOnStartup="Abrir diálogo de estatísticas no ar Basic.Settings.General.WarnBeforeStartingStream="Mostrar caixa de diálogo de confirmação ao iniciar transmissões" Basic.Settings.General.WarnBeforeStoppingStream="Mostrar caixa de diálogo de confirmação ao parar transmissões" Basic.Settings.General.Projectors="Projetores" +Basic.Settings.General.HideProjectorCursor="Esconder o cursor em projetores" +Basic.Settings.General.ProjectorAlwaysOnTop="Pôr os projetores sempre por cima" Basic.Settings.General.Snapping="Alinhamentos com encaixe na Cena" +Basic.Settings.General.ScreenSnapping="Alinhar Fontes ao canto do ecrã" +Basic.Settings.General.CenterSnapping="Alinhar Fontes ao centro horizontal e vertical" +Basic.Settings.General.SourceSnapping="Alinhar Fontes a outras fontes" Basic.Settings.General.SnapDistance="Sensibilidade do Snap" Basic.Settings.General.RecordWhenStreaming="Gravar automaticamente quando estiver a transmitir" Basic.Settings.General.KeepRecordingWhenStreamStops="Continuar a gravar quando a transmissão parar" +Basic.Settings.General.ReplayBufferWhileStreaming="Começar automaticamente o replay buffer quando transmitir" +Basic.Settings.General.KeepReplayBufferStreamStops="Manter o replay buffer ativo quando a transmissão parar" Basic.Settings.General.SysTray="Bandeja do Sistema" Basic.Settings.General.SysTrayWhenStarted="Minimizar para a área de notificações quando iniciado" +Basic.Settings.General.SystemTrayHideMinimize="Minimizar sempre para a área de notoficações em vez da barra de tarefas" +Basic.Settings.General.SaveProjectors="Guardar projectores ao sair" +Basic.Settings.General.Preview="Pré-visualização" +Basic.Settings.General.OverflowHidden="Esconder excesso" +Basic.Settings.General.OverflowAlwaysVisible="Tornar excesso visível" +Basic.Settings.General.OverflowSelectionHidden="Mostrar excesso mesmo quando a fonte está invisível" +Basic.Settings.General.SwitchOnDoubleClick="Transição para cena ao fazer duplo clique" +Basic.Settings.General.StudioPortraitLayout="Habilitar layout horizontal/vertical" +Basic.Settings.General.TogglePreviewProgramLabels="Mostrar etiquetas de pré-visualização/programas" +Basic.Settings.General.Multiview="Multiview" +Basic.Settings.General.Multiview.MouseSwitch="Clique para alternar entre cenas" +Basic.Settings.General.Multiview.DrawSourceNames="Mostrar nome das cenas" +Basic.Settings.General.Multiview.DrawSafeAreas="Desenhar áreas seguras (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Layout do Multiview" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontal, Topo (8 Cenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontal, Fundo (8 Cenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertical, Esquerda (8 Cenas)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertical, Direita (8 Cenas)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontal, Topo (24 Cenas)" Basic.Settings.Stream="Transmissão" Basic.Settings.Stream.StreamType="Tipo de transmissão" +Basic.Settings.Stream.Custom.UseAuthentication="Usar autenticação" +Basic.Settings.Stream.Custom.Username="Nome de usuário" +Basic.Settings.Stream.Custom.Password="Senha" +Basic.Settings.Stream.BandwidthTestMode="Habilitar Modo de Teste de Largura de Banda" Basic.Settings.Output="Saída" Basic.Settings.Output.Format="Formato de gravação" @@ -492,6 +584,12 @@ Basic.Settings.Output.Mode="Modo de saída" Basic.Settings.Output.Mode.Simple="Simples" Basic.Settings.Output.Mode.Adv="Avançado" Basic.Settings.Output.Mode.FFmpeg="Saída FFmpeg" +Basic.Settings.Output.UseReplayBuffer="Ativar Replay Buffer" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Tempo Máximo de Replay (Segundos)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memória Máxima (Megabytes)" +Basic.Settings.Output.ReplayBuffer.Estimate="Utilização estimada de memória: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Não é possível estimar a utilização de memória. Defina o limite máximo de memória." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Nota: Certifica-te de definires uma tecla de atalho para o replay buffer na secção de teclas de atalho)" Basic.Settings.Output.ReplayBuffer.Prefix="Buffer de repetição de nome prefixo" Basic.Settings.Output.ReplayBuffer.Suffix="Sufixo" Basic.Settings.Output.Simple.SavePath="Caminho da gravação" @@ -500,6 +598,10 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="A mesma da transmissão" Basic.Settings.Output.Simple.RecordingQuality.Small="Alta qualidade, Tamanho médio" Basic.Settings.Output.Simple.RecordingQuality.HQ="Qualidade indistinguível, Tamanho de Arquivo Grande" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Sem perda de qualidade, Tamanho de Arquivo Enorme" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Aviso: O bitrate do vídeo de transmissão será definido para %1, que é o limite superior para o dispositivo atual de transmissão. Se tens a certeza de que queres ir acima de %1, ativa opções de codificação avançadas e desmarca a opçáo \"Impor limites de bitrate do serviço de transmissao\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Aviso: O bitrate do áudio de transmissão será definido para %1, que é o limite superior para o dispositivo atual de transmissão. Se tens a certeza de que queres ir acima de %1, ativa opções de codificação avançadas e desmarca a opçáo \"Impor limites de bitrate do serviço de transmissao\"." +Basic.Settings.Output.Simple.Warn.Encoder="Aviso: Gravar com um codificador de software com uma qualidade diferente da transmissão vai exigir mais da CPU se transmitires e gravares ao mesmo tempo." +Basic.Settings.Output.Simple.Warn.Lossless="Aviso: Qualidade sem perdas cria ficheiros com tamanhos tremendos! A qualidade sem perdas pode usar até 7 gigabytes de espaço no disco por minuto a altas resoluções e framerates. Não é recomendado usar qualidade sem perdas para gravações longas a não ser que tenhas muito espaço disponível no disco." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Tem a certeza de que pretende utilizar a qualidade sem perdas?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Aviso de qualidade sem perda!" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" @@ -513,7 +615,7 @@ Basic.Settings.Output.Reconnect="Religar Automaticamente" Basic.Settings.Output.RetryDelay="Atraso de Tentatica de Religação (segundos)" Basic.Settings.Output.MaxRetries="Número Máximo de Tentativas de Religação" Basic.Settings.Output.Advanced="Ativar definições avançadas de codificação" -Basic.Settings.Output.EncoderPreset="Predefinição de codificação (maior = menor processamento)" +Basic.Settings.Output.EncoderPreset="Predefinição do codificador" Basic.Settings.Output.CustomEncoderSettings="Definições de codificação personalizadas" Basic.Settings.Output.CustomMuxerSettings="Configurações personalizadas do Muxer" Basic.Settings.Output.NoSpaceFileName="Gerar o Nome do Arquivo sem espaço" @@ -555,9 +657,12 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Definições do codificador d Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificador de áudio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Definições do codificador de áudio (se houver)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Configurações Muxer (se houver)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Intervalo de Keyframes (frames)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Mostrar todos os codecs (mesmo que potencialmente incompatíveis)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" +FilenameFormatting.TT="%CCYY Ano, quatro dígitos\n%YY Ano, últimos dois dígitos (00-99)\n%MM Mês em número decimal (01-12)\n%DD Dia do mês, com zero em prefixo (01-31)\n%hh Hora em formato 24h (00-23)\n%mm Minuto (00-59)\n%ss Segundo (00-61)\n%% Um sinal % \n%a Dia da semana abreviado\n%A Dia da semana completo\n%b Mês abreviado\n%B Mês completo\n%d Dia do mês, com zero em prefixo (01-31)\n%H Hora em formato 24h (00-23)\n%I Hora em formato 12h (01-12)\n%m Mês em número decimal (01-12)\n%M Minuto (00-59)\n%p Designação AM ou PM\n%S Segundo (00-61)\n%y Ano, últimos dois dígitos (00-99)\n%Y Ano\n%z ISO 8601 offset de UTC ou de fuso horário completo ou abreviado\n name or abbreviation\n%Z Fuso horário completo ou abreviado\n" Basic.Settings.Video="Vídeo" Basic.Settings.Video.Adapter="Adaptador de Vídeo" @@ -583,18 +688,22 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (escalamento nítido, 32 a Basic.Settings.Audio="Áudio" Basic.Settings.Audio.SampleRate="Frequência de Samplagem" Basic.Settings.Audio.Channels="Canias" +Basic.Settings.Audio.MeterDecayRate.Fast="Rápido" +Basic.Settings.Audio.MeterDecayRate.Medium="Médio (Tipo I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Lento (Tipo II PPM)" +Basic.Settings.Audio.PeakMeterType="Tipo de Medidor de Pico" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Pico Pré-definido" +Basic.Settings.Audio.PeakMeterType.TruePeak="Pico Verdadeiro (Maior Uso da CPU)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="AVISO: O som surround está ativo." +Basic.Settings.Audio.MultichannelWarning="Se transmitir, verifique se o seu serviço de transmissão suporta tanto ingestão de áudio surround como playback de áudio surround. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast são exemplos onde o áudio surround é totalmente suportado. Embora o Facebook Live e o YouTube Live aceitem os dois ingestão de áudio surround, o Facebook Live transforma-o em stereo, e o YouTube Live só toca dois canais.\n\nOs filtros de áudio do OBS são compatíveis com áudio surround, embora não esteja garantido o suporte para plugins VST." Basic.Settings.Audio.MultichannelWarning.Title="Ativar audio surround?" Basic.Settings.Audio.MultichannelWarning.Confirm="Tem a certeza que quer ativar audio surround?" -Basic.Settings.Audio.DesktopDevice="Desktop Audio Device" -Basic.Settings.Audio.DesktopDevice2="Desktop Audio Device 2" -Basic.Settings.Audio.AuxDevice="Mic/Auxiliary Audio Device" -Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary Audio Device 2" -Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary Audio Device 3" Basic.Settings.Audio.EnablePushToMute="Ativar o push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Atrado do push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Ativar o push-to-talk" Basic.Settings.Audio.PushToTalkDelay="Atraso do push-to-talk" Basic.Settings.Audio.UnknownAudioDevice="[Dispositivo não conectado ou não disponível]" +Basic.Settings.Audio.Disabled="Desativado" Basic.Settings.Advanced="Avançado" Basic.Settings.Advanced.General.ProcessPriority="Prioridade do precesso" @@ -606,11 +715,8 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inativo" Basic.Settings.Advanced.FormatWarning="Aviso: Formatos de cor diferentes de NV12 destinam-se principalmente a gravação e não são recomendados durante a transmissão. A transmissão pode incorrer numa maior utilização do processador devido à conversão do formato de cor." Basic.Settings.Advanced.Audio.BufferingTime="Tempo de carregamento do áudio" Basic.Settings.Advanced.Video.ColorFormat="Formato de cor" -Basic.Settings.Advanced.Video.ColorSpace="Espaço de cor YUV" -Basic.Settings.Advanced.Video.ColorRange="Gama de cor YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Parcial" Basic.Settings.Advanced.Video.ColorRange.Full="Total" -Basic.Settings.Advanced.Audio.MonitoringDevice="Dispositivo de monitorização de audio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predefinição" Basic.Settings.Advanced.Audio.DisableAudioDucking="Desativar o ducking de audio do Windows" Basic.Settings.Advanced.StreamDelay="Atraso na trasmissão" @@ -621,12 +727,14 @@ Basic.Settings.Advanced.Network="Rede" Basic.Settings.Advanced.Network.BindToIP="Ligar pelo IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Ativar nova codificação de net" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Modo de baixa latência" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Desativar teclas de atalho quando a janela principal está em foco" +Basic.Settings.Advanced.AutoRemux="Fazer automaticamente remux para mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(gravar como mkv)" Basic.AdvAudio="Propriedades avançadas de áudio" Basic.AdvAudio.Name="Nome" -Basic.AdvAudio.Volume="Volume (%)" Basic.AdvAudio.Mono="Diminuir para mono" -Basic.AdvAudio.Panning="Desproporcionar" +Basic.AdvAudio.Balance="Equilíbrio" Basic.AdvAudio.SyncOffset="Atraso de sincronização (ms)" Basic.AdvAudio.Monitoring="Monitorização de Áudio" Basic.AdvAudio.Monitoring.None="Monitor Desligado" @@ -636,6 +744,7 @@ Basic.AdvAudio.AudioTracks="Faixas" Basic.Settings.Hotkeys="Teclas de atalho" Basic.Settings.Hotkeys.Pair="Combinações de teclas partilhadas com '%1' atuam como alavancas" +Basic.Settings.Hotkeys.Filter="Filtro" Basic.Hotkeys.SelectScene="Mudar para cena" @@ -690,9 +799,30 @@ SceneItemHide="Ocultar '%1'" OutputWarnings.NoTracksSelected="Tem de selecionar pelo menos uma faixa" OutputWarnings.MultiTrackRecording="Aviso: Alguns formatos (como FLV) não suportam várias faixas por gravação" +OutputWarnings.MP4Recording="Aviso: Gravações salvas em MP4/MOV serão irrecuperáveis se o arquivo não puder ser finalizado (por exemplo, como resultado de BSODs, perdas de energia, etc.). Se você quiser gravar várias pistas de áudio, considere usar MKV e remuxar a gravação para MP4/MOV depois de terminada (Arquivo → Remux Recordings)" FinalScene.Title="Apagar Cena" - - +FinalScene.Text="É preciso que exista pelo menos uma cena." + +NoSources.Title="Sem Fontes" +NoSources.Text="Parece que não adicionaste nenhuma fonte de vídeo ainda, por isso só vai ser produzido um ecrã em branco. De certeza que queres fazer isto?" +NoSources.Text.AddSource="Podes adicionar fontes ao clicar no ícone + dentro da caixa Fontes na janela principal em qualquer altura." + +ChangeBG="Definir Cor" +CustomColor="Cor Personalizada" + +BrowserSource.EnableHardwareAcceleration="Ativar Aceleração de Hardware para Fontes de Navegador" + +About="Acerca" +About.Info="O OBS Studio é um software livre e open source para gravação e streaming de video." +About.Donate="Faça uma Contribuição" +About.GetInvolved="Envolve-te" +About.Authors="Autores" +About.License="Licença" +About.Contribute="Apoiar o Projeto OBS" + +ResizeOutputSizeOfSource="Redimensionar output (tamanho da fonte)" +ResizeOutputSizeOfSource.Text="As resoluções base e de output serão redimensionadas para o tamanho da fonte atual." +ResizeOutputSizeOfSource.Continue="Deseja continuar?" diff --git a/UI/data/locale/ro-RO.ini b/UI/data/locale/ro-RO.ini index 43208f0..7035bf3 100644 --- a/UI/data/locale/ro-RO.ini +++ b/UI/data/locale/ro-RO.ini @@ -28,21 +28,27 @@ Browse="Răsfoiește" Mono="Mono" Stereo="Stereo" DroppedFrames="Cadre pierdute %1 (%2%)" +StudioProgramProjector="Proiector în fereastră (Program)" PreviewProjector="Proiector pe tot ecranul (Previzualizare)" SceneProjector="Proiector pe tot ecranul (Scenă)" SourceProjector="Proiector pe tot ecranul (Sursă)" +StudioProgramWindow="Proiector în fereastră (Program)" +PreviewWindow="Proiector pe tot ecranul (Previzualizare)" +SceneWindow="Proiector în fereastră (Program)" +SourceWindow="Proiector în fereastră (Sursa)" +MultiviewProjector="Vedere multipla (Pe tot ecranul)" Clear="Șterge" Revert="Inversează" -Show="Arată" +Show="Afișează" Hide="Ascunde" -UnhideAll="Reafișare totală" +UnhideAll="Reafișează toate" Untitled="Fără nume" New="Nou" Duplicate="Duplică" Enable="Activează" -DisableOSXVSync="Dezactivează OSX V-Sync" -ResetOSXVSyncOnExit="Resetează OSX V-Sync la ieșire" -HighResourceUsage="Codificare supraîncărcată! Ia în considerare reducerea setărilor video sau folosirea unei presetări de codare mai rapidă." +DisableOSXVSync="Dezactivează V-Sync în OSX" +ResetOSXVSyncOnExit="Resetează V-Sync în OSX la ieșire" +HighResourceUsage="Codificare supraîncărcată! Ia în considerare reducerea setărilor video sau folosirea unei presetări de codare mai rapidă." Transition="Tranziție" QuickTransitions="Tranziții rapide" Left="Stânga" @@ -53,75 +59,149 @@ Reset="Resetează" Hours="Ore" Minutes="Minute" Seconds="Secunde" -Deprecated="Invechit" +Deprecated="Obsolet" ReplayBuffer="Reluare Buffer" Import="Importă" Export="Exportă" Copy="Copiază" -Paste="Inserare" -PasteReference="Inserare (Referință)" -PasteDuplicate="Inserare (Duplicare)" +Paste="Lipește" +PasteReference="Lipește (Referință)" +PasteDuplicate="Lipește (Duplicare)" RemuxRecordings="Înregistrări Remux" Next="Următorul" Back="Înapoi" -Defaults="Prestabilite" +Defaults="Valori implicite" HideMixer="Ascunde în Mixer" +TransitionOverride="Suprascrierea tranziției" +None="Fără" +StudioMode.Preview="Previzualizare" +StudioMode.Program="Program" +ShowInMultiview="Afișează în vizualizarea multiplă" +VerticalLayout="Aranjament vertical" +Group="Grup" +DoNotShowAgain="Nu afișa iar" AlreadyRunning.Title="OBS ruleaza deja" AlreadyRunning.Text="OBS rulează deja! În cazul în care ați încercat sa faceți acest lucru, vă rugăm să închideți toate instanțele OBS înainte de a porni una noua. Dacă aveți OBS-ul setat pentru a se minimiza in system tray vă rugam sa verificați daca inca ruleaza acolo." AlreadyRunning.LaunchAnyway="Lansați Oricum" + +Auth.Authing.Title="Se autentifică..." +Auth.Authing.Text="Se autentifică cu %1, te rugăm să aștepți..." +Auth.AuthFailure.Title="Eșec la autentificare" +Auth.InvalidScope.Title="Autentificare necesară" +Auth.LoadingChannel.Title="Se încarcă informațiile canalului..." +Auth.LoadingChannel.Text="Se încarcă informațiile canalului pentru %1, te rugăm să aștepți..." +Auth.ChannelFailure.Title="Eșec la încărcarea canalului" +Auth.ChannelFailure.Text="Eșec la încărcarea informațiilor canalului pentru %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informații privind transmisiunea" +TwitchAuth.Stats="Statistici Twitch" +TwitchAuth.Feed="Fluxul activității Twitch" + Copy.Filters="Copiază filtrele" Paste.Filters="Lipește filtrele" +BrowserPanelInit.Title="Se inițializează browserul..." +BrowserPanelInit.Text="Se inițializează browserul, te rugăm să aștepți..." + BandwidthTest.Region="Regiune" BandwidthTest.Region.US="Statele Unite" BandwidthTest.Region.EU="Europa" BandwidthTest.Region.Asia="Asia" BandwidthTest.Region.Other="Alta" -Basic.FirstStartup.RunWizard="Dorești să rulezi expertul de configurare automată? Poți, de asemenea, să configurezi setările manual prin apăsarea butonului Setări din fereastra principală." -Basic.FirstStartup.RunWizard.BetaWarning="(Notă: Expertul de configurare este în prezent în versiune beta)" +Basic.FirstStartup.RunWizard="Vrei să rulezi asistentul de configurare automată? Poți, de asemenea, să configurezi setările manual dând clic pe butonul Setări din fereastra principală." +Basic.FirstStartup.RunWizard.NoClicked="Dacă vă răzgândiți, puteți rula auto-configuratorul oricând din meniul Instrumente." -Basic.AutoConfig="Expertul de Configurare-Automata" -Basic.AutoConfig.Beta="Expertul de Configurare-Automata (Beta)" -Basic.AutoConfig.ApplySettings="Aplicați setarile" +Basic.AutoConfig="Asistentul de configurare automată" +Basic.AutoConfig.ApplySettings="Aplică setările" Basic.AutoConfig.StartPage="Informații de utilizare" -Basic.AutoConfig.StartPage.SubTitle="Specificați pentru ce vreți sa folosiți programul" +Basic.AutoConfig.StartPage.SubTitle="Specifică pentru ce vrei să folosești programul" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimizează pentru transmisiune, înregistrarea este pe plan secund" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimizează numai pentru înregistrare, nu voi face transmisiuni" Basic.AutoConfig.VideoPage="Setări video" -Basic.AutoConfig.VideoPage.SubTitle="Specifică setările video dorite pe care ai dori să le folosești" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Utilizare curentă (%1x%2)" -Basic.AutoConfig.VideoPage.BaseResolution.Display="Afișați %1 (%2x%3)" -Basic.AutoConfig.StreamPage="Flux de informații" -Basic.AutoConfig.StreamPage.Service="Service" -Basic.AutoConfig.StreamPage.Service.ShowAll="Arătați tot..." +Basic.AutoConfig.VideoPage.SubTitle="Specifică setările video dorite pe care dorești să le folosești" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Folosește-o pe cea actuală (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Ecranul %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Folosește valoarea actuală (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Fie 60 sau 30, însă prefer 60 când este posibil" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Fie 60 sau 30, însă prefer rezoluție înaltă" +Basic.AutoConfig.VideoPage.CanvasExplanation="Notă: Rezoluția (de bază) a planșei nu este neapărat aceeași cu rezoluția cu care vei transmite sau înregistra. Rezoluția efectivă de transmisiune/înregistrare poate fi scalată în jos de la rezoluția planșei pentru a reduce necesarul de resurse sau de rată de biți." +Basic.AutoConfig.StreamPage="Informații privind transmisiunea" +Basic.AutoConfig.StreamPage.SubTitle="Te rugăm să introduci informațiile pentru transmisiune" +Basic.AutoConfig.StreamPage.ConnectAccount="Conectează un cont (opțional)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Deconectează contul" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Deconectezi contul?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Această modificare se va aplica imediat. Ești sigur că vrei să deconectezi contul?" +Basic.AutoConfig.StreamPage.UseStreamKey="Folosește cheia de transmisiune" +Basic.AutoConfig.StreamPage.Service="Serviciu" +Basic.AutoConfig.StreamPage.Service.ShowAll="Afișează toate..." +Basic.AutoConfig.StreamPage.Service.Custom="Personalizat..." Basic.AutoConfig.StreamPage.Server="Server" +Basic.AutoConfig.StreamPage.StreamKey="Cheie de transmisiune" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" -Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimează rata de biți cu un test al lățimii de bandă (poate dura câteva minute)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Estimează rata de biți cu o testare a lățimii de bandă (poate dura câteva minute)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Preferă codificarea hardware" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Codificarea hardware elimină cea mai mare parte a utilizării CPU, însă ar putea avea nevoie de o rată de biți mai mare pentru a obține același nivel de calitate." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Avertizare transmisie" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Testarea lățimii de bandă este pe cale să transmită date video aleatorii fără audio către canalul tău. Dacă ai posibilitatea, este recomandat să oprești temporar salvarea videoclipurilor transmisiunilor și să setezi transmisiunea pe privat până la încheierea testării. Continui?" Basic.AutoConfig.TestPage="Rezultate finale" +Basic.AutoConfig.TestPage.SubTitle.Testing="Programul rulează acum o serie de teste pentru identificarea setărilor ideale" Basic.AutoConfig.TestPage.SubTitle.Complete="Testare completă" +Basic.AutoConfig.TestPage.TestingBandwidth="Se efectuează testarea lățimii de bandă, acest lucru poate dura câteva minute..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Se conectează la: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Nu s-a putut conecta la niciun server. Te rugăm să verifici conexiunea la Internet și să încerci din nou." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Se testează lățimea de bandă pentru: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="Testare encoder transmisie, poate dura câteva minute..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testare encoder înregistrare, poate dura câteva minute..." Basic.AutoConfig.TestPage.TestingRes="Testare rezoluții, aceasta ar putea dura câteva minute..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Nu s-a putut porni encodarea" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Testare %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Codificator pentru transmisiune" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Codificator pentru înregistrare" +Basic.AutoConfig.TestPage.Result.Header="Programul a determinat că următoarele setări sunt cele mai potrivite:" +Basic.AutoConfig.TestPage.Result.Footer="Pentru a folosi aceste setări, dă clic pe Aplică setările. Pentru a reconfigura și a încerca din nou, dă clic pe Înapoi. Pentru a configura manual setările, apasă Anulează și deschide Setările." Basic.Stats="Statistici" -Basic.Stats.HDDSpaceAvailable="Spațiu HDD disponibil" +Basic.Stats.CPUUsage="Utilizare CPU" +Basic.Stats.HDDSpaceAvailable="Spațiu disponibil pe disc" +Basic.Stats.MemoryUsage="Utilizarea memoriei" +Basic.Stats.AverageTimeToRender="Timpul mediu de redare a cadrului" +Basic.Stats.SkippedFrames="Cadre sărite din pricina întârzierilor de codificare" +Basic.Stats.MissedFrames="Cadre sărite din pricina întârzierii de redare" +Basic.Stats.Output.Stream="Transmisie" +Basic.Stats.Output.Recording="Înregistrare" +Basic.Stats.Status="Stare" +Basic.Stats.Status.Recording="Înregistrare" Basic.Stats.Status.Live="ÎN DIRECT" +Basic.Stats.Status.Reconnecting="Reconectare" Basic.Stats.Status.Inactive="Inactiv" +Basic.Stats.DroppedFrames="Cadre pierdute (Rețea)" +Basic.Stats.MegabytesSent="Date transmise în total" Basic.Stats.Bitrate="Rată de biți" -Updater.UpdateNow="Actualizați acum" -Updater.RemindMeLater="Amintește-mi mai târziu" -QuickTransitions.SwapScenes="Comută între previzualizare/scenele de ieșire după tranziționare" +Updater.Title="Actualizare nouă disponibilă" +Updater.Text="Există o nouă actualizare disponibilă:" +Updater.UpdateNow="Actualizează acum" +Updater.RemindMeLater="Reamintește-mi mai târziu" +Updater.Skip="Omite versiunea" +Updater.NoUpdatesAvailable.Title="Nu există actualizări disponibile" +Updater.NoUpdatesAvailable.Text="În prezent nu sunt disponibile actualizări" +Updater.GameCaptureActive.Title="Captură de joc activă" + +QuickTransitions.SwapScenes="Comută previzualizarea/scenele de ieșire după tranziționare" QuickTransitions.SwapScenesTT="Schimba previzualizarea si scenele de output dupa tranzitionare (în cazul în care încă există outputul scenei originale). \nAceasta nu va anula nicio modificăre care au fost făcute la outputul scenei originale." QuickTransitions.DuplicateScene="Duplică scena" QuickTransitions.DuplicateSceneTT="La editarea aceleiaşi scene, permite editarea transformarii/vizibilitatii surselor fără modificarea output-ului. \nPentru a edita proprietăţile surselor fără a modifica output-ul, activaţi 'Surse Dublate'. \nSchimband această valoare va reseta outputul scenei curente (în cazul în care încă mai există)." -QuickTransitions.EditProperties="Surse duplicate" +QuickTransitions.EditProperties="Duplică scenele" QuickTransitions.EditPropertiesTT="La editarea aceleiaşi scene, permite editarea proprietăţilor surselor fără modificareaa outputului. \nAceasta poate fi utilizat doar dacă este activată 'Scena Dublata'. \nAnumite surse (cum ar fi sursele de captare sau mass-media) nu acceptă acest lucru şi nu poate fi editat separat. \nSchimband această valoare va reseta outputul scenei curente (în cazul în care încă mai există).\n\nAtentie: deoarece sursele vor fi dublate, aceasta poate solicita suplimentar sistemul sau resursele video." QuickTransitions.HotkeyName="Tranziție rapidă: %1" Basic.AddTransition="Adaugă tranziție configurabilă" Basic.RemoveTransition="Elimină tranziția configurabilă" -Basic.TransitionProperties="Proprietăți pentru tranziții" +Basic.TransitionProperties="Proprietăți pentru tranziție" Basic.SceneTransitions="Tranziții pentru scene" Basic.TransitionDuration="Durată" Basic.TogglePreviewProgramMode="Mod studio" @@ -138,66 +218,71 @@ NameExists.Text="Numele este deja în uz." NoNameEntered.Title="Te rugăm să introduci un nume valid" NoNameEntered.Text="Nu poți folosi nume necompletate." -ConfirmStart.Title="Începi streamul?" -ConfirmStart.Text="Sigur dorești să pornești streamul?" +ConfirmStart.Title="Începi transmisiunea?" +ConfirmStart.Text="Sigur vrei să pornești transmisiunea?" ConfirmStop.Title="Oprești streamul?" -ConfirmStop.Text="Sigur dorești să oprești streamul?" +ConfirmStop.Text="Sigur vrei să oprești transmisiunea?" + +ConfirmBWTest.Title="Începi testarea pentru lățimea de bandă?" +ConfirmBWTest.Text="Ai configurat OBS în modul de testare a lățimii de bandă. Acest mod permite testarea rețelei fără să transmiți live pe canal. Odată ce ai terminat testarea, va trebui să îl dezactivezi pentru ca spectatorii să îți poată vedea transmisiunea.\n\nVrei să continui?" ConfirmExit.Title="Ieși din OBS?" -ConfirmExit.Text="OBS este în prezent activ. Toate streamurile/înregistrările vor fi închise. Sigur dorești să ieși?" +ConfirmExit.Text="OBS este în prezent activ. Toate transmisiunile/înregistrările vor fi închise. Sigur vrei să ieși?" ConfirmRemove.Title="Confirmă eliminarea" -ConfirmRemove.Text="Sigur dorești să elimini „$1”?" +ConfirmRemove.Text="Sigur vrei să elimini „$1”?" ConfirmRemove.TextMultiple="Sigur doriți sa eliminați %1 obiecte?" +Output.StartStreamFailed="Pornirea transmisiunii a eșuat" +Output.StartRecordingFailed="Pornirea înregistrării a eșuat" + Output.ConnectFail.Title="Eșec la conectare" -Output.ConnectFail.BadPath="URL-ul conexiunii sau calea este invalidă. Te rugăm să verifici setările pentru a confirma că acestea sunt valide." +Output.ConnectFail.BadPath="URL-ul conexiunii sau calea este invalidă. Te rugăm să verifici setările pentru a confirma că acestea sunt valide." Output.ConnectFail.ConnectFailed="Nu se poate conecta la server" -Output.ConnectFail.InvalidStream="Nu a putut fi accesat canalul sau cheia de stream respectiva, vă rugăm să verificaţi cheia de stream. Dacă aceasta este corectă, poate fi o problemă la conectarea la server." -Output.ConnectFail.Error="Eroare neașteptată la încercarea de a conecta la server. Mai multe informaţii în fişierul jurnal." +Output.ConnectFail.InvalidStream="Nu a putut fi accesat canalul sau cheia de transmisiune specificată, te rugăm să verifici cheia de transmisiune. Dacă aceasta este corectă, poate fi o problemă cu conectarea la server." +Output.ConnectFail.Error="Eroare neașteptată la încercarea de a conecta la server. Mai multe informaţii în fişierul jurnal." Output.ConnectFail.Disconnected="Deconectat de la server." + Output.RecordFail.Title="Eșec la pornirea înregistrării" -Output.RecordFail.Unsupported="Formatul de ieşire este fie neacceptat sau nu acceptă mai multe piese audio. Vă rugăm să verificaţi setările şi încercaţi din nou." +Output.RecordFail.Unsupported="Formatul de ieşire este fie nesuportat, fie nu suportă mai mult de o pistă audio. Te rugăm să verifici setările şi să încerci din nou." Output.RecordNoSpace.Title="Spațiu insuficient pe disc" Output.RecordNoSpace.Msg="Nu există spațiu suficient pe disc pentru a continua înregistrarea." Output.RecordError.Title="Eroare de înregistrare" Output.RecordError.Msg="S-a produs o eroare nespecificată în timpul înregistrării." +Output.ReplayBuffer.NoHotkey.Title="Nicio tastă rapidă setată!" Output.BadPath.Title="Calea fișierului greșită" -Output.BadPath.Text="Calea de ieşire pentru fişiere invalidă. Vă rugăm să verificaţi setările pentru a confirma că s-a stabilit o cale de fişier validă." +Output.BadPath.Text="Calea de ieşire pentru fişiere invalidă. Vă rugăm să verificaţi setările pentru a confirma că s-a stabilit o cale de fişier validă." LogReturnDialog="Jurnal incărcat cu succes" LogReturnDialog.CopyURL="Copiază URL-ul" LogReturnDialog.ErrorUploadingLog="Eroare la încărcarea fișierului jurnal" -LicenseAgreement="Acord de licență" -LicenseAgreement.PleaseReview="Vă rugăm să revedeţi termenii de licenţă înainte de a utiliza OBS. Utilizând acest program, confirmaţi că aţi citit şi sunt de acord cu termenii Licenței Publice Generale GNU v2.0. Vă rugăm să derulaţi în jos pentru a vedea restul acordului." -LicenseAgreement.ClickIAgreeToContinue="Dacă acceptaţi termenii acordului, faceţi clic pe Sunt de acord să continuaţi. Trebuie să acceptaţi acordul pentru a utiliza OBS." -LicenseAgreement.IAgree="Sunt de acord" -LicenseAgreement.Exit="Ieși" - Remux.SourceFile="Înregistrare OBS" Remux.TargetFile="Fișier țintă" Remux.Remux="Remux" +Remux.Stop="Oprește remuxarea" +Remux.ClearFinished="Șterge elementele finalizate" +Remux.ClearAll="Șterge toate elementele" Remux.OBSRecording="Înregistrare OBS" Remux.FinishedTitle="Remuxing încheiat" Remux.Finished="Înregistrare remuxată" Remux.FinishedError="Înregistrare remuxată, însă fișierul poate fi incomplet" -Remux.SelectRecording="Selectează înregistrarea OBS …" -Remux.SelectTarget="Selectează fișierul țintă …" -Remux.FileExistsTitle="Fișierul țintă există" -Remux.FileExists="Fișierul țintă există, dorești să-l înlocuiești?" +Remux.SelectRecording="Selectează înregistrarea OBS..." +Remux.FileExistsTitle="Fișierele țintă există deja" +Remux.FileExists="Fișierele deja exista. Vreți să le înlocuiți?" Remux.ExitUnfinishedTitle="Remuxing în desfășurare" -Remux.ExitUnfinished="Remuxingul nu este încheiat, oprirea în acest moment poate face fișierul țintă inutilizabil.\nSigur dorești să oprești remuxingul?" +Remux.ExitUnfinished="Remuxingul nu este încheiat, oprirea în acest moment poate face fișierul țintă inutilizabil.\nSigur vrei să oprești remuxingul?" +Remux.HelpText="Plasează fișierele în această fereastră pentru a remuxa ori selectează o celulă „Înregistrare OBS” goală pentru a răsfoi un fișier." UpdateAvailable="Actualizare nouă disponibilă" -UpdateAvailable.Text="Versiunea %1.%2.%3 este acum disponibilă. Clic aici pentru a descărca" +UpdateAvailable.Text="Versiunea %1.%2.%3 este acum disponibilă. Clic aici pentru a descărca" -Basic.DesktopDevice1="Desktop audio" -Basic.DesktopDevice2="Desktop audio 2" +Basic.DesktopDevice1="Audio desktop" +Basic.DesktopDevice2="Audio desktop 2" Basic.AuxDevice1="Microfon/Aux" Basic.AuxDevice2="Microfon/Aux 2" Basic.AuxDevice3="Microfon/Aux 3" @@ -208,6 +293,7 @@ Basic.DisplayCapture="Captură de display" Basic.Main.PreviewConextMenu.Enable="Activează previzualizarea" + ScaleFiltering.Point="Punct" ScaleFiltering.Bilinear="Biliniar" ScaleFiltering.Bicubic="Bicubic" @@ -226,6 +312,7 @@ Deinterlacing.TopFieldFirst="Câmpul de sus prima oară" Deinterlacing.BottomFieldFirst="Câmpul de jos prima oară" VolControl.Mute="Mut '%1'" +VolControl.Properties="Proprietăți pentru „%1”" Basic.Main.AddSceneDlg.Title="Adaugă scenă" Basic.Main.AddSceneDlg.Text="Te rugăm să introduci numele scenei" @@ -242,24 +329,27 @@ AddProfile.Text="Te rugăm să introduci numele profilului" RenameProfile.Title="Redenumește profilul" +Basic.Main.MixerRename.Text="Te rugăm să introduci numele sursei audio" -Basic.Main.PreviewDisabled="Previzualizarea este în prezent dezactivată" +Basic.Main.PreviewDisabled="Previzualizarea este dezactivată în prezent" Basic.SourceSelect="Creează/Selectează sursa" -Basic.SourceSelect.CreateNew="Creează nouă" -Basic.SourceSelect.AddExisting="Adaugă existentă" +Basic.SourceSelect.CreateNew="Creează una nouă" +Basic.SourceSelect.AddExisting="Adaugă una existentă" Basic.SourceSelect.AddVisible="Fă sursa vizibilă" Basic.PropertiesWindow="Proprietăți pentru '%1'" -Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselectare: %2)" +Basic.PropertiesWindow.AutoSelectFormat="%1 (selectare automată: %2)" Basic.PropertiesWindow.SelectColor="Selectează culoarea" Basic.PropertiesWindow.SelectFont="Selectează fontul" Basic.PropertiesWindow.ConfirmTitle="Setări schimbate" -Basic.PropertiesWindow.Confirm="Există modificări nesalvate. Dorești să le păstrezi?" +Basic.PropertiesWindow.Confirm="Există modificări nesalvate. Vrei să le păstrezi?" Basic.PropertiesWindow.NoProperties="Nicio proprietate disponibilă" Basic.PropertiesWindow.AddFiles="Adaugă fișiere" +Basic.PropertiesWindow.AddDir="Adaugă un director" Basic.PropertiesWindow.AddURL="Adaugă cale/URL" +Basic.PropertiesWindow.AddEditableListDir="Adaugă directorul în „%1”" Basic.PropertiesWindow.AddEditableListFiles="Adaugă fișiere la '%1'" Basic.PropertiesWindow.AddEditableListEntry="Adaugă intrare la '%1'" Basic.PropertiesWindow.EditEditableListEntry="Editează intrarea de la '%1'" @@ -270,23 +360,23 @@ Basic.PropertiesView.FPS.ValidFPSRanges="Intervale FPS valide:" Basic.InteractionWindow="Interacționează cu '%1'" -Basic.StatusBar.Reconnecting="Deconectat, se reconectează în %2 secunda(e) (încercarea %1)" +Basic.StatusBar.Reconnecting="Deconectat, se reconectează în %2 secundă(e) (încercarea %1)" Basic.StatusBar.AttemptingReconnect="Se încearcă reconectarea... (încercarea %1)" Basic.StatusBar.ReconnectSuccessful="Reconectare cu succes" Basic.StatusBar.Delay="Întârziere (%1 secunde)" Basic.StatusBar.DelayStartingIn="Întârziere (începând în %1 sec)" -Basic.StatusBar.DelayStoppingIn="Întârziere (oprindu-se în %1 sec)" -Basic.StatusBar.DelayStartingStoppingIn="Întârziere (oprindu-se în %1 sec, începând în %2 sec)" +Basic.StatusBar.DelayStoppingIn="Întârziere (se oprește în %1 sec)" +Basic.StatusBar.DelayStartingStoppingIn="Întârziere (se oprește în %1 sec, începe în %2 sec)" Basic.Filters="Filtre" Basic.Filters.AsyncFilters="Filtre audio/video" Basic.Filters.AudioFilters="Filtre audio" Basic.Filters.EffectFilters="Filtre de efect" -Basic.Filters.Title="Filtre pentru „%1”" +Basic.Filters.Title="Filtre pentru '%1'" Basic.Filters.AddFilter.Title="Numele filtrului" Basic.Filters.AddFilter.Text="Te rugăm să specifici numele filtrului" -Basic.TransformWindow="Transformare a elementelor pentru scene" +Basic.TransformWindow="Transformarea elementelor pentru scene" Basic.TransformWindow.Position="Poziție" Basic.TransformWindow.Rotation="Rotație" Basic.TransformWindow.Size="Dimensiune" @@ -319,21 +409,26 @@ Basic.Main.AddSourceHelp.Text="Trebuie să ai cel puțin 1 scenă pentru a adău Basic.Main.Scenes="Scene" Basic.Main.Sources="Surse" +Basic.Main.Controls="Comenzi" Basic.Main.Connecting="Se conectează..." Basic.Main.StartRecording="Pornește înregistrarea" -Basic.Main.StartStreaming="Pornește streamingul" +Basic.Main.StartStreaming="Pornește transmisiunea" Basic.Main.StopRecording="Oprește înregistrarea" -Basic.Main.StopStreaming="Oprește streamingul" -Basic.Main.ForceStopStreaming="Oprește streamingul (renunță la întârziere)" +Basic.Main.StoppingRecording="Se oprește înregistrarea..." +Basic.Main.StopStreaming="Oprește transmisiunea" +Basic.Main.StoppingStreaming="Se oprește transmisiunea..." +Basic.Main.ForceStopStreaming="Oprește transmisiunea (renunță la întârziere)" +Basic.Main.GroupItems="Grupează elementele selectate" +Basic.Main.Ungroup="Anulează grupul" Basic.MainMenu.File="&Fișier" Basic.MainMenu.File.Export="&Exportă" Basic.MainMenu.File.Import="&Importă" -Basic.MainMenu.File.ShowRecordings="Arată în®istrări" +Basic.MainMenu.File.ShowRecordings="Afișează în®istrările" Basic.MainMenu.File.Remux="Înregistrări re&mux" Basic.MainMenu.File.Settings="&Setări" -Basic.MainMenu.File.ShowSettingsFolder="Arată folderul cu setări" -Basic.MainMenu.File.ShowProfileFolder="Arată folderul cu profil" +Basic.MainMenu.File.ShowSettingsFolder="Afișează folderul cu setări" +Basic.MainMenu.File.ShowProfileFolder="Afișează folderul cu profiluri" Basic.MainMenu.AlwaysOnTop="Întotde&auna deasupra" Basic.MainMenu.File.Exit="Ieșire (&X)" @@ -342,127 +437,171 @@ Basic.MainMenu.Edit.Undo="An&ulează acțiunea" Basic.MainMenu.Edit.Redo="&Refă acțiunea" Basic.MainMenu.Edit.UndoAction="An&ulează $1" Basic.MainMenu.Edit.RedoAction="&Refă $1" +Basic.MainMenu.Edit.LockPreview="B&lochează previzualizarea" +Basic.MainMenu.Edit.Scale="Previzualizează &scalarea" +Basic.MainMenu.Edit.Scale.Window="Scalează la fereastră" +Basic.MainMenu.Edit.Scale.Canvas="Planșă (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformare" Basic.MainMenu.Edit.Transform.EditTransform="&Editează transformarea..." +Basic.MainMenu.Edit.Transform.CopyTransform="Copiază transformarea" +Basic.MainMenu.Edit.Transform.PasteTransform="Lipește transformarea" Basic.MainMenu.Edit.Transform.ResetTransform="&Resetează transformarea" Basic.MainMenu.Edit.Transform.Rotate90CW="Rotește la 90° (în sensul acelor ceasornicului)" Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotește la 90° (în sensul contrar acelor ceasornicului)" Basic.MainMenu.Edit.Transform.Rotate180="Rotește la 180°" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Răstoarnă &orizontal" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Răstoarnă orizontal (&H)" Basic.MainMenu.Edit.Transform.FlipVertical="Răstoarnă &vertical" -Basic.MainMenu.Edit.Transform.FitToScreen="&Potrivește pe ecran" -Basic.MainMenu.Edit.Transform.StretchToScreen="În&tinde pe ecran" +Basic.MainMenu.Edit.Transform.FitToScreen="Potrivește pe ecran (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Întinde pe ecran (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrează pe ecran" Basic.MainMenu.Edit.Order="&Ordonare" -Basic.MainMenu.Edit.Order.MoveUp="Mută &sus" -Basic.MainMenu.Edit.Order.MoveDown="Mută &jos" +Basic.MainMenu.Edit.Order.MoveUp="M&ută sus" +Basic.MainMenu.Edit.Order.MoveDown="Mută jos (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Mu&tă în vârf" -Basic.MainMenu.Edit.Order.MoveToBottom="Mută la fu&nd" +Basic.MainMenu.Edit.Order.MoveToBottom="Mută la fund (&B)" Basic.MainMenu.Edit.AdvAudio="Proprietăți audio &avansate" +Basic.MainMenu.View="&Vizualizare" +Basic.MainMenu.View.Toolbars="Bare de unel&te" +Basic.MainMenu.View.Docks="Andocare" +Basic.MainMenu.View.Docks.ResetUI="Resetează UI-ul" +Basic.MainMenu.View.Docks.LockUI="Blochează UI-ul" +Basic.MainMenu.View.Toolbars.Listboxes="Casete cu &liste" +Basic.MainMenu.View.SceneTransitions="Tranziții pentru s&cene" +Basic.MainMenu.View.StatusBar="Bară de &stare" +Basic.MainMenu.View.Fullscreen.Interface="Interfață în ecran complet" Basic.MainMenu.SceneCollection="Colecție de &scene" Basic.MainMenu.Profile="&Profil" -Basic.MainMenu.Profile.Import="Importă Profil" +Basic.MainMenu.Profile.Import="Importă profil" Basic.MainMenu.Profile.Export="Exportă profil" -Basic.MainMenu.Profile.Exists="Profilul deja există" +Basic.MainMenu.SceneCollection.Import="Importă colecție de scene" +Basic.MainMenu.SceneCollection.Export="Exportă colecție de scene" +Basic.MainMenu.Profile.Exists="Profilul există deja" +Basic.MainMenu.SceneCollection.Exists="Colecția de scene există deja" -Basic.MainMenu.Tools="&Unelte" +Basic.MainMenu.Tools="Unel&te" -Basic.MainMenu.Help="&Ajutor" +Basic.MainMenu.Help="Ajutor (&H)" +Basic.MainMenu.Help.HelpPortal="&Portalul de ajutor" Basic.MainMenu.Help.Website="Vizitează site-ul &web" +Basic.MainMenu.Help.Discord="Alătură-te serverului de &Discord" Basic.MainMenu.Help.Logs="Fișiere jurna&l" -Basic.MainMenu.Help.Logs.ShowLogs="Arată &fișierele jurnal" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Încărcaţi &fişierul de Log curent" -Basic.MainMenu.Help.Logs.UploadLastLog="Încărcaţi &ultimul fișier log" +Basic.MainMenu.Help.Logs.ShowLogs="Afișează fișierele jurnal (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="În&carcă actualul fişier jurnal" +Basic.MainMenu.Help.Logs.UploadLastLog="Încarcă u<imul fișier jurnal" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Vezi log-ul actual" Basic.MainMenu.Help.CheckForUpdates="Caută actualizări" +Basic.MainMenu.Help.CrashLogs="&Rapoarte de defecțiuni" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Afișează rapoartele de defecțiuni (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Încarcă u<imul raport de defecțiune" +Basic.MainMenu.Help.About="Despre (&A)" Basic.Settings.ProgramRestart="Programul trebuie repornit pentru ca aceste setări să aibă efect." Basic.Settings.ConfirmTitle="Confirmă modificările" -Basic.Settings.Confirm="Ai modificări nesalvate. Salvezi modificările?" +Basic.Settings.Confirm="Ai modificări nesalvate. Salvezi modificările?" Basic.Settings.General="Generale" Basic.Settings.General.Theme=" Temă" Basic.Settings.General.Language="Limbă" -Basic.Settings.General.WarnBeforeStartingStream="Arată dialog de confirmare când pornește streamul" -Basic.Settings.General.WarnBeforeStoppingStream="Arată dialog de confirmare când se oprește streamul" +Basic.Settings.General.EnableAutoUpdates="Caută automat actualizări la pornire" +Basic.Settings.General.OpenStatsOnStartup="Deschide dialogul cu statistici la pornire" +Basic.Settings.General.WarnBeforeStartingStream="Afișează dialog de confirmare când pornește transmisiunea" +Basic.Settings.General.WarnBeforeStoppingStream="Afișează dialog de confirmare când se oprește transmisiunea" +Basic.Settings.General.Projectors="Proiectoare" +Basic.Settings.General.HideProjectorCursor="Ascunde cursorul peste proiectoare" +Basic.Settings.General.ProjectorAlwaysOnTop="Pune proiectoarele mereu deasupra" Basic.Settings.General.Snapping="Alipire la alinierea cu sursa" Basic.Settings.General.ScreenSnapping="Aliniază sursele la marginea ecranului" Basic.Settings.General.CenterSnapping="Aliniază sursele la centrul vertical și orizontal" Basic.Settings.General.SourceSnapping="Aliniază sursele la alte surse" Basic.Settings.General.SnapDistance="Sensibilitatea alinierii" +Basic.Settings.General.RecordWhenStreaming="Înregistrează automat atunci când faci transmisiune" +Basic.Settings.General.KeepRecordingWhenStreamStops="Continuă înregistrarea când transmisiunea se oprește" +Basic.Settings.General.SysTray="Bară de sistem" +Basic.Settings.General.SysTrayWhenStarted="Minimizează în bara de sistem la pornire" +Basic.Settings.General.SystemTrayHideMinimize="Întotdeauna minimizează în bara de sistem în loc de bara de activități" +Basic.Settings.General.SaveProjectors="Salvează proiectoarele la ieșire" +Basic.Settings.General.Preview="Previzualizare" +Basic.Settings.General.SwitchOnDoubleClick="Efectuează tranziția către scenă la dublu clic" +Basic.Settings.General.Multiview.MouseSwitch="Efectuează clic pentru a comuta între scene" +Basic.Settings.General.Multiview.DrawSourceNames="Afișează numele scenelor" -Basic.Settings.Stream="Stream" -Basic.Settings.Stream.StreamType="Tipul streamului" +Basic.Settings.Stream="Transmisiune" +Basic.Settings.Stream.StreamType="Tipul transmisiunii" +Basic.Settings.Stream.BandwidthTestMode="Activează modul de testare a lățimii de bandă" Basic.Settings.Output="Ieșire" Basic.Settings.Output.Format="Format de înregistrare" Basic.Settings.Output.Encoder="Codificator" -Basic.Settings.Output.SelectDirectory="Selectează folderul de înregistrări" -Basic.Settings.Output.SelectFile="Selectează fișierul de înregistrări" -Basic.Settings.Output.EnforceBitrate="Forțează limitele ratei de biți pentru streaming" +Basic.Settings.Output.SelectDirectory="Selectează directorul de înregistrări" +Basic.Settings.Output.SelectFile="Selectează fișierul înregistrării" +Basic.Settings.Output.EnforceBitrate="Impune limitele ratei de biți pentru serviciul de transmisiune" Basic.Settings.Output.Mode="Mod de ieșire" Basic.Settings.Output.Mode.Simple="Simplu" Basic.Settings.Output.Mode.Adv="Avansat" Basic.Settings.Output.Mode.FFmpeg="Ieșire FFmpeg" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Memorie maximă (megabyți)" Basic.Settings.Output.ReplayBuffer.Estimate="Utilizare estimată a memoriei: %1 MB" Basic.Settings.Output.ReplayBuffer.Suffix="Sufix" Basic.Settings.Output.Simple.SavePath="Cale de înregistrare" Basic.Settings.Output.Simple.RecordingQuality="Calitatea înregistrării" Basic.Settings.Output.Simple.RecordingQuality.Stream="La fel cu cea a streamului" -Basic.Settings.Output.Simple.RecordingQuality.Small="Calitate înaltă, dimensiune medie a fișierului" -Basic.Settings.Output.Simple.RecordingQuality.HQ="Calitate imposibil de distins, Marime mare" -Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calitate lossless, dimensiune extrem de mare a fișierelor" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Atentie: Bitrate-ul pentru video stream va fi setat la %1, care este limita superioară pentru serviciul de streaming actual. Dacă sunteţi sigur că doriţi să depasiţi %1, permiteţi opțiuni codare avansate şi debifaţi \"Forteaza limite de bitrate pentru stream\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Atentie: Bitrate-ul pentru audio stream va fi setat la %1, care este limita superioară pentru serviciul de streaming actual. Dacă sunteţi sigur că doriţi să depasiţi %1, permiteţi opțiuni codare avansate şi debifaţi \"Forteaza limite de bitrate pentru stream\"." -Basic.Settings.Output.Simple.Warn.Encoder="Atenție: Înregistrarea cu un encoder software la o calitate diferită decât stream-ul va necesita o utilizare CPU crescută dacă faci stream şi înregistrezi în acelaşi timp." -Basic.Settings.Output.Simple.Warn.Lossless="Avertisment: Calitatea lossless generează dimensiuni extrem de mari de fișiere! Calitatea lossless poate utiliza până la 7GB spațiu de disc per minut la frecvențe de cadre și rezoluții ridicate. Lossless nu este recomandat pentru înregistrări lungi decât dacă ai o cantitate foarte mare de spațiu disponibil pe disc." -Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sigur dorești să folosești calitatea lossless?" +Basic.Settings.Output.Simple.RecordingQuality.Small="Calitate înaltă, dimensiune medie pentru fișiere" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Calitate imposibil de distins, dimensiune mare pentru fișiere" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="Calitate lossless, dimensiune extrem de mare pentru fișiere" +Basic.Settings.Output.Simple.Warn.VideoBitrate="Avertisment: Rata de biți a transmisiei video va fi setată la %1, care este limita superioară pentru serviciul de transmisiune actual. Dacă ești sigur că vrei să depășești %1, activează opțiunile avansate ale codificatorului și debifează „Impune limitele ratei de biți pentru serviciul de transmisiune”." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Avertisment: Rata de biți a transmisiei audio va fi setată la %1, care este limita superioară pentru serviciul de transmisiune actual. Dacă ești sigur că vrei să depășești %1, activează opțiunile avansate ale codificatorului și debifează „Impune limitele ratei de biți pentru serviciul de transmisiune”." +Basic.Settings.Output.Simple.Warn.Encoder="Avertisment: Înregistrarea cu un codificator software la o calitate diferită de cea a transmisiunii va necesita o utilizare CPU crescută dacă transmiți şi înregistrezi în același timp." +Basic.Settings.Output.Simple.Warn.Lossless="Avertisment: Calitatea lossless generează dimensiuni extrem de mari de fișiere! Calitatea lossless poate folosi până la 7GB spațiu de disc per minut la frecvențe de cadre și rezoluții ridicate. Lossless nu este recomandat pentru înregistrări lungi decât dacă ai o cantitate foarte mare de spațiu disponibil pe disc." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sigur vrei să folosești calitatea lossless?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Avertizare privind calitatea lossless!" Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardware (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (presetare x264 cu utilizare scăzută de CPU, crește dimensiunea fișierului)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Software (presetare x264 cu utilizare CPU scăzută, crește dimensiunea pentru fișiere)" Basic.Settings.Output.VideoBitrate="Rată de biți video" Basic.Settings.Output.AudioBitrate="Rată de biți audio" Basic.Settings.Output.Reconnect="Reconectare automată" Basic.Settings.Output.RetryDelay="Întârziere pentru reîncercare (secunde)" -Basic.Settings.Output.MaxRetries="Încercări maxime" +Basic.Settings.Output.MaxRetries="Reîncercări maxime" Basic.Settings.Output.Advanced="Activează setările avansate ale codificatorului" -Basic.Settings.Output.EncoderPreset="Presetare a codificatorului (mai mare = mai puțin CPU)" -Basic.Settings.Output.CustomEncoderSettings="Setări particularizate ale codificatorului" -Basic.Settings.Output.CustomMuxerSettings="Setări particularizate ale muxerului" -Basic.Settings.Output.NoSpaceFileName="Generează nume de fișier fără spațiu" +Basic.Settings.Output.EncoderPreset="Presetare pentru codificator" +Basic.Settings.Output.CustomEncoderSettings="Setări personalizate pentru codificator" +Basic.Settings.Output.CustomMuxerSettings="Setări personalizate pentru muxer" +Basic.Settings.Output.NoSpaceFileName="Generează nume de fișiere fără spațiu" Basic.Settings.Output.Adv.Rescale="Rescalează ieșirea" Basic.Settings.Output.Adv.AudioTrack="Pistă audio" -Basic.Settings.Output.Adv.Streaming="Streaming" -Basic.Settings.Output.Adv.ApplyServiceSettings="Aplică setările codificatorului pentru serviciul de streaming" +Basic.Settings.Output.Adv.Streaming="Transmisiune" +Basic.Settings.Output.Adv.ApplyServiceSettings="Impune setările codificatorului pentru serviciul de transmisiune" Basic.Settings.Output.Adv.Audio.Track1="Pistă 1" Basic.Settings.Output.Adv.Audio.Track2="Pistă 2" Basic.Settings.Output.Adv.Audio.Track3="Pistă 3" Basic.Settings.Output.Adv.Audio.Track4="Pistă 4" +Basic.Settings.Output.Adv.Audio.Track5="Pistă 5" +Basic.Settings.Output.Adv.Audio.Track6="Pistă 6" Basic.Settings.Output.Adv.Recording="Înregistrare" Basic.Settings.Output.Adv.Recording.Type="Tip" Basic.Settings.Output.Adv.Recording.Type.Standard="Standard" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Ieșire personalizată (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Folosește codificatorul de stream)" -Basic.Settings.Output.Adv.Recording.Filename="Formatarea numelui de fișier" -Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Suprascrie dacă fișierul există" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Folosește codificatorul de transmisiune)" +Basic.Settings.Output.Adv.Recording.Filename="Formatarea numelui pentru fișiere" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Suprascrie în cazul în care fișierul există" Basic.Settings.Output.Adv.FFmpeg.Type="Tipul ieșirii FFmpeg" Basic.Settings.Output.Adv.FFmpeg.Type.URL="Ieșire spre URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="Ieșire spre fișier" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="Formate comune de înregistrare" Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="Toate fișierele" Basic.Settings.Output.Adv.FFmpeg.SavePathURL="Calea fișierului sau URL-ul" -Basic.Settings.Output.Adv.FFmpeg.Format="Format container" +Basic.Settings.Output.Adv.FFmpeg.Format="Format pentru container" Basic.Settings.Output.Adv.FFmpeg.FormatAudio="Audio" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="Video" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="Format implicit" -Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descriere Format Recipient" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Codecul Audio/Video ghicit din calea fisierului sau URL-ul" +Basic.Settings.Output.Adv.FFmpeg.FormatDesc="Descriere pentru formatul containerului" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="Codecul audio/video ghicit din calea fișierului sau URL" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="Codificator implicit" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="Dezactivează codificatorul" Basic.Settings.Output.Adv.FFmpeg.VEncoder="Codificator video" @@ -470,6 +609,7 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Setările codificatorului vid Basic.Settings.Output.Adv.FFmpeg.AEncoder="Codificator audio" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Setările codificatorului audio (dacă există)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Setările muxerului (dacă există)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Interval de cadre cheie (cadre)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" @@ -477,10 +617,10 @@ FilenameFormatting.TT="%CCYY An, patru cifre\n%YY An, ultimele 2 cifre (00-99) Basic.Settings.Video="Video" Basic.Settings.Video.Adapter="Adaptor video" -Basic.Settings.Video.BaseResolution="Rezoluție (canvas) de bază" +Basic.Settings.Video.BaseResolution="Rezoluție (planșă) de bază" Basic.Settings.Video.ScaledResolution="Rezoluție (scalată) la ieșire" Basic.Settings.Video.DownscaleFilter="Filtru pentru descalare" -Basic.Settings.Video.DisableAeroWindows="Dezactivează Aero (Numai Windows)" +Basic.Settings.Video.DisableAeroWindows="Dezactivează Aero (numai Windows)" Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Valori FPS comune" Basic.Settings.Video.FPSInteger="Valoare cu număr întreg pentru FPS" @@ -488,8 +628,8 @@ Basic.Settings.Video.FPSFraction="Valoare FPS fracționată" Basic.Settings.Video.Numerator="Numărător" Basic.Settings.Video.Denominator="Numitor" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Valoare rezoluţie invalidă. Trebuie să fie [latime]x[înălţime] (de exemplu, 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Ieşirea video este în prezent activă. Vă rugăm să opriţi orice ieşiri pentru a schimba setările video." +Basic.Settings.Video.InvalidResolution="Valoare invalidă pentru rezoluție. Trebuie să fie [lățime]x[înălțime] (de ex., 1920x1080)" +Basic.Settings.Video.CurrentlyActive="Ieşirea video este în prezent activă. Vă rugăm să opriţi orice ieşiri pentru a schimba setările video." Basic.Settings.Video.DisableAero="Dezactivează Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Biliniar (Cel mai rapid, dar neclar în cazul scalării)" @@ -499,48 +639,57 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Scalare ascuțită, 32 de Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Rată de eșantionare" Basic.Settings.Audio.Channels="Canale" -Basic.Settings.Audio.DesktopDevice="Dispozitiv audio desktop" -Basic.Settings.Audio.DesktopDevice2="Dispozitiv audio desktop 2" -Basic.Settings.Audio.AuxDevice="Dispozitiv audio microfon/auxiliar" -Basic.Settings.Audio.AuxDevice2="Dispozitiv audio microfon/auxiliar 2" -Basic.Settings.Audio.AuxDevice3="Dispozitiv audio microfon/auxiliar 3" -Basic.Settings.Audio.EnablePushToMute="Pornește push-to-mute" -Basic.Settings.Audio.PushToMuteDelay="Întârziere push-to-mute" +Basic.Settings.Audio.MeterDecayRate.Fast="Rapidă" +Basic.Settings.Audio.MeterDecayRate.Medium="Medie (Type I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Lentă (Type II PPM)" +Basic.Settings.Audio.DesktopDevice="Audio desktop" +Basic.Settings.Audio.DesktopDevice2="Audio desktop 2" +Basic.Settings.Audio.EnablePushToMute="Activează push-to-mute" +Basic.Settings.Audio.PushToMuteDelay="Întârziere la push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Activează push-to-talk" -Basic.Settings.Audio.PushToTalkDelay="Întârziere push-to-talk" -Basic.Settings.Audio.UnknownAudioDevice="[Dispozitivul nu este disponibil sau nu este conectat]" +Basic.Settings.Audio.PushToTalkDelay="Întârziere la push-to-talk" +Basic.Settings.Audio.UnknownAudioDevice="[Dispozitiv neconectat sau indisponibil]" +Basic.Settings.Audio.Disabled="Dezactivat" Basic.Settings.Advanced="Avansate" -Basic.Settings.Advanced.General.ProcessPriority="Prioritate Proces" +Basic.Settings.Advanced.General.ProcessPriority="Prioritatea procesului" Basic.Settings.Advanced.General.ProcessPriority.High="Ridicată" -Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Peste Normal" +Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Peste normal" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normală" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Sub normal" Basic.Settings.Advanced.General.ProcessPriority.Idle="Inactiv" Basic.Settings.Advanced.FormatWarning="Atentie: Formatele de culori diferite de NV12 sunt facute pentru inregistrare si nu sunt recomandate in cazul streaming-ului. Streaming-ul e posibil sa ceara mai multe resurse CPU datorita conversiei formatului culorii." -Basic.Settings.Advanced.Audio.BufferingTime="Timp de buffering pentru audio" -Basic.Settings.Advanced.Video.ColorFormat="Format de culoare" -Basic.Settings.Advanced.Video.ColorSpace="Spațiu de culori YUV" -Basic.Settings.Advanced.Video.ColorRange="Gamă de culori YUV" +Basic.Settings.Advanced.Audio.BufferingTime="Timp pentru zona tampon audio" +Basic.Settings.Advanced.Video.ColorFormat="Format de culori" Basic.Settings.Advanced.Video.ColorRange.Partial="Parțială" Basic.Settings.Advanced.Video.ColorRange.Full="Completă" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Implicit" -Basic.Settings.Advanced.StreamDelay="Întârziere pentru stream" +Basic.Settings.Advanced.StreamDelay="Întârziere pentru transmisiune" Basic.Settings.Advanced.StreamDelay.Duration="Durată (secunde)" Basic.Settings.Advanced.StreamDelay.Preserve="Păstrează punctul de tăiere (crește întârzierea) la reconectare" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Utilizare estimată a memoriei: %1 MB" Basic.Settings.Advanced.Network="Rețea" Basic.Settings.Advanced.Network.BindToIP="Leagă de IP" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="Activează noul cod pentru rețea" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mod de latență redusă" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Dezactivează tastele rapide când fereastra principală este în prim-plan" +Basic.Settings.Advanced.AutoRemux="Remuxează automat în mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(înregistrează ca mkv)" Basic.AdvAudio="Proprietăți audio avansate" Basic.AdvAudio.Name="Nume" -Basic.AdvAudio.Volume="Volum (%)" Basic.AdvAudio.Mono="Transformă în mono" -Basic.AdvAudio.Panning="Panning" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Decalajul sincronizării (ms)" +Basic.AdvAudio.Monitoring="Monitorizare audio" +Basic.AdvAudio.Monitoring.None="Monitorizare dezactivată" +Basic.AdvAudio.Monitoring.MonitorOnly="Numai monitorizare (amuțește ieșirea)" +Basic.AdvAudio.Monitoring.Both="Monitorizare și ieșire" Basic.AdvAudio.AudioTracks="Piste" Basic.Settings.Hotkeys="Taste rapide" Basic.Settings.Hotkeys.Pair="Combinațiile de taste partajate cu '%1' acționează ca comutatoare" +Basic.Settings.Hotkeys.Filter="Filtrează" Basic.Hotkeys.SelectScene="Comută la scenă" @@ -570,7 +719,7 @@ Hotkeys.Windows="Windows" Hotkeys.Super="Super" Hotkeys.Menu="Meniu" Hotkeys.Space="Space" -Hotkeys.NumpadNum="Numpad %1" +Hotkeys.NumpadNum="Tasta numerică %1" Hotkeys.NumpadMultiply="Numpad Multiplica" Hotkeys.NumpadDivide="Numpad Divide" Hotkeys.NumpadAdd="Numpad Aduna" @@ -590,14 +739,27 @@ Unmute="Scoate de pe mut" Push-to-mute="Push-to-mute" Push-to-talk="Push-to-talk" -SceneItemShow="Arată „%1”" -SceneItemHide="Ascunde „%1”" +SceneItemShow="Afișează '%1'" +SceneItemHide="Ascunde '%1'" OutputWarnings.NoTracksSelected="Trebuie să selectezi cel puțin o pistă" OutputWarnings.MultiTrackRecording="Atenție: Anumite formate (precum FLV) nu suportă multiple piste per înregistrare" +FinalScene.Title="Șterge scena" FinalScene.Text="Trebuie să existe cel puțin o scenă." +ChangeBG="Setează culoarea" + +BrowserSource.EnableHardwareAcceleration="Activează accelerarea hardware pentru Browser Source" + +About="Despre" +About.Info="OBS Studio este un program gratuit și cu sursă deschisă de înregistrare video și transmisiune live." +About.Donate="Contribuie" +About.GetInvolved="Implică-te" +About.Authors="Autori" +About.License="Licență" +About.Contribute="Sprijină proiectul OBS" + diff --git a/UI/data/locale/ru-RU.ini b/UI/data/locale/ru-RU.ini index cb2a1a7..61e686c 100644 --- a/UI/data/locale/ru-RU.ini +++ b/UI/data/locale/ru-RU.ini @@ -80,14 +80,40 @@ StudioMode.Program="Программа" ShowInMultiview="Отображать в Мульти-обзоре" VerticalLayout="Вертикальное расположение" Group="Группа" +DoNotShowAgain="Не показывать снова" +Default="(По умолчанию)" +Calculating="Расчёт..." AlreadyRunning.Title="OBS уже запущен" AlreadyRunning.Text="OBS уже запущен! Пожалуйста, закройте все запущенные экземпляры OBS перед попыткой запустить новые (только если вы не хотели именно этого). Если вы настроили OBS на сворачивание в системный трей, пожалуйста, проверьте, возможно он до сих пор запущен." AlreadyRunning.LaunchAnyway="Запустить в любом случае" +DockCloseWarning.Title="Закрытие закрепляемого окна" +DockCloseWarning.Text="Вы только что закрыли закрепляемое окно. Если вы хотите показать его снова, используйте меню Вид → Док-панели в строке меню." + +Auth.Authing.Title="Аутентификация..." +Auth.Authing.Text="Аутентификация с %1, пожалуйста подождите..." +Auth.AuthFailure.Title="Ошибка аутентификации" +Auth.AuthFailure.Text="Ошибка аутентификации с %1:\n\n%2: %3" +Auth.InvalidScope.Title="Требуется аутентификация" +Auth.InvalidScope.Text="Требования к аутентификации для %1 изменились. Некоторые функции могут быть недоступны." +Auth.LoadingChannel.Title="Загрузка информации о канале..." +Auth.LoadingChannel.Text="Загрузка информации о канале для %1, пожалуйста подождите..." +Auth.ChannelFailure.Title="Не удалось загрузить канал" +Auth.ChannelFailure.Text="Не удалось загрузить информацию о канале для %1\n\n%2: %3" +Auth.Chat="Чат" +Auth.StreamInfo="Информация о трансляции" +TwitchAuth.Stats="Статистика Twitch" +TwitchAuth.Feed="Лента активности Twitch" +TwitchAuth.TwoFactorFail.Title="Не удалось запросить ключ трансляции" +TwitchAuth.TwoFactorFail.Text="Невозможно подключиться к учётной записи Twitch. Пожалуйста, убедитесь, что в настройках безопасности включена и настроена двухфакторная аутентификация." + Copy.Filters="Копировать фильтры" Paste.Filters="Вставить фильтры" +BrowserPanelInit.Title="Инициализация браузера..." +BrowserPanelInit.Text="Инициализация браузера, пожалуйста подождите..." + BandwidthTest.Region="Регион" BandwidthTest.Region.US="США" BandwidthTest.Region.EU="Европа" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Азия" BandwidthTest.Region.Other="Другой" Basic.FirstStartup.RunWizard="Хотите ли вы запустить Мастер автоматической настройки? Вы также можете настроить параметры вручную, нажав кнопку Настройки в главном окне." -Basic.FirstStartup.RunWizard.BetaWarning="(Примечание: Мастер автоматической настройки в настоящее время в бета-версии)" Basic.FirstStartup.RunWizard.NoClicked="Если вы передумаете, то в любой момент сможете запустить Мастер автоматической настройки из пункта меню Инструменты." Basic.AutoConfig="Мастер автоматической настройки" -Basic.AutoConfig.Beta="Мастер автоматической настройки (Бета)" Basic.AutoConfig.ApplySettings="Применить настройки" Basic.AutoConfig.StartPage="Информация об использовании" Basic.AutoConfig.StartPage.SubTitle="Укажите, для чего вы хотите использовать программу" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 или 30, но предпоч Basic.AutoConfig.VideoPage.CanvasExplanation="Примечание: Разрешение холста (базовое), не обязательно должно совпадать с разрешением трансляции или записи. Реальное разрешение вашей трансляции/записи может быть снижено для уменьшения использования ресурсов или битрейта." Basic.AutoConfig.StreamPage="Информация о трансляции" Basic.AutoConfig.StreamPage.SubTitle="Пожалуйста, введите вашу информацию о трансляциях" +Basic.AutoConfig.StreamPage.ConnectAccount="Подключить аккаунт (необязательно)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Отключить аккаунт" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Отключить аккаунт?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Это изменение вступит в силу немедленно. Вы уверены, что хотите отключить ваш аккаунт?" +Basic.AutoConfig.StreamPage.UseStreamKey="Использовать ключ потока" Basic.AutoConfig.StreamPage.Service="Сервис" Basic.AutoConfig.StreamPage.Service.ShowAll="Показать все..." +Basic.AutoConfig.StreamPage.Service.Custom="Настраиваемый..." Basic.AutoConfig.StreamPage.Server="Сервер" Basic.AutoConfig.StreamPage.StreamKey="Ключ потока" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Ссылка)" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="Неактивна" Basic.Stats.DroppedFrames="Пропущенные кадры (Сеть)" Basic.Stats.MegabytesSent="Данных отправлено" Basic.Stats.Bitrate="Битрейт" +Basic.Stats.DiskFullIn="Диск заполнится (около)" + +ResetUIWarning.Title="Вы уверены, что хотите сбросить пользовательский интерфейс?" +ResetUIWarning.Text="Сброс пользовательского интерфейса скроет дополнительные док-панели. Если вы хотите чтобы эти панели были видимыми, вам нужно будет отметить их в меню Вид.\n\nВы уверены, что хотите сбросить пользовательский интерфейс?" Updater.Title="Доступно обновление" Updater.Text="Доступно новое обновление:" @@ -206,6 +240,9 @@ ConfirmStart.Text="Вы уверены, что хотите начать тра ConfirmStop.Title="Остановить трансляцию?" ConfirmStop.Text="Вы уверены, что хотите остановить трансляцию?" +ConfirmBWTest.Title="Начать тест пропускной способности?" +ConfirmBWTest.Text="Вы настроили OBS в режиме тестирования пропускной способности. Этот режим позволяет тестировать сеть без выхода вашего канала в эфир. После того, как вы закончите тестирование, вам необходимо выключить эту функцию для того чтобы зрители могли видеть вашу трансляцию.\n\nВы хотите продолжить?" + ConfirmExit.Title="Выйти из OBS?" ConfirmExit.Text="В настоящее время OBS активен. Все потоки/записи будут выключены. Вы уверены, что хотите выйти?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="Не удалось начать запись" Output.StartReplayFailed="Не удалось запустить воспроизведение из буфера" Output.StartFailedGeneric="Сбой вывода. Подробности отражены в журнале.\n\nПримечание: Если вы используете кодировщики NVENC или AMD, убедитесь что у вас установлена последняя версия видеорайвера." + Output.ConnectFail.Title="Не удалось подключиться" Output.ConnectFail.BadPath="Неверный путь или URL соединения. Пожалуйста, проверьте настройки, чтобы подтвердить, что они являются действительными." Output.ConnectFail.ConnectFailed="Не удалось подключиться к серверу" @@ -225,41 +263,43 @@ Output.ConnectFail.InvalidStream="Не удалось получить дост Output.ConnectFail.Error="Произошла непредвиденная ошибка при попытке подключиться к серверу. Более подробная информация в лог-файле." Output.ConnectFail.Disconnected="Отключен от сервера." +Output.StreamEncodeError.Title="Ошибка кодирования" +Output.StreamEncodeError.Msg="Произошла ошибка кодировщика во время трансляции." + Output.RecordFail.Title="Не удалось начать запись" Output.RecordFail.Unsupported="Выходной формат либо не поддерживается, либо не поддерживает более одной звуковой дорожки. Пожалуйста, проверьте настройки и повторите попытку." Output.RecordNoSpace.Title="Недостаточно места на диске" Output.RecordNoSpace.Msg="На диске недостаточно места для продолжения записи." Output.RecordError.Title="Ошибка записи" Output.RecordError.Msg="Во время записи произошла неопознанная ошибка." +Output.RecordError.EncodeErrorMsg="Произошла ошибка кодировщика во время записи." Output.ReplayBuffer.NoHotkey.Title="Нет набора горячих клавиш!" Output.ReplayBuffer.NoHotkey.Msg="Не установлено клавиши для сохранения повтора. Пожалуйста, установите горячую клавишу для сохранения записей повторов." Output.BadPath.Title="Неправильный путь к файлу" -Output.BadPath.Text="Некорректный путь к файлу. Пожалуйста, проверьте настройки, чтобы убедиться в корректности установленного пути." +Output.BadPath.Text="Некорректный путь к файлу. Пожалуйста, проверьте настройки, чтобы убедиться в корректности установленного пути." LogReturnDialog="Log загружен успешно" LogReturnDialog.CopyURL="Скопировать URL" LogReturnDialog.ErrorUploadingLog="Ошибка загрузки log файла" -LicenseAgreement="Лицензионное соглашение" -LicenseAgreement.PleaseReview="Пожалуйста, ознакомьтесь с условиями лицензионного соглашения перед использованием OBS. Используя эту программу, вы признаете, что прочитали и согласны с условиями лицензии GNU General Public License v2.0. Пожалуйста, прокрутите вниз, чтобы увидеть оставшуюся часть соглашения." -LicenseAgreement.ClickIAgreeToContinue="Если вы принимаете условия соглашения, нажмите \"Принимаю\", чтобы продолжить. Вы должны принять соглашение, чтобы использовать OBS." -LicenseAgreement.IAgree="Принимаю" -LicenseAgreement.Exit="Выход" - Remux.SourceFile="OBS Запись" Remux.TargetFile="Конечный файл" Remux.Remux="Ремультиплексирование" +Remux.Stop="Остановить ремультиплексирование" +Remux.ClearFinished="Очистить завершённые элементы" +Remux.ClearAll="Очистить все элементы" Remux.OBSRecording="OBS Запись" Remux.FinishedTitle="Ремультиплексирование завершено" Remux.Finished="Запись ремультиплексирована" Remux.FinishedError="Запись ремультиплексирована, но файл может быть неполон" -Remux.SelectRecording="Выбрать OBS запись …" -Remux.SelectTarget="Выбрать конечный файл …" -Remux.FileExistsTitle="Конечный файл существует" -Remux.FileExists="Конечный файл уже существует, хотите заменить его?" +Remux.SelectRecording="Выберите запись OBS..." +Remux.SelectTarget="Выберите целевой файл..." +Remux.FileExistsTitle="Конечные файлы существуют" +Remux.FileExists="Следующие конечные файлы уже существуют. Хотите их заменить?" Remux.ExitUnfinishedTitle="Ремультиплексирование в процессе" Remux.ExitUnfinished="Ремультиплексирование не закончено, остановка процесса сейчас может сделать файл непригодным.\nВы уверены, что хотите остановить ремультиплексирование?" +Remux.HelpText="Перетащите файлы в это окно для ремультиплексирования или выберите пустую ячейку \"OBS Запись\" для выбора файла." UpdateAvailable="Доступно новое обновление" UpdateAvailable.Text="Доступна версия %1.%2.%3. Нажмите сюда, чтобы скачать" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Захват экрана" Basic.Main.PreviewConextMenu.Enable="Включить предпросмотр" +Basic.Main.Preview.Disable="Отключить предпросмотр" + ScaleFiltering="Фильтр масштабирования" ScaleFiltering.Point="Точечный" ScaleFiltering.Bilinear="Билинейный" ScaleFiltering.Bicubic="Бикубический" ScaleFiltering.Lanczos="Метод Ланцоша" +ScaleFiltering.Area="Область экрана" Deinterlacing="Устранение чересстрочности" Deinterlacing.Discard="Отклонить" @@ -411,59 +454,61 @@ Basic.Main.Group="Группа %1" Basic.Main.GroupItems="Сгруппировать выбранные элементы" Basic.Main.Ungroup="Разгруппировать" -Basic.MainMenu.File="&Файл" -Basic.MainMenu.File.Export="&Экспорт" -Basic.MainMenu.File.Import="&Импорт" -Basic.MainMenu.File.ShowRecordings="Показать &записи" -Basic.MainMenu.File.Remux="Ре&мультиплексирование записей" -Basic.MainMenu.File.Settings="&Настройки" +Basic.MainMenu.File="Файл (&F)" +Basic.MainMenu.File.Export="Экспорт (&E)" +Basic.MainMenu.File.Import="Импорт (&I)" +Basic.MainMenu.File.ShowRecordings="Показать записи (&R)" +Basic.MainMenu.File.Remux="Ремультиплексирование записей (&M)" +Basic.MainMenu.File.Settings="Настройки (&S)" Basic.MainMenu.File.ShowSettingsFolder="Показать папку с настройками" Basic.MainMenu.File.ShowProfileFolder="Показать папку с профилями" -Basic.MainMenu.AlwaysOnTop="&Поверх других окон" -Basic.MainMenu.File.Exit="&Выход" +Basic.MainMenu.AlwaysOnTop="Поверх других окон (&A)" +Basic.MainMenu.File.Exit="Выход (&X)" -Basic.MainMenu.Edit="&Редактировать" -Basic.MainMenu.Edit.Undo="&Отменить" -Basic.MainMenu.Edit.Redo="&Повторить" -Basic.MainMenu.Edit.UndoAction="&Отменить $1" -Basic.MainMenu.Edit.RedoAction="&Повторить $1" -Basic.MainMenu.Edit.LockPreview="&Заблокировать предпросмотр" -Basic.MainMenu.Edit.Scale="&Масштабирование предпросмотра" +Basic.MainMenu.Edit="Правка (&E)" +Basic.MainMenu.Edit.Undo="Отменить (&U)" +Basic.MainMenu.Edit.Redo="Повторить (&R)" +Basic.MainMenu.Edit.UndoAction="Отменить $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Повторить $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Заблокировать предпросмотр (&L)" +Basic.MainMenu.Edit.Scale="Масштабирование предпросмотра (&S)" Basic.MainMenu.Edit.Scale.Window="Масштаб окна" Basic.MainMenu.Edit.Scale.Canvas="Холст (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Вывод (%1x%2)" -Basic.MainMenu.Edit.Transform="&Трансформировать" -Basic.MainMenu.Edit.Transform.EditTransform="&Изменить отображение..." +Basic.MainMenu.Edit.Transform="Трансформировать (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Изменить отображение... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Скопировать трансформацию" Basic.MainMenu.Edit.Transform.PasteTransform="Вставить трансформацию" -Basic.MainMenu.Edit.Transform.ResetTransform="&Сбросить трансформацию" +Basic.MainMenu.Edit.Transform.ResetTransform="Сбросить трансформацию (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Повернуть на 90 градусов по часовой" Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернуть на 90 градусов против часовой" Basic.MainMenu.Edit.Transform.Rotate180="Повернуть на 180 градусов" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Отразить горизонтально" -Basic.MainMenu.Edit.Transform.FlipVertical="Отразить вертикально" -Basic.MainMenu.Edit.Transform.FitToScreen="&Подогнать по размеру экрана" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Растянуть на весь экран" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Разместить по центру экрана" -Basic.MainMenu.Edit.Order="&Порядок" -Basic.MainMenu.Edit.Order.MoveUp="Переместить &выше" -Basic.MainMenu.Edit.Order.MoveDown="Переместить &Ниже" -Basic.MainMenu.Edit.Order.MoveToTop="Переместить &Наверх" -Basic.MainMenu.Edit.Order.MoveToBottom="Переместить &Вниз" -Basic.MainMenu.Edit.AdvAudio="&Расширенные свойства аудио" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Отразить горизонтально (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Отразить вертикально (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Подогнать по размеру экрана (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Растянуть на весь экран (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Разместить по центру экрана (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Выровнять по вертикали" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Выровнять по горизонтали" +Basic.MainMenu.Edit.Order="Порядок (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Переместить выше (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Переместить ниже (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Переместить наверх (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Переместить вниз (&B)" +Basic.MainMenu.Edit.AdvAudio="Расширенные свойства аудио (&A)" -Basic.MainMenu.View="&Вид" -Basic.MainMenu.View.Toolbars="&Панель инструментов" +Basic.MainMenu.View="Вид (&V)" +Basic.MainMenu.View.Toolbars="Панель инструментов (&T)" Basic.MainMenu.View.Docks="Док-панели" Basic.MainMenu.View.Docks.ResetUI="Сбросить интерфейс" Basic.MainMenu.View.Docks.LockUI="Зафиксировать интерфейс" -Basic.MainMenu.View.Toolbars.Listboxes="&Списки" -Basic.MainMenu.View.SceneTransitions="Сцена переходов" -Basic.MainMenu.View.StatusBar="&Строка состояния" +Basic.MainMenu.View.Toolbars.Listboxes="Списки (&L)" +Basic.MainMenu.View.SceneTransitions="Сцена переходов (&C)" +Basic.MainMenu.View.StatusBar="Строка состояния (&S)" Basic.MainMenu.View.Fullscreen.Interface="Полный экран" -Basic.MainMenu.SceneCollection="Коллекция сцен" -Basic.MainMenu.Profile="Профиль" +Basic.MainMenu.SceneCollection="Коллекция сцен (&S)" +Basic.MainMenu.Profile="Профиль (&P)" Basic.MainMenu.Profile.Import="Импортировать профиль" Basic.MainMenu.Profile.Export="Экспортировать профиль" Basic.MainMenu.SceneCollection.Import="Импортировать коллекцию сцен" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Экспортировать коллек Basic.MainMenu.Profile.Exists="Профиль уже существует" Basic.MainMenu.SceneCollection.Exists="Коллекция сцен уже существует" -Basic.MainMenu.Tools="&Инструменты" +Basic.MainMenu.Tools="Инструменты (&T)" -Basic.MainMenu.Help="&Справка" -Basic.MainMenu.Help.HelpPortal="&Портал помощи" -Basic.MainMenu.Help.Website="Посетить &веб-сайт" +Basic.MainMenu.Help="Справка (&H)" +Basic.MainMenu.Help.HelpPortal="Портал помощи (&P)" +Basic.MainMenu.Help.Website="Посетить веб-сайт (&W)" Basic.MainMenu.Help.Discord="Зайти на сервер &Discord" Basic.MainMenu.Help.Logs="&Log файлы" -Basic.MainMenu.Help.Logs.ShowLogs="&Показать лог-файлы" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Загрузить &текущий Log файл" -Basic.MainMenu.Help.Logs.UploadLastLog="Загрузить &последний Log файл" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Просмотреть текущий журнал" +Basic.MainMenu.Help.Logs.ShowLogs="Показать лог-файлы (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Загрузить текущий Log файл (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Загрузить последний &Log файл" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Просмотреть текущий журнал (&V)" Basic.MainMenu.Help.CheckForUpdates="Проверить наличие обновлений" -Basic.MainMenu.Help.CrashLogs="&Отчёты об ошибках" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Показать отчёты об ошибках" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Загрузить последний отчёт об ошибке" +Basic.MainMenu.Help.CrashLogs="Отчёты об ошибках (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Показать отчёты об ошибках (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Загрузить последний отчёт об ошибке (&L)" +Basic.MainMenu.Help.About="О программе (&A)" Basic.Settings.ProgramRestart="Для изменения этих параметров требуется перезапустить программу." Basic.Settings.ConfirmTitle="Подтверждить Изменения" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Системный трей" Basic.Settings.General.SysTrayWhenStarted="Скрывать окно в системный трей при запуске" Basic.Settings.General.SystemTrayHideMinimize="Всегда сворачивать в трей вместо панели задач" Basic.Settings.General.SaveProjectors="Сохранять проекторы при выходе" +Basic.Settings.General.Preview="Предпросмотр" +Basic.Settings.General.OverflowHidden="Скрыть переполнение" +Basic.Settings.General.OverflowAlwaysVisible="Переполнение всегда видно" +Basic.Settings.General.OverflowSelectionHidden="Показывать переполнение даже когда источник невидим" Basic.Settings.General.SwitchOnDoubleClick="Переход к сцене при двойном щелчке" Basic.Settings.General.StudioPortraitLayout="Включить портретное/вертикальное расположение" +Basic.Settings.General.TogglePreviewProgramLabels="Показывать отметки предпросмотра/программы" Basic.Settings.General.Multiview="Мульти-обзор" Basic.Settings.General.Multiview.MouseSwitch="Переключение сцен щелчком мыши" Basic.Settings.General.Multiview.DrawSourceNames="Показывать названия сцен" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Горизонт Basic.Settings.Stream="Вещание" Basic.Settings.Stream.StreamType="Тип вещания" +Basic.Settings.Stream.Custom.UseAuthentication="Использовать аутентификацию" +Basic.Settings.Stream.Custom.Username="Имя пользователя" +Basic.Settings.Stream.Custom.Password="Пароль" +Basic.Settings.Stream.BandwidthTestMode="Включить режим тестирования пропускной способности" Basic.Settings.Output="Вывод" Basic.Settings.Output.Format="Формат записи" @@ -544,7 +599,7 @@ Basic.Settings.Output.UseReplayBuffer="Включить Буфер повтор Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимальное время повтора (секунд)" Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимальный объем памяти (МБ)" Basic.Settings.Output.ReplayBuffer.Estimate="Предполагаемое использование памяти: %1 МБ" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Невозможно оценить использование памяти. Пожалуйста, установите максимальный объем памяти." +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Невозможно оценить использование памяти. Пожалуйста, установите максимальный объем памяти." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Примечание: Убедитесь, что установили горячую клавишу для воспроизведения буфера в разделе горячие клавиши)" Basic.Settings.Output.ReplayBuffer.Prefix="Префикс имени файла повтора" Basic.Settings.Output.ReplayBuffer.Suffix="Суффикс" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Предупреждение: Зап Basic.Settings.Output.Simple.Warn.Lossless="Предупреждение: Качество без потерь создает чрезвычайно большие файлы! Такое качество может использовать свыше 7 гигабайт дискового пространства в минуту при высоком разрешении и частоте кадров. Оно не рекомендуется для долгой записи, если у Вас нет очень много места на диске." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Вы уверены, что хотите записывать без потери качества?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Предупреждение о качестве без потерь!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Предупреждение: вы не можете использовать несколько различных QSV-кодировщиков при одновременной трансляции и записи. Если вы хотите одновременно и транслировать, и записывать, поменяйте либо кодировщик вещания, либо кодировщик записи." Basic.Settings.Output.Simple.Encoder.Software="Программный (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Аппаратный (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Аппаратный (AМD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Автопереподключение" Basic.Settings.Output.RetryDelay="Переподключиться через (секунд)" Basic.Settings.Output.MaxRetries="Количество попыток подключиться" Basic.Settings.Output.Advanced="Включить дополнительные настройки кодировщика" -Basic.Settings.Output.EncoderPreset="Предустановки кодировщика (выше = меньше ЦП)" +Basic.Settings.Output.EncoderPreset="Предустановка кодировщика" Basic.Settings.Output.CustomEncoderSettings="Пользовательские настройки кодировщика" Basic.Settings.Output.CustomMuxerSettings="Пользовательские настройки мультиплексора" Basic.Settings.Output.NoSpaceFileName="Генерировать имя файла без пробела" @@ -617,7 +671,6 @@ Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Настройки мульти Basic.Settings.Output.Adv.FFmpeg.GOPSize="Интервал ключевых кадров (кадры)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Показать все кодеки (даже потенциально несовместимые)" -FilenameFormatting.completer="%DD-%MM-%CCYY %hh-%mm-%ss\n%DD-%MM-%YY %hh-%mm-%ss\n%d-%m-%Y %H-%M-%S\n%d-%m-%y %H-%M-%S\n%a %d-%m-%Y %H-%M-%S\n%A %d-%m-%Y %H-%M-%S\n%d-%b-%Y %H-%M-%S\n%d-%B-%Y %H-%M-%S" FilenameFormatting.TT="%CCYY Год, четыре знака\n%YY Год, последние два знака (00-99)\n%MM Месяц в числовом значении (01-12)\n%DD День месяца, ноль не опускается (01-31)\n%hh Час в 24-часовом формате (00-23)\n%mm Минута (00-59)\n%ss Секунда (00-61)\n%% Знак '%'\n%a Сокращенное название дня недели\n%A Полное название дня недели\n%b Сокращенное название месяца\n%B Полное название месяца\n%d День месяца, ноль не опускается (01-31)\n%H Час в 24 часовом формате (00-23)\n%I Час в 12 часовом формате (01-12)\n%m Месяц в числовом значении (01-12)\n%M Минута (00-59)\n%p Обозначение AM или PM\n%S Секунда (00-61)\n%y Год, последние два знака (00-99)\n%Y Год\n%z ISO 8601 смещение от UTC или\n название или сокращение часового пояса\n%Z Название или сокращение часового пояса\n" @@ -634,7 +687,7 @@ Basic.Settings.Video.FPSFraction="Дробное значение FPS" Basic.Settings.Video.Numerator="Числитель" Basic.Settings.Video.Denominator="Знаменатель" Basic.Settings.Video.Renderer="Рендер" -Basic.Settings.Video.InvalidResolution="Неверное разрешение. Должно быть [Ширина]x[Высота] (т.е. 1920x1080)" +Basic.Settings.Video.InvalidResolution="Неверное разрешение. Должно быть [Ширина]x[Высота] (т.е. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Видео выход в данный момент активен. Пожалуйста, отключите все выходы, чтобы изменить настройки видео." Basic.Settings.Video.DisableAero="Отключить Aero" @@ -645,7 +698,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Метод Ланцоша (Чёт Basic.Settings.Audio="Аудио" Basic.Settings.Audio.SampleRate="Частота дискретизации" Basic.Settings.Audio.Channels="Каналы" -Basic.Settings.Audio.MeterDecayRate="Скорость спада аудиометра" +Basic.Settings.Audio.Meters="Измерители" +Basic.Settings.Audio.MeterDecayRate="Скорость спада" Basic.Settings.Audio.MeterDecayRate.Fast="Быстро" Basic.Settings.Audio.MeterDecayRate.Medium="Средне (PPM типа I)" Basic.Settings.Audio.MeterDecayRate.Slow="Медленно (PPM типа II)" @@ -656,16 +710,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="ВНИМАНИЕ: Объемн Basic.Settings.Audio.MultichannelWarning="При запуске стрима проверьте, поддерживает ли ваш сервис потокового вещания объемный звук (как запись, так и воспроизведение). Twitch, Facebook 360 Live, Mixer RTMP, Smashcast — примеры сервисов, полностью поддерживающих объемное звучание. Несмотря на то, что Facebook Live и Youtube Live принимают объёмный звук, Facebook Live микширует его в стерео, а Youtube Live воспроизводит только два канала.\n\nЗвуковые фильтры OBS совместимы с объемным звучанием, хотя поддержка плагинов VST не гарантируется." Basic.Settings.Audio.MultichannelWarning.Title="Включить объемный звук?" Basic.Settings.Audio.MultichannelWarning.Confirm="Хотите включить объемный звук?" -Basic.Settings.Audio.DesktopDevice="Desktop Аудиоустройство" -Basic.Settings.Audio.DesktopDevice2="Desktop Аудиоустройство 2" -Basic.Settings.Audio.AuxDevice="Mic/Auxiliary Аудиоустройство" -Basic.Settings.Audio.AuxDevice2="Mic/Auxiliary Аудиоустройство 2" -Basic.Settings.Audio.AuxDevice3="Mic/Auxiliary Аудиоустройство 3" +Basic.Settings.Audio.Devices="Устройства" +Basic.Settings.Audio.DesktopDevice="Аудио с рабочего стола" +Basic.Settings.Audio.DesktopDevice2="Аудио с рабочего стола 2" +Basic.Settings.Audio.AuxDevice="Микрофон/Дополнительное аудио" +Basic.Settings.Audio.AuxDevice2="Микрофон/Дополнительное аудио 2" +Basic.Settings.Audio.AuxDevice3="Микрофон/Дополнительное аудио 3" +Basic.Settings.Audio.AuxDevice4="Микрофон/Дополнительное аудио 4" Basic.Settings.Audio.EnablePushToMute="Выключать микрофон по нажатии" Basic.Settings.Audio.PushToMuteDelay="Задержка выключения микрофона" Basic.Settings.Audio.EnablePushToTalk="Включать микрофон по нажатии" Basic.Settings.Audio.PushToTalkDelay="Задержка включения микрофона" Basic.Settings.Audio.UnknownAudioDevice="[Устройство не подключено или недоступно]" +Basic.Settings.Audio.Disabled="Выключено" Basic.Settings.Advanced="Расширенные" Basic.Settings.Advanced.General.ProcessPriority="Приоритет процесса" @@ -677,11 +734,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Низкий" Basic.Settings.Advanced.FormatWarning="Предупреждение: цветовые форматы, отличные от NV12, прежде всего предназначены для записи и не рекомендуются для потокового вещания. Преобразование цветового формата во время вещания может потребовать дополнительную нагрузку на ЦП." Basic.Settings.Advanced.Audio.BufferingTime="Время буферизации аудио" Basic.Settings.Advanced.Video.ColorFormat="Цветовой формат" -Basic.Settings.Advanced.Video.ColorSpace="Цветовое пространство YUV" -Basic.Settings.Advanced.Video.ColorRange="Цветовой диапазон YUV" +Basic.Settings.Advanced.Video.ColorSpace="Цветовое пространство" +Basic.Settings.Advanced.Video.ColorRange="Цветовой диапазон" Basic.Settings.Advanced.Video.ColorRange.Partial="Частичный" Basic.Settings.Advanced.Video.ColorRange.Full="Полный" -Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство прослушивания аудио" +Basic.Settings.Advanced.Audio.MonitoringDevice="Устройство прослушивания" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="По умолчанию" Basic.Settings.Advanced.Audio.DisableAudioDucking="Отключить приглушение звуков Windows" Basic.Settings.Advanced.StreamDelay="Задержка потока" @@ -693,12 +750,14 @@ Basic.Settings.Advanced.Network.BindToIP="Привязать к IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Включить новый сетевой код" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим низкой задержки" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Отключить горячие клавиши, если главное окно находится в фокусе" +Basic.Settings.Advanced.AutoRemux="Автоматически ремультиплексировать в mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(записывать как mkv)" Basic.AdvAudio="Расширенные свойства аудио" Basic.AdvAudio.Name="Название" -Basic.AdvAudio.Volume="Громкость (%)" +Basic.AdvAudio.Volume="Громкость" Basic.AdvAudio.Mono="Объединение в один канал" -Basic.AdvAudio.Panning="Панорамирование" +Basic.AdvAudio.Balance="Баланс" Basic.AdvAudio.SyncOffset="Смещение синхронизации (мс)" Basic.AdvAudio.Monitoring="Аудио прослушивание" Basic.AdvAudio.Monitoring.None="Выключить прослушивание" @@ -708,6 +767,7 @@ Basic.AdvAudio.AudioTracks="Дорожки" Basic.Settings.Hotkeys="Горячие клавиши" Basic.Settings.Hotkeys.Pair="Сочетания клавиш вместе с '%1' действуют как переключатели" +Basic.Settings.Hotkeys.Filter="Фильтр" Basic.Hotkeys.SelectScene="Перейти на сцену" @@ -751,6 +811,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Мышь %1" +Hotkeys.Escape="Esc" Mute="Отключить звук" Unmute="Включить звук" @@ -762,7 +823,7 @@ SceneItemHide="Скрыть '%1'" OutputWarnings.NoTracksSelected="Вы должны выбрать хотя бы одну звуковую дорожку" OutputWarnings.MultiTrackRecording="Предупреждение: Некоторые форматы (такие как FLV) не поддерживают множественные звуковые дорожки" -OutputWarnings.MP4Recording="Внимание: Записи, сохраненные в MP4 будут нечитаемы, если файл не будет завершен (например, в результате BSOD'а, потери напряжения в сети и т.д.). Если вы хотите записывать несколько аудио дорожек, рассмотрите использование MKV, и последующее ремультиплексирование в MP4 после завершения записи (Файл -> Ремультиплексирование записей)" +OutputWarnings.MP4Recording="Внимание: Записи, сохраненные в MP4/MOV будут нечитаемы если файл не будет завершен (например, в результате BSOD'а, потери напряжения в сети и т.д.). Если вы хотите записывать несколько аудио дорожек, рассмотрите использование MKV и последующее ремультиплексирование в MP4/MOV после завершения записи (Файл → Ремультиплексирование записей)" FinalScene.Title="Удалить сцену" FinalScene.Text="Здесь должна быть по крайней мере одна сцена." @@ -770,9 +831,24 @@ FinalScene.Text="Здесь должна быть по крайней мере NoSources.Title="Нет источников" NoSources.Text="Похоже, вы еще не добавили ни одного источника. Вы будете выводить только пустой экран. Вы уверены, что хотите этого?" NoSources.Text.AddSource="Вы можете добавить источники, нажав иконку + под окном Источники в главном окне в любое время." +NoSources.Label="У вас нет источников.\nНажмите кнопку + ниже,\nили нажмите правой кнопкой здесь, чтобы добавить его." ChangeBG="Установить цвет" CustomColor="Пользовательский цвет" BrowserSource.EnableHardwareAcceleration="Включить аппаратное ускорение Браузера" +About="О программе" +About.Info="OBS Studio — это бесплатная программа с открытым исходным кодом для записи видео и потокового вещания." +About.Donate="Сделать вклад" +About.GetInvolved="Принять участие" +About.Authors="Авторы" +About.License="Лицензия" +About.Contribute="Поддержать проект OBS" + +ResizeOutputSizeOfSource="Масштабировать вывод (по размеру источника)" +ResizeOutputSizeOfSource.Text="Базовое и выходное разрешение будет изменено до размера текущего источника." +ResizeOutputSizeOfSource.Continue="Хотите продолжить?" + +PreviewTransition="Предпросмотр перехода" + diff --git a/UI/data/locale/sk-SK.ini b/UI/data/locale/sk-SK.ini index fd45ee8..acabb1d 100644 --- a/UI/data/locale/sk-SK.ini +++ b/UI/data/locale/sk-SK.ini @@ -49,7 +49,7 @@ Duplicate="Duplikovať" Enable="Povoliť" DisableOSXVSync="Vypnúť OSX V-Sync" ResetOSXVSyncOnExit="Resetovať OSX V-Sync po zavretí" -HighResourceUsage="Kódovanie preťažené! Uvažujte o znížení nastavení videa alebo vyberte rýchlejší preset kódovania." +HighResourceUsage="Kódovanie preťažené! Uvažujte o znížení nastavení videa alebo vyberte rýchlejšiu predvoľbu kódovania." Transition="Prechod" QuickTransitions="Rýchle prechody" Left="Vľavo" @@ -68,7 +68,7 @@ Copy="Kopírovať" Paste="Vložiť" PasteReference="Vložiť (odkaz)" PasteDuplicate="Vložiť (duplikát)" -RemuxRecordings="Multiplexné nahrávky" +RemuxRecordings="Previesť nahrávky" Next="Ďalej" Back="Späť" Defaults="Predvolené" @@ -80,14 +80,38 @@ StudioMode.Program="Program" ShowInMultiview="Zobraziť v Multiview" VerticalLayout="Vertikálne rozloženie" Group="Skupina" +DoNotShowAgain="Znovu neukazovať" +Default="(Predvolené)" +Calculating="Kalkulovanie..." AlreadyRunning.Title="OBS je už spustený" -AlreadyRunning.Text="OBS je už spustená! Prosím vypnite všetky existujúce inštancie OBS pred pokusom o spustenie novej inštancie. Ak máte OBS minimalizovaný do systémovej lišty, prosím skontrolujte či tam stále beží." +AlreadyRunning.Text="Aplikácia OBS je už spustená! Prosím vypnite všetky existujúce inštancie OBS pred pokusom o spustenie novej inštancie. Ak máte OBS minimalizovaný do systémovej lišty, prosím skontrolujte, či tam stále beží." AlreadyRunning.LaunchAnyway="Napriek tomu spustiť" +DockCloseWarning.Title="Zatvorenie dokovateľného okna" +DockCloseWarning.Text="Práve ste zatvorili dokovateľné okno. Ak ho chcete znovu zobraziť, použite menu Zobraziť → Doky." + +Auth.Authing.Title="Autentifikácia..." +Auth.Authing.Text="Prebieha overovanie so službou %1, čakajte..." +Auth.AuthFailure.Title="Overenie zlyhalo" +Auth.AuthFailure.Text="Zlyhalo overenie so službou %1:\n\n%2: %3" +Auth.InvalidScope.Title="Požadovaná autentifikácia" +Auth.InvalidScope.Text="Požiadavky na overenie pre %1 sa zmenili. Niektoré funkcie nemusia byť k dispozícii." +Auth.LoadingChannel.Title="Načítavajú sa informácie o kanáli..." +Auth.LoadingChannel.Text="Načítavajú sa informácie o kanáli pre službu %1, prosím čakajte..." +Auth.ChannelFailure.Title="Načítanie kanálu zlyhalo" +Auth.ChannelFailure.Text="Nepodarilo sa načítať informácie o kanáli pre službu %1\n\n%2: %3" +Auth.Chat="Chat" +Auth.StreamInfo="Informácie o vysielaní" +TwitchAuth.Stats="Twitch štatistiky" +TwitchAuth.Feed="Kanál aktivít v službe Twitch" + Copy.Filters="Kopírovať filtre" Paste.Filters="Vložiť filtre" +BrowserPanelInit.Title="Načítavam prehliadač..." +BrowserPanelInit.Text="Prehliadač sa načítava, prosím čakajte..." + BandwidthTest.Region="Región" BandwidthTest.Region.US="Spojené Štáty Americké" BandwidthTest.Region.EU="Európa" @@ -95,11 +119,9 @@ BandwidthTest.Region.Asia="Ázia" BandwidthTest.Region.Other="Iné" Basic.FirstStartup.RunWizard="Chcete spustiť sprievodcu automatickej konfigurácie? Nastavenie môžete nakonfigurovať aj manuálne kliknutím na tlačidlo nastavenia v hlavnom okne." -Basic.FirstStartup.RunWizard.BetaWarning="(Poznámka: Sprievodca automatickou konfiguráciou je v súčasnosti v beta verzii)" Basic.FirstStartup.RunWizard.NoClicked="Ak zmeníte názor, môžete spustiť sprievodcu automatickou konfiguráciou kedykoľvek znova z ponuky Nástroje." Basic.AutoConfig="Sprievodca automatickou konfiguráciou" -Basic.AutoConfig.Beta="Sprievodca automatickou konfiguráciou (Beta)" Basic.AutoConfig.ApplySettings="Použiť nastavenia" Basic.AutoConfig.StartPage="Informácie o používaní" Basic.AutoConfig.StartPage.SubTitle="Vyberte na čo chcete program použiť" @@ -115,8 +137,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 alebo 30, ale radšej vysoké r Basic.AutoConfig.VideoPage.CanvasExplanation="Poznámka: rozlíšenie (základné) plátna nie je nevyhnutne rovnaké ako rozlíšenie v ktorom budete streamovať alebo nahrávať. Skutočné streamovacie/nahrávacie rozlíšenie môže byť zmenšené preto aby sa znížilo používanie dát alebo zdrojov." Basic.AutoConfig.StreamPage="Informácie o streame" Basic.AutoConfig.StreamPage.SubTitle="Prosím, zadajte svoje údaje o vysielaní" +Basic.AutoConfig.StreamPage.ConnectAccount="Prepojiť účet (voliteľné)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Odpojiť účet" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Odpojiť účet?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Táto zmena sa uplatní okamžite. Naozaj chcete odpojiť svoj účet?" +Basic.AutoConfig.StreamPage.UseStreamKey="Použiť kľúč vysielania" Basic.AutoConfig.StreamPage.Service="Služba" Basic.AutoConfig.StreamPage.Service.ShowAll="Zobraziť všetky..." +Basic.AutoConfig.StreamPage.Service.Custom="Vlastné..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Streamovací kľúč" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Odkaz)" @@ -132,8 +160,8 @@ Basic.AutoConfig.TestPage.TestingBandwidth="Prebieha testovanie rýchlosti pripo Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Pripájanie k: %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Nepodarilo sa pripojiť k žiadnemu serveru. Skontrolujte vaše internetové pripojenie a skúste to znovu." Basic.AutoConfig.TestPage.TestingBandwidth.Server="Testovanie rýchlosti pripojenia pre: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="Testovanie streamovacieho enkodéra, toto môže trvať minútu..." -Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testovanie nahrávacieho enkodéra, toto môže trvať minútu..." +Basic.AutoConfig.TestPage.TestingStreamEncoder="Testovanie streamovacieho enkodéra, toto môže minútku trvať..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="Testovanie nahrávacieho enkodéra, toto môže minútku trvať..." Basic.AutoConfig.TestPage.TestingRes="Testovanie rozlíšení, toto môže trvať niekoľko minút..." Basic.AutoConfig.TestPage.TestingRes.Fail="Nepodarilo sa spustiť enkodér" Basic.AutoConfig.TestPage.TestingRes.Resolution="Testovanie %1x%2 %3 FPS..." @@ -144,7 +172,7 @@ Basic.AutoConfig.TestPage.Result.Footer="Pre použitie týchto nastavení klikni Basic.Stats="Štatistiky" Basic.Stats.CPUUsage="Využitie CPU" -Basic.Stats.HDDSpaceAvailable="Dostupné miesto na HDD" +Basic.Stats.HDDSpaceAvailable="Dostupné miesto na disku" Basic.Stats.MemoryUsage="Využitie pamäte" Basic.Stats.AverageTimeToRender="Priemerný čas vykreslenia snímku" Basic.Stats.SkippedFrames="Preskočené snímky kvôli chybe kódovania" @@ -159,6 +187,10 @@ Basic.Stats.Status.Inactive="Neaktívne" Basic.Stats.DroppedFrames="Stratené snímky (sieť)" Basic.Stats.MegabytesSent="Celkový dátový výstup" Basic.Stats.Bitrate="Dátový tok" +Basic.Stats.DiskFullIn="Disk plný za (približne)" + +ResetUIWarning.Title="Naozaj chcete obnoviť používateľské rozhranie?" +ResetUIWarning.Text="Obnovením používateľského rozhrania sa skryjú ďalšie doky. Pre ich opätovné zobrazenie ich budete musieť povoliť v ponuke Zobraziť.\n\nNaozaj chcete resetovať používateľské rozhranie?" Updater.Title="Nová aktualizácia k dispozícii" Updater.Text="Je dostupná nová aktualizácia:" @@ -173,8 +205,8 @@ Updater.FailedToLaunch="Nepodarilo sa spustiť aktualizátor" Updater.GameCaptureActive.Title="Zachytenie hry aktívne" Updater.GameCaptureActive.Text="Knižnica pre záznam hier je stále aktívna. Ukončite, prosím, všetky snímané hry/programy (alebo reštartujte Windows) a skúste to znovu." -QuickTransitions.SwapScenes="Prehodiť scény po prechode" -QuickTransitions.SwapScenesTT="Prehodí scény pre náhľad a výstup po prechode (ak pôvodná scéna výstupu stále existuje).\nToto nevráti žiadne zmeny vykonané v pôvodnej scéne pre výstup." +QuickTransitions.SwapScenes="Vymeniť scény po prechode" +QuickTransitions.SwapScenesTT="Vymení scény pre náhľad a výstup po prechode (ak pôvodná scéna výstupu stále existuje).\nToto nevráti žiadne zmeny vykonané v pôvodnej scéne výstupu." QuickTransitions.DuplicateScene="Duplikovať scénu" QuickTransitions.DuplicateSceneTT="Pri úprave rovnakej scény umožňuje úpravu pozície/viditeľnosti zdrojov bez úpravy výstupu.\nPre úpravu vlastností zdrojov bez úpravy výstupu povoľte možnosť \"Duplikovať zdroje\".\nZmena tejto hodnoty spôsobí vyresetovanie súčasnej scény výstupu (ak stále existuje)." QuickTransitions.EditProperties="Duplikovať zdroje" @@ -206,8 +238,11 @@ ConfirmStart.Text="Naozaj chcete spustiť stream?" ConfirmStop.Title="Zastaviť stream?" ConfirmStop.Text="Naozaj chcete zastaviť stream?" +ConfirmBWTest.Title="Spustiť test šírky pásma siete?" +ConfirmBWTest.Text="Vaše OBS je nakonfigurované pre režim testovania šírky pásma. Toto umožní zistiť parametre vašej siete bez spustenia živého vysielania na vašom kanáli. Po dokončení testovania musíte tento režim zakázať, ináč diváci neuvidia vami prenášaný obsah.\n\nNaozaj si želáte pokračovať?" + ConfirmExit.Title="Ukončiť OBS?" -ConfirmExit.Text="OBS je momentálne aktívny. Všetky prúdy údajov/záznamy sa ukončia. Naozaj pokračovať?" +ConfirmExit.Text="OBS je momentálne aktívny. Všetky prúdy údajov/záznamy sa ukončia. Naozaj pokračovať?" ConfirmRemove.Title="Potvrdenie odobratia" ConfirmRemove.Text="Naozaj si prajete odobrať '$1'?" @@ -218,48 +253,51 @@ Output.StartRecordingFailed="Nepodarilo sa spustiť nahrávanie" Output.StartReplayFailed="Nepodarilo sa spustiť medzipamäť znovunahrávania" Output.StartFailedGeneric="Nastala chyba pri spúšťaní nahrávania. Podrobnosti nájdete v textovom logu.\n\nPoznámka: Ak používate NVENC alebo AMD enkodér, uistite sa, že používate najnovšiu verziu grafického ovládača." + Output.ConnectFail.Title="Spojenie sa nepodarilo" Output.ConnectFail.BadPath="Neplatná cesta alebo URL. Prosím, skontrolujte, či sú vaše nastavenia správne." Output.ConnectFail.ConnectFailed="Spojenie so serverom sa nepodarilo" Output.ConnectFail.InvalidStream="K nastavenému kanálu alebo kľúču sa nedá pristupovať. Skontrolujte, prosím, či je váš vysielací kľúč správny. Ak áno, mohol nastať problém s pripojením k serveru." -Output.ConnectFail.Error="Pri pokuse o pripojenie k serveru nastala neočakávaná chyba. Ďalšie informácie nájdete v textovom logu." +Output.ConnectFail.Error="Pri pokuse o pripojenie k serveru nastala neočakávaná chyba. Ďalšie informácie nájdete v textovom logu." Output.ConnectFail.Disconnected="Odpojený od servera." +Output.StreamEncodeError.Title="Chyba kódovania" +Output.StreamEncodeError.Msg="Nastala chyba pri kódovaní počas vysielania." + Output.RecordFail.Title="Nepodarilo sa spustiť nahrávanie" Output.RecordFail.Unsupported="Výstupný formát nie je podporovaný alebo nepodporuje viac ako jednu zvukovú stopu. Skontrolujte nastavenia a skúste to znovu." Output.RecordNoSpace.Title="Nedostatok miesta na disku" Output.RecordNoSpace.Msg="Pre pokračovanie nahrávania nie je dostatok miesta na disku." Output.RecordError.Title="Chyba nahrávania" Output.RecordError.Msg="Pri nahrávaní došlo k nešpecifikovanej chybe." +Output.RecordError.EncodeErrorMsg="Nastala chyba pri kódovaní počas nahrávania." Output.ReplayBuffer.NoHotkey.Title="Nepriradená žiadna klávesová skratka!" Output.ReplayBuffer.NoHotkey.Msg="Nie je nastavená žiadna klávesová skratka pre uloženie záznamu. Nastavte ju, prosím, aby ste mohli ukladať záznam." Output.BadPath.Title="Nesprávna cesta k súboru" -Output.BadPath.Text="Nastavená cesta k výstupnému súboru je chybná. Prosím, skontrolujte správnosť nastavenej cesty." +Output.BadPath.Text="Nastavená cesta k výstupnému súboru je chybná. Prosím, skontrolujte správnosť nastavenej cesty." LogReturnDialog="Nahranie logu bolo úspešné" LogReturnDialog.CopyURL="Kopírovať URL" LogReturnDialog.ErrorUploadingLog="Chyba pri nahrávaní súboru denníka chýb" -LicenseAgreement="Licenčná zmluva" -LicenseAgreement.PleaseReview="Pred použitím OBS si, prosím, prečítajte licenčné podmienky. Používaním tohto programu potvrdzujete, že ste si prečítali a súhlasíte s podmienkami GNU General Public License v2.0. Pre zobrazenie zvyšku licencie prejdite nižšie." -LicenseAgreement.ClickIAgreeToContinue="Ak súhlasíte s podmienkami licencie, kliknite na Súhlasím. Pred začatím používania OBS musíte súhlasiť s ujednaním." -LicenseAgreement.IAgree="Súhlasím" -LicenseAgreement.Exit="Ukončiť" - Remux.SourceFile="OBS nahrávka" Remux.TargetFile="Cieľový súbor" Remux.Remux="Previesť" +Remux.Stop="Zastaviť prevod" +Remux.ClearFinished="Odstrániť dokončené položky" +Remux.ClearAll="Odstrániť všetky položky" Remux.OBSRecording="OBS nahrávanie" Remux.FinishedTitle="Prevod dokončený" Remux.Finished="Nahrávka prevedená" Remux.FinishedError="Nahrávka prevedená, ale súbor nemusí byť kompletný" -Remux.SelectRecording="Vybrať OBS nahrávku …" -Remux.SelectTarget="Vyberte cieľový súbor …" +Remux.SelectRecording="Vyberte OBS nahrávku..." +Remux.SelectTarget="Vyberte cieľový súbor..." Remux.FileExistsTitle="Cieľový súbor existuje" -Remux.FileExists="Cieľový súbor už existuje, chcete ho nahradiť?" +Remux.FileExists="Nasledujúce súbory už existujú. Chcete ich nahradiť?" Remux.ExitUnfinishedTitle="Prebieha prevod" Remux.ExitUnfinished="Prevod nie je dokončený. Zastavenie môže spôsobiť poškodenie výstupného súboru.\nNaozaj chcete prevod prerušiť?" +Remux.HelpText="Presuňte súbory do tohto okna k prevodu alebo vyberte prázdne pole \"OBS nahrávka\" pre výber súboru." UpdateAvailable="Je dostupná aktualizácia" UpdateAvailable.Text="Verzia %1.%2.%3 je dostupná. Kliknite sem na jej stiahnutie" @@ -276,11 +314,14 @@ Basic.DisplayCapture="Zachytávanie monitora" Basic.Main.PreviewConextMenu.Enable="Zapnúť náhľad" +Basic.Main.Preview.Disable="Vypnúť nahľad" + ScaleFiltering="Filter škálovania" ScaleFiltering.Point="Bodové" ScaleFiltering.Bilinear="Bilineárne" ScaleFiltering.Bicubic="Bikubické" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Oblastný" Deinterlacing="Odstránenie prekladania" Deinterlacing.Discard="Zahodenie" @@ -415,11 +456,11 @@ Basic.MainMenu.File="Súbor (&F)" Basic.MainMenu.File.Export="&Exportovať" Basic.MainMenu.File.Import="&Importovať" Basic.MainMenu.File.ShowRecordings="Zobraziť nah&rávky" -Basic.MainMenu.File.Remux="Previesť &nahrávky" +Basic.MainMenu.File.Remux="Previesť nahrávky (&M)" Basic.MainMenu.File.Settings="Na&stavenia" Basic.MainMenu.File.ShowSettingsFolder="Zobraziť priečinok nastavení" Basic.MainMenu.File.ShowProfileFolder="Zobraziť priečinok profilu" -Basic.MainMenu.AlwaysOnTop="&Vždy navrchu" +Basic.MainMenu.AlwaysOnTop="Vždy n&avrchu" Basic.MainMenu.File.Exit="Ukončiť (&x)" Basic.MainMenu.Edit="Upraviť (&E)" @@ -427,8 +468,8 @@ Basic.MainMenu.Edit.Undo="Vrátiť späť (&U)" Basic.MainMenu.Edit.Redo="Opakovať v&rátené" Basic.MainMenu.Edit.UndoAction="Vrátiť $1 (&U)" Basic.MainMenu.Edit.RedoAction="Opakovať $1 (&R)" -Basic.MainMenu.Edit.LockPreview="&Zámknúť náhľad" -Basic.MainMenu.Edit.Scale="%Rozmer náhľadu" +Basic.MainMenu.Edit.LockPreview="Zámknúť náhľad (&L)" +Basic.MainMenu.Edit.Scale="Rozmer náhľadu (&S)" Basic.MainMenu.Edit.Scale.Window="Vtesnať do okna" Basic.MainMenu.Edit.Scale.Canvas="Plátno (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Výstup (%1x%2)" @@ -445,6 +486,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="Preklopiť z&visle" Basic.MainMenu.Edit.Transform.FitToScreen="Prispôsobiť obrazovke (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Roztiahnuť na celú obrazovku (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="Umiestniť na stred obrazovky (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrovať zvislo" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrovať vodorovne" Basic.MainMenu.Edit.Order="P&oradie" Basic.MainMenu.Edit.Order.MoveUp="Pos&unúť vyššie" Basic.MainMenu.Edit.Order.MoveDown="Posunúť nižšie (&D)" @@ -453,7 +496,7 @@ Basic.MainMenu.Edit.Order.MoveToBottom="Premiestniť naspodok (&B)" Basic.MainMenu.Edit.AdvAudio="Rozšírené vl&astnosti zvuku" Basic.MainMenu.View="Zobraziť (&V)" -Basic.MainMenu.View.Toolbars="&Panely s nástrojmi" +Basic.MainMenu.View.Toolbars="Panely s nás&trojmi" Basic.MainMenu.View.Docks="Doky" Basic.MainMenu.View.Docks.ResetUI="Resetovať UI" Basic.MainMenu.View.Docks.LockUI="Zamknúť UI" @@ -483,9 +526,10 @@ Basic.MainMenu.Help.Logs.UploadCurrentLog="Nahrať súčasný súbor záznamu (& Basic.MainMenu.Help.Logs.UploadLastLog="Nahrať posledný súbor záznamu (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="Zobraziť aktuálny záznam (&V)" Basic.MainMenu.Help.CheckForUpdates="Skontrolovať aktualizácie" -Basic.MainMenu.Help.CrashLogs="&Hlásenia o zlyhaní" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Zobraziť správy o zlyhaniach" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Nahrať poslednú správu" +Basic.MainMenu.Help.CrashLogs="Hlásenia o zlyhaní (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Zobraziť &správy o zlyhaniach" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Nahrať pos&lednú správu" +Basic.MainMenu.Help.About="O &aplikácii" Basic.Settings.ProgramRestart="Tieto nastavenia sa prejavia až po reštarte programu." Basic.Settings.ConfirmTitle="Potvrdenie zmien" @@ -495,6 +539,9 @@ Basic.Settings.General="Všeobecné" Basic.Settings.General.Theme="Vzhľad" Basic.Settings.General.Language="Jazyk" Basic.Settings.General.EnableAutoUpdates="Automaticky kontrolovať aktualizácie pri štarte" +Basic.Settings.General.OpenStatsOnStartup="Otvoriť dialógové okno štatistík po štarte" +Basic.Settings.General.WarnBeforeStartingStream="Ukáž potvrďovacie okno pri začatí vysielania" +Basic.Settings.General.WarnBeforeStoppingStream="Ukáž potvrďovacie okno pri zastavení vysielania" Basic.Settings.General.Projectors="Projektory" Basic.Settings.General.HideProjectorCursor="Skryť kurzor pred náhľadmi" Basic.Settings.General.ProjectorAlwaysOnTop="Náhľady vždy navrchu" @@ -505,15 +552,36 @@ Basic.Settings.General.SourceSnapping="Prichytávať zdroje k iným zdrojom" Basic.Settings.General.SnapDistance="Prichytávať citlivosť" Basic.Settings.General.RecordWhenStreaming="Automaticky nahrávať pri vysielaní" Basic.Settings.General.KeepRecordingWhenStreamStops="Nahrávať aj po ukončení vysielania" +Basic.Settings.General.ReplayBufferWhileStreaming="Automaticky zapnúť záznam do pamäti pri začatí vysielania" +Basic.Settings.General.KeepReplayBufferStreamStops="Ponechať záznam do pamäti aktívny i po zastavení vysielania" Basic.Settings.General.SysTray="Systémová lišta" Basic.Settings.General.SysTrayWhenStarted="Minimalizovať do systémovej lišty pri spustení" Basic.Settings.General.SystemTrayHideMinimize="Vždy minimalizovať do systémovej lišty namiesto panela úloh" Basic.Settings.General.SaveProjectors="Uložiť projektory pri skončení" +Basic.Settings.General.Preview="Náhľad" +Basic.Settings.General.OverflowHidden="Skryť pretečenie" +Basic.Settings.General.OverflowAlwaysVisible="Pretečenie vždy viditeľné" +Basic.Settings.General.OverflowSelectionHidden="Ukázať pretečenie aj keď je zdroj neviditeľný" +Basic.Settings.General.SwitchOnDoubleClick="Prejsť do scény pri dvojkliku" +Basic.Settings.General.StudioPortraitLayout="Zapnúť portrétové/vertikálne rozloženie" +Basic.Settings.General.TogglePreviewProgramLabels="Zobraziť popisy okien náhľadu a programu" +Basic.Settings.General.Multiview="Multiview" +Basic.Settings.General.Multiview.MouseSwitch="Povoliť prechod medzi scénami kliknutím" Basic.Settings.General.Multiview.DrawSourceNames="Zobraziť názvy scén" Basic.Settings.General.Multiview.DrawSafeAreas="Vykresliť bezpečné zóny (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Rozloženie Multiview" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontálne, Navrchu (8 scén)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontálne, Dole (8 scén)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertikálne, Vľavo (8 scén)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertikálne, Vpravo (8 scén)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontálne, Navrchu (24 scén)" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Typ streamu" +Basic.Settings.Stream.Custom.UseAuthentication="Použiť overenie" +Basic.Settings.Stream.Custom.Username="Užívateľské meno" +Basic.Settings.Stream.Custom.Password="Heslo" +Basic.Settings.Stream.BandwidthTestMode="Povoliť režim testovania šírky pásma" Basic.Settings.Output="Výstup" Basic.Settings.Output.Format="Formát nahrávania" @@ -525,21 +593,30 @@ Basic.Settings.Output.Mode="Režim výstupu" Basic.Settings.Output.Mode.Simple="Jednoduchý" Basic.Settings.Output.Mode.Adv="Rozšírené" Basic.Settings.Output.Mode.FFmpeg="Výstup FFmpeg" +Basic.Settings.Output.UseReplayBuffer="Zapnúť záznam do pamäti" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maximálny čas záznamu (v sekundách)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maximálna pamäť (v megabajtoch)" Basic.Settings.Output.ReplayBuffer.Estimate="Odhadované využitie pamäte: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nemôžem odhadnúť použivanie pamäte. Prosím nastavte maximálny limit pamäte." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Poznámka: Uistite sa, že ste nastavili klávesovú skratku pre záznam do pamäte, v sekcii klávesových skratiek)" +Basic.Settings.Output.ReplayBuffer.Prefix="Predpona názvu súboru záznamu do pamäte" Basic.Settings.Output.ReplayBuffer.Suffix="Prípona" Basic.Settings.Output.Simple.SavePath="Nahrávacia cesta" Basic.Settings.Output.Simple.RecordingQuality="Kvalita nahrávania" Basic.Settings.Output.Simple.RecordingQuality.Stream="Rovnaká ako pre stream" Basic.Settings.Output.Simple.RecordingQuality.Small="Vysoká kvalita, stredná veľkosť súboru" +Basic.Settings.Output.Simple.RecordingQuality.HQ="Nerozoznateľná kvalita, veľká veľkosť súboru" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Bezstratová kvalita, ohromne veľké súbory" Basic.Settings.Output.Simple.Warn.VideoBitrate="Upozornenie: Dátový tok vysielaného obrazu bude nastavený na %1, čo je horná hranica pre súčasnú vysielaciu službu. Ak ste si istý, že chcete vysielať nad %1, v rozšírených nastaveniach enkodéra zakážte \"Vynútiť limit dátového toku vysielacou službou\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Upozornenie: Dátový tok vysielaného zvuku bude nastavený na %1, čo je horná hranica pre súčasnú vysielaciu službu. Ak ste si istý, že chcete vysielať nad %1, v rozšírených nastaveniach enkodéra zakážte \"Vynútiť limit dátového toku vysielacou službou\"." Basic.Settings.Output.Simple.Warn.Encoder="Upozornenie: Nahrávanie softvérovým enkodérom s rozdielnou kvalitou než vysielanie spôsobí zvýšenú záťaž CPU pri nahrávaní a vysielaní zároveň." -Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozornenie: Nemôžete použiť viacero QSV kodérov pri vysielaní a nahrávaní zároveň. Ak chcete vysielať a nahrávať zároveň, zmeňte, prosím, kodér vysielania alebo kodér nahrávania." +Basic.Settings.Output.Simple.Warn.Lossless="Varovanie: Bezstratová kvalita generuje ohromne veľké súbory! Bezstratová kvalita môže použiť až 7 gigabajtov za minútu na disku pri vysokých rozlíšeniach a snímkoch za sekundu. Bezstratová kvalita nie je odporúčaná pre dlhé nahrávky pokiaľ nemáte veľmi veľa priestoru na disku." +Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ste si istí, že chcete použiť bezstratovú kvalitu?" +Basic.Settings.Output.Simple.Warn.Lossless.Title="Varovanie bezstratovej kvality!" Basic.Settings.Output.Simple.Encoder.Software="Softvérový (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardvérový (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardvérový (AMD)" -Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardvér (NVENC)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="Hardvérový (NVENC)" Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softvérový (x264, nízke zaťaženie CPU, zvyšuje veľkosť súboru)" Basic.Settings.Output.VideoBitrate="Bitrate videa" Basic.Settings.Output.AudioBitrate="Bitrate zvuku" @@ -547,8 +624,10 @@ Basic.Settings.Output.Reconnect="Automaticky znovupripájať" Basic.Settings.Output.RetryDelay="Čas medzi pokusmi (sekundy)" Basic.Settings.Output.MaxRetries="Maximálny počet pokusov" Basic.Settings.Output.Advanced="Povoliť pokročilé nastavenia enkodéra" -Basic.Settings.Output.EncoderPreset="Predvoľba enkodéra (vyššie = menej CPU)" +Basic.Settings.Output.EncoderPreset="Predvoľba kodéra" Basic.Settings.Output.CustomEncoderSettings="Vlastné nastavenie enkodéra" +Basic.Settings.Output.CustomMuxerSettings="Vlastné nastavenia muxera" +Basic.Settings.Output.NoSpaceFileName="Vygenerovať názov súboru bez medzier" Basic.Settings.Output.Adv.Rescale="Škálovať výstup" Basic.Settings.Output.Adv.AudioTrack="Zvuková stopa" @@ -565,7 +644,7 @@ Basic.Settings.Output.Adv.Recording="Nahrávanie" Basic.Settings.Output.Adv.Recording.Type="Typ" Basic.Settings.Output.Adv.Recording.Type.Standard="Štandardný" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="Vlastný výstup (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Použiť kóder vysielania)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(Použiť kodér vysielania)" Basic.Settings.Output.Adv.Recording.Filename="Formát názvu súboru" Basic.Settings.Output.Adv.Recording.OverwriteIfExists="Prepísať, ak súbor existuje" Basic.Settings.Output.Adv.FFmpeg.Type="Typ výstupu FFmpeg" @@ -590,6 +669,7 @@ Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Nastavenie zmiešavača (ak exis Basic.Settings.Output.Adv.FFmpeg.GOPSize="Interval kľúčových snímkov (snímky)" Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Zobraziť všetky kodeky (aj potenciálne nekompatibilné)" +FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" FilenameFormatting.TT="%CCYY Rok, 4 číslice\n%YY Rok, posledné dve cifry (00-99)\n%MM Mesiac, číslo (01-12)\n%DD Deň v mesiaci, s úvodnou nulou (01-31)\n%hh Hodina vo 24-hod. formáte (00-23)\n%mm Minúta (00-59)\n%ss Sekunda (00-61)\n%% Znak %\n%a Skrátený názov dňa v týždni\n%A Celý názov dňa v týždni\n%b Skrátený názov mesiaca\n%B Celý názov mesiaca\n%d Deň v mesiaci, s úvodnou nulou (01-31)\n%H Hodina v 24-hod. formáte (00-23)\n%I Hodina v 12-hod. formáte (01-12)\n%m Mesiac ako desiatkové číslo (01-12)\n%M Minúta (00-59)\n%p Časť dňa (AM/PM)\n%S Sekunda (00-61)\n%y Rok, posledné dve cifry (00-99)\n%Y Rok\n%z ISO 8601 časový posun od UTC\n%Z Názov alebo skratka časového pásma\n" @@ -605,6 +685,7 @@ Basic.Settings.Video.FPSInteger="Celočíselná hodnota FPS" Basic.Settings.Video.FPSFraction="Zlomková hodnota FPS" Basic.Settings.Video.Numerator="Čitateľ" Basic.Settings.Video.Denominator="Menovateľ" +Basic.Settings.Video.Renderer="Vykresľovač" Basic.Settings.Video.InvalidResolution="Neplatné rozlíšenie. Správne je [šírka]x[výška] (napr. 1920x1080)" Basic.Settings.Video.CurrentlyActive="Výstup videa je práve aktívny. Prosím, vypnite všetky výstupy na zmenu nastavení videa." Basic.Settings.Video.DisableAero="Vypnúť Aero" @@ -616,18 +697,31 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczosov (ostrejšie pri škálov Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Vzorkovacia frekvencia" Basic.Settings.Audio.Channels="Kanály" +Basic.Settings.Audio.Meters="Metre" +Basic.Settings.Audio.MeterDecayRate="Rýchlosť slabnutia" Basic.Settings.Audio.MeterDecayRate.Fast="Rýchlo" Basic.Settings.Audio.MeterDecayRate.Medium="Stredne (typ I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Pomaly (typ II PPM)" Basic.Settings.Audio.PeakMeterType="Typ merača špičiek" Basic.Settings.Audio.PeakMeterType.SamplePeak="Špička vzorky" +Basic.Settings.Audio.PeakMeterType.TruePeak="Pravý Špička (Vyššie využitie CPU)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="VAROVANIE: Priestorový zvuk je zapnutý." +Basic.Settings.Audio.MultichannelWarning="Ak vysielate, uistite sa že vaša vysielacia služba podporuje prijímanie a aj prehrávanie priestorového zvuku. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast sú príklady služieb ktoré priestorový zvuk plne podporujú. Avšak Facebook Live a YouTube Live podporujú prijímanie priestorového zvuku, Facebook Live ho prevádza do stereo zvuku a YouTub Live prehráva iba 2 kanály.\n\nOBS zvukové filtre sú kompatibilné s priestorovým zvukom, no podpora u VST pluginu nie je garantovaná." Basic.Settings.Audio.MultichannelWarning.Title="Povoliť priestorový zvuk?" Basic.Settings.Audio.MultichannelWarning.Confirm="Naozaj si želáte povoliť priestorový zvuk?" +Basic.Settings.Audio.Devices="Zariadenia" +Basic.Settings.Audio.DesktopDevice="Zvuk plochy" +Basic.Settings.Audio.DesktopDevice2="Zvuk plochy 2" +Basic.Settings.Audio.AuxDevice="Mikrofón/Aux - Zvukové zariadenie" +Basic.Settings.Audio.AuxDevice2="Mikrofón/Aux - Zvukové zariadenie 2" +Basic.Settings.Audio.AuxDevice3="Mikrofón/Aux - Zvukové zariadenie 3" +Basic.Settings.Audio.AuxDevice4="Mikrofón/Aux - Zvukové zariadenie 4" Basic.Settings.Audio.EnablePushToMute="Povoliť push-to-mute" Basic.Settings.Audio.PushToMuteDelay="Oneskorenie push-to-mute" Basic.Settings.Audio.EnablePushToTalk="Povoliť push-to-talk" Basic.Settings.Audio.PushToTalkDelay="Oneskorenie push-to-talk" Basic.Settings.Audio.UnknownAudioDevice="[Zariadenie nie je pripojené alebo dostupné]" +Basic.Settings.Audio.Disabled="Zakázané" Basic.Settings.Advanced="Pokročilé" Basic.Settings.Advanced.General.ProcessPriority="Priorita procesu" @@ -639,28 +733,40 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Nízka" Basic.Settings.Advanced.FormatWarning="Upozornenie: Formáty farieb iné ako NV12 sú primárne určené na nahrávanie a nie sú odporúčane pre vysielanie. Použitie iných formátov môže spôsobiť zvýšené využitie CPU pri vysielaní kvôli prevodu medzi formátmi." Basic.Settings.Advanced.Audio.BufferingTime="Čas medzipamäte zvuku" Basic.Settings.Advanced.Video.ColorFormat="Formát farieb" -Basic.Settings.Advanced.Video.ColorSpace="Farebný priestor YUV" -Basic.Settings.Advanced.Video.ColorRange="Rozsah farieb YUV" +Basic.Settings.Advanced.Video.ColorSpace="Farebný priestor" +Basic.Settings.Advanced.Video.ColorRange="Farebný rozsah" Basic.Settings.Advanced.Video.ColorRange.Partial="Čiastočný" Basic.Settings.Advanced.Video.ColorRange.Full="Úplný" +Basic.Settings.Advanced.Audio.MonitoringDevice="Monitorovacie zariadenie" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Predvolené" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Vypnúť zvukové utišovanie Windowsu" Basic.Settings.Advanced.StreamDelay="Oneskorenie vysielania" Basic.Settings.Advanced.StreamDelay.Duration="Trvanie (sekundy)" +Basic.Settings.Advanced.StreamDelay.Preserve="Zachovať bod prerušenia (zväčšiť oneskorenie) pri znovupripojení" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Odhadované využitie pamäte: %1 MB" Basic.Settings.Advanced.Network="Sieť" Basic.Settings.Advanced.Network.BindToIP="Zviazať s IP adresou" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Použiť nový sieťový kód" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Režim nízkej odozvy" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Zakázať klávesové skratky, keď je hlavné okno aktívne" +Basic.Settings.Advanced.AutoRemux="Automaticky previesť do mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(nahrať ako mkv)" Basic.AdvAudio="Pokročilé nastavenia zvuku" Basic.AdvAudio.Name="Názov" -Basic.AdvAudio.Volume="Hlasitosť (%)" +Basic.AdvAudio.Volume="Hlasitosť" Basic.AdvAudio.Mono="Previesť na Mono" +Basic.AdvAudio.Balance="Vyváženie" +Basic.AdvAudio.SyncOffset="Oneskorenie synchronizácie (ms)" +Basic.AdvAudio.Monitoring="Monitorovanie zvuku" +Basic.AdvAudio.Monitoring.None="Vypnuté monitorovanie" +Basic.AdvAudio.Monitoring.MonitorOnly="Iba monitorovanie (žiaden výstup)" +Basic.AdvAudio.Monitoring.Both="Monitorovanie a výstup" Basic.AdvAudio.AudioTracks="Stopy" Basic.Settings.Hotkeys="Klávesové skratky" Basic.Settings.Hotkeys.Pair="Klávesové skratky pre \"%1\" slúžia ako prepínače" +Basic.Settings.Hotkeys.Filter="Filter" Basic.Hotkeys.SelectScene="Prepnúť na scénu" @@ -691,6 +797,11 @@ Hotkeys.Super="Super" Hotkeys.Menu="Menu" Hotkeys.Space="Medzerník" Hotkeys.NumpadNum="Numerická klávesa %1" +Hotkeys.NumpadMultiply="Číselník *" +Hotkeys.NumpadDivide="Číselník /" +Hotkeys.NumpadAdd="Číselník +" +Hotkeys.NumpadSubtract="Číselník -" +Hotkeys.NumpadDecimal="Číselník ," Hotkeys.AppleKeypadNum="%1 (num. klávesnica)" Hotkeys.AppleKeypadMultiply="* (num. klávesnica)" Hotkeys.AppleKeypadDivide="/ (num. klávesnica)" @@ -699,11 +810,19 @@ Hotkeys.AppleKeypadSubtract="- (num. klávesnica)" Hotkeys.AppleKeypadDecimal=". (num. klávesnica)" Hotkeys.AppleKeypadEqual="= (num. klávesnica)" Hotkeys.MouseButton="Tlačidlo myši %1" +Hotkeys.Escape="Esc" Mute="Stlmiť" Unmute="Zrušiť stlmenie" +Push-to-mute="Stlač-pre-stíšenie" +Push-to-talk="Stlač-pre-rozprávanie" +SceneItemShow="Zobraz '%1'" +SceneItemHide="Skry '%1'" +OutputWarnings.NoTracksSelected="Musíte vybrať aspoň jednu zvukovú stopu" +OutputWarnings.MultiTrackRecording="Varovanie: Niektoré formáty (ako FLV) nepodporujú nahrávanie viacerých stôp" +OutputWarnings.MP4Recording="Upozornenie: Nahrávky uložené v MP4/MOV nebude možné obnoviť, ak súbor nebude korektne ukončený (napr. po BSOD, výpadku napájania atp.). Ak chcete nahrávať viacero zvukových stôp, skúste použiť MKV a po dokončení súbor previesť do MP4/MOV (Súbor -> Previesť nahrávky)" FinalScene.Title="Odstrániť scénu" FinalScene.Text="Musí existovať aspoň jedna scéna." @@ -711,8 +830,24 @@ FinalScene.Text="Musí existovať aspoň jedna scéna." NoSources.Title="Žiadne zdroje" NoSources.Text="Nepridali ste žiadne zdroje obrazu, takže výstup bude prázdny. Naozaj chcete pokračovať?" NoSources.Text.AddSource="Zdroje môžete kedykoľvek pridať kliknutím na ikonu + v zozname zdrojov v hlavnom okne." +NoSources.Label="Nemáte žiadne zdroje.\nKliknite na tlačidlo + nižšie\nalebo pravým kliknite sem a nejaký pridajte." ChangeBG="Nastaviť farbu" CustomColor="Vlastná farba" +BrowserSource.EnableHardwareAcceleration="Zapnúť hardvérovú akceleráciu pre zdroje prehliadača" + +About="O programe" +About.Info="OBS Studio je softvér pre nahrávanie videa a živé vysielanie. Má otvorený zdroj a je zdarma." +About.Donate="Prispieť" +About.GetInvolved="Zapojiť sa" +About.Authors="Autori" +About.License="Licencia" +About.Contribute="Podporte projekt OBS" + +ResizeOutputSizeOfSource="Zmeniť veľkosť výstupu (veľkosť zdroja)" +ResizeOutputSizeOfSource.Text="Základné a výstupné rozlíšenie budú zmenené na veľkosť súčasného zdroja." +ResizeOutputSizeOfSource.Continue="Chcete pokračovať?" + +PreviewTransition="Ukážka prechodu" diff --git a/UI/data/locale/sl-SI.ini b/UI/data/locale/sl-SI.ini index d749b2c..ce0ee11 100644 --- a/UI/data/locale/sl-SI.ini +++ b/UI/data/locale/sl-SI.ini @@ -28,16 +28,21 @@ Browse="Prebrskaj" Mono="Mono" Stereo="Stereo" DroppedFrames="Izpuščene sličice %1 (%2 %)" +StudioProgramProjector="Celozaslonski predogled (Program)" PreviewProjector="Celozaslonski predogled (Predogled)" SceneProjector="Celozaslonski predogled (Scena)" SourceProjector="Celozaslonski predogled (Vir)" +StudioProgramWindow="Predogled v oknu (Program)" PreviewWindow="Predogled v oknu (Predogled)" SceneWindow="Predogled v oknu (Scena)" SourceWindow="Predogled v oknu (Vir)" +MultiviewProjector="Večdelni pogled (Celozaslonsko)" +MultiviewWindowed="Večdelni pogled (V oknu)" Clear="Počisti" Revert="Povrni" Show="Prikaži" Hide="Skrij" +UnhideAll="Odkrij vse" Untitled="Neimenovan" New="Nov" Duplicate="Podvoji" @@ -67,19 +72,32 @@ RemuxRecordings="Nadaljuj snemanje" Next="Naprej" Back="Nazaj" Defaults="Privzeto" +HideMixer="Skrij v mešalnik" +TransitionOverride="Vsili prehod" +None="Nič" +StudioMode.Preview="Predogled" +StudioMode.Program="Program" +ShowInMultiview="Pokaži v večdelnem pogledu" +VerticalLayout="Navpična razporeditev" +Group="Skupina" AlreadyRunning.Title="OBS že obratuje" AlreadyRunning.Text="OBS je že v izvajanju! Razen če ste imeli namen zagnati dve aplikaciji naenkrat, zaustavite vse OBS aplikacije v teku, tudi v sistemski vrstici." AlreadyRunning.LaunchAnyway="Vseeno zaženi" + + Copy.Filters="Kopiraj Filtre" Paste.Filters="Prilepi Filtre" + BandwidthTest.Region="Območje" BandwidthTest.Region.US="Združene države Amerike" BandwidthTest.Region.EU="Evropa" BandwidthTest.Region.Asia="Azija" +BandwidthTest.Region.Other="Drugo" +Basic.FirstStartup.RunWizard="Želite zagnati čarovnika za samodejno konfiguracijo? Svoje nastavitve lahko tudi spremenite tako, da kliknete gumb Nastavitve v glavnem oknu." Basic.Stats.MemoryUsage="Poraba Pomnilnika" @@ -97,6 +115,7 @@ Basic.Stats.DroppedFrames="Izpuščanje sličic (omrežje)" Basic.Stats.MegabytesSent="Skupni podatkovni izhod" Basic.Stats.Bitrate="Bitna hitrost" + Updater.Title="Na Voljo So Nove Posodobitve" Updater.Text="Nova Posodobitev Je Na Voljo:" Updater.UpdateNow="Posodobi zdaj" @@ -122,12 +141,14 @@ NoNameEntered.Text="Praznega imena ne morete uporabiti." + ConfirmExit.Title="Zapusti OBS?" ConfirmRemove.Title="Potrdite odstranitev" ConfirmRemove.Text="Ali ste prepričani, da želite odstraniti '$ 1'?" + Output.ConnectFail.Title="Povezava ni uspela" Output.ConnectFail.BadPath="Neveljavna pot ali URL povezava. Prosimo, preverite vaše nastavitve za potrditev, da so veljavne." Output.ConnectFail.ConnectFailed="Ni uspelo povezati s strežnikom" @@ -135,6 +156,7 @@ Output.ConnectFail.Error="Med poskusom povezave s strežnikom je prišlo do nepr Output.ConnectFail.Disconnected="Odklopiti od strežnika." + Output.BadPath.Title="Nepravilna pot do datoteke" Output.BadPath.Text="Pot izhodne konfiguracije ni veljavna. Prosimo, preverite vaše nastavitve, da je določena veljavna pot datoteke." @@ -142,15 +164,9 @@ LogReturnDialog="Dnevnik uspešno naložen" LogReturnDialog.CopyURL="Kopiraj URL" LogReturnDialog.ErrorUploadingLog="Napaka pri nalaganju dnevnika" -LicenseAgreement="Licenčna pogodba" -LicenseAgreement.PleaseReview="Preberite licenčne pogoje pred uporabo OBS. Z uporabo tega programa se strinjate, da ste prebrali in se strinjate s pogoji GNU General Public License v2.0. Prosimo, da se pomaknete navzdol, da vidite preostali del sporazuma." -LicenseAgreement.ClickIAgreeToContinue="Če se strinjate s pogoji pogodbe, kliknite Strinjam se, da nadaljujete naprej. Morate sprejeti dogovor za uporabo OBS." -LicenseAgreement.IAgree="Strinjam se" -LicenseAgreement.Exit="Izhod" - UpdateAvailable="Nova posodobitev je na voljo" -UpdateAvailable.Text="Verzija %1.%2.%3 je sedaj na voljo. Klikni tukaj za prenos" +UpdateAvailable.Text="Verzija %1.%2.%3 je sedaj na voljo. Klikni tukaj za prenos" Basic.DesktopDevice1="Namizni Zvok" Basic.DesktopDevice2="Namizni Zvok 2" @@ -166,6 +182,7 @@ Basic.DisplayCapture="Zajemanje zaslona" + Basic.Main.AddSceneDlg.Title="Dodaj seceno" Basic.Main.AddSceneDlg.Text="Prosimo, vnesite ime scene" @@ -230,43 +247,43 @@ Basic.Main.StartStreaming="Začni oddajati" Basic.Main.StopRecording="Prenehaj snemati" Basic.Main.StopStreaming="Prenehaj oddajati" -Basic.MainMenu.File="&Datoteka" -Basic.MainMenu.File.Export="&Izvozi" -Basic.MainMenu.File.Import="&Uvozi" -Basic.MainMenu.File.ShowRecordings="Pokaži &Posnetke" -Basic.MainMenu.File.Settings="&Nastavitve" -Basic.MainMenu.File.Exit="I&zhod" +Basic.MainMenu.File="Datoteka (&F)" +Basic.MainMenu.File.Export="Izvozi (&E)" +Basic.MainMenu.File.Import="Uvoz (&I)" +Basic.MainMenu.File.ShowRecordings="Pokaži Posnetke (&R)" +Basic.MainMenu.File.Settings="Na&stavitve" +Basic.MainMenu.File.Exit="Izhod (&X)" -Basic.MainMenu.Edit="&Spremeni" -Basic.MainMenu.Edit.Undo="&Razveljavi" -Basic.MainMenu.Edit.Redo="&Uveljavi" -Basic.MainMenu.Edit.UndoAction="&Razveljavi $1" -Basic.MainMenu.Edit.RedoAction="&Uveljavi $1" -Basic.MainMenu.Edit.Transform="&Preoblikuj" -Basic.MainMenu.Edit.Transform.EditTransform="&Uredi preoblikovanje..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Ponostavi preoblikovanje" +Basic.MainMenu.Edit="Spr&emeni" +Basic.MainMenu.Edit.Undo="Razveljavi (&U)" +Basic.MainMenu.Edit.Redo="Uveljavi (&R)" +Basic.MainMenu.Edit.UndoAction="Razveljavi $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Uveljavi $1 (&R)" +Basic.MainMenu.Edit.Transform="Preoblikuj (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Ur&edi preoblikovanje..." +Basic.MainMenu.Edit.Transform.ResetTransform="Ponostavi p&reoblikovanje" Basic.MainMenu.Edit.Transform.Rotate90CW="Zasukati za 90 stopinj v desno" Basic.MainMenu.Edit.Transform.Rotate90CCW="Zasukati za 90 stopinj v levo" Basic.MainMenu.Edit.Transform.Rotate180="Zavrti 180 stopin" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Zrcali &Vodoravno" -Basic.MainMenu.Edit.Transform.FlipVertical="Zrcali &Navpično" -Basic.MainMenu.Edit.Transform.FitToScreen="&Prilagodi zaslonu" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Prilagodi zaslonu" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Zrcali Vodoravno (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Zrcali Na&vpično" +Basic.MainMenu.Edit.Transform.FitToScreen="Prilagodi zaslonu (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Prilagodi za&slonu" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centriraj na zaslon" -Basic.MainMenu.Edit.Order="&Zaporedje" -Basic.MainMenu.Edit.Order.MoveUp="Premakni &Gor" +Basic.MainMenu.Edit.Order="Zap&oredje" +Basic.MainMenu.Edit.Order.MoveUp="Premakni Gor (&U)" Basic.MainMenu.Edit.Order.MoveDown="Premakni &Dol" -Basic.MainMenu.Edit.Order.MoveToTop="Premakni na &Vrh" -Basic.MainMenu.Edit.Order.MoveToBottom="Premakni na &Dno" +Basic.MainMenu.Edit.Order.MoveToTop="Premakni na Vrh (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Premakni na Dno (&B)" -Basic.MainMenu.Help="&Pomoč" -Basic.MainMenu.Help.Logs="&Dnevniki" -Basic.MainMenu.Help.Logs.ShowLogs="&Pokaži Zapisnik" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Naloži &Trenutni dnevnik" -Basic.MainMenu.Help.Logs.UploadLastLog="Naloži &Zadni dnevnik" +Basic.MainMenu.Help="Pomoč (&H)" +Basic.MainMenu.Help.Logs="Dnevniki (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Pokaži Zapi&snik" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Naloži Trenutni dnevnik (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Na&loži Zadni dnevnik" Basic.MainMenu.Help.CheckForUpdates="Preveri za posodobitve" Basic.Settings.ProgramRestart="Program je treba ponovno zagnati, da se te nastavitve uveljavijo." @@ -310,11 +327,6 @@ Basic.Settings.Video.CurrentlyActive="Video izhod je trenutno aktiven. Prosimo, Basic.Settings.Audio="Zvok" Basic.Settings.Audio.SampleRate="Sample Rate" Basic.Settings.Audio.Channels="Kanali" -Basic.Settings.Audio.DesktopDevice="Namizna Zvočna Naprava" -Basic.Settings.Audio.DesktopDevice2="Namizna Zvočna Naprava 2" -Basic.Settings.Audio.AuxDevice="Mic / Dodatne Zvočne Naprave" -Basic.Settings.Audio.AuxDevice2="Mic / Dodatne Zvočne Naprave 2" -Basic.Settings.Audio.AuxDevice3="Mic / Dodatne Zvočne Naprave 3" Basic.Settings.Advanced.Video.ColorRange.Partial="Delno" Basic.Settings.Advanced.Video.ColorRange.Full="Celotno" @@ -332,3 +344,6 @@ Basic.Settings.Advanced.Video.ColorRange.Full="Celotno" + + + diff --git a/UI/data/locale/sq-AL.ini b/UI/data/locale/sq-AL.ini index 7a88840..3c0e51d 100644 --- a/UI/data/locale/sq-AL.ini +++ b/UI/data/locale/sq-AL.ini @@ -78,20 +78,67 @@ None="Asnje" StudioMode.Preview="Inspektim" StudioMode.Program="Program" ShowInMultiview="Shfaqe në Shumë Pamje" +VerticalLayout="Plani vertikal" +Group="Grup" AlreadyRunning.Title="OBS tashmë po funksion" AlreadyRunning.Text="OBS tashmë po kandidon! Nëse nuk keni ndërmend ta bëni këtë, mbyllni çdo rast ekzistues të OBS para se të provoni të shkoni në një instancë të re. Nëse keni OBS vendosur për të minimizuar në tabaka e sistemit, ju lutemi kontrolloni për të parë nëse vazhdon të ekzekutohet atje." AlreadyRunning.LaunchAnyway="Filloje ne nje menyre" + + Copy.Filters="Kopjo Filterat" Paste.Filters="Ngjit Filterat" + BandwidthTest.Region="Regjioni" BandwidthTest.Region.US="Shtetet e Bashkuara" BandwidthTest.Region.EU="Evropë" BandwidthTest.Region.Asia="Azi" BandwidthTest.Region.Other="Të tjera" +Basic.FirstStartup.RunWizard="A deshironi te nisni konfigurimin automatik? Ju gjithashtu mund ta konfiguroni manualisht ne parametrat e tua duke klikuar Parametrat ne butonin tek dritarja kryesore." +Basic.FirstStartup.RunWizard.NoClicked="Nese ju ndryshoni mendjen, ju mund te nisni konfigurimin automatik ne menune e Mjeteve." + +Basic.AutoConfig="Konfigurimi automatik" +Basic.AutoConfig.ApplySettings="Aplikoni Parametrat" +Basic.AutoConfig.StartPage="Informacion mbi perdorimin" +Basic.AutoConfig.StartPage.SubTitle="Specifikoni perse ju deshironi ta perdorni kete program" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimizo per transmetim, rregjistrimi eshte dytesore" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimizo vetem per rregjistrim, une nuk do te rregjistroj" +Basic.AutoConfig.VideoPage="Parametrat e videos" +Basic.AutoConfig.VideoPage.SubTitle="Specifikoni parametrat e videos qe ju deshironi" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Perdorni Aktualen (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Ekrani %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Perdor Aktualen (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 ose 30, por preferoj 60 kur eshte e mundur" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ose 30, por perferoj rezolucion te larte" +Basic.AutoConfig.VideoPage.CanvasExplanation="Shenim: Revolucioni i kanvasit (baza) nuk eshte domosdoshmerisht rezolucioni i njetje me te cilin transmeton ose rregjistron. Rezolucioni i transmetimit/rregjistrimit mund te shkallzohet qe te ulen resurset e perdorimit ose kerkesat e bitratit." +Basic.AutoConfig.StreamPage="Informacion mbi transmetimin" +Basic.AutoConfig.StreamPage.SubTitle="Ju lutem shkruani informacionin e transmetimit" +Basic.AutoConfig.StreamPage.Service="Sherbim" +Basic.AutoConfig.StreamPage.Service.ShowAll="Trego të gjitha..." +Basic.AutoConfig.StreamPage.Server="Server" +Basic.AutoConfig.StreamPage.StreamKey="Celesi i transmetimit" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(linku)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Vlerso bitratin e testit te bandwithit (mund te vonohet disa minuta)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Enkodim me pajisje" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Enkodimi me pajisje eliminim shumicen e perdorimit te procesorit, por mund te kerkoje me shume bitrate qe te ruaje kualitetin." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Lajmerim mbi transmetimin" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Testi i Bandwithit do te transmetoje te dhena te rastesishme pa audio te kanali juaj. Nese ti mundesh, rekomandohet qe ti te fikesh perkohesisht ruajtjen e transmetimeve si video dhe beje transmetimin private derisa testi te mbaroje. Te vazhdoje?" +Basic.AutoConfig.TestPage="Rezultat finale" +Basic.AutoConfig.TestPage.SubTitle.Testing="Programi tani do te ekzekutoje nje set testesh qe te gjeje parametrat ideal" +Basic.AutoConfig.TestPage.SubTitle.Complete="Testi mbaroj" +Basic.AutoConfig.TestPage.TestingBandwidth="Duke performuar nje test per bandwithin, kjo mund te vonohet disa menyra..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Duke u lidhur tek: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Dështoi të lidhej me serverin. Kontrollo lidhjen tënde në internet dhe provo përsëri." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Duke testuar bandwithin per: %1" + + + + + + diff --git a/UI/data/locale/sr-CS.ini b/UI/data/locale/sr-CS.ini index 44ea89e..9e80ef1 100644 --- a/UI/data/locale/sr-CS.ini +++ b/UI/data/locale/sr-CS.ini @@ -28,13 +28,21 @@ Browse="Pretraži" Mono="Mono" Stereo="Stereo" DroppedFrames="Ispušteni frejmovi %1 (%2%)" +StudioProgramProjector="Prikaz preko celog ekrana" PreviewProjector="Projektor celog ekrana (pregled)" SceneProjector="Projektor celog ekrana (scena)" SourceProjector="Projektor celog ekrana (izvor)" +StudioProgramWindow="Prikaz u prozoru" +PreviewWindow="Prikaz u prozoru (radna verzija)" +SceneWindow="Prikaz u prozoru (scena)" +SourceWindow="Prikaz u prozoru (izvorni kod)" +MultiviewProjector="Simultani prikaz (Preko celog ekrana)" +MultiviewWindowed="Simultani prikaz (U prozoru)" Clear="Poništi" -Revert="Povrati" +Revert="Vrati na stara podešavanja" Show="Prikaži" Hide="Sakrij" +UnhideAll="Prikaži sve" Untitled="Nenaslovljeno" New="Novi" Duplicate="Dupliraj" @@ -53,20 +61,152 @@ Hours="Sati" Minutes="Minuta" Seconds="Sekundi" Deprecated="Prevaziđeno" +ReplayBuffer="Buffer za ponovljeni prikaz" +Import="Uvеzi" +Export="Izvezi" +Copy="Kopiraj" +Paste="Paste (Nalepi)" +PasteReference="Nalepi (Referentno)" +PasteDuplicate="Nalepi (Duplikat)" +RemuxRecordings="Snimanje u slabijem kvalitetu (Remuks)" +Next="Napred" +Back="Nazad" +Defaults="Standardno" +HideMixer="Sakrij u mikser panel" +TransitionOverride="Tip tranzicije" +None="Bez" +StudioMode.Preview="Radna verzija" +StudioMode.Program="Program" +ShowInMultiview="Prikaži kao simultani pregled" +VerticalLayout="Organizovano po vertikali" +Group="Grupa objekata" +DoNotShowAgain="Ne prikazuj ponovo" +Default="(Podrazumevano)" +Calculating="Proračunavam..." + +AlreadyRunning.Title="OBS je već porkenut" +AlreadyRunning.Text="OBS je već pokrenut! Osim ako zaista želite da uradite ovo, molimo Vas da prekinete sve procese vezane za OBS pre nego što pokrenete nov zadatak. U slučaju da OBS radi u pozadini, molimo Vas da proverite system tray (ikonice dole desno, pored sata)." +AlreadyRunning.LaunchAnyway="Pokreni bez obzira na sve" +Auth.Authing.Title="Provera autentičnosti.." +Auth.Authing.Text="Provera autentičnosti pomoću %1, molim sačekajte.." +Auth.AuthFailure.Title="Nije moguće utvrditi autentičnost" +Auth.AuthFailure.Text="Nije moguće utvrditi autentičnost pomoću %1:\n\n%2: %3" +Auth.InvalidScope.Title="Obavezna je potvda autentičnosti" +Auth.InvalidScope.Text="Zahtevi za autentifikaciju pomoću %1 su promenjeni. Neki dodaci možda neće biti dostupni." +Auth.LoadingChannel.Title="Učitavanje informacijа o kanalu..." +Auth.LoadingChannel.Text="Učitavanje informacijа o kanalu za %1, molim sačekajte..." +Auth.ChannelFailure.Title="Nije moguće učitati kanal" +Auth.ChannelFailure.Text="Nije moguće učitati informacijе o kanalu za %1\n\n%2: %3" +Auth.Chat="Čet" +Auth.StreamInfo="Informacije o strimovanju" +TwitchAuth.Stats="Twitch statistika" +Copy.Filters="Kopiraj filtere" +Paste.Filters="Nalepi filtere" +BrowserPanelInit.Title="Pokretanje pretraživača..." +BrowserPanelInit.Text="Pokretanje pretraživača, molim sačekajte..." +BandwidthTest.Region="Region" +BandwidthTest.Region.US="Sjedinjene Američke Države" +BandwidthTest.Region.EU="Evropa" +BandwidthTest.Region.Asia="Azija" +BandwidthTest.Region.Other="Ostatak sveta" +Basic.FirstStartup.RunWizard="Da li želite da pokrenete čarobnjaka za automatsko konfigurisanje? Ovo takođe možete uraditi i ručno, ako kliknete na podešavanja (settings) u glavnom prozoru." +Basic.FirstStartup.RunWizard.NoClicked="Ako se predomislite, možete pokrenuti čarobnjaka za automatsko konfigurisanje kad god poželite, iz menija Alata (Tools)." +Basic.AutoConfig="Čarobnjak za automatsko konfigurisanje" +Basic.AutoConfig.ApplySettings="Premeni podešavanja" +Basic.AutoConfig.StartPage="Način upotrebe programa" +Basic.AutoConfig.StartPage.SubTitle="Navedite za šta tačno želite da koristite program" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Optimizuj za steaming (prenos uživo), snimanje je sekindarno" +Basic.AutoConfig.StartPage.PrioritizeRecording="Optimizuj za snimanje, streaming (prenos uživo) se neće izvršiti" +Basic.AutoConfig.VideoPage="Podešavanje videa" +Basic.AutoConfig.VideoPage.SubTitle="Definišite željena video podešavanja koja bisteeleli da koristite" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Koristi trenutna (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Prikaz %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Koristite trenutni (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Ili 60 ili 30, sa akcentom na 60 kad god je moguće" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Ili 60 ili 30, sa akcentom na visoku rezoluciju" +Basic.AutoConfig.VideoPage.CanvasExplanation="Napomena: Osnovna rezolucija nije nužno ista kao rezolucija kojom ćete strimovati ili kojom ćete snimati. Vaša stvarna rezolucija kojom strimujete/snimate može biti skalirana u odnosu na osnovnu kako bi se smanjila upotreba resursa ili optimizovao protok." +Basic.AutoConfig.StreamPage="Informacije o strimovanju" +Basic.AutoConfig.StreamPage.SubTitle="Molimo unesite Vaše informacije o strimovanju" +Basic.AutoConfig.StreamPage.ConnectAccount="Poveži nalog (opciono)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Diskonektuj nalog" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Diskonektuj nalog?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ova promena će biti primenjena odmah. Da li ste sigurni da želite da diskonektujete Vaš nalog?" +Basic.AutoConfig.StreamPage.UseStreamKey="Koristi šifru za strimovanje" +Basic.AutoConfig.StreamPage.Service="Usluga" +Basic.AutoConfig.StreamPage.Service.ShowAll="Prikaži sve..." +Basic.AutoConfig.StreamPage.Service.Custom="Prilagođeno..." +Basic.AutoConfig.StreamPage.Server="Server" +Basic.AutoConfig.StreamPage.StreamKey="Šifra za strimovanje" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Link)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Proceni brzinu protoka testom propusnog opsega (može potrajati nekoliko minuta)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Sa akcentom na hardversko kodiranje" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Hardversko kodiranje sprečava veliku upotrebu procesora, ali može zahtevati veću brzinu protoka kako bi se održao isti nivo kvaliteta." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Upozorenje o strimovanju" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Test propusnog opsega strimuje nasumične video podatke bez zvuka na Vašem kanalu. Preporučeno je da privremeno isključite čuvanje video snimaka strimova i da podesite strim kao privatni dok se test ne završi, ako je to moguće. Želite li da nastavite?" +Basic.AutoConfig.TestPage="Konačni rezultati" +Basic.AutoConfig.TestPage.SubTitle.Testing="Program trenutno izvršava set testova kako bi procenio optimalna podešavanja" +Basic.AutoConfig.TestPage.SubTitle.Complete="Testiranje je završeno" +Basic.AutoConfig.TestPage.TestingBandwidth="U toku je izvođenje testa propusnog opsega, ovo može potrajati nekoliko minuta..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Povezivanje sa: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Neuspеlo povеzivanjе sa sеrvеrom, molimo provеritе Vašu intеrnеt vеzu i pokušajtе ponovo." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Testiranje propusnog opsega za: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="U toku je testiranje strim enkodera, ovo može potrajati par minuta..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="U toku je testiranje enkodera za snimanje, ovo može potrajati par minuta..." +Basic.AutoConfig.TestPage.TestingRes="U toku je testiranje rezolucije, ovo može potrajati nekoliko minuta..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Neuspelo pokretanje enkodera" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Trenutno se testira %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Enkoder strimovanja" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Enkoder snimanja" +Basic.AutoConfig.TestPage.Result.Header="Program je odredio da su ova podešavanja najpovoljnija za vas:" +Basic.AutoConfig.TestPage.Result.Footer="Da biste koristili ova podešavanja, kliknite na ''Primenite Podešavanja''. Da opet konfigurišete wizard i pokušate ponovo, kliknite ''Nazad''. Da konfigurišete ručno podešavanja, kliknite ''Poništi'' i otvorite ''Podešavanja''." + +Basic.Stats="Statistika" +Basic.Stats.CPUUsage="Iskorišćenost procesora" +Basic.Stats.HDDSpaceAvailable="Dostupan prostor na disku" +Basic.Stats.MemoryUsage="Iskorišćenost memorije" +Basic.Stats.AverageTimeToRender="Prosečno vreme potrebno da se prikaže frejm" +Basic.Stats.SkippedFrames="Preskočeni frejmovi zbog zaostatka kodiranja" +Basic.Stats.MissedFrames="Propušteni frejmovi zbog zaostatka prikazivanja" +Basic.Stats.Output.Stream="Strim" +Basic.Stats.Output.Recording="Snimanje" +Basic.Stats.Status="Status" +Basic.Stats.Status.Recording="Snimanje je u toku" +Basic.Stats.Status.Live="UŽIVO" +Basic.Stats.Status.Reconnecting="Ponovno povezivanje" +Basic.Stats.Status.Inactive="Neaktivan" +Basic.Stats.DroppedFrames="Propušteni frejmovi (Mreža)" +Basic.Stats.MegabytesSent="Ukupni podaci na izlazu" +Basic.Stats.Bitrate="Brzina protoka" + +ResetUIWarning.Title="Da li ste sigurni da želite da resetujete korisnički interfejs?" +ResetUIWarning.Text="Resetovanje korisničkog interfejsa će sakriti dodatne dokove. Ako želite da dokovi ponovo postanu vidljivi, potrebno je da se otkriju u meniju pregleda.\n\nDa li ste sigurni da želite da resetujete korisnički interfejs?" + +Updater.Title="Dostupna je nova verzija programa" +Updater.Text="Izašla je nova, unapređena verzija:" +Updater.UpdateNow="Ažuriraj odmah" +Updater.RemindMeLater="Podseti me kasnije" +Updater.Skip="Preskoči ovu verziju" +Updater.Running.Title="Program je trenutno aktivan" +Updater.Running.Text="Neki procesi su već započeti i ažuriranje software-a nije moguće u datim uslovima. Molimo Vas da zatvorite sve započete procese pre nego što se odlučite da ažurirate software" +Updater.NoUpdatesAvailable.Title="Nema novih unapređenja" +Updater.NoUpdatesAvailable.Text="Trenutno nema novih unapređenja" +Updater.FailedToLaunch="Pokretanje ažuriranja software-a nije uspelo" +Updater.GameCaptureActive.Title="Snimanje prikaza ekrana igrice je aktivirano" +Updater.GameCaptureActive.Text="Trenutno je u upotrebi biblioteka za snimanje igre. Molimo da zatvorite sve igre/programe koji su snimljeni (ili restartujte Windows) i pokušate ponovo." QuickTransitions.SwapScenes="Zameni scene pregleda/izlaza nakon prelaza" QuickTransitions.SwapScenesTT="Zamenjuje scene pregleda i izlaza nakon prelaza (ako originalna scena izlaza još uvek postoji).\nOvo neće poništiti promene koje su načinjene nad originalnom scenom izlaza." QuickTransitions.DuplicateScene="Dupliraj scenu" -QuickTransitions.DuplicateSceneTT="Kada se menja ista scena, dozvoli promenu izmena/vidljivosti izvora bez promene izlaza.\nDa biste promenili svojstva izvora bez promene izlaza, omogućite 'Dupliraj izvore'.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji)." +QuickTransitions.DuplicateSceneTT="Prilikom editovanja iste scene, omogući editovanje izmene/vidljivosti izvora bez promene izlaza.\nDa biste editovali svojstva izvora bez promene izlaza, omogućite 'Dupliraj izvore'.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji)." QuickTransitions.EditProperties="Dupliraj izvore" -QuickTransitions.EditPropertiesTT="Kada se menja ista scena, dozvoli promenu svojstava izvora bez promene izlaza.\nOvo može biti upotrebljeno samo ako je 'Dupliraj scene' omogućeno.\nOdređeni izvori (kao što su video hvatanja ili medija izvori) ne podržavaju ovo i ne mogu biti izmenjeni zasebno.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji).\n\nUpozorenje: Zbog toga što izvori mogu biti duplirani, ovo može zahtevati dodatne sistemske ili video resurse." +QuickTransitions.EditPropertiesTT="Kada se edituje ista scena, dozvoli editovanje svojstava izvora bez promene izlaza.\nOvo može biti upotrebljeno samo ako je 'Dupliraj scene' omogućeno.\nOdređeni izvori (kao što su video hvatanja ili medija izvori) ne podržavaju ovo i ne mogu da budu editovani zasebno.\nPromena ove vrednosti će poništiti trenutnu scenu izlaza (ako i dalje postoji).\n\nUpozorenje: Zbog toga što izvori mogu biti duplirani, ovo može zahtevati dodatne sistemske ili video resurse." QuickTransitions.HotkeyName="Brzi prelaz: %1" Basic.AddTransition="Dodaj podesivi prelaz" @@ -89,62 +229,67 @@ NoNameEntered.Title="Molim unesite ispravno ime" NoNameEntered.Text="Ne možete izostaviti ime." ConfirmStart.Title="Započni strim?" -ConfirmStart.Text="Da li ste sigurni da želite započeti strim?" +ConfirmStart.Text="Da li ste sigurni da želite da započnete strimovanje?" ConfirmStop.Title="Zaustavi strim?" -ConfirmStop.Text="Da li ste sigurni da želite zaustaviti strim?" +ConfirmStop.Text="Da li ste sigurni da želite da zaustavite strimovanje?" -ConfirmExit.Title="Napustiti OBS?" -ConfirmExit.Text="OBS je trenutno aktivan. Svi strimovi/snimanja će biti ugašeni. Da li ste sigurni da želite izaći?" + +ConfirmExit.Title="Izađite iz OBS programa?" +ConfirmExit.Text="OBS je trenutno aktivan. Svi strimovi/snimanja će biti ugašeni. Da li ste sigurni da želite da izađete iz programa?" ConfirmRemove.Title="Potvrdi izbacivanje" -ConfirmRemove.Text="Da li ste sigurni da želite izbaciti '$1'?" -ConfirmRemove.TextMultiple="Da li ste sigurni da želite izbaciti %1 stavke?" +ConfirmRemove.Text="Da li ste sigurni da želite da izbacite '$1'?" +ConfirmRemove.TextMultiple="Da li ste sigurni da želite da izbacite %1 stavke?" + +Output.StartStreamFailed="Neuspelo pokretanje strimovanja" +Output.StartRecordingFailed="Neuspelo pokretanje snimanja" +Output.StartReplayFailed="Neuspelo pokretanje bafera za ponovni prikaz" +Output.StartFailedGeneric="Neuspelo pokretanje izlaza. Molimo proverite prijavu za detalje.\n\n Obaveštenje: Ukoliko koristite NVENC ili AMD enkodere, postarajte se da su Vaši video drajveri ažurirani." Output.ConnectFail.Title="Neuspešno povezivanje" Output.ConnectFail.BadPath="Neispravna putanja ili URL konekcije. Molim proverite vaša podešavanja da potvrdite njihovu ispravnost." Output.ConnectFail.ConnectFailed="Neuspešno povezivanje na server" -Output.ConnectFail.InvalidStream="Ne mogu pristupiti navedenom kanalu ili strim ključu, molim proverite vaš strim ključ. Ako je ispravan, možda postoji problem pri povezivanju na server." +Output.ConnectFail.InvalidStream="Nemoguće je pristupiti navedenom kanalu ili strim ključu, molim proverite vaš strim ključ. Ako je ispravan, možda postoji problem pri povezivanju na server." Output.ConnectFail.Error="Neočekivana greška u povezivanju sa serverom. Više informacija se nalazi u log datoteci." Output.ConnectFail.Disconnected="Prekinuta veza sa serverom." + Output.RecordFail.Title="Neuspešno započinjanje snimanja" Output.RecordFail.Unsupported="Izlazni format ili nije podržan ili ne podržava više od jedne zvučne trake. Molim proverite podešavanja i pokušajte ponovo." Output.RecordNoSpace.Title="Nedovoljno prostora na disku" Output.RecordNoSpace.Msg="Nema dovoljno prostora na disku da se nastavi snimanje." Output.RecordError.Title="Greška pri snimanju" Output.RecordError.Msg="Neodređena greška se dogodila pri snimanju." +Output.ReplayBuffer.NoHotkey.Title="Nije podešena prečica na tastaturi!" +Output.ReplayBuffer.NoHotkey.Msg="Nije podešena prečica za bafer ponovnog prikazivanja. Molimo podesite prečicu ''Sačuvaj'', za čuvanje snimaka koji su ponovo prikazivani." Output.BadPath.Title="Neispravna putanja datoteke" -Output.BadPath.Text="Podešavana putanja za dokument je neispravna. Molim proverite vaša podešavanja da potvrdite ispravnost putanje." +Output.BadPath.Text="Podešena putanja za izlaz dokumenta je neispravna. Molim proverite vaša podešavanja da potvrdite ispravnost putanje." LogReturnDialog="Slanje log dokumenta uspešno" LogReturnDialog.CopyURL="Kopiraj URL" -LogReturnDialog.ErrorUploadingLog="Greška u slanju log dokumenta" - -LicenseAgreement="Uslovi korišćenja" -LicenseAgreement.PleaseReview="Molim proverite uslove korišćenja pre upotrebe OBS-a. Upotrebom ovog programa smatra se da ste pročitali i prihvatili uslove GNU General Public License v2.0 licence. Molimo skrolujte niže da vidite ostatak ugovora." -LicenseAgreement.ClickIAgreeToContinue="Ako prihvatate uslove korišćenja, kliknite na Slažem se da nastavite. Da biste koristili OBS morate prihvatiti ugovor." -LicenseAgreement.IAgree="Slažem se" -LicenseAgreement.Exit="Izlaz" +LogReturnDialog.ErrorUploadingLog="Greška u učitavanju log dokumenta" Remux.SourceFile="OBS snimak" Remux.TargetFile="Datoteka" -Remux.Remux="Remux" +Remux.Remux="Remuks" +Remux.Stop="Zaustavi remuks" +Remux.ClearFinished="Obriši završene elemente" +Remux.ClearAll="Obriši sve elemente" Remux.OBSRecording="OBS snimak" -Remux.FinishedTitle="Remux završen" -Remux.Finished="Završen remux snimka" -Remux.FinishedError="Remux završen, ali datoteka možda nije kompletirana" -Remux.SelectRecording="Izaberi OBS snimak …" -Remux.SelectTarget="Izaberi datoteku …" -Remux.FileExistsTitle="Datoteka postoji" -Remux.FileExists="Datoteka već postoji, da li želite da je prepišete?" -Remux.ExitUnfinishedTitle="Remux u toku" -Remux.ExitUnfinished="Remux nije završen, ako sada zaustavite proces datoteka može biti neupotrebljiva.\nDa li ste sigurni da želite zaustaviti remux?" +Remux.FinishedTitle="Remuks je završen" +Remux.Finished="Završen je remuks snimka" +Remux.FinishedError="Remuks je završen, ali datoteka možda nije kompletirana" +Remux.FileExistsTitle="Ciljni fajl već postoji" +Remux.FileExists="Sledeći ciljni fajlovi već postoje. Da li želite da ih zamenite novim?" +Remux.ExitUnfinishedTitle="Remuks u toku" +Remux.ExitUnfinished="Remuks nije završen, ako sada zaustavite proces datoteka može biti neupotrebljiva.\nDa li ste sigurni da želite da zaustavite remuks?" +Remux.HelpText="Priložite fajlove u ovaj prozor za remuks, ili izaberite praznu ''OBS Recording'' ćeliju da potražite fajl." UpdateAvailable="Dostupna je novija verzija programa" -UpdateAvailable.Text="Verzija %1.%2.%3 je dostupna. Kliknite ovde da preuzmete" +UpdateAvailable.Text="Verzija %1.%2.%3 je dostupna. Kliknite ovde da preuzmete" Basic.DesktopDevice1="Zvuk sa računara" Basic.DesktopDevice2="Zvuk sa računara 2" @@ -158,6 +303,7 @@ Basic.DisplayCapture="Prikaži ulaz" Basic.Main.PreviewConextMenu.Enable="Omogući pregled" + ScaleFiltering="Filter uvećanja" ScaleFiltering.Point="Tačka" ScaleFiltering.Bilinear="Bilinearno" @@ -176,6 +322,10 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="Prvo gornje polje" Deinterlacing.BottomFieldFirst="Prvo donje polje" +VolControl.SliderUnmuted="Slajder jačine zvuka za '%1': %2" +VolControl.SliderMuted="Slajder jačine zvuka za '%1': %2 (trenutno isključen)" +VolControl.Mute="Isključite zvuk '%1'" +VolControl.Properties="Svojstva '%1'" Basic.Main.AddSceneDlg.Title="Dodaj scenu" Basic.Main.AddSceneDlg.Text="Molim unesite ime scene" @@ -192,6 +342,8 @@ AddProfile.Text="Molim unesite ime profila" RenameProfile.Title="Promeni ime profila" +Basic.Main.MixerRename.Title="Preimenujte izvor zvuka" +Basic.Main.MixerRename.Text="Molimo unesite naziv izvora zvuka" Basic.Main.PreviewDisabled="Pregled je trenutno onemogućen" @@ -225,10 +377,10 @@ Basic.InteractionWindow="Interakcija sa '%1'" Basic.StatusBar.Reconnecting="Veza je prekinuta, ponovno povezivanje za %2 sekund(i) (%1 pokušaj)" Basic.StatusBar.AttemptingReconnect="Pokušavam ponovno povezivanje... (%1 pokušaj)" Basic.StatusBar.ReconnectSuccessful="Ponovno povezivanje uspešno" -Basic.StatusBar.Delay="Odlaganje (%1 sek)" -Basic.StatusBar.DelayStartingIn="Odlaganje (počinje za %1 sek)" -Basic.StatusBar.DelayStoppingIn="Odlaganje (zaustavljam za %1 sek)" -Basic.StatusBar.DelayStartingStoppingIn="Odlaganje (zaustavljam za %1 sek, počinje za %2 sek)" +Basic.StatusBar.Delay="Kašnjenje (%1 sek)" +Basic.StatusBar.DelayStartingIn="Kašnjenje (počinje za %1 sek)" +Basic.StatusBar.DelayStoppingIn="Kašnjenje (zaustavlja se za %1 sek)" +Basic.StatusBar.DelayStartingStoppingIn="Kašnjenje (zaustavlja se za %1 sek, počinje za %2 sek)" Basic.Filters="Filteri" Basic.Filters.AsyncFilters="Zvučni/Video filteri" @@ -249,13 +401,13 @@ Basic.TransformWindow.Bounds="Veličina okvira" Basic.TransformWindow.Crop="Isecanje" Basic.TransformWindow.Alignment.TopLeft="Gore levo" -Basic.TransformWindow.Alignment.TopCenter="Gore centar" +Basic.TransformWindow.Alignment.TopCenter="Gore, na sredini" Basic.TransformWindow.Alignment.TopRight="Gore desno" -Basic.TransformWindow.Alignment.CenterLeft="Levo centar" +Basic.TransformWindow.Alignment.CenterLeft="Na sredini, levo" Basic.TransformWindow.Alignment.Center="Centar" -Basic.TransformWindow.Alignment.CenterRight="Desno centar" +Basic.TransformWindow.Alignment.CenterRight="Na sredini, desno" Basic.TransformWindow.Alignment.BottomLeft="Donje levo" -Basic.TransformWindow.Alignment.BottomCenter="Donje centar" +Basic.TransformWindow.Alignment.BottomCenter="Dole, na sredini" Basic.TransformWindow.Alignment.BottomRight="Donje desno" Basic.TransformWindow.BoundsType.None="Bez okvira" @@ -266,25 +418,32 @@ Basic.TransformWindow.BoundsType.ScaleToWidth="Skaliraj do širine okvira" Basic.TransformWindow.BoundsType.ScaleToHeight="Skaliraj do visine okvira" Basic.TransformWindow.BoundsType.Stretch="Razvuci do okvira" -Basic.Main.AddSourceHelp.Title="Ne mogu dodati izvor" -Basic.Main.AddSourceHelp.Text="Potrebno je najmanje jedna scena da dodate izvor." +Basic.Main.AddSourceHelp.Title="Nije moguće dodati izvor" +Basic.Main.AddSourceHelp.Text="Potrebna je najmanje jedna scena da biste dodali izvor." Basic.Main.Scenes="Scene" Basic.Main.Sources="Izvori" +Basic.Main.Controls="Kontrole" Basic.Main.Connecting="Povezivanje..." Basic.Main.StartRecording="Počni snimanje" +Basic.Main.StartReplayBuffer="Pokreni bafer za ponovno prikazivanje" Basic.Main.StartStreaming="Počni strimovanje" Basic.Main.StopRecording="Zaustavi snimanje" Basic.Main.StoppingRecording="Zaustavljanje snimanja..." +Basic.Main.StopReplayBuffer="Zaustavi bafer za ponovno prikazivanje" +Basic.Main.StoppingReplayBuffer="Zaustavljanje bafera za ponovno prikazivanje je u toku..." Basic.Main.StopStreaming="Zaustavi strimovanje" Basic.Main.StoppingStreaming="Zaustavljanje emitovanja..." -Basic.Main.ForceStopStreaming="Zaustavi strimovanje (poništi odlaganje)" +Basic.Main.ForceStopStreaming="Zaustavi strimovanje (poništi kašnjenje)" +Basic.Main.Group="Grupa %1" +Basic.Main.GroupItems="Grupiši odabrane elemente" +Basic.Main.Ungroup="Razdvoji elemente grupe" Basic.MainMenu.File="&Fajl" -Basic.MainMenu.File.Export="Izv&ezi" -Basic.MainMenu.File.Import="Uvoz (&I)" +Basic.MainMenu.File.Export="Izvezi (&E)" +Basic.MainMenu.File.Import="Uvezi (&I)" Basic.MainMenu.File.ShowRecordings="P&rikaži snimke" -Basic.MainMenu.File.Remux="Re&mux snimaka" +Basic.MainMenu.File.Remux="Re&muks snimaka" Basic.MainMenu.File.Settings="Podešavanja (&S)" Basic.MainMenu.File.ShowSettingsFolder="Prikaži folder sa podešavanjima" Basic.MainMenu.File.ShowProfileFolder="Prikaži folder sa profilima" @@ -292,8 +451,8 @@ Basic.MainMenu.AlwaysOnTop="Uvek na vrhu (&A)" Basic.MainMenu.File.Exit="Izlaz (&X)" Basic.MainMenu.Edit="Izm&ena" -Basic.MainMenu.Edit.Undo="Vrati (&U)" -Basic.MainMenu.Edit.Redo="U&radi ponovo" +Basic.MainMenu.Edit.Undo="Vrati unazad (&U)" +Basic.MainMenu.Edit.Redo="Ponovi (&R)" Basic.MainMenu.Edit.UndoAction="Vrati $1 (&U)" Basic.MainMenu.Edit.RedoAction="U&radi ponovo $1" Basic.MainMenu.Edit.LockPreview="Zak&ljučaj prikaz" @@ -302,7 +461,9 @@ Basic.MainMenu.Edit.Scale.Window="Skaliraj na veličinu prozora" Basic.MainMenu.Edit.Scale.Canvas="Platno (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Izlaz (%1x%2)" Basic.MainMenu.Edit.Transform="&Transformiši" -Basic.MainMenu.Edit.Transform.EditTransform="Izm&eni transformaciju..." +Basic.MainMenu.Edit.Transform.EditTransform="Edituj transformaciju... (&E)" +Basic.MainMenu.Edit.Transform.CopyTransform="Kopiraj transformaciju" +Basic.MainMenu.Edit.Transform.PasteTransform="Nalepi transformaciju" Basic.MainMenu.Edit.Transform.ResetTransform="Poništi t&ransformaciju" Basic.MainMenu.Edit.Transform.Rotate90CW="Okreni za 90 stepeni u smeru kazaljke na satu" Basic.MainMenu.Edit.Transform.Rotate90CCW="Okreni za 90 stepeni u kontra smeru kazaljke na satu" @@ -319,25 +480,41 @@ Basic.MainMenu.Edit.Order.MoveToTop="Pomeri na vrh (&T)" Basic.MainMenu.Edit.Order.MoveToBottom="Pomeri na dno (&B)" Basic.MainMenu.Edit.AdvAudio="N&apredna podešavanja zvuka" -Basic.MainMenu.View="Pogled (&V)" +Basic.MainMenu.View="Pregled (&V)" Basic.MainMenu.View.Toolbars="Linije ala&tki" +Basic.MainMenu.View.Docks="Dokovi" +Basic.MainMenu.View.Docks.ResetUI="Resetuj korisnički interfejs" +Basic.MainMenu.View.Docks.LockUI="Zaključaj korisnički interfejs" Basic.MainMenu.View.Toolbars.Listboxes="Spisak stavki (&L)" Basic.MainMenu.View.SceneTransitions="S&censki prelazi" Basic.MainMenu.View.StatusBar="&Statusna linija" +Basic.MainMenu.View.Fullscreen.Interface="Interfejs na celom ekranu" Basic.MainMenu.SceneCollection="Kolekcija &scena" Basic.MainMenu.Profile="&Profil" +Basic.MainMenu.Profile.Import="Uvezi profil" +Basic.MainMenu.Profile.Export="Izvezi profil" +Basic.MainMenu.SceneCollection.Import="Uvezi kolekciju scena" +Basic.MainMenu.SceneCollection.Export="Izvezi kolekciju scena" +Basic.MainMenu.Profile.Exists="Ovaj profil već postoji" +Basic.MainMenu.SceneCollection.Exists="Ova kolekcija scena već postoji" Basic.MainMenu.Tools="Ala&ti" Basic.MainMenu.Help="Pomoć (&H)" +Basic.MainMenu.Help.HelpPortal="&Portal za pomoć" Basic.MainMenu.Help.Website="Poseti stranicu (&W)" +Basic.MainMenu.Help.Discord="Pridružite se &Discord serveru" Basic.MainMenu.Help.Logs="&Log datoteke" Basic.MainMenu.Help.Logs.ShowLogs="Prikaži log datoteke (&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="Pošalji trenutnu log datoteku (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Pošalji pos&lednju log datoteku" Basic.MainMenu.Help.Logs.ViewCurrentLog="Prikaži trenutni zapisnik (&V)" Basic.MainMenu.Help.CheckForUpdates="Proveri verziju programa" +Basic.MainMenu.Help.CrashLogs="Izveštaji o prekidima (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Prikaži izveštaje o prekidima (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Postavi pos&lednji izveštaj o prekidu" +Basic.MainMenu.Help.About="O progr&amu" Basic.Settings.ProgramRestart="Program mora biti ponovo pokrenut da bi ova podešavanja bila prihvaćena." Basic.Settings.ConfirmTitle="Potvrdite promene" @@ -346,8 +523,11 @@ Basic.Settings.Confirm="Postoje promene koje nisu sačuvane. Sačuvati?" Basic.Settings.General="Opšte" Basic.Settings.General.Theme="Tema" Basic.Settings.General.Language="Jezik" +Basic.Settings.General.EnableAutoUpdates="Automatski potraži ažuriranja pri pokretanju" +Basic.Settings.General.OpenStatsOnStartup="Prikaži statistiku pri pokretanju" Basic.Settings.General.WarnBeforeStartingStream="Prikaži prozor za potvrdu kada se započinju strimovi" Basic.Settings.General.WarnBeforeStoppingStream="Prikaži prozor za potvrdu kada se zaustavljaju strimovi" +Basic.Settings.General.Projectors="Projektori" Basic.Settings.General.HideProjectorCursor="Sakrij pokazivač na projektorima" Basic.Settings.General.ProjectorAlwaysOnTop="Uvek postavi projektor na vrh prozora" Basic.Settings.General.Snapping="Poravnavanje privlačenjem izvora" @@ -357,10 +537,34 @@ Basic.Settings.General.SourceSnapping="Privlačenje izvora ka drugim izvorima" Basic.Settings.General.SnapDistance="Osetljivost privlačenja" Basic.Settings.General.RecordWhenStreaming="Automatsko snimanje pri emitovanju" Basic.Settings.General.KeepRecordingWhenStreamStops="Nastavi snimati kada se emitovanje zaustavi" -Basic.Settings.General.SysTrayWhenStarted="Pri pokretanju minimiziraj na ikonicu u sistemskom panelu" +Basic.Settings.General.ReplayBufferWhileStreaming="Automatski pokreni bafer ponovnog prikazivanja tokom strimovanja" +Basic.Settings.General.KeepReplayBufferStreamStops="Nakon zaustavljanja strimovanja, zadrži bafer ponovnog prikazivanja kao aktivan" +Basic.Settings.General.SysTray="System tray" +Basic.Settings.General.SysTrayWhenStarted="Pri pokretanju minimizuj na ikonicu u sistemskom panelu" +Basic.Settings.General.SystemTrayHideMinimize="Uvek minimizuj system tray umesto task bar-a" +Basic.Settings.General.SaveProjectors="Sačuvaj projektore pre izlaska iz programa" +Basic.Settings.General.Preview="Pregled" +Basic.Settings.General.OverflowHidden="Sakrij višak" +Basic.Settings.General.OverflowAlwaysVisible="Višak je uvek vidljiv" +Basic.Settings.General.OverflowSelectionHidden="Prikaži višak čak i kada je izvor nevidljiv" +Basic.Settings.General.SwitchOnDoubleClick="Prelaz na scenu duplim klikom" +Basic.Settings.General.StudioPortraitLayout="Uključi portret/vertikalni prikaz" +Basic.Settings.General.Multiview="Simultani prikaz" +Basic.Settings.General.Multiview.MouseSwitch="Promena scene klikom" +Basic.Settings.General.Multiview.DrawSourceNames="Prikaži imena scena" +Basic.Settings.General.Multiview.DrawSafeAreas="Prikaži sigurne oblasti (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Raspored simultanog prikaza" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Horizontalno, gore (8 scena)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Horizontalno, dole (8 scena)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Vertikalno, levo (8 scena)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Vertikalno, desno (8 scena)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horizontalno, gore (24 scene)" Basic.Settings.Stream="Strim" Basic.Settings.Stream.StreamType="Vrsta strima" +Basic.Settings.Stream.Custom.UseAuthentication="Koristi autentifikaciju" +Basic.Settings.Stream.Custom.Username="Korisničko ime" +Basic.Settings.Stream.Custom.Password="Šifra" Basic.Settings.Output="Izlaz" Basic.Settings.Output.Format="Format snimanja" @@ -372,6 +576,14 @@ Basic.Settings.Output.Mode="Režim izlaza" Basic.Settings.Output.Mode.Simple="Jednostavno" Basic.Settings.Output.Mode.Adv="Napredno" Basic.Settings.Output.Mode.FFmpeg="FFmpeg izlaz" +Basic.Settings.Output.UseReplayBuffer="Uključi bafer ponovnog prikazivanja" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Maksimalno vreme ponovnog prikazivanja (sekunde)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimalna memorija (MB)" +Basic.Settings.Output.ReplayBuffer.Estimate="Procenjena iskorišćenost memorije: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Nemoguće je proceniti iskorišćenost memorije. Molimo podesite maksimalnu granicu memorije." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Obaveštenje: Pobrinite se da u sekciji za prečice namestite prečicu na tastaturi za bafer ponovnog prikazivanja)" +Basic.Settings.Output.ReplayBuffer.Prefix="Prefiks imena fajla bafera reprodukovanja" +Basic.Settings.Output.ReplayBuffer.Suffix="Sufiks" Basic.Settings.Output.Simple.SavePath="Putanja za snimanje" Basic.Settings.Output.Simple.RecordingQuality="Kvalitet snimanja" Basic.Settings.Output.Simple.RecordingQuality.Stream="Isto kao strim" @@ -383,8 +595,7 @@ Basic.Settings.Output.Simple.Warn.AudioBitrate="Upozorenje: Zvučni protok strim Basic.Settings.Output.Simple.Warn.Encoder="Upozorenje: Snimanje sa softverskim enkoderom drugačijeg kvaliteta u odnosu na strim će zahtevati dodatnu procesorsku snagu ako strimujete i snimate u isto vreme." Basic.Settings.Output.Simple.Warn.Lossless="Upozorenje: Kvalitet bez gubitka stvara izričito velike datoteke! Kvalitet bez gubitka može koristiti više od 7 gigabajta prostora na disku po minutu pri visokim rezolucijama i framerate-om. Kvalitet bez gubitka nije preporučen za duže snimanje osim ako imate veliku količinu slobodnog prostora na disku." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Da li ste sigurni da želite koristiti kvalitet bez gubitka?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje za kvalitet bez gubitka!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Upozorenje: Ne možete koristi više odvojenih QSV enkodera kada emitujete i snimate u isto vreme. Ako želite da emitujete i snimate u isto vreme, molim promenite ili enkoder snimanja ili enkoder emitovanja." +Basic.Settings.Output.Simple.Warn.Lossless.Title="Upozorenje o kvalitetu bez gubitka!" Basic.Settings.Output.Simple.Encoder.Software="Softverski (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Mašinski (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Mašinski (AMD)" @@ -393,11 +604,11 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Softverski (x264 niska upot Basic.Settings.Output.VideoBitrate="Protok videa" Basic.Settings.Output.AudioBitrate="Protok zvuka" Basic.Settings.Output.Reconnect="Automatski poveži ponovo" -Basic.Settings.Output.RetryDelay="Pauza pre ponovnog pokušaja (sekunde)" +Basic.Settings.Output.RetryDelay="Kašnjenje ponovnog pokušaja (sekunde)" Basic.Settings.Output.MaxRetries="Maksimalan broj ponovnih pokušaja" Basic.Settings.Output.Advanced="Omogući napredna podešavanja kompresora" -Basic.Settings.Output.EncoderPreset="Šablon enkodera (veće = manje CPU)" -Basic.Settings.Output.CustomEncoderSettings="Prilagođena enkoder podešavanja" +Basic.Settings.Output.EncoderPreset="Predefinisano podešavanje enkodera" +Basic.Settings.Output.CustomEncoderSettings="Prilagođena podešavanja enkodera" Basic.Settings.Output.CustomMuxerSettings="Posebna podešavanja muksera" Basic.Settings.Output.NoSpaceFileName="Stvori ime datoteke bez razmaka" @@ -409,6 +620,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Izvor 1" Basic.Settings.Output.Adv.Audio.Track2="Izvor 2" Basic.Settings.Output.Adv.Audio.Track3="Izvor 3" Basic.Settings.Output.Adv.Audio.Track4="Izvor 4" +Basic.Settings.Output.Adv.Audio.Track5="Traka 5" +Basic.Settings.Output.Adv.Audio.Track6="Traka 6" Basic.Settings.Output.Adv.Recording="Snimanje" Basic.Settings.Output.Adv.Recording.Type="Vrsta" @@ -436,6 +649,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Podešavanja video enkodera ( Basic.Settings.Output.Adv.FFmpeg.AEncoder="Zvučni enkoder" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Podešavanja zvučnog enkodera (ako postoje)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Podešavanja muxer-a (ako postoje)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Interval ključnih frejmova (frejmovi)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Prikaži sve kodeke (čak iako su potencijalno nekompatibilni)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" @@ -465,47 +680,64 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (oštrije skaliranje, 32 u Basic.Settings.Audio="Zvuk" Basic.Settings.Audio.SampleRate="Protok" Basic.Settings.Audio.Channels="Kanali" -Basic.Settings.Audio.DesktopDevice="Zvuk sa računara" -Basic.Settings.Audio.DesktopDevice2="Zvuk sa računara 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/Ulaz" -Basic.Settings.Audio.AuxDevice2="Mikrofon/Ulaz 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/Ulaz 3" +Basic.Settings.Audio.MeterDecayRate.Fast="Brza" +Basic.Settings.Audio.MeterDecayRate.Medium="Srednja (Tip I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Spora (Tip II PPM)" +Basic.Settings.Audio.PeakMeterType="Tip merača vrha" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Vrh uzorka" +Basic.Settings.Audio.PeakMeterType.TruePeak="Pravi vrh (Veća upotreba procesora)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="UPOZORENJE: Zvuk okruženja je uključen." +Basic.Settings.Audio.MultichannelWarning="Ako je strim u toku, proverite da li vaša striming usluga podržava integraciju i plejbek zvuka okruženja. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast su primeri gde je zvuk okruženja u potpunosti podržan. Iako i Facebook Live i YouTube Live podržavaju integraciju okruženja, Facebook Live miksuje kao stereo, a YouTube Live reprodukuje samo dva kanala.\n\nOBS zvučni filteri su kompatibilni sa zvukom okruženja, mada podrška za VST priključke nije zagarantovana." +Basic.Settings.Audio.MultichannelWarning.Title="Da li želite da uključite zvuk okruženja?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Da li ste sigurni da želite da uključite zvuk okruženja?" +Basic.Settings.Audio.Devices="Uređaji" Basic.Settings.Audio.EnablePushToMute="Omogući stisni-za-mutiranje" -Basic.Settings.Audio.PushToMuteDelay="Stisni-za-mutiranje pauza" +Basic.Settings.Audio.PushToMuteDelay="Kašnjenje opcije stisni-za-mutiranje" Basic.Settings.Audio.EnablePushToTalk="Omogući Stisni-za-govor" -Basic.Settings.Audio.PushToTalkDelay="Stisni-za-govor pauza" +Basic.Settings.Audio.PushToTalkDelay="Kašnjenje opcije stisni-za-govor" Basic.Settings.Audio.UnknownAudioDevice="[Uređaj nije povezan ili nije dostupan]" +Basic.Settings.Audio.Disabled="Onemogućeno" Basic.Settings.Advanced="Napredno" Basic.Settings.Advanced.General.ProcessPriority="Prioritet procesa" Basic.Settings.Advanced.General.ProcessPriority.High="Visoki" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Iznad normalnog" Basic.Settings.Advanced.General.ProcessPriority.Normal="Normalni" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Niži od normalnog" Basic.Settings.Advanced.General.ProcessPriority.Idle="Besposleni" Basic.Settings.Advanced.FormatWarning="Upozorenje: Formati boja različiti od NV12 su prvenstveno namenjeni za snimanje i nisu preporučeni za strimovanje. Strimovanje može prouzrokovati povišeno zauzeće procesora zbog pretvaranja formata boja." Basic.Settings.Advanced.Audio.BufferingTime="Vreme baferovanja zvuka" Basic.Settings.Advanced.Video.ColorFormat="Format boja" -Basic.Settings.Advanced.Video.ColorSpace="YUV prostor boja" -Basic.Settings.Advanced.Video.ColorRange="YUV raspon boja" Basic.Settings.Advanced.Video.ColorRange.Partial="Delimično" Basic.Settings.Advanced.Video.ColorRange.Full="Potpuno" -Basic.Settings.Advanced.StreamDelay="Odlaganje strima" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Podrazumevano" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Isključi Windows audio ducking" +Basic.Settings.Advanced.StreamDelay="Kašnjenje strimovanja" Basic.Settings.Advanced.StreamDelay.Duration="Trajanje (sekunde)" -Basic.Settings.Advanced.StreamDelay.Preserve="Očuvaj tačku prekidanja (povećava odlaganje) kada se ponovo povezuje" +Basic.Settings.Advanced.StreamDelay.Preserve="Sačuvaj tačku prekida (povećaj kašnjenje) prilikom ponovnog povezivanja" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Procenjena upotreba memorije: %1 MB" Basic.Settings.Advanced.Network="Mreža" Basic.Settings.Advanced.Network.BindToIP="Veži se za IP" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="Uključi novu šifru za umrežavanje" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Režim slabe prikrivenosti" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Isključi prečice kada je glavni prozor u fokusu" +Basic.Settings.Advanced.AutoRemux="Automatski uradi remuks u mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(snimi kao mkv)" Basic.AdvAudio="Napredna podešavanja zvuka" Basic.AdvAudio.Name="Ime" -Basic.AdvAudio.Volume="Glasnoća (%)" Basic.AdvAudio.Mono="Spoji u mono" -Basic.AdvAudio.Panning="Pomeranje" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Razlika u sinhronizaciji (ms)" +Basic.AdvAudio.Monitoring="Audio nadzor" +Basic.AdvAudio.Monitoring.None="Isključi nadzor" +Basic.AdvAudio.Monitoring.MonitorOnly="Samo nadzor (izlaz bez zvuka)" +Basic.AdvAudio.Monitoring.Both="Nadzor i izlaz" Basic.AdvAudio.AudioTracks="Izvori" Basic.Settings.Hotkeys="Prečice" Basic.Settings.Hotkeys.Pair="Kombinacije tastera deljene sa '%1' se ponašaju kao prekidači" +Basic.Settings.Hotkeys.Filter="Filter" Basic.Hotkeys.SelectScene="Prebaci na scenu" @@ -549,6 +781,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Miš %1" +Hotkeys.Escape="Esc" Mute="Mutiraj" Unmute="Odmutiraj" @@ -561,7 +794,26 @@ SceneItemHide="Sakrij '%1'" OutputWarnings.NoTracksSelected="Morate odabrati makar jednu traku" OutputWarnings.MultiTrackRecording="Upozorenje: Određeni formati (kao što je FLV) ne podržavaju više traka po snimku" - - +FinalScene.Title="Obriši scenu" +FinalScene.Text="Mora da postoji barem jedna scena, kako bi bila obrisana." + +NoSources.Title="Nema izvora" +NoSources.Text="Izgleda da još uvek niste dodali ni jedan video izvor, tako da će se prikazivati samo prazan ekran. Da li ste sigurni da želite da nastavite?" +NoSources.Text.AddSource="Možete da dodate izvore u bilo kom trenutku, klikom na ikonicu ''+'' ispod dugmeta ''Izvori'' u glavnom prozoru." + +ChangeBG="Podesi boju" +CustomColor="Personalizovana boja" + +BrowserSource.EnableHardwareAcceleration="Uključi izvor pretraživača hardverskog ubrzanja" + +About="O programu" +About.Info="OBS Studio je besplatan softver otvorenog koda koji omogućava video snimanje i strimovanje uživo." +About.GetInvolved="Učestvujte" +About.Authors="Autori" +About.License="Licenca" + +ResizeOutputSizeOfSource="Promeni veličinu izlaza (veličina izvora)" +ResizeOutputSizeOfSource.Text="Rezolucija izlaza i osnovna rezolucija će biti promenjene kako bi odgovarale veličini trenutnog izvora." +ResizeOutputSizeOfSource.Continue="Da li želite da nastavite?" diff --git a/UI/data/locale/sr-SP.ini b/UI/data/locale/sr-SP.ini index 49b2f82..5f94565 100644 --- a/UI/data/locale/sr-SP.ini +++ b/UI/data/locale/sr-SP.ini @@ -1,8 +1,8 @@ -Language="Српски" -Region="Serbia" +Language="српски" +Region="Србија" -OK="ОК" +OK="У реду" Apply="Примени" Cancel="Откажи" Close="Затвори" @@ -14,27 +14,35 @@ No="Не" Add="Додај" Remove="Уклони" Rename="Преименуј" -Interact="Интерактивно" +Interact="Врши интеракцију" Filters="Филтери" Properties="Својства" -MoveUp="Помери горе" -MoveDown="Помери доле" +MoveUp="Премести нагоре" +MoveDown="Премести надоле" Settings="Подешавања" Display="Екран" Name="Име" -Exit="Излаз" +Exit="Изађи" Mixer="Миксета" -Browse="Претражи" +Browse="Прегледај" Mono="Моно" Stereo="Стерео" DroppedFrames="Испуштени фрејмови %1 (%2%)" +StudioProgramProjector="Пројектор целог екрана (програм)" PreviewProjector="Пројектор целог екрана (преглед)" SceneProjector="Пројектор целог екрана (сцена)" SourceProjector="Пројектор целог екрана (извор)" -Clear="Поништи" -Revert="Поврати" +StudioProgramWindow="Приказ у прозору" +PreviewWindow="Приказ у прозору (радна верзија)" +SceneWindow="Приказ у прозору (сцена)" +SourceWindow="Приказ у прозору (изворни код)" +MultiviewProjector="Симултани приказ (преко целог екрана)" +MultiviewWindowed="Симултани приказ (у прозору)" +Clear="Обриши" +Revert="Врати на стара подешавања" Show="Прикажи" Hide="Сакриј" +UnhideAll="Откриј све" Untitled="Ненасловљено" New="Нови" Duplicate="Дуплирај" @@ -53,20 +61,148 @@ Hours="Сати" Minutes="Минута" Seconds="Секунди" Deprecated="Превазиђено" +ReplayBuffer="Бафер за поновљени приказ" +Import="Увези" +Export="Извези" +Copy="Копирај" +Paste="Налепи" +PasteReference="Налепи (референцу)" +PasteDuplicate="Налепи (дупликат)" +RemuxRecordings="Снимање у слабијем квалитету (Remux)" +Next="Следеће" +Back="Назад" +Defaults="Подразумеване вредности" +HideMixer="Сакриј у миксер панел" +TransitionOverride="Тип транзиције" +None="Без" +StudioMode.Preview="Прегледај" +StudioMode.Program="Програм" +ShowInMultiview="Прикажи као симултани преглед" +VerticalLayout="Вертикални распоред" +Group="Група" + +AlreadyRunning.Title="OBS је већ покренут" +AlreadyRunning.Text="OBS je већ покренут! Осим ако заиста желите да урадите ово, молимо Вас да прекинете све процесе везане за OBS пре него што покренете нов задатак. У случају да OBS ради у позадини, молимо вас да проверите system tray (иконице доле десно, поред сата)." +AlreadyRunning.LaunchAnyway="Свеједно покрени" +Auth.Authing.Title="Потврда идентитета" +Auth.Authing.Text="Потврда идентитета помоћу %1-а, сачекајте…" +Auth.AuthFailure.Title="Грешка при потврди идентитета" +Auth.AuthFailure.Text="Потврда идентитета помоћу %1-а није успела:\n\n%2: %3" +Auth.InvalidScope.Title="Потребна је потврда идентитета" +Auth.InvalidScope.Text="Захтеви за аутентификацију помоћу %1 су промењени. Неки додаци можда неће бити доступни." +Auth.LoadingChannel.Title="Учитавање информација о каналу..." +Auth.LoadingChannel.Text="Учитавање информација о каналу за %1, молим сачекајте..." +Auth.ChannelFailure.Title="Није могуће учитати канал" +Auth.ChannelFailure.Text="Није могуће учитати информације о каналу за %1\n\n%2: %3" +Auth.Chat="Ћаскање" +Auth.StreamInfo="Информације о стримовању" +TwitchAuth.Stats="Twitch статистика" +Copy.Filters="Копирај филтере" +Paste.Filters="Налепи филтере" +BrowserPanelInit.Title="Покретање претраживача" +BrowserPanelInit.Text="Покретање претраживача, молим сачекајте..." +BandwidthTest.Region="Регион" +BandwidthTest.Region.US="Сједињене Америчке Државе" +BandwidthTest.Region.EU="Европа" +BandwidthTest.Region.Asia="Азија" +BandwidthTest.Region.Other="Други" +Basic.FirstStartup.RunWizard="Да ли желите да покренете чаробњака за аутоматско конфигурисање? Ово такође можете урадити и ручно, ако кликнете на подешавања (settings) у главном прозору." +Basic.FirstStartup.RunWizard.NoClicked="Ако се предомислите можете покренути чаробњака за аутоматско конфигурисање кад год пожелите, из менија Алата (Tools)." +Basic.AutoConfig="Чаробњак за аутоматско конфигурисање (Бета верзија)" +Basic.AutoConfig.ApplySettings="Промени подешавања" +Basic.AutoConfig.StartPage="Информације о коришћењу" +Basic.AutoConfig.StartPage.SubTitle="Наведите за шта тачно желите да користите програм" +Basic.AutoConfig.StartPage.PrioritizeStreaming="Оптимизуј за стримовање, снимање је секундарно" +Basic.AutoConfig.StartPage.PrioritizeRecording="Оптимизуј за снимање, стримовање се неће извршити" +Basic.AutoConfig.VideoPage="Подешавања видео-снимака" +Basic.AutoConfig.VideoPage.SubTitle="Наведите жељена подешавања видео-снимака која желите да користите" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="Користи тренутну (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="Приказ %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="Користите тренутни (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Или 60 или 30, са акцентом на 60 кад год је могуће" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Или 60 или 30, са акцентом на високу резолуцију" +Basic.AutoConfig.VideoPage.CanvasExplanation="Напомена: основна резолуција није нужно иста као резолуција којом ћете стримовати или којом ћете снимати. Ваша стварна резолуција којом стримујете/снимате може бити скалирана у односу на основну како би се смањила употреба ресурса или оптимизовао проток." +Basic.AutoConfig.StreamPage="Информације о стримовању" +Basic.AutoConfig.StreamPage.SubTitle="Молимо унесите ваше информације о стримовању" +Basic.AutoConfig.StreamPage.ConnectAccount="Повежи налог (опционо)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Дисконектуј налог" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Дисконектуј налог?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ова промена ће бити примењена одмах. Да ли сте сигурни да желите да дисконектујете Ваш налог?" +Basic.AutoConfig.StreamPage.UseStreamKey="Користи шифру за стримовање" +Basic.AutoConfig.StreamPage.Service="Услуга" +Basic.AutoConfig.StreamPage.Service.ShowAll="Прикажи све..." +Basic.AutoConfig.StreamPage.Service.Custom="Прилагођено..." +Basic.AutoConfig.StreamPage.Server="Сервер" +Basic.AutoConfig.StreamPage.StreamKey="Шифра за стримовање" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Линк)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="Процени брзину протока тестом пропусног опсега (може потрајати неколико минута)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Са акцентом на хардверско кодирање" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Хардверско кодирање спречава велику употребу процесора, али може захтевати већу брзину протока како би се одржао исти ниво квалитета." +Basic.AutoConfig.StreamPage.StreamWarning.Title="Упозорење о стримовању" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Тест пропусног опсега стримује насумичне видео податке без звука на Вашем каналу. Препоручено је да привремено искључите чување видео снимака стримова и да подесите стрим као приватни док се тест не заврши, ако је то могуће. Желите ли да наставите?" +Basic.AutoConfig.TestPage="Коначни резултати" +Basic.AutoConfig.TestPage.SubTitle.Testing="Програм тренутно извршава сет тестова како би проценио оптимална подешавања" +Basic.AutoConfig.TestPage.SubTitle.Complete="Тестирање је завршено" +Basic.AutoConfig.TestPage.TestingBandwidth="У току је извођење теста пропусног опсега, ово може потрајати неколико минута..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="Повезивање са: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="Неуспело повезивање са сервером, молимо проверите Вашу интернет везу и покушајте поново." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="Тестирање пропусног опсега за: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="У току је тестирање стрим енкодера, ово може потрајати неколико минута..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="У току је тестирање енкодера за снимање, ово може потрајати пар минута..." +Basic.AutoConfig.TestPage.TestingRes="У току је тестирање резолуције, ово може потрајати неколико минута..." +Basic.AutoConfig.TestPage.TestingRes.Fail="Неуспело покретање енкодера" +Basic.AutoConfig.TestPage.TestingRes.Resolution="Тренутно се тестира %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="Енкодер стримовања" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="Енкодер снимања" +Basic.AutoConfig.TestPage.Result.Header="Програм је одредио да су ова подешавања најповољнија за Вас:" +Basic.AutoConfig.TestPage.Result.Footer="Да бисте користили ова подешавања, кликните на ''Примените Подешавања''. Да опет конфигуришете wizard и покушате поново, кликните ''Назад''. Да конфигуришете ручно подешавања, кликните ''Поништи'' и отворите ''Подешавања''." + +Basic.Stats="Статистика" +Basic.Stats.CPUUsage="Искоришћеност процесора" +Basic.Stats.MemoryUsage="Искоришћеност меморије" +Basic.Stats.AverageTimeToRender="Просечно време потребно да се прикаже фрејм" +Basic.Stats.SkippedFrames="Прескочени фрејмови због заостатка кодирања" +Basic.Stats.MissedFrames="Пропуштени фрејмови због заостатка приказивања" +Basic.Stats.Output.Stream="Стрим" +Basic.Stats.Output.Recording="Снимање" +Basic.Stats.Status="Статус" +Basic.Stats.Status.Recording="Снимање" +Basic.Stats.Status.Live="УЖИВО" +Basic.Stats.Status.Reconnecting="Поновно повезивање" +Basic.Stats.Status.Inactive="Неактивно" +Basic.Stats.DroppedFrames="Пропуштени фрејмови (Мрежа)" +Basic.Stats.MegabytesSent="Укупни подаци на излазу" +Basic.Stats.Bitrate="Брзина протока" + +ResetUIWarning.Title="Да ли сте сигурни да желите да ресетујете кориснички интерфејс?" +ResetUIWarning.Text="Ресетовање корисничког интерфејса ће сакрити додатне докове. Ако желите да докови поново постану видљиви, потребно је да се открију у менију прегледа.\n\nДа ли сте сигурни да желите да ресетујете кориснички интерфејс?" + +Updater.Title="Доступна је нова верзија програма" +Updater.Text="Изашла је нова, унапређена верзија:" +Updater.UpdateNow="Aжурирај одмах" +Updater.RemindMeLater="Подсети ме касније" +Updater.Skip="Прескочи верзију" +Updater.Running.Title="Програм је тренутно активан" +Updater.Running.Text="Неки процеси су већ започети и ажурирање софтвера није могуће у датим условима. Молимо Вас да затворите све започете процесе пре него што се одлучите да ажурирате софтвер" +Updater.NoUpdatesAvailable.Title="Ажурирања нису доступна" +Updater.NoUpdatesAvailable.Text="Нема нових унапређења" +Updater.FailedToLaunch="Покретање ажурирања софтвера није успело" +Updater.GameCaptureActive.Title="Снимање приказа екрана игрице је активирано" +Updater.GameCaptureActive.Text="Тренутно је у употреби библиотека за снимање игре. Молимо да затворите све игре/програме који су снимљени (или да рестартујете Windows) и покушате поново." QuickTransitions.SwapScenes="Замени сцене прегледа/излаза након прелаза" QuickTransitions.SwapScenesTT="Замењује сцене прегледа и излаза након прелаза (ако оригинална сцена још увек постоји).\nОво неће поништити промене које су начињене над оригиналном сценом излаза." QuickTransitions.DuplicateScene="Дуплирај сцену" -QuickTransitions.DuplicateSceneTT="Када се мења иста сцена, дозволи промену измена/видљивости извора без промене излаза.\nДа бисте променили својства извора без промене излаза, омогућите 'Дуплирај изворе'.\nПромена ове вредности ће поништити тренутну сцену излаза (ако и даље постоји)." +QuickTransitions.DuplicateSceneTT="Приликом едитовања исте сцене, омогући едитовање измене/видљивости извора без промене излаза.\nДа бисте едитовали својства извора без промене излаза, омогућите 'Дуплирај изворе'.\nПромена ове вредности ће поништити тренутну сцену излаза (ако и даље постоји)." QuickTransitions.EditProperties="Дуплирај изворе" -QuickTransitions.EditPropertiesTT="Када се мења иста сцена, дозволи промену својстава извора без промене излаза.\nОво може бити употребљено само ако је 'Дуплирај сцене' омогућено.\nОдређени извори (као што су видео хватања или медија извори) не подржавају ово и не могу бити измењени засебно.\nПромена ове вредности ће поништити тренутну сцену излаза (ако и даље постоји).\n\nУпозорење: Због тога што извори могу бити дуплирани, ово може захтевати додатне системске или видео ресурсе." +QuickTransitions.EditPropertiesTT="Када се едитује иста сцена, дозволи едитовање својстава извора без промене излаза.\nОво може бити употребљено само ако је 'Дуплирај сцене' омогућено.\nОдређени извори (као што су видео хватања или медија извори) не подржавају ово и не могу бити измењени засебно.\nПромена ове вредности ће поништити тренутну сцену излаза (ако и даље постоји).\n\nУпозорење: Због тога што извори могу бити дуплирани, ово може захтевати додатне системске или видео ресурсе." QuickTransitions.HotkeyName="Брзи прелаз: %1" Basic.AddTransition="Додај подесиви прелаз" @@ -89,62 +225,67 @@ NoNameEntered.Title="Молим унесите исправно име" NoNameEntered.Text="Не можете изоставити име." ConfirmStart.Title="Започни стрим?" -ConfirmStart.Text="Да ли сте сигурни да желите започети стрим?" +ConfirmStart.Text="Да ли сте сигурни да желите да започнете стримовање?" ConfirmStop.Title="Заустави стрим?" -ConfirmStop.Text="Да ли сте сигурни да желите зауставити стрим?" +ConfirmStop.Text="Да ли сте сигурни да желите да зауставите стримовање?" -ConfirmExit.Title="Напустити OBS?" -ConfirmExit.Text="OBS је тренутно активан. Сви стримови/снимања ће бити угашени. Да ли сте сигурни да желите изаћи?" + +ConfirmExit.Title="Изађите из OBS програма?" +ConfirmExit.Text="OBS је тренутно активан. Сви стримови/снимања ће бити угашени. Да ли сте сигурни да желите да изађете из програма?" ConfirmRemove.Title="Потврди избацивање" -ConfirmRemove.Text="Да ли сте сигурни да желите избацити '$1'?" -ConfirmRemove.TextMultiple="Да ли сте сигурни да желите избацити %1 ставке?" +ConfirmRemove.Text="Да ли сте сигурни да желите да избаците '$1'?" +ConfirmRemove.TextMultiple="Да ли сте сигурни да желите да избаците %1 ставке?" + +Output.StartStreamFailed="Неуспело покретање стримовања" +Output.StartRecordingFailed="Неуспело покретање снимања" +Output.StartReplayFailed="Неуспело покретање бафера за поновни приказ" +Output.StartFailedGeneric="Неуспело покретање излаза. Молимо проверите пријaву за детаље.\n\n Обавештење: уколико користите NVENC или AMD енкодере, постарајте се да су Ваши видео драјвери ажурирани." Output.ConnectFail.Title="Неуспешно повезивање" Output.ConnectFail.BadPath="Неисправна путања или URL конекције. Молим проверите ваша подешавања да потврдите њихову исправност." Output.ConnectFail.ConnectFailed="Неуспешно повезивање на сервер" -Output.ConnectFail.InvalidStream="Не могу приступити наведеном каналу или стрим кључу, молим проверите ваш стрим кључ. Ако је исправан, можда постоји проблем при повезивању на сервер." +Output.ConnectFail.InvalidStream="Немогуће је приступити наведеном каналу или стрим кључу, молим проверите ваш стрим кључ. Ако је исправан, можда постоји проблем при повезивању на сервер." Output.ConnectFail.Error="Неочекивана грешка у повезивању са сервером. Више информација се налази у лог датотеци." Output.ConnectFail.Disconnected="Прекинута веза са сервером." + Output.RecordFail.Title="Неуспешно започињање снимања" Output.RecordFail.Unsupported="Излазни формат или није подржан или не подржава више од једне звучне траке. Молим проверите подешавања и покушајте поново." Output.RecordNoSpace.Title="Недовољно простора на диску" Output.RecordNoSpace.Msg="Нема довољно простора на диску да се настави снимање." Output.RecordError.Title="Грешка при снимању" Output.RecordError.Msg="Неодређена грешка се догодила при снимању." +Output.ReplayBuffer.NoHotkey.Title="Није подешена пречица на тастатури!" +Output.ReplayBuffer.NoHotkey.Msg="Није подешена пречица за бафер поновног приказивања. Молимо подесите пречицу ''Сачувај'' за чување снимака који су поново приказивани." Output.BadPath.Title="Неисправна путања датотеке" -Output.BadPath.Text="Подешена путања за документ је неисправна. Молим проверите ваша подешавања да потврдите исправност путање." +Output.BadPath.Text="Подешена путања за излаз документа је неисправна. Молим проверите ваша подешавања да потврдите исправност путање." LogReturnDialog="Слање лог документа успешно" LogReturnDialog.CopyURL="Копирај URL" -LogReturnDialog.ErrorUploadingLog="Грешка у слању лог документа" - -LicenseAgreement="Услови коришћења" -LicenseAgreement.PleaseReview="Молим проверите услове коришћења пре употребе OBS-а. Употребом овог програма сматра се да сте прочитали и прихватили услове GNU General Public License v2.0 лиценце. Молимо скролујте ниже да видите остатак уговора." -LicenseAgreement.ClickIAgreeToContinue="Ако прихватате услове коришћења, кликните на Слажем се да наставите. Да бисте користили OBS морате прихватити уговор." -LicenseAgreement.IAgree="Слажем се" -LicenseAgreement.Exit="Излаз" +LogReturnDialog.ErrorUploadingLog="Грешка у учитавању лог документа" Remux.SourceFile="OBS снимак" Remux.TargetFile="Датотека" -Remux.Remux="Remux" +Remux.Remux="Ремукс" +Remux.Stop="Заустави ремукс" +Remux.ClearFinished="Обриши завршене елементе" +Remux.ClearAll="Обриши све елементе" Remux.OBSRecording="OBS снимак" -Remux.FinishedTitle="Remux завршен" -Remux.Finished="Завршен remux снимка" -Remux.FinishedError="Remux завршен, али датотека можда није комплетирана" -Remux.SelectRecording="Изабери OBS снимак …" -Remux.SelectTarget="Изабери датотеку …" -Remux.FileExistsTitle="Датотека постоји" -Remux.FileExists="Датотека већ постоји, да ли желите да је препишете?" -Remux.ExitUnfinishedTitle="Remux у току" -Remux.ExitUnfinished="Remux није завршен, ако сада зауставите процес датотека може бити неупотребљива.\nДа ли сте сигурни да желите зауставити remux?" +Remux.FinishedTitle="Ремукс је завршен" +Remux.Finished="Завршен ремукс снимка" +Remux.FinishedError="Ремукс је завршен, али датотека можда није комплетирана" +Remux.FileExistsTitle="Циљни фајл већ постоји" +Remux.FileExists="Следећи циљни фајлови већ постоје. Да ли желите да их замените новим?" +Remux.ExitUnfinishedTitle="Ремукс у току" +Remux.ExitUnfinished="Ремукс није завршен, ако сада зауставите процес датотека може бити неупотребљива.\nДа ли сте сигурни да желите зауставити ремукс?" +Remux.HelpText="Приложите фајлове у овај прозор за ремукс, или изаберите празну \"OBS Recording\" ћелију да потражите фајл." UpdateAvailable="Доступна је новија верзија програма" -UpdateAvailable.Text="Верзија %1.%2.%3 је доступна. Кликните овде да преузмете" +UpdateAvailable.Text="Верзија %1.%2.%3 је доступна. Кликните овде да преузмете" Basic.DesktopDevice1="Звук са рачунара" Basic.DesktopDevice2="Звук са рачунара 2" @@ -158,6 +299,7 @@ Basic.DisplayCapture="Прикажи улаз" Basic.Main.PreviewConextMenu.Enable="Омогући преглед" + ScaleFiltering="Филтер увећања" ScaleFiltering.Point="Тачка" ScaleFiltering.Bilinear="Билинеарно" @@ -176,6 +318,10 @@ Deinterlacing.Yadif2x="Yadif 2x" Deinterlacing.TopFieldFirst="Прво горње поље" Deinterlacing.BottomFieldFirst="Прво доње поље" +VolControl.SliderUnmuted="Слајдер јачине звука за '%1': %2" +VolControl.SliderMuted="Слајдер јачине звука за '%1': %2 (тренутно искључен)" +VolControl.Mute="Искључите звук '%1'" +VolControl.Properties="Својства '%1'" Basic.Main.AddSceneDlg.Title="Додај сцену" Basic.Main.AddSceneDlg.Text="Молим унесите име сцене" @@ -192,6 +338,8 @@ AddProfile.Text="Молим унесите име профила" RenameProfile.Title="Промени име профила" +Basic.Main.MixerRename.Title="Преименујте извор звука" +Basic.Main.MixerRename.Text="Молимо унесите назив извора звука" Basic.Main.PreviewDisabled="Преглед је тренутно онемогућен" @@ -225,10 +373,10 @@ Basic.InteractionWindow="Интеракција са '%1'" Basic.StatusBar.Reconnecting="Веза је прекинута, поновно повезивање за %2 секунд(и) (%1 покушај)" Basic.StatusBar.AttemptingReconnect="Покушавам поновно повезивање... (%1 покушај)" Basic.StatusBar.ReconnectSuccessful="Поновно повезивање успешно" -Basic.StatusBar.Delay="Одлагање (%1 сек)" -Basic.StatusBar.DelayStartingIn="Одлагање (почиње за %1 сек)" -Basic.StatusBar.DelayStoppingIn="Одлагање (заустављам за %1 сек)" -Basic.StatusBar.DelayStartingStoppingIn="Одлагање (заустављам за %1 сек, почиње за %2 сек)" +Basic.StatusBar.Delay="Кашњење (%1 сек)" +Basic.StatusBar.DelayStartingIn="Кашњење (почиње за %1 сек)" +Basic.StatusBar.DelayStoppingIn="Кашњење (зауставља се за %1 сек)" +Basic.StatusBar.DelayStartingStoppingIn="Кашњење (зауставља се за %1 сек, почиње за %2 сек)" Basic.Filters="Филтери" Basic.Filters.AsyncFilters="Звучни/Видео филтери" @@ -249,13 +397,13 @@ Basic.TransformWindow.Bounds="Величина оквира" Basic.TransformWindow.Crop="Исецање" Basic.TransformWindow.Alignment.TopLeft="Горе лево" -Basic.TransformWindow.Alignment.TopCenter="Горе центар" +Basic.TransformWindow.Alignment.TopCenter="Горе, на средини" Basic.TransformWindow.Alignment.TopRight="Горе десно" -Basic.TransformWindow.Alignment.CenterLeft="Лево центар" +Basic.TransformWindow.Alignment.CenterLeft="На средини, лево" Basic.TransformWindow.Alignment.Center="Центар" -Basic.TransformWindow.Alignment.CenterRight="Десно центар" +Basic.TransformWindow.Alignment.CenterRight="На средини, десно" Basic.TransformWindow.Alignment.BottomLeft="Доње лево" -Basic.TransformWindow.Alignment.BottomCenter="Доње центар" +Basic.TransformWindow.Alignment.BottomCenter="Доле, на средини" Basic.TransformWindow.Alignment.BottomRight="Доње десно" Basic.TransformWindow.BoundsType.None="Без оквира" @@ -266,22 +414,29 @@ Basic.TransformWindow.BoundsType.ScaleToWidth="Скалирај до ширин Basic.TransformWindow.BoundsType.ScaleToHeight="Скалирај до висине оквира" Basic.TransformWindow.BoundsType.Stretch="Развуци до оквира" -Basic.Main.AddSourceHelp.Title="Не могу додати извор" -Basic.Main.AddSourceHelp.Text="Потребно је најмање једна сцена да додате извор." +Basic.Main.AddSourceHelp.Title="Немогуће је додати извор" +Basic.Main.AddSourceHelp.Text="Потребна је најмање једна сцена да бисте додали извор." Basic.Main.Scenes="Сцене" Basic.Main.Sources="Извори" +Basic.Main.Controls="Контроле" Basic.Main.Connecting="Повезивање..." Basic.Main.StartRecording="Почни снимање" +Basic.Main.StartReplayBuffer="Покрени бафер за поновно приказивање" Basic.Main.StartStreaming="Почни стримовање" Basic.Main.StopRecording="Заустави снимање" Basic.Main.StoppingRecording="Заустављање снимања..." +Basic.Main.StopReplayBuffer="Заустави бафер за поновно приказивање" +Basic.Main.StoppingReplayBuffer="Заустављање бафера за поновно приказивање је у току..." Basic.Main.StopStreaming="Заустави стримовање" Basic.Main.StoppingStreaming="Заустављање емитовања..." -Basic.Main.ForceStopStreaming="Заустави стримовање (поништи одлагање)" +Basic.Main.ForceStopStreaming="Заустави стримовање (поништи кашњење)" +Basic.Main.Group="Група %1" +Basic.Main.GroupItems="Групиши одабране елементе" +Basic.Main.Ungroup="Раздвоји елементе групе" Basic.MainMenu.File="Фајл (&F)" -Basic.MainMenu.File.Export="Изв&ези" +Basic.MainMenu.File.Export="Извези (Е) (&E)" Basic.MainMenu.File.Import="Увоз (&I)" Basic.MainMenu.File.ShowRecordings="Прикажи снимке (&R)" Basic.MainMenu.File.Remux="Re&mux снимака" @@ -291,18 +446,20 @@ Basic.MainMenu.File.ShowProfileFolder="Прикажи фолдер са поде Basic.MainMenu.AlwaysOnTop="Увек на врху (&A)" Basic.MainMenu.File.Exit="Излаз (&X)" -Basic.MainMenu.Edit="Изм&ена" -Basic.MainMenu.Edit.Undo="Врати (&U)" +Basic.MainMenu.Edit="Едитуј (Е) (&E)" +Basic.MainMenu.Edit.Undo="Врати уназад (&U)" Basic.MainMenu.Edit.Redo="Уради поново (&R)" -Basic.MainMenu.Edit.UndoAction="Врати $1 (&U)" -Basic.MainMenu.Edit.RedoAction="Уради поново $1 (&R)" +Basic.MainMenu.Edit.UndoAction="Врати уназад $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Понови $1 (&R)" Basic.MainMenu.Edit.LockPreview="Закључај приказ (&L)" Basic.MainMenu.Edit.Scale="Преглед скалирања (&s)" Basic.MainMenu.Edit.Scale.Window="Скалирај на величину прозора" Basic.MainMenu.Edit.Scale.Canvas="Платно (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Излаз (%1x%2)" -Basic.MainMenu.Edit.Transform="&Трансформиши" -Basic.MainMenu.Edit.Transform.EditTransform="Изм&ени трансформацију..." +Basic.MainMenu.Edit.Transform="Трансформиши (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Едитуј трансформацију... (&E)" +Basic.MainMenu.Edit.Transform.CopyTransform="Копирај трансформацију" +Basic.MainMenu.Edit.Transform.PasteTransform="Налепи трансформацију" Basic.MainMenu.Edit.Transform.ResetTransform="Поништи трансформацију (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Окрени за 90 степени у смеру казаљке на сату" Basic.MainMenu.Edit.Transform.Rotate90CCW="Окрени за 90 степени у контра смеру казаљке на сату" @@ -312,32 +469,48 @@ Basic.MainMenu.Edit.Transform.FlipVertical="Преврни вертикално Basic.MainMenu.Edit.Transform.FitToScreen="Рашири по екрану (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="Развуци по екрану (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="Центрирај на екрану (&C)" -Basic.MainMenu.Edit.Order="Ред&ослед" +Basic.MainMenu.Edit.Order="Редослед (&O)" Basic.MainMenu.Edit.Order.MoveUp="Помери горе (&U)" Basic.MainMenu.Edit.Order.MoveDown="Помери доле (&D)" Basic.MainMenu.Edit.Order.MoveToTop="Помери на врх (&T)" Basic.MainMenu.Edit.Order.MoveToBottom="Помери на дно (&B)" -Basic.MainMenu.Edit.AdvAudio="Н&апредна подешавања звука" +Basic.MainMenu.Edit.AdvAudio="Напредна подешавања звука (&A)" -Basic.MainMenu.View="Поглед (&V)" +Basic.MainMenu.View="Преглед (&V)" Basic.MainMenu.View.Toolbars="Линије алатки (&T)" +Basic.MainMenu.View.Docks="Докови" +Basic.MainMenu.View.Docks.ResetUI="Ресетуј кориснички интерфејс" +Basic.MainMenu.View.Docks.LockUI="Закључаj кориснички интерфејс" Basic.MainMenu.View.Toolbars.Listboxes="Списак ставки (&L)" Basic.MainMenu.View.SceneTransitions="Сценски прелази (&C)" Basic.MainMenu.View.StatusBar="Статусна линија (&S)" +Basic.MainMenu.View.Fullscreen.Interface="Интерфејс на целом екрану" Basic.MainMenu.SceneCollection="Колекција сцена (&S)" Basic.MainMenu.Profile="Профил (&P)" +Basic.MainMenu.Profile.Import="Увези профил" +Basic.MainMenu.Profile.Export="Извези профил" +Basic.MainMenu.SceneCollection.Import="Увези колекцију сцена" +Basic.MainMenu.SceneCollection.Export="Извези колекцију сцена" +Basic.MainMenu.Profile.Exists="Овај профил већ постоји" +Basic.MainMenu.SceneCollection.Exists="Ова колекција сцена већ постоји" Basic.MainMenu.Tools="Алати (&T)" Basic.MainMenu.Help="Помоћ (&H)" +Basic.MainMenu.Help.HelpPortal="Портал за помоћ (&P)" Basic.MainMenu.Help.Website="Посети страницу (&W)" +Basic.MainMenu.Help.Discord="Придружите се &Discord серверу" Basic.MainMenu.Help.Logs="Лог датотеке (&L)" Basic.MainMenu.Help.Logs.ShowLogs="Прикажи лог датотеке (&S)" Basic.MainMenu.Help.Logs.UploadCurrentLog="Пошаљи тренутну лог датотеку (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="Пошаљи последњу лог датотеку (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="Прикажи тренутни записник (&V)" Basic.MainMenu.Help.CheckForUpdates="Провери верзију програма" +Basic.MainMenu.Help.CrashLogs="Извештаји о прекидима (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Прикажи извештаје о прекидима (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Постави последњи извештај о прекиду (&L)" +Basic.MainMenu.Help.About="О програму (&A)" Basic.Settings.ProgramRestart="Програм мора бити поново покренут да би ова подешавања била прихваћена." Basic.Settings.ConfirmTitle="Потврдите промене" @@ -346,8 +519,11 @@ Basic.Settings.Confirm="Постоје промене које нису сачу Basic.Settings.General="Опште" Basic.Settings.General.Theme="Тема" Basic.Settings.General.Language="Језик" +Basic.Settings.General.EnableAutoUpdates="Аутоматски потражи ажурирања при покрeтању" +Basic.Settings.General.OpenStatsOnStartup="Прикажи статистику при покретању" Basic.Settings.General.WarnBeforeStartingStream="Прикажи прозор за потврду када се започињу стримови" Basic.Settings.General.WarnBeforeStoppingStream="Прикажи прозор за потврду када се заустављају стримови" +Basic.Settings.General.Projectors="Пројектори" Basic.Settings.General.HideProjectorCursor="Сакриј показивач на пројекторима" Basic.Settings.General.ProjectorAlwaysOnTop="Увек постави пројектор на врх прозора" Basic.Settings.General.Snapping="Поравнавање привлачењем извора" @@ -357,10 +533,34 @@ Basic.Settings.General.SourceSnapping="Привлачење извора ка д Basic.Settings.General.SnapDistance="Осетљивост привлачења" Basic.Settings.General.RecordWhenStreaming="Аутоматско снимање при емитовању" Basic.Settings.General.KeepRecordingWhenStreamStops="Настави снимати када се емитовање заустави" -Basic.Settings.General.SysTrayWhenStarted="При покретању минимизирај на иконицу у системском панелу" +Basic.Settings.General.ReplayBufferWhileStreaming="Аутоматски покрени бафер поновног приказивања током стримовања" +Basic.Settings.General.KeepReplayBufferStreamStops="Након заустављања стримовања, задржи бафер поновног приказивања као активан" +Basic.Settings.General.SysTray="System Tray" +Basic.Settings.General.SysTrayWhenStarted="При покретању минимизуј на иконицу у системском панелу" +Basic.Settings.General.SystemTrayHideMinimize="Увек минимизуј system tray уместо таск бара" +Basic.Settings.General.SaveProjectors="Сачувај пројекторе пре изласка из програма" +Basic.Settings.General.Preview="Преглед" +Basic.Settings.General.OverflowHidden="Сакриј вишак" +Basic.Settings.General.OverflowAlwaysVisible="Вишак је увек видљив" +Basic.Settings.General.OverflowSelectionHidden="Прикажи вишак чак и када је извор невидљив" +Basic.Settings.General.SwitchOnDoubleClick="Прелаз на сцену дуплим кликом" +Basic.Settings.General.StudioPortraitLayout="Укључи портрет/вертикални приказ" +Basic.Settings.General.Multiview="Симултани приказ" +Basic.Settings.General.Multiview.MouseSwitch="Промена сцене кликом" +Basic.Settings.General.Multiview.DrawSourceNames="Прикажи имена сцена" +Basic.Settings.General.Multiview.DrawSafeAreas="Прикажи сигурне области (EBU R 95)" +Basic.Settings.General.MultiviewLayout="Распоред симултаног приказа" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="Хоризонтално, горе (8 сцена)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="Хоризонтално, доле (8 сцена)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="Вертикално, лево (8 сцена)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="Вертикално, десно (8 сцена)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Хоризонтално, горе (24 сцене)" Basic.Settings.Stream="Стрим" Basic.Settings.Stream.StreamType="Врста стрима" +Basic.Settings.Stream.Custom.UseAuthentication="Користи аутентификацију" +Basic.Settings.Stream.Custom.Username="Корисничко име" +Basic.Settings.Stream.Custom.Password="Шифра" Basic.Settings.Output="Излаз" Basic.Settings.Output.Format="Формат снимања" @@ -372,6 +572,14 @@ Basic.Settings.Output.Mode="Режим излаза" Basic.Settings.Output.Mode.Simple="Једноставно" Basic.Settings.Output.Mode.Adv="Напредно" Basic.Settings.Output.Mode.FFmpeg="FFmpeg излаз" +Basic.Settings.Output.UseReplayBuffer="Укључи бафер поновног приказивања" +Basic.Settings.Output.ReplayBuffer.SecondsMax="Максимално време поновног приказивања (секунде)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="Максимална меморија (мегабајти)" +Basic.Settings.Output.ReplayBuffer.Estimate="Процењена искоришћеност меморије: %1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Немогуће је проценити искоришћеност меморије. Молимо подесите максималну границу меморије." +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Обавештење: побрините се да у секцији за пречице подесите пречицу на тастатури за бафер поновног приказивања)" +Basic.Settings.Output.ReplayBuffer.Prefix="Префикс имена фајла бафера репродуковања" +Basic.Settings.Output.ReplayBuffer.Suffix="Суфикс" Basic.Settings.Output.Simple.SavePath="Путања за снимање" Basic.Settings.Output.Simple.RecordingQuality="Квалитет снимања" Basic.Settings.Output.Simple.RecordingQuality.Stream="Исто као стрим" @@ -383,8 +591,7 @@ Basic.Settings.Output.Simple.Warn.AudioBitrate="Упозорење: Звучни Basic.Settings.Output.Simple.Warn.Encoder="Упозорење: Снимање са софтверским енкодером другачијег квалитета у односу на стрим ће захтевати додатну процесорску снагу ако стримујете и снимате у исто време." Basic.Settings.Output.Simple.Warn.Lossless="Упозорење: Квалитет без губитка ствара изричито велике датотеке! Квалитет без губитка може користити више од 7 гигабајта простора на диску по минуту при високим резолуцијама и framerate-ом. Квалитет без губитка није препоручен за дуже снимање осим ако имате велику количину слободног простора на диску." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Да ли сте сигурни да желите користити квалитет без губитка?" -Basic.Settings.Output.Simple.Warn.Lossless.Title="Упозорење за квалитет без губитка!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Упозорење: Не можете користити више одвојених QSV енкодера када емитујете и снимате у исто време. Ако желите да емитујете и снимате у исто време, молим промените или енкодер снимања или енкодер емитовања." +Basic.Settings.Output.Simple.Warn.Lossless.Title="Упозорење о квалитету без губитка!" Basic.Settings.Output.Simple.Encoder.Software="Софтверски (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Машински (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Машински (AMD)" @@ -393,11 +600,11 @@ Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="Софтверски (x264 Basic.Settings.Output.VideoBitrate="Проток видеа" Basic.Settings.Output.AudioBitrate="Проток звука" Basic.Settings.Output.Reconnect="Аутоматски повежи поново" -Basic.Settings.Output.RetryDelay="Пауза пре поновног покушаја (секунде)" +Basic.Settings.Output.RetryDelay="Кашњење поновног покушаја (секунде)" Basic.Settings.Output.MaxRetries="Максималан број поновних покушаја" Basic.Settings.Output.Advanced="Омогући напредна подешавања компресора" -Basic.Settings.Output.EncoderPreset="Шаблон енкодера (веће = мање CPU-а)" -Basic.Settings.Output.CustomEncoderSettings="Прилагођена енкодер подешавања" +Basic.Settings.Output.EncoderPreset="Предефинисано подешавање енкодера" +Basic.Settings.Output.CustomEncoderSettings="Прилагођена подешавања енкодера" Basic.Settings.Output.CustomMuxerSettings="Посебна подешавања муксера" Basic.Settings.Output.NoSpaceFileName="Створи име датотеке без размака" @@ -409,6 +616,8 @@ Basic.Settings.Output.Adv.Audio.Track1="Извор 1" Basic.Settings.Output.Adv.Audio.Track2="Извор 2" Basic.Settings.Output.Adv.Audio.Track3="Извор 3" Basic.Settings.Output.Adv.Audio.Track4="Извор 4" +Basic.Settings.Output.Adv.Audio.Track5="Трака 5" +Basic.Settings.Output.Adv.Audio.Track6="Трака 6" Basic.Settings.Output.Adv.Recording="Снимање" Basic.Settings.Output.Adv.Recording.Type="Врста" @@ -436,6 +645,8 @@ Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="Подешавања виде Basic.Settings.Output.Adv.FFmpeg.AEncoder="Звучни енкодер" Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="Подешавања звучног енкодера (ако постоје)" Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Подешавања muxer-а (ако постоје)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="Интервал кључних фрејмова (фрејмови)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="Прикажи све кодеке (чак иако су потенцијално некомпатибилни)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" @@ -465,15 +676,20 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (оштрије скали Basic.Settings.Audio="Звук" Basic.Settings.Audio.SampleRate="Проток" Basic.Settings.Audio.Channels="Канали" -Basic.Settings.Audio.DesktopDevice="Звук са рачунара" -Basic.Settings.Audio.DesktopDevice2="Звук са рачунара 2" -Basic.Settings.Audio.AuxDevice="Микрофон/Улаз" -Basic.Settings.Audio.AuxDevice2="Микрофон/Улаз 2" -Basic.Settings.Audio.AuxDevice3="Микрофон/Улаз 3" +Basic.Settings.Audio.MeterDecayRate.Fast="Брза" +Basic.Settings.Audio.MeterDecayRate.Medium="Средња (Tип I PPM)" +Basic.Settings.Audio.MeterDecayRate.Slow="Спора (Tип II PPM)" +Basic.Settings.Audio.PeakMeterType="Тип мерача врха" +Basic.Settings.Audio.PeakMeterType.SamplePeak="Врх узорка" +Basic.Settings.Audio.PeakMeterType.TruePeak="Прави врх (већа употреба процесора)" +Basic.Settings.Audio.MultiChannelWarning.Enabled="УПОЗОРЕЊЕ: Звук окружења је укључен." +Basic.Settings.Audio.MultichannelWarning="Ако је стрим у току, проверите да ли ваша стриминг услуга подржава интеграцију и плејбек звука окружења. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast су примери где је звук окружења у потпуности подржан. Иако и Facebook Live i YouTube Live подржавају интеграцију окружења, Facebook Live миксује као стерео, а YouTube Live репродукује само два канала. \n\nOBS звучни филтери су компатибилни са звуком окружења, мада подршка за VST прикључке није загарантована." +Basic.Settings.Audio.MultichannelWarning.Title="Да ли желите да укључите звук окружења?" +Basic.Settings.Audio.MultichannelWarning.Confirm="Да ли сте сигурни да желите да укључите звук окружења?" Basic.Settings.Audio.EnablePushToMute="Омогући стисни-за-мутирање" -Basic.Settings.Audio.PushToMuteDelay="Стисни-за-мутирање пауза" +Basic.Settings.Audio.PushToMuteDelay="Кашњење опције стисни-за-мутирање" Basic.Settings.Audio.EnablePushToTalk="Омогући Стисни-за-говор" -Basic.Settings.Audio.PushToTalkDelay="Стисни-за-говор пауза" +Basic.Settings.Audio.PushToTalkDelay="Кашњење опције стисни-за-говор" Basic.Settings.Audio.UnknownAudioDevice="[Уређај није повезан или није доступан]" Basic.Settings.Advanced="Напредно" @@ -481,31 +697,41 @@ Basic.Settings.Advanced.General.ProcessPriority="Приоритет процес Basic.Settings.Advanced.General.ProcessPriority.High="Високи" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Изнад нормалног" Basic.Settings.Advanced.General.ProcessPriority.Normal="Нормални" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Нижи од нормалног" Basic.Settings.Advanced.General.ProcessPriority.Idle="Беспослени" Basic.Settings.Advanced.FormatWarning="Упозорење: Формати боја различити од NV12 су првенствено намењени за снимање и нису препоручени за стримовање. Стримовање може проузроковати повишено заузеће процесора због претварања формата боја." Basic.Settings.Advanced.Audio.BufferingTime="Време баферовања звука" Basic.Settings.Advanced.Video.ColorFormat="Формат боја" -Basic.Settings.Advanced.Video.ColorSpace="YUV простор боја" -Basic.Settings.Advanced.Video.ColorRange="YUV распон боја" Basic.Settings.Advanced.Video.ColorRange.Partial="Делимично" Basic.Settings.Advanced.Video.ColorRange.Full="Потпуно" -Basic.Settings.Advanced.StreamDelay="Одлагање стрима" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Подразумевано" +Basic.Settings.Advanced.Audio.DisableAudioDucking="Искључи Windows audio ducking" +Basic.Settings.Advanced.StreamDelay="Кашњење стримовања" Basic.Settings.Advanced.StreamDelay.Duration="Трајање (секунде)" -Basic.Settings.Advanced.StreamDelay.Preserve="Очувај тачку прекидања (повећава одлагање) када се поново повезује" +Basic.Settings.Advanced.StreamDelay.Preserve="Сачувај тачку прекида (повећај кашњење) приликом поновног повезивања" Basic.Settings.Advanced.StreamDelay.MemoryUsage="Процењена употреба меморије: %1 MB" Basic.Settings.Advanced.Network="Мрежа" Basic.Settings.Advanced.Network.BindToIP="Вежи се за IP" +Basic.Settings.Advanced.Network.EnableNewSocketLoop="Укључи нову шифру за умрежавање" +Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим слабе прикривености" +Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Искључи пречице када је главни прозор у фокусу" +Basic.Settings.Advanced.AutoRemux="Аутоматски уради ремукс у mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(сними као mkv)" Basic.AdvAudio="Напредна подешавања звука" Basic.AdvAudio.Name="Име" -Basic.AdvAudio.Volume="Гласноћа (%)" Basic.AdvAudio.Mono="Споји у моно" -Basic.AdvAudio.Panning="Померање" +Basic.AdvAudio.Balance="Баланс" Basic.AdvAudio.SyncOffset="Разлика у синхронизацији (ms)" +Basic.AdvAudio.Monitoring="Аудио надзор" +Basic.AdvAudio.Monitoring.None="Искључи надзор" +Basic.AdvAudio.Monitoring.MonitorOnly="Само надзор (излаз без звука)" +Basic.AdvAudio.Monitoring.Both="Надзор и излаз" Basic.AdvAudio.AudioTracks="Извори" Basic.Settings.Hotkeys="Пречице" Basic.Settings.Hotkeys.Pair="Комбинације тастера дељене са '%1' се понашају као прекидачи" +Basic.Settings.Hotkeys.Filter="Филтер" Basic.Hotkeys.SelectScene="Пребаци на сцену" @@ -561,7 +787,26 @@ SceneItemHide="Сакриј '%1'" OutputWarnings.NoTracksSelected="Морате одабрати макар једну траку" OutputWarnings.MultiTrackRecording="Упозорење: Одређени формати (као што је FLV) не подржавају више трака по снимку" - - +FinalScene.Title="Обриши сцену" +FinalScene.Text="Мора да постоји барем једна сцена, како би била обрисана." + +NoSources.Title="Нема извора" +NoSources.Text="Изгледа да још увек нисте додали ни један видео извор, тако да ће се приказивати само празан екран. Да ли сте сигурни да желите да наставите?" +NoSources.Text.AddSource="Можете да додате изворе у било ком тренутку, кликом на иконицу ''+'' испод дугмета ''Извори'' у главном прозору." + +ChangeBG="Подеси боју" +CustomColor="Персонализована боја" + +BrowserSource.EnableHardwareAcceleration="Укључи извор претраживача хардверског убрзања" + +About="О програму" +About.Info="OBS Studio је бесплатан софтвер отвореног кода који омогућава видео снимање и стримовање уживо." +About.GetInvolved="Учествујте" +About.Authors="Аутори" +About.License="Лиценца" + +ResizeOutputSizeOfSource="Промени величину излаза (величина извора)" +ResizeOutputSizeOfSource.Text="Резолуција излаза и основна резолуција ће бити промењене како би одговарале величини тренутног извора." +ResizeOutputSizeOfSource.Continue="Да ли желите да наставите?" diff --git a/UI/data/locale/sv-SE.ini b/UI/data/locale/sv-SE.ini index b1b065b..7439dc0 100644 --- a/UI/data/locale/sv-SE.ini +++ b/UI/data/locale/sv-SE.ini @@ -27,7 +27,7 @@ Mixer="Mixer" Browse="Bläddra" Mono="Mono" Stereo="Stereo" -DroppedFrames="Tappade bildrutor %1 (%2%)" +DroppedFrames="Tappade bildrutor %1 (%2 %)" StudioProgramProjector="Helskärmsprojektor (program)" PreviewProjector="Fullskärmsprojektor (förhandsvisning)" SceneProjector="Fullskärmsprojektor (scen)" @@ -80,14 +80,40 @@ StudioMode.Program="Program" ShowInMultiview="Visa i multivy" VerticalLayout="Vertikal layout" Group="Grupp" +DoNotShowAgain="Visa inte igen" +Default="(Standard)" +Calculating="Beräknar..." AlreadyRunning.Title="OBS körs redan" -AlreadyRunning.Text="OBS körs redan! Såvida du gjorde detta med flit, stäng ned alla befintliga instanser av OBS innan du försöker köra en ny instans. Om du har minimerat OBS till systemfältet, kontroller om det fortfarande körs där." +AlreadyRunning.Text="OBS körs redan! Såvida du gjorde detta med flit, stäng ned alla befintliga instanser av OBS innan du försöker köra en ny instans. Om du har minimerat OBS till systemfältet, kontroller om det fortfarande körs där." AlreadyRunning.LaunchAnyway="Kör ändå" +DockCloseWarning.Title="Stäng flytande fönster" +DockCloseWarning.Text="Du stängde precis ett flytande fönster. Om du vill visa det igen, använd Visa → Flytande fönster i menyfältet." + +Auth.Authing.Title="Autentiserar..." +Auth.Authing.Text="Autentiserar med %1, var god vänta..." +Auth.AuthFailure.Title="Autentiseringsfel" +Auth.AuthFailure.Text="Misslyckades att autentisera med %1:\n\n%2: %3" +Auth.InvalidScope.Title="Autentisering krävs" +Auth.InvalidScope.Text="Autentiseringskraven för %1 har ändrats. Vissa funktioner kanske inte är tillgängliga." +Auth.LoadingChannel.Title="Läser in kanalinformation..." +Auth.LoadingChannel.Text="Läser in kanalinformation för %1, var god vänta..." +Auth.ChannelFailure.Title="Misslyckades att läsa in kanal" +Auth.ChannelFailure.Text="Misslyckades att läsa in kanalinformation för %1\n\n%2: %3" +Auth.Chat="Chatt" +Auth.StreamInfo="Ströminformation" +TwitchAuth.Stats="Twitch-statistik" +TwitchAuth.Feed="Aktivitetsflöde för Twitch" +TwitchAuth.TwoFactorFail.Title="Kunde inte efterfråga strömnyckel" +TwitchAuth.TwoFactorFail.Text="OBS kunde inte ansluta till ditt Twitch-konto. Se till att tvåfaktorsautentiseringen har ställts in i säkerhetsinställningarna på Twitch då detta är nödvändigt för att kunna strömma." + Copy.Filters="Kopiera filter" Paste.Filters="Klistra in filter" +BrowserPanelInit.Title="Initierar webbläsare..." +BrowserPanelInit.Text="Initierar webbläsare, var god vänta..." + BandwidthTest.Region="Region" BandwidthTest.Region.US="USA" BandwidthTest.Region.EU="Europa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Asien" BandwidthTest.Region.Other="Övrigt" Basic.FirstStartup.RunWizard="Skulle du vilja köra den automatiska konfigurationsguiden? Du kan konfigurera dina inställningar manuellt genom att klicka på knappen Inställningar i huvudfönstret." -Basic.FirstStartup.RunWizard.BetaWarning="(OBS: Den automatiska konfigurationsguiden är för nuvarande i betastadiet)" Basic.FirstStartup.RunWizard.NoClicked="Om du ändrar dig kan du köra den automatiska konfigurationsguiden när som helst från verktygsmenyn." Basic.AutoConfig="Automatisk konfigurationsguide" -Basic.AutoConfig.Beta="Automatisk konfigurationsguide (beta)" Basic.AutoConfig.ApplySettings="Verkställ inställningar" Basic.AutoConfig.StartPage="Användningsinformation" Basic.AutoConfig.StartPage.SubTitle="Ange vad du vill använda programmet för" @@ -112,11 +136,17 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Bildskärm %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Använd nuvarande (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="Antingen 60 eller 30, men föredra 60 när det är möjligt" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="Antingen 60 eller 30, men föredra hög upplösning" -Basic.AutoConfig.VideoPage.CanvasExplanation="OBS: Kanvasens (grundens) upplösning är nödvändigtvis samma som upplösningen upp kommer att strömma eller spela in med. Din riktiga upplösning för strömning/inspelning kan skalas ned från kanvasupplösningen för att reducera användning av resurser eller krav på bithastighet." +Basic.AutoConfig.VideoPage.CanvasExplanation="OBS: Kanvasens (grundens) upplösning är nödvändigtvis samma som upplösningen upp kommer att strömma eller spela in med. Din riktiga upplösning för strömning/inspelning kan skalas ned från kanvasupplösningen för att reducera användning av resurser eller krav på bithastighet." Basic.AutoConfig.StreamPage="Ströminformation" -Basic.AutoConfig.StreamPage.SubTitle="Ange din ströminformation" +Basic.AutoConfig.StreamPage.SubTitle="Var god ange din ströminformation" +Basic.AutoConfig.StreamPage.ConnectAccount="Anslut konto (valfritt)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Koppla från konto" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Koppla från konto?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Denna ändring kommer tillämpas direkt. Är du säker på att du vill koppla från ditt konto?" +Basic.AutoConfig.StreamPage.UseStreamKey="Använd strömnyckel" Basic.AutoConfig.StreamPage.Service="Tjänst" Basic.AutoConfig.StreamPage.Service.ShowAll="Visa alla..." +Basic.AutoConfig.StreamPage.Service.Custom="Anpassad..." Basic.AutoConfig.StreamPage.Server="Server" Basic.AutoConfig.StreamPage.StreamKey="Strömnyckel" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Länk)" @@ -143,8 +173,8 @@ Basic.AutoConfig.TestPage.Result.Header="Programmet har bestämt att dessa uppsk Basic.AutoConfig.TestPage.Result.Footer="För att använda dessa inställningar, klicka på Verkställ inställningar. För att omkonfigurera guiden och försöka igen, klicka på Tillbaka. För att konfigurera inställningarna manuellt, klicka på Avbryt och öppna Inställningar." Basic.Stats="Statistik" -Basic.Stats.CPUUsage="CPU-användning" -Basic.Stats.HDDSpaceAvailable="Tillgängligt hårddiskutrymme" +Basic.Stats.CPUUsage="Processoranvändning" +Basic.Stats.HDDSpaceAvailable="Ledigt hårddiskutrymme" Basic.Stats.MemoryUsage="Minnesanvändning" Basic.Stats.AverageTimeToRender="Medeltid för att rendera bildruta" Basic.Stats.SkippedFrames="Bildrutor som hoppades över p.g.a. kodningslagg" @@ -156,9 +186,13 @@ Basic.Stats.Status.Recording="Spelar in" Basic.Stats.Status.Live="SÄNDER" Basic.Stats.Status.Reconnecting="Återansluter" Basic.Stats.Status.Inactive="Inaktiv" -Basic.Stats.DroppedFrames="Tappade bildrutor (nätverk)" +Basic.Stats.DroppedFrames="Förlorade bildrutor (nätverk)" Basic.Stats.MegabytesSent="Total datautmatning" Basic.Stats.Bitrate="Bithastighet" +Basic.Stats.DiskFullIn="Hårddisk full om (ca.)" + +ResetUIWarning.Title="Är du säker på att du vill återställa gränssnittet?" +ResetUIWarning.Text="När gränssnittet återställs dölj ytterligare komponenter. Du kommer behöva ta fram dessa komponenter från menyn Visa om du vill att de ska vara synliga.\n\nÄr du säker på att du vill återställa gränssnittet?" Updater.Title="Ny uppdatering tillgänglig" Updater.Text="Det finns en ny uppdatering tillgänglig:" @@ -188,7 +222,7 @@ Basic.SceneTransitions="Scenövergångar" Basic.TransitionDuration="Varaktighet" Basic.TogglePreviewProgramMode="Studioläge" -TransitionNameDlg.Text="Skriv in namnet på övergången" +TransitionNameDlg.Text="Var god ange övergångens namn" TransitionNameDlg.Title="Övergångsnamn" TitleBar.Profile="Profil" @@ -197,7 +231,7 @@ TitleBar.Scenes="Scener" NameExists.Title="Namnet används redan" NameExists.Text="Det namnet används redan." -NoNameEntered.Title="Vänligen ange ett giltigt namn" +NoNameEntered.Title="Var god ange ett giltigt namn" NoNameEntered.Text="Du måste ange ett namn." ConfirmStart.Title="Börja strömma?" @@ -206,17 +240,21 @@ ConfirmStart.Text="Är du säker på att du vill börja strömma?" ConfirmStop.Title="Sluta strömma?" ConfirmStop.Text="Är du säker på att du vill sluta strömma?" +ConfirmBWTest.Title="Starta bandbreddstest?" +ConfirmBWTest.Text="Du har konfigurerat OBS i testläge för bandbredd. Detta läge låter dig testa nätverket utan att din kanal direktsänder. När du har testat färdigt behöver du inaktivera den för att att tittare ska kunna se din ström.\n\nVill du fortsätta?" + ConfirmExit.Title="Avsluta OBS?" -ConfirmExit.Text="OBS är aktivt. Alla strömmar/inspelningar kommer att stängas av. Är du säker på att du vill avsluta?" +ConfirmExit.Text="OBS är aktivt. Alla strömmar/inspelningar kommer att stängas av. Är du säker på att du vill avsluta?" ConfirmRemove.Title="Bekräfta borttagning" -ConfirmRemove.Text="Vill du verkligen ta bort '$1'?" +ConfirmRemove.Text="Vill du verkligen ta bort \"$1\"?" ConfirmRemove.TextMultiple="Är du säker på att du vill ta bort %1 poster?" Output.StartStreamFailed="Misslyckades att starta strömning" Output.StartRecordingFailed="Misslyckades att starta inspelning" Output.StartReplayFailed="Misslyckades att starta reprisbuffert" -Output.StartFailedGeneric="Misslyckades att starta utmatningen. Kolla loggen för detaljer.\n\nOBS: Om du använder kodarna NVENC eller AMD, se till att dina grafikdrivrutiner är uppdaterade." +Output.StartFailedGeneric="Misslyckades att starta utmatningen. Kolla loggen för detaljer.\n\nOBS: Om du använder kodarna NVENC eller AMD, se till att dina grafikdrivrutiner är uppdaterade." + Output.ConnectFail.Title="Anslutning misslyckades" Output.ConnectFail.BadPath="Ogiltig sökväg eller anslutnings-URL. Kontrollera att dina inställningar är korrekta." @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="Kunde inte komma åt den valda kanalen eller s Output.ConnectFail.Error="Ett oväntat fel uppstod vid anslutning till servern. Se loggfilen för ytterligare information." Output.ConnectFail.Disconnected="Nedkopplad från servern." +Output.StreamEncodeError.Title="Kodningsfel" +Output.StreamEncodeError.Msg="Ett kodarfel uppstod under strömmande." + Output.RecordFail.Title="Det gick inte att starta inspelningen" Output.RecordFail.Unsupported="Antingen stöds inte utdataformatet eller så har det inte stöd för mer än ett ljudspår. Kontrollera dina inställningar och försök igen." Output.RecordNoSpace.Title="Otillräckligt diskutrymme" Output.RecordNoSpace.Msg="Det finns inte tillräckligt med diskutrymme för att fortsätta inspelningen." Output.RecordError.Title="Inspelningsfel" Output.RecordError.Msg="Ett okänt fel uppstod vid inspelning." +Output.RecordError.EncodeErrorMsg="Ett kodarfel uppstod under inspelning." Output.ReplayBuffer.NoHotkey.Title="Ingen angivet kortkommando!" Output.ReplayBuffer.NoHotkey.Msg="Inget kortkommando för att spara reprisbufferten har angivits. Ange kortkommandot \"Spara\" för att kunna spara reprisinspelningar." @@ -241,25 +283,23 @@ LogReturnDialog="Loggfilen laddades upp utan problem." LogReturnDialog.CopyURL="Kopiera URL" LogReturnDialog.ErrorUploadingLog="Ett fel uppstod när loggfilen skulle laddas upp" -LicenseAgreement="Licensavtal" -LicenseAgreement.PleaseReview="Läs igenom licensvillkoren innan du använder OBS. Genom att använda det här programmet bekräftar du att du har läst och godkänner villkoren i GNU General Public License v2.0. Vänligen scrolla ner för att se resten av avtalet." -LicenseAgreement.ClickIAgreeToContinue="Om du accepterar villkoren i avtalet, klicka på \"Jag godkänner\" för att fortsätta. Du måste godkänna avtalet för att använda OBS." -LicenseAgreement.IAgree="Jag godkänner" -LicenseAgreement.Exit="Avsluta" - Remux.SourceFile="OBS Inspelning" Remux.TargetFile="Målfil" Remux.Remux="Remux" +Remux.Stop="Stoppa remuxing" +Remux.ClearFinished="Rensa slutförda objekt" +Remux.ClearAll="Rensa alla objekt" Remux.OBSRecording="OBS Inspelning" Remux.FinishedTitle="Remuxing färdig" Remux.Finished="Inspelning remuxed" Remux.FinishedError="Inspelning remuxed, men filen kan vara ofullständig" -Remux.SelectRecording="Välj OBS inspelning …" -Remux.SelectTarget="Välj målfil …" -Remux.FileExistsTitle="Målfil finns" -Remux.FileExists="Målfil finns, vill du ersätta den?" +Remux.SelectRecording="Välj OBS-inspelning..." +Remux.SelectTarget="Välj målfil..." +Remux.FileExistsTitle="Målfiler finns redan" +Remux.FileExists="Följande målfiler finns redan. Vill du ersätta dem?" Remux.ExitUnfinishedTitle="Remuxing pågår" Remux.ExitUnfinished="Remuxing är inte klar, stoppas det nu kan göra målfilen oanvändbar.\nÄr du säker på att du vill stoppa remuxing?" +Remux.HelpText="Släpp filer att göra en remux på i detta fönster eller välj en tom tabellcell under \"OBS-inspelning\" för att bläddra efter en fil." UpdateAvailable="Ny uppdatering tillgänglig" UpdateAvailable.Text="Version %1.%2.%3 finns nu tillgänglig. Klicka här för att ladda ner" @@ -276,11 +316,14 @@ Basic.DisplayCapture="Bildskärmskälla" Basic.Main.PreviewConextMenu.Enable="Aktivera förhandsvisning" +Basic.Main.Preview.Disable="Inaktivera förhandsvisning" + ScaleFiltering="Skalningsfiltrering" ScaleFiltering.Point="Punkt" ScaleFiltering.Bilinear="Bilinjär" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" Deinterlacing="Avflätning" Deinterlacing.Discard="Avfärda" @@ -300,22 +343,22 @@ VolControl.Mute="Tysta \"%1\"" VolControl.Properties="Egenskaper för \"%1\"" Basic.Main.AddSceneDlg.Title="Lägg till scen" -Basic.Main.AddSceneDlg.Text="Vänligen ange ett namn för scenen" +Basic.Main.AddSceneDlg.Text="Var god ange scenens namn" Basic.Main.DefaultSceneName.Text="Scen %1" -Basic.Main.AddSceneCollection.Title="Lägg till scen-samling" -Basic.Main.AddSceneCollection.Text="Skriv in namnet på scen-samlingen" +Basic.Main.AddSceneCollection.Title="Lägg till scensamling" +Basic.Main.AddSceneCollection.Text="Var god ange scensamlingens namn" -Basic.Main.RenameSceneCollection.Title="Byt namn på scen-samlingen" +Basic.Main.RenameSceneCollection.Title="Byt namn på scensamling" -AddProfile.Title="Lägg till Profil" -AddProfile.Text="Skriv in namnet på profilen" +AddProfile.Title="Lägg till profil" +AddProfile.Text="Var god ange profilens namn" -RenameProfile.Title="Byt namn på Profilen" +RenameProfile.Title="Byt namn på profilen" -Basic.Main.MixerRename.Title="Döp om ljudkälla" -Basic.Main.MixerRename.Text="Ange namnet på ljudkällan" +Basic.Main.MixerRename.Title="Byt namn på ljudkälla" +Basic.Main.MixerRename.Text="Var god ange ljudkällans namn" Basic.Main.PreviewDisabled="Förhandsvisningen är inaktiverad" @@ -325,26 +368,26 @@ Basic.SourceSelect.CreateNew="Skapa ny" Basic.SourceSelect.AddExisting="Lägg till befintlig" Basic.SourceSelect.AddVisible="Gör källan synlig" -Basic.PropertiesWindow="Egenskaper för '%1'" +Basic.PropertiesWindow="Egenskaper för \"%1\"" Basic.PropertiesWindow.AutoSelectFormat="%1 (välj automatiskt: %2)" Basic.PropertiesWindow.SelectColor="Välj färg" Basic.PropertiesWindow.SelectFont="Välj typsnitt" Basic.PropertiesWindow.ConfirmTitle="Inställningarna har ändrats" -Basic.PropertiesWindow.Confirm="Det finns osparade ändringar. Vill du behålla dem?" +Basic.PropertiesWindow.Confirm="Det finns osparade ändringar. Vill du behålla dem?" Basic.PropertiesWindow.NoProperties="Inga inställningar tillgängliga" Basic.PropertiesWindow.AddFiles="Lägg till Filer" Basic.PropertiesWindow.AddDir="Lägg till mapp" Basic.PropertiesWindow.AddURL="Lägg till Sökväg/URL" -Basic.PropertiesWindow.AddEditableListDir="Lägg till mapp i '%1'" -Basic.PropertiesWindow.AddEditableListFiles="Lägg till filer i '%1'" -Basic.PropertiesWindow.AddEditableListEntry="Lägg till post i '%1'" -Basic.PropertiesWindow.EditEditableListEntry="Redigera post från '%1'" +Basic.PropertiesWindow.AddEditableListDir="Lägg till mapp i \"%1\"" +Basic.PropertiesWindow.AddEditableListFiles="Lägg till filer i \"%1\"" +Basic.PropertiesWindow.AddEditableListEntry="Lägg till post i \"%1\"" +Basic.PropertiesWindow.EditEditableListEntry="Redigera post från \"%1\"" Basic.PropertiesView.FPS.Simple="Enkla bildfrekvensvärden" Basic.PropertiesView.FPS.Rational="Rationella bildfrekvensvärden" Basic.PropertiesView.FPS.ValidFPSRanges="Giltiga bildfrekvensintervall:" -Basic.InteractionWindow="Interagerar med '%1'" +Basic.InteractionWindow="Interagerar med \"%1\"" Basic.StatusBar.Reconnecting="Frånkopplad, återansluter om %2 sekund(er) (försök %1)" Basic.StatusBar.AttemptingReconnect="Försöker att återansluta... (försök %1)" @@ -358,7 +401,7 @@ Basic.Filters="Filter" Basic.Filters.AsyncFilters="Audio/Video filter" Basic.Filters.AudioFilters="Ljudfilter" Basic.Filters.EffectFilters="Effektfilter" -Basic.Filters.Title="Filter för '%1'" +Basic.Filters.Title="Filter för \"%1\"" Basic.Filters.AddFilter.Title="Filternamn" Basic.Filters.AddFilter.Text="Vänligen ange namnet på filtret" @@ -397,64 +440,66 @@ Basic.Main.Scenes="Scener" Basic.Main.Sources="Källor" Basic.Main.Controls="Kontroller" Basic.Main.Connecting="Ansluter..." -Basic.Main.StartRecording="Starta inspelning" +Basic.Main.StartRecording="Börja spela in" Basic.Main.StartReplayBuffer="Starta reprisbuffert" Basic.Main.StartStreaming="Börja strömma" -Basic.Main.StopRecording="Stoppa inspelning" -Basic.Main.StoppingRecording="Stoppar inspelning..." +Basic.Main.StopRecording="Sluta spela in" +Basic.Main.StoppingRecording="Slutar spela in..." Basic.Main.StopReplayBuffer="Stoppa reprisbuffert" Basic.Main.StoppingReplayBuffer="Stoppar reprisbuffert..." Basic.Main.StopStreaming="Sluta strömma" -Basic.Main.StoppingStreaming="Stoppar ström..." +Basic.Main.StoppingStreaming="Slutar strömma..." Basic.Main.ForceStopStreaming="Sluta strömma (ignorera fördröjning)" Basic.Main.Group="Grupp %1" -Basic.Main.GroupItems="Gruppmarkerade föremål" +Basic.Main.GroupItems="Gruppera markerade föremål" Basic.Main.Ungroup="Avgruppera" -Basic.MainMenu.File="&Arkiv" +Basic.MainMenu.File="Arkiv (&F)" Basic.MainMenu.File.Export="&Exportera" Basic.MainMenu.File.Import="&Importera" -Basic.MainMenu.File.ShowRecordings="Visa &inspelningar" +Basic.MainMenu.File.ShowRecordings="Visa inspelninga&r" Basic.MainMenu.File.Remux="Re&muxa inspelningar" -Basic.MainMenu.File.Settings="&Inställningar" +Basic.MainMenu.File.Settings="In&ställningar" Basic.MainMenu.File.ShowSettingsFolder="Visa inställningsmapp" Basic.MainMenu.File.ShowProfileFolder="Visa profilmapp" Basic.MainMenu.AlwaysOnTop="&Alltid överst" -Basic.MainMenu.File.Exit="&Avsluta" +Basic.MainMenu.File.Exit="Avsluta (&X)" -Basic.MainMenu.Edit="&Redigera" -Basic.MainMenu.Edit.Undo="&Ångra" -Basic.MainMenu.Edit.Redo="&Gör om" -Basic.MainMenu.Edit.UndoAction="&Ångra $1" -Basic.MainMenu.Edit.RedoAction="&Gör om $1" +Basic.MainMenu.Edit="R&edigera" +Basic.MainMenu.Edit.Undo="Ångra (&U)" +Basic.MainMenu.Edit.Redo="Gö&r om" +Basic.MainMenu.Edit.UndoAction="Ångra $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Gö&r om $1" Basic.MainMenu.Edit.LockPreview="&Lås förhandsvisning" Basic.MainMenu.Edit.Scale="Förhandsvisa &skalning" Basic.MainMenu.Edit.Scale.Window="Skala till fönster" Basic.MainMenu.Edit.Scale.Canvas="Kanvas (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Utmatning (%1x%2)" -Basic.MainMenu.Edit.Transform="&Omvandla" -Basic.MainMenu.Edit.Transform.EditTransform="&Redigera omvandling..." +Basic.MainMenu.Edit.Transform="Omvandla (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="R&edigera omvandling..." Basic.MainMenu.Edit.Transform.CopyTransform="Kopiera transformering" Basic.MainMenu.Edit.Transform.PasteTransform="Klistra in transformering" -Basic.MainMenu.Edit.Transform.ResetTransform="&Återställ omvandling" -Basic.MainMenu.Edit.Transform.Rotate90CW="Rotera 90 grader medsols &>" -Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotera 90 grader motsols &<" +Basic.MainMenu.Edit.Transform.ResetTransform="Åte&rställ omvandling" +Basic.MainMenu.Edit.Transform.Rotate90CW="Rotera 90 grader medsols" +Basic.MainMenu.Edit.Transform.Rotate90CCW="Rotera 90 grader motsols" Basic.MainMenu.Edit.Transform.Rotate180="Rotera 180 grader" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Spegelvänd &vågrätt" -Basic.MainMenu.Edit.Transform.FlipVertical="Spegelvänd &lodrätt" -Basic.MainMenu.Edit.Transform.FitToScreen="&Anpassa till skärmen" -Basic.MainMenu.Edit.Transform.StretchToScreen="Anpassa storlek till sk&ärmen" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Spegelvänd vågrätt (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Spegel&vänd lodrätt" +Basic.MainMenu.Edit.Transform.FitToScreen="Anpassa till skärmen (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Anpa&ssa storlek till skärmen" Basic.MainMenu.Edit.Transform.CenterToScreen="&Centrera på skärmen" +Basic.MainMenu.Edit.Transform.VerticalCenter="Centrera vertikalt" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Centrera horisontalt" Basic.MainMenu.Edit.Order="&Ordning" Basic.MainMenu.Edit.Order.MoveUp="Flytta &upp" -Basic.MainMenu.Edit.Order.MoveDown="Flytta &ned" -Basic.MainMenu.Edit.Order.MoveToTop="Lägg &överst" -Basic.MainMenu.Edit.Order.MoveToBottom="Lägg unders&t" +Basic.MainMenu.Edit.Order.MoveDown="Flytta ne&d" +Basic.MainMenu.Edit.Order.MoveToTop="Lägg övers&t" +Basic.MainMenu.Edit.Order.MoveToBottom="Lägg underst (&B)" Basic.MainMenu.Edit.AdvAudio="&Avancerade ljudinställningar" Basic.MainMenu.View="&Visa" -Basic.MainMenu.View.Toolbars="&Verktygsfält" -Basic.MainMenu.View.Docks="Komponenter" +Basic.MainMenu.View.Toolbars="Verk&tygsfält" +Basic.MainMenu.View.Docks="Flytande fönster" Basic.MainMenu.View.Docks.ResetUI="Återställ gränssnitt" Basic.MainMenu.View.Docks.LockUI="Lås gränssnitt" Basic.MainMenu.View.Toolbars.Listboxes="&Listrutor" @@ -471,21 +516,22 @@ Basic.MainMenu.SceneCollection.Export="Exportera scensamling" Basic.MainMenu.Profile.Exists="Profilen finns redan" Basic.MainMenu.SceneCollection.Exists="Scensamlingen finns redan" -Basic.MainMenu.Tools="&Verktyg" +Basic.MainMenu.Tools="Verk&tyg" Basic.MainMenu.Help="&Hjälp" Basic.MainMenu.Help.HelpPortal="Hjälp&portal" Basic.MainMenu.Help.Website="Besök &webbplats" Basic.MainMenu.Help.Discord="Anslut till &Discord-servern" Basic.MainMenu.Help.Logs="&Loggfiler" -Basic.MainMenu.Help.Logs.ShowLogs="&Visa loggfiler" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Ladda upp &aktuell loggfil" -Basic.MainMenu.Help.Logs.UploadLastLog="Ladda upp &senaste loggfil" +Basic.MainMenu.Help.Logs.ShowLogs="Vi&sa loggfiler" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Ladda upp aktuell loggfil (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="&Ladda upp senaste loggfil" Basic.MainMenu.Help.Logs.ViewCurrentLog="&Visa Aktuell Logg" Basic.MainMenu.Help.CheckForUpdates="Sök efter uppdateringar" Basic.MainMenu.Help.CrashLogs="Krasch&rapporter" -Basic.MainMenu.Help.CrashLogs.ShowLogs="&Visa kraschrapporter" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Ladda upp &senaste kraschrapport" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Vi&sa kraschrapporter" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Ladda upp senaste kraschrapport" +Basic.MainMenu.Help.About="Om (&A)" Basic.Settings.ProgramRestart="Du måste starta om programmet för att ändringarna ska träda i kraft." Basic.Settings.ConfirmTitle="Bekräfta ändringar" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="Systemfält" Basic.Settings.General.SysTrayWhenStarted="Minimera till meddelandefältet vid start" Basic.Settings.General.SystemTrayHideMinimize="Minimera alltid till meddelandefältet i stället för aktivitetsfältet" Basic.Settings.General.SaveProjectors="Spara projektorer vid avslut" +Basic.Settings.General.Preview="Förhandsvisning" +Basic.Settings.General.OverflowHidden="Dölj överflöd" +Basic.Settings.General.OverflowAlwaysVisible="Överflöd visas alltid" +Basic.Settings.General.OverflowSelectionHidden="Visa överflöd även om källan är osynlig" Basic.Settings.General.SwitchOnDoubleClick="Övergång till scen vid dubbelklick" Basic.Settings.General.StudioPortraitLayout="Aktivera porträtt-/vertikalt utseende" +Basic.Settings.General.TogglePreviewProgramLabels="Visa förhandsvisning/programetiketter" Basic.Settings.General.Multiview="Multivy" Basic.Settings.General.Multiview.MouseSwitch="Klicka för att byta mellan scener" Basic.Settings.General.Multiview.DrawSourceNames="Visa scennamn" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Horisontal, öve Basic.Settings.Stream="Ström" Basic.Settings.Stream.StreamType="Strömtyp" +Basic.Settings.Stream.Custom.UseAuthentication="Använd autentisering" +Basic.Settings.Stream.Custom.Username="Användarnamn" +Basic.Settings.Stream.Custom.Password="Lösenord" +Basic.Settings.Stream.BandwidthTestMode="Aktivera testläge för bandbredd" Basic.Settings.Output="Utmatning" Basic.Settings.Output.Format="Inspelningsformat" @@ -557,10 +612,9 @@ Basic.Settings.Output.Simple.RecordingQuality.Lossless="Förlustfri kvalitet, oe Basic.Settings.Output.Simple.Warn.VideoBitrate="Varning: Streamens videobit-rate kommer att sättas till %1, vilket är den övre gränsen för den nuvarande streaming-tjänsten. Om du är säker på att du vill gå över %1, aktivera \"avancerade kodarinställningar\" och avaktivera \"Tvinga streaming-tjänstens bit-rategränser\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="Varning: Streamens ljudbit-rate kommer att sättas till %1, vilket är den övre gränsen för den nuvarande streaming-tjänsten. Om du är säker på att du vill gå över %1, aktivera \"avancerade kodarinställningar\" och avaktivera \"Tvinga streaming-tjänstens bit-rategränser\"." Basic.Settings.Output.Simple.Warn.Encoder="Varning: Inspelning med en mjukvaru-kodare i annan kvalitet än streamen kräver mer CPU-använding om du streamar och spelar in samtidigt." -Basic.Settings.Output.Simple.Warn.Lossless="Varning: Förlustfri kvalitet generar oerhört stora filstorlekar! Förlustfri kvalitet kan använda upp till 7 gigabyte hårddiskutrymme per minut vid höga upplösningar och bildfrekvenser. Detta rekommenderas inte för långa inspelningar såvida du har riktigt mycket hårddiskutrymme tillgängligt." +Basic.Settings.Output.Simple.Warn.Lossless="Varning: Förlustfri kvalitet generar oerhört stora filstorlekar! Förlustfri kvalitet kan använda upp till 7 gigabyte hårddiskutrymme per minut vid höga upplösningar och bildfrekvenser. Detta rekommenderas inte för långa inspelningar såvida du har riktigt mycket hårddiskutrymme tillgängligt." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Är du säker på att du vill använda förlustfri kvalitet?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Varning angående förlustfri kvalitet!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Varning: Du kan inte använda flera separata QSV-kodare när du streamar och spelar in samtidigt. Om du vill streama och spela in samtidigt, vänligen ändra inspelnings-kodek eller streaming-kodek." Basic.Settings.Output.Simple.Encoder.Software="Programvara (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hårdvara (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hårdvara (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="Automatisk återanslutning" Basic.Settings.Output.RetryDelay="Återanslutningsfördröjning (sek)" Basic.Settings.Output.MaxRetries="Maximalt antal försök" Basic.Settings.Output.Advanced="Aktivera avancerade kodarinställningar" -Basic.Settings.Output.EncoderPreset="Kodarförinställning (högre = mindre CPU)" +Basic.Settings.Output.EncoderPreset="Förinställning för kodare" Basic.Settings.Output.CustomEncoderSettings="Inställningar för anpassade kodare" Basic.Settings.Output.CustomMuxerSettings="Anpassade muxerinställningar" Basic.Settings.Output.NoSpaceFileName="Generera filnamn utan mellanrum" @@ -622,18 +676,18 @@ FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss FilenameFormatting.TT="%CCYY År, fyra siffror\n%YY År, de två sista siffrorna (00-99)\n%MM Månad som en siffra (01-12)\n%DD Månadens dag, inledande nolla (01-31)\n%hh Timme i 24-timmarsformat (00-23)\n%mm Minut (00-59)\n%ss Sekund (00-61)\n%% Ett procenttecken\n%a Förkortad veckodag\n%A Fullständig veckodag\n%b Förkortat månadsnamn\n%B Fullständigt månadsnamn\n%d Månadens dag, inledande nolla (01-31)\n%H Timme i 24-timmarsformat (00-23)\n%I Timme i 12-timmarsformat (01-12)\n%m Månad som en siffra (01-12)\n%M Minut (00-59)\n%p AM eller PM\n%S Sekund (00-61)\n%y År, de två sista siffrorna (00-99)\n%Y År\n%z ISO 8601-offset från UTC eller tidszonens\n namn eller förkortning\n%Z Tidszonens namn eller förkortning\n" Basic.Settings.Video="Video" -Basic.Settings.Video.Adapter="Grafikkort:" -Basic.Settings.Video.BaseResolution="Grundupplösning (kanvas):" -Basic.Settings.Video.ScaledResolution="Utdataupplösning (skalad):" +Basic.Settings.Video.Adapter="Grafikkort" +Basic.Settings.Video.BaseResolution="Grundupplösning (kanvas)" +Basic.Settings.Video.ScaledResolution="Utdataupplösning (skalad)" Basic.Settings.Video.DownscaleFilter="Nedskalningsfilter" -Basic.Settings.Video.DisableAeroWindows="Inaktivera Aero (endast Windows)" +Basic.Settings.Video.DisableAeroWindows="Avaktivera Aero (endast Windows)" Basic.Settings.Video.FPS="FPS" Basic.Settings.Video.FPSCommon="Vanliga bildhastighetsvärden" Basic.Settings.Video.FPSInteger="Heltals-bildhastighetsvärde" Basic.Settings.Video.FPSFraction="Decimaltals-bildhastighetsvärde" Basic.Settings.Video.Numerator="Täljare" Basic.Settings.Video.Denominator="Nämnare" -Basic.Settings.Video.Renderer="Renderare" +Basic.Settings.Video.Renderer="Renderare:" Basic.Settings.Video.InvalidResolution="Ogiltig upplösning. Måste anges som [bredd]x[höjd] (t.ex 1920x1080)" Basic.Settings.Video.CurrentlyActive="Videoutmatning är aktiv. Stoppa alla utmatningar för att kunna ändra videoinställningar." Basic.Settings.Video.DisableAero="Inaktivera Aero" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Vässd skalning, 32 prove Basic.Settings.Audio="Ljud" Basic.Settings.Audio.SampleRate="Samplingsfrekvens" Basic.Settings.Audio.Channels="Kanaler" -Basic.Settings.Audio.MeterDecayRate="Ljudmätarens förfallfrekvens" +Basic.Settings.Audio.Meters="Mätare" +Basic.Settings.Audio.MeterDecayRate="Sänkningshastighet" Basic.Settings.Audio.MeterDecayRate.Fast="Snabb" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Långsam (Type II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="VARNING: Surroundljud är akti Basic.Settings.Audio.MultichannelWarning="Om du strömmar, se till att kolla om din strömtjänst stöder både inmatning och uppspelning av surroundljud. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast är några exempel på tjänster som har fullt stöd. Fastän Facebook Live och YouTube Live stöder inmatning för surroundljud mixar Facebook Live ned till stereo och YouTube Live spelar upp i bara två kanaler.\n\nLjudfiltren i OBS är kompatibla med surroundljud, fast stöd för VST-insticksmodulen garanteras inte." Basic.Settings.Audio.MultichannelWarning.Title="Aktivera surroundljud?" Basic.Settings.Audio.MultichannelWarning.Confirm="Är du säker på att du vill aktivera surroundljud?" -Basic.Settings.Audio.DesktopDevice="Skrivbordsljudenhet" -Basic.Settings.Audio.DesktopDevice2="Skrivbordsljudenhet 2" -Basic.Settings.Audio.AuxDevice="Mikrofon/extra ljudenhet" -Basic.Settings.Audio.AuxDevice2="Mikrofon/extra ljudenhet 2" -Basic.Settings.Audio.AuxDevice3="Mikrofon/extra ljudenhet 3" +Basic.Settings.Audio.Devices="Enheter" +Basic.Settings.Audio.DesktopDevice="Skrivbordsljud" +Basic.Settings.Audio.DesktopDevice2="Skrivbordsljud 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/extra ljud" +Basic.Settings.Audio.AuxDevice2="Mikrofon/extra ljud 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/extra ljud 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/extra ljud 4" Basic.Settings.Audio.EnablePushToMute="Aktivera tryck för att tysta" Basic.Settings.Audio.PushToMuteDelay="Fördröjning för tryck för att tysta" Basic.Settings.Audio.EnablePushToTalk="Aktivera tryck för att tala" Basic.Settings.Audio.PushToTalkDelay="Fördröjning för tryck för att tala" Basic.Settings.Audio.UnknownAudioDevice="[Enheten är inte ansluten eller tillgänglig]" +Basic.Settings.Audio.Disabled="Inaktiverad" Basic.Settings.Advanced="Avancerat" Basic.Settings.Advanced.General.ProcessPriority="Processprioritet" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Inaktiv" Basic.Settings.Advanced.FormatWarning="Varning: Andra färgformat än NV12 är avsedda för inspelning och rekommenderas inte för att strömma. Högre processoranvändning kan uppstå vid strömning p.g.a. konvertering av färgformat." Basic.Settings.Advanced.Audio.BufferingTime="Ljudbuffringstid" Basic.Settings.Advanced.Video.ColorFormat="Färgformat" -Basic.Settings.Advanced.Video.ColorSpace="YUV-färgrymd" -Basic.Settings.Advanced.Video.ColorRange="YUV-färgområde" +Basic.Settings.Advanced.Video.ColorSpace="Färgrymd" +Basic.Settings.Advanced.Video.ColorRange="Färgintervall" Basic.Settings.Advanced.Video.ColorRange.Partial="Partiell" Basic.Settings.Advanced.Video.ColorRange.Full="Full" -Basic.Settings.Advanced.Audio.MonitoringDevice="Ljuduppspelningsenhet" +Basic.Settings.Advanced.Audio.MonitoringDevice="Uppspelningsenhet" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Standard" Basic.Settings.Advanced.Audio.DisableAudioDucking="Inaktivera audio ducking i Windows" Basic.Settings.Advanced.StreamDelay="Strömfördröjning" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="Bind till IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Aktivera ny nätverkskod" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Låg latens-läge" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Inaktivera kortkommandon när fokus ligger i huvudfönstret" +Basic.Settings.Advanced.AutoRemux="Remuxa automatiskt till mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(spela in som mkv)" Basic.AdvAudio="Avancerade ljudinställningar" Basic.AdvAudio.Name="Namn" -Basic.AdvAudio.Volume="Volym (%)" +Basic.AdvAudio.Volume="Volym" Basic.AdvAudio.Mono="Nedmixa till mono" -Basic.AdvAudio.Panning="Panorering" +Basic.AdvAudio.Balance="Balans" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.Monitoring="Ljuduppspelning" Basic.AdvAudio.Monitoring.None="Monitor av" @@ -708,6 +768,7 @@ Basic.AdvAudio.AudioTracks="Spår" Basic.Settings.Hotkeys="Kortkommandon" Basic.Settings.Hotkeys.Pair="Tangentkombinationer som delas med \"%1\" fungerar som strömbrytare" +Basic.Settings.Hotkeys.Filter="Filter" Basic.Hotkeys.SelectScene="Byt till scen" @@ -735,7 +796,7 @@ Hotkeys.Up="Upp" Hotkeys.Down="Ned" Hotkeys.Windows="Windows" Hotkeys.Super="Super" -Hotkeys.Menu="Meny" +Hotkeys.Menu="Menu" Hotkeys.Space="Mellanslag" Hotkeys.NumpadNum="%1 (Numpad)" Hotkeys.NumpadMultiply="* (Numpad)" @@ -743,26 +804,27 @@ Hotkeys.NumpadDivide="/ (Numpad)" Hotkeys.NumpadAdd="+ (Numpad)" Hotkeys.NumpadSubtract="- (Numpad)" Hotkeys.NumpadDecimal=", (Numpad)" -Hotkeys.AppleKeypadNum="%1 (Keypad)" -Hotkeys.AppleKeypadMultiply="* (Keypad)" -Hotkeys.AppleKeypadDivide="/ (Keypad)" -Hotkeys.AppleKeypadAdd="+ (Keypad)" -Hotkeys.AppleKeypadSubtract="- (Keypad)" -Hotkeys.AppleKeypadDecimal=". (Keypad)" -Hotkeys.AppleKeypadEqual="= (Keypad)" +Hotkeys.AppleKeypadNum="%1 (numpad)" +Hotkeys.AppleKeypadMultiply="* (numpad)" +Hotkeys.AppleKeypadDivide="/ (numpad)" +Hotkeys.AppleKeypadAdd="+ (numpad)" +Hotkeys.AppleKeypadSubtract="- (numpad)" +Hotkeys.AppleKeypadDecimal=". (numpad)" +Hotkeys.AppleKeypadEqual="= (numpad)" Hotkeys.MouseButton="Musknapp %1" +Hotkeys.Escape="Esc" Mute="Stäng av ljud" Unmute="Slå på ljud" Push-to-mute="Tryck för att tysta" Push-to-talk="Tryck för att tala" -SceneItemShow="Visa '%1'" -SceneItemHide="Dölj '%1'" +SceneItemShow="Visa \"%1\"" +SceneItemHide="Dölj \"%1\"" OutputWarnings.NoTracksSelected="Du måste välja minst ett spår" OutputWarnings.MultiTrackRecording="Varning: En del format (t.ex. FLV) stöder inte flera spår för varje inspelning" -OutputWarnings.MP4Recording="Varning: Inspelningar som sparas som MP4 kommer inte att kunna återställas om filen inte kan slutföras (d.v.s. om en datorkrasch, strömavbrott, etc. skulle inträffa). Om du vill spela in flera ljudspår, överväg att använda MKV och remuxa inspelningen till mp4 när den är färdig (Arkiv->Remuxa inspelningar)" +OutputWarnings.MP4Recording="Varning: Inspelningar som sparas i MP4/MOV kommer inte kunna återhämtas om filen inte slutförs (t.ex. p.g.a. blåskärmar, strömavbrott, etc.). Om du vill spela in flera ljudspår, överväg att använda MKV och remuxa inspelningen till MP4/MOV när den är färdig (Arkiv → Remuxa inspelningar)" FinalScene.Title="Radera scen" FinalScene.Text="Det måste finnas minst en scen." @@ -770,9 +832,24 @@ FinalScene.Text="Det måste finnas minst en scen." NoSources.Title="Inga källor" NoSources.Text="Det verkar som om du inte har lagt till några videokällor än, så du kommer endast att visa en tom skärm. Är du säker på att du vill göra detta?" NoSources.Text.AddSource="Du kan lägga till källor genom att klicka på plusikonen under rutan \"källor\" i huvudfönstret när som helst." +NoSources.Label="Du har inga källor.\nKlicka på plusknappen nedan eller\nhögerklicka för att lägga till en." ChangeBG="Ändra färg" CustomColor="Anpassad färg" BrowserSource.EnableHardwareAcceleration="Aktiverar webbläsarkällans hårdvaruaccelerering" +About="Om" +About.Info="OBS Studio är en fri och öppen programvara för att spela in video och direktsända." +About.Donate="Lämna ett bidrag" +About.GetInvolved="Engagera dig" +About.Authors="Upphovsmän" +About.License="Licens" +About.Contribute="Stöd OBS-projektet" + +ResizeOutputSizeOfSource="Storleksändra utmatning (källans storlek)" +ResizeOutputSizeOfSource.Text="Grund- och utmatningsupplösningarna kommer att ändras till storleken för den nuvarande källan." +ResizeOutputSizeOfSource.Continue="Vill du fortsätta?" + +PreviewTransition="Förhandsvisa övergång" + diff --git a/UI/data/locale/ta-IN.ini b/UI/data/locale/ta-IN.ini index b419738..a766569 100644 --- a/UI/data/locale/ta-IN.ini +++ b/UI/data/locale/ta-IN.ini @@ -1,6 +1,6 @@ Language="ஆங்கிலம்" -Region="யூனைடெட் ஸ்டேட்ஸ்" +Region="அமெரிக்கா" OK="சரி" Apply="அமல்படுத்து" @@ -14,96 +14,638 @@ No="இல்லை" Add="சேர்க்க" Remove="அகற்ற" Rename="மறுபெயரிடு" +Interact="ஊடாடு" +Filters="வடிகட்டிகள்" Properties="பண்புகள்" MoveUp="மேலே நகர்த்து" MoveDown="கீழ் நகர்த்து" Settings="அமைப்புகள்" +Display="காட்சித்திரை" Name="பெயர்" Exit="வெளியேறு" +Mixer="ஒலி கலவை" +Browse="உலாவு" +Mono="ஒற்றை ஒலி" +Stereo="பல ஒலி" +DroppedFrames="சிதறிய சட்டகங்கள் " +StudioProgramProjector="முழுத்திரை பிரதிபலிப்பான் (நிகழ்ச்சி)" +PreviewProjector="முழுத்திரை பிரதிபலிப்பான் (முன்னோட்டம்)" +SceneProjector="முழுத்திரை பிரதிபலிப்பான் (காட்சி)" +SourceProjector="முழுத்திரை பிரதிபலிப்பான் (மூலம்)" +StudioProgramWindow="சாளர பிரதிபலிப்பான் (நிகழ்ச்சி)" +PreviewWindow="சாளர பிரதிபலிப்பான் (முன்னோட்டம்)" +SceneWindow="சாளர பிரதிபலிப்பான் (காட்சி)" +SourceWindow="சாளர பிரதிபலிப்பான் (மூலம்)" +MultiviewProjector="பல்பார்வை (முழுத்திரை)" +MultiviewWindowed="பல்பார்வை (சாளரம்)" +Clear="நீக்கு" +Revert="மாற்றியமை" Show="காட்டு" Hide="மறை" -Untitled="தலைப்பிடாத" +UnhideAll="அனைத்தும் காண்பி" +Untitled="தலைப்பிடாதது" New="புதிய" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Duplicate="நகல்" +Enable="இயக்கு" +DisableOSXVSync="OSX V ஒத்திசைவை முடக்கு" +ResetOSXVSyncOnExit="V-ஒத்திசைவு வெளியேறுகையில் OSX மீட்டமை" +HighResourceUsage="குறியீட்டு சுமை அதிகமாக உள்ளது! வீடியோ அமைப்புகளைத் திருத்துவது அல்லது ஒரு வேகமான குறியீட்டு முன்னுரிமையைப் பயன்படுத்துவதைக் கருத்தில் கொள்ளவும்." +Transition="மாற்றம்" +QuickTransitions="விரைவான மாற்றங்கள்" +Left="இடது" +Right="வலது" +Top="மேல்" +Bottom="கீழ்" +Reset="மீட்டமை" +Hours="மணி நேரம்" +Minutes="நிமிடங்கள்" +Seconds="நொடிகள்" +Deprecated="அங்கீகரிக்கப்படாதது" +ReplayBuffer="தாங்கல் மறுபிரதி" +Import="இறக்குமதி" +Export="ஏற்றுமதி" +Copy="நகலெடு" +Paste="ஒட்டு" +PasteReference="ஒட்டு (குறிப்பு)" +PasteDuplicate="ஒட்டு (நகல்)" +RemuxRecordings="பதிவுகள் மாற்றியமைத்தல்" +Next="அடுத்த" +Back="பின்" +Defaults="இயல்புநிலை" +HideMixer="ஒலி கலவையில் மறைத்தல்" +TransitionOverride="மாற்றம் புறக்கணிப்பு" +None="எதுவுமில்லை" +StudioMode.Preview="முன்னோட்டம்" +StudioMode.Program="நிகழ்ச்சி" +ShowInMultiview="பல்பார்வை காண்பி" +VerticalLayout="செங்குத்து வடிவமைப்பு" +Group="குழு" +DoNotShowAgain="மீண்டும் காட்ட வேண்டாம்" + +AlreadyRunning.Title="OBS ஏற்கனவே இயங்கிக்கொண்டிருக்கிறது" +AlreadyRunning.Text="OBS ஏற்கனவே இயங்குகிறது! இதை தொடர நீங்கள் விரும்பவில்லை எனில், புதிய நிகழ்வை இயக்க முயற்சிக்கும் முன் OBS இன் எந்தவொரு நிகழ்வுகளையும் மூடவும். நீங்கள் கணினி தட்டில் OBS ஐ குறைத்து அமைத்திருந்தால், அது இன்னமும் இயங்கிக்கொண்டிருக்கிறதா என்பதைப் பார்க்கவும்." +AlreadyRunning.LaunchAnyway="எப்படியும் தொடங்கு" + +DockCloseWarning.Title="நகரக்கூடிய சாளரத்தை மூடு" +DockCloseWarning.Text="நீங்கள் ஒரு நகர்த்தக்கூடிய சாளரத்தை மூடியுள்ளீர்கள். நீங்கள் அதை மீண்டும் காண்பிக்க விரும்பினால், மெனு பட்டியில் காட்சி → டாக்ஸ் மெனுவைப் பயன்படுத்தவும்." + +Auth.Authing.Title="அங்கீகரிக்கிறது..." +Auth.Authing.Text="%1, உடன் அங்கீகரிக்கிறது, தயவுசெய்து காத்திருக்கவும்..." +Auth.AuthFailure.Title="அங்கீகரிப்பு தோல்வி" +Auth.AuthFailure.Text="%1:\n\n%2: %3 உடன் அங்கீகரிக்க தோல்வி" +Auth.InvalidScope.Title="அங்கீகாரம் தேவை" +Auth.InvalidScope.Text="%1 அங்கீகார தேவைகள் மாறிவிட்டன. சில அம்சங்கள் கிடைக்காது." +Auth.LoadingChannel.Title="சேனல் தகவல் ஏற்றுகிறது..." +Auth.LoadingChannel.Text="சேனல் தகவல் %1ஏற்றுகிறது, தயவுசெய்து காத்திருக்கவும்..." +Auth.ChannelFailure.Title="சேனல் நினைவேற்றுவது தோல்வியுற்றது" +Auth.ChannelFailure.Text="%1\n\n%2சேனல் தகவல் ஏற்ற முடியவில்லை: %3" +Auth.Chat="அரட்டை" +Auth.StreamInfo="அலை தகவல்" +TwitchAuth.Stats="Twitch விபரம்" +TwitchAuth.Feed="Twitch செயல்பாடு ஊட்டம்" + +Copy.Filters="வடிகட்டிகள் நகல்" +Paste.Filters="வடிகட்டிகள் ஒட்டு" + +BrowserPanelInit.Title="உலாவியில் தொடங்குகிறது..." +BrowserPanelInit.Text="உலாவியில் தொடங்குகிறது, தயவுசெய்து காத்திருக்கவும்..." + +BandwidthTest.Region="பிராந்தியம்" +BandwidthTest.Region.US="அமெரிக்கா" +BandwidthTest.Region.EU="ஐரோப்பா" +BandwidthTest.Region.Asia="ஆசியா" +BandwidthTest.Region.Other="மற்ற" + +Basic.FirstStartup.RunWizard="தானியங்கு உள்ளமைவு வழிகாட்டியை இயக்க விரும்புகிறீர்களா? நீங்கள் கைமுறையாக மேலும் உங்கள் அமைப்புகளை பிரதான சாளரத்தில் அமைப்புகள் பொத்தானை கிளிக் செய்வதன் மூலம் உள்ளமைக்கலாம்." +Basic.FirstStartup.RunWizard.NoClicked="உங்கள் மனதை மாற்றினால், நீங்கள் தானியங்கு உள்ளமைவு வழிகாட்டி எந்த நேரத்திலும் மீண்டும் பட்டியலிருந்து கருவிகளை இயக்கலாம்." + +Basic.AutoConfig="தானியங்கு உள்ளமைவு வழிகாட்டி" +Basic.AutoConfig.ApplySettings="அமைப்புகளைப் பயன்படுத்து" +Basic.AutoConfig.StartPage="தகவல் பயன்பாடு" +Basic.AutoConfig.StartPage.SubTitle="நீங்கள் நிகழ்ச்சியை எதற்காக பயன்படுத்துகிறீர் என்பதை குறிப்பிடவும்" +Basic.AutoConfig.StartPage.PrioritizeStreaming="நேரலைக்கு உகந்ததாகக்கு, பதிவு இரண்டாம் நிலையாக" +Basic.AutoConfig.StartPage.PrioritizeRecording="பதிவுக்கு மட்டும் உகந்ததாக்கு, நேரலை செய்ய மாட்டேன்" +Basic.AutoConfig.VideoPage="காணொளி அமைப்புகள்" +Basic.AutoConfig.VideoPage.SubTitle="நீங்கள் பயன்படுத்த விரும்பிய காணொளி அமைப்புகளைக் குறிப்பிடவும்" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="தற்போதையதை பயன்படுத்தவும் (%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="காட்சி முறை %1 (%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="தற்போதையதை பயன்படுத்தவும் (%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="ஒன்று 60 அல்லது 30, ஆனால் முடிந்தால் 60 தெரிந்தெடுக்கவும்" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="ஒன்று 60 அல்லது 30, ஆனால் உயர் தெளிவுத்திறனை தெரிந்தெடுக்கவும்" +Basic.AutoConfig.VideoPage.CanvasExplanation="குறிப்பு: சுற்றளவு (அடிப்படை) தெளிவுதிறனானது நேரலை அல்லது பதிவுக்கான தெளிவுதிறனுக்கு சமமாக இருக்கவேண்டிய அவசியம் இல்லை. உங்கள் உண்மையான நேரலை அல்லது பதிவுக்கான தெளிவுதிறன் சுற்றளவு தெளிவுதிறனிலிருந்து ஆதார பயன்பாடு அல்லது பிட்ரேட் தேவைகளுக்கு குறைக்கப்பட்டு இருக்கலாம்." +Basic.AutoConfig.StreamPage="அலை தகவல்" +Basic.AutoConfig.StreamPage.SubTitle="உங்கள் அலை தகவலை உள்ளிடவும்" +Basic.AutoConfig.StreamPage.ConnectAccount="இணைய கணக்கு (விருப்ப)" +Basic.AutoConfig.StreamPage.DisconnectAccount="கணக்கைத் துண்டிக்கவும்" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="கணக்கைத் துண்டிக்கவா?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="இந்த மாற்றம் உடனடியாக பொருந்தும். உங்கள் கணக்கு துண்டிக்க விரும்புகிறீர்களா?" +Basic.AutoConfig.StreamPage.UseStreamKey="நேரலை குறியீட்டை பயன்படுத்தவும்" +Basic.AutoConfig.StreamPage.Service="சேவை" +Basic.AutoConfig.StreamPage.Service.ShowAll="அனைத்தும் காண்பி..." +Basic.AutoConfig.StreamPage.Service.Custom="தனிபயன்..." +Basic.AutoConfig.StreamPage.Server="சேவையகம்" +Basic.AutoConfig.StreamPage.StreamKey="அலை குறியீடு" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(இணைப்பு)" +Basic.AutoConfig.StreamPage.PerformBandwidthTest="அலைவரிசை சோதனை மூலம் bitrate மதிப்பீடு (சில நிமிடங்கள் ஆகலாம்)" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding="விரும்பிய வன்பொருள் குறியீடு" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="வன்பொருள் குறியீட்டு முறை அதிக CPU பயன்பாட்டை நீக்குகிறது, ஆனால் அதே அளவு தரத்தை பெற bitrate தேவைப்படலாம்." +Basic.AutoConfig.StreamPage.StreamWarning.Title="நேரலை எச்சரிக்கை" +Basic.AutoConfig.StreamPage.StreamWarning.Text="அலைவரிசை சோதனை உங்கள் சேனலுக்கு ஆடியோ இல்லாமல் சீரற்ற வீடியோ தரவை நேரலை செய்ய உள்ளது. நீங்கள் முடிந்தால், சோதனை வீடியோக்களைத் தற்காலிகமாக நிறுத்துமாறு பரிந்துரைக்கிறோம், சோதனையை முடிந்தவரை, தனிப்பட்ட நேரலையாக அமைக்கலாம். தொடர்ந்து?" +Basic.AutoConfig.TestPage="இறுதி முடிவுகள்" +Basic.AutoConfig.TestPage.SubTitle.Testing="இந்த நிகழ்ச்சி மிகவும் சிறந்த அமைப்புகளை மதிப்பிடுவதற்கான சோதனைகளின் தொகுப்பை இப்போது செயல்படுத்துகிறது" +Basic.AutoConfig.TestPage.SubTitle.Complete="சோதனை முடிந்தது" +Basic.AutoConfig.TestPage.TestingBandwidth="அலைவரிசை சோதனை செய்கிறது, இதற்கு சில நிமிடங்கள் ஆகலாம்..." +Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="இணைப்பதற்கு: %1..." +Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="எந்த சேவையகங்களுடன் இணைப்பதில் தோல்வி, உங்கள் இணைய இணைப்பைச் சரிபார்த்து, மீண்டும் முயற்சிக்கவும்." +Basic.AutoConfig.TestPage.TestingBandwidth.Server="அலைவரிசை பரிசோதனை: %1" +Basic.AutoConfig.TestPage.TestingStreamEncoder="அலை குறியாக்கி பரிசோதனை, இது ஒரு நிமிடம் ஆகலாம்..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="பதிவு குறியாக்கி பரிசோதனை, இது ஒரு நிமிடம் ஆகலாம்..." +Basic.AutoConfig.TestPage.TestingRes="தெளிவுத்திறன் பரிசோதனை, இது சில நிமிடங்கள் எடுக்கலாம்..." +Basic.AutoConfig.TestPage.TestingRes.Fail="குறியாக்கி துவக்க இயலவில்லை" +Basic.AutoConfig.TestPage.TestingRes.Resolution="பரிசோதனை %1x%2 %3 FPS..." +Basic.AutoConfig.TestPage.Result.StreamingEncoder="அலை குறியாக்கி" +Basic.AutoConfig.TestPage.Result.RecordingEncoder="பதிவு குறியாக்கி" +Basic.AutoConfig.TestPage.Result.Header="இந்த நிகழ்ச்சி மதிப்பிடப்பட்ட அமைப்புகள் உங்களுக்கு மிகவும் சிறந்தது என்று தீர்மானித்துள்ளது:" +Basic.AutoConfig.TestPage.Result.Footer="இந்த அமைப்புகளைப் பயன்படுத்த, அமைப்புகள் பயன்படுத்து என்பதை சொடுக்கிடுக. வழிகாட்டி சீரமைக்க மற்றும் மீண்டும் முயற்சிக்க, பின் என்பதை சொடுக்கிடுக. கைமுறையாக அமைப்புகளை நீங்களாக கட்டமைக்க, ரத்துசெய் மற்றும் திறந்த அமைப்புகள் என்பதை சொடுக்கிடுக." + +Basic.Stats="புள்ளிவிவரங்கள்" +Basic.Stats.CPUUsage="CPU பயன்பாடு" +Basic.Stats.HDDSpaceAvailable="Hdd வட்டு இடம் கிடைக்கிறது" +Basic.Stats.MemoryUsage="நினைவக உபயோகம்" +Basic.Stats.AverageTimeToRender="சட்டம் வழங்குவதற்கான சராசரி நேரம்" +Basic.Stats.SkippedFrames="குறியீட்டு பின்னடைவு காரணமாக தவிர்க்கப்பட்ட சட்டங்கள்" +Basic.Stats.MissedFrames="வழங்குவதில் பின்னடைவு காரணமாக சட்டங்கள் தவறியது" +Basic.Stats.Output.Stream="அலை" +Basic.Stats.Output.Recording="பதிவு" +Basic.Stats.Status="நிலை" +Basic.Stats.Status.Recording="பதிவுசெய்கிறது" +Basic.Stats.Status.Live="நேரலை" +Basic.Stats.Status.Reconnecting="மறுஇணைப்பு செய்கிறது" +Basic.Stats.Status.Inactive="செயலற்ற" +Basic.Stats.DroppedFrames="கைவிடப்பட்ட சட்டங்கள் (இணையம்)" +Basic.Stats.MegabytesSent="மொத்த தகவல் வெளியீடு" +Basic.Stats.Bitrate="Bit விகிதம்" + +ResetUIWarning.Title="UI மீட்டமைக்க விரும்புகிறீர்களா?" +ResetUIWarning.Text="UI ஐ மீட்டமைப்பது கூடுதலான துறைகளை மறைக்கும். பார்வை மெனுவிலிருந்து இந்த டாக்ஸை நீங்கள் தெரிவு செய்ய வேண்டும் எனில் அவற்றை நீங்கள் மறைக்க வேண்டும். \n\n நீங்கள் UI ஐ மீட்டமைக்க விரும்புகிறீர்களா?" + +Updater.Title="புதிய மேம்படுத்தல்கள் கிடைக்கிறது" +Updater.Text="புதிய மேம்படுத்தல்கள் உள்ளது:" +Updater.UpdateNow="இப்போதே மேம்படுத்தவும்" +Updater.RemindMeLater="பிறகு நினைவூட்டு" +Updater.Skip="பதிப்பு தவிர்க்க" +Updater.Running.Title="நடப்பில் உள்ள நிகழ்ச்சி" +Updater.Running.Text="வெளியீடுகள் தற்போது செயலில் உள்ளன, தயவுசெய்து மேம்படுத்துவதற்கு முயற்சிக்கும் முன் செயலில் உள்ள வெளியீட்டை மூடவும்" +Updater.NoUpdatesAvailable.Title="மேம்படுத்தல்கள் கிடைக்கவில்லை" +Updater.NoUpdatesAvailable.Text="மேம்படுத்தல்கள் ஏதும் நடப்பில் இல்லை" +Updater.FailedToLaunch="மேம்படுத்தல் தோல்வியுற்றது" +Updater.GameCaptureActive.Title="விளையாட்டு பிடிப்பு செயலில்" + +QuickTransitions.SwapScenes="முன்னோட்டம் / வெளியீடு காட்சிகள் இடமாற்றத்திற்கு பிறகு மாற்றவும்" +QuickTransitions.SwapScenesTT="(வெளியீடு-உண்மையான காட்சியில் நீடித்தால்) வெளியீடு மற்றும் காட்சிகள் swaps பின்னர் இடம் பெயர்கிறது.\nஇது, வெளியீடு உண்மையான காட்சியில் கணக்கிற்குரியதாய் எந்த மாற்றங்களை செயல்தவிர்க்க வேண்டும்.\n\n(வெளியீட்டு அசல் காட்சி இன்னும் இருந்தால்) முன்னோட்டம் மற்றும் வெளியீட்டு காட்சிகளை இடமாற்றத்திற்குப் பிறகு மாற்றும். \n வெளியீட்டின் அசல் காட்சிக்கு மாற்றப்பட்ட எந்த மாற்றத்தையும் இது சரிசெய்யாது." +QuickTransitions.DuplicateScene="நகல் காட்சி" +QuickTransitions.DuplicateSceneTT="அதே காட்சியின் போது, வெளியீடு மாற்றுவதை மாற்றும்/தெரியும் ஆதாரங்கள் திருத்தத்தை அனுமதிக்கும்.\nநகல் ஆதாரங்கள் குணங்களை ஆதாரங்கள் வெளியீடு திருத்த திருத்த உதவும்.\n(அது நீடித்தால்) இந்த மதிப்பு மாற்ற தற்போதைய வெளியீடு காட்சி மீட்டமைக்கும்." +QuickTransitions.EditProperties="நகல் மூலங்கள்" +QuickTransitions.EditPropertiesTT="அதே காட்சியைத் திருத்தும்போது, வெளியீடு மாற்றியமைக்கப்படாமல் மூலங்களின் பண்புகளை திருத்த அனுமதிக்கிறது. \n 'நகல் காட்சி' செயல்படுத்தப்பட்டால் மட்டுமே இதைப் பயன்படுத்த முடியும்.\n குறிப்பிட்ட c (பிடிப்பு அல்லது ஊடக மூலங்கள் போன்றவை) இதை ஆதரிக்காது, தனித்தனியாக திருத்தவும் முடியாது. \n இந்த மதிப்பு மாற்றுவது தற்போதைய வெளியீட்டு காட்சியை (அது இன்னும் இருந்தால்) மீட்டமைக்கும். \n\n எச்சரிக்கை: மூலங்கள் நகல் செய்யப்படுவதால், கூடுதல் கணினி அல்லது வீடியோ மூலங்கள் இதற்கு தேவைப்படலாம்." +QuickTransitions.HotkeyName="விரைவான மாற்றம்: %1" + +Basic.AddTransition="கட்டமைக்கக்கூடிய மாற்றத்தைச் சேர்" +Basic.RemoveTransition="கட்டமைக்கக்கூடிய மாற்றத்தை நீக்கு" +Basic.TransitionProperties="மாற்றம் குணங்கள்" +Basic.SceneTransitions="காட்சி மாற்றங்கள்" +Basic.TransitionDuration="நேர அளவு" +Basic.TogglePreviewProgramMode="ஸ்டூடியோ பயன்முறை" + +TransitionNameDlg.Text="மாற்றத்தின் பெயரை உள்ளிடவும்" +TransitionNameDlg.Title="மாற்றத்தின் பெயர்" + +TitleBar.Profile="விவரம்" +TitleBar.Scenes="காட்சிகள்" + +NameExists.Title="பெயர் ஏற்கனவே உள்ளது" +NameExists.Text="இந்த பெயர் ஏற்கனவே உபயோகத்தில் உள்ளது." + +NoNameEntered.Title="சரியான பெயரை உள்ளிடுக" +NoNameEntered.Text="வெற்று பெயர்களை நீங்கள் பயன்படுத்த முடியாது." + +ConfirmStart.Title="அலை தொடக்கம்?" +ConfirmStart.Text="அலை தொடங்க விரும்புகிறீர்களா?" + +ConfirmStop.Title="அலை நிறுத்த?" +ConfirmStop.Text="அலை நிறுத்த நீங்கள் உறுதியாக இருக்கிறீர்களா?" + + +ConfirmExit.Title="OBS ஐ வெளியேற்றவா?" +ConfirmExit.Text="OBS தற்போது செயலில் உள்ளது. அனைத்து அலைகள் / பதிவுகள் மூடப்படும். நிச்சயமாக வெளியேற விரும்புகிறீர்களா?" + +ConfirmRemove.Title="அகற்ற உறுதி செய்" +ConfirmRemove.Text="'$ 1' ஐ அகற்ற விரும்புகிறீர்களா?" +ConfirmRemove.TextMultiple="'%1' ஐ அகற்ற விரும்புகிறீர்களா?" + +Output.StartStreamFailed="அலை துவக்க இயலவில்லை" +Output.StartRecordingFailed="பதிவு துவக்க இயலவில்லை" +Output.StartReplayFailed="மறுபகிர்வு தாங்கலை தொடங்க முடியவில்லை" + + +Output.ConnectFail.Title="இணைக்க இயலவில்லை" +Output.ConnectFail.BadPath="தவறான URL பாதை அல்லது இணைப்பு. அவை செல்லுபடியாகிறதா என்று உறுதிப்படுத்த உங்கள் அமைப்புகளை சரிபார்க்கவும்." +Output.ConnectFail.ConnectFailed="சேவகையத்திடம் தொடர்பு கொள்ள முடியவில்லை" +Output.ConnectFail.Error="சேவையகத்துடன் இணைக்க முயற்சிக்கும் போது எதிர்பாராத பிழை ஏற்பட்டது. மேலும் தகவல்கள் பதிவு கோப்பில் உள்ளன." +Output.ConnectFail.Disconnected="சேவையகத்திலிருந்து துண்டிக்கப்பட்டது." + + +Output.RecordFail.Title="பதிவு துவக்க இயலவில்லை" +Output.RecordFail.Unsupported="வெளியீட்டு வடிவமைப்பு ஒன்று ஆதரிக்கப்படவில்லை அல்லது ஒன்றுக்கு மேற்பட்ட ஒலி தடங்கள் ஆதரிக்கவில்லை. தயவுசெய்து உங்கள் அமைப்புகளை சரிபார்த்து மீண்டும் முயற்சிக்கவும்." +Output.RecordNoSpace.Title="போதுமான வட்டு இடம் இல்லை" +Output.RecordNoSpace.Msg="பதிவைத் தொடர போதுமான வட்டு இடம் இல்லை." +Output.RecordError.Title="பதிவு பிழை" +Output.RecordError.Msg="பதிவு செய்யும் போது ஒரு குறிப்பிடப்படாத பிழை ஏற்பட்டது." +Output.ReplayBuffer.NoHotkey.Title="குறுக்குவிசை அமைப்பு இல்லை!" + +Output.BadPath.Title="தவறான கோப்பு பாதை" +Output.BadPath.Text="கட்டமைக்கப்பட்ட கோப்பு வெளியீடு பாதை தவறானது. செல்லுபடியாகும் கோப்பு பாதை அமைக்கப்பட்டுள்ளதா என்பதை உறுதிப்படுத்த உங்கள் அமைப்புகளை சரிபார்க்கவும்." + +LogReturnDialog="பதிவு பதிவேற்றம் வெற்றி" +LogReturnDialog.CopyURL="URL-ஐ நகலெடு" +LogReturnDialog.ErrorUploadingLog="பதிவு கோப்பை பதிவேற்றுவதில் பிழை" + +Remux.SourceFile="OBS பதிவு" +Remux.TargetFile="இலக்கு கோப்பு" +Remux.Remux="வடிவமாற்றம்" +Remux.ClearFinished="முடிக்கப்பட்ட உருப்படிகளை நீக்கு" +Remux.ClearAll="அனைத்து உருப்படிகளையும் நீக்க" +Remux.OBSRecording="OBS பதிவு" +Remux.FinishedTitle="வடிவமாற்றம் முடித்து" +Remux.Finished="பதிவு வடிவமாற்றம் செய்யப்பட்டது" +Remux.FinishedError="பதிவு வடிவமாற்றம் செய்யப்பட்டது, ஆனால் கோப்பு முழுமையற்றதாக இருக்கலாம்" +Remux.SelectRecording="OBS பதிவு தேர்ந்தெடு..." +Remux.SelectTarget="இலக்குக்கான கோப்புறையை தேர்ந்தெடு..." +Remux.FileExistsTitle="இலக்கு கோப்புகளை இல்லை" +Remux.FileExists="பின்வரும் இலக்கு கோப்புகள் ஏற்கனவே உள்ளன. அவற்றை மாற்ற விரும்புகிறீர்களா?" +Remux.ExitUnfinishedTitle="வடிவமாற்றம் நடைபெற்று வருகிறது" +Remux.ExitUnfinished="வடிவமாற்றம் முடிக்கப்படவில்லை, இப்போது நிறுத்த இலக்கு கோப்பை பயன்படுத்த முடியாது ஆகலாம். \n நீங்கள் மறுதொடக்கம் நிறுத்த விரும்புகிறீர்களா?" +Remux.HelpText="கோப்புகளை வடிவமாற்றம் செய்ய இந்த சாளரத்தில் விடவும், அல்லது கோப்பை உலாவ ஒரு வெற்று \"OBS பதிவு\" செல்லை தேர்ந்தெடுக்கவும்." + +UpdateAvailable="புதிய மேம்படுத்தல்கள் கிடைக்கிறது" +UpdateAvailable.Text="பதிப்பு %1.%2.%3 தற்போது கிடைக்கிறது. பதிவிறக்கம் செய்ய இங்கே சொடுக்கிடுக" + +Basic.DesktopDevice1="திரைப்பலக ஒலி" +Basic.DesktopDevice2="திரைப்பலக ஒலி 2" +Basic.AuxDevice1="ஒலிவாங்கி/ஒலி முனையம்" +Basic.AuxDevice2="ஒலிவாங்கி/ஒலி முனையம் 2" +Basic.AuxDevice3="ஒலிவாங்கி/ஒலி முனையம் 3" +Basic.AuxDevice4="ஒலிவாங்கி/ஒலி முனையம் 4" + +Basic.Scene="காட்சி" +Basic.DisplayCapture="திரை பிடிப்பு" + +Basic.Main.PreviewConextMenu.Enable="முன்னோட்டம் இயக்கு" + + +ScaleFiltering="அளவு வடிகட்டுதல்" +ScaleFiltering.Point="புள்ளி" +ScaleFiltering.Bilinear="இருநேர்கோடு" +ScaleFiltering.Bicubic="இருபட்டக" +ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="பகுதி" + +Deinterlacing="இடைப்பின்னலகற்றம்" +Deinterlacing.Discard="புறக்கணி" +Deinterlacing.Retro="Retro" +Deinterlacing.Blend="Blend" +Deinterlacing.Blend2x="Blend 2x" +Deinterlacing.Linear="Linear" +Deinterlacing.Linear2x="Linear 2x" +Deinterlacing.Yadif="Yadif" +Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="முதலில் மேல் புலம்" +Deinterlacing.BottomFieldFirst="முதலில் கீழ் புலம்" + +VolControl.SliderUnmuted="ஒலியளவு நகர்வுகோல் '%1': %2" +VolControl.SliderMuted="ஒலியளவு நகர்வுகோல் '%1': %2 (தற்போது ஒலி தடுக்கப்பட்டது)" +VolControl.Mute="'%1' ஒலிதடு" +VolControl.Properties="'%1' பண்புகள்" + +Basic.Main.AddSceneDlg.Title="காட்சி சேர்" +Basic.Main.AddSceneDlg.Text="காட்சி பெயர் உள்ளிடவும்" + +Basic.Main.DefaultSceneName.Text="காட்சி %1" + +Basic.Main.AddSceneCollection.Title="காட்சி தொகுப்பில் சேர்க்க" +Basic.Main.AddSceneCollection.Text="காட்சி தொகுப்பின் பெயரை உள்ளிடுக" + +Basic.Main.RenameSceneCollection.Title="காட்சி தொகுப்புக்கு மறுபெயரிடு" + +AddProfile.Title="விவரக்குறிப்பை மேலேற்று" +AddProfile.Text="சுயவிவரத்தில் பெயரை உள்ளிடவும்" + +RenameProfile.Title="சுயவிவரத்தை மறுபெயரிடு" + +Basic.Main.MixerRename.Title="ஒலி மூலம் மறுபெயரிடு" +Basic.Main.MixerRename.Text="ஒலி மூலம் பெயரை உள்ளிடவும்" + + +Basic.Main.PreviewDisabled="முன்னோட்டம் தற்போது முடக்கப்பட்டுள்ளது" + +Basic.SourceSelect="மூலத்தை உருவாக்கு/தேர்ந்தெடு" +Basic.SourceSelect.CreateNew="புதிதாக உருவாக்கு" +Basic.SourceSelect.AddExisting="தற்போதுள்ள சேர்" +Basic.SourceSelect.AddVisible="மூலத்தை காண்பி" + +Basic.PropertiesWindow="'%1' பண்புகள்" +Basic.PropertiesWindow.AutoSelectFormat="%1 (தானியங்குதேர்வு: %2)" +Basic.PropertiesWindow.SelectColor="வண்ணம் தேர்ந்தெடு" +Basic.PropertiesWindow.SelectFont="எழுத்துரு தேர்ந்தெடு" +Basic.PropertiesWindow.ConfirmTitle="அமைப்புகள் மாற்றப்பட்டன" +Basic.PropertiesWindow.Confirm="சேமிக்கப்படாத மாற்றங்கள் உள்ளன. அவற்றை வைத்திருக்க விரும்புகிறீர்களா?" +Basic.PropertiesWindow.NoProperties="பண்புகள் இல்லை" +Basic.PropertiesWindow.AddFiles="கோப்புகளை இணைக்க" +Basic.PropertiesWindow.AddDir="அடைவை சேர்" +Basic.PropertiesWindow.AddURL="URL/பாதை சேர்" +Basic.PropertiesWindow.AddEditableListDir="'%1 ' அடைவை சேர்" +Basic.PropertiesWindow.AddEditableListFiles="'%1 ' கோப்புகளை சேர்" +Basic.PropertiesWindow.AddEditableListEntry="'%1 ' உள்ளீ ̈ட்டைச் சேர்" +Basic.PropertiesWindow.EditEditableListEntry="'%1' -லிருந்து உள்ளீடுகளைத் திருத்து" + +Basic.PropertiesView.FPS.Simple="எளிய FPS மதிப்புகள்" +Basic.PropertiesView.FPS.Rational="பகுத்தறிவு FPS மதிப்புகள்" +Basic.PropertiesView.FPS.ValidFPSRanges="செல்லத்தக்க FPS வரம்புகள்:" + +Basic.InteractionWindow="'%1' உடன் தொடர்புகொள்" + +Basic.StatusBar.Reconnecting="துண்டிக்கப்பட்டது, %2 விநாடி(கள்) மீண்டும் இணைக்கிறது ( %1 முயற்சி)" +Basic.StatusBar.AttemptingReconnect="மீண்டும் இணைக்க முயற்சிக்கிறது... ( %1 முயற்சி)" +Basic.StatusBar.ReconnectSuccessful="மறு இணைப்பு வெற்றி" +Basic.StatusBar.Delay="(% 1 நொடி) தாமதம்" +Basic.StatusBar.DelayStartingIn="தாமதம் (%1 நொடியில் தொடங்கி)" +Basic.StatusBar.DelayStoppingIn="தாமதம் (%1 நொடியில் நிறுத்துகிறது)" +Basic.StatusBar.DelayStartingStoppingIn="தாமதம் (%1 வினாடிகளில் நிறுத்துகிறது, %2 வினாடிகளில் தொடங்குகிறது)" + +Basic.Filters="வடிகட்டிகள்" +Basic.Filters.AsyncFilters="ஒலி/ஒளி வடிகட்டிகள்" +Basic.Filters.AudioFilters="ஒலி வடிகட்டிகள்" +Basic.Filters.EffectFilters="விளைவு வடிகட்டிகள்" +Basic.Filters.Title="'%1' வடிகட்டிகள்" +Basic.Filters.AddFilter.Title="வடிகட்டி பெயர்" +Basic.Filters.AddFilter.Text="வடிகட்டியின் பெயர் குறிப்பிடவும்" + +Basic.TransformWindow="காட்சி உருப்படியை மாற்றம்" +Basic.TransformWindow.Position="நிலை" +Basic.TransformWindow.Rotation="சுழற்சி" +Basic.TransformWindow.Size="அளவு" +Basic.TransformWindow.Alignment="நிலை ஒழுங்கமைத்தல்" +Basic.TransformWindow.BoundsType="எல்லைக்குட்பட்ட பெட்டி வகை" +Basic.TransformWindow.BoundsAlignment="எல்லைக்குட்பட்ட பெட்டி ஒழுங்கமைத்தல்" +Basic.TransformWindow.Bounds="எல்லைக்குட்பட்ட பெட்டி அளவு" +Basic.TransformWindow.Crop="நுனிவெட்டு" + +Basic.TransformWindow.Alignment.TopLeft="மேல் இடது" +Basic.TransformWindow.Alignment.TopCenter="மேல் மையம்" +Basic.TransformWindow.Alignment.TopRight="மேல் வலது" +Basic.TransformWindow.Alignment.CenterLeft="மையம் இடது" +Basic.TransformWindow.Alignment.Center="மையம்" +Basic.TransformWindow.Alignment.CenterRight="மையம் வலது" +Basic.TransformWindow.Alignment.BottomLeft="கீழ் இடது" +Basic.TransformWindow.Alignment.BottomCenter="கீழ் மையம்" +Basic.TransformWindow.Alignment.BottomRight="கீழ் வலது" + +Basic.TransformWindow.BoundsType.None="எல்லையற்று" +Basic.TransformWindow.BoundsType.MaxOnly="அதிகபட்ச அளவு மட்டும்" +Basic.TransformWindow.BoundsType.ScaleInner="உள் எல்லைகளுக்கு அளவிட" +Basic.TransformWindow.BoundsType.ScaleOuter="வெளி எல்லைகளுக்கு அளவிடு" +Basic.TransformWindow.BoundsType.ScaleToWidth="எல்லைகளின் அகலத்திற்கு அளவிடு" +Basic.TransformWindow.BoundsType.ScaleToHeight="எல்லைகளின் உயரத்திற்கு அளவிடு" +Basic.TransformWindow.BoundsType.Stretch="வரம்புக்கு நீட்டு" + +Basic.Main.AddSourceHelp.Title="மூலத்தில் சேர்க்க முடியாது" +Basic.Main.AddSourceHelp.Text="மூலத்தைச் சேர்க்க நீங்கள் குறைந்தபட்சம் 1 காட்சியைக் கொண்டிருக்க வேண்டும்." + +Basic.Main.Scenes="காட்சிகள்" +Basic.Main.Sources="மூலம்" +Basic.Main.Controls="கட்டுப்பாடு" +Basic.Main.Connecting="இணைக்கிறது..." +Basic.Main.StartRecording="பதிவைத் தொடங்கவும்" +Basic.Main.StartReplayBuffer="மறுபிரதி தாங்கல் தொடங்கு" +Basic.Main.StartStreaming="நேரலை தொடக்கம்" +Basic.Main.StopRecording="பதிவெடுப்பதை நிறுத்து" +Basic.Main.StoppingRecording="பதிவு நிறுத்துகிறது..." +Basic.Main.StopReplayBuffer="மறுபிரதி தாங்கல் நிறுத்து" +Basic.Main.StoppingReplayBuffer="மறுபிரதி தாங்கல் நிறுத்துகிறது..." +Basic.Main.StopStreaming="அலை நிறுத்தம்" +Basic.Main.StoppingStreaming="அலை நிறுத்தம்..." +Basic.Main.ForceStopStreaming="நேரலை நிறுத்து (தாமதத்தை நிராகரி)" +Basic.Main.Group="குழு %1" +Basic.Main.GroupItems="தேர்ந்தெடுத்த உருப்படிகளை குழுப்படுத்த" +Basic.Main.Ungroup="குழு நீக்கம்" + +Basic.MainMenu.File="கோப்பு (&F)" +Basic.MainMenu.File.Export="ஏற்றுமதி (&E)" +Basic.MainMenu.File.Import="இறக்குமதி (&I)" +Basic.MainMenu.File.ShowRecordings="பதிவுகளை காண்பி (&R)" +Basic.MainMenu.File.Remux="வடிவமாற்ற பதிவுகள் (&M)" +Basic.MainMenu.File.Settings="அமைப்புகள் (&S)" +Basic.MainMenu.File.ShowSettingsFolder="அமைப்புகள் கோப்புறைகளைக் காண்பி" +Basic.MainMenu.File.ShowProfileFolder="கோப்புறை சுயவிவரம் காண்பி" +Basic.MainMenu.AlwaysOnTop="எப்போதும் உச்சியில்இரு (&A)" +Basic.MainMenu.File.Exit="வெளியேறு (&X)" + +Basic.MainMenu.Edit="திருத்து (&E)" +Basic.MainMenu.Edit.Undo="செயல்தவிர் (&U)" +Basic.MainMenu.Edit.Redo="மீண்டும்செய் (&R)" +Basic.MainMenu.Edit.UndoAction="செயல்தவிர் $1 (&U)" +Basic.MainMenu.Edit.RedoAction="மீண்டும்செய் $1 (&R)" +Basic.MainMenu.Edit.LockPreview="முன்னோட்டம் பூட்டு (&L)" +Basic.MainMenu.Edit.Scale="முன்னோட்டம் அளவிடல் (&S)" +Basic.MainMenu.Edit.Scale.Window="சாளரத்தின் அளவிற்கு" +Basic.MainMenu.Edit.Scale.Canvas="சுற்றளவு (%1x%2)" +Basic.MainMenu.Edit.Scale.Output="வெளியீடு (%1x%2)" +Basic.MainMenu.Edit.Transform="மாற்றும் (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="மாற்றும் திருத்து... (&E)" +Basic.MainMenu.Edit.Transform.CopyTransform="மாற்றம் நகலெடு" +Basic.MainMenu.Edit.Transform.PasteTransform="மாற்றம் ஒட்டுக" +Basic.MainMenu.Edit.Transform.ResetTransform="மாற்றம் மீட்டமை (&R)" +Basic.MainMenu.Edit.Transform.Rotate90CW="CW 90 டிகிரி சுழற்று" +Basic.MainMenu.Edit.Transform.Rotate90CCW="CCW 90 டிகிரி சுழற்று" +Basic.MainMenu.Edit.Transform.Rotate180="180 டிகிரி சுழற்று" +Basic.MainMenu.Edit.Transform.FlipHorizontal="கிடைமட்டமாக மடக்கு (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="செங்குத்தாக மடக்கு (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="திரைக்கு ஏற்றார் போல் பொருத்து (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="திரைக்கு முழுவதும் இழு (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="திரையின் மையத்திற்கு (&C)" +Basic.MainMenu.Edit.Order="ஒழுங்கு (&O)" +Basic.MainMenu.Edit.Order.MoveUp="மேலே நகர்த்து (&U)" +Basic.MainMenu.Edit.Order.MoveDown="கீழ் நகர்த்து (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="முதலாவதாக நகர்த்து (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="கடைசிக்கு நகர்த்து (&B)" +Basic.MainMenu.Edit.AdvAudio="மேம்பட்ட ஒலி குணங்கள் (&A)" + +Basic.MainMenu.View="பார்வை (&V)" +Basic.MainMenu.View.Toolbars="கருவிப்பட்டிகள் (&T)" +Basic.MainMenu.View.Docks="பாகங்கள்" +Basic.MainMenu.View.Docks.ResetUI="UI மீட்டமை" +Basic.MainMenu.View.Docks.LockUI="UI பூட்டு" +Basic.MainMenu.View.Toolbars.Listboxes="பட்டியல் பெட்டி (&L)" +Basic.MainMenu.View.SceneTransitions="காட்சி மாற்றங்கள் (&C)" +Basic.MainMenu.View.StatusBar="நிலை பட்டை (&S)" +Basic.MainMenu.View.Fullscreen.Interface="முழுத்திரை இடைமுகம்" + +Basic.MainMenu.SceneCollection="காட்சி தொகுப்பு (&S)" +Basic.MainMenu.Profile="சுயவிவரம் (&P)" +Basic.MainMenu.Profile.Import="சுயவிவரம் இறக்குமதி" +Basic.MainMenu.Profile.Export="சுயவிவரம் ஏற்றுமதி" +Basic.MainMenu.SceneCollection.Import="காட்சி தொகுப்பு இறக்குமதி" +Basic.MainMenu.SceneCollection.Export="காட்சி தொகுப்பு ஏற்றுமதி" +Basic.MainMenu.Profile.Exists="இந்த விவரம் ஏற்கனவே உள்ளது" +Basic.MainMenu.SceneCollection.Exists="காட்சி தொகுப்பு ஏற்கனவே உள்ளது" + +Basic.MainMenu.Tools="கருவிகள் (&T)" + +Basic.MainMenu.Help="உதவி (&H)" +Basic.MainMenu.Help.HelpPortal="உதவி இணையதளம் (&P)" +Basic.MainMenu.Help.Website="வலைத்தளம் செல்ல (&W)" +Basic.MainMenu.Help.Discord="சேவையகம் சேர நிராகரிப்பு (&D)" +Basic.MainMenu.Help.Logs="பதிவுக் கோப்புகள் (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="பதிவுக் கோப்புகள் காண்பி (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="தற்போதைய பதிவு கோப்பை பதிவேற்றவும் (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="கடைசி பதிவு கோப்பை பதிவேற்றவும் (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="தற்போதைய பதிவு கோப்பை காணவும் (&V)" +Basic.MainMenu.Help.CheckForUpdates="மேம்படுத்தல்களை சோதிக்க" +Basic.MainMenu.Help.CrashLogs="C&rash அறிக்கை" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Cra&sh அறிக்கை காட்டு" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="பதிவேற்ற கடைசி Crash அறிக்கை (&L)" +Basic.MainMenu.Help.About="இதைப்பற்றி (&A)" + +Basic.Settings.ProgramRestart="இந்த அமைப்புகள் நடைமுறைக்கு வர நிகழச்சி நிரலை மறுதொடக்கம் செய்ய வேண்டும்." +Basic.Settings.ConfirmTitle="மாற்றம் உறுதி செய்தல்" +Basic.Settings.Confirm="சேமிக்கப்படாத மாற்றங்கள் உள்ளன. மாற்றங்களை சேமிக்கவா?" + +Basic.Settings.General="பொதுவானவை" +Basic.Settings.General.Theme="வண்ண அமைப்பு" +Basic.Settings.General.Language="மொழி" +Basic.Settings.General.EnableAutoUpdates="தொடக்கத்தில் மேம்படுத்தல்களை தானியங்கு முறையில் சோதிக்க" +Basic.Settings.General.OpenStatsOnStartup="தொடக்கத்தில் விபரம் திறந்த உரையாடல்" +Basic.Settings.General.WarnBeforeStartingStream="நேரலை தொடங்கும் போது உறுதிப்படுத்தல் உரையாடலைக் காட்டு" +Basic.Settings.General.WarnBeforeStoppingStream="நேரலை நிறுத்தும்போது உறுதிப்படுத்தல் உரையாடலை காட்டு" +Basic.Settings.General.Projectors="பிரதிபலிப்பான்" +Basic.Settings.General.HideProjectorCursor="பிரதிபலிப்பான் மீது காட்டியை மறை" +Basic.Settings.General.ProjectorAlwaysOnTop="பிரதிபலிப்பானை எப்போதும் மேலே வைக்கவும்" +Basic.Settings.General.SysTray="கணினி தட்டு" +Basic.Settings.General.SysTrayWhenStarted="தொடங்கிய போது கணினி தட்டில் சிறிதாக்கு" + +Basic.Settings.Stream="நேரலை" +Basic.Settings.Stream.StreamType="நேரலை வகை" +Basic.Settings.Stream.Custom.UseAuthentication="அங்கீகாரத்தைப் பயன்படுத்துக" +Basic.Settings.Stream.Custom.Username="பயனர் பெயர்" +Basic.Settings.Stream.Custom.Password="கடவுச்சொல்" +Basic.Settings.Stream.BandwidthTestMode="அலைவரிசை சோதனை பயன்முறையை இயக்கு" + +Basic.Settings.Output="வெளியீடு" +Basic.Settings.Output.Format="பதிவு வடிவமைப்பு" +Basic.Settings.Output.Encoder="குறியாக்கி" +Basic.Settings.Output.SelectDirectory="பதிவு கோப்பகத்தைத் தேர்ந்தெடுக்கவும்" +Basic.Settings.Output.SelectFile="பதிவு கோப்பு தேர்ந்தெடு" +Basic.Settings.Output.Mode.Simple="எளிய" +Basic.Settings.Output.Mode.Adv="மேம்பட்டது" +Basic.Settings.Output.Mode.FFmpeg="FFmpeg வெளியீட்டு வகை" +Basic.Settings.Output.ReplayBuffer.Suffix="பின்னொட்டு" +Basic.Settings.Output.Simple.SavePath="பதிவு பாதை" +Basic.Settings.Output.Simple.RecordingQuality="பதிவின் தரம்" +Basic.Settings.Output.Simple.RecordingQuality.Small="உயர்தர, நடுத்தர கோப்பு அளவு" +Basic.Settings.Output.Simple.RecordingQuality.HQ="எந்தவிதமான வேறுபாட்டையும் காணமுடியாத தரம், பெரிய கோப்பு அளவு" +Basic.Settings.Output.Simple.RecordingQuality.Lossless="இழப்பின்றி தரம், மிகவும் பெரிய கோப்பு அளவு" +Basic.Settings.Output.Simple.Encoder.Software="மென்பொருள் (x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="வன்பொருள் (QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="வன்பொருள் (AMD)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="வன்பொருள் (NVENC)" +Basic.Settings.Output.RetryDelay="தாமதம் (நொடிகளில்) மீண்டும் முயற்சிக்கவும்" +Basic.Settings.Output.MaxRetries="அதிகபட்ச முயற்சிகள்" +Basic.Settings.Output.Advanced="மேம்பட்ட குறியாக்கி அமைப்புகளை இயக்கு" +Basic.Settings.Output.CustomEncoderSettings="விருப்ப குறியாக்கி அமைப்புகள்" +Basic.Settings.Output.NoSpaceFileName="இடைவெளி இல்லாமல் கோப்பு பெயரினை உருவாக்கவும்" + +Basic.Settings.Output.Adv.AudioTrack="ஒலி தடம்" +Basic.Settings.Output.Adv.Streaming="நேரலை" +Basic.Settings.Output.Adv.ApplyServiceSettings="நேரலை சேவையை குறியாக்கி அமைப்புகளை செயற்படுத்து" +Basic.Settings.Output.Adv.Audio.Track1="ஒலி தடம் 1" +Basic.Settings.Output.Adv.Audio.Track2="ஒலி தடம் 2" +Basic.Settings.Output.Adv.Audio.Track3="ஒலி தடம் 3" +Basic.Settings.Output.Adv.Audio.Track4="ஒலி தடம் 4" +Basic.Settings.Output.Adv.Audio.Track5="ஒலி தடம் 5" +Basic.Settings.Output.Adv.Audio.Track6="ஒலி தடம் 6" + +Basic.Settings.Output.Adv.Recording="பதிவுசெய்கிறது" +Basic.Settings.Output.Adv.Recording.Type="வகை" +Basic.Settings.Output.Adv.Recording.Type.Standard="தரநிலை" +Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="தனிப்பயன் விருப்ப வெளியீடு (FFmpeg)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(நேரலை குறியாக்கி பயன்படுத்து)" +Basic.Settings.Output.Adv.Recording.Filename="கோப்பின் பெயர் வடிவமைப்பு" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="கோப்பு இருந்தால் மேலெழுது" +Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg வெளியீட்டு வகை" +Basic.Settings.Output.Adv.FFmpeg.Type.URL="URLக்கு வெளியிடுக" +Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="கோப்பிற்கு வெளியிடுக" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.Common="பொதுவான பதிவு வடிவங்கள்" +Basic.Settings.Output.Adv.FFmpeg.SaveFilter.All="அனைத்து கோப்புகள்" +Basic.Settings.Output.Adv.FFmpeg.SavePathURL="கோப்பு பாதை அல்லது URL" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="ஒலி" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="காணொளி" +Basic.Settings.Output.Adv.FFmpeg.FormatDefault="இயல்புநிலை வடிவமைப்பு" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="இயல்புநிலை குறியாக்கி" +Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="குறியாக்கி முடக்கு" +Basic.Settings.Output.Adv.FFmpeg.VEncoder="காணொளி குறியாக்கி" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="காணொளி குறியாக்கி அமைப்புகள் (இருந்தால்)" +Basic.Settings.Output.Adv.FFmpeg.AEncoder="ஒலி குறியாக்கி" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="ஒலி குறியாக்கி அமைப்புகள் (இருந்தால்)" + + + +Basic.Settings.Video="காணொளி" +Basic.Settings.Video.BaseResolution="அடிப்படை (சுற்றளவு) தெளிவுத்திறன்" +Basic.Settings.Video.ScaledResolution="(அளவிட்ட) வெளியீட்டு தெளிவுத்திறன்" +Basic.Settings.Video.FPS="FPS" +Basic.Settings.Video.InvalidResolution="தவறான தெளிவுத்திறன் மதிப்பு. [width]x[height] இருக்க வேண்டும் (அதாவது 1920 x 1080)" + + +Basic.Settings.Audio="ஒலி" +Basic.Settings.Audio.SampleRate="மாதிரி விகிதம்" +Basic.Settings.Audio.MeterDecayRate.Fast="வேகமாக" +Basic.Settings.Audio.Disabled="முடக்கப்பட்டது" + +Basic.Settings.Advanced="மேம்பட்டவை" +Basic.Settings.Advanced.General.ProcessPriority.High="உயர்" +Basic.Settings.Advanced.General.ProcessPriority.Normal="இயல்பு" +Basic.Settings.Advanced.General.ProcessPriority.Idle="செயலின்றி" +Basic.Settings.Advanced.Video.ColorFormat="வண்ண வடிவமைப்பு" +Basic.Settings.Advanced.Video.ColorRange.Full="முழு" +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="இயல்புநிலை" + +Basic.AdvAudio.Name="பெயர்" +Basic.AdvAudio.Balance="சமநிலை" + +Basic.Settings.Hotkeys.Filter="வடிகட்டிகள்" + + +Basic.SystemTray.Hide="மறை" + + +Hotkeys.Insert="செருகு" +Hotkeys.Delete="நீக்கு" +Hotkeys.Home="முகப்பு" +Hotkeys.End="இறுதி" +Hotkeys.PageUp="பக்கத்தில் மேலே" +Hotkeys.PageDown="பக்கத்தில் கீழே" +Hotkeys.NumLock="எண் பூட்டு" +Hotkeys.Menu="பட்டியல்" +Hotkeys.Space="இடைவெளி" +Hotkeys.NumpadNum="எண் திண்டு %1" + + + + + + + + + +ResizeOutputSizeOfSource.Text="அடிப்படை மற்றும் வெளியீடு தெளிவுத்திறன்கள் தற்போதைய மூலத்தின் அளவிற்கு மாற்றப்படும்." diff --git a/UI/data/locale/th-TH.ini b/UI/data/locale/th-TH.ini index 7ab922a..83af19c 100644 --- a/UI/data/locale/th-TH.ini +++ b/UI/data/locale/th-TH.ini @@ -33,18 +33,83 @@ Hide="ซ่อน" Untitled="ไม่มีชื่อ" New="ใหม่" Enable="เปิดใช้งาน" +Transition="เปลี่ยนภาพ" +QuickTransitions="ช่วงการเปลี่ยนภาพอย่างรวดเร็ว" +Left="ซ้าย" +Right="ขวา" +Top="บน" +Bottom="ล่าง" +Reset="รีเซ็ต" +Hours="ชั่วโมง" +Minutes="นาที" +Seconds="วินาที" +Deprecated="ไม่ใช้งาน" +Import="นําเข้า" +Export="ส่งออก" +Copy="คัดลอก" +Paste="วาง" +PasteReference="วาง (อ้างอิง)" +PasteDuplicate="วาง (ซ้ำ)" +Next="ถัดไป" +Back="กลับ" +Defaults="ค่ามาตรฐาน" +None="ไม่มี" +StudioMode.Preview="แสดงตัวอย่าง" +StudioMode.Program="โปรแกรม" +Group="กลุ่ม" + +AlreadyRunning.Title="OBS กำลังทำงานอยู่" + + + +Copy.Filters="คัดลอก Filters" +Paste.Filters="วาง Filters" + + +BandwidthTest.Region="ภูมิภาค" +BandwidthTest.Region.US="สหรัฐอเมริกา" +BandwidthTest.Region.EU="ยุโรป" +BandwidthTest.Region.Asia="เอเชีย" +BandwidthTest.Region.Other="อื่นๆ" + +Basic.FirstStartup.RunWizard="คุณต้องการเรียกใช้ตัวช่วยสร้างการกำหนดค่าอัตโนมัติ นอกจากนี้คุณด้วยตนเองสามารถกำหนดค่าการตั้งค่า โดยคลิกปุ่มการตั้งค่าในหน้าต่างหลัก" + +Basic.AutoConfig="การปรับแต่งอัตโนมัติ" +Basic.AutoConfig.ApplySettings="ใช้การตั้งค่า" +Basic.AutoConfig.StartPage="ข้อมูลการใช้งาน" +Basic.AutoConfig.StartPage.SubTitle="ระบุสิ่งที่คุณต้องการใช้โปรแกรมสำหรับ" +Basic.AutoConfig.StartPage.PrioritizeStreaming="เพิ่มประสิทธิภาพสำหรับการสตรีม บันทึกเป็นรอง" +Basic.AutoConfig.StartPage.PrioritizeRecording="เพิ่มประสิทธิภาพสำหรับการบันทึก ฉันจะไม่สามารถส่งข้อมูล Steam" +Basic.AutoConfig.StreamPage.SubTitle="กรุณากรอกข้อมูลสตรีม" +Basic.AutoConfig.StreamPage.Service="บริการ" +Basic.AutoConfig.StreamPage.Service.ShowAll="แสดงทั้งหมด..." +Basic.AutoConfig.StreamPage.Server="เซิร์ฟเวอร์" +Basic.AutoConfig.StreamPage.StreamKey="รหัสสตรีม" +Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(เชื่อมโยง)" + +Basic.Stats="สถานะ" +Basic.Stats.CPUUsage="การใช้ CPU" +Basic.Stats.Output.Stream="สตรีม" +Basic.Stats.Status="สถานะ" +Basic.Stats.Status.Live="ออกอากาศ" +Basic.Stats.Status.Reconnecting="กำลังเชื่อมต่อใหม่" +Basic.Stats.Status.Inactive="ไม่ใช้งาน" +Basic.Stats.Bitrate="บิตเรต" + + +Updater.Title="มีการอัปเดตใหม่" +Updater.UpdateNow="อัปเดตเดี๋ยวนี้" +Updater.RemindMeLater="เตือนฉันในภายหลัง" +Updater.Skip="ข้ามรุ่น" +TitleBar.Profile="โปรไฟล์" +NameExists.Title="มีผู้ใช้นี้ในระบบแล้ว" - - - - - - +NoNameEntered.Title="กรุณาใส่ชื่อให้ถูกต้อง" @@ -54,17 +119,21 @@ ConfirmRemove.Title="ยืนยันการลบ" ConfirmRemove.Text="คุณแน่ใจแล้วหรือที่จะลบ '$1'?" + Output.ConnectFail.Title="ไม่สามารถเชื่อมต่อได้" Output.ConnectFail.ConnectFailed="ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์" Output.ConnectFail.Disconnected="ถูกตัดออกจากเซิร์ฟเวอร์" +Output.RecordNoSpace.Title="พื้นที่เก็บข้อมูลไม่เพียงพอ" +Output.RecordError.Title="บันทึกข้อผิดพลาด" +Output.ReplayBuffer.NoHotkey.Title="ไม่มีการตั้งค่าคีย์ลัด" + +Output.BadPath.Title="เส้นทางของแฟ้มไม่ถูกต้อง" LogReturnDialog="อัพโหลดไฟล์ Log สำเร็จ" LogReturnDialog.CopyURL="คัดลอก URL" - -LicenseAgreement.IAgree="ยอมรับ" -LicenseAgreement.Exit="ออก" +LogReturnDialog.ErrorUploadingLog="มีข้อผิดพลาดในการอัปโหลด Log File" @@ -74,6 +143,8 @@ Basic.Scene="ฉาก" +Deinterlacing.Discard="ยกเลิก" + Basic.Main.AddSceneDlg.Title="เพิ่มฉาก" @@ -88,6 +159,8 @@ Basic.Main.DefaultSceneName.Text="ฉาก %1" Basic.SourceSelect.CreateNew="สร้างใหม่" +Basic.PropertiesWindow.SelectColor="เลือกสี" +Basic.PropertiesWindow.AddFiles="เพิ่มไฟล์" @@ -110,8 +183,13 @@ Basic.Main.StartStreaming="เริ่มสตรีมมิ่ง" Basic.Main.StopRecording="หยุดบันทึก" Basic.Main.StopStreaming="หยุดสตรีมมิ่ง" -Basic.MainMenu.File.Exit="อ&อก" +Basic.MainMenu.File="ไฟล์ (&F)" +Basic.MainMenu.File.Export="ส่งออก (&E)" +Basic.MainMenu.File.Import="นําเข้า (&I)" +Basic.MainMenu.File.Settings="ตั้งค่า (&S)" +Basic.MainMenu.File.Exit="ออก (&X)" +Basic.MainMenu.Edit="แก้ไข (&E)" @@ -121,12 +199,16 @@ Basic.MainMenu.Help.CheckForUpdates="ตรวจสอบการอัพเ Basic.Settings.ConfirmTitle="ยืนยันการเปลี่ยนแปลง" Basic.Settings.General="ทั่วไป" +Basic.Settings.General.Theme="ธีม" +Basic.Settings.General.Language="ภาษา" Basic.Settings.Stream="สตรีม" Basic.Settings.Stream.StreamType="รูปแบบการสตรีม" +Basic.Settings.Output.Adv.FFmpeg.FormatAudio="เสียง" +Basic.Settings.Output.Adv.FFmpeg.FormatVideo="วิดีโอ" @@ -137,9 +219,25 @@ Basic.Settings.Video.FPS="FPS" Basic.Settings.Audio="เสียง" - - - +Basic.Settings.Advanced.Audio.MonitoringDevice.Default="ค่าเริ่มต้น" +Basic.Settings.Advanced.Network="เครือข่าย" + +Basic.AdvAudio.Name="ชื่อ" + +Basic.Settings.Hotkeys="ปุ่มลัด" + + +Basic.SystemTray.Show="แสดง" + + +Hotkeys.Delete="ลบ" +Hotkeys.Home="หน้าหลัก" +Hotkeys.End="สิ้นสุด" +Hotkeys.Left="ซ้าย" +Hotkeys.Right="ขวา" +Hotkeys.Up="บน" +Hotkeys.Down="ลง" +Hotkeys.Menu="เมนู" diff --git a/UI/data/locale/tl-PH.ini b/UI/data/locale/tl-PH.ini index c4d5628..2067ffd 100644 --- a/UI/data/locale/tl-PH.ini +++ b/UI/data/locale/tl-PH.ini @@ -83,9 +83,12 @@ AlreadyRunning.Title="Ang OBS ay tumatakbo na" AlreadyRunning.Text="Ang OBS ay tumatakbo na! Kung hindi mo ito sinasadya, mangyari lamang patayin ang mga umiiral na OBS bago subukang magpatakbo ng bago. Kung ikaw ay may OBS set na kailangan i-minimize sa system tray, mangyari lamang tingnan kung ito ay tumatakbo pa doon." AlreadyRunning.LaunchAnyway="Ilunsad pa rin" + + Copy.Filters="Kopyahin ang mga Panala" Paste.Filters="I-paste ang mga Panala" + BandwidthTest.Region="Rehiyon" BandwidthTest.Region.US="Estados Unidos" BandwidthTest.Region.EU="Europa" @@ -93,11 +96,9 @@ BandwidthTest.Region.Asia="Asya" BandwidthTest.Region.Other="Iba pa" Basic.FirstStartup.RunWizard="Nais mo bang patakbuhin ang auto-configuration wizard? Maaari mo ring i-configure ang iyong mga setting ng mano-mano sa pamamagitan ng pagpindot ng Settings na button sa pangunahing window." -Basic.FirstStartup.RunWizard.BetaWarning="(Tandaan: Ang auto-configuration wizard ay kasukuyang nasa beta)" Basic.FirstStartup.RunWizard.NoClicked="Kung magbabago ang iyong isip, maaari mong patakbuhin ang auto-configuration wizard sa anumang oras mula muli sa Tools na menu." Basic.AutoConfig="Auto-Configuration Wizard" -Basic.AutoConfig.Beta="Auto-Configuration Wizard (Beta)" Basic.AutoConfig.ApplySettings="Gamitin ang mga Setting" Basic.AutoConfig.StartPage="Impormasyon ukol sa Paggamit" Basic.AutoConfig.StartPage.SubTitle="Tukuyin kung para saan mo gustong gamitin ang programa" @@ -142,7 +143,6 @@ Basic.AutoConfig.TestPage.Result.Footer="Upang magamit ang mga setting, pindutin Basic.Stats="Mga Statistika" Basic.Stats.CPUUsage="Paggamit ng CPU" -Basic.Stats.HDDSpaceAvailable="Puwang sa HDD na magagamit pa" Basic.Stats.MemoryUsage="Paggamit ng Memorya" Basic.Stats.AverageTimeToRender="Karaniwang bilis upang ma-render ang frame" Basic.Stats.SkippedFrames="Mga nalaktawang imahe dahil sa antala sa pag-encode" @@ -158,6 +158,7 @@ Basic.Stats.DroppedFrames="Mga Imaheng hindi sinali (Network)" Basic.Stats.MegabytesSent="Kabuuan ng Output ng mga Datos" Basic.Stats.Bitrate="Bitrate" + Updater.Title="Mga bagong update na magagamit" Updater.Text="Mayroong bagong update na magagamit:" Updater.UpdateNow="Iupdate na Ngayon" @@ -169,7 +170,7 @@ Updater.NoUpdatesAvailable.Title="Walang mga update na magagamit" Updater.NoUpdatesAvailable.Text="Walang mga update ang kasalukuyang magagamit" Updater.FailedToLaunch="Bigong malunsad ang updater" Updater.GameCaptureActive.Title="Ang Game capture ay aktibo" -Updater.GameCaptureActive.Text="Ang hook library ng game capture ay kasalukuyang ginagamit. Mangyari lamang isara ang anumang mga laro/programang nahuli (o i-start muli ang windows) at subukan muli." +Updater.GameCaptureActive.Text="Ang hook library ng game capture ay kasalukuyang ginagamit. Mangyari lamang isara ang anumang mga laro/programang nahuli (o i-start muli ang Windows) at subukan muli." QuickTransitions.SwapScenes="Pagpalitin ang Preview/Output ng mga Eksena Matapos ang Pag-transisyon" QuickTransitions.SwapScenesTT="Pinagpapalit ang preview at output ng mga eksena matapos ang pagtransisyon (kung ang orihinal na eksena ng output ay nariyan pa).\nHindi nito mapapawalang-bisa ang mga pagbabagong napatupad sa orihinal na eksena ng output." @@ -204,6 +205,7 @@ ConfirmStart.Text="Sigurado ka bang gusto mo nang simulan ang pag-stream?" ConfirmStop.Title="Itigil ang pag-stream?" ConfirmStop.Text="Sigurado ka bang gusto mong itigil ang pag-stream?" + ConfirmExit.Title="Lumabas sa OBS?" ConfirmExit.Text="Ang OBS ang kasalukuyang aktibo. Ang lahat ng pag-stream/pagrerekord ay magsasara. Sigurado ka bang gusto mong lumabas?" @@ -216,6 +218,7 @@ Output.StartRecordingFailed="Bigong masimulan ang pag-rerekord" Output.StartReplayFailed="Bigong masimulan ang replay buffer" Output.StartFailedGeneric="Bigong masimulan ang output. Mangyari lamang tingnan ang log para sa mga detalye. \n\nTandaan: Kung ikaw ay gumagamit ng NVENC o AMD na mga encoder, siguraduhing ang iyong mga video driver ay naka-update." + Output.ConnectFail.Title="Bigong kumonekta" Output.ConnectFail.BadPath="Hindi wasto ang Path o Connection URL. Mangyari lamang tingnan ang iyong mga setting upang makumpirma na sila ay balido." Output.ConnectFail.ConnectFailed="Bigong kumonekta sa serber" @@ -223,6 +226,7 @@ Output.ConnectFail.InvalidStream="Hindi madaanan ang tinutukoy na channel o stre Output.ConnectFail.Error="Isang di-inaasahang error ang naganap habang sinusubukang kumonekta sa serber. Karagdagang impormasyon ay nasa log file." Output.ConnectFail.Disconnected="Nadiskonek mula sa serber." + Output.RecordFail.Title="Bigong masimulan ang pa-rerekord" Output.RecordFail.Unsupported="Ang output format ay maaaring hindi suportado o di kaya'y hindi nagsusuporta ng higit sa isang audio track. Mangyari lamang tingnan ang iyong mga setting at subukan muli." Output.RecordNoSpace.Title="Hindi sapat ang espasyo sa disk" @@ -239,12 +243,6 @@ LogReturnDialog="Matagumpay na na-upload ang log" LogReturnDialog.CopyURL="Kopyahin ang URL" LogReturnDialog.ErrorUploadingLog="Error sa pag-uupload ng log file" -LicenseAgreement="Kasunduan sa Lisensya" -LicenseAgreement.PleaseReview="Mangyari lamang basahin ang mga termino sa lisensya bago gamitin ang OBS. Sa paggamit ng programang ito, iyong kinikilala na binasa at sumasang-ayon ka sa mga termino ng GNU General Public License v2.0. Paki-scroll down upang makita ang iba pang bahagi ng kasunduan." -LicenseAgreement.ClickIAgreeToContinue="Kung iyong tinatanggap ang mga termino ng kasunduan, pindutin ang I Agree upang makapagpatulay. Kailangan mong sumang-ayon sa kasunduan upang magamit ang OBS." -LicenseAgreement.IAgree="Sumasang-ayon Ako" -LicenseAgreement.Exit="Lumabas" - Remux.SourceFile="OBS Recording" Remux.TargetFile="Target File" Remux.Remux="Remux" @@ -252,10 +250,6 @@ Remux.OBSRecording="OBS Recording" Remux.FinishedTitle="Tapos na ang pag-remux" Remux.Finished="Na-remux na ang recording" Remux.FinishedError="Na-remux na ang recording, ngunit ay file ay maaaring hindi kumpleto" -Remux.SelectRecording="Pumili ng OBS Recording …" -Remux.SelectTarget="Pumili ng target file …" -Remux.FileExistsTitle="Ang target file ay umiiral na" -Remux.FileExists="Ang target file na ito ay umiiral na, gusto ma ba itong palitan?" Remux.ExitUnfinishedTitle="Ang pagremux ay tinutuloy pa" Remux.ExitUnfinished="Hindi pa tapos ang pag-remux. Kung ihihinto ito ngayon, maaaring hindi na magagamit ang target file.\nSigurado ka bang gusto mong ihinto ang pagremux?" @@ -274,6 +268,7 @@ Basic.DisplayCapture="Ipakita ang Kuha" Basic.Main.PreviewConextMenu.Enable="Paganahin ang Preview" + ScaleFiltering="I-scale ang pag-fifilter" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilinear" @@ -407,14 +402,14 @@ Basic.Main.StoppingStreaming="Pagtigil ng Daloy..." Basic.Main.ForceStopStreaming="Itigil ang pag-stream (tanggalin ang antala)" Basic.MainMenu.File="&File" -Basic.MainMenu.File.Export="&I-export" +Basic.MainMenu.File.Export="I-&export" Basic.MainMenu.File.Import="&I-angkat" Basic.MainMenu.File.ShowRecordings="Ipakita ang mga &Recording" Basic.MainMenu.File.Remux="Re&mux na mga Recording" -Basic.MainMenu.File.Settings="&Mga Setting" +Basic.MainMenu.File.Settings="Mga &Setting" Basic.MainMenu.File.ShowSettingsFolder="Ipakita ang Folder ng mga Setting" Basic.MainMenu.File.ShowProfileFolder="Ipakita ang Profile Folder" -Basic.MainMenu.AlwaysOnTop="&Palaging Nasa Tuktok" +Basic.MainMenu.AlwaysOnTop="P&alaging Nasa Tuktok" Basic.MainMenu.File.Exit="E&xit" Basic.MainMenu.Edit="I&edit" @@ -422,42 +417,42 @@ Basic.MainMenu.Edit.Undo="Ipawalang-bisa (&U)" Basic.MainMenu.Edit.Redo="Gawin Muli (&R)" Basic.MainMenu.Edit.UndoAction="Ipawalang-bisa $1 (&U)" Basic.MainMenu.Edit.RedoAction="Gawing Muli $1 (&R)" -Basic.MainMenu.Edit.LockPreview="&Naka-lock na Preview" +Basic.MainMenu.Edit.LockPreview="Naka-&lock na Preview" Basic.MainMenu.Edit.Scale="Preview &Scaling" Basic.MainMenu.Edit.Scale.Window="Gawing Kasing-Laki ng Window" Basic.MainMenu.Edit.Scale.Canvas="Kanbas (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Output (%1x%2)" Basic.MainMenu.Edit.Transform="&Transform" -Basic.MainMenu.Edit.Transform.EditTransform="&Baguhin ang Transform..." +Basic.MainMenu.Edit.Transform.EditTransform="Baguhin ang Transform... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Kopyahin ang Transform" Basic.MainMenu.Edit.Transform.PasteTransform="I-paste ang Transform" -Basic.MainMenu.Edit.Transform.ResetTransform="&I-set muli ang Transform" +Basic.MainMenu.Edit.Transform.ResetTransform="I-set muli ang T&ransform" Basic.MainMenu.Edit.Transform.Rotate90CW="Iikot ng 90 degrees CW" Basic.MainMenu.Edit.Transform.Rotate90CCW="Iikot ng 90 degrees CCW" Basic.MainMenu.Edit.Transform.Rotate180="Iikot ng 180 degrees" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Baliktarin ng &pahalang" -Basic.MainMenu.Edit.Transform.FlipVertical="Baliktarin ng &patayo" -Basic.MainMenu.Edit.Transform.FitToScreen="&Pagkasyahin sa Screen" -Basic.MainMenu.Edit.Transform.StretchToScreen="&I-stretch sa screen" -Basic.MainMenu.Edit.Transform.CenterToScreen="&I-sentro sa screen" -Basic.MainMenu.Edit.Order="&Pagkakasunod-sunod" -Basic.MainMenu.Edit.Order.MoveUp="Ilipat &Pataas" -Basic.MainMenu.Edit.Order.MoveDown="Ilipat &Pababa" -Basic.MainMenu.Edit.Order.MoveToTop="Ilipat sa &Pinaka taas" -Basic.MainMenu.Edit.Order.MoveToBottom="Ilipat sa &Pinaka baba" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Baliktarin ng pa&halang" +Basic.MainMenu.Edit.Transform.FlipVertical="Baliktarin ng patayo (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Pagkasyahin sa Screen (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="I-&stretch sa screen" +Basic.MainMenu.Edit.Transform.CenterToScreen="I-sentro sa s&creen" +Basic.MainMenu.Edit.Order="Pagkakasun&od-sunod" +Basic.MainMenu.Edit.Order.MoveUp="Ilipat Pataas (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Ilipat Pababa (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Ilipa&t sa Pinaka taas" +Basic.MainMenu.Edit.Order.MoveToBottom="Ilipat sa Pinaka &baba" Basic.MainMenu.Edit.AdvAudio="&Advanced na mga Katangian ng Audio" Basic.MainMenu.View="&View" -Basic.MainMenu.View.Toolbars="&Mga Toolbar" +Basic.MainMenu.View.Toolbars="Mga &Toolbar" Basic.MainMenu.View.Docks="Mga Dock" Basic.MainMenu.View.Docks.ResetUI="I-set muli ang UI" Basic.MainMenu.View.Docks.LockUI="I-lock UI" -Basic.MainMenu.View.Toolbars.Listboxes="&Mga Listbox" +Basic.MainMenu.View.Toolbars.Listboxes="Mga &Listbox" Basic.MainMenu.View.SceneTransitions="Mga Transisyon ng S&cene" Basic.MainMenu.View.StatusBar="&Status Bar" Basic.MainMenu.View.Fullscreen.Interface="Interface gamit ang buong screen" -Basic.MainMenu.SceneCollection="&Kolekysyon ng mga Scene" +Basic.MainMenu.SceneCollection="Koleky&syon ng mga Scene" Basic.MainMenu.Profile="&Profile" Basic.MainMenu.Profile.Import="I-import ang Profile" Basic.MainMenu.Profile.Export="I-export ang Profile" @@ -466,16 +461,16 @@ Basic.MainMenu.SceneCollection.Export="I-export ang Koleksyon ng mga Eksena" Basic.MainMenu.Profile.Exists="May ganito ng Profile" Basic.MainMenu.SceneCollection.Exists="Mayroon ng ganitong koleksyon ng mga eksena" -Basic.MainMenu.Tools="&Mga Kasangkapan" +Basic.MainMenu.Tools="Mga Kasangkapan (&T)" -Basic.MainMenu.Help="&Tulong" -Basic.MainMenu.Help.HelpPortal="Portal Para sa &Tulong" +Basic.MainMenu.Help="Tulong (&H)" +Basic.MainMenu.Help.HelpPortal="&Portal Para sa Tulong" Basic.MainMenu.Help.Website="Bisitahin ang &Website" -Basic.MainMenu.Help.Logs="&Mga Log File" -Basic.MainMenu.Help.Logs.ShowLogs="&Ipakita ang mga Log File" -Basic.MainMenu.Help.Logs.UploadCurrentLog="I-upload ang &Pangkasalukuyang Log File" -Basic.MainMenu.Help.Logs.UploadLastLog="I-upload ang Huling Log File" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Tingnan ang Pangkasalukuyang Log" +Basic.MainMenu.Help.Logs="Mga &Log File" +Basic.MainMenu.Help.Logs.ShowLogs="Ipakita ang mga Log File (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="I-upload ang Pangkasalukuyang Log File (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="I-up&load ang Huling Log File" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Tingnan ang Pangkasalukuyang Log (&V)" Basic.MainMenu.Help.CheckForUpdates="Maghanap ng mga Update" Basic.Settings.ProgramRestart="Ang programa ay kailangan i-start muli para gumana ang mga setting na ito." @@ -542,7 +537,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="Babal: Ang pag-rekord gamit ang isang Basic.Settings.Output.Simple.Warn.Lossless="Babala: Ang kalidad na lossless ay nagbibigay ng lubhang malalaking file. Ang kalidad na lossless ay maaaring gumamit ng 7 gigabytes ng espasyo ng disk kada minuto o higit pa sa matataas na mga resolusyon o mga framerate. Ang lossless ay hindi minumungkahi para sa mga mahahabang recording maliban na lamang kung mayroon kang napakalaking espasyo sa disk na magagamit." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Sigurado ka bang gusto mong gamitin ang lossless na kalidad?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless na kalidad babala!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Babala: Hindi ka maaaring gumamit ng maraming magkahiwalay na QSV na mga encoder kapag say na nag-stream at nag-rerekord. Kung nais pagsabayin ang pag-stream at pag-rekord, mangyari lamang ibahin ang encoder para sa pag-rekord o ang encoder para sa pag-stream." Basic.Settings.Output.Simple.Encoder.Software="Software (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Hardware (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Hardware (AMD)" @@ -554,7 +548,6 @@ Basic.Settings.Output.Reconnect="Pakusa Makipagkonek muli" Basic.Settings.Output.RetryDelay="Subukan muling Maantala (Mga segundo)" Basic.Settings.Output.MaxRetries="Pinakamaraming Retries" Basic.Settings.Output.Advanced="Paganahin Pauna ang Enkoder Settings" -Basic.Settings.Output.EncoderPreset="Pangkasalukuyan enkoder (Nakatataas = Mas mababa CPU)" Basic.Settings.Output.CustomEncoderSettings="Pasadyang enkoder Mga setting" Basic.Settings.Output.CustomMuxerSettings="Pasadyang mga Setting ng Muxer" Basic.Settings.Output.NoSpaceFileName="Gumawa ng Pangalan ng File nang walang Pagitan" @@ -627,7 +620,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Pinatalas na pag-scale, 3 Basic.Settings.Audio="Audio" Basic.Settings.Audio.SampleRate="Sample Rate" Basic.Settings.Audio.Channels="Mga Channel" -Basic.Settings.Audio.MeterDecayRate="Audio Meter Decay Rate" Basic.Settings.Audio.MeterDecayRate.Fast="Mabilis" Basic.Settings.Audio.MeterDecayRate.Medium="Medium (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Mabagal (Type II PPM)" @@ -635,11 +627,6 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="BABALA: Naka-enable ang surrou Basic.Settings.Audio.MultichannelWarning="Kung nagsi-stream, tingnan kung ang streaming service ay sinusuportahan ang parehong surround sound ingest pat ang surround sound playback. Ang Twitch, Facebook 360 Live, Mixer RTMP, Smashcast ay mga halimbawa kung saan ang surround sound ay sinusuportahan ng buo. Kahit na ang Facebook Live at YouTube live ay parehong tumatanggap ng surround ingest, ang Facebook Live ay nagda-downmix sa stereo, at ang YouTube Live ay nagpapakita lamang ng dalawang channel. \n\nAng OBS audio na mga filter ay akma sa surround sound, pero ang suporta sa VST plugin ay hindi garantisado." Basic.Settings.Audio.MultichannelWarning.Title="Mapapagana ba ang tunog ng palibot ng audio?" Basic.Settings.Audio.MultichannelWarning.Confirm="Sigurado ka ba na gusto mong paganahin ang tunog ng palibot ng audio?" -Basic.Settings.Audio.DesktopDevice="Apatarong Desktop Awdiyo" -Basic.Settings.Audio.DesktopDevice2="Aparatong Desktop Awdiyo 2" -Basic.Settings.Audio.AuxDevice="Mic/Katulong na Aparato ng Awdiyo" -Basic.Settings.Audio.AuxDevice2="Mic/Katulong na Aparato ng Awdiyo 2" -Basic.Settings.Audio.AuxDevice3="Mic/Katulong na Aparato ng Awdiyo 3" Basic.Settings.Audio.EnablePushToMute="Paganahin Itulak-para-ma-i-mute" Basic.Settings.Audio.PushToMuteDelay="Pag-antala sa pagtulak-sa-walang tunog" Basic.Settings.Audio.EnablePushToTalk="Paganahin itulak-sa-usapan" @@ -656,11 +643,8 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Walang ginagawa" Basic.Settings.Advanced.FormatWarning="Babala: Ang mga format ng mga kulay maliban sa NV12 ay ginawa unsa lahat para sa pagrerekord, at hindi nirerekomenda para sa pag-stream. Ang pag-stream ay maaaring magdulot ng dagdag na gamit sa CPU dahil sa pagbago ng format ng kulay." Basic.Settings.Advanced.Audio.BufferingTime="Bilis ng Pag-buffer ng Audio" Basic.Settings.Advanced.Video.ColorFormat="Fomat ng Kulay" -Basic.Settings.Advanced.Video.ColorSpace="YUV Espasyo ng Kulay" -Basic.Settings.Advanced.Video.ColorRange="YUV Hanay ng Kulay" Basic.Settings.Advanced.Video.ColorRange.Partial="Panguna" Basic.Settings.Advanced.Video.ColorRange.Full="Buo" -Basic.Settings.Advanced.Audio.MonitoringDevice="Kagamitang Pangsubaybay ng Audio" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Default" Basic.Settings.Advanced.Audio.DisableAudioDucking="Huwag paganahin ang audio ducking ng Windows" Basic.Settings.Advanced.StreamDelay="Antala sa Pag-stream" @@ -674,9 +658,7 @@ Basic.Settings.Advanced.Network.EnableLowLatencyMode="Mode para sa low latency" Basic.AdvAudio="Pinahusay na mga Katangian ng Audio" Basic.AdvAudio.Name="Pangalan" -Basic.AdvAudio.Volume="Lakas ng tunog (%)" Basic.AdvAudio.Mono="I-downmix para maging Mono" -Basic.AdvAudio.Panning="Panning" Basic.AdvAudio.SyncOffset="Sync Offset (ms)" Basic.AdvAudio.Monitoring="Pagsubaybay sa Audio" Basic.AdvAudio.Monitoring.None="Naka-off ang Monitor" @@ -740,7 +722,6 @@ SceneItemHide="Itago '%1'" OutputWarnings.NoTracksSelected="Kailangan mong pumili ng kahit isang track" OutputWarnings.MultiTrackRecording="Babala: May ilang mga format (tulad ng FLV) na hindi sumusuporta ng maramihang track kada isang pag-rekord" -OutputWarnings.MP4Recording="Babala: Ang mga rekording na naka-save sa MP4 ay hindi na muling mababawi kung ang file ay hindi maaaring tapusin (hal. bilang resulta ng mga BSOD, nawalan ng kuryente, at iba pa). Kung gusto mong mag-rekord ng maraming audio track, maaari mong gamitin ang MKV at i-remux ang recording sa mp4 pag natapos na ito (File->Remux Recordings)" FinalScene.Title="Burahin ang Eksena" FinalScene.Text="Kailangan mayroon kahit isang eksena." @@ -748,3 +729,6 @@ FinalScene.Text="Kailangan mayroon kahit isang eksena." + + + diff --git a/UI/data/locale/tr-TR.ini b/UI/data/locale/tr-TR.ini index 7aee010..227ab87 100644 --- a/UI/data/locale/tr-TR.ini +++ b/UI/data/locale/tr-TR.ini @@ -2,7 +2,7 @@ Language="Türkçe" Region="Türkiye" -OK="Tamam" +OK="TAMAM" Apply="Uygula" Cancel="İptal" Close="Kapat" @@ -22,16 +22,16 @@ MoveDown="Aşağı Taşı" Settings="Ayarlar" Display="Ekran" Name="İsim" -Exit="Çık" +Exit="Çıkış" Mixer="Karıştırıcı" Browse="Gözat" Mono="Mono" Stereo="Stereo" DroppedFrames="Kaybedilen Kareler %1 (%2%)" StudioProgramProjector="Tam Ekran Projektör (Program)" -PreviewProjector="Tam Ekran Projektör (Önizleme)" -SceneProjector="Tam Ekran Projektör (Sahne)" -SourceProjector="Tam Ekran Projektör (Kaynak)" +PreviewProjector="Tam Ekran Yansıtması (Önizleme)" +SceneProjector="Tam Ekran Yansıtması (Sahne)" +SourceProjector="Tam Ekran Yansıtması (Kaynak)" StudioProgramWindow="Pencereli Projektör (Program)" PreviewWindow="Pencereli Projektör (Önizleme)" SceneWindow="Pencereli Projektör (Sahne)" @@ -49,7 +49,7 @@ Duplicate="Çoğalt" Enable="Etkinleştir" DisableOSXVSync="OSX V-Sync'i Devre Dışı Bırak" ResetOSXVSyncOnExit="OSX V-Sync'i Çıkışta Sıfırla" -HighResourceUsage="Kodlama aşırı yüklendi! Video ayarlarını kapatmayı veya daha hızlı bir kodlama ön ayarını kullanmayı düşünün." +HighResourceUsage="Kodlama aşırı yüklendi! Video ayarlarını kapatmayı veya daha hızlı bir kodlama ön ayarını kullanmayı düşünün." Transition="Geçiş" QuickTransitions="Hızlı Geçiş" Left="Sol" @@ -68,7 +68,7 @@ Copy="Kopyala" Paste="Yapıştır" PasteReference="Yapıştır (Referans)" PasteDuplicate="Yapıştır (Çoğalt)" -RemuxRecordings="Remux Kayıtları" +RemuxRecordings="Kayıtları Remux Et" Next="İleri" Back="Geri" Defaults="Varsayılanlar" @@ -80,14 +80,40 @@ StudioMode.Program="Program" ShowInMultiview="Çoklu Ekranda Göster" VerticalLayout="Dikey Düzen" Group="Grup" +DoNotShowAgain="Tekrar gösterme" +Default="(Varsayılan)" +Calculating="Hesaplanıyor..." AlreadyRunning.Title="OBS zaten çalışıyor" -AlreadyRunning.Text="OBS zaten çalışıyor! Bunu yapmak istemediyseniz, lütfen yeni bir örneği çalıştırmayı denemeden önce varolan tüm OBS örneklerini kapatın. OBS'yi sistem tablasına küçülmesi için ayarladıysanız, lütfen hala çalışıp çalışmadığını görmek için orayı kontrol edin." +AlreadyRunning.Text="OBS zaten çalışıyor! Bunu yapmak istemediyseniz, lütfen yeni bir örneği çalıştırmayı denemeden önce varolan tüm OBS örneklerini kapatın. OBS'yi sistem tablasına küçülmesi için ayarladıysanız, lütfen hala çalışıp çalışmadığını görmek için orayı kontrol edin." AlreadyRunning.LaunchAnyway="Yine de Başlat" +DockCloseWarning.Title="Yuvalanabilir Pencere Kapatma" +DockCloseWarning.Text="Az önce yuvalanabilir bir pencere kapattınız. Eğer tekrardan göstermek istiyorsanız, Menü çubuğundan Görüntüle → Paneller menüsünü kullanın." + +Auth.Authing.Title="Kimlik doğrulanıyor..." +Auth.Authing.Text="%1 ile doğrulanıyor, lütfen bekleyin..." +Auth.AuthFailure.Title="Kimlik Doğrulaması Başarısız" +Auth.AuthFailure.Text="%1 kimliği doğrulanamadı:\n\n%2: %3" +Auth.InvalidScope.Title="Kimlik Doğrulaması Gerekli" +Auth.InvalidScope.Text="%1 için kimlik doğrulama gereksinimleri değişti. Bazı özellikler kullanılamayabilir." +Auth.LoadingChannel.Title="Kanal bilgileri yükleniyor..." +Auth.LoadingChannel.Text="%1 için kanal bilgileri yükleniyor, lütfen bekleyin..." +Auth.ChannelFailure.Title="Kanal yüklenemedi" +Auth.ChannelFailure.Text="%1 için kanal bilgisi yüklenemedi\n\n%2: %3" +Auth.Chat="Sohbet" +Auth.StreamInfo="Yayın Bilgisi" +TwitchAuth.Stats="Twitch İstatistikleri" +TwitchAuth.Feed="Twitch Etkinlik akışı" +TwitchAuth.TwoFactorFail.Title="Yayın anahtarı sorgulanamadı" +TwitchAuth.TwoFactorFail.Text="OBS Twitch hesabına bağlanamadı. Lütfen iki-faktörlü doğrulamanın Twitch güvenlik ayarlarında ayarlandığından emin olun Bu yayın yapmanız için gereklidir." + Copy.Filters="Filtreleri Kopyala" Paste.Filters="Filtreleri Yapıştır" +BrowserPanelInit.Title="Tarayıcı başlatılıyor..." +BrowserPanelInit.Text="Tarayıcı başlatılıyor, lütfen bekleyin..." + BandwidthTest.Region="Bölge" BandwidthTest.Region.US="Amerika Birleşik Devletleri" BandwidthTest.Region.EU="Avrupa" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="Asya" BandwidthTest.Region.Other="Diğer" Basic.FirstStartup.RunWizard="Otomatik yapılandırma sihirbazını çalıştırmak istiyor musunuz? Ana penceredeki Ayarlar düğmesine tıklayarak ayarlarınızı elle de yapılandırabilirsiniz." -Basic.FirstStartup.RunWizard.BetaWarning="(Not: Otomatik yapılandırma sihirbazı şu anda beta'da)" Basic.FirstStartup.RunWizard.NoClicked="Fikrinizi değiştirirseniz, otomatik yapılandırma sihirbazını istediğiniz zaman Araçlar menüsünden yeniden çalıştırabilirsiniz." Basic.AutoConfig="Otomatik Yapılandırma Sihirbazı" -Basic.AutoConfig.Beta="Otomatik Yapılandırma Sihirbazı (Beta)" Basic.AutoConfig.ApplySettings="Ayarları Uygula" Basic.AutoConfig.StartPage="Kullanım Bilgileri" Basic.AutoConfig.StartPage.SubTitle="Programı ne için kullanmak istediğinizi belirtin" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 ya da 30, ama yüksek çözün Basic.AutoConfig.VideoPage.CanvasExplanation="Not: Tuval (taban) çözünürlüğü yayın veya kayıt yapacağınız çözünürlük ile aynı olmak zorunda değildir. Gerçek yayın/kayıt çözünürlüğünüz kaynak kullanımı ve bit hızı gereksinimlerini düşürmek için tuval çözünürlüğünüzden aşağıya boyutlandırılabilir." Basic.AutoConfig.StreamPage="Yayın Bilgisi" Basic.AutoConfig.StreamPage.SubTitle="Lütfen yayın bilginizi girin" +Basic.AutoConfig.StreamPage.ConnectAccount="Hesabı Bağla (isteğe bağlı)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Hesap Bağlantısını Kes" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Hesap Bağlantısı Kesilsin Mi?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Bu değişiklik hemen uygulanacaktır. Hesabınızın bağlantısını kesmek istediğinize emin misiniz?" +Basic.AutoConfig.StreamPage.UseStreamKey="Yayın Anahtarını Kullan" Basic.AutoConfig.StreamPage.Service="Hizmet" Basic.AutoConfig.StreamPage.Service.ShowAll="Tümünü Göster..." +Basic.AutoConfig.StreamPage.Service.Custom="Özel..." Basic.AutoConfig.StreamPage.Server="Sunucu" Basic.AutoConfig.StreamPage.StreamKey="Yayın Anahtarı" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Bağlantı)" @@ -144,7 +174,7 @@ Basic.AutoConfig.TestPage.Result.Footer="Bu ayarları kullanmak için, Ayarları Basic.Stats="İstatistikler" Basic.Stats.CPUUsage="İşlemci Kullanımı" -Basic.Stats.HDDSpaceAvailable="Mevcut HDD alanı" +Basic.Stats.HDDSpaceAvailable="Mevcut disk alanı" Basic.Stats.MemoryUsage="Bellek Kullanımı" Basic.Stats.AverageTimeToRender="Kare işleme için ortalama süre" Basic.Stats.SkippedFrames="Kodlama gecikmesi nedeniyle atlanan kareler" @@ -160,6 +190,9 @@ Basic.Stats.DroppedFrames="Atlanan Kareler (Ağ)" Basic.Stats.MegabytesSent="Toplam Veri Çıkışı" Basic.Stats.Bitrate="Bit Hızı" +ResetUIWarning.Title="Kullanıcı arayüzünü sıfırlamak istediğinize emin misiniz?" +ResetUIWarning.Text="Kullanıcı arayüzünü sıfırlamak, ek panelleri gizleyecektir. Panellerin görünmelerini istiyorsanız, bu panelleri görünüm menüsünden etkinleştirebilirsiniz.\n\nKullanıcı arayüzünü sıfırlamak istediğinize emin misiniz?" + Updater.Title="Yeni güncelleme mevcut" Updater.Text="Mevcut yeni bir güncelleme var:" Updater.UpdateNow="Şimdi Güncelle" @@ -206,8 +239,11 @@ ConfirmStart.Text="Yayını gerçekten başlatmak istiyor musunuz?" ConfirmStop.Title="Yayın Durdurulsun Mu?" ConfirmStop.Text="Yayını gerçekten durdurmak istiyor musunuz?" +ConfirmBWTest.Title="Bant genişliği testini başlat?" +ConfirmBWTest.Text="OBS'i bant genişliği test modunda yapılandırdınız. Bu mod, kanalınız yayına girmeden ağ testi yapmanıza olanak sağlar. Test tamamlandıktan sonra, izleyicilerin yayını görebilmesi için bu modu devre dışı bırakmanız gerekecektir.\n\nDevam etmek istiyor musunuz?" + ConfirmExit.Title="OBS'den Çıkılsın mı?" -ConfirmExit.Text="OBS şu anda etkin. Tüm yayınlar / kayıtlar kapatılacak. Çıkmak istediğinize emin misiniz?" +ConfirmExit.Text="OBS şu anda etkin. Tüm yayınlar/kayıtlar kapatılacaktır. Çıkmak istediğinize emin misiniz?" ConfirmRemove.Title="Kaldırmayı Onayla" ConfirmRemove.Text="'$1''i kaldırmak istediğinizden emin misiniz?" @@ -218,51 +254,54 @@ Output.StartRecordingFailed="Kayıt başlatılamadı" Output.StartReplayFailed="Tekrar oynatma arabelleği başlatılamadı" Output.StartFailedGeneric="Çıkışı başlatma başarısız oldu. Detaylar için lütfen günlüğe bakın: \n\nNVENC veya AMD kodlayıcılarını kullanıyorsanız, video sürücülerinin güncel olduğundan emin olun." + Output.ConnectFail.Title="Bağlantı kurulamadı" Output.ConnectFail.BadPath="Bağlantı adresiniz geçersiz. Ayarlarınızı kontrol edin ve geçerli bir adres giriniz." Output.ConnectFail.ConnectFailed="Sunucuya bağlanılamadı" Output.ConnectFail.InvalidStream="Belirtilen kanal veya yayın anahtarına erişilemedi, lütfen yayın anahtarınızı iyi kontrol edin. Eğer doğruysa, sunucuya bağlanırken sorun oluyor olabilir." -Output.ConnectFail.Error="Sunucuya bağlanmaya çalışırken beklenmeyen bir hata oluştu. Daha fazla bilgi için günlük dosyasına bakınız." +Output.ConnectFail.Error="Sunucuya bağlanmaya çalışırken beklenmeyen bir hata oluştu. Daha fazla bilgi için günlük dosyasına bakınız." Output.ConnectFail.Disconnected="Sunucu bağlantısı kesildi." +Output.StreamEncodeError.Title="Kodlama hatası" +Output.StreamEncodeError.Msg="Yayın sırasında bir kodlayıcı hatası oluştu." + Output.RecordFail.Title="Kayıt başlatılamadı" Output.RecordFail.Unsupported="Çıkış biçimi ya desteklenmiyor ya da birden fazla sesi desteklemiyor. Lütfen ayarlarınızı kontrol edip tekrar deneyin." Output.RecordNoSpace.Title="Yetersiz disk alanı" Output.RecordNoSpace.Msg="Kayıt'aa devam etmek yeterli disk alanı yok." Output.RecordError.Title="Kayıt Hatası" Output.RecordError.Msg="Kayıt anında bir hata oluştu." +Output.RecordError.EncodeErrorMsg="Kayıt sırasında bir kodlayıcı hatası oluştu." Output.ReplayBuffer.NoHotkey.Title="Kısayol tuşu ayarlanmadı!" Output.ReplayBuffer.NoHotkey.Msg="Yeniden oynatma arabelleği için ayarlı bir kısayol tuşu yok. Lütfen yeniden oynatma kayıtlarını kaydetmek için \"Kaydet\" kısayol tuşunu ayarlayın." -Output.BadPath.Title="Dosya Yolu Geçersiz" +Output.BadPath.Title="Geçersiz Dosya Dizini" Output.BadPath.Text="Ayarlanan dosya kayıt yolu geçersiz. Lütfen ayarlarınızı kontrol ederek geçerli bir dosya yolunun girilmiş olduğundan emin olunuz." LogReturnDialog="Günlük Dosyası Başarıyla Karşıya Yüklendi" LogReturnDialog.CopyURL="URL'yi Kopyala" LogReturnDialog.ErrorUploadingLog="Günlük dosyası yüklenirken hata oluştu" -LicenseAgreement="Lisans Sözleşmesi" -LicenseAgreement.PleaseReview="Lütfen OBS'yi kullanmadan önce lisans sözleşmesini gözden geçiriniz. Bu programı kullanarak GNU Genel Kamu Lisansı v2.0 okuyup anladığınızı kabul etmiş sayılırsınız. Sözleşmenin geri kalan kısmını görmek için lütfen sayfayı aşağı kaydırınız." -LicenseAgreement.ClickIAgreeToContinue="Sözleşme koşullarını kabul ediyorsanız, devam etmek için Kabul Ediyoruma tıklayın. OBS'yi kullanmak için sözleşme koşullarını kabul etmelisiniz." -LicenseAgreement.IAgree="Kabul Ediyorum" -LicenseAgreement.Exit="Çık" - -Remux.SourceFile="OBS Kayıt ediyor" +Remux.SourceFile="OBS Kaydı" Remux.TargetFile="Hedef Dosya" Remux.Remux="Remux" -Remux.OBSRecording="OBS Kayıt Ediyor" +Remux.Stop="Remux'u Durdur" +Remux.ClearFinished="Biten Ögeleri Temizle" +Remux.ClearAll="Tüm Ögeleri Temizle" +Remux.OBSRecording="OBS Kaydı" Remux.FinishedTitle="Remux tamamlandı" Remux.Finished="Kayıt remux edildi" Remux.FinishedError="Kayıt remux edildi, ancak dosya tamamlanmamış olabilir" -Remux.SelectRecording="OBS kaydını seçiniz …" -Remux.SelectTarget="Hedef dosyayı seçiniz …" -Remux.FileExistsTitle="Hedef dosya mevcut" -Remux.FileExists="Hedef dosya mevcut, dosyayı değiştirmek istiyor musunuz?" -Remux.ExitUnfinishedTitle="Remux işlemi devam etmekte" -Remux.ExitUnfinished="Remux işlemi tamamlanmadı, şu anda durma dosyayı kullanılamaz hale getirebilir.\nRemux işlemini durdurmak istediğinizden emin misiniz?" +Remux.SelectRecording="OBS Kaydı seçin..." +Remux.SelectTarget="Hedef dosyayı seçin..." +Remux.FileExistsTitle="Hedef dosyalar var" +Remux.FileExists="Aşağıdaki hedef dosyalar zaten var. Var olan dosyaları değiştirmek istiyor musunuz?" +Remux.ExitUnfinishedTitle="Remux devam ediyor" +Remux.ExitUnfinished="Remux tamamlanmadı, şu anda durdurmak hedef dosyayı kullanılamaz kılabilir.\nRemux'u durdurmak istediğinizden emin misiniz?" +Remux.HelpText="Remux etmek için dosyaları bu pencereye sürükleyip bırakın veya bir dosyaya göz atmak için boş bir \"OBS Kaydı\" hücresini seçin." UpdateAvailable="Yeni Güncelleştirme Mevcut" -UpdateAvailable.Text="%1.%2.%3 sürümü şimdi kullanılabilir. İndirmek için tıklayın" +UpdateAvailable.Text="%1.%2.%3 sürümü şimdi kullanılabilir. İndirmek için tıklayın" Basic.DesktopDevice1="Masaüstü Ses" Basic.DesktopDevice2="Masaüstü Ses 2" @@ -276,11 +315,14 @@ Basic.DisplayCapture="Ekran Yakalama" Basic.Main.PreviewConextMenu.Enable="Önizlemeyi Etkinleştir" +Basic.Main.Preview.Disable="Önizlemeyi Devre dışı bırak" + ScaleFiltering="Boyut Filtreleme" ScaleFiltering.Point="Nokta" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bikübik" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Alan" Deinterlacing="Deinterlacing" Deinterlacing.Discard="Discard" @@ -411,55 +453,57 @@ Basic.Main.Group="Grup %1" Basic.Main.GroupItems="Seçilen Ögeleri Grupla" Basic.Main.Ungroup="Grubu Çöz" -Basic.MainMenu.File="&Dosya" -Basic.MainMenu.File.Export="Dışa Aktar" -Basic.MainMenu.File.Import="İçe Aktar" +Basic.MainMenu.File="Dosya (&F)" +Basic.MainMenu.File.Export="Dışa Aktar (&E)" +Basic.MainMenu.File.Import="İçe Aktar (&I)" Basic.MainMenu.File.ShowRecordings="Kayıtla&rı Göster" -Basic.MainMenu.File.Remux="Re&mux Kayıtları" -Basic.MainMenu.File.Settings="&Ayarlar" +Basic.MainMenu.File.Remux="Kayıtları Re&mux Et" +Basic.MainMenu.File.Settings="Ayarlar (&S)" Basic.MainMenu.File.ShowSettingsFolder="Ayarlar Dosyasını Göster" Basic.MainMenu.File.ShowProfileFolder="Profil Dosyasını Göster" -Basic.MainMenu.AlwaysOnTop="&Her Zaman Üstte" -Basic.MainMenu.File.Exit="Ç&ıkış" +Basic.MainMenu.AlwaysOnTop="Her Z&aman Üstte" +Basic.MainMenu.File.Exit="Çıkış (&X)" -Basic.MainMenu.Edit="&Düzenle" -Basic.MainMenu.Edit.Undo="&Geri al" -Basic.MainMenu.Edit.Redo="&Tekrar Yap" -Basic.MainMenu.Edit.UndoAction="&$1 Geri al" -Basic.MainMenu.Edit.RedoAction="&$1 Yinele" -Basic.MainMenu.Edit.LockPreview="&Önizlemeyi Kilitle" -Basic.MainMenu.Edit.Scale="Boyutlandırmayı &Önizle" +Basic.MainMenu.Edit="Düz&enle" +Basic.MainMenu.Edit.Undo="Geri al (&U)" +Basic.MainMenu.Edit.Redo="Tek&rar Yap" +Basic.MainMenu.Edit.UndoAction="$1 Geri al (&U)" +Basic.MainMenu.Edit.RedoAction="$1 Yinele (&R)" +Basic.MainMenu.Edit.LockPreview="Öniz&lemeyi Kilitle" +Basic.MainMenu.Edit.Scale="Boyutlandırmayı Önizle (&S)" Basic.MainMenu.Edit.Scale.Window="Pencereye Boyutlandır" Basic.MainMenu.Edit.Scale.Canvas="Tuval (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Çıkış (%1x%2)" -Basic.MainMenu.Edit.Transform="&Dönüştür" -Basic.MainMenu.Edit.Transform.EditTransform="&Dönüştürmeyi Düzenle..." +Basic.MainMenu.Edit.Transform="Dönüş&tür" +Basic.MainMenu.Edit.Transform.EditTransform="Dönüştürm&eyi Düzenle..." Basic.MainMenu.Edit.Transform.CopyTransform="Dönüştürmeyi Kopyala" Basic.MainMenu.Edit.Transform.PasteTransform="Dönüştürmeyi Yapıştır" -Basic.MainMenu.Edit.Transform.ResetTransform="&Dönüştürmeyi Sıfırla" +Basic.MainMenu.Edit.Transform.ResetTransform="Dönüştü&rmeyi Sıfırla" Basic.MainMenu.Edit.Transform.Rotate90CW="90 derece saat yönüne döndür" Basic.MainMenu.Edit.Transform.Rotate90CCW="90 derece saatin tersi yönüne döndür" Basic.MainMenu.Edit.Transform.Rotate180="180 derece döndür" -Basic.MainMenu.Edit.Transform.FlipHorizontal="&Yatay Döndür" -Basic.MainMenu.Edit.Transform.FlipVertical="Dikey &Çevir" -Basic.MainMenu.Edit.Transform.FitToScreen="&Ekrana Sığdır" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Ekrana genişlet" -Basic.MainMenu.Edit.Transform.CenterToScreen="&Ekrana Ortala" -Basic.MainMenu.Edit.Order="&Sırala" -Basic.MainMenu.Edit.Order.MoveUp="&Yukarı Taşı" -Basic.MainMenu.Edit.Order.MoveDown="Aşağı &Taşı" -Basic.MainMenu.Edit.Order.MoveToTop="En &Üste Taşı" -Basic.MainMenu.Edit.Order.MoveToBottom="En &Alta Taşı" -Basic.MainMenu.Edit.AdvAudio="&Gelişmiş Ses Özellikleri" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Yatay Döndür (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Dikey Çe&vir" +Basic.MainMenu.Edit.Transform.FitToScreen="Ekrana Sığdır (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Ekrana genişlet (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Ekrana Ortala (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Dikeye Hizala" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Yataya Hizala" +Basic.MainMenu.Edit.Order="Sırala (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Y&ukarı Taşı" +Basic.MainMenu.Edit.Order.MoveDown="Aşağı Taşı (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="En Üs&te Taşı" +Basic.MainMenu.Edit.Order.MoveToBottom="En Alta Taşı (&B)" +Basic.MainMenu.Edit.AdvAudio="Gelişmiş Ses Özellikleri (&A)" -Basic.MainMenu.View="&Görünüm" -Basic.MainMenu.View.Toolbars="&Araç Çubukları" +Basic.MainMenu.View="Görünüm (&V)" +Basic.MainMenu.View.Toolbars="Araç Çubukları (&T)" Basic.MainMenu.View.Docks="Paneller" Basic.MainMenu.View.Docks.ResetUI="Arayüzü Sıfırla" Basic.MainMenu.View.Docks.LockUI="Arayüzü Kilitle" Basic.MainMenu.View.Toolbars.Listboxes="&Liste Kutuları" -Basic.MainMenu.View.SceneTransitions="S&ahne Geçişleri" -Basic.MainMenu.View.StatusBar="&Durum Çubuğu" +Basic.MainMenu.View.SceneTransitions="Sahne Geçişleri (&C)" +Basic.MainMenu.View.StatusBar="Durum Çubuğu (&S)" Basic.MainMenu.View.Fullscreen.Interface="Tam Ekran Arayüz" Basic.MainMenu.SceneCollection="&Sahne Koleksiyonu" @@ -471,21 +515,22 @@ Basic.MainMenu.SceneCollection.Export="Sahne Koleksiyonunu Dışa Aktar" Basic.MainMenu.Profile.Exists="Profil zaten var" Basic.MainMenu.SceneCollection.Exists="Sahne koleksiyonu zaten var" -Basic.MainMenu.Tools="&Araçlar" +Basic.MainMenu.Tools="Araçlar (&T)" -Basic.MainMenu.Help="&Yardım" +Basic.MainMenu.Help="Yardım (&H)" Basic.MainMenu.Help.HelpPortal="Yardım &Portalı" -Basic.MainMenu.Help.Website="&Siteyi Ziyaret Et" +Basic.MainMenu.Help.Website="Siteyi Ziyaret Et (&W)" Basic.MainMenu.Help.Discord="&Discord Sunucusuna Katıl" -Basic.MainMenu.Help.Logs="&Günlük Dosyaları" -Basic.MainMenu.Help.Logs.ShowLogs="&Günlük Dosyalarını Göster" -Basic.MainMenu.Help.Logs.UploadCurrentLog="&Mevcut Günlük Dosyasını Karşıya Yükle" -Basic.MainMenu.Help.Logs.UploadLastLog="&Son Günlük Dosyasını Karşıya Yükle" -Basic.MainMenu.Help.Logs.ViewCurrentLog="&Şimdiki Günlüğü Göster" +Basic.MainMenu.Help.Logs="Gün&lük Dosyaları" +Basic.MainMenu.Help.Logs.ShowLogs="Günlük Do&syalarını Göster" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Mev&cut Günlük Dosyasını Karşıya Yükle" +Basic.MainMenu.Help.Logs.UploadLastLog="Son Gün&lük Dosyasını Karşıya Yükle" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Şimdiki Günlüğü Göster (&V)" Basic.MainMenu.Help.CheckForUpdates="Güncellemeleri Denetle" Basic.MainMenu.Help.CrashLogs="Çökme &Raporları" -Basic.MainMenu.Help.CrashLogs.ShowLogs="Çökme Raporlarını &Göster" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="&Son Çökme Raporunu Yükle" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Çökme Raporlarını Gö&ster" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Son Çökme Raporunu Yük&le" +Basic.MainMenu.Help.About="H&akkında" Basic.Settings.ProgramRestart="Programın, bu ayarların etkinleşmesi için yeniden başlatılması gerekir." Basic.Settings.ConfirmTitle="Değişiklikleri Onayla" @@ -514,8 +559,13 @@ Basic.Settings.General.SysTray="Sistem tepsisi" Basic.Settings.General.SysTrayWhenStarted="Başladığında sistem tepsisine küçült" Basic.Settings.General.SystemTrayHideMinimize="Her zaman görev çubuğu yerine sistem tepsisine küçült" Basic.Settings.General.SaveProjectors="Çıkışta projektörleri kaydet" +Basic.Settings.General.Preview="Önizleme" +Basic.Settings.General.OverflowHidden="Taşmayı gizle" +Basic.Settings.General.OverflowAlwaysVisible="Taşmayı her zaman görünür yap" +Basic.Settings.General.OverflowSelectionHidden="Kaynak görünmese bile taşmayı göster" Basic.Settings.General.SwitchOnDoubleClick="Çift tıklamada sahneye geçiş yap" Basic.Settings.General.StudioPortraitLayout="Dikey düzeni etkinleştir" +Basic.Settings.General.TogglePreviewProgramLabels="Önizlemeyi göster/program etiketleri" Basic.Settings.General.Multiview="Çoklu görüntü" Basic.Settings.General.Multiview.MouseSwitch="Sahneler arası geçiş için tıkla" Basic.Settings.General.Multiview.DrawSourceNames="Sahne adlarını göster" @@ -529,6 +579,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Yatay, Üst (24 Basic.Settings.Stream="Yayın" Basic.Settings.Stream.StreamType="Yayın Türü" +Basic.Settings.Stream.Custom.UseAuthentication="Kimlik doğrulaması kullan" +Basic.Settings.Stream.Custom.Username="Kullanıcı adı" +Basic.Settings.Stream.Custom.Password="Şifre" +Basic.Settings.Stream.BandwidthTestMode="Bant Genişliği Test Modunu Etkinleştir" Basic.Settings.Output="Çıkış" Basic.Settings.Output.Format="Kayıt Biçimi" @@ -546,21 +600,20 @@ Basic.Settings.Output.ReplayBuffer.MegabytesMax="Maksimum Bellek (Megabayt)" Basic.Settings.Output.ReplayBuffer.Estimate="Tahmini bellek kullanımı: %1 MB" Basic.Settings.Output.ReplayBuffer.EstimateUnknown="Bellek kullanımını tahmin edemezsin. Lütfen maksimum bellek sınırını ayarlayın." Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(Not: kısayol tuşları bölümünde yeniden oynatma ara belleği için kısayol tuşu ayarladığınızdan emin olun)" -Basic.Settings.Output.ReplayBuffer.Prefix="Tekrar Oynatma Arabelleği Dosya Adı Öneki" -Basic.Settings.Output.ReplayBuffer.Suffix="Suffix" +Basic.Settings.Output.ReplayBuffer.Prefix="Tekrar Oynatma Arabelleği Dosya Adı Ön Eki" +Basic.Settings.Output.ReplayBuffer.Suffix="Son Eki" Basic.Settings.Output.Simple.SavePath="Kayıt Yolu" Basic.Settings.Output.Simple.RecordingQuality="Kayıt Kalitesi" Basic.Settings.Output.Simple.RecordingQuality.Stream="Canlı Yayın ile Aynı" Basic.Settings.Output.Simple.RecordingQuality.Small="Yüksek Kalite, Normal Dosya Boyutu" Basic.Settings.Output.Simple.RecordingQuality.HQ="Aynı Kaliteye Yakın, Büyük Dosya Boyutu" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Kayıpsız Kalite, Çok Büyük Dosya Boyutu" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Uyarı: Yayın video bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Uyarı: Yayın audio bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Uyarı: Yayın video bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Uyarı: Yayın audio bit hızı %1 olarak ayarlanacak, bu şu anki yayın hizmeti için üst sınırdır. Eğer %1 değerinin üstüne çıkmak istediğinizden eminseniz, gelişmiş kodlayıcı seçeneklerini etkinleştirin ve \"Yayın hizmetini bit hızı sınırlarına zorla\" işaretini kaldırın." Basic.Settings.Output.Simple.Warn.Encoder="Uyarı: Bir yazılım kodlayıcı ile yayın kalitesinden farklı kayıt yapmak eğer aynı anda hem kayıt hem de yayın yapıyorsanız ilave CPU kullanımı gerektirecektir." Basic.Settings.Output.Simple.Warn.Lossless="Uyarı: Kayıpsız kalite muazzam büyük dosya boyutları oluşturur! Kayıpsız kalite, yüksek çözünürlüklerde ve kare hızlarında, dakikada 7 gigabyte'a kadar disk alanı kullanabilir. Kayıpsız, kullanılabilir disk alanınız çok büyük değilse, uzun kayıtlar için tavsiye edilmez." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Kayıpsız kalitede kullanmak istediğinizden emin misiniz?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Kayıpsız kalite uyarısı!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Uyarı: Aynı anda yayın ve kayıt yaparken çoklu ayrı QSV kodlayıcı kullanamazsınız. Eğer aynı anda yayın ve kayıt yapmak istiyorsanız, lütfen kayıt kodlayıcısını yada yayın kodlayıcısını değiştirin." Basic.Settings.Output.Simple.Encoder.Software="Yazılım (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Donanım (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Donanım (AMD)" @@ -572,7 +625,7 @@ Basic.Settings.Output.Reconnect="Otomatik Yeniden Bağlan" Basic.Settings.Output.RetryDelay="Yeniden Deneme Gecikmesi (saniye)" Basic.Settings.Output.MaxRetries="Maksimum Deneme Sayısı" Basic.Settings.Output.Advanced="Gelişmiş Kodlayıcı Ayarlarını Etkinleştir" -Basic.Settings.Output.EncoderPreset="Kodlayıcı Önayarı (yüksek = daha az İŞLEMCİ)" +Basic.Settings.Output.EncoderPreset="Kodlayıcı Hazır Ayarı" Basic.Settings.Output.CustomEncoderSettings="Özel Kodlayıcı Ayarları" Basic.Settings.Output.CustomMuxerSettings="Özel Muxer Ayarları" Basic.Settings.Output.NoSpaceFileName="Dosya ismini boşluk olmadan oluştur" @@ -635,7 +688,7 @@ Basic.Settings.Video.Numerator="Pay" Basic.Settings.Video.Denominator="Payda" Basic.Settings.Video.Renderer="İşleyici" Basic.Settings.Video.InvalidResolution="Geçersiz çözünürlük değeri. [Genişlik]x[Yükseklik] şeklinde olmalıdır. (örnek 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Video çıkışı şu anda etkin durumda. Video ayarlarını değiştirmek için lütfen bütün çıkışları kapalı duruma getirin." +Basic.Settings.Video.CurrentlyActive="Video çıkışı şu anda etkin durumda. Video ayarlarını değiştirmek için lütfen bütün çıkışları kapalı duruma getirin." Basic.Settings.Video.DisableAero="Aero'yu Devre Dışı Bırak" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (En hızlı, ancak boyutlandırmada bulanık görüntü)" @@ -645,7 +698,6 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Keskinleştirilmiş boyut Basic.Settings.Audio="Ses" Basic.Settings.Audio.SampleRate="Örnekleme Sıklığı" Basic.Settings.Audio.Channels="Kanallar" -Basic.Settings.Audio.MeterDecayRate="Ses Ölçer Sönüm Hızı" Basic.Settings.Audio.MeterDecayRate.Fast="Hızlı" Basic.Settings.Audio.MeterDecayRate.Medium="Orta (Tür I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="Yavaş (Tür II PPM)" @@ -656,16 +708,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="Uyarı: Surround ses etkin." Basic.Settings.Audio.MultichannelWarning="Yayın yapılıyorsa, yayın hizmetinizin hem surround ses alınımını hem de surround ses geri oynatımını desteklediğinden emin olun. Twitch, Facebook 360 Live, Karıştırıcı RTMP, Smashcast, surround sesin tam desteklendiği örneklerdir. Facebook Live'ın ve YouTube Live'ın her ikisi de surround alınımını desteklese de, Facebook Live stereo'ya indirger, ve YouTube Live sadece iki kanal oynatır.\n\nOBS ses filtreleri surround sesle uyumludur, ancak VST eklenti desteği kesin değildir." Basic.Settings.Audio.MultichannelWarning.Title="Surround ses etkinleştirilsin mi?" Basic.Settings.Audio.MultichannelWarning.Confirm="Surround sesi etkinleştirmek istediğinize emin misiniz?" -Basic.Settings.Audio.DesktopDevice="Masaüstü Ses Aygıtı" -Basic.Settings.Audio.DesktopDevice2="Masaüstü Ses Aygıtı 2" -Basic.Settings.Audio.AuxDevice="Mic/yardımcı ses aygıtı" -Basic.Settings.Audio.AuxDevice2="Mic/yardımcı ses aygıtı 2" -Basic.Settings.Audio.AuxDevice3="Mic/yardımcı ses aygıtı 3" +Basic.Settings.Audio.Devices="Cihazlar" +Basic.Settings.Audio.DesktopDevice="Masaüstü Sesi" +Basic.Settings.Audio.DesktopDevice2="Masaüstü Sesi 2" +Basic.Settings.Audio.AuxDevice="Mikrofon/Yardımcı Ses" +Basic.Settings.Audio.AuxDevice2="Mikrofon/Yardımcı Ses 2" +Basic.Settings.Audio.AuxDevice3="Mikrofon/Yardımcı Ses 3" +Basic.Settings.Audio.AuxDevice4="Mikrofon/Yardımcı Ses 4" Basic.Settings.Audio.EnablePushToMute="Bas sustur'u etkinleştir" Basic.Settings.Audio.PushToMuteDelay="Bas sustur gecikmesi" Basic.Settings.Audio.EnablePushToTalk="Bas-Konuş'u Etkinleştir" Basic.Settings.Audio.PushToTalkDelay="Bas-Konuş gecikmesi" Basic.Settings.Audio.UnknownAudioDevice="[Cihaz bağlı yada kullanılabilir değil]" +Basic.Settings.Audio.Disabled="Devre Dışı" Basic.Settings.Advanced="Gelişmiş" Basic.Settings.Advanced.General.ProcessPriority="İşlem Önceliği" @@ -677,11 +732,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="Boşta" Basic.Settings.Advanced.FormatWarning="Uyarı: NV12 dışındaki renk biçimleri esas olarak kayıt için tasarlanmıştır ve yayın anında kullanma önerilmez. Yayın nedeni ile renk biçimini dönüştürme çok fazla İŞLEMCİ kullanımına sebep olabilir." Basic.Settings.Advanced.Audio.BufferingTime="Ses Arabelleğe Alma Süresi" Basic.Settings.Advanced.Video.ColorFormat="Renk Biçimi" -Basic.Settings.Advanced.Video.ColorSpace="YUV Renk Alanı" -Basic.Settings.Advanced.Video.ColorRange="YUV Renk Aralığı" +Basic.Settings.Advanced.Video.ColorSpace="Renk Uzayı" +Basic.Settings.Advanced.Video.ColorRange="Renk Aralığı" Basic.Settings.Advanced.Video.ColorRange.Partial="Kısmi" Basic.Settings.Advanced.Video.ColorRange.Full="Tam" -Basic.Settings.Advanced.Audio.MonitoringDevice="Ses İzleme Aygıtı" +Basic.Settings.Advanced.Audio.MonitoringDevice="İzleme Aygıtı" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Varsayılan" Basic.Settings.Advanced.Audio.DisableAudioDucking="Windows ses alçaltmasını devre dışı bırak" Basic.Settings.Advanced.StreamDelay="Yayın Gecikmesi" @@ -693,12 +748,14 @@ Basic.Settings.Advanced.Network.BindToIP="IP Bağla" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Yeni ağ kodunu etkinleştir" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Düşük gecike modu" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Ana pencere odaktayken kısayol tuşlarını devre dışı bırak" +Basic.Settings.Advanced.AutoRemux="Otomatik olarak mp4'e remux et" +Basic.Settings.Advanced.AutoRemux.MP4="(mkv olarak kaydet)" Basic.AdvAudio="Gelişmiş Ses Özellikleri" Basic.AdvAudio.Name="İsim" -Basic.AdvAudio.Volume="Ses Düzeyi (%)" +Basic.AdvAudio.Volume="Ses" Basic.AdvAudio.Mono="Mono Karıştırmayı Azalt" -Basic.AdvAudio.Panning="Kaydırma" +Basic.AdvAudio.Balance="Denge" Basic.AdvAudio.SyncOffset="Eşitleme Uzaklığı (ms)" Basic.AdvAudio.Monitoring="Ses İzleme" Basic.AdvAudio.Monitoring.None="Ekran Kapalı" @@ -708,13 +765,14 @@ Basic.AdvAudio.AudioTracks="Parçalar" Basic.Settings.Hotkeys="Kısayollar" Basic.Settings.Hotkeys.Pair="'%1' ile paylaşılan tuş kombinasyonu açma/kapama olarak çalışır" +Basic.Settings.Hotkeys.Filter="Filtre" Basic.Hotkeys.SelectScene="Sahneye geçiş yap" Basic.SystemTray.Show="Göster" Basic.SystemTray.Hide="Gizle" -Basic.SystemTray.Message.Reconnecting="Bağlantı kesildi. Yeniden bağlanılıyor..." +Basic.SystemTray.Message.Reconnecting="Bağlantı kesildi. Yeniden bağlanılıyor..." Hotkeys.Insert="Ekle" Hotkeys.Delete="Sil" @@ -751,6 +809,7 @@ Hotkeys.AppleKeypadSubtract="- (Tuş takımı)" Hotkeys.AppleKeypadDecimal=". (Tuş takımı)" Hotkeys.AppleKeypadEqual="= (Tuş takımı)" Hotkeys.MouseButton="%1 Fare" +Hotkeys.Escape="Esc" Mute="Sesi Kapat" Unmute="Sesi Aç" @@ -762,7 +821,7 @@ SceneItemHide="'%1' Gizle" OutputWarnings.NoTracksSelected="En az bir ses parçası seçmelisiniz" OutputWarnings.MultiTrackRecording="Uyarı: Bazı biçimler (FLV gibi) kayıt başına birden fazla parçayı desteklemez" -OutputWarnings.MP4Recording="Uyarı: MP4'e kaydedilen kayıtlar eğer dosya sonlandırılamazsa kurtarılamaz (örneğin: Mavi Hata Ekranı, güç kesintisi v.b.). Eğer çoklu ses izi kaydetmek istiyorsanız MKV kullanmayı düşünün ve bittikten sonra sonra kayıtı mp4'e remuxlayabilirsiniz (Dosya->Remux Kayıtları)" +OutputWarnings.MP4Recording="Uyarı: MP4/MOV için kaydedilen kayıtları dosya (örneğin BSODs sonucu olarak, güç kayıp, vb.) kesinleşmiş değil varsa geri almanız mümkün olmayacaktır. Kaydetmek istediğiniz birden çok ses parçaları bu bittikten sonra MKV ve MP4/MOV için kayıt remux kullanmayı göz önünde bulundurun (dosya → Remux kayıtları)" FinalScene.Title="Sahneyi Sil" FinalScene.Text="En az bir sahne olması gerekiyor." @@ -770,9 +829,24 @@ FinalScene.Text="En az bir sahne olması gerekiyor." NoSources.Title="Kaynak Yok" NoSources.Text="Henüz hiç video kaynağı eklemediniz gibi görünüyor, bu yüzden sadece boş bir ekran çıktısı alacaksınız. Bunu yapmak istediğinize emin misiniz?" NoSources.Text.AddSource="Ana pencerede Kaynaklar kutusundaki + simgesine tıklayarak istediğiniz zaman kaynak ekleyebilirsiniz." +NoSources.Label="Herhangi bir kaynağınız yok. \n Bir kaynak eklemek için aşağıdaki tuşlara basın yada sağ tıklayın." ChangeBG="Renk Ayarla" CustomColor="Özel Renk" BrowserSource.EnableHardwareAcceleration="Tarayıcı Kaynak Donanım Hızlandırmasını Etkinleştir" +About="Hakkında" +About.Info="OBS Studio özgür ve açık kaynaklı video kayıt ve canlı yayın yazılımıdır." +About.Donate="Katkıda Bulunun" +About.GetInvolved="Katkıda Bulun" +About.Authors="Yazarlar" +About.License="Lisans" +About.Contribute="OBS Projesini Destekleyin" + +ResizeOutputSizeOfSource="Çıkışı yeniden boyutlandır (kaynak boyutu)" +ResizeOutputSizeOfSource.Text="Temel ve çıkış çözünürlüğü mevcut kaynağın boyutuna göre yeniden boyutlandırılacaktır." +ResizeOutputSizeOfSource.Continue="Devam etmek istiyor musunuz?" + +PreviewTransition="Geçişi Önizle" + diff --git a/UI/data/locale/uk-UA.ini b/UI/data/locale/uk-UA.ini index 57ff3fc..92ca8d0 100644 --- a/UI/data/locale/uk-UA.ini +++ b/UI/data/locale/uk-UA.ini @@ -80,14 +80,39 @@ StudioMode.Program="Програма наживо" ShowInMultiview="Показувати у Мульти-перегляді" VerticalLayout="Вертикальне компонування" Group="Група" +DoNotShowAgain="Більше не показувати" +Default="(За замовчуванням)" +Calculating="Обчислення..." AlreadyRunning.Title="OBS вже виконується" AlreadyRunning.Text="OBS вже запущено! Тільки якщо ви дійсно не намагаєтесь цього зробити, будь ласка позакривайте всі відкриті OBS перед тим як запускати нову копію. Якщо OBS налаштовано згортатися в трей, перевірте чи не виконується він там й досі." AlreadyRunning.LaunchAnyway="Все одно запустити" +DockCloseWarning.Title="Закриття панелі інтерфейсу" +DockCloseWarning.Text="Ви щойно закрили одну з панелей інтерфейсу. Якщо ви бажаєте вивести її знов - використайте опції з головного меню Вид → Панелі інтерфейсу." + +Auth.Authing.Title="Перевірка автентичності..." +Auth.Authing.Text="Перевірка автентичності з %1, будь ласка зачекайте..." +Auth.AuthFailure.Title="Помилка автентифікації" +Auth.AuthFailure.Text="Не вдалося завершити перевірку автентичності з %1:\n\n%2: %3" +Auth.InvalidScope.Title="Потрібна перевірка автентичності" +Auth.InvalidScope.Text="Вимоги до перевірки автентичності з %1 змінилися. Деякі функції можуть бути недоступними." +Auth.LoadingChannel.Title="Завантаження інформації про канал..." +Auth.LoadingChannel.Text="Завантажується інформація про канал з %1, будь ласка зачекайте..." +Auth.ChannelFailure.Title="Не вдалося завантажити канал" +Auth.ChannelFailure.Text="Не вдалося завантажити інформацію про канал з %1\n\n%2: %3" +Auth.Chat="Розмова (мій чат)" +Auth.StreamInfo="Інформація про Трансляцію" +TwitchAuth.Stats="Статистика Twitch" +TwitchAuth.Feed="Стрічка активності Twitch" +TwitchAuth.TwoFactorFail.Title="Не вдалося запросити ключ трансляції" + Copy.Filters="Копіювати фільтри" Paste.Filters="Вставити фільтри" +BrowserPanelInit.Title="Ініціалізація браузеру..." +BrowserPanelInit.Text="Ініціалізація браузеру, будь ласка, зачекайте..." + BandwidthTest.Region="Регіон" BandwidthTest.Region.US="США" BandwidthTest.Region.EU="Європа" @@ -95,11 +120,9 @@ BandwidthTest.Region.Asia="Азія" BandwidthTest.Region.Other="Інше" Basic.FirstStartup.RunWizard="Бажаєте запустити майстр з автонастроювання? Можна також вручну настроїти параметри, натиснувши кнопку Налаштування в головному вікні." -Basic.FirstStartup.RunWizard.BetaWarning="(Примітка: майстр з автонастроювання наразі в бета-версії)" Basic.FirstStartup.RunWizard.NoClicked="Якщо ви передумаєте, ви можете повторно запустити майстер з автонастроювання у будь-який час з меню Додаткові засоби." Basic.AutoConfig="Майстер з автонастроювання" -Basic.AutoConfig.Beta="Майстер з автонастроювання (бета-версія)" Basic.AutoConfig.ApplySettings="Застосувати Налаштування" Basic.AutoConfig.StartPage="Інформація про використання" Basic.AutoConfig.StartPage.SubTitle="Вкажіть, для чого вам потрібна ця програма" @@ -112,11 +135,17 @@ Basic.AutoConfig.VideoPage.BaseResolution.Display="Дисплей %1 (%2x%3)" Basic.AutoConfig.VideoPage.FPS.UseCurrent="Використовувати поточне (%1)" Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 або 30, але краще 60, коли це можливо" Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 або 30, але краще висока роздільна здатність" -Basic.AutoConfig.VideoPage.CanvasExplanation="Примітка: Роздільна здатність (Полотно), не обов'язково повинно дорівнювати роздільної здатності з якою ви плануєте транслювати або записувати. Роздільну здатність фактичної трансляції/запису може бути зменшено від роздільною здатності полотна задля зменшення використання ресурсів або зменшення вимог до бітрейту." +Basic.AutoConfig.VideoPage.CanvasExplanation="Примітка: Роздільна здатність (Полотно), не обов'язково повинно дорівнювати роздільної здатності з якою ви плануєте транслювати або записувати. Роздільну здатність фактичної трансляції/запису може бути зменшено від роздільною здатності полотна задля зменшення використання ресурсів або зменшення вимог до бітрейту." Basic.AutoConfig.StreamPage="Інформація про Трансляцію" Basic.AutoConfig.StreamPage.SubTitle="Будь ласка, введіть інформацію щодо вашої Трансляції" +Basic.AutoConfig.StreamPage.ConnectAccount="Підключити обліковий запис (за бажанням)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Відключити обліковий запис" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Відключити обліковий запис?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Ці зміни буде застосовано негайно. Ви дійсно бажаєте відключити обліковий запис?" +Basic.AutoConfig.StreamPage.UseStreamKey="Використовувати ключ трансляції" Basic.AutoConfig.StreamPage.Service="Сервіс" Basic.AutoConfig.StreamPage.Service.ShowAll="Показати всі..." +Basic.AutoConfig.StreamPage.Service.Custom="Визначається користувачем..." Basic.AutoConfig.StreamPage.Server="Сервер" Basic.AutoConfig.StreamPage.StreamKey="Ключ трансляції" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Посилання)" @@ -124,7 +153,7 @@ Basic.AutoConfig.StreamPage.PerformBandwidthTest="Оцінка бітрейту Basic.AutoConfig.StreamPage.PreferHardwareEncoding="Віддати перевагу апаратному енкодеру" Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="Апаратне кодування зменшує використання ЦП, але може вимагати більший бітрейт для отримання того ж рівня якості." Basic.AutoConfig.StreamPage.StreamWarning.Title="Попередження, Трансляція" -Basic.AutoConfig.StreamPage.StreamWarning.Text="Тест пропускної здатності буде транслювати випадкові відеодані без аудіо на ваш канал. Якщо ви можете, рекомендується, щоб ви тимчасово вимкнути збереження відео потоків і встановили потік як приватний допоки тест не буде завершено. Продовжити?" +Basic.AutoConfig.StreamPage.StreamWarning.Text="Тест пропускної здатності буде транслювати випадкові відеодані без аудіо на ваш канал. Якщо ви можете, рекомендується, щоб ви тимчасово вимкнути збереження відео потоків і встановили потік як приватний допоки тест не буде завершено. Продовжити?" Basic.AutoConfig.TestPage="Остаточні результати" Basic.AutoConfig.TestPage.SubTitle.Testing="Програма зараз виконує набір тестів, щоб знайти ідеальні налаштування" Basic.AutoConfig.TestPage.SubTitle.Complete="Тестування завершено" @@ -140,11 +169,11 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="Тестування %1x%2 %3 Basic.AutoConfig.TestPage.Result.StreamingEncoder="Енкодер Трансляцій" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Енкодер Записів" Basic.AutoConfig.TestPage.Result.Header="Програма визначила, що дані налаштування є ідеальним для вас:" -Basic.AutoConfig.TestPage.Result.Footer="Щоб використовувати ці параметри, натисніть кнопку Застосувати Налаштування. Щоб переналаштувати майстра та спробувати знов, натисніть кнопку Назад. Можна вручну вказати всі параметри, для цього натисніть кнопку Скасувати та відкрите Налаштування." +Basic.AutoConfig.TestPage.Result.Footer="Щоб використовувати ці параметри, натисніть кнопку Застосувати Налаштування. Щоб переналаштувати майстра та спробувати знов, натисніть кнопку Назад. Можна вручну вказати всі параметри, для цього натисніть кнопку Скасувати та відкрите Налаштування." Basic.Stats="Статистика" Basic.Stats.CPUUsage="Використання ЦП" -Basic.Stats.HDDSpaceAvailable="HDD, вільне місце" +Basic.Stats.HDDSpaceAvailable="Доступно місця на диску" Basic.Stats.MemoryUsage="Використання пам'яті" Basic.Stats.AverageTimeToRender="Середній час побудови кадру" Basic.Stats.SkippedFrames="Кадри пропущені через перевантаження кодування" @@ -160,6 +189,9 @@ Basic.Stats.DroppedFrames="Пропущено кадрів (мережа)" Basic.Stats.MegabytesSent="Загалом до Виводу" Basic.Stats.Bitrate="Бітрейт" +ResetUIWarning.Title="Ви дійсно бажаєте скинути інтерфейс?" +ResetUIWarning.Text="Скидання інтерфейсу користувача приховує всі додаткові вікна. Вам потрібно буде знов увімкнути ці додаткові вікна з меню Вид, якщо ви хочете, щоб вони були видимі.\n\nВи дійсно бажаєте скинути інтерфейс?" + Updater.Title="З'явилось оновлення" Updater.Text="Існує нове оновлення:" Updater.UpdateNow="Оновити зараз" @@ -206,6 +238,9 @@ ConfirmStart.Text="Ви впевнені, що хочете почати тра ConfirmStop.Title="Закінчити трансляцію?" ConfirmStop.Text="Ви впевнені, що хочете закінчити трансляцію?" +ConfirmBWTest.Title="Почати тест пропускної здатності?" +ConfirmBWTest.Text="OBS було настроєно у режимі тестування пропускної здатності. Цей режим дозволяє здійснювати тестування мережі без виводу вашого каналу наживо. Як тільки ви закінчите тестування, вам потрібно буде вимкнути його для того, щоб глядачі змогли побачити вашу трансляцію.\n\nВи бажаєте продовжити?" + ConfirmExit.Title="Вийти з OBS?" ConfirmExit.Text="OBS ще працює. Всі розпочаті трансляції та записи буде припинено. Ви дійсно хочете вийти?" @@ -216,7 +251,8 @@ ConfirmRemove.TextMultiple="Ви впевнені, що хочете видал Output.StartStreamFailed="Не вдалося розпочати трансляцію" Output.StartRecordingFailed="Не вдалося розпочати запис" Output.StartReplayFailed="Не вдалося запустити Буфер Повторів" -Output.StartFailedGeneric="Помилка. Вивід не було розпочато. За додатковою інформацією, будь ласка зверніться до файлу журналу.\n\nПримітка: якщо ви використовуєте NVENC або AMD енкодер, перевірте чи оновлений драйвер відео." +Output.StartFailedGeneric="Помилка. Вивід не було розпочато. За додатковою інформацією, будь ласка зверніться до файлу журналу.\n\nПримітка: якщо ви використовуєте NVENC або AMD енкодер, перевірте чи оновлений драйвер відео." + Output.ConnectFail.Title="Не вдалося підключитися" Output.ConnectFail.BadPath="Шлях або URL-адреса недосяжні. Будь ласка, перевірте налаштування програмного забезпечення." @@ -225,6 +261,7 @@ Output.ConnectFail.InvalidStream="Немає доступу до вказано Output.ConnectFail.Error="Під час зв'язку з сервером відбулася несподівана помилка. Подробиці знаходяться у лог-файлі." Output.ConnectFail.Disconnected="Від'єднаний від серверу." + Output.RecordFail.Title="Не вдалося розпочати запис" Output.RecordFail.Unsupported="Формат виводу на жаль не підтримується або форматом не підтримується більш однієї звукової доріжки. Будь ласка, перевірте налаштування та повторіть спробу." Output.RecordNoSpace.Title="Недостатньо простору на диску" @@ -232,7 +269,7 @@ Output.RecordNoSpace.Msg="На диску недостатньо простор Output.RecordError.Title="Помилка запису" Output.RecordError.Msg="Під час запису відбулася несподівана помилка." Output.ReplayBuffer.NoHotkey.Title="Гарячу клавішу не вказано!" -Output.ReplayBuffer.NoHotkey.Msg="Гарячу клавішу для Буферу Повторів не вказано. Будь ласка, встановіть гарячу клавішу на дію \"Зберегти Повтор\", щоб використовувати її для збереження повторів." +Output.ReplayBuffer.NoHotkey.Msg="Гарячу клавішу для Буферу Повторів не вказано. Будь ласка, встановіть гарячу клавішу на дію \"Зберегти Повтор\", щоб використовувати її для збереження повторів." Output.BadPath.Title="Недійсний шлях до файлу" Output.BadPath.Text="Шлях вказаний для виводу файлу недійсний. Будь ласка, перевірте у налаштуваннях, що шлях було вказано вірно." @@ -241,28 +278,26 @@ LogReturnDialog="Файл журналу успішно завантажено" LogReturnDialog.CopyURL="Копіювати посилання" LogReturnDialog.ErrorUploadingLog="Помилка завантаження файлу журналу" -LicenseAgreement="Ліцензійна угода" -LicenseAgreement.PleaseReview="Будь ласка, ознайомтеся з умовами ліцензії, перш ніж використовувати OBS. Використовуючи цю програму, ви підтверджуєте, що ви прочитали і згодні з умовами GNU General Public License v 2.0. Будь ласка, прокрутіть вниз, щоб побачити весь текст угоди." -LicenseAgreement.ClickIAgreeToContinue="Якщо ви згодні з умовами угоди, натисніть кнопку Я згоден(-а), щоб продовжити. Ви повинні прийняти угоду для використання OBS." -LicenseAgreement.IAgree="Я згоден(-а)" -LicenseAgreement.Exit="Вихід" - Remux.SourceFile="OBS запис" Remux.TargetFile="Кінцевий файл" -Remux.Remux="Ремультиплексація" +Remux.Remux="Ремуксити" +Remux.Stop="Зупинити Ремультіплекс" +Remux.ClearFinished="Прибрати завершені" +Remux.ClearAll="Прибрати всі" Remux.OBSRecording="OBS запис" Remux.FinishedTitle="Ремультиплексацію завершено" Remux.Finished="Запис ремультиплексовано" Remux.FinishedError="Запис ремультиплексовано, але схоже файл неповний" -Remux.SelectRecording="Виберіть OBS запис …" -Remux.SelectTarget="Виберіть кінцевий файл …" +Remux.SelectRecording="Виберіть OBS запис..." +Remux.SelectTarget="Виберіть кінцевий файл..." Remux.FileExistsTitle="Кінцевий файл існує" -Remux.FileExists="Кінцевий файл існує, ви хочете його замінити?" +Remux.FileExists="Наступні кінцеві файли вже існують. Бажаєте їх замінити?" Remux.ExitUnfinishedTitle="Ремультиплексація триває" Remux.ExitUnfinished="Ремультиплексацію не завершено, якщо зупинити зараз, то файл може лишитись пошкодженим.\nВи впевнені, що хочете зупинити ремультиплексацію?" +Remux.HelpText="Перетягніть файли до цього вікна щоб ремультиплексувати їх, або клацніть пусту клітинку з графи \"OBS запис\" щоб обрати файл." UpdateAvailable="Доступне оновлення" -UpdateAvailable.Text="Доступна версія %1.%2.%3. Натисніть тут, щоб завантажити" +UpdateAvailable.Text="Доступна версія %1.%2.%3. Натисніть тут, щоб завантажити" Basic.DesktopDevice1="Системне аудіо" Basic.DesktopDevice2="Системне аудіо 2" @@ -276,11 +311,14 @@ Basic.DisplayCapture="Захват екрану" Basic.Main.PreviewConextMenu.Enable="Увімкнути вікно Перегляду" +Basic.Main.Preview.Disable="Відключити попередній перегляд" + ScaleFiltering="Фільтр масштабування" ScaleFiltering.Point="Ступінчастий" ScaleFiltering.Bilinear="Білінійний" ScaleFiltering.Bicubic="Бікубічний" ScaleFiltering.Lanczos="Ланцош" +ScaleFiltering.Area="Усереднення площ" Deinterlacing="Деінтерлейсинг" Deinterlacing.Discard="Discard" @@ -411,59 +449,61 @@ Basic.Main.Group="Група %1" Basic.Main.GroupItems="Згрупувати вибрані елементи" Basic.Main.Ungroup="Розгрупувати" -Basic.MainMenu.File="&Файл" -Basic.MainMenu.File.Export="&Експорт" -Basic.MainMenu.File.Import="&Імпорт" -Basic.MainMenu.File.ShowRecordings="Показати &Записи" -Basic.MainMenu.File.Remux="Ре&мультиплексація Записів" -Basic.MainMenu.File.Settings="&Налаштування" +Basic.MainMenu.File="Файл (&F)" +Basic.MainMenu.File.Export="Експорт (&E)" +Basic.MainMenu.File.Import="Імпорт (&I)" +Basic.MainMenu.File.ShowRecordings="Показати Записи (&R)" +Basic.MainMenu.File.Remux="Ремультиплексація Записів (&M)" +Basic.MainMenu.File.Settings="Налаштування (&S)" Basic.MainMenu.File.ShowSettingsFolder="Показати папку Налаштувань" Basic.MainMenu.File.ShowProfileFolder="Показати папку Профілю" -Basic.MainMenu.AlwaysOnTop="&Поверх всіх вікон" -Basic.MainMenu.File.Exit="В&ихід" +Basic.MainMenu.AlwaysOnTop="Поверх всіх вікон (&A)" +Basic.MainMenu.File.Exit="Вихід (&X)" -Basic.MainMenu.Edit="&Редагування" -Basic.MainMenu.Edit.Undo="&Відмінити" -Basic.MainMenu.Edit.Redo="Від&новити" -Basic.MainMenu.Edit.UndoAction="&Відмінити $1" -Basic.MainMenu.Edit.RedoAction="Від&новити $1" -Basic.MainMenu.Edit.LockPreview="&Заблокувати вікно Перегляду" -Basic.MainMenu.Edit.Scale="&Масштабувати вікно Перегляду" +Basic.MainMenu.Edit="Редагування (&E)" +Basic.MainMenu.Edit.Undo="Відмінити (&U)" +Basic.MainMenu.Edit.Redo="Відновити (&R)" +Basic.MainMenu.Edit.UndoAction="Відмінити $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Відновити $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Заблокувати вікно Перегляду (&L)" +Basic.MainMenu.Edit.Scale="Масштабувати вікно Перегляду (&S)" Basic.MainMenu.Edit.Scale.Window="В розмір вікна" Basic.MainMenu.Edit.Scale.Canvas="Як Полотно (%1x%2)" Basic.MainMenu.Edit.Scale.Output="Як Вивід (%1x%2)" -Basic.MainMenu.Edit.Transform="&Розміри" -Basic.MainMenu.Edit.Transform.EditTransform="Редагуват&и Розміри..." +Basic.MainMenu.Edit.Transform="Розміри (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Редагувати Розміри... (&E)" Basic.MainMenu.Edit.Transform.CopyTransform="Копіювати Розміри" Basic.MainMenu.Edit.Transform.PasteTransform="Вставити Розміри" -Basic.MainMenu.Edit.Transform.ResetTransform="Розміри за &замовчуванням" +Basic.MainMenu.Edit.Transform.ResetTransform="Розміри за замовчуванням (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Повернути на 90 За годинниковою стрілкою" Basic.MainMenu.Edit.Transform.Rotate90CCW="Повернути на 90 Проти годинникової стрілки" Basic.MainMenu.Edit.Transform.Rotate180="Повернути на 180 градусів" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Віддзеркалити по &горизонталі" -Basic.MainMenu.Edit.Transform.FlipVertical="Віддзеркалити по &вертикалі" -Basic.MainMenu.Edit.Transform.FitToScreen="&Умістити на екрані" -Basic.MainMenu.Edit.Transform.StretchToScreen="Р&озтягнути на весь екран" -Basic.MainMenu.Edit.Transform.CenterToScreen="По &центру екрана" -Basic.MainMenu.Edit.Order="&Упорядкувати" -Basic.MainMenu.Edit.Order.MoveUp="&Нагору" -Basic.MainMenu.Edit.Order.MoveDown="&Донизу" -Basic.MainMenu.Edit.Order.MoveToTop="До &верха" -Basic.MainMenu.Edit.Order.MoveToBottom="До ни&зу" -Basic.MainMenu.Edit.AdvAudio="Р&озширені Налаштування Аудіо" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Віддзеркалити по горизонталі (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Віддзеркалити по вертикалі (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Умістити на екрані (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Розтягнути на весь екран (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="По центру екрана (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Центрувати по вертикалі" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Центрувати по горизонталі" +Basic.MainMenu.Edit.Order="Упорядкувати (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Нагору (&U)" +Basic.MainMenu.Edit.Order.MoveDown="Донизу (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="До верха (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="До низу (&B)" +Basic.MainMenu.Edit.AdvAudio="Розширені Налаштування Аудіо (&A)" -Basic.MainMenu.View="&Вид" -Basic.MainMenu.View.Toolbars="&Панелі інструментів" +Basic.MainMenu.View="Вид (&V)" +Basic.MainMenu.View.Toolbars="Панелі інструментів (&T)" Basic.MainMenu.View.Docks="Панелі інтерфейсу" Basic.MainMenu.View.Docks.ResetUI="Скинути інтерфейс" Basic.MainMenu.View.Docks.LockUI="Зафіксувати інтерфейс" -Basic.MainMenu.View.Toolbars.Listboxes="У &Списках" -Basic.MainMenu.View.SceneTransitions="В&ідео-переходи між Сценами" -Basic.MainMenu.View.StatusBar="Панель с&тану" +Basic.MainMenu.View.Toolbars.Listboxes="У Списках (&L)" +Basic.MainMenu.View.SceneTransitions="Відео-переходи між Сценами (&C)" +Basic.MainMenu.View.StatusBar="Панель стану (&S)" Basic.MainMenu.View.Fullscreen.Interface="Повноекранний режим" -Basic.MainMenu.SceneCollection="&Набір Сцен" -Basic.MainMenu.Profile="&Профіль" +Basic.MainMenu.SceneCollection="Набір Сцен (&S)" +Basic.MainMenu.Profile="Профіль (&P)" Basic.MainMenu.Profile.Import="Імпорт Профілю" Basic.MainMenu.Profile.Export="Експорт Профілю" Basic.MainMenu.SceneCollection.Import="Імпорт Набору Сцен" @@ -471,25 +511,26 @@ Basic.MainMenu.SceneCollection.Export="Експорт Набору Сцен" Basic.MainMenu.Profile.Exists="Профіль вже існує" Basic.MainMenu.SceneCollection.Exists="Набір Сцен вже існує" -Basic.MainMenu.Tools="Додаткові &засоби" +Basic.MainMenu.Tools="Додаткові засоби (&T)" -Basic.MainMenu.Help="&Довідка" -Basic.MainMenu.Help.HelpPortal="&Портал з допомоги" -Basic.MainMenu.Help.Website="Відвідати &сайт" -Basic.MainMenu.Help.Discord="Приє&днатися до серверу Discord" -Basic.MainMenu.Help.Logs="&Файли журналів" -Basic.MainMenu.Help.Logs.ShowLogs="&Показати файли журналів" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Завантажити на сервер По&точний журнал" -Basic.MainMenu.Help.Logs.UploadLastLog="Завантажити на сервер &Останній журнал" -Basic.MainMenu.Help.Logs.ViewCurrentLog="П&ереглянути поточний журнал" +Basic.MainMenu.Help="Довідка (&H)" +Basic.MainMenu.Help.HelpPortal="Портал з допомоги (&P)" +Basic.MainMenu.Help.Website="Відвідати сайт (&W)" +Basic.MainMenu.Help.Discord="Приєднатися до серверу &Discord" +Basic.MainMenu.Help.Logs="Файли журналів (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Показати файли журналів (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Завантажити на сервер Поточний журнал (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Завантажити на сервер Останній журнал (&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Переглянути поточний журнал (&V)" Basic.MainMenu.Help.CheckForUpdates="Перевірити оновлення" -Basic.MainMenu.Help.CrashLogs="Звіти про &збої" -Basic.MainMenu.Help.CrashLogs.ShowLogs="П&оказати звіти про збої" -Basic.MainMenu.Help.CrashLogs.UploadLastLog="Заванта&жити на сервер останній звіт про збій" +Basic.MainMenu.Help.CrashLogs="Звіти про збої (&R)" +Basic.MainMenu.Help.CrashLogs.ShowLogs="Показати звіти про збої (&S)" +Basic.MainMenu.Help.CrashLogs.UploadLastLog="Завантажити на сервер останній звіт про збій (&L)" +Basic.MainMenu.Help.About="Про програму (&A)" Basic.Settings.ProgramRestart="Програма потребує перезапуску, щоб нові налаштування набрали сили." Basic.Settings.ConfirmTitle="Підтвердження змін" -Basic.Settings.Confirm="Є незбережені зміни. Зберегти ці зміни?" +Basic.Settings.Confirm="Є незбережені зміни. Зберегти ці зміни?" Basic.Settings.General="Загальні" Basic.Settings.General.Theme="Тема" @@ -504,7 +545,7 @@ Basic.Settings.General.ProjectorAlwaysOnTop="Режим Проектор пок Basic.Settings.General.Snapping="Прив'язка та вирівнювання" Basic.Settings.General.ScreenSnapping="Примагнітити Джерела до краю екрана" Basic.Settings.General.CenterSnapping="Примагнітити Джерела до центру по вертикалі та горизонталі" -Basic.Settings.General.SourceSnapping="Примагнітити Джерело до інших джерел" +Basic.Settings.General.SourceSnapping="Примагнітити Джерела до інших джерел" Basic.Settings.General.SnapDistance="Чутливість примагничування" Basic.Settings.General.RecordWhenStreaming="Автоматично почати запис з початком трансляції" Basic.Settings.General.KeepRecordingWhenStreamStops="Не припиняти запис, якщо трансляцію закінчено" @@ -514,8 +555,13 @@ Basic.Settings.General.SysTray="Системний трей" Basic.Settings.General.SysTrayWhenStarted="Згорнути програму до трею при запуску" Basic.Settings.General.SystemTrayHideMinimize="Згортати в трей замість того, щоб мінімізувати до панелі завдань" Basic.Settings.General.SaveProjectors="Зберегти налаштування режиму Проектор при виході" +Basic.Settings.General.Preview="вікно Перегляду" +Basic.Settings.General.OverflowHidden="Не показувати надлишок з джерел за межами робочої зони" +Basic.Settings.General.OverflowAlwaysVisible="Завжди показувати надлишок з джерел за межами робочої зони" +Basic.Settings.General.OverflowSelectionHidden="Показувати надлишок за межами робочої зони навіть для прихованих джерел" Basic.Settings.General.SwitchOnDoubleClick="Відео-перехід до сцени за подвійним клацанням" Basic.Settings.General.StudioPortraitLayout="Увімкнути портретне/вертикальне компонування" +Basic.Settings.General.TogglePreviewProgramLabels="Показати написи: вікно Перегляду/Програма наживо" Basic.Settings.General.Multiview="Мульти-перегляд" Basic.Settings.General.Multiview.MouseSwitch="Переходити до сцени за клацанням миші" Basic.Settings.General.Multiview.DrawSourceNames="Показувати назви сцен" @@ -529,6 +575,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="Горизонт Basic.Settings.Stream="Трансляція" Basic.Settings.Stream.StreamType="Тип Трансляції" +Basic.Settings.Stream.Custom.UseAuthentication="Використовувати автентифікацію" +Basic.Settings.Stream.Custom.Username="Логін" +Basic.Settings.Stream.Custom.Password="Пароль" +Basic.Settings.Stream.BandwidthTestMode="Увімкнути тест пропускної здатності" Basic.Settings.Output="Вивід" Basic.Settings.Output.Format="Формат запису" @@ -554,13 +604,12 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Так само як тр Basic.Settings.Output.Simple.RecordingQuality.Small="Висока якість, середній розмір файлу" Basic.Settings.Output.Simple.RecordingQuality.HQ="Якість майже без втрат, великий розмір файлу" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Без втрат якості, надзвичайно великий розмір файлу" -Basic.Settings.Output.Simple.Warn.VideoBitrate="Увага! Буде встановлено відео бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." -Basic.Settings.Output.Simple.Warn.AudioBitrate="Увага! Буде встановлено аудіо бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." +Basic.Settings.Output.Simple.Warn.VideoBitrate="Увага! Буде встановлено відео бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." +Basic.Settings.Output.Simple.Warn.AudioBitrate="Увага! Буде встановлено аудіо бітрейт трансляції %1, що є верхней межою для обраного сервісу трансляцій. Якщо ви хочете встановити бітрейт вищий за %1, то увімкніть Додаткові Налаштування Енкодера та зніміть прапорець \"Застосувати примусовий бітрейт з сервісу трансляцій\"." Basic.Settings.Output.Simple.Warn.Encoder="Попередження: Запис програмним енкодером з якістю не \"Так само як трансляція\", здійснює додаткове навантаження на ЦП при використовуванні трансляції і запису одночасно." -Basic.Settings.Output.Simple.Warn.Lossless="Попередження: Відео Без втрат якості генерує надзвичайно великі розміри файлів! Воно може використовувати понад 7 гігабайт дискового простору на хвилину при високих роздільній здатності зображення та частоти кадрів. Відео Без втрат якості не рекомендується для довгого запису, тільки якщо у вас є дуже великий обсяг вільного дискового простору." +Basic.Settings.Output.Simple.Warn.Lossless="Попередження: Відео Без втрат якості генерує надзвичайно великі розміри файлів! Воно може використовувати понад 7 гігабайт дискового простору на хвилину при високих роздільній здатності зображення та частоти кадрів. Відео Без втрат якості не рекомендується для довгого запису, тільки якщо у вас є дуже великий обсяг вільного дискового простору." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Ви впевнені, що ви хочете використовувати якість \"Без втрат якості\"?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Якість Без втрат, попередження!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Попередження: Не можна використовувати кілька окремих енкодерів QSV одночасно для запису і трансляції. Якщо ви хочете транслювати і записувати одночасно, будь ласка, змінить або енкодер запису, або енкодер трансляції на інший." Basic.Settings.Output.Simple.Encoder.Software="Програмний (x264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Апаратний (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Апаратний (AMD)" @@ -572,7 +621,7 @@ Basic.Settings.Output.Reconnect="Поновити зв'язок автомати Basic.Settings.Output.RetryDelay="Затримка спроби (секунди)" Basic.Settings.Output.MaxRetries="Кількість спроб" Basic.Settings.Output.Advanced="Увімкнути Додаткові Налаштування Енкодера" -Basic.Settings.Output.EncoderPreset="Профіль енкодера (вище = менше ЦП)" +Basic.Settings.Output.EncoderPreset="Шаблон до енкодера" Basic.Settings.Output.CustomEncoderSettings="Енкодер, параметри користувача" Basic.Settings.Output.CustomMuxerSettings="Мультиплексор, параметри користувача" Basic.Settings.Output.NoSpaceFileName="Генерувати ім'я файла без Пробілів" @@ -634,8 +683,8 @@ Basic.Settings.Video.FPSFraction="Кадр/сек, дробові значенн Basic.Settings.Video.Numerator="Чисельник" Basic.Settings.Video.Denominator="Знаменник" Basic.Settings.Video.Renderer="Візуалізація" -Basic.Settings.Video.InvalidResolution="Неприпустиме значення роздільної здатності. Повинно бути [ширина]x[висота] (тобто, 1920x1080)" -Basic.Settings.Video.CurrentlyActive="Вивід відео в даний час активний. Будь ласка, зупинить весь вивід відео, щоб змінити настройки відео." +Basic.Settings.Video.InvalidResolution="Неприпустиме значення роздільної здатності. Повинно бути [ширина]x[висота] (тобто, 1920x1080)" +Basic.Settings.Video.CurrentlyActive="Вивід відео в даний час активний. Будь ласка, зупинить весь вивід відео, щоб змінити настройки відео." Basic.Settings.Video.DisableAero="Вимкнути Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Білінійний (найшвидший, але розмито, якщо масштабувати)" @@ -645,7 +694,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Ланцош (чітке масш Basic.Settings.Audio="Аудіо" Basic.Settings.Audio.SampleRate="Частота дискретизації" Basic.Settings.Audio.Channels="Канали" -Basic.Settings.Audio.MeterDecayRate="Швидкість спаду індикатору звуку" +Basic.Settings.Audio.Meters="Індикатори" +Basic.Settings.Audio.MeterDecayRate="Швидкість спаду" Basic.Settings.Audio.MeterDecayRate.Fast="Швидко" Basic.Settings.Audio.MeterDecayRate.Medium="Середньо (PPM типу I)" Basic.Settings.Audio.MeterDecayRate.Slow="Повільно (PPM типу II)" @@ -653,19 +703,22 @@ Basic.Settings.Audio.PeakMeterType="Тип вимірювача пікових Basic.Settings.Audio.PeakMeterType.SamplePeak="З точністю до вибірки" Basic.Settings.Audio.PeakMeterType.TruePeak="Істинно-піковий (більше навантаження на ЦП)" Basic.Settings.Audio.MultiChannelWarning.Enabled="ПОПЕРЕДЖЕННЯ: Увімкнуто об'ємний звук." -Basic.Settings.Audio.MultichannelWarning="Якщо робите трансляції, перевірте чи підтримує ваш сервіс трансляцій об'ємний звук на вході та виході. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast - це приклади сервісів де об'ємний звук цілком підтримується. Навпаки, Facebook Live і YouTube Live обидва підтримують вхідний об'ємний звук, але Facebook Live мікшує його до стерео, а YouTube Live відтворює лише два канали.\n\nАудіо фільтри самої OBS сумісні з об'ємним звуком, хоча підтримку VST плагінами не гарантовано." +Basic.Settings.Audio.MultichannelWarning="Якщо робите трансляції, перевірте чи підтримує ваш сервіс трансляцій об'ємний звук на вході та виході. Twitch, Facebook 360 Live, Mixer RTMP, Smashcast - це приклади сервісів де об'ємний звук цілком підтримується. Навпаки, Facebook Live і YouTube Live обидва підтримують вхідний об'ємний звук, але Facebook Live мікшує його до стерео, а YouTube Live відтворює лише два канали.\n\nАудіо фільтри самої OBS сумісні з об'ємним звуком, хоча підтримку VST плагінами не гарантовано." Basic.Settings.Audio.MultichannelWarning.Title="Увімкнути об'ємний звук для виводу аудіо?" Basic.Settings.Audio.MultichannelWarning.Confirm="Ви справді бажаєте увімкнути об'ємний звук для виводу аудіо?" -Basic.Settings.Audio.DesktopDevice="Системний аудіопристрій" -Basic.Settings.Audio.DesktopDevice2="Системний аудіопристрій 2" -Basic.Settings.Audio.AuxDevice="Мікрофон/допоміжні аудіопристрої" -Basic.Settings.Audio.AuxDevice2="Мікрофон/допоміжні аудіопристрої 2" -Basic.Settings.Audio.AuxDevice3="Мікрофон/допоміжні аудіопристрої 3" +Basic.Settings.Audio.Devices="Пристрої" +Basic.Settings.Audio.DesktopDevice="Системне аудіо" +Basic.Settings.Audio.DesktopDevice2="Системне аудіо 2" +Basic.Settings.Audio.AuxDevice="Мікрофон/допоміжне аудіо" +Basic.Settings.Audio.AuxDevice2="Мікрофон/допоміжне аудіо 2" +Basic.Settings.Audio.AuxDevice3="Мікрофон/допоміжне аудіо 3" +Basic.Settings.Audio.AuxDevice4="Мікрофон/допоміжне аудіо 4" Basic.Settings.Audio.EnablePushToMute="Увімкнути Натисніть-щоб-відключити" Basic.Settings.Audio.PushToMuteDelay="Натисніть-щоб-відключити, затримка" Basic.Settings.Audio.EnablePushToTalk="Увімкнути Натисніть-щоб-говорити" Basic.Settings.Audio.PushToTalkDelay="Натисніть-щоб-говорити, затримка" Basic.Settings.Audio.UnknownAudioDevice="[Пристрій не підключено або недоступний]" +Basic.Settings.Audio.Disabled="Вимкнено" Basic.Settings.Advanced="Розширені" Basic.Settings.Advanced.General.ProcessPriority="Пріоритет процесу" @@ -674,11 +727,9 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Вище норма Basic.Settings.Advanced.General.ProcessPriority.Normal="Нормальний" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Нижче нормального" Basic.Settings.Advanced.General.ProcessPriority.Idle="Очікування" -Basic.Settings.Advanced.FormatWarning="Попередження: Формати кольору, які відрізняються від NV12, в першу чергу призначені для запису, і не рекомендуються для трансляцій. Трансляція може додатково навантажити ЦП через перетворення форматів." +Basic.Settings.Advanced.FormatWarning="Попередження: Формати кольору, які відрізняються від NV12, в першу чергу призначені для запису, і не рекомендуються для трансляцій. Трансляція може додатково навантажити ЦП через перетворення форматів." Basic.Settings.Advanced.Audio.BufferingTime="Розмір аудіо буфера, (мс)" Basic.Settings.Advanced.Video.ColorFormat="Формат кольору" -Basic.Settings.Advanced.Video.ColorSpace="YUV, колірний простір" -Basic.Settings.Advanced.Video.ColorRange="YUV, колірний діапазон" Basic.Settings.Advanced.Video.ColorRange.Partial="Частковий" Basic.Settings.Advanced.Video.ColorRange.Full="Повний" Basic.Settings.Advanced.Audio.MonitoringDevice="Пристрій Тестування Аудіо (на слух)" @@ -693,12 +744,13 @@ Basic.Settings.Advanced.Network.BindToIP="Прив'язати до адапте Basic.Settings.Advanced.Network.EnableNewSocketLoop="Увімкнути новий мережевий код" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Режим з низькою затримкою" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="Відключати гарячі клавіші, коли головне вікно знаходиться у фокусі" +Basic.Settings.Advanced.AutoRemux="Запускати автоматичну Ремультиплексацію до .mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(записувати як .mkv)" Basic.AdvAudio="Розширені Налаштування Аудіо" Basic.AdvAudio.Name="Назва" -Basic.AdvAudio.Volume="Гучність (%)" Basic.AdvAudio.Mono="Мікшувати до псевдо-Моно" -Basic.AdvAudio.Panning="Баланс" +Basic.AdvAudio.Balance="Баланс" Basic.AdvAudio.SyncOffset="Зсув синхронізації (мс)" Basic.AdvAudio.Monitoring="Тестування Аудіо (на слух)" Basic.AdvAudio.Monitoring.None="Тест вимкнено" @@ -708,6 +760,7 @@ Basic.AdvAudio.AudioTracks="Доріжки" Basic.Settings.Hotkeys="Гарячі клавіші" Basic.Settings.Hotkeys.Pair="Однакові комбінації клавіш задані до '%1' діють як перемикач" +Basic.Settings.Hotkeys.Filter="Фільтр" Basic.Hotkeys.SelectScene="Перейти до сцени" @@ -751,6 +804,7 @@ Hotkeys.AppleKeypadSubtract="- (Keypad)" Hotkeys.AppleKeypadDecimal=". (Keypad)" Hotkeys.AppleKeypadEqual="= (Keypad)" Hotkeys.MouseButton="Mouse %1" +Hotkeys.Escape="Esc" Mute="Вимкнути звук" Unmute="Увімкнути звук" @@ -762,7 +816,7 @@ SceneItemHide="Приховати '%1'" OutputWarnings.NoTracksSelected="Ви повинні вибрати хоча б одну аудіо-доріжку" OutputWarnings.MultiTrackRecording="Попередження: Певні формати (наприклад, FLV) не підтримують кілька треків на запис" -OutputWarnings.MP4Recording="Попередження: Запис в MP4 може стати невиправно пошкодженим, якщо файл не буде завершено (наприклад, в результаті BSOD, втрати живлення і т.п.). Якщо ви хочете, мати запис декількох звукових доріжок спробуйте використати MKV та зробіть ремультиплексацію запису до mp4 після того, як запис буде закінчено (Файл->Ремультиплексація Записів)" +OutputWarnings.MP4Recording="Попередження: Запис в MP4/MOV може стати невиправно пошкодженим, якщо файл не буде завершено (наприклад, в результаті BSOD, втрати живлення і т.п.). Якщо ви хочете, мати запис декількох звукових доріжок спробуйте використати MKV та зробіть ремультиплексацію запису до MP4/MOV після того, як запис буде закінчено (Файл → Ремультиплексація Записів)" FinalScene.Title="Видалення сцени" FinalScene.Text="Повинна бути принаймні одна сцена." @@ -770,9 +824,23 @@ FinalScene.Text="Повинна бути принаймні одна сцена. NoSources.Title="Немає Джерел" NoSources.Text="Схоже, що ви не ще додали будь-якого відео Джерела. Таким чином на виводі буде лише порожній екран. Ви справді бажаєте це зробити?" NoSources.Text.AddSource="Ви можете будь-коли додати Джерела, натиснувши на значок (+) під панеллю Джерела в головному вікні." +NoSources.Label="У вас немає джерел.\nКлацніть кнопку + , що нижче,\nчи клацніть правою та додайте нове." ChangeBG="Позначити кольором" CustomColor="Особливий колір" BrowserSource.EnableHardwareAcceleration="Задіяти апаратне прискорення для джерела 'Браузер'" +About="Про програму" +About.Info="OBS Studio - це програмне забезпечення для відео запису та трансляцій наживо з відкритим вихідним кодом." +About.Donate="Зробити внесок" +About.GetInvolved="Взяти участь" +About.Authors="Автори" +About.License="Ліцензія" +About.Contribute="Підтримати проект OBS" + +ResizeOutputSizeOfSource="Встановити (Вивід) за розміром Джерела" +ResizeOutputSizeOfSource.Text="Параметри: Роздільна здатність (Полотно) та Роздільна здатність (Вивід), буде встановлено у розмір обраного Джерела." +ResizeOutputSizeOfSource.Continue="Ви хочете продовжити?" + + diff --git a/UI/data/locale/ur-PK.ini b/UI/data/locale/ur-PK.ini index d0afe8d..047a3b5 100644 --- a/UI/data/locale/ur-PK.ini +++ b/UI/data/locale/ur-PK.ini @@ -51,6 +51,44 @@ DisableOSXVSync="OSX V-Sync کو غیر فعال کریں" ResetOSXVSyncOnExit="باہر نکلیں پرOSX V-Sync ری سیٹ کریں" HighResourceUsage="انکوڈنگ زیادہ اوورلوڈ! ویڈیو ترتیبات کو تبدیل کرنے یا تیزی سے انکوڈنگ کے پیش سیٹ کا استعمال کرتے ہوئے غور کریں." Transition="منتقلی" +Left="بائیں" +Right="دائیں" +Top="اوپر" +Bottom="نیچے" +Reset="ری سیٹ کریں" +Hours="گھنٹے" +Minutes="منٹ" +Seconds="سیکنڈز" +Import="درآمد کریں" +Export="برآمد کریں" +Copy="کاپی" +Paste="پیسٹ کریں" +PasteDuplicate="جوڑیں (مثنی)" +Next="اگلا" +Back="واپس" +Defaults="طے شدہ" +None="کوئی بھی نہیں" +StudioMode.Program="پروگرام" +Group="گروپس" +DoNotShowAgain="دوبارہ مت دکھائیں" + +AlreadyRunning.LaunchAnyway="ویسے بھی شروع" + + +Auth.Authing.Title="توثیق کر رہا ہے..." +Auth.AuthFailure.Title="تصدیق کی ناکامی" +Auth.Chat="گفتگو" + + + +BandwidthTest.Region.EU="یورپ" +BandwidthTest.Region.Asia="ایشیا" +BandwidthTest.Region.Other="دیگر" + + +Basic.AutoConfig.VideoPage="ویڈیو سیٹنگز" + + diff --git a/UI/data/locale/vi-VN.ini b/UI/data/locale/vi-VN.ini index 763874d..8b8b084 100644 --- a/UI/data/locale/vi-VN.ini +++ b/UI/data/locale/vi-VN.ini @@ -28,10 +28,16 @@ Browse="Chọn đường dẫn" Mono="Âm thanh đơn" Stereo="Âm thanh nổi" DroppedFrames="Khung bị rớt %1 (%2%)" +StudioProgramProjector="Fullscreen Projector (Program)" PreviewProjector="Toàn màn hình (xem trước)" SceneProjector="Toàn màn hình (cảnh)" SourceProjector="Toàn màn hình (nguồn)" +StudioProgramWindow="Hình chiếu dạng cửa sổ (đầu ra cuối)" +PreviewWindow="Hình chiếu dạng cửa sổ (xem trước)" +SceneWindow="Hình chiếu dạng cửa sổ (phần cảnh)" +SourceWindow="Hình chiếu dạng cửa sổ (phần nguồn)" MultiviewProjector="Giao diện nhiều lớp (Toàn màn hình)" +MultiviewWindowed="Đa góc nhìn (chỉ cửa sổ)" Clear="Xóa" Revert="Phục hồi" Show="Hiện" @@ -43,7 +49,7 @@ Duplicate="Tạo bản sao" Enable="Bật" DisableOSXVSync="Tắt OSX V-Sync" ResetOSXVSyncOnExit="Đặt lại OSX V-Sync khi Thoát" -HighResourceUsage="Bộ mã hóa bị quá tải! Hãy xem xét giảm chất lượng video hoặc sử dụng bộ mã hóa nhanh hơn." +HighResourceUsage="Bộ mã hóa bị quá tải! Hãy xem xét giảm chất lượng video hoặc sử dụng bộ mã hóa nhanh hơn." Transition="Chuyển cảnh" QuickTransitions="C. cảnh nhanh" Left="Trái" @@ -66,30 +72,50 @@ RemuxRecordings="Remux video" Next="Tiếp tục" Back="Quay lại" Defaults="Mặc định" +TransitionOverride="Ghi đè chuyển tiếp" None="Không có" StudioMode.Preview="Xem trước" StudioMode.Program="Chương trình" +ShowInMultiview="Xem trong Đa góc nhìn" +VerticalLayout="Bố cục dọc" Group="Nhóm" +DoNotShowAgain="Không hiện lại thông báo nữa" +Default="(Mặc định)" +Calculating="Đang tính toán..." AlreadyRunning.Title="OBS đã chạy" -AlreadyRunning.Text="OBS đã chạy rồi! Trừ khi bạn muốn làm điều này, xin vui lòng tắt mọi chương trình hiện tại của OBS trước khi cố gắng chạy một chương trình mới. Nếu bạn có OBS thiết lập để thu nhỏ trên khay hệ thống, xin vui lòng kiểm tra để xem nếu nó vẫn đang chạy hay không." +AlreadyRunning.Text="OBS đã chạy rồi! Trừ khi bạn muốn làm điều này, xin vui lòng tắt mọi chương trình hiện tại của OBS trước khi cố gắng chạy một chương trình mới. Nếu bạn có OBS thiết lập để thu nhỏ trên khay hệ thống, xin vui lòng kiểm tra để xem nếu nó vẫn đang chạy hay không." AlreadyRunning.LaunchAnyway="Khởi động luôn" +DockCloseWarning.Title="Đóng cửa sổ gắn đế được" +DockCloseWarning.Text="Bạn vừa đóng một cửa số gắn đế được. Nếu bạn muốn hiển thị lại lần nữa, sử dụng trình đơn Hiển thị → Thanh đế trên thanh trình đơn." + +Auth.Authing.Title="Đang xác thực..." +Auth.AuthFailure.Title="Xác thực không thành công" +Auth.InvalidScope.Title="Bắt buộc phải xác thực" +Auth.LoadingChannel.Title="Đang tải thông tin kênh..." +Auth.ChannelFailure.Title="Bị lỗi khi nạp kênh" +Auth.Chat="Tán gẫu" +Auth.StreamInfo="Thông tin luồng phát" +TwitchAuth.Stats="Thống kê Twitch" +TwitchAuth.TwoFactorFail.Title="Không thể truy vấn khóa luồng" + Copy.Filters="Sao chép các bộ lọc" Paste.Filters="Dán các bộ lọc" +BrowserPanelInit.Title="Đang khởi chạy trình duyệt..." +BrowserPanelInit.Text="Đang khởi chạy trình duyệt, xin vui lòng chờ..." + BandwidthTest.Region="Khu vực" BandwidthTest.Region.US="Hoa Kỳ" BandwidthTest.Region.EU="Châu Âu" BandwidthTest.Region.Asia="Châu Á" BandwidthTest.Region.Other="Khác" -Basic.FirstStartup.RunWizard="Bạn có muốn chạy trình cấu hình tự động? Bạn có thể cấu hình bằng tay cài đặt của bạn bằng cách nhấn vào nút Cài đặt trong cửa sổ chính." -Basic.FirstStartup.RunWizard.BetaWarning="(Lưu ý: Trình cấu hình tự động đang trong phiên bản beta)" +Basic.FirstStartup.RunWizard="Bạn có muốn chạy trình cấu hình tự động? Bạn có thể cấu hình bằng tay cài đặt của bạn bằng cách nhấn vào nút Cài đặt trong cửa sổ chính." Basic.FirstStartup.RunWizard.NoClicked="Nếu bạn thay đổi, bạn có thể chạy trình cấu hình tự động bất kỳ lúc nào từ menu Công cụ." Basic.AutoConfig="Trình cấu hình tự động" -Basic.AutoConfig.Beta="Trình cấu hình tự động (Beta)" Basic.AutoConfig.ApplySettings="Áp dụng các thiết lập" Basic.AutoConfig.StartPage="Thông tin sử dụng" Basic.AutoConfig.StartPage.SubTitle="Xác định bạn muốn sử dụng chương trình cho mục đích gì" @@ -104,8 +130,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 hoặc 30, nhưng ưu tiên ch Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 hoặc 30, nhưng ưu tiên độ phân giải cao" Basic.AutoConfig.StreamPage="Thông tin stream" Basic.AutoConfig.StreamPage.SubTitle="Vui lòng nhập thông tin máy chủ stream của bạn" +Basic.AutoConfig.StreamPage.ConnectAccount="Kết nối tài khoản (tùy chọn)" +Basic.AutoConfig.StreamPage.DisconnectAccount="Ngắt kết nối tài khoản" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="Ngắt kết nối tài khoản?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="Thay đổi này sẽ được áp dụng ngay lập tức. Bạn có chắc là bạn muốn ngắt kết nối tài khoản của bạn?" +Basic.AutoConfig.StreamPage.UseStreamKey="Dùng khóa luồng phát" Basic.AutoConfig.StreamPage.Service="Dịch vụ" Basic.AutoConfig.StreamPage.Service.ShowAll="Hiện tất cả..." +Basic.AutoConfig.StreamPage.Service.Custom="Tự chọn..." Basic.AutoConfig.StreamPage.Server="Máy chủ" Basic.AutoConfig.StreamPage.StreamKey="Khóa stream" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(Liên kết)" @@ -127,11 +159,11 @@ Basic.AutoConfig.TestPage.TestingRes.Resolution="Thử nghiệm %1x%2 %3 FPS..." Basic.AutoConfig.TestPage.Result.StreamingEncoder="Mã hóa streaming" Basic.AutoConfig.TestPage.Result.RecordingEncoder="Mã hóa quay video" Basic.AutoConfig.TestPage.Result.Header="Chương trình đã xác định được cài đặt lý tưởng nhất dành cho bạn:" -Basic.AutoConfig.TestPage.Result.Footer="Để sử dụng các thiết lập này, nhấp vào Áp dụng cài đặt. Để cấu hình lại và thử lại, bấm Lùi lại. Để cấu hình thiết lập bằng tay, bấm Hủy bỏ và mở Cài đặt." +Basic.AutoConfig.TestPage.Result.Footer="Để sử dụng các thiết lập này, nhấp vào Áp dụng cài đặt. Để cấu hình lại và thử lại, bấm Lùi lại. Để cấu hình thiết lập bằng tay, bấm Hủy bỏ và mở Cài đặt." Basic.Stats="Thống kê" Basic.Stats.CPUUsage="Sử dụng CPU" -Basic.Stats.HDDSpaceAvailable="Không gian ổ cứng còn trống" +Basic.Stats.HDDSpaceAvailable="Không gian đĩa còn trống" Basic.Stats.MemoryUsage="Bộ nhớ đã sử dụng" Basic.Stats.AverageTimeToRender="Thời gian trung bình để vẽ hình" Basic.Stats.SkippedFrames="Khung hình bị bỏ qua do mã hóa bị lag" @@ -147,6 +179,9 @@ Basic.Stats.DroppedFrames="Khung hình bị rớt (Mạng)" Basic.Stats.MegabytesSent="Tổng dung lượng" Basic.Stats.Bitrate="Bitrate" +ResetUIWarning.Title="Bạn có chắc bạn muốn thiết lập lại giao diện người dùng?" +ResetUIWarning.Text="Việc đặt lại giao diện người dùng (UI) sẽ ẩn các thanh đế nâng cao. Bạn cần hiện lại chúng từ trình đơn Hiển thị nếu muốn nhìn thấy chúng.\n\nBạn có chắc là muốn đặt lại UI không?" + Updater.Title="Có bản cập nhật mới" Updater.Text="Có sẵn một bản cập nhật mới:" Updater.UpdateNow="Cập nhật ngay" @@ -168,6 +203,7 @@ QuickTransitions.HotkeyName="C. cảnh nhanh: %1" Basic.AddTransition="Thêm cấu hình chuyển cảnh" Basic.RemoveTransition="Xóa cấu hình chuyển cảnh" +Basic.TransitionProperties="Thuộc tính chuyển tiếp" Basic.SceneTransitions="Chuyển cảnh" Basic.TransitionDuration="Thời gian" Basic.TogglePreviewProgramMode="Chế độ Studio" @@ -190,8 +226,10 @@ ConfirmStart.Text="Bạn có chắc muốn bắt đầu stream?" ConfirmStop.Title="Ngừng Stream?" ConfirmStop.Text="Bạn có chắc muốn dừng stream?" +ConfirmBWTest.Title="Bắt đầu kiểm tra băng thông?" + ConfirmExit.Title="Thoát OBS?" -ConfirmExit.Text="OBS hiện đang hoạt động. Tất cả các stream/quay video sẽ bị tắt. Bạn có chắc muốn thoát không?" +ConfirmExit.Text="OBS hiện đang hoạt động. Tất cả các stream/quay video sẽ bị tắt. Bạn có chắc muốn thoát không?" ConfirmRemove.Title="Xác nhận loại bỏ" ConfirmRemove.Text="Bạn có chắc bạn muốn loại bỏ '$1' không?" @@ -202,51 +240,50 @@ Output.StartRecordingFailed="Không thể bắt đầu quay video" Output.StartReplayFailed="Không thể khởi động replay buffer" Output.StartFailedGeneric="Bắt đầu đầu ra đã thất bại. Vui lòng kiểm tra các bản ghi để biết thêm chi tiết.\n\nGhi chú: nếu bạn đang sử dụng bộ mã hóa NVENC hoặc AMD, hãy chắc chắn rằng các trình điều khiển GPU được cập nhật phiên bản mới nhất." + Output.ConnectFail.Title="Không thể kết nối" -Output.ConnectFail.BadPath="URL không hợp lệ của đường dẫn hoặc kết nối. Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng họ là hợp lệ." +Output.ConnectFail.BadPath="URL không hợp lệ của đường dẫn hoặc kết nối. Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng họ là hợp lệ." Output.ConnectFail.ConnectFailed="Không thể kết nối tới hệ phục vụ" -Output.ConnectFail.InvalidStream="Không thể truy cập kênh chỉ định hoặc khóa stream, Vui lòng kiểm tra khóa stream của bạn. Nếu nó đúng, có thể có một vấn đề về kết nối với máy chủ." -Output.ConnectFail.Error="1 lỗi bất ngờ xảy ra khi thử kết nối tới máy chủ. Thông tin thêm nằm trong log file." +Output.ConnectFail.InvalidStream="Không thể truy cập kênh chỉ định hoặc khóa stream, Vui lòng kiểm tra khóa stream của bạn. Nếu nó đúng, có thể có một vấn đề về kết nối với máy chủ." +Output.ConnectFail.Error="1 lỗi bất ngờ xảy ra khi thử kết nối tới máy chủ. Thông tin thêm nằm trong log file." Output.ConnectFail.Disconnected="Ngắt kết nối từ máy chủ." +Output.StreamEncodeError.Title="Lỗi mã hóa" +Output.StreamEncodeError.Msg="Xảy ra lỗi mã hóa trong khi truyền phát." + Output.RecordFail.Title="Không thể bắt đầu ghi âm" -Output.RecordFail.Unsupported="Định dạng đầu ra là một trong hai không được hỗ trợ hoặc không hỗ trợ nhiều hơn một rãnh âm thanh. Xin vui lòng kiểm tra cài đặt của bạn và thử lại." +Output.RecordFail.Unsupported="Định dạng đầu ra là một trong hai không được hỗ trợ hoặc không hỗ trợ nhiều hơn một rãnh âm thanh. Xin vui lòng kiểm tra cài đặt của bạn và thử lại." Output.RecordNoSpace.Title="Không gian đĩa không đủ" Output.RecordNoSpace.Msg="Không còn đủ không gian đĩa để tiếp tục ghi âm." Output.RecordError.Title="Lỗi ghi âm" Output.RecordError.Msg="Một lỗi không xác định xảy ra trong khi ghi âm." +Output.RecordError.EncodeErrorMsg="Xảy ra lỗi mã hóa trong khi ghi." Output.ReplayBuffer.NoHotkey.Title="Không có hotkey!" -Output.ReplayBuffer.NoHotkey.Msg="Không hotkey lưu replay buffer. Vui lòng đặt hotkey \"Lưu\" để sử dụng để lưu video." +Output.ReplayBuffer.NoHotkey.Msg="Không hotkey lưu replay buffer. Vui lòng đặt hotkey \"Lưu\" để sử dụng để lưu video." Output.BadPath.Title="Đường dẫn tệp xấu" -Output.BadPath.Text="Đường dẫn đầu ra của cấu hình tệp không hợp lệ. Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng một đường dẫn hợp lệ tập tin đã được thiết lập." +Output.BadPath.Text="Đường dẫn đầu ra của cấu hình tệp không hợp lệ. Xin vui lòng kiểm tra cài đặt của bạn để xác nhận rằng một đường dẫn hợp lệ tập tin đã được thiết lập." LogReturnDialog="Đăng tải lên thành công" LogReturnDialog.CopyURL="Chép địa chỉ" LogReturnDialog.ErrorUploadingLog="Lỗi tải lên tập tin đăng nhập" -LicenseAgreement="Giấy phép" -LicenseAgreement.PleaseReview="Vui lòng xem lại điều khoản cấp phép trước khi sử dụng làm Bằng cách sử dụng chương trình này, bạn công nhận rằng bạn đã đọc và đồng ý với các điều khoản của GNU General Public License v2.0. Xin vui lòng di chuyển xuống để xem phần còn lại của Hiệp định." -LicenseAgreement.ClickIAgreeToContinue="Nếu bạn chấp nhận các điều khoản của Hiệp định, bấm tôi đồng ý để tiếp tục. Bạn phải chấp nhận thỏa thuận để sử dụng làm." -LicenseAgreement.IAgree="Tôi đồng ý" -LicenseAgreement.Exit="Thoát" - Remux.SourceFile="Ghi âm OBS" Remux.TargetFile="Tệp đích" Remux.Remux="Remux" +Remux.Stop="Ngừng làm lại" +Remux.ClearFinished="Xóa thành phẩm" +Remux.ClearAll="Xóa tất cả các mục" Remux.OBSRecording="Ghi OBS" Remux.FinishedTitle="Remuxing đã hoàn thành" Remux.Finished="Ghi remuxed" Remux.FinishedError="Ghi âm remuxed, nhưng các tập tin có thể không đầy đủ" -Remux.SelectRecording="Chọn OBS ghi âm…" -Remux.SelectTarget="Chọn tập tin mục tiêu…" -Remux.FileExistsTitle="Tệp đích tồn tại" -Remux.FileExists="Tệp đích tồn tại, bạn có muốn thay thế nó?" +Remux.SelectRecording="Chọn Ghi âm OBS..." Remux.ExitUnfinishedTitle="Remuxing trong tiến trình" Remux.ExitUnfinished="Remuxing không được hoàn tất, dừng bây giờ có thể hiển thị các tập tin mục tiêu không sử dụng được. \nAre bạn có chắc bạn muốn dừng remuxing?" UpdateAvailable="Bản cập nhật mới" -UpdateAvailable.Text="Phiên bản %1.%2.%3 có sẵn. Click vào đây để tải về" +UpdateAvailable.Text="Phiên bản %1.%2.%3 có sẵn. Click vào đây để tải về" Basic.DesktopDevice1="Âm thanh máy tính để bàn" Basic.DesktopDevice2="Máy tính để bàn âm thanh 2" @@ -260,11 +297,14 @@ Basic.DisplayCapture="Chụp màn hình" Basic.Main.PreviewConextMenu.Enable="Bật xem trước" +Basic.Main.Preview.Disable="Tắt xem trước" + ScaleFiltering="Scale Filtering" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Khu vực" Deinterlacing="Deinterlacing" Deinterlacing.Discard="Discard" @@ -275,6 +315,8 @@ Deinterlacing.Linear="Linear" Deinterlacing.Linear2x="Linear 2x" Deinterlacing.Yadif="Yadif" Deinterlacing.Yadif2x="Yadif 2x" +Deinterlacing.TopFieldFirst="Trường đầu tiên" +Deinterlacing.BottomFieldFirst="Trường dưới cùng trước" VolControl.Mute="Tắt tiếng '%1'" VolControl.Properties="Thuộc tính '%1'" @@ -310,7 +352,7 @@ Basic.PropertiesWindow.AutoSelectFormat="%1 (autoselect: %2)" Basic.PropertiesWindow.SelectColor="Chọn Màu" Basic.PropertiesWindow.SelectFont="Chọn font" Basic.PropertiesWindow.ConfirmTitle="Thay đổi cài đặt" -Basic.PropertiesWindow.Confirm="Có được lưu thay đổi. Bạn có muốn giữ họ?" +Basic.PropertiesWindow.Confirm="Có được lưu thay đổi. Bạn có muốn giữ họ?" Basic.PropertiesWindow.NoProperties="Không có tài sản có sẵn" Basic.PropertiesWindow.AddFiles="Thêm tập tin" Basic.PropertiesWindow.AddDir="Thêm thư mục" @@ -388,55 +430,63 @@ Basic.Main.StopStreaming="Ngừng Stream" Basic.Main.StoppingStreaming="Đang dừng stream..." Basic.Main.ForceStopStreaming="Ngừng Stream (huỷ chậm trễ)" Basic.Main.Group="Nhóm %1" +Basic.Main.GroupItems="Nhóm đã chọn" +Basic.Main.Ungroup="Tháo nhóm" -Basic.MainMenu.File="&Tập tin" -Basic.MainMenu.File.Export="&Xuất" -Basic.MainMenu.File.Import="&Nhập" -Basic.MainMenu.File.ShowRecordings="Hiển thị &Bản ghi" +Basic.MainMenu.File="Tập tin (&F)" +Basic.MainMenu.File.Export="Xuất (&E)" +Basic.MainMenu.File.Import="Nhập (&I)" +Basic.MainMenu.File.ShowRecordings="Hiển thị Bản ghi (&R)" Basic.MainMenu.File.Remux="Re&mux bản ghi" -Basic.MainMenu.File.Settings="&Cài đặt" +Basic.MainMenu.File.Settings="Cài đặt (&S)" Basic.MainMenu.File.ShowSettingsFolder="Hiển thị thư mục cài đặt" Basic.MainMenu.File.ShowProfileFolder="Hiển thị thư mục cấu hình" -Basic.MainMenu.AlwaysOnTop="&Luôn trên đầu trang" -Basic.MainMenu.File.Exit="&Thoát" +Basic.MainMenu.AlwaysOnTop="Luôn trên đầu tr&ang" +Basic.MainMenu.File.Exit="Thoát (&X)" -Basic.MainMenu.Edit="&Chỉnh sửa" -Basic.MainMenu.Edit.Undo="&Hoàn tác" -Basic.MainMenu.Edit.Redo="&Làm lại" -Basic.MainMenu.Edit.UndoAction="&Hoàn tác $1" -Basic.MainMenu.Edit.RedoAction="&Làm lại $1" -Basic.MainMenu.Edit.LockPreview="&Khóa xem trước" -Basic.MainMenu.Edit.Scale="Xem trước & co dãn" +Basic.MainMenu.Edit="Chỉnh sửa (&E)" +Basic.MainMenu.Edit.Undo="Hoàn tác (&U)" +Basic.MainMenu.Edit.Redo="Làm lại (&R)" +Basic.MainMenu.Edit.UndoAction="Hoàn tác $1 (&U)" +Basic.MainMenu.Edit.RedoAction="Làm lại $1 (&R)" +Basic.MainMenu.Edit.LockPreview="Khóa xem trước (&L)" +Basic.MainMenu.Edit.Scale="Xem trước co dãn (&S)" Basic.MainMenu.Edit.Scale.Window="Co dãn cửa sổ" Basic.MainMenu.Edit.Scale.Output="Đầu ra (%1x%2)" -Basic.MainMenu.Edit.Transform="&Biến đổi" -Basic.MainMenu.Edit.Transform.EditTransform="&Chỉnh sửa biến đổi..." -Basic.MainMenu.Edit.Transform.ResetTransform="&Đặt lại biến đổi" +Basic.MainMenu.Edit.Transform="Biến đổi (&T)" +Basic.MainMenu.Edit.Transform.EditTransform="Chỉnh sửa biến đổi... (&E)" +Basic.MainMenu.Edit.Transform.CopyTransform="Sao chép chuyển đổi" +Basic.MainMenu.Edit.Transform.PasteTransform="Dán chuyển đổi" +Basic.MainMenu.Edit.Transform.ResetTransform="Đặt lại biến đổi (&R)" Basic.MainMenu.Edit.Transform.Rotate90CW="Xoay 90 độ bên phải" Basic.MainMenu.Edit.Transform.Rotate90CCW="Xoay 90 độ bên trái" Basic.MainMenu.Edit.Transform.Rotate180="Xoay 180 độ" -Basic.MainMenu.Edit.Transform.FlipHorizontal="Lật &Ngang" -Basic.MainMenu.Edit.Transform.FlipVertical="Lật &Dọc" -Basic.MainMenu.Edit.Transform.FitToScreen="&Vừa với màn hình" -Basic.MainMenu.Edit.Transform.StretchToScreen="&Giãn ra để lấp đầy m.hình" -Basic.MainMenu.Edit.Transform.CenterToScreen="& Trung tâm màn hình" -Basic.MainMenu.Edit.Order="&Đặt" -Basic.MainMenu.Edit.Order.MoveUp="Chuyển &Lên" -Basic.MainMenu.Edit.Order.MoveDown="Chuyển &Xuống" -Basic.MainMenu.Edit.Order.MoveToTop="Chuyển đến &Đầu" -Basic.MainMenu.Edit.Order.MoveToBottom="Chuyển xuống &Dưới" -Basic.MainMenu.Edit.AdvAudio="Các thuộc tính âm thanh nâng cao" +Basic.MainMenu.Edit.Transform.FlipHorizontal="Lật Ngang (&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="Lật Dọc (&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="Vừa với màn hình (&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="Giãn ra để lấp đầy m.hình (&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="Trung tâm màn hình (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="Giữa theo chiều dọc" +Basic.MainMenu.Edit.Transform.HorizontalCenter="Giữa theo chiều ngang" +Basic.MainMenu.Edit.Order="Đặt (&O)" +Basic.MainMenu.Edit.Order.MoveUp="Ch&uyển Lên" +Basic.MainMenu.Edit.Order.MoveDown="Chuyển Xuống (&D)" +Basic.MainMenu.Edit.Order.MoveToTop="Chuyển đến Đầu (&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="Chuyển xuống Dưới (&B)" +Basic.MainMenu.Edit.AdvAudio="Các thuộc tính âm th&anh nâng cao" -Basic.MainMenu.View="&Hiển thị" +Basic.MainMenu.View="Hiển thị (&V)" Basic.MainMenu.View.Toolbars="&Thanh công cụ" +Basic.MainMenu.View.Docks="Thanh đế" Basic.MainMenu.View.Docks.ResetUI="Đặt lại UI" Basic.MainMenu.View.Docks.LockUI="Khóa UI" Basic.MainMenu.View.Toolbars.Listboxes="&Listboxes" -Basic.MainMenu.View.StatusBar="&Thanh trạng thái" +Basic.MainMenu.View.SceneTransitions="Chuyển cảnh" +Basic.MainMenu.View.StatusBar="Thanh trạng thái (&S)" Basic.MainMenu.View.Fullscreen.Interface="Giao diện toàn màn hình" -Basic.MainMenu.SceneCollection="& Bộ sưu tập cảnh" -Basic.MainMenu.Profile="&Cấu hình" +Basic.MainMenu.SceneCollection="Bộ &sưu tập cảnh" +Basic.MainMenu.Profile="Cấu hình (&P)" Basic.MainMenu.Profile.Import="Nhập cấu hình" Basic.MainMenu.Profile.Export="Xuất cấu hình" Basic.MainMenu.SceneCollection.Import="Nhập bộ sưu tập cảnh" @@ -444,20 +494,24 @@ Basic.MainMenu.SceneCollection.Export="Xuất bộ sưu tập cảnh" Basic.MainMenu.Profile.Exists="Cấu hình này đã tồn tại" Basic.MainMenu.SceneCollection.Exists="Bộ sưu tập cảnh đã tồn tại" -Basic.MainMenu.Tools="&Công cụ" +Basic.MainMenu.Tools="Công cụ (&T)" -Basic.MainMenu.Help="&Trợ giúp" -Basic.MainMenu.Help.Website="Ghé thăm Website" -Basic.MainMenu.Help.Logs="& Tập tin đăng nhập" -Basic.MainMenu.Help.Logs.ShowLogs="& Hiển thị tập tin đăng nhập" -Basic.MainMenu.Help.Logs.UploadCurrentLog="Tải lên & tệp sổ ghi hiện tại" -Basic.MainMenu.Help.Logs.UploadLastLog="Tải lên & cuối đăng nhập tập tin" -Basic.MainMenu.Help.Logs.ViewCurrentLog="& Xem sổ ghi hiện tại" +Basic.MainMenu.Help="Trợ giúp (&H)" +Basic.MainMenu.Help.HelpPortal="Trợ giúp & Cổng thông tin" +Basic.MainMenu.Help.Website="Ghé thăm &Website" +Basic.MainMenu.Help.Discord="Tham gia & Discord Server" +Basic.MainMenu.Help.Logs="Tập tin đăng nhập (&L)" +Basic.MainMenu.Help.Logs.ShowLogs="Hiển thị tập tin đăng nhập (&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="Tải lên tệp sổ ghi hiện tại (&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="Tải &lên cuối đăng nhập tập tin" +Basic.MainMenu.Help.Logs.ViewCurrentLog="Xem sổ ghi hiện tại (&V)" Basic.MainMenu.Help.CheckForUpdates="Kiểm tra cập nhật mới" +Basic.MainMenu.Help.CrashLogs="Sự cố & Báo cáo" +Basic.MainMenu.Help.About="Giới thiệu (&A)" Basic.Settings.ProgramRestart="Chương trình phải được khởi động lại để những thiết đặt có hiệu lực." Basic.Settings.ConfirmTitle="Xác nhận thay đổi" -Basic.Settings.Confirm="Bạn đã lưu thay đổi. Lưu thay đổi?" +Basic.Settings.Confirm="Bạn đã lưu thay đổi. Lưu thay đổi?" Basic.Settings.General="Chung" Basic.Settings.General.Theme="Theme" @@ -466,8 +520,12 @@ Basic.Settings.General.EnableAutoUpdates="Tự động kiểm tra cập nhật k Basic.Settings.General.OpenStatsOnStartup="Mở hộp thoại thống kê khi khởi động" Basic.Settings.General.WarnBeforeStartingStream="Hiển thị hộp thoại xác nhận khi bắt đầu stream" Basic.Settings.General.WarnBeforeStoppingStream="Hiển thị hộp thoại xác nhận khi dừng lại stream" +Basic.Settings.General.Projectors="Máy chiếu" Basic.Settings.General.HideProjectorCursor="Ẩn con trỏ chuột trên màn chiếu" Basic.Settings.General.ProjectorAlwaysOnTop="Làm cho màn chiếu luôn luôn trên đầu" +Basic.Settings.General.Snapping="Chụp liên kết nguồn" +Basic.Settings.General.ScreenSnapping="Nguồn Snap đến cạnh màn hình" +Basic.Settings.General.CenterSnapping="Chụp nguồn vào trung tâm ngang và dọc" Basic.Settings.General.RecordWhenStreaming="Tự động quay video khi stream" Basic.Settings.General.KeepRecordingWhenStreamStops="Quay tiếp khi dừng stream" Basic.Settings.General.ReplayBufferWhileStreaming="Tự động bắt đầu replay buffer khi stream" @@ -475,11 +533,15 @@ Basic.Settings.General.KeepReplayBufferStreamStops="Để replay buffer tiếp t Basic.Settings.General.SysTray="Khay hệ thống" Basic.Settings.General.SysTrayWhenStarted="Thu nhỏ về khay hệ thống khi bắt đầu" Basic.Settings.General.SystemTrayHideMinimize="Luôn luôn thu nhỏ về khay hệ thống thay vì thanh tác vụ" +Basic.Settings.General.Preview="Xem trước" Basic.Settings.General.StudioPortraitLayout="Bật bố cục theo chiều ngang/dọc" +Basic.Settings.General.Multiview="Đa góc nhìn" Basic.Settings.General.MultiviewLayout="Giao diện nhiều lớp" Basic.Settings.Stream="Stream" Basic.Settings.Stream.StreamType="Kiểu Stream" +Basic.Settings.Stream.Custom.Username="Tên đăng nhập" +Basic.Settings.Stream.Custom.Password="Mật khẩu" Basic.Settings.Output="Đầu ra" Basic.Settings.Output.Format="Định dạng ghi âm" @@ -504,10 +566,9 @@ Basic.Settings.Output.Simple.RecordingQuality.Small="Chất lượng cao, Trung Basic.Settings.Output.Simple.RecordingQuality.HQ="Không thể phân biệt chất lượng, lớn kích thước" Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless chất lượng, rất lớn tập tin kích thước" Basic.Settings.Output.Simple.Warn.Encoder="Chú ý: Ghi âm với một phần mềm mã hóa ở một chất lượng khác nhau hơn dòng sẽ yêu cầu phụ CPU sử dụng nếu bạn suối và hồ sơ cùng một lúc." -Basic.Settings.Output.Simple.Warn.Lossless="Cảnh báo: Lossless chất lượng tạo ra kích thước tập tin rất lớn! Lossless chất lượng có thể sử dụng upward of 7 GB không gian đĩa cho một phút ở độ phân giải cao và framerates. Lossless không nên dùng cho bản ghi âm dài trừ khi bạn có một số lượng rất lớn của không gian đĩa sẵn dùng." +Basic.Settings.Output.Simple.Warn.Lossless="Cảnh báo: Lossless chất lượng tạo ra kích thước tập tin rất lớn! Lossless chất lượng có thể sử dụng upward of 7 GB không gian đĩa cho một phút ở độ phân giải cao và framerates. Lossless không nên dùng cho bản ghi âm dài trừ khi bạn có một số lượng rất lớn của không gian đĩa sẵn dùng." Basic.Settings.Output.Simple.Warn.Lossless.Msg="Bạn có chắc bạn muốn sử dụng lossless chất lượng?" Basic.Settings.Output.Simple.Warn.Lossless.Title="Lossless chất lượng cảnh báo!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="Chú ý: Bạn không thể sử dụng nhiều mã hóa QSV khi streaming và ghi âm cùng lúc. Nếu bạn muốn stream và quay cùng lúc, xin vui lòng thay đổi mã hóa quay video hoặc mã hóa stream." Basic.Settings.Output.Simple.Encoder.Software="Phần mềm (x 264)" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="Phần cứng (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="Phần cứng (AMD)" @@ -519,7 +580,6 @@ Basic.Settings.Output.Reconnect="Tự động kết nối" Basic.Settings.Output.RetryDelay="Thử lại chậm trễ (giây)" Basic.Settings.Output.MaxRetries="Tối đa Retries" Basic.Settings.Output.Advanced="Kích hoạt tính năng cài đặt mã hóa nâng cao" -Basic.Settings.Output.EncoderPreset="Cài sẵn mã hóa (cao hơn = ít CPU)" Basic.Settings.Output.CustomEncoderSettings="Thiết đặt tùy chỉnh mã hóa" Basic.Settings.Output.CustomMuxerSettings="Thiết đặt tùy chỉnh Muxer" Basic.Settings.Output.NoSpaceFileName="Tạo ra tên tập tin mà không cần Space" @@ -579,8 +639,8 @@ Basic.Settings.Video.FPSFraction="Phân đoạn FPS giá trị" Basic.Settings.Video.Numerator="Tử số" Basic.Settings.Video.Denominator="Mẫu số" Basic.Settings.Video.Renderer="Renderer" -Basic.Settings.Video.InvalidResolution="Giá trị độ phân giải không hợp lệ. Phải là [width]x[height] (tức là năm 1920 x 1080)" -Basic.Settings.Video.CurrentlyActive="Đầu ra video là hiện đang hoạt động. Hãy tắt vào bất kỳ kết quả đầu ra để thay đổi thiết đặt video." +Basic.Settings.Video.InvalidResolution="Giá trị độ phân giải không hợp lệ. Phải là [width]x[height] (tức là năm 1920 x 1080)" +Basic.Settings.Video.CurrentlyActive="Đầu ra video là hiện đang hoạt động. Hãy tắt vào bất kỳ kết quả đầu ra để thay đổi thiết đặt video." Basic.Settings.Video.DisableAero="Vô hiệu hóa Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="Bilinear (nhanh nhất, nhưng mờ nếu rộng)" @@ -590,31 +650,26 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos (Sharpened rộng, 32 mẫ Basic.Settings.Audio="Âm thanh" Basic.Settings.Audio.SampleRate="Tỷ lệ mẫu" Basic.Settings.Audio.Channels="Kênh Tivi" -Basic.Settings.Audio.DesktopDevice="Thiết bị âm thanh máy tính" -Basic.Settings.Audio.DesktopDevice2="Thiết bị âm thanh máy tính 2" -Basic.Settings.Audio.AuxDevice="Thiết bị âm thanh mic/phụ trợ" -Basic.Settings.Audio.AuxDevice2="Thiết bị âm thanh mic/phụ trợ 2" -Basic.Settings.Audio.AuxDevice3="Thiết bị âm thanh mic/phụ trợ 3" +Basic.Settings.Audio.MeterDecayRate.Fast="Nhanh" Basic.Settings.Audio.EnablePushToMute="Bật bấm để tắt tiếng" Basic.Settings.Audio.PushToMuteDelay="Bấm để tắt tiếng trễ" Basic.Settings.Audio.EnablePushToTalk="Bật bắm để nói" Basic.Settings.Audio.PushToTalkDelay="Bấm để nói trễ" Basic.Settings.Audio.UnknownAudioDevice="[Thiết bị không được kết nối hoặc không sẵn dùng]" +Basic.Settings.Audio.Disabled="Đã vô hiệu" Basic.Settings.Advanced="Nâng cao" Basic.Settings.Advanced.General.ProcessPriority="Chương trình ưu tiên" Basic.Settings.Advanced.General.ProcessPriority.High="Cao" Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="Trên bình thường" Basic.Settings.Advanced.General.ProcessPriority.Normal="Thường" +Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="Dưới trung bình" Basic.Settings.Advanced.General.ProcessPriority.Idle="Rảnh" -Basic.Settings.Advanced.FormatWarning="Cảnh báo: Định dạng màu sắc khác với NV12 chủ yếu dành cho ghi âm và không được khuyến cáo khi streaming. Stream có thể làm tăng sử dụng CPU do phải chuyển đổi định dạng màu sắc." +Basic.Settings.Advanced.FormatWarning="Cảnh báo: Định dạng màu sắc khác với NV12 chủ yếu dành cho ghi âm và không được khuyến cáo khi streaming. Stream có thể làm tăng sử dụng CPU do phải chuyển đổi định dạng màu sắc." Basic.Settings.Advanced.Audio.BufferingTime="Âm thanh thời gian đệm" Basic.Settings.Advanced.Video.ColorFormat="Định dạng màu sắc" -Basic.Settings.Advanced.Video.ColorSpace="Không gian màu YUV" -Basic.Settings.Advanced.Video.ColorRange="Phạm vi màu YUV" Basic.Settings.Advanced.Video.ColorRange.Partial="Một phần" Basic.Settings.Advanced.Video.ColorRange.Full="Đầy đủ" -Basic.Settings.Advanced.Audio.MonitoringDevice="Thiết bị giám sát âm thanh" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="Mặc định" Basic.Settings.Advanced.StreamDelay="Stream trễ" Basic.Settings.Advanced.StreamDelay.Duration="Thời gian (giây)" @@ -624,12 +679,12 @@ Basic.Settings.Advanced.Network="Mạng" Basic.Settings.Advanced.Network.BindToIP="Liên kết với IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="Sử dụng mã mạng mới" Basic.Settings.Advanced.Network.EnableLowLatencyMode="Chế độ độ trễ thấp" +Basic.Settings.Advanced.AutoRemux.MP4="(ghi với định dạng mkv)" Basic.AdvAudio="Thuộc tính âm thanh nâng cao" Basic.AdvAudio.Name="Tên" -Basic.AdvAudio.Volume="Khối lượng (%)" Basic.AdvAudio.Mono="Downmix để Mono" -Basic.AdvAudio.Panning="Panning" +Basic.AdvAudio.Balance="Cân bằng" Basic.AdvAudio.SyncOffset="Bù đắp đồng bộ (ms)" Basic.AdvAudio.Monitoring="Giám sát âm thanh" Basic.AdvAudio.Monitoring.None="Tắt giám sát" @@ -639,13 +694,14 @@ Basic.AdvAudio.AudioTracks="Bài hát" Basic.Settings.Hotkeys="Phím nóng" Basic.Settings.Hotkeys.Pair="Tổ hợp phím được chia sẻ với '%1' hành động như chuyển" +Basic.Settings.Hotkeys.Filter="Bộ lọc" Basic.Hotkeys.SelectScene="Chuyển cảnh" Basic.SystemTray.Show="Hiện" Basic.SystemTray.Hide="Ẩn" -Basic.SystemTray.Message.Reconnecting="Ngắt kết nối. Đang kết nối lại..." +Basic.SystemTray.Message.Reconnecting="Ngắt kết nối. Đang kết nối lại..." Hotkeys.Insert="Chèn" Hotkeys.Delete="Xoá" @@ -682,6 +738,7 @@ Hotkeys.AppleKeypadSubtract="-(Bàn phím)" Hotkeys.AppleKeypadDecimal=". (Bàn phím)" Hotkeys.AppleKeypadEqual="= (Bàn phím)" Hotkeys.MouseButton="Chuột %1" +Hotkeys.Escape="Esc (Thoát)" Mute="Tắt Tiếng" Unmute="Bật tiếng" @@ -693,13 +750,22 @@ SceneItemHide="Ẩn '%1'" OutputWarnings.NoTracksSelected="Bạn phải chọn ít nhất một track" OutputWarnings.MultiTrackRecording="Chú ý: Một số định dạng (chẳng hạn như FLV) không hỗ trợ nhiều track cho mỗi video" -OutputWarnings.MP4Recording="Chú ý: các bản ghi âm được lưu ở dạng MP4 sẽ không thể phục hồi nếu các tập tin không thể được hoàn thành (ví dụ như bị màn hình xanh, mất điện, vv.). Nếu bạn muốn ghi nhiều âm thanh thì xem xét sử dụng MKV và remux video sang mp4 sau khi hoàn tất (Tập tin -> Remux video)" FinalScene.Title="Xóa cảnh" FinalScene.Text="Cần có ít nhất một cảnh." +NoSources.Title="Không có nguồn" ChangeBG="Thiết lập màu sắc" CustomColor="Tùy chỉnh màu sắc" +About="Giới thiệu" +About.GetInvolved="Tham gia" +About.Authors="Các tác giả" +About.License="Giấy phép" +About.Contribute="Hỗ trợ dự án OBS" + +ResizeOutputSizeOfSource.Continue="Bạn có muốn tiếp tục không?" + + diff --git a/UI/data/locale/zh-CN.ini b/UI/data/locale/zh-CN.ini index 86fb246..0c2920f 100644 --- a/UI/data/locale/zh-CN.ini +++ b/UI/data/locale/zh-CN.ini @@ -7,51 +7,51 @@ Apply="应用" Cancel="取消" Close="关闭" Save="保存" -Discard="舍弃" +Discard="放弃" Disable="禁用" Yes="是" No="否" Add="添加" -Remove="移除(&E)" -Rename="重命名(&R)" -Interact="交互" +Remove="移除" +Rename="重命名" +Interact="互动" Filters="滤镜" Properties="属性" MoveUp="上移" MoveDown="下移" Settings="设置" -Display="显示" +Display="显示器" Name="名称" Exit="退出" Mixer="混音器" Browse="浏览" Mono="单声道​" Stereo="立体声​​​" -DroppedFrames="丢帧 %1 (%2%)" -StudioProgramProjector="全屏投影仪(输出)" -PreviewProjector="全屏投影仪(预览)" -SceneProjector="全屏投影仪 (现场)" -SourceProjector="全屏投影仪(源)" -StudioProgramWindow="窗口式投影仪 (输出)" -PreviewWindow="窗口化投影仪 (预览)" -SceneWindow="窗口化投影仪 (场景)" -SourceWindow="窗口化投影仪 (源)" -MultiviewProjector="多屏显示 (全屏)" -MultiviewWindowed="多屏显示 (窗口化)" +DroppedFrames="丢帧 %1(%2%)" +StudioProgramProjector="全屏投影(输出)" +PreviewProjector="全屏投影(预览)" +SceneProjector="全屏投影(场景)" +SourceProjector="全屏投影(源)" +StudioProgramWindow="窗口投影(输出)" +PreviewWindow="窗口投影(预览)" +SceneWindow="窗口投影(场景)" +SourceWindow="窗口投影(源)" +MultiviewProjector="多视图(全屏)" +MultiviewWindowed="多视图(窗口)" Clear="清除" Revert="还原" Show="显示" Hide="隐藏" -UnhideAll="取消所有隐藏" +UnhideAll="全部取消隐藏" Untitled="未命名" -New="新建(&N)" -Duplicate="复制(&D)" +New="新建" +Duplicate="复制" Enable="启用" DisableOSXVSync="禁用 OSX V-Sync" ResetOSXVSyncOnExit="退出时重置 OSX V-Sync" -HighResourceUsage="编码过载! 请考虑降低视频设置或使用更快的编码预设" -Transition="过渡动画" -QuickTransitions="快速过渡动画" +HighResourceUsage="编码过载!请考虑降低视频设置或使用更快的编码预设。" +Transition="转场特效" +QuickTransitions="快速转场特效" Left="左" Right="右" Top="上" @@ -68,62 +68,92 @@ Copy="复制" Paste="粘贴" PasteReference="粘贴(引用)" PasteDuplicate="粘贴(重复)" -RemuxRecordings="转封装录像" -Next="下一个" +RemuxRecordings="录像转封装" +Next="前进" Back="后退" -Defaults="默认值" -HideMixer="混合器中隐藏" -TransitionOverride="过渡覆盖模式" +Defaults="默认" +HideMixer="在混音器中隐藏" +TransitionOverride="覆盖默认转场特效" None="无" StudioMode.Preview="预览" StudioMode.Program="输出" -ShowInMultiview="多屏中显示" +ShowInMultiview="在多视图中显示" VerticalLayout="垂直布局" Group="分组" +DoNotShowAgain="不再显示" +Default="(默认)" +Calculating="计算中……" AlreadyRunning.Title="OBS 已在运行" -AlreadyRunning.Text="OBS 已经在运行! 除非你想要这样做, 请在你运行一个新的 OBS 前, 关闭任何已经在运行的 OBS. 如果你有一个 OBS 设置最小化到系统托盘, 请检查他是否仍在运行." -AlreadyRunning.LaunchAnyway="始终启动" +AlreadyRunning.Text="OBS 已经在运行中!若你真的想要这样做,请在启动新的 OBS 前关闭其他正在在运行中的 OBS。如果你把 OBS 设置成最小化到系统托盘,请检查它是否仍在运行。" +AlreadyRunning.LaunchAnyway="仍然启动" + +DockCloseWarning.Title="关闭可停靠窗口" +DockCloseWarning.Text="您刚关闭了一个可停靠的窗口。如果想要再次显示它,请使用菜单栏上的 查看→停靠部件 菜单。" + +Auth.Authing.Title="正在验证…" +Auth.Authing.Text="正在与 %1 进行身份验证,请稍候…" +Auth.AuthFailure.Title="身份验证失败" +Auth.AuthFailure.Text="无法与 %1 进行身份验证:\n\n%2: %3" +Auth.InvalidScope.Title="需要身份验证" +Auth.InvalidScope.Text="%1 的身份验证要求已更改。某些功能可能不可用。" +Auth.LoadingChannel.Title="正在加载频道信息…" +Auth.LoadingChannel.Text="正在加载 %1 的频道信息,请稍候…" +Auth.ChannelFailure.Title="无法加载频道" +Auth.ChannelFailure.Text="为 %1 加载频道信息失败\n\n%2: %3" +Auth.Chat="聊天" +Auth.StreamInfo="串流资讯" +TwitchAuth.Stats="Twitch 统计" +TwitchAuth.Feed="Twitch 活动订阅源" +TwitchAuth.TwoFactorFail.Title="无法查询流密钥" +TwitchAuth.TwoFactorFail.Text="OBS 无法连接到您的 Twitch 账户。请确保在 Twitch 安全性设置中开启了双重身份验证,只有开启后才能开始推流。" Copy.Filters="复制滤镜" Paste.Filters="粘贴滤镜" +BrowserPanelInit.Title="正在初始化浏览器…" +BrowserPanelInit.Text="正在初始化浏览器,请稍候…" + BandwidthTest.Region="区域" BandwidthTest.Region.US="美国" BandwidthTest.Region.EU="欧洲" BandwidthTest.Region.Asia="亚洲" BandwidthTest.Region.Other="其他" -Basic.FirstStartup.RunWizard="你想要运行自动配置向导吗? 你也可手动可以通过单击主窗口中的设置按钮来配置你的设置." -Basic.FirstStartup.RunWizard.BetaWarning="(注意: 自动配置向导目前处于 beta 阶段)" -Basic.FirstStartup.RunWizard.NoClicked="如果你改变主意, 你可以随时从工具菜单再次运行自动配置向导." +Basic.FirstStartup.RunWizard="你想要运行自动配置向导吗?你也可以通过单击主窗口中的设置按钮来手动调节你的设置。" +Basic.FirstStartup.RunWizard.NoClicked="如果你改变了主意,可以随时从工具菜单再次运行自动配置向导。" Basic.AutoConfig="自动配置向导" -Basic.AutoConfig.Beta="自动配置向导(Beta)" Basic.AutoConfig.ApplySettings="应用设置" -Basic.AutoConfig.StartPage="使用信息" +Basic.AutoConfig.StartPage="使用情况" Basic.AutoConfig.StartPage.SubTitle="选择你使用此程序的目的" -Basic.AutoConfig.StartPage.PrioritizeStreaming="优先考虑推流, 其次是录像" -Basic.AutoConfig.StartPage.PrioritizeRecording="只优先考虑录像, 我不会推流" +Basic.AutoConfig.StartPage.PrioritizeStreaming="优先优化串流,其次为录像" +Basic.AutoConfig.StartPage.PrioritizeRecording="仅优化录像,将不会进行串流" Basic.AutoConfig.VideoPage="视频设置" -Basic.AutoConfig.VideoPage.SubTitle="指定你想要使用视频设置" -Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="使用当前 (%1x%2)" -Basic.AutoConfig.VideoPage.BaseResolution.Display="显示 %1 (%2x%3)" -Basic.AutoConfig.VideoPage.FPS.UseCurrent="使用当前 (%1)" -Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60 或 30,但尽可能选择 60" -Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 或 30, 但优先选择高分辨率" -Basic.AutoConfig.VideoPage.CanvasExplanation="注意: canvas(base) 分辨率并非与你将要推流或者录像的分辨率相同. 你实际的推流/录像的分辨率可能会从 canvas 的分辨率缩放来减少分辨率使用或者比特率需要." -Basic.AutoConfig.StreamPage="流信息" -Basic.AutoConfig.StreamPage.SubTitle="请输入你的流信息" +Basic.AutoConfig.VideoPage.SubTitle="指定你想要使用的视频设置" +Basic.AutoConfig.VideoPage.BaseResolution.UseCurrent="使用当前的(%1x%2)" +Basic.AutoConfig.VideoPage.BaseResolution.Display="显示器 %1(%2x%3)" +Basic.AutoConfig.VideoPage.FPS.UseCurrent="使用当前(%1)" +Basic.AutoConfig.VideoPage.FPS.PreferHighFPS="60或30,但尽可能选择60" +Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60或30,但优先选择高分辨率" +Basic.AutoConfig.VideoPage.CanvasExplanation="注意:画布(基础)分辨率并不一定要与推流或录像的分辨率相同。实际推流或录像的分辨率可从画布分辨率缩小,以降低对资源的使用或对比特率的需求。" +Basic.AutoConfig.StreamPage="串流资讯" +Basic.AutoConfig.StreamPage.SubTitle="请输入你的串流信息" +Basic.AutoConfig.StreamPage.ConnectAccount="连接帐户(可选)" +Basic.AutoConfig.StreamPage.DisconnectAccount="解除帐户连接" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="解除帐户连接?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="此更改将立即应用。您确定要解除帐户连接吗?" +Basic.AutoConfig.StreamPage.UseStreamKey="使用串流密钥" Basic.AutoConfig.StreamPage.Service="服务" Basic.AutoConfig.StreamPage.Service.ShowAll="显示全部..." +Basic.AutoConfig.StreamPage.Service.Custom="自定义..." Basic.AutoConfig.StreamPage.Server="服务器" -Basic.AutoConfig.StreamPage.StreamKey="流密钥" +Basic.AutoConfig.StreamPage.StreamKey="串流密钥" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(链接)" Basic.AutoConfig.StreamPage.PerformBandwidthTest="通过带宽测试估计比特率(可能需要几分钟)" Basic.AutoConfig.StreamPage.PreferHardwareEncoding="优先选择硬件编码" -Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="硬件编码降低了大多数的 CPU 使用率, 但可能需要更多的比特率, 来获得同等的质量." -Basic.AutoConfig.StreamPage.StreamWarning.Title="流警告" +Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip="硬件编码可大量降低 CPU 的使用率,但要获得与软件编码相同的质量,可能需要更多的比特率。" +Basic.AutoConfig.StreamPage.StreamWarning.Title="串流警告" Basic.AutoConfig.StreamPage.StreamWarning.Text="带宽测试将开始串流无音频的随机视频数据。如果可以,建议你暂时关闭视频保存功能并把串流设置成私人直到测试结束。要继续吗?" Basic.AutoConfig.TestPage="最终结果" Basic.AutoConfig.TestPage.SubTitle.Testing="该程序目前正在执行一系列的测试来估计最理想的设置" @@ -132,33 +162,37 @@ Basic.AutoConfig.TestPage.TestingBandwidth="执行带宽测试, 这可能需要 Basic.AutoConfig.TestPage.TestingBandwidth.Connecting="正在连接到 %1..." Basic.AutoConfig.TestPage.TestingBandwidth.ConnectFailed="无法连接任何服务器, 请检查你的网络连接并重试." Basic.AutoConfig.TestPage.TestingBandwidth.Server="测试带宽: %1" -Basic.AutoConfig.TestPage.TestingStreamEncoder="测试推流编码器, 这可能需要一分钟......" -Basic.AutoConfig.TestPage.TestingRecordingEncoder="测试录像编码器, 这可能需要一分钟..." +Basic.AutoConfig.TestPage.TestingStreamEncoder="测试串流编码器中,这可能需要一分钟的时间..." +Basic.AutoConfig.TestPage.TestingRecordingEncoder="测试录像编码器中,这可能需要一分钟的时间..." Basic.AutoConfig.TestPage.TestingRes="测试分辨率, 这可能需要几分钟时间......" Basic.AutoConfig.TestPage.TestingRes.Fail="未能启动编码器" Basic.AutoConfig.TestPage.TestingRes.Resolution="测试 %1x%2 %3 FPS..." -Basic.AutoConfig.TestPage.Result.StreamingEncoder="推流编码器" +Basic.AutoConfig.TestPage.Result.StreamingEncoder="串流编码器" Basic.AutoConfig.TestPage.Result.RecordingEncoder="录像编码器" Basic.AutoConfig.TestPage.Result.Header="程序已确定这些估计设置是最适合你:" -Basic.AutoConfig.TestPage.Result.Footer="要使用这些设置, 单击应用设置. 要重新配置向导并再试一次, 单击后退. 要自己手动配置设置, 单击取消, 然后打开设置." +Basic.AutoConfig.TestPage.Result.Footer="要使用这些设置,单击“应用设置”。要重新配置向导并再试一次,单击“后退”。要自己手动配置设置,单击“取消”,然后打开设置。" Basic.Stats="统计" Basic.Stats.CPUUsage="CPU 使用率" -Basic.Stats.HDDSpaceAvailable="可用的硬盘空间" +Basic.Stats.HDDSpaceAvailable="可用磁盘空间" Basic.Stats.MemoryUsage="内存使用" Basic.Stats.AverageTimeToRender="渲染帧平均时间" Basic.Stats.SkippedFrames="由于编码延迟跳过的帧" Basic.Stats.MissedFrames="由于渲染延迟错过的帧" -Basic.Stats.Output.Stream="流" +Basic.Stats.Output.Stream="串流" Basic.Stats.Output.Recording="录像" Basic.Stats.Status="状态" -Basic.Stats.Status.Recording="录像" -Basic.Stats.Status.Live="实时" +Basic.Stats.Status.Recording="录像中" +Basic.Stats.Status.Live="直播中" Basic.Stats.Status.Reconnecting="重新连接中" Basic.Stats.Status.Inactive="未激活" Basic.Stats.DroppedFrames="丢弃的帧(网络)" Basic.Stats.MegabytesSent="总数据输出" Basic.Stats.Bitrate="比特率" +Basic.Stats.DiskFullIn="硬盘装满前剩余录制时间(约)" + +ResetUIWarning.Title="您确定要重置界面吗?" +ResetUIWarning.Text="重置界面将隐藏额外的停靠窗口。如果希望重新显示这些停靠窗口,则需要从“查看”菜单中取消隐藏它们。\n\n您确定要重置界面吗?" Updater.Title="有可用的更新" Updater.Text="有可用的新版本:" @@ -168,28 +202,28 @@ Updater.Skip="跳过版本" Updater.Running.Title="程序当前处于活跃状态" Updater.Running.Text="输出当前处于活动状态, 请关闭任何活跃的输出, 然后尝试更新" Updater.NoUpdatesAvailable.Title="无可用更新" -Updater.NoUpdatesAvailable.Text="没有更新当前可用" +Updater.NoUpdatesAvailable.Text="当前没有可用更新" Updater.FailedToLaunch="启动更新程序失败" Updater.GameCaptureActive.Title="游戏捕获活跃" -Updater.GameCaptureActive.Text="游戏捕获钩子库正在使用中, 请关闭所有正在被捕获的游戏/程序(或重新启动 windows), 然后重试." +Updater.GameCaptureActive.Text="游戏捕获钩子库正在使用中。请关闭所有正在被捕获的游戏/程序(或重新启动 Windows),然后重试。" -QuickTransitions.SwapScenes="在过渡动画后交换预览/输出场景" -QuickTransitions.SwapScenesTT="在过渡后,交换预览和输出场景(如果输出的原始场景仍然存在). \n 这个不会撤消任何可能对输出的原始场景的更改." +QuickTransitions.SwapScenes="在转场后交换预览/输出场景" +QuickTransitions.SwapScenesTT="(如果输出的原始场景仍存在)在转场后交换预览和输出场景。\n这将不会撤消任何对输出的原始场景的更改。" QuickTransitions.DuplicateScene="复制场景" -QuickTransitions.DuplicateSceneTT="当编辑同一场景, 允许编辑来源的可见性/变换而无需修改源输出. \n 为了编辑源属性而无需修改输出, 启动 ' 复制源'. \n 改变这个值将会重置当前的输出场景(如果它仍然存在)." +QuickTransitions.DuplicateSceneTT="当编辑同一场景时,可以修改源的变换/可见性,而不会影响输出。\n若要修改源属性而不影响输出,请打开“复制源”。\n改变这个值将会重置当前的输出场景(如果仍存在)。" QuickTransitions.EditProperties="复制源" -QuickTransitions.EditPropertiesTT="当编辑同一场景, 允许编辑来源的属性而不修改输出. \n 只有启用了'复制场景',才能使用这项设置. \n 某些来源 (如捕获或媒体源) 并不支持这个, 并不能单独编辑. \n 修改这个值将重置当前输出场景 (如果它仍然存在). \n\n 警告: 因为源将被复制这可能需要额外的系统或视频资源." -QuickTransitions.HotkeyName="快速过渡: %1" +QuickTransitions.EditPropertiesTT="当编辑同一场景时,可以修改源的属性,而不会影响输出。\n只有启用了“复制场景”之后才能使用这项设置。\n某些源(如捕获或媒体源)并不支持此功能,且不能单独修改。\n改变这个值将会重置当前的输出场景(如果仍存在)。\n\n警告:因为源将被复制,可能需要额外的系统或视频资源。" +QuickTransitions.HotkeyName="快速转场:%1" -Basic.AddTransition="添加可配置的过渡动画" -Basic.RemoveTransition="删除可配置的过渡动画" -Basic.TransitionProperties="过渡动画属性" -Basic.SceneTransitions="场景过渡" +Basic.AddTransition="添加可配置的转场特效" +Basic.RemoveTransition="删除可配置的转场特效" +Basic.TransitionProperties="转场特效属性" +Basic.SceneTransitions="转场特效" Basic.TransitionDuration="时长" Basic.TogglePreviewProgramMode="工作室模式" -TransitionNameDlg.Text="请输入过渡动画的名称" -TransitionNameDlg.Title="过渡动画名称" +TransitionNameDlg.Text="请输入转场特效的名称" +TransitionNameDlg.Title="转场特效名称" TitleBar.Profile="配置文件" TitleBar.Scenes="场景" @@ -200,11 +234,14 @@ NameExists.Text="该名称已被使用" NoNameEntered.Title="请输入一个有效的名称" NoNameEntered.Text="您不能使用空白名称。" -ConfirmStart.Title="启动流" -ConfirmStart.Text="你确定你想要启动流?" +ConfirmStart.Title="开始串流?" +ConfirmStart.Text="你确定你想要启动串流?" -ConfirmStop.Title="停止流?" -ConfirmStop.Text="你确定你想要停止流?" +ConfirmStop.Title="停止串流?" +ConfirmStop.Text="你确定你想要停止串流?" + +ConfirmBWTest.Title="开始带宽测试?" +ConfirmBWTest.Text="您已经在带宽测试模式下配置了 OBS。此模式允许在不启用频道的情况下进行网络测试。完成测试后,您需要禁用它,以便观众能够看到您的流。\n\n是否继续?" ConfirmExit.Title="退出OBS?" ConfirmExit.Text="OBS工作中. 所有的流/录像将会停止. 你确定想要退出吗?" @@ -213,74 +250,80 @@ ConfirmRemove.Title="确认移除" ConfirmRemove.Text="确定要删除 '$1' 吗?" ConfirmRemove.TextMultiple="您确定要删除 %1 项目吗?" -Output.StartStreamFailed="启动推流失败" +Output.StartStreamFailed="启动串流失败" Output.StartRecordingFailed="启动录像失败" Output.StartReplayFailed="启动回放缓存失败" Output.StartFailedGeneric="启动输出失败. 请检查日志来了解细节.\n\n注意: 如果你使用的是 NVENC 或 AMD 编码器, 请确保您的视频驱动程序是最新的." + Output.ConnectFail.Title="连接失败" Output.ConnectFail.BadPath="无效的路径或URL。请检查您的设置以确认它们是有效的。" Output.ConnectFail.ConnectFailed="无法连接到服务器" -Output.ConnectFail.InvalidStream="无法访问指定的频道或流密钥, 请仔细检查您的密钥流. 如果它是正确的, 有可能是连接到服务器时出现问题." +Output.ConnectFail.InvalidStream="无法访问指定的频道或串流密钥,请仔细检查您的串流密钥。如果没有问题,则可能是连接到服务器时出现问题。" Output.ConnectFail.Error="试图连接到服务器时出现意外的错误。详细信息记录在日志文件中。" Output.ConnectFail.Disconnected="已从服务器断开。" +Output.StreamEncodeError.Title="编码错误" +Output.StreamEncodeError.Msg="推流时发生了编码器错误。" + Output.RecordFail.Title="未能开始录制" Output.RecordFail.Unsupported="输出格式不支持或者不支持超过一个音轨. 请检查你的设置, 然后重试" Output.RecordNoSpace.Title="磁盘空间不足" Output.RecordNoSpace.Msg="没有足够磁盘空间来继续录像." Output.RecordError.Title="录像错误" -Output.RecordError.Msg="录像时发生未指定错误." -Output.ReplayBuffer.NoHotkey.Title="没有快捷键设置!" -Output.ReplayBuffer.NoHotkey.Msg="没有为回放缓存设置快捷键. 请设置保存跨借鉴来用于保存回放录像." +Output.RecordError.Msg="录像时发生了预料外的错误。" +Output.RecordError.EncodeErrorMsg="录制时发生了编码器错误。" +Output.ReplayBuffer.NoHotkey.Title="没有设置快捷键!" +Output.ReplayBuffer.NoHotkey.Msg="没有为回放缓存设置保存快捷键。请设置“保存回放”的快捷键,用于保存回放录像。" -Output.BadPath.Title="错误的文件路径" -Output.BadPath.Text="无效的输出路径。请检查您的设置,确认文件路径是否有效。" +Output.BadPath.Title="文件路径错误" +Output.BadPath.Text="输出路径无效。请检查您的设置,并确认文件路径有效。" LogReturnDialog="日志上传成功" LogReturnDialog.CopyURL="复制链接" LogReturnDialog.ErrorUploadingLog="日志上传失败" -LicenseAgreement="授权许可协议" -LicenseAgreement.PleaseReview="使用此程序前请查看许可条款,表明您已经阅读并同意 v2.0 GNU 通用公共许可证 的条款。请向下滚动以查看剩余的协议。" -LicenseAgreement.ClickIAgreeToContinue="如果您接受协议的条款,请单击我同意。您必须接受该协议才能使用 OBS。" -LicenseAgreement.IAgree="我同意" -LicenseAgreement.Exit="退出" - Remux.SourceFile="OBS 录像" Remux.TargetFile="目标文件" -Remux.Remux="重新封装" +Remux.Remux="转换封装" +Remux.Stop="停止封装转换" +Remux.ClearFinished="清除已完成项目" +Remux.ClearAll="清除所有项目" Remux.OBSRecording="OBS 录像" Remux.FinishedTitle="转封装完成" Remux.Finished="录像已经转封装" -Remux.FinishedError="录像已经转封装, 但是文件可能不完整." -Remux.SelectRecording="选择OBS录像 ..." -Remux.SelectTarget="选择目标文件 ..." +Remux.FinishedError="录像封装已转换,但文件可能不完整" +Remux.SelectRecording="选择 OBS 录像文件…" +Remux.SelectTarget="选择目标文件…" Remux.FileExistsTitle="目标文件已存在" -Remux.FileExists="目标文件存在,你想要替换它吗?" +Remux.FileExists="目标文件已存在。你想替换它们吗?" Remux.ExitUnfinishedTitle="转封装在进行中" -Remux.ExitUnfinished="转封装没有完成, 现在停止可能使目标文件不可用.\n你确定要停止转封装吗?" +Remux.ExitUnfinished="转封装尚未完成,现在停止可能会使目标文件无法使用。\n你确定要停止封装转换吗?" +Remux.HelpText="拖动文件到此窗口以转换封装格式,或选择空“OBS 录像”单元以浏览文件。" -UpdateAvailable="版本升级" +UpdateAvailable="有可用的更新" UpdateAvailable.Text="新的版本 %1.%2.%3 已可用。 点击这里下载" -Basic.DesktopDevice1="台式音响" -Basic.DesktopDevice2="台式音响 2" +Basic.DesktopDevice1="桌面音频" +Basic.DesktopDevice2="桌面音频 2" Basic.AuxDevice1="麦克风/Aux" Basic.AuxDevice2="麦克风/Aux 2" Basic.AuxDevice3="麦克风/Aux 3" Basic.AuxDevice4="麦克风/Aux 4" Basic.Scene="场景" -Basic.DisplayCapture="显示捕获" +Basic.DisplayCapture="显示器捕获" Basic.Main.PreviewConextMenu.Enable="开启预览" +Basic.Main.Preview.Disable="关闭预览" + ScaleFiltering="尺度滤波" ScaleFiltering.Point="点" ScaleFiltering.Bilinear="双线性算法" ScaleFiltering.Bicubic="双立方算法" ScaleFiltering.Lanczos="兰索斯算法" +ScaleFiltering.Area="区域" Deinterlacing="去隔行扫描" Deinterlacing.Discard="舍弃" @@ -297,7 +340,7 @@ Deinterlacing.BottomFieldFirst="下场优先" VolControl.SliderUnmuted="音量滑动条 '%1': %2" VolControl.SliderMuted="音量滑动条 '%1': %2 (当前静音)" VolControl.Mute="静音 '%1'" -VolControl.Properties="属性 '%1'" +VolControl.Properties="'%1' 的属性" Basic.Main.AddSceneDlg.Title="添加场景" Basic.Main.AddSceneDlg.Text="请输入场景名称" @@ -354,49 +397,49 @@ Basic.StatusBar.DelayStartingIn="延迟 (在 %1 秒后开始)" Basic.StatusBar.DelayStoppingIn="延迟 (在 %1 秒后停止)" Basic.StatusBar.DelayStartingStoppingIn="延迟 (在%1 秒后停止,在 %2 秒后开始)" -Basic.Filters="过滤器" -Basic.Filters.AsyncFilters="音频/视频 过滤器" -Basic.Filters.AudioFilters="音频过滤器" +Basic.Filters="滤镜" +Basic.Filters.AsyncFilters="音频/视频滤镜" +Basic.Filters.AudioFilters="音频滤镜" Basic.Filters.EffectFilters="效果滤镜" -Basic.Filters.Title="'%1' 的过滤器" -Basic.Filters.AddFilter.Title="过滤器名称" -Basic.Filters.AddFilter.Text="请指定过滤器的名称" +Basic.Filters.Title="'%1' 的滤镜" +Basic.Filters.AddFilter.Title="滤镜名称" +Basic.Filters.AddFilter.Text="请指定滤镜的名称" -Basic.TransformWindow="现场项目变换" +Basic.TransformWindow="场景物体变换" Basic.TransformWindow.Position="位置" Basic.TransformWindow.Rotation="旋转" Basic.TransformWindow.Size="大小" -Basic.TransformWindow.Alignment="位置对齐" -Basic.TransformWindow.BoundsType="边界框类型" -Basic.TransformWindow.BoundsAlignment="边界框对齐方式" -Basic.TransformWindow.Bounds="边界框大小" +Basic.TransformWindow.Alignment="对齐点" +Basic.TransformWindow.BoundsType="边框类型" +Basic.TransformWindow.BoundsAlignment="边框内对齐方式" +Basic.TransformWindow.Bounds="边框大小" Basic.TransformWindow.Crop="裁剪" Basic.TransformWindow.Alignment.TopLeft="左上" -Basic.TransformWindow.Alignment.TopCenter="顶上" +Basic.TransformWindow.Alignment.TopCenter="中上" Basic.TransformWindow.Alignment.TopRight="右上" -Basic.TransformWindow.Alignment.CenterLeft="靠左居中" +Basic.TransformWindow.Alignment.CenterLeft="左中" Basic.TransformWindow.Alignment.Center="居中" -Basic.TransformWindow.Alignment.CenterRight="靠右居中" +Basic.TransformWindow.Alignment.CenterRight="右中" Basic.TransformWindow.Alignment.BottomLeft="左下" -Basic.TransformWindow.Alignment.BottomCenter="正下" +Basic.TransformWindow.Alignment.BottomCenter="中下" Basic.TransformWindow.Alignment.BottomRight="右下" -Basic.TransformWindow.BoundsType.None="没有界限" -Basic.TransformWindow.BoundsType.MaxOnly="最大大小" -Basic.TransformWindow.BoundsType.ScaleInner="缩放到内部边界" -Basic.TransformWindow.BoundsType.ScaleOuter="扩展到外部界限" -Basic.TransformWindow.BoundsType.ScaleToWidth="缩放到边界宽度" -Basic.TransformWindow.BoundsType.ScaleToHeight="缩放到边界高度" +Basic.TransformWindow.BoundsType.None="无边框" +Basic.TransformWindow.BoundsType.MaxOnly="等比缩放到框内,不超过原始大小" +Basic.TransformWindow.BoundsType.ScaleInner="等比缩放到框内" +Basic.TransformWindow.BoundsType.ScaleOuter="等比缩放到框外" +Basic.TransformWindow.BoundsType.ScaleToWidth="等比缩放到边框宽度" +Basic.TransformWindow.BoundsType.ScaleToHeight="等比缩放到边框高度" Basic.TransformWindow.BoundsType.Stretch="拉伸" Basic.Main.AddSourceHelp.Title="无法添加源" -Basic.Main.AddSourceHelp.Text="你需要至少一个场景来添加源。" +Basic.Main.AddSourceHelp.Text="你需要至少一个场景才能添加源。" Basic.Main.Scenes="场景" Basic.Main.Sources="来源" Basic.Main.Controls="控件" -Basic.Main.Connecting="连接中..." +Basic.Main.Connecting="连接中……" Basic.Main.StartRecording="开始录制" Basic.Main.StartReplayBuffer="开始回放缓存" Basic.Main.StartStreaming="开始推流" @@ -415,77 +458,80 @@ Basic.MainMenu.File="文件(&F)" Basic.MainMenu.File.Export="导出(&E)" Basic.MainMenu.File.Import="导入(&I)" Basic.MainMenu.File.ShowRecordings="显示录像(&R)" -Basic.MainMenu.File.Remux="转封装录像 (&M)" +Basic.MainMenu.File.Remux="录像转封装(&M)" Basic.MainMenu.File.Settings="设置(&S)" -Basic.MainMenu.File.ShowSettingsFolder="打开设置所在路径(&F)" -Basic.MainMenu.File.ShowProfileFolder="打开配置文件所在路径(&P)" -Basic.MainMenu.AlwaysOnTop="窗口置顶 (&A)" -Basic.MainMenu.File.Exit="退出 (&X)" +Basic.MainMenu.File.ShowSettingsFolder="打开设置文件夹" +Basic.MainMenu.File.ShowProfileFolder="打开配置文件文件夹" +Basic.MainMenu.AlwaysOnTop="窗口置顶(&A)" +Basic.MainMenu.File.Exit="退出(&X)" -Basic.MainMenu.Edit="编辑 (&E)" -Basic.MainMenu.Edit.Undo="撤销 (&U)" -Basic.MainMenu.Edit.Redo="重做 (&R)" +Basic.MainMenu.Edit="编辑(&E)" +Basic.MainMenu.Edit.Undo="撤消(&U)" +Basic.MainMenu.Edit.Redo="重做(&R)" Basic.MainMenu.Edit.UndoAction="撤消 $1 (&U)" Basic.MainMenu.Edit.RedoAction="重做 $1 (&R)" -Basic.MainMenu.Edit.LockPreview="锁定预览 (&L)" -Basic.MainMenu.Edit.Scale="预览 & 缩放" +Basic.MainMenu.Edit.LockPreview="锁定预览(&L)" +Basic.MainMenu.Edit.Scale="预览缩放(&S)" Basic.MainMenu.Edit.Scale.Window="缩放至窗口" -Basic.MainMenu.Edit.Scale.Canvas="背景 (%1x%2)" -Basic.MainMenu.Edit.Scale.Output="输出 (%1x%2)" -Basic.MainMenu.Edit.Transform="变换 (&T)" -Basic.MainMenu.Edit.Transform.EditTransform="编辑变换 (&E)" +Basic.MainMenu.Edit.Scale.Canvas="画布(%1x%2)" +Basic.MainMenu.Edit.Scale.Output="输出(%1x%2)" +Basic.MainMenu.Edit.Transform="变换(&T)" +Basic.MainMenu.Edit.Transform.EditTransform="编辑变换(&E)..." Basic.MainMenu.Edit.Transform.CopyTransform="复制变换" Basic.MainMenu.Edit.Transform.PasteTransform="粘贴变换" -Basic.MainMenu.Edit.Transform.ResetTransform="重置变换 (&R)" -Basic.MainMenu.Edit.Transform.Rotate90CW="顺时针旋转 90 度(&9)" -Basic.MainMenu.Edit.Transform.Rotate90CCW="逆时针旋转 90 度(&D)" -Basic.MainMenu.Edit.Transform.Rotate180="旋转 180 度(&1)" -Basic.MainMenu.Edit.Transform.FlipHorizontal="水平翻转 (&H)" -Basic.MainMenu.Edit.Transform.FlipVertical="垂直翻转 (&V)" -Basic.MainMenu.Edit.Transform.FitToScreen="比例适配屏幕 (&F)" -Basic.MainMenu.Edit.Transform.StretchToScreen="拉伸到全屏 (&S)" -Basic.MainMenu.Edit.Transform.CenterToScreen="屏幕居中 (&C)" -Basic.MainMenu.Edit.Order="排序 (&O)" -Basic.MainMenu.Edit.Order.MoveUp="上移 (&U)" -Basic.MainMenu.Edit.Order.MoveDown="下移 (&D)" -Basic.MainMenu.Edit.Order.MoveToTop="移至顶部 (&T)" -Basic.MainMenu.Edit.Order.MoveToBottom="移至底部 (&B)" +Basic.MainMenu.Edit.Transform.ResetTransform="重置变换(&R)" +Basic.MainMenu.Edit.Transform.Rotate90CW="顺时针旋转 90 度" +Basic.MainMenu.Edit.Transform.Rotate90CCW="逆时针旋转 90 度" +Basic.MainMenu.Edit.Transform.Rotate180="旋转 180 度" +Basic.MainMenu.Edit.Transform.FlipHorizontal="水平翻转(&H)" +Basic.MainMenu.Edit.Transform.FlipVertical="垂直翻转(&V)" +Basic.MainMenu.Edit.Transform.FitToScreen="比例适配屏幕(&F)" +Basic.MainMenu.Edit.Transform.StretchToScreen="拉伸到全屏(&S)" +Basic.MainMenu.Edit.Transform.CenterToScreen="屏幕居中(&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="垂直居中" +Basic.MainMenu.Edit.Transform.HorizontalCenter="水平居中" +Basic.MainMenu.Edit.Order="排序(&O)" +Basic.MainMenu.Edit.Order.MoveUp="上移(&U)" +Basic.MainMenu.Edit.Order.MoveDown="下移(&D)" +Basic.MainMenu.Edit.Order.MoveToTop="移至顶层(&T)" +Basic.MainMenu.Edit.Order.MoveToBottom="移至底层(&B)" Basic.MainMenu.Edit.AdvAudio="高级音频属性(&A)" -Basic.MainMenu.View="查看 (&V)" -Basic.MainMenu.View.Toolbars="工具栏 (&T)" +Basic.MainMenu.View="查看(&V)" +Basic.MainMenu.View.Toolbars="工具栏(&T)" Basic.MainMenu.View.Docks="停靠部件" Basic.MainMenu.View.Docks.ResetUI="重置界面" Basic.MainMenu.View.Docks.LockUI="锁定界面" -Basic.MainMenu.View.Toolbars.Listboxes="列表框 (&L)" -Basic.MainMenu.View.SceneTransitions="场景过渡 (&C)" -Basic.MainMenu.View.StatusBar="状态栏 (&S)" +Basic.MainMenu.View.Toolbars.Listboxes="列表框(&L)" +Basic.MainMenu.View.SceneTransitions="转场特效(&C)" +Basic.MainMenu.View.StatusBar="状态栏(&S)" Basic.MainMenu.View.Fullscreen.Interface="全屏界面" -Basic.MainMenu.SceneCollection="场景集合 (&S)" -Basic.MainMenu.Profile="配置文件 (&P)" +Basic.MainMenu.SceneCollection="场景集合(&S)" +Basic.MainMenu.Profile="配置文件(&P)" Basic.MainMenu.Profile.Import="导入配置文件" Basic.MainMenu.Profile.Export="导出配置文件" Basic.MainMenu.SceneCollection.Import="导入场景集合" Basic.MainMenu.SceneCollection.Export="导出场景集合" Basic.MainMenu.Profile.Exists="配置文件已存在" -Basic.MainMenu.SceneCollection.Exists="场景机会已存在" +Basic.MainMenu.SceneCollection.Exists="场景集合已存在" -Basic.MainMenu.Tools="工具 (&T)" +Basic.MainMenu.Tools="工具(&T)" -Basic.MainMenu.Help="帮助 (&H)" -Basic.MainMenu.Help.HelpPortal="帮助门户" -Basic.MainMenu.Help.Website="访问OBS主页 (&W)" +Basic.MainMenu.Help="帮助(&H)" +Basic.MainMenu.Help.HelpPortal="帮助门户(&P)" +Basic.MainMenu.Help.Website="访问 OBS 主页(&W)" Basic.MainMenu.Help.Discord="加入 &Discord 服务器" -Basic.MainMenu.Help.Logs="日志文件 (&L)" -Basic.MainMenu.Help.Logs.ShowLogs="显示日志文件 (&S)" -Basic.MainMenu.Help.Logs.UploadCurrentLog="上传当前日志文件 (&C)" -Basic.MainMenu.Help.Logs.UploadLastLog="上传最后一个日志文件 (&L)" -Basic.MainMenu.Help.Logs.ViewCurrentLog="查看当前日志 (&V)" +Basic.MainMenu.Help.Logs="日志文件(&L)" +Basic.MainMenu.Help.Logs.ShowLogs="显示日志文件(&S)" +Basic.MainMenu.Help.Logs.UploadCurrentLog="上传当前日志文件(&C)" +Basic.MainMenu.Help.Logs.UploadLastLog="上传上次日志文件(&L)" +Basic.MainMenu.Help.Logs.ViewCurrentLog="查看当前日志(&V)" Basic.MainMenu.Help.CheckForUpdates="检查升级(&C)" Basic.MainMenu.Help.CrashLogs="错误报告(&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="查看错误报告(&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="上传上一次错误报告(&L)" +Basic.MainMenu.Help.About="关于(&A)" Basic.Settings.ProgramRestart="要使这些设置生效,必须重新启动该程序。" Basic.Settings.ConfirmTitle="确认更改" @@ -498,37 +544,46 @@ Basic.Settings.General.EnableAutoUpdates="启动时自动检查更新" Basic.Settings.General.OpenStatsOnStartup="在启动时打开统计对话框" Basic.Settings.General.WarnBeforeStartingStream="启动流时显示确认对话框" Basic.Settings.General.WarnBeforeStoppingStream="停止流时显示确认对话框" -Basic.Settings.General.Projectors="投影仪" -Basic.Settings.General.HideProjectorCursor="隐藏投影仪上的光标" -Basic.Settings.General.ProjectorAlwaysOnTop="使投影器总是置顶" -Basic.Settings.General.Snapping="源对齐方式" -Basic.Settings.General.ScreenSnapping="对齐源到屏幕边缘" -Basic.Settings.General.CenterSnapping="水平和垂直居中对齐源" -Basic.Settings.General.SourceSnapping="对齐源跟其他的源" -Basic.Settings.General.SnapDistance="对齐的敏感性" -Basic.Settings.General.RecordWhenStreaming="当推流时自动录像" -Basic.Settings.General.KeepRecordingWhenStreamStops="当推流停止时保持录像" +Basic.Settings.General.Projectors="投影窗口" +Basic.Settings.General.HideProjectorCursor="投影窗口中隐藏光标" +Basic.Settings.General.ProjectorAlwaysOnTop="使投影窗口置顶" +Basic.Settings.General.Snapping="源对齐吸附" +Basic.Settings.General.ScreenSnapping="吸附源到屏幕边缘" +Basic.Settings.General.CenterSnapping="吸附源到水平和垂直中心" +Basic.Settings.General.SourceSnapping="吸附源到其他的源" +Basic.Settings.General.SnapDistance="吸附敏感度" +Basic.Settings.General.RecordWhenStreaming="推流时自动录像" +Basic.Settings.General.KeepRecordingWhenStreamStops="推流停止后继续录像" Basic.Settings.General.ReplayBufferWhileStreaming="推流时自动启动重播缓冲区" -Basic.Settings.General.KeepReplayBufferStreamStops="推流停止时重播缓冲区保持活动状态" +Basic.Settings.General.KeepReplayBufferStreamStops="推流停止后保持重播缓冲区启用" Basic.Settings.General.SysTray="系统托盘" Basic.Settings.General.SysTrayWhenStarted="开始时最小化到系统托盘" -Basic.Settings.General.SystemTrayHideMinimize="总是最小化到系统托盘, 而不是任务栏" -Basic.Settings.General.SaveProjectors="退出时保存投影仪" +Basic.Settings.General.SystemTrayHideMinimize="总是最小化到系统托盘,而不是任务栏" +Basic.Settings.General.SaveProjectors="退出时保存投影窗口设置" +Basic.Settings.General.Preview="预览" +Basic.Settings.General.OverflowHidden="隐藏溢出" +Basic.Settings.General.OverflowAlwaysVisible="溢出始终可见" +Basic.Settings.General.OverflowSelectionHidden="即使源不可见,也会显示溢出" Basic.Settings.General.SwitchOnDoubleClick="双击时切换到场景" Basic.Settings.General.StudioPortraitLayout="启用纵向布局" +Basic.Settings.General.TogglePreviewProgramLabels="显示 预览/输出 标签" Basic.Settings.General.Multiview="多视图" -Basic.Settings.General.Multiview.MouseSwitch="点击切换场景" -Basic.Settings.General.Multiview.DrawSourceNames="显示场景名" -Basic.Settings.General.Multiview.DrawSafeAreas="显示安全区域(EBU R 95)" +Basic.Settings.General.Multiview.MouseSwitch="单击以切换场景" +Basic.Settings.General.Multiview.DrawSourceNames="显示场景名称" +Basic.Settings.General.Multiview.DrawSafeAreas="显示安全区域(EBU R 95)" Basic.Settings.General.MultiviewLayout="多视图布局" -Basic.Settings.General.MultiviewLayout.Horizontal.Top="水平, 顶部(8 场景)" -Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="水平, 底部(8 场景)" -Basic.Settings.General.MultiviewLayout.Vertical.Left="垂直, 左侧(8 场景)" -Basic.Settings.General.MultiviewLayout.Vertical.Right="垂直, 右侧(8 场景)" -Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="水平, 顶部(24 场景)" +Basic.Settings.General.MultiviewLayout.Horizontal.Top="横向平铺,顶部(8 场景)" +Basic.Settings.General.MultiviewLayout.Horizontal.Bottom="横向平铺,底部(8 场景)" +Basic.Settings.General.MultiviewLayout.Vertical.Left="纵向平铺,左侧(8 场景)" +Basic.Settings.General.MultiviewLayout.Vertical.Right="纵向平铺,右侧(8 场景)" +Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="横向平铺,顶部(24 场景)" -Basic.Settings.Stream="流" -Basic.Settings.Stream.StreamType="流类型" +Basic.Settings.Stream="推流" +Basic.Settings.Stream.StreamType="推流类型" +Basic.Settings.Stream.Custom.UseAuthentication="使用身份验证" +Basic.Settings.Stream.Custom.Username="用户名" +Basic.Settings.Stream.Custom.Password="密码" +Basic.Settings.Stream.BandwidthTestMode="启用带宽测试模式" Basic.Settings.Output="输出" Basic.Settings.Output.Format="录像格式" @@ -541,46 +596,45 @@ Basic.Settings.Output.Mode.Simple="简单" Basic.Settings.Output.Mode.Adv="高级" Basic.Settings.Output.Mode.FFmpeg="FFmpeg 输出" Basic.Settings.Output.UseReplayBuffer="启用回放缓存" -Basic.Settings.Output.ReplayBuffer.SecondsMax="最大回放时间(秒)" -Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大内存(Mb)" -Basic.Settings.Output.ReplayBuffer.Estimate="估计内存使用率: %1 MB" -Basic.Settings.Output.ReplayBuffer.EstimateUnknown="无法估计内存使用率. 请设置最大内存限制." -Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注意: 确保在快捷键部分设置一个回放缓冲区的快捷键)" +Basic.Settings.Output.ReplayBuffer.SecondsMax="最大回放时间(秒)" +Basic.Settings.Output.ReplayBuffer.MegabytesMax="最大内存(MB)" +Basic.Settings.Output.ReplayBuffer.Estimate="估计内存使用量:%1 MB" +Basic.Settings.Output.ReplayBuffer.EstimateUnknown="无法估计内存使用量。请设置最大内存限制。" +Basic.Settings.Output.ReplayBuffer.HotkeyMessage="(注意:一定要在快捷键部分为保存回放缓存设置快捷键)" Basic.Settings.Output.ReplayBuffer.Prefix="回放缓存文件名前缀" Basic.Settings.Output.ReplayBuffer.Suffix="后缀" Basic.Settings.Output.Simple.SavePath="录像路径" Basic.Settings.Output.Simple.RecordingQuality="录像质量" -Basic.Settings.Output.Simple.RecordingQuality.Stream="与流相同" +Basic.Settings.Output.Simple.RecordingQuality.Stream="与串流画质相同" Basic.Settings.Output.Simple.RecordingQuality.Small="高质量, 中等文件大小" Basic.Settings.Output.Simple.RecordingQuality.HQ="近似无损的质量, 大文件大小" Basic.Settings.Output.Simple.RecordingQuality.Lossless="无损的质量, 非常大的文件大小" Basic.Settings.Output.Simple.Warn.VideoBitrate="警告: 视频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." Basic.Settings.Output.Simple.Warn.AudioBitrate="警告: 音频比特率将设置为 %1, 这是当前的流媒体服务的上限值. 如果你确定你想要超过 %1, 启用高级的编码器选项并取消选中\"强制流媒体服务比特率限制\"." Basic.Settings.Output.Simple.Warn.Encoder="警告: 同时传输流和录像, 并使用软件编码器编码与流不同的质量, 将会需要额外的CPU使用." -Basic.Settings.Output.Simple.Warn.Lossless="警告: 无损质量产生的文件大小非常大! 无损质量在高分辨率和帧速率的情况下可以使用超过7GB的磁盘空间每分钟。 无损不适合长时间录像,除非你有很多可用的磁盘空间。" +Basic.Settings.Output.Simple.Warn.Lossless="警告:无损质量产生的文件大小非常大!无损质量在高分辨率和帧速率的情况下每分钟可使用超过 7GB 的磁盘空间。无损不适合长时间录像,除非你有很多可用的磁盘空间。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你确定你想要使用无损质量?" Basic.Settings.Output.Simple.Warn.Lossless.Title="无损质量警告!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="警告: 当同时推流和录像时, 你不能使用多个单独的 QSV 编码器. 如果你想要同时推流和录像, 请更改录像的编码器或者推流的编码器." -Basic.Settings.Output.Simple.Encoder.Software="软件 (x264)" -Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬件 (QSV)" -Basic.Settings.Output.Simple.Encoder.Hardware.AMD="硬件 (AMD)" -Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬件 (NVENC)" -Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="软件 (x 264 低 CPU 使用率预设,增加文件大小)" +Basic.Settings.Output.Simple.Encoder.Software="软件(x264)" +Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬件(QSV)" +Basic.Settings.Output.Simple.Encoder.Hardware.AMD="硬件(AMD)" +Basic.Settings.Output.Simple.Encoder.Hardware.NVENC="硬件(NVENC)" +Basic.Settings.Output.Simple.Encoder.SoftwareLowCPU="软件(x264 低 CPU 使用率预设,将会增加文件大小)" Basic.Settings.Output.VideoBitrate="视频比特率" Basic.Settings.Output.AudioBitrate="音频比特率" Basic.Settings.Output.Reconnect="自动重连" -Basic.Settings.Output.RetryDelay="重试延迟时间 (秒)" +Basic.Settings.Output.RetryDelay="重试间隔(秒)" Basic.Settings.Output.MaxRetries="最大重试次数" Basic.Settings.Output.Advanced="启用高级编码器设置" -Basic.Settings.Output.EncoderPreset="编码器预设 (更高 = 较少的CPU占用)" +Basic.Settings.Output.EncoderPreset="编码器预设" Basic.Settings.Output.CustomEncoderSettings="自定义编码器设置" -Basic.Settings.Output.CustomMuxerSettings="自定义 Muxer 设置" -Basic.Settings.Output.NoSpaceFileName="生成没有空格文件名" +Basic.Settings.Output.CustomMuxerSettings="自定义混流器设置" +Basic.Settings.Output.NoSpaceFileName="生成没有空格的文件名" Basic.Settings.Output.Adv.Rescale="重新缩放输出" Basic.Settings.Output.Adv.AudioTrack="音轨" -Basic.Settings.Output.Adv.Streaming="流" -Basic.Settings.Output.Adv.ApplyServiceSettings="强制流服务编码器设置" +Basic.Settings.Output.Adv.Streaming="串流" +Basic.Settings.Output.Adv.ApplyServiceSettings="强制执行流媒体服务编码器设置" Basic.Settings.Output.Adv.Audio.Track1="轨道 1" Basic.Settings.Output.Adv.Audio.Track2="轨道 2" Basic.Settings.Output.Adv.Audio.Track3="轨道 3" @@ -592,9 +646,9 @@ Basic.Settings.Output.Adv.Recording="录像" Basic.Settings.Output.Adv.Recording.Type="类型" Basic.Settings.Output.Adv.Recording.Type.Standard="标准" Basic.Settings.Output.Adv.Recording.Type.FFmpegOutput="自定义输出 (FFmpeg)" -Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(使用流编码器)" +Basic.Settings.Output.Adv.Recording.UseStreamEncoder="(使用串流编码器)" Basic.Settings.Output.Adv.Recording.Filename="文件名格式" -Basic.Settings.Output.Adv.Recording.OverwriteIfExists="如果文件存在, 覆盖" +Basic.Settings.Output.Adv.Recording.OverwriteIfExists="如果文件存在则覆盖" Basic.Settings.Output.Adv.FFmpeg.Type="FFmpeg 输出类型" Basic.Settings.Output.Adv.FFmpeg.Type.URL="输出到 URL" Basic.Settings.Output.Adv.FFmpeg.Type.RecordToFile="输出到文件" @@ -606,37 +660,37 @@ Basic.Settings.Output.Adv.FFmpeg.FormatAudio="音频" Basic.Settings.Output.Adv.FFmpeg.FormatVideo="视频" Basic.Settings.Output.Adv.FFmpeg.FormatDefault="默认格式" Basic.Settings.Output.Adv.FFmpeg.FormatDesc="容器格式说明" -Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="通过文件路径或者URL推断音频/视频格式" +Basic.Settings.Output.Adv.FFmpeg.FormatDescDef="通过文件路径或 URL 推断音频/视频格式" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDefault="默认编码器" Basic.Settings.Output.Adv.FFmpeg.AVEncoderDisable="禁用编码器" Basic.Settings.Output.Adv.FFmpeg.VEncoder="视频编码器" -Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="视频编码器设置 (如果有)" +Basic.Settings.Output.Adv.FFmpeg.VEncoderSettings="视频编码器设置(如果有)" Basic.Settings.Output.Adv.FFmpeg.AEncoder="音频编码器" -Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="视频编码器设置 (如果有)" -Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="Muxer 设置 (如果有)" -Basic.Settings.Output.Adv.FFmpeg.GOPSize="关键帧间隔 (帧)" -Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="显示所有编解码器 (即使可能不兼容)" +Basic.Settings.Output.Adv.FFmpeg.AEncoderSettings="音频编码器设置(如果有)" +Basic.Settings.Output.Adv.FFmpeg.MuxerSettings="混流器设置(如果有)" +Basic.Settings.Output.Adv.FFmpeg.GOPSize="关键帧间隔(帧)" +Basic.Settings.Output.Adv.FFmpeg.IgnoreCodecCompat="显示所有编码器(即使可能不兼容)" FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z" -FilenameFormatting.TT="%CCYY 年, 4位\n%YY 年, 后两位 (00-99)\n%MM 月份 (01-12)\n%DD 日, 用0补充 (01-31)\n%hh 24小时制小时 (00-23)\n%mm 分钟 (00-59)\n%ss 秒 (00-61)\n%% A % sign\n%a 缩写工作日名称\n%A 完整工作日名称\n%b 缩写月份名称\n%B 完整月份名称\n%d 日, 用0补充 (01-31)\n%H 24小时制小时 (00-23)\n%I 12小时制小时 (01-12)\n%m 月份 (01-12)\n%M 分支 (00-59)\n%p AM 或 PM\n%S 秒 (00-61)\n%y 年, 后两位 (00-99)\n%Y 年\n%z ISO 8601 offset from UTC 或者 时区\n 名称或缩写\n%Z 时区名称或缩写\n" +FilenameFormatting.TT="%CCYY 年,4位\n%YY 年,后两位(00-99)\n%MM 月份(01-12)\n%DD 日,用0补全(01-31)\n%hh 24小时制小时(00-23)\n%mm 分钟(00-59)\n%ss 秒(00-61)\n%% 一个“%”符号\n%a 缩写工作日名称\n%A 完整工作日名称\n%b 缩写月份名称\n%B 完整月份名称\n%d 日,用0补全(01-31)\n%H 24小时制小时(00-23)\n%I 12小时制小时(01-12)\n%m 月份(01-12)\n%M 分钟(00-59)\n%p AM 或 PM\n%S 秒(00-61)\n%y 年,后两位(00-99)\n%Y 年\n%z 与UTC的时差(ISO 8601 格式)\n%Z 时区名称或缩写\n" Basic.Settings.Video="视频" Basic.Settings.Video.Adapter="视频适配器" -Basic.Settings.Video.BaseResolution="基础 (Canvas) 分辨率" +Basic.Settings.Video.BaseResolution="基础(画布)分辨率" Basic.Settings.Video.ScaledResolution="输出 (缩放) 分辨率" -Basic.Settings.Video.DownscaleFilter="缩放过滤器" +Basic.Settings.Video.DownscaleFilter="缩小方法" Basic.Settings.Video.DisableAeroWindows="禁用 Aero (仅限 Windows)" -Basic.Settings.Video.FPS="每秒帧数:" -Basic.Settings.Video.FPSCommon="常见的 FPS 值" -Basic.Settings.Video.FPSInteger="整数 FPS 值" -Basic.Settings.Video.FPSFraction="分数帧率值" +Basic.Settings.Video.FPS="FPS(每秒帧数)" +Basic.Settings.Video.FPSCommon="常用 FPS 值(帧率)" +Basic.Settings.Video.FPSInteger="整数 FPS 值(帧率)" +Basic.Settings.Video.FPSFraction="分数 FPS 值(帧率)" Basic.Settings.Video.Numerator="分子:" Basic.Settings.Video.Denominator="分母:" Basic.Settings.Video.Renderer="渲染器:" -Basic.Settings.Video.InvalidResolution="无效的分辨率值。必须是 [宽]x[高] (如 1920 x 1080)" +Basic.Settings.Video.InvalidResolution="无效的分辨率值。必须是 [宽]x[高](如 1920x1080)" Basic.Settings.Video.CurrentlyActive="视频输出处于活动状态。请关闭任何输出以更改视频设置。" -Basic.Settings.Video.DisableAero="禁用Aero" +Basic.Settings.Video.DisableAero="禁用 Aero" Basic.Settings.Video.DownscaleFilter.Bilinear="双直线法(最快, 但如果缩放会模糊)" Basic.Settings.Video.DownscaleFilter.Bicubic="两次立方(削尖缩放, 16 个样本)" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(削尖缩放, 32个样本) Basic.Settings.Audio="音频" Basic.Settings.Audio.SampleRate="采样率" Basic.Settings.Audio.Channels="声道" -Basic.Settings.Audio.MeterDecayRate="音频表衰减率" +Basic.Settings.Audio.Meters="电平表" +Basic.Settings.Audio.MeterDecayRate="衰减速率" Basic.Settings.Audio.MeterDecayRate.Fast="快速" Basic.Settings.Audio.MeterDecayRate.Medium="中速(峰值电平表I型)" Basic.Settings.Audio.MeterDecayRate.Slow="慢速(峰值电平表II型)" @@ -653,19 +708,22 @@ Basic.Settings.Audio.PeakMeterType="峰值计类型" Basic.Settings.Audio.PeakMeterType.SamplePeak="采样峰值" Basic.Settings.Audio.PeakMeterType.TruePeak="真峰值 (更高的的 CPU 使用率)" Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: 已启用环绕声音频。" -Basic.Settings.Audio.MultichannelWarning="如果串流, 请检查串流服务是否支持环绕立体声接收和环绕立体声播放。 Twitch, Facebook 360 Live, Mixer RTMP, Smashcast 是充分支持环绕立体声的例子。 虽然 Facebook Live 和 Youtube Live 都支持环绕立体声接收, 但是Facebook Live 降低混合至立体声, 而 Youtube Live 则只播放两个声道。\n\nOBS 音频过滤器与环绕立体声兼容, 但 VST 插件支持无法保证。" +Basic.Settings.Audio.MultichannelWarning="如果是串流,请检查你的串流服务是否支持环绕立体声的接收与播放。Twitch、Facebook 360 Live、Mixer RTMP、Smashcast 皆完全支持环绕立体声。虽然 Facebook Live 和 YouTube Live 都支持对环绕立体声的接收,但是 Facebook Live 将把声音混音成立体声,而 YouTube Live 则只播放两个声道。\n\n虽然无法保证 VST 插件对其的支持,但 OBS 的音频滤镜与环绕立体声兼容。" Basic.Settings.Audio.MultichannelWarning.Title="是否启用环绕立体声?" Basic.Settings.Audio.MultichannelWarning.Confirm="确实要启用环绕立体声吗?" -Basic.Settings.Audio.DesktopDevice="桌面音频设备" -Basic.Settings.Audio.DesktopDevice2="桌面音频设备 2" -Basic.Settings.Audio.AuxDevice="麦克风/辅助音频设备" -Basic.Settings.Audio.AuxDevice2="麦克风/辅助音频设备 2" -Basic.Settings.Audio.AuxDevice3="麦克风/辅助音频设备 3" +Basic.Settings.Audio.Devices="设备" +Basic.Settings.Audio.DesktopDevice="桌面音频" +Basic.Settings.Audio.DesktopDevice2="桌面音频 2" +Basic.Settings.Audio.AuxDevice="麦克风/辅助音频" +Basic.Settings.Audio.AuxDevice2="麦克风/辅助音频 2" +Basic.Settings.Audio.AuxDevice3="麦克风/辅助音频 3" +Basic.Settings.Audio.AuxDevice4="麦克风/辅助音频 4" Basic.Settings.Audio.EnablePushToMute="启用按住静音" Basic.Settings.Audio.PushToMuteDelay="按住静音延迟" Basic.Settings.Audio.EnablePushToTalk="启动按住讲话" Basic.Settings.Audio.PushToTalkDelay="按住讲话延时" Basic.Settings.Audio.UnknownAudioDevice="[设备未连接或不可用]" +Basic.Settings.Audio.Disabled="已禁用" Basic.Settings.Advanced="高级" Basic.Settings.Advanced.General.ProcessPriority="进程优先级" @@ -674,75 +732,78 @@ Basic.Settings.Advanced.General.ProcessPriority.AboveNormal="高于正常" Basic.Settings.Advanced.General.ProcessPriority.Normal="常规" Basic.Settings.Advanced.General.ProcessPriority.BelowNormal="低于正常" Basic.Settings.Advanced.General.ProcessPriority.Idle="空闲" -Basic.Settings.Advanced.FormatWarning="警告: NV12 之外的颜色格式主要用于录像, 并不推荐在流式传输时使用. 流可能导致更多的 CPU 使用率, 因为需要颜色格式转换." +Basic.Settings.Advanced.FormatWarning="警告:NV12 之外的色彩格式主要用于录像,并不推荐在串流时使用。因为串流时需要进行色彩格式转换,可能会导致 CPU 使用率增加。" Basic.Settings.Advanced.Audio.BufferingTime="音频缓冲时间" Basic.Settings.Advanced.Video.ColorFormat="颜色格式" -Basic.Settings.Advanced.Video.ColorSpace="YUV 颜色空间" -Basic.Settings.Advanced.Video.ColorRange="YUV 颜色范围" +Basic.Settings.Advanced.Video.ColorSpace="色彩空间" +Basic.Settings.Advanced.Video.ColorRange="色彩范围" Basic.Settings.Advanced.Video.ColorRange.Partial="局部" Basic.Settings.Advanced.Video.ColorRange.Full="全部" -Basic.Settings.Advanced.Audio.MonitoringDevice="音频监测设备" +Basic.Settings.Advanced.Audio.MonitoringDevice="监听设备" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="默认" -Basic.Settings.Advanced.Audio.DisableAudioDucking="禁用 Windows 音频闪避" -Basic.Settings.Advanced.StreamDelay="流延迟" -Basic.Settings.Advanced.StreamDelay.Duration="持续时间 (秒)" +Basic.Settings.Advanced.Audio.DisableAudioDucking="禁用 Windows 音频闪避(检测到通信活动时降低其他声音的音量)" +Basic.Settings.Advanced.StreamDelay="串流延迟" +Basic.Settings.Advanced.StreamDelay.Duration="延迟时间(秒)" Basic.Settings.Advanced.StreamDelay.Preserve="重新连接时保持截止点 (增加延迟)" -Basic.Settings.Advanced.StreamDelay.MemoryUsage="估计的内存使用率: %1 MB" +Basic.Settings.Advanced.StreamDelay.MemoryUsage="估计内存使用量:%1 MB" Basic.Settings.Advanced.Network="网络" -Basic.Settings.Advanced.Network.BindToIP="绑定 IP" +Basic.Settings.Advanced.Network.BindToIP="绑定到 IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="启用新的网络代码" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延迟模式" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="当主窗口获得焦点时禁用热键" +Basic.Settings.Advanced.AutoRemux="自动封装至 MP4 格式" +Basic.Settings.Advanced.AutoRemux.MP4="(录制为 mkv 格式)" Basic.AdvAudio="高级音频属性" Basic.AdvAudio.Name="名称" -Basic.AdvAudio.Volume="音量 (%)" -Basic.AdvAudio.Mono="下降混合为单声道" -Basic.AdvAudio.Panning="平移" +Basic.AdvAudio.Volume="音量" +Basic.AdvAudio.Mono="混缩为单声道" +Basic.AdvAudio.Balance="平衡" Basic.AdvAudio.SyncOffset="同步偏移 (毫秒)" Basic.AdvAudio.Monitoring="音频监听" -Basic.AdvAudio.Monitoring.None="关闭监视" -Basic.AdvAudio.Monitoring.MonitorOnly="仅显示器(静音输出)" +Basic.AdvAudio.Monitoring.None="关闭监听" +Basic.AdvAudio.Monitoring.MonitorOnly="仅监听(输出静音)" Basic.AdvAudio.Monitoring.Both="监听并输出" Basic.AdvAudio.AudioTracks="轨道" Basic.Settings.Hotkeys="热键" -Basic.Settings.Hotkeys.Pair="作为切换的键组合与 '%1' 共享" +Basic.Settings.Hotkeys.Pair="当按键组合与“%1”相同时,作为切换开关使用" +Basic.Settings.Hotkeys.Filter="筛选" Basic.Hotkeys.SelectScene="切换到场景" Basic.SystemTray.Show="显示" Basic.SystemTray.Hide="隐藏" -Basic.SystemTray.Message.Reconnecting="已断开连接。 重新连接..." +Basic.SystemTray.Message.Reconnecting="已断开连接。 正在重新连接…" -Hotkeys.Insert="插入" -Hotkeys.Delete="删除" -Hotkeys.Home="首页" -Hotkeys.End="结束" -Hotkeys.PageUp="上一页" -Hotkeys.PageDown="下一页" -Hotkeys.NumLock="Num Lock 键" -Hotkeys.ScrollLock="滚动锁定" -Hotkeys.CapsLock="大写锁定" -Hotkeys.Backspace="退格键" -Hotkeys.Tab="选项卡" -Hotkeys.Print="打印" -Hotkeys.Pause="暂停" +Hotkeys.Insert="Insert" +Hotkeys.Delete="Delete" +Hotkeys.Home="Home" +Hotkeys.End="End" +Hotkeys.PageUp="Page Up" +Hotkeys.PageDown="Page Down" +Hotkeys.NumLock="Num Lock" +Hotkeys.ScrollLock="Scroll Lock" +Hotkeys.CapsLock="Caps Lock" +Hotkeys.Backspace="Backspace" +Hotkeys.Tab="Tab" +Hotkeys.Print="Print" +Hotkeys.Pause="Pause" Hotkeys.Left="左" Hotkeys.Right="右" Hotkeys.Up="上" Hotkeys.Down="下" -Hotkeys.Windows="窗口" -Hotkeys.Super="超级" -Hotkeys.Menu="菜单" +Hotkeys.Windows="Windows" +Hotkeys.Super="Super" +Hotkeys.Menu="Menu" Hotkeys.Space="空格" -Hotkeys.NumpadNum="数字键 %1" -Hotkeys.NumpadMultiply="数字键 乘" -Hotkeys.NumpadDivide="数字键 除" -Hotkeys.NumpadAdd="数字键 加" -Hotkeys.NumpadSubtract="数字键 减" -Hotkeys.NumpadDecimal="数字键 十进制" +Hotkeys.NumpadNum="小键盘 %1" +Hotkeys.NumpadMultiply="小键盘 乘" +Hotkeys.NumpadDivide="小键盘 除" +Hotkeys.NumpadAdd="小键盘 加" +Hotkeys.NumpadSubtract="小键盘 减" +Hotkeys.NumpadDecimal="小键盘 点" Hotkeys.AppleKeypadNum="%1 (键盘)" Hotkeys.AppleKeypadMultiply="* (键盘)" Hotkeys.AppleKeypadDivide="/ (键盘)" @@ -751,28 +812,44 @@ Hotkeys.AppleKeypadSubtract="- (键盘)" Hotkeys.AppleKeypadDecimal=".(键盘)" Hotkeys.AppleKeypadEqual="= (键盘)" Hotkeys.MouseButton="鼠标 %1" +Hotkeys.Escape="Esc" Mute="静音" Unmute="取消静音" Push-to-mute="按住静音" Push-to-talk="按住讲话" -SceneItemShow="显示 '%1'" -SceneItemHide="隐藏 '%1'" +SceneItemShow="显示“%1”" +SceneItemHide="隐藏“%1”" OutputWarnings.NoTracksSelected="您必须选择至少一个轨道" OutputWarnings.MultiTrackRecording="警告: 某些格式 (如 FLV) 不支持每个录像多个轨道" -OutputWarnings.MP4Recording="警告︰ 录制保存到 MP4 将无法恢复,如果该文件不能完成 (例如由于蓝屏死机,掉电等)。如果您想要记录多个音频轨道考虑使用 MKV 然后在它完成后 remux 录制到 mp4 (文件 -> Remux 录制文件)" +OutputWarnings.MP4Recording="警告:如果文件无法完成(例如,由于蓝屏BSOD,掉电等),保存到 MP4/MOV 的记录将无法恢复。如果要录制多个音轨,请考虑使用 MKV 录制,并在完成后将录像重新封装为 MP4/MOV(文件→录像转封装)" FinalScene.Title="删除场景" FinalScene.Text="至少要有一个场景." NoSources.Title="无来源" -NoSources.Text="看起来您未添加任何视频源,所以我们将只会输出黑色萤幕。确实要这样做吗?" +NoSources.Text="看起来您未添加任何视频源,所以我们将只会输出黑色画面。确实要这样做吗?" NoSources.Text.AddSource="您可以通过单击主窗口中“来源”框下的“+”图标以添加来源。" +NoSources.Label="您还没有添加任何源。\n点击下面的 + 按钮,\n或者右击此处添加一个。" ChangeBG="设置颜色" CustomColor="自定义颜色" BrowserSource.EnableHardwareAcceleration="启用浏览器源硬件加速" +About="关于" +About.Info="OBS Studio是一个自由、开源的视频录制与直播软件。" +About.Donate="做出贡献" +About.GetInvolved="参与贡献" +About.Authors="作者" +About.License="许可" +About.Contribute="支持 OBS 项目" + +ResizeOutputSizeOfSource="调整输出大小(到源大小)" +ResizeOutputSizeOfSource.Text="基准与输出分辨率将调整为当前源大小。" +ResizeOutputSizeOfSource.Continue="您是否想要继续?" + +PreviewTransition="预览转场" + diff --git a/UI/data/locale/zh-TW.ini b/UI/data/locale/zh-TW.ini index bc2a215..8c8a6f5 100644 --- a/UI/data/locale/zh-TW.ini +++ b/UI/data/locale/zh-TW.ini @@ -1,5 +1,5 @@ -Language="繁體中文" +Language="正體中文(臺灣)" Region="臺灣/香港/澳門" OK="確定" @@ -80,14 +80,40 @@ StudioMode.Program="程式" ShowInMultiview="在多視圖中顯示" VerticalLayout="垂直排版" Group="群組" +DoNotShowAgain="不再顯示" +Default="(預設)" +Calculating="正在計算……" AlreadyRunning.Title="OBS 已在執行中" AlreadyRunning.Text="OBS 已在執行中!除非這是您的意圖,請在執行新的 OBS 前關閉現存的 OBS 。如果有設定 OBS 最小化到系統工具列,請確認是否仍在該處執行。" AlreadyRunning.LaunchAnyway="強制啟動" +DockCloseWarning.Title="關閉停駐視窗" +DockCloseWarning.Text="您剛關閉了一個停駐視窗。若想再次顯示,請重新在選單欄的「檢視」->「停駐視窗」選單開啟此視窗。" + +Auth.Authing.Title="正在認證中…" +Auth.Authing.Text="正在透過 %1 認證,請稍候…" +Auth.AuthFailure.Title="身份驗證失敗" +Auth.AuthFailure.Text="%1 認證失敗:\n\n%2: %3" +Auth.InvalidScope.Title="需要身份驗證" +Auth.InvalidScope.Text="%1 的身份驗證要求已更改。 某些功能可能不可用。" +Auth.LoadingChannel.Title="正在載入頻道資訊…" +Auth.LoadingChannel.Text="正在載入 %1 的頻道資訊,請稍候…" +Auth.ChannelFailure.Title="讀取頻道資訊失敗" +Auth.ChannelFailure.Text="讀取 %1 頻道失敗\n\n%2: %3" +Auth.Chat="聊天室" +Auth.StreamInfo="實況資訊" +TwitchAuth.Stats="Twitch狀態" +TwitchAuth.Feed="Twitch 活動摘要" +TwitchAuth.TwoFactorFail.Title="無法查詢串流金鑰" +TwitchAuth.TwoFactorFail.Text="OBS 無法連線至您的 Twitch 帳號。請確保您已經在 Twitch 安全性設定 中設定串流所需的兩步驟驗證。" + Copy.Filters="複製過濾器" Paste.Filters="貼上篩選器" +BrowserPanelInit.Title="正在初始化瀏覽器…" +BrowserPanelInit.Text="正在初始化瀏覽器,請稍候…" + BandwidthTest.Region="區域" BandwidthTest.Region.US="美國" BandwidthTest.Region.EU="歐洲" @@ -95,11 +121,9 @@ BandwidthTest.Region.Asia="亞洲" BandwidthTest.Region.Other="其他" Basic.FirstStartup.RunWizard="您想要運行自動設定精靈嗎? 也可以透過點選主視窗中的設定按鈕來手動設定。" -Basic.FirstStartup.RunWizard.BetaWarning="(注意: 自動設定精靈目前處於 Beta 階段)" Basic.FirstStartup.RunWizard.NoClicked="如果你改變主意,可以隨時從工具功能表再次執行自動設定精靈。" Basic.AutoConfig="自動設定精靈" -Basic.AutoConfig.Beta="自動設定精靈 (Beta)" Basic.AutoConfig.ApplySettings="套用設定" Basic.AutoConfig.StartPage="使用資訊" Basic.AutoConfig.StartPage.SubTitle="指定想運用的場合" @@ -115,8 +139,14 @@ Basic.AutoConfig.VideoPage.FPS.PreferHighRes="60 或 30,但優先高解析度" Basic.AutoConfig.VideoPage.CanvasExplanation="注︰ 畫布(來源)解析度並不一定與串流或錄影相同。實際的串流/錄影解析度可以從畫布解析度縮小以減少資源使用或位元率需求。" Basic.AutoConfig.StreamPage="串流資訊" Basic.AutoConfig.StreamPage.SubTitle="請輸入您的串流資訊" +Basic.AutoConfig.StreamPage.ConnectAccount="連結帳號 (選用)" +Basic.AutoConfig.StreamPage.DisconnectAccount="解除帳號連結" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title="是否要解除帳號連結?" +Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text="此變更將立即套用,確定斷開帳號連結?" +Basic.AutoConfig.StreamPage.UseStreamKey="使用串流金鑰" Basic.AutoConfig.StreamPage.Service="服務" Basic.AutoConfig.StreamPage.Service.ShowAll="顯示全部..." +Basic.AutoConfig.StreamPage.Service.Custom="自訂…" Basic.AutoConfig.StreamPage.Server="伺服器" Basic.AutoConfig.StreamPage.StreamKey="串流金鑰" Basic.AutoConfig.StreamPage.StreamKey.LinkToSite="(連結)" @@ -159,6 +189,10 @@ Basic.Stats.Status.Inactive="未啟動" Basic.Stats.DroppedFrames="丟棄的訊框 (網路)" Basic.Stats.MegabytesSent="總輸出資料" Basic.Stats.Bitrate="位元率" +Basic.Stats.DiskFullIn="(估計)硬碟空間用盡前剩餘錄影時長" + +ResetUIWarning.Title="確定要重置介面嗎?" +ResetUIWarning.Text="重設介面將隱藏額外的停駐視窗。若想重新顯示這些停駐視窗,則需要進入「檢視」選單解除隱藏。\n\n是否重設介面?" Updater.Title="有新更新" Updater.Text="有新更新︰" @@ -171,7 +205,7 @@ Updater.NoUpdatesAvailable.Title="沒有更新" Updater.NoUpdatesAvailable.Text="沒有更新" Updater.FailedToLaunch="啟動更新程式失敗" Updater.GameCaptureActive.Title="遊戲擷取使用中" -Updater.GameCaptureActive.Text="遊戲擷取函式庫正在使用中。 請關閉所有被擷取的遊戲/程式 (或重新開機 windows),然後重試。" +Updater.GameCaptureActive.Text="遊戲擷取函式庫正在使用中。 請關閉所有被擷取的遊戲/程式 (或重新開機 Windows),然後重試。" QuickTransitions.SwapScenes="轉場後交換預覽/輸出場景" QuickTransitions.SwapScenesTT="(如果輸出的原始場景仍然存在) 轉場後交換預覽和輸出場景。\n這並不會復原任何對輸出原始場景所作的改動。" @@ -181,7 +215,7 @@ QuickTransitions.EditProperties="複製來源" QuickTransitions.EditPropertiesTT="在修改同樣的場景時,讓修改影像來源的屬性時不需要修改輸出。\n這只能在'複製場景'被啟動時使用。\n某些來源 (如擷取或是媒體來源) 並不支援此功能且無法被單獨修改。\n變更這個值將會 (如果還存在的話) 重置目前的輸出場景。\n\n警告:由於來源會被複製,這功能可能會使用額外的系統或是影像資源。" QuickTransitions.HotkeyName="快速轉場:%1" -Basic.AddTransition="添加設置轉換" +Basic.AddTransition="新增可選的轉場特效" Basic.RemoveTransition="移除可選的轉場特效" Basic.TransitionProperties="轉場特效屬性" Basic.SceneTransitions="轉場特效" @@ -206,6 +240,9 @@ ConfirmStart.Text="你確定你想要啟動串流?" ConfirmStop.Title="停止串流?" ConfirmStop.Text="你確定你想要停止串流?" +ConfirmBWTest.Title="開始頻寬測試?" +ConfirmBWTest.Text="你已在頻寬測試模式下配置了 OBS。此模式允許在沒有開始直播的情況下進行網路測試。完成測試後,你要禁用它才可以進行直播。\n\n要繼續嗎?" + ConfirmExit.Title="離開OBS?" ConfirmExit.Text="正在使用 OBS,所有的串流/錄製都將被關閉。您確定要退出嗎?" @@ -218,6 +255,7 @@ Output.StartRecordingFailed="無法開始錄影" Output.StartReplayFailed="無法啟動重播緩衝區" Output.StartFailedGeneric="啟動輸出失敗。 詳情請看 Log 檔。\n\n注意︰ 如果你使用 NVENC 或 AMD 編碼器,請確保您的視頻驅動程式是最新。" + Output.ConnectFail.Title="連線失敗" Output.ConnectFail.BadPath="無效的路徑或 URL。 請確認您的設定是正確的。" Output.ConnectFail.ConnectFailed="與伺服器連線失敗。" @@ -225,12 +263,16 @@ Output.ConnectFail.InvalidStream="無法訪問指定的頻道或串流金鑰, Output.ConnectFail.Error="發生無法預期的連線錯誤。 參見 Log 檔以便獲取更多資訊。" Output.ConnectFail.Disconnected="與伺服器連線中斷。" +Output.StreamEncodeError.Title="編碼錯誤" +Output.StreamEncodeError.Msg="直播時編碼器發生錯誤。" + Output.RecordFail.Title="無法開始錄影" Output.RecordFail.Unsupported="輸出格式不被支援或不支援超過一個音軌。請確認你的設定後再試一次。" Output.RecordNoSpace.Title="硬碟空間不足" Output.RecordNoSpace.Msg="沒有足夠的空間存放錄製影片" Output.RecordError.Title="錄製錯誤" Output.RecordError.Msg="在錄製時發生了預料外的錯誤。" +Output.RecordError.EncodeErrorMsg="錄影時編碼器發生錯誤。" Output.ReplayBuffer.NoHotkey.Title="沒有設定熱鍵 !" Output.ReplayBuffer.NoHotkey.Msg="沒有為重播緩衝設定儲存重播熱鍵。請設定\"儲存重播\"熱鍵以保存重播。" @@ -241,28 +283,26 @@ LogReturnDialog="上傳 Log 成功" LogReturnDialog.CopyURL="複製連結" LogReturnDialog.ErrorUploadingLog="上傳 Log 失敗" -LicenseAgreement="授權條款" -LicenseAgreement.PleaseReview="請先閱讀並同意授權條款。 使用本軟體(OBS)時,您必須遵守 GNU General Public License v2.0 條款。 請往下閱讀整個授權條款。" -LicenseAgreement.ClickIAgreeToContinue="如果您同意遵守,請點選「我同意」以開始使用 OBS。" -LicenseAgreement.IAgree="我同意" -LicenseAgreement.Exit="離開" - Remux.SourceFile="OBS 錄影" Remux.TargetFile="目標檔案" Remux.Remux="重新封裝" +Remux.Stop="停止重新封裝" +Remux.ClearFinished="清除已完成項目" +Remux.ClearAll="清除所有項目" Remux.OBSRecording="OBS錄影" Remux.FinishedTitle="重新封裝完成" Remux.Finished="錄影已被重新封裝" Remux.FinishedError="錄影已被重新封裝,但檔案可能不完整" -Remux.SelectRecording="選擇OBS錄影…" -Remux.SelectTarget="選擇目標檔案…" +Remux.SelectRecording="請選擇 OBS 錄影檔…" +Remux.SelectTarget="請選擇目標檔案…" Remux.FileExistsTitle="目標檔案已存在" -Remux.FileExists="目標檔案已存在,是否取代它?" +Remux.FileExists="以下的目標檔案已經存在,是否要取代?" Remux.ExitUnfinishedTitle="正在重新封裝" Remux.ExitUnfinished="尚未完成重新封裝,現在停止可能導致目標檔案損毀。\n你確定要停止重新封裝嗎?" +Remux.HelpText="將檔案拖曳到此視窗中進行 Remux,或是選擇一個空白的「OBS 錄製」元件來瀏覽檔案。" UpdateAvailable="現有新版本更新" -UpdateAvailable.Text="版本 %1.%2.%3 已釋出。 請點此下載" +UpdateAvailable.Text="版本 %1.%2.%3 已釋出。 請點此下載" Basic.DesktopDevice1="輸出音效 1" Basic.DesktopDevice2="輸出音效 2" @@ -276,11 +316,14 @@ Basic.DisplayCapture="截取螢幕" Basic.Main.PreviewConextMenu.Enable="啟用預覽" +Basic.Main.Preview.Disable="停用預覽" + ScaleFiltering="縮放濾鏡" ScaleFiltering.Point="點" ScaleFiltering.Bilinear="雙線性插值" ScaleFiltering.Bicubic="雙三次插值" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="範圍" Deinterlacing="去交錯" Deinterlacing.Discard="捨棄" @@ -428,7 +471,7 @@ Basic.MainMenu.Edit.Redo="重做 (&R)" Basic.MainMenu.Edit.UndoAction="復原 $1 (&U)" Basic.MainMenu.Edit.RedoAction="重做 $1 (&R)" Basic.MainMenu.Edit.LockPreview="鎖定預覽 (&L)" -Basic.MainMenu.Edit.Scale="預覽與縮放" +Basic.MainMenu.Edit.Scale="預覽與縮放(&S)" Basic.MainMenu.Edit.Scale.Window="縮放至視窗" Basic.MainMenu.Edit.Scale.Canvas="畫布 (%1x%2)" Basic.MainMenu.Edit.Scale.Output="輸出 (%1x%2)" @@ -445,6 +488,8 @@ Basic.MainMenu.Edit.Transform.FlipVertical="垂直翻轉 (&V)" Basic.MainMenu.Edit.Transform.FitToScreen="縮放到螢幕大小,不改變比例 (&F)" Basic.MainMenu.Edit.Transform.StretchToScreen="拉伸到螢幕大小 (&S)" Basic.MainMenu.Edit.Transform.CenterToScreen="置中畫面 (&C)" +Basic.MainMenu.Edit.Transform.VerticalCenter="垂直置中" +Basic.MainMenu.Edit.Transform.HorizontalCenter="水平置中" Basic.MainMenu.Edit.Order="排序 (&O)" Basic.MainMenu.Edit.Order.MoveUp="向上移動 (&U)" Basic.MainMenu.Edit.Order.MoveDown="向下移動 (&D)" @@ -454,8 +499,8 @@ Basic.MainMenu.Edit.AdvAudio="進階音訊屬性(&A)" Basic.MainMenu.View="檢視(&V)" Basic.MainMenu.View.Toolbars="工具列(&T)" -Basic.MainMenu.View.Docks="固定" -Basic.MainMenu.View.Docks.ResetUI="重置使用者介面" +Basic.MainMenu.View.Docks="停駐視窗" +Basic.MainMenu.View.Docks.ResetUI="重設使用者介面" Basic.MainMenu.View.Docks.LockUI="鎖定使用者介面" Basic.MainMenu.View.Toolbars.Listboxes="列表控制項(&L)" Basic.MainMenu.View.SceneTransitions="轉場特效(&c)" @@ -474,7 +519,7 @@ Basic.MainMenu.SceneCollection.Exists="已有該場景群組" Basic.MainMenu.Tools="工具(&T)" Basic.MainMenu.Help="說明 (&H)" -Basic.MainMenu.Help.HelpPortal="幫助和門戶" +Basic.MainMenu.Help.HelpPortal="幫助和門戶(&P)" Basic.MainMenu.Help.Website="前往 OBS 網站 (&W)" Basic.MainMenu.Help.Discord="加入 &Discord 伺服器" Basic.MainMenu.Help.Logs="Log 檔案 (&L)" @@ -483,9 +528,10 @@ Basic.MainMenu.Help.Logs.UploadCurrentLog="上傳目前 Log 檔 (&C)" Basic.MainMenu.Help.Logs.UploadLastLog="上傳上次的 Log 檔 (&L)" Basic.MainMenu.Help.Logs.ViewCurrentLog="顯示當前紀錄檔 (&V)" Basic.MainMenu.Help.CheckForUpdates="檢查更新" -Basic.MainMenu.Help.CrashLogs="錯誤報告" +Basic.MainMenu.Help.CrashLogs="錯誤報告 (&R)" Basic.MainMenu.Help.CrashLogs.ShowLogs="顯示當機回報(&S)" Basic.MainMenu.Help.CrashLogs.UploadLastLog="上傳最新的錯誤回報(&L)" +Basic.MainMenu.Help.About="關於(&A)" Basic.Settings.ProgramRestart="為了套用新設定,請關閉後重啟。" Basic.Settings.ConfirmTitle="確認修改" @@ -514,8 +560,13 @@ Basic.Settings.General.SysTray="系統工具列" Basic.Settings.General.SysTrayWhenStarted="開始時最小化至系統列" Basic.Settings.General.SystemTrayHideMinimize="總是最小化到系統列,而非工作列" Basic.Settings.General.SaveProjectors="退出時保存投影設定" +Basic.Settings.General.Preview="預覽" +Basic.Settings.General.OverflowHidden="隱藏畫面溢出" +Basic.Settings.General.OverflowAlwaysVisible="總是顯示溢出畫面" +Basic.Settings.General.OverflowSelectionHidden="就算來源不可見,仍顯示畫面溢出" Basic.Settings.General.SwitchOnDoubleClick="按兩下時切換到場景" Basic.Settings.General.StudioPortraitLayout="啟用縱向/垂直佈局" +Basic.Settings.General.TogglePreviewProgramLabels="顯示預覽/程式標籤" Basic.Settings.General.Multiview="多顯示" Basic.Settings.General.Multiview.MouseSwitch="點擊以在場景之間切換" Basic.Settings.General.Multiview.DrawSourceNames="顯示場景名稱" @@ -529,6 +580,10 @@ Basic.Settings.General.MultiviewLayout.Horizontal.Extended.Top="橫排、頂部 Basic.Settings.Stream="串流" Basic.Settings.Stream.StreamType="串流類型" +Basic.Settings.Stream.Custom.UseAuthentication="使用身份驗證" +Basic.Settings.Stream.Custom.Username="使用者名稱" +Basic.Settings.Stream.Custom.Password="密碼" +Basic.Settings.Stream.BandwidthTestMode="啟用頻寬測試模式" Basic.Settings.Output="輸出" Basic.Settings.Output.Format="錄影格式" @@ -560,7 +615,6 @@ Basic.Settings.Output.Simple.Warn.Encoder="警告:如果錄影與串流同時 Basic.Settings.Output.Simple.Warn.Lossless="警告:無損畫質將會產生非常大的檔案!無損畫質在高解析度或高影格率時,可能會每分鐘使用高達 7GB(gigabytes)的容量。除非您擁有非常大量的硬碟空間,否則不建議使用無損畫質錄製長時間的影片。" Basic.Settings.Output.Simple.Warn.Lossless.Msg="你確定你想要使用無損畫質?" Basic.Settings.Output.Simple.Warn.Lossless.Title="無損畫質警告!" -Basic.Settings.Output.Simple.Warn.MultipleQSV="警告︰同時串流和錄影時,不能使用多個不同的 QSV 編碼器。如果你想要在同一時間串流和錄影,請更改錄影編碼器或串流編碼器。" Basic.Settings.Output.Simple.Encoder.Software="軟體編碼( x264 )" Basic.Settings.Output.Simple.Encoder.Hardware.QSV="硬體編碼 (QSV)" Basic.Settings.Output.Simple.Encoder.Hardware.AMD="硬體 (AMD)" @@ -572,7 +626,7 @@ Basic.Settings.Output.Reconnect="自動重新連線" Basic.Settings.Output.RetryDelay="重試間隔(秒)" Basic.Settings.Output.MaxRetries="最大嘗試次數" Basic.Settings.Output.Advanced="啓用進階編碼器設定" -Basic.Settings.Output.EncoderPreset="編碼器配置 (越高 = 越少CPU使用率)" +Basic.Settings.Output.EncoderPreset="編碼器預設" Basic.Settings.Output.CustomEncoderSettings="自訂編碼器設定" Basic.Settings.Output.CustomMuxerSettings="自訂 Muxer 設定" Basic.Settings.Output.NoSpaceFileName="產生沒有空格的檔案名稱" @@ -645,7 +699,8 @@ Basic.Settings.Video.DownscaleFilter.Lanczos="Lanczos(縮放後最為銳利, Basic.Settings.Audio="音效" Basic.Settings.Audio.SampleRate="取樣頻率" Basic.Settings.Audio.Channels="通道數" -Basic.Settings.Audio.MeterDecayRate="音量計衰減速率" +Basic.Settings.Audio.Meters="計量器" +Basic.Settings.Audio.MeterDecayRate="衰變率" Basic.Settings.Audio.MeterDecayRate.Fast="快速" Basic.Settings.Audio.MeterDecayRate.Medium="中 (Type I PPM)" Basic.Settings.Audio.MeterDecayRate.Slow="慢 (Type II PPM)" @@ -656,16 +711,19 @@ Basic.Settings.Audio.MultiChannelWarning.Enabled="警告: 已啟用環繞聲音 Basic.Settings.Audio.MultichannelWarning="如果是流媒體,請檢查您的流媒體服務是否同時支持環繞聲攝取和環繞聲播放。 Twitch,Facebook 360 Live,Mixer RTMP,Smashcast都是完全支持環繞聲的例子。 儘管Facebook Live和YouTube Live都接受環繞聲攝取,但是Facebook Live會混音為立體聲,而YouTube Live只播放兩個聲道。\n\n 儘管不支持VST插件,但OBS音頻濾波器與環繞聲兼容。" Basic.Settings.Audio.MultichannelWarning.Title="是否啟用環繞聲音訊?" Basic.Settings.Audio.MultichannelWarning.Confirm="確實要啟用環繞聲音訊嗎?" -Basic.Settings.Audio.DesktopDevice="輸出音效 1" -Basic.Settings.Audio.DesktopDevice2="輸出音效 2" -Basic.Settings.Audio.AuxDevice="麥克風/輸入音效 1" -Basic.Settings.Audio.AuxDevice2="麥克風/輸入音效 2" -Basic.Settings.Audio.AuxDevice3="麥克風/輸入音效 3" +Basic.Settings.Audio.Devices="裝置" +Basic.Settings.Audio.DesktopDevice="桌面音效" +Basic.Settings.Audio.DesktopDevice2="桌面音效 2" +Basic.Settings.Audio.AuxDevice="麥克風 / 輔助音效" +Basic.Settings.Audio.AuxDevice2="麥克風 / 輔助音效 2" +Basic.Settings.Audio.AuxDevice3="麥克風 / 輔助音效 3" +Basic.Settings.Audio.AuxDevice4="麥克風 / 輔助音效 4" Basic.Settings.Audio.EnablePushToMute="啟用 按壓時靜音" Basic.Settings.Audio.PushToMuteDelay="按壓時靜音 延遲" Basic.Settings.Audio.EnablePushToTalk="啟用 按壓時說話" Basic.Settings.Audio.PushToTalkDelay="按壓時說話 延遲" Basic.Settings.Audio.UnknownAudioDevice="[設備未連接或不可用]" +Basic.Settings.Audio.Disabled="已停用" Basic.Settings.Advanced="進階" Basic.Settings.Advanced.General.ProcessPriority="程序優先順序" @@ -677,11 +735,11 @@ Basic.Settings.Advanced.General.ProcessPriority.Idle="閒置" Basic.Settings.Advanced.FormatWarning="警告: NV12以外的色彩格式主要用於錄影,並不推薦在串流時使用。串流時可能會因需要轉換色彩格式而增加CPU使用率。" Basic.Settings.Advanced.Audio.BufferingTime="音訊緩衝時間" Basic.Settings.Advanced.Video.ColorFormat="色彩格式" -Basic.Settings.Advanced.Video.ColorSpace="YUV 色彩空間" -Basic.Settings.Advanced.Video.ColorRange="YUV 顏色範圍" +Basic.Settings.Advanced.Video.ColorSpace="色彩空間" +Basic.Settings.Advanced.Video.ColorRange="顏色範圍" Basic.Settings.Advanced.Video.ColorRange.Partial="部份" Basic.Settings.Advanced.Video.ColorRange.Full="完整" -Basic.Settings.Advanced.Audio.MonitoringDevice="音訊監測設備" +Basic.Settings.Advanced.Audio.MonitoringDevice="監測裝置" Basic.Settings.Advanced.Audio.MonitoringDevice.Default="預設裝置" Basic.Settings.Advanced.Audio.DisableAudioDucking="停用 Windows 雙層次音量自動調整" Basic.Settings.Advanced.StreamDelay="實況延遲" @@ -693,12 +751,14 @@ Basic.Settings.Advanced.Network.BindToIP="綁定到 IP" Basic.Settings.Advanced.Network.EnableNewSocketLoop="啟用新的網路程式碼" Basic.Settings.Advanced.Network.EnableLowLatencyMode="低延遲模式" Basic.Settings.Advanced.Hotkeys.DisableHotkeysInFocus="當主視窗處於焦點,則停用熱鍵" +Basic.Settings.Advanced.AutoRemux="自動 remux 到 mp4" +Basic.Settings.Advanced.AutoRemux.MP4="(錄成 mkv 格式)" Basic.AdvAudio="進階音訊屬性" Basic.AdvAudio.Name="名稱" -Basic.AdvAudio.Volume="音量(%)" +Basic.AdvAudio.Volume="音量" Basic.AdvAudio.Mono="混降為單聲道" -Basic.AdvAudio.Panning="偏移" +Basic.AdvAudio.Balance="聲道平衡" Basic.AdvAudio.SyncOffset="同步位移(ms)" Basic.AdvAudio.Monitoring="音訊監測" Basic.AdvAudio.Monitoring.None="關閉監測" @@ -706,8 +766,9 @@ Basic.AdvAudio.Monitoring.MonitorOnly="僅監測(輸出為靜音)" Basic.AdvAudio.Monitoring.Both="監測和輸出" Basic.AdvAudio.AudioTracks="音軌" -Basic.Settings.Hotkeys="快速鍵" +Basic.Settings.Hotkeys="快捷鍵" Basic.Settings.Hotkeys.Pair="按鍵組合與'%1'共用作為切換鍵" +Basic.Settings.Hotkeys.Filter="過濾" Basic.Hotkeys.SelectScene="切換到場景" @@ -751,6 +812,7 @@ Hotkeys.AppleKeypadSubtract="+ (九宮鍵)" Hotkeys.AppleKeypadDecimal=". (九宮鍵)" Hotkeys.AppleKeypadEqual="+ (九宮鍵)" Hotkeys.MouseButton="滑鼠 %1" +Hotkeys.Escape="Esc 鍵" Mute="靜音" Unmute="取消靜音" @@ -762,7 +824,7 @@ SceneItemHide="隱藏 「%1」" OutputWarnings.NoTracksSelected="您必須至少選擇一個軌道" OutputWarnings.MultiTrackRecording="警告:某些格式 (例如 FLV) 不支援多個軌道錄製" -OutputWarnings.MP4Recording="警告︰ 如果檔案無法完成,儲存成 MP4 的紀錄將無法復原 (例如由於 BSOD,斷電等)。如果想要記錄多個音軌請考慮儲存成 MKV 並在完成後重新封裝成 mp4(檔案 -> 重新封裝)" +OutputWarnings.MP4Recording="警告︰ 如果檔案沒有完整儲存(例如由於 BSOD,斷電等中斷),儲存成 MP4/MOV 的檔案將無法復原 。如果想要記錄多個音軌,請考慮儲存成 MKV ,並在完成後重新封裝成 MP4/MOV (檔案 -> 重新封裝)" FinalScene.Title="刪除場景" FinalScene.Text="至少要有一個場景。" @@ -770,8 +832,24 @@ FinalScene.Text="至少要有一個場景。" NoSources.Title="沒有來源" NoSources.Text="看起來您尚未增加任何視訊來源,所以我們只會輸出黑畫面。確定?" NoSources.Text.AddSource="您可以透過點一下主視窗「來源」框底下的 + 按鈕,隨時增加來源。" +NoSources.Label="您未設定任何來源。\n按下方 + 鍵,\n或在此按下右鍵新增一個來源。" ChangeBG="設定顏色" CustomColor="自訂顏色" +BrowserSource.EnableHardwareAcceleration="啟用瀏覽器來源硬體加速" + +About="關於" +About.Info="OBS Studio 是款自由且開放原始碼的影片錄製與直播串流軟體。" +About.Donate="做出貢獻" +About.GetInvolved="參與貢獻" +About.Authors="作者群" +About.License="授權" +About.Contribute="支持OBS專案" + +ResizeOutputSizeOfSource="縮放輸出大小(來源大小)" +ResizeOutputSizeOfSource.Text="來源和輸出解析度將會縮放到目前來源的大小。" +ResizeOutputSizeOfSource.Continue="是否繼續?" + +PreviewTransition="預覽轉場" diff --git a/UI/data/themes/Acri.qss b/UI/data/themes/Acri.qss index ca9637e..ae2ef8c 100644 --- a/UI/data/themes/Acri.qss +++ b/UI/data/themes/Acri.qss @@ -42,7 +42,6 @@ QWidget { outline: none; font-family: "Open Sans", "Tahoma", "Arial", sans-serif; font-size: 12px; - padding: 4px; overflow: auto; } @@ -56,6 +55,7 @@ QLabel:link { QMenu { border: 1px solid #333336; + padding: 4px; } * [frameShape="1"], * [frameShape="2"], * [frameShape="3"], * [frameShape="4"], * [frameShape="5"], * [frameShape="6"] { @@ -156,7 +156,7 @@ QListWidget QLineEdit { /* Dock stuff */ QDockWidget { - background: transparent; + background: #181819; border: none; font-size: 14px; font-weight: bold; @@ -260,6 +260,7 @@ QScrollBar:vertical { width: 20px; margin-top: -3px; margin-bottom: -3px; + padding: 4px; } QScrollBar::handle:vertical { @@ -273,6 +274,7 @@ QScrollBar::handle:vertical { QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { border: none; background: none; + height: 0; } QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { @@ -283,15 +285,16 @@ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, QScrollBar::add- QScrollBar:horizontal { background-color: transparent; - height: 10px; + height: 20px; margin-left: -3px; margin-right: -3px; + padding: 4px; } QScrollBar::handle:horizontal { background-color: #2f2f2f; min-width: 20px; - margin: 0px 0px -3px; + margin: 3px 0px; border-radius: 0px; border: none; } @@ -299,6 +302,7 @@ QScrollBar::handle:horizontal { QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { border: none; background: none; + width: 0; } QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { @@ -326,27 +330,27 @@ QToolButton:pressed { } * [themeID="addIconSmall"] { - qproperty-icon: url(./Acri/plus.png); + qproperty-icon: url(./Dark/plus.svg); } * [themeID="removeIconSmall"] { - qproperty-icon: url(./Acri/minus.png); + qproperty-icon: url(./Dark/minus.svg); } * [themeID="propertiesIconSmall"] { - qproperty-icon: url(./Acri/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="configIconSmall"] { - qproperty-icon: url(./Acri/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="upArrowIconSmall"] { - qproperty-icon: url(./Acri/up_arrow.png); + qproperty-icon: url(./Dark/up.svg); } * [themeID="downArrowIconSmall"] { - qproperty-icon: url(./Acri/down_arrow.png); + qproperty-icon: url(./Dark/down.svg); } /* Tab Widget */ @@ -405,7 +409,7 @@ QComboBox::drop-down { QComboBox::down-arrow { qproperty-alignment: AlignTop; - image: url(./Acri/updown.png); + image: url(./Dark/updown.svg); width: 100%; } @@ -425,7 +429,7 @@ QComboBox::drop-down:editable { QComboBox::down-arrow:editable { qproperty-alignment: AlignTop; - image: url(./Acri/down_arrow.png); + image: url(./Dark/down.svg); width: 8%; } @@ -434,6 +438,7 @@ QComboBox::down-arrow:editable { QLineEdit, QTextEdit, QPlainTextEdit { background-color: rgb(8,8,11); border: none; + padding: 4px; padding-left: 2px; } @@ -442,6 +447,7 @@ QLineEdit, QTextEdit, QPlainTextEdit { QSpinBox, QDoubleSpinBox { background-color: rgb(8,8,11); border: none; + padding: 4px; padding-left: 2px; padding-right: 15px; margin-right: 10px; @@ -489,12 +495,12 @@ QDoubleSpinBox::up-button:disabled, QDoubleSpinBox::up-button:off, QDoubleSpinBo } QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(./Acri/up_arrow.png); + image: url(./Dark/up.svg); width: 100%; } QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(./Acri/down_arrow.png); + image: url(./Dark/down.svg); width: 100%; } @@ -672,6 +678,10 @@ QStatusBar::item { } /* Checkboxes */ +QCheckBox { + padding: 4px; +} + QCheckBox::indicator, QGroupBox::indicator { width: 20px; @@ -762,34 +772,34 @@ MuteCheckBox { } MuteCheckBox::indicator:checked { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:unchecked { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:unchecked:hover { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:unchecked:focus { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:checked:hover { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:checked:focus { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:checked:disabled { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:unchecked:disabled { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } OBSHotkeyLabel[hotkeyPairHover=true] { @@ -812,12 +822,12 @@ SourceTreeSubItemCheckBox::indicator { SourceTreeSubItemCheckBox::indicator:checked, SourceTreeSubItemCheckBox::indicator:checked:hover { - image: url(./Dark/expand.png); + image: url(./Dark/expand.svg); } SourceTreeSubItemCheckBox::indicator:unchecked, SourceTreeSubItemCheckBox::indicator:unchecked:hover { - image: url(./Dark/collapse.png); + image: url(./Dark/down.svg); } @@ -860,3 +870,131 @@ FocusList::item { background: transparent; min-height: 26px; } + +/* About dialog */ + +#OBSAbout #icon { + padding: 0; +} + +#OBSAbout QTextBrowser { + background: transparent; + padding: 2px 0; +} + +* [themeID="aboutName"] { + font-size: 36px; + font-weight: bold; + padding: 0; +} + +* [themeID="aboutVersion"] { + font-size: 16px; + margin-bottom: 20px; + padding: 0; +} + +* [themeID="aboutInfo"] { + margin-bottom: 20px; +} + +* [themeID="aboutHLayout"] { + background-color: rgb(8, 8, 11); +} + +/* Preview background color */ + +OBSQTDisplay { + qproperty-displayBackgroundColor: #28282A; +} + +/* Preview/Program labels */ + +* [themeID="previewProgramLabels"] { + font-size: 18px; + font-weight: bold; + color: rgb(122,121,122); +} + +/* Settings Icons */ + +OBSBasicSettings { + qproperty-generalIcon: url(./Dark/settings/general.svg); + qproperty-streamIcon: url(./Dark/settings/stream.svg); + qproperty-outputIcon: url(./Dark/settings/output.svg); + qproperty-audioIcon: url(./Dark/settings/audio.svg); + qproperty-videoIcon: url(./Dark/settings/video.svg); + qproperty-hotkeysIcon: url(./Dark/settings/hotkeys.svg); + qproperty-advancedIcon: url(./Dark/settings/advanced.svg); +} + +OBSBasicSettings QListWidget::item { + padding-top: 5px; + padding-bottom: 5px; +} + +/* Locked CheckBox */ + +LockedCheckBox { + outline: none; + background: transparent; + padding: 0px; +} + +LockedCheckBox::indicator { + width: 16px; + height: 16px; +} + +LockedCheckBox::indicator:checked { + image: url(./Dark/locked.svg); +} + +LockedCheckBox::indicator:unchecked { + image: url(:res/images/unlocked.svg); +} + +LockedCheckBox::indicator:checked:hover { + image: url(./Dark/locked.svg); +} + +LockedCheckBox::indicator:unchecked:hover { + image: url(:res/images/unlocked.svg); +} + +/* Visibilty CheckBox */ + +VisibilityCheckBox { + outline: none; + background: transparent; + padding: 0px; +} + +VisibilityCheckBox::indicator { + width: 16px; + height: 16px; +} + +VisibilityCheckBox::indicator:checked { + image: url(./Dark/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked { + image: url(:res/images/invisible.svg); +} + +VisibilityCheckBox::indicator:checked:hover { + image: url(./Dark/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked:hover { + image: url(:res/images/invisible.svg); +} + +* [themeID="trashIcon"] { + qproperty-icon: url(./Dark/trash.svg); +} + +* [themeID="revertIcon"] { + qproperty-icon: url(./Dark/revert.svg); +} diff --git a/UI/data/themes/Acri/cogwheel.png b/UI/data/themes/Acri/cogwheel.png deleted file mode 100644 index e0456ce..0000000 Binary files a/UI/data/themes/Acri/cogwheel.png and /dev/null differ diff --git a/UI/data/themes/Acri/down_arrow.png b/UI/data/themes/Acri/down_arrow.png deleted file mode 100644 index 39d31da..0000000 Binary files a/UI/data/themes/Acri/down_arrow.png and /dev/null differ diff --git a/UI/data/themes/Acri/minus.png b/UI/data/themes/Acri/minus.png deleted file mode 100644 index 26e35b4..0000000 Binary files a/UI/data/themes/Acri/minus.png and /dev/null differ diff --git a/UI/data/themes/Acri/mute.png b/UI/data/themes/Acri/mute.png deleted file mode 100644 index 682f91e..0000000 Binary files a/UI/data/themes/Acri/mute.png and /dev/null differ diff --git a/UI/data/themes/Acri/plus.png b/UI/data/themes/Acri/plus.png deleted file mode 100644 index 69325d1..0000000 Binary files a/UI/data/themes/Acri/plus.png and /dev/null differ diff --git a/UI/data/themes/Acri/unmute.png b/UI/data/themes/Acri/unmute.png deleted file mode 100644 index c50c263..0000000 Binary files a/UI/data/themes/Acri/unmute.png and /dev/null differ diff --git a/UI/data/themes/Acri/up_arrow.png b/UI/data/themes/Acri/up_arrow.png deleted file mode 100644 index 89a5d47..0000000 Binary files a/UI/data/themes/Acri/up_arrow.png and /dev/null differ diff --git a/UI/data/themes/Acri/updown.png b/UI/data/themes/Acri/updown.png deleted file mode 100644 index 69cadbb..0000000 Binary files a/UI/data/themes/Acri/updown.png and /dev/null differ diff --git a/UI/data/themes/Dark.qss b/UI/data/themes/Dark.qss index 934706a..693a556 100644 --- a/UI/data/themes/Dark.qss +++ b/UI/data/themes/Dark.qss @@ -86,7 +86,7 @@ QWidget::disabled { color: 2px solid rgb(200,199,200); /* lighter */ } -QAbstractItemView { +QAbstractItemView, QStackedWidget#stackedMixerArea QWidget { background-color: rgb(31,30,31); /* veryDark */ } @@ -100,21 +100,27 @@ QMenuBar::item { background-color: rgb(58,57,58); /* dark */ } -QListWidget::item:selected:!active { +QListWidget::item:selected:!active, +SourceTree::item:selected:!active { color: rgb(255, 255, 255); background-color: rgb(48,47,48); } +QListWidget QLineEdit, +SourceTree QLineEdit { + padding-top: 0px; + padding-bottom: 0px; + padding-right: 0; + padding-left: 2px; + border: none; + border-radius: none; +} + /* Dock Widget */ QDockWidget::title { text-align: center; - background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 rgb(86,85,86), - stop: 0.1 rgb(82,81,82), - stop: 0.5 rgb(78,77,78), - stop: 0.9 rgb(74,73,74), - stop: 1 rgb(70,69,70)); + background-color: rgb(70,69,70); } QDockWidget::close-button, QDockWidget::float-button { @@ -148,28 +154,24 @@ QGroupBox { } QScrollBar:vertical { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 rgb(31,30,31), /* veryDark */ - stop: 0.75 rgb(54, 53, 54), - stop: 1 rgb(58,57,58)); /* dark */ + background-color: rgb(58,57,58); width: 14px; + margin: 0px; } QScrollBar::handle:vertical { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 1, y2: 0, - stop: 0 rgb(122,121,122), /* light */ - stop: 0.25 rgb(100, 99, 100), - stop: 1 rgb(88,87,88)); /* kindaDark */ + background-color: rgb(76,76,76); min-height: 20px; margin: 2px; border-radius: 5px; border-width: 1px; - border: 1px solid rgb(31,30,31); /* veryDark */ + border: 1px solid rgb(76,76,76); } QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical { border: none; background: none; + height: 0px; } QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { @@ -179,28 +181,24 @@ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical, QScrollBar::add- } QScrollBar:horizontal { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 rgb(31,30,31), /* veryDark */ - stop: 0.75 rgb(54, 53, 54), - stop: 1 rgb(58,57,58)); /* dark */ + background-color: rgb(58,57,58); /* dark */ height: 14px; + margin: 0px; } QScrollBar::handle:horizontal { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 rgb(122,121,122), /* light */ - stop: 0.25 rgb(100, 99, 100), - stop: 1 rgb(88,87,88)); /* kindaDark */ + background-color: rgb(76,76,76); min-width: 20px; margin: 2px; border-radius: 5px; border-width: 1px; - border: 1px solid rgb(31,30,31); /* veryDark */ + border: 1px solid rgb(76,76,76); } QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal { border: none; background: none; + width: 0px; } QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal, QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal { @@ -228,31 +226,31 @@ QToolButton:pressed { } * [themeID="addIconSmall"] { - qproperty-icon: url(./Dark/plus.png); + qproperty-icon: url(./Dark/plus.svg); } * [themeID="removeIconSmall"] { - qproperty-icon: url(./Dark/minus.png); + qproperty-icon: url(./Dark/minus.svg); } * [themeID="propertiesIconSmall"] { - qproperty-icon: url(./Dark/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="configIconSmall"] { - qproperty-icon: url(./Dark/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="refreshIconSmall"] { - qproperty-icon: url(./Dark/refresh.png); + qproperty-icon: url(./Dark/refresh.svg); } * [themeID="upArrowIconSmall"] { - qproperty-icon: url(./Dark/up_arrow.png); + qproperty-icon: url(./Dark/up.svg); } * [themeID="downArrowIconSmall"] { - qproperty-icon: url(./Dark/down_arrow.png); + qproperty-icon: url(./Dark/down.svg); } @@ -263,11 +261,11 @@ QTabWidget::pane { /* The tab widget frame */ } QTabWidget::tab-bar { - alignment: center; + alignment: left; } QTabBar::tab { - background-color: rgb(88,87,88); /* kindaDark */ + background-color: rgb(76,76,76); border: none; padding: 5px; min-width: 50px; @@ -276,16 +274,16 @@ QTabBar::tab { QTabBar::tab:top { border-bottom: 1px transparent; - border-top-left-radius: 5px; - border-top-right-radius: 5px; + border-top-left-radius: 3px; + border-top-right-radius: 3px; } QTabBar::tab:bottom { padding-top: 1px; margin-bottom: 4px; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; height: 14px; } @@ -305,20 +303,19 @@ QTabBar::tab:pressed { /* ComboBox */ QComboBox { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 rgb(86,85,86), - stop: 0.1 rgb(82,81,82), - stop: 0.5 rgb(78,77,78), - stop: 0.9 rgb(74,73,74), - stop: 1 rgb(70,69,70)); + background-color: rgb(76,76,76); border-style: solid; border: 1px; border-radius: 3px; - border-color: rgb(31,30,31); /* veryDark */ + border-color: rgb(76,76,76); /* veryDark */ padding: 2px; padding-left: 10px; } +QComboBox:hover { + background-color: rgb(88,87,88); +} + QComboBox::drop-down { border:none; border-left: 1px solid rgba(31,30,31,155); /* veryDark */ @@ -327,7 +324,7 @@ QComboBox::drop-down { QComboBox::down-arrow { qproperty-alignment: AlignTop; - image: url(./Dark/updown.png); + image: url(./Dark/updown.svg); width: 100%; } @@ -347,7 +344,7 @@ QComboBox::drop-down:editable { QComboBox::down-arrow:editable { qproperty-alignment: AlignTop; - image: url(./Dark/down_arrow.png); + image: url(./Dark/down.svg); width: 8%; } @@ -357,25 +354,25 @@ QComboBox::down-arrow:editable { QLineEdit, QTextEdit, QPlainTextEdit { background-color: rgb(31,30,31); /* veryDark */ border: none; - padding-left: 2px; + border-radius: 3px; + padding: 2px 2px 3px 7px; } - /* Spinbox and doubleSpinbox */ QSpinBox, QDoubleSpinBox { background-color: rgb(31,30,31); /* veryDark */ border: none; - padding-left: 2px; - padding-right: 15px; - margin-right: 10px; + border-radius: 3px; + margin: 0px 3px 0px 0px; + padding: 2px 2px 3px 7px; } QSpinBox::up-button, QDoubleSpinBox::up-button { subcontrol-origin: margin; subcontrol-position: top right; /* position at the top right corner */ - background-color: rgb(88,87,88); /* kindaDark */ + background-color: rgb(76,76,76); border: 1px solid rgb(31,30,31); /* veryDark */ border-radius: 3px; border-width: 0; @@ -387,7 +384,7 @@ QSpinBox::up-button, QDoubleSpinBox::up-button { QSpinBox::down-button, QDoubleSpinBox::down-button { subcontrol-origin: margin; subcontrol-position: bottom right; /* position at the top right corner */ - background-color: rgb(88,87,88); /* kindaDark */ + background-color: rgb(76,76,76); border: 1px solid rgb(31,30,31); /* veryDark */ border-radius: 3px; border-width: 0; @@ -413,12 +410,12 @@ QDoubleSpinBox::up-button:disabled, QDoubleSpinBox::up-button:off, QDoubleSpinBo } QSpinBox::up-arrow, QDoubleSpinBox::up-arrow { - image: url(./Dark/up_arrow.png); + image: url(./Dark/up.svg); width: 100%; } QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { - image: url(./Dark/down_arrow.png); + image: url(./Dark/down.svg); width: 100%; } @@ -427,7 +424,7 @@ QSpinBox::down-arrow, QDoubleSpinBox::down-arrow { QPushButton { color: rgb(225,224,225); /* veryLight */ - background-color: rgb(88,87,88); /* kindaDark */ + background-color: rgb(76,76,76); border: none; border-radius: 3px; padding: 4px; @@ -452,7 +449,7 @@ QPushButton:checked { } QPushButton::menu-indicator { - image: url(./Dark/down_arrow.png); + image: url(./Dark/down.svg); subcontrol-position: right; subcontrol-origin: padding; width: 25px; @@ -461,20 +458,15 @@ QPushButton::menu-indicator { /* Sliders */ QSlider::groove:horizontal { - background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 rgb(50, 49, 50), /* dark */ - stop: 0.75 rgb(88,87,88)); /* kindaDark */ + background-color: rgb(76,76,76); height: 4px; border: none; border-radius: 2px; } QSlider::handle:horizontal { - background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, - stop: 0 rgb(240,239,240), /* lighter */ - stop: 0.25 rgb(200,199,200), - stop: 1 rgb(162,161,162)); /* light */ - border: 1px solid rgb(58,57,58); /* dark */ + background-color: #d2d2d2; + border: 1px solid rgb(58,57,58); border-radius: 3px; height: 10px; width: 18px; @@ -482,10 +474,7 @@ QSlider::handle:horizontal { } QSlider::handle:horizontal:pressed { - background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 rgb(240,239,240), /* lighter */ - stop: 0.25 rgb(200,199,200), - stop: 1 rgb(162,161,162)); /* light */ + background-color: #d2d2d2; } QSlider::sub-page:horizontal { @@ -494,27 +483,20 @@ QSlider::sub-page:horizontal { } QSlider::sub-page:horizontal:disabled { - background-color: QLinearGradient(x1: 0, y1: 1, x2: 0, y2: 0, - stop: 0 rgb(31,30,31), /* veryDark */ - stop: 0.75 rgb(50, 49, 50)); /* dark */ + background-color: rgb(50, 49, 50); /* dark */ border-radius: 2px; } QSlider::groove:vertical { - background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 rgb(50, 49, 50), /* dark */ - stop: 0.75 rgb(88,87,88)); /* kindaDark */ + background-color: rgb(76,76,76); width: 4px; border: none; border-radius: 2px; } QSlider::handle:vertical { - background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 rgb(240,239,240), /* lighter */ - stop: 0.25 rgb(200,199,200), - stop: 1 rgb(162,161,162)); /* light */ - border: 1px solid rgb(58,57,58); /* dark */ + background-color: #d2d2d2; + border: 1px solid rgb(58,57,58); border-radius: 3px; width: 10px; height: 18px; @@ -522,10 +504,7 @@ QSlider::handle:vertical { } QSlider::handle:vertical:pressed { - background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 rgb(240,239,240), /* lighter */ - stop: 0.25 rgb(200,199,200), - stop: 1 rgb(162,161,162)); /* light */ + background-color: #d2d2d2; } QSlider::add-page:vertical { @@ -534,9 +513,7 @@ QSlider::add-page:vertical { } QSlider::add-page:vertical:disabled { - background-color: QLinearGradient(x1: 1, y1: 0, x2: 0, y2: 0, - stop: 0 rgb(31,30,31), /* veryDark */ - stop: 0.75 rgb(50, 49, 50)); /* dark */ + background-color: rgb(50, 49, 50); /* dark */ border-radius: 2px; } @@ -569,6 +546,18 @@ QStatusBar::item { border: none; } +/* Table View */ + +QTableView { + gridline-color: rgb(88,87,88); /* kindaDark */ +} + +QHeaderView::section { + background-color: rgb(58,57,58); /* dark */ + color: rgb(225,224,225); /* veryLight */ + border: 1px solid rgb(31,30,31); /* veryDark */; + border-radius: 5px; +} /* Mute CheckBox */ @@ -577,18 +566,17 @@ MuteCheckBox { } MuteCheckBox::indicator:checked { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:unchecked { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } OBSHotkeyLabel[hotkeyPairHover=true] { color: red; } - /* Group Collapse Checkbox */ SourceTreeSubItemCheckBox { @@ -602,11 +590,11 @@ SourceTreeSubItemCheckBox::indicator { } SourceTreeSubItemCheckBox::indicator:checked { - image: url(./Dark/expand.png); + image: url(./Dark/expand.svg); } SourceTreeSubItemCheckBox::indicator:unchecked { - image: url(./Dark/collapse.png); + image: url(./Dark/down.svg); } @@ -636,3 +624,92 @@ QLabel#errorLabel { color: rgb(0, 192, 0); font-weight: bold; } + +/* About dialog */ + +* [themeID="aboutName"] { + font-size: 36px; + font-weight: bold; +} + +* [themeID="aboutVersion"] { + font-size: 16px; + margin-bottom: 20px; +} + +* [themeID="aboutInfo"] { + margin-bottom: 20px; +} + +* [themeID="aboutHLayout"] { + background-color: rgb(31, 30, 31); /* veryDark */ +} + +/* Preview background color */ + +OBSQTDisplay { + qproperty-displayBackgroundColor: rgb(76, 76, 76); +} + +/* Preview/Program labels */ + +* [themeID="previewProgramLabels"] { + font-size: 18px; + font-weight: bold; + color: rgb(122,121,122); +} + +/* Settings Icons */ + +OBSBasicSettings { + qproperty-generalIcon: url(./Dark/settings/general.svg); + qproperty-streamIcon: url(./Dark/settings/stream.svg); + qproperty-outputIcon: url(./Dark/settings/output.svg); + qproperty-audioIcon: url(./Dark/settings/audio.svg); + qproperty-videoIcon: url(./Dark/settings/video.svg); + qproperty-hotkeysIcon: url(./Dark/settings/hotkeys.svg); + qproperty-advancedIcon: url(./Dark/settings/advanced.svg); +} + +OBSBasicSettings QListWidget::item { + padding-top: 5px; + padding-bottom: 5px; +} + +/* Locked CheckBox */ + +LockedCheckBox { + outline: none; + background: transparent; +} + +LockedCheckBox::indicator:checked { + image: url(./Dark/locked.svg); +} + +LockedCheckBox::indicator:unchecked { + image: url(:res/images/unlocked.svg); +} + +/* Visibilty CheckBox */ + +VisibilityCheckBox { + outline: none; + background: transparent; +} + +VisibilityCheckBox::indicator:checked { + image: url(./Dark/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked { + image: url(:res/images/invisible.svg); +} + +* [themeID="trashIcon"] { + qproperty-icon: url(./Dark/trash.svg); +} + +* [themeID="revertIcon"] { + qproperty-icon: url(./Dark/revert.svg); +} diff --git a/UI/data/themes/Dark/cogwheel.png b/UI/data/themes/Dark/cogwheel.png deleted file mode 100644 index 62ecce9..0000000 Binary files a/UI/data/themes/Dark/cogwheel.png and /dev/null differ diff --git a/UI/data/themes/Dark/collapse.png b/UI/data/themes/Dark/collapse.png deleted file mode 100644 index 1fd72a1..0000000 Binary files a/UI/data/themes/Dark/collapse.png and /dev/null differ diff --git a/UI/data/themes/Dark/down.svg b/UI/data/themes/Dark/down.svg new file mode 100644 index 0000000..e3920cf --- /dev/null +++ b/UI/data/themes/Dark/down.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/down_arrow.png b/UI/data/themes/Dark/down_arrow.png deleted file mode 100644 index 39d31da..0000000 Binary files a/UI/data/themes/Dark/down_arrow.png and /dev/null differ diff --git a/UI/data/themes/Dark/expand.png b/UI/data/themes/Dark/expand.png deleted file mode 100644 index dd5d2b5..0000000 Binary files a/UI/data/themes/Dark/expand.png and /dev/null differ diff --git a/UI/data/themes/Dark/expand.svg b/UI/data/themes/Dark/expand.svg new file mode 100644 index 0000000..b87cc7b --- /dev/null +++ b/UI/data/themes/Dark/expand.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/locked.svg b/UI/data/themes/Dark/locked.svg new file mode 100644 index 0000000..58239eb --- /dev/null +++ b/UI/data/themes/Dark/locked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/UI/data/themes/Dark/minus.png b/UI/data/themes/Dark/minus.png deleted file mode 100644 index 26e35b4..0000000 Binary files a/UI/data/themes/Dark/minus.png and /dev/null differ diff --git a/UI/data/themes/Dark/minus.svg b/UI/data/themes/Dark/minus.svg new file mode 100644 index 0000000..8fdc037 --- /dev/null +++ b/UI/data/themes/Dark/minus.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/mute.png b/UI/data/themes/Dark/mute.png deleted file mode 100644 index 682f91e..0000000 Binary files a/UI/data/themes/Dark/mute.png and /dev/null differ diff --git a/UI/data/themes/Dark/mute.svg b/UI/data/themes/Dark/mute.svg new file mode 100644 index 0000000..d6c9c5d --- /dev/null +++ b/UI/data/themes/Dark/mute.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/no_sources.svg b/UI/data/themes/Dark/no_sources.svg new file mode 100644 index 0000000..be6ad55 --- /dev/null +++ b/UI/data/themes/Dark/no_sources.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/UI/data/themes/Dark/plus.png b/UI/data/themes/Dark/plus.png deleted file mode 100644 index 69325d1..0000000 Binary files a/UI/data/themes/Dark/plus.png and /dev/null differ diff --git a/UI/data/themes/Dark/plus.svg b/UI/data/themes/Dark/plus.svg new file mode 100644 index 0000000..c441b0f --- /dev/null +++ b/UI/data/themes/Dark/plus.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/refresh.png b/UI/data/themes/Dark/refresh.png deleted file mode 100644 index 7a6f6e6..0000000 Binary files a/UI/data/themes/Dark/refresh.png and /dev/null differ diff --git a/UI/data/themes/Dark/refresh.svg b/UI/data/themes/Dark/refresh.svg new file mode 100644 index 0000000..4d64bd6 --- /dev/null +++ b/UI/data/themes/Dark/refresh.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/revert.svg b/UI/data/themes/Dark/revert.svg new file mode 100644 index 0000000..38d0170 --- /dev/null +++ b/UI/data/themes/Dark/revert.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/advanced.svg b/UI/data/themes/Dark/settings/advanced.svg new file mode 100644 index 0000000..9ee4de7 --- /dev/null +++ b/UI/data/themes/Dark/settings/advanced.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/audio.svg b/UI/data/themes/Dark/settings/audio.svg new file mode 100644 index 0000000..5a5a78a --- /dev/null +++ b/UI/data/themes/Dark/settings/audio.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/general.svg b/UI/data/themes/Dark/settings/general.svg new file mode 100644 index 0000000..a2b0c42 --- /dev/null +++ b/UI/data/themes/Dark/settings/general.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/hotkeys.svg b/UI/data/themes/Dark/settings/hotkeys.svg new file mode 100644 index 0000000..6fdd695 --- /dev/null +++ b/UI/data/themes/Dark/settings/hotkeys.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/output.svg b/UI/data/themes/Dark/settings/output.svg new file mode 100644 index 0000000..9d36210 --- /dev/null +++ b/UI/data/themes/Dark/settings/output.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/UI/data/themes/Dark/settings/stream.svg b/UI/data/themes/Dark/settings/stream.svg new file mode 100644 index 0000000..982fd1a --- /dev/null +++ b/UI/data/themes/Dark/settings/stream.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/settings/video.svg b/UI/data/themes/Dark/settings/video.svg new file mode 100644 index 0000000..2aca1f3 --- /dev/null +++ b/UI/data/themes/Dark/settings/video.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/trash.svg b/UI/data/themes/Dark/trash.svg new file mode 100644 index 0000000..2748485 --- /dev/null +++ b/UI/data/themes/Dark/trash.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/unmute.png b/UI/data/themes/Dark/unmute.png deleted file mode 100644 index ae73cd2..0000000 Binary files a/UI/data/themes/Dark/unmute.png and /dev/null differ diff --git a/UI/data/themes/Dark/up.svg b/UI/data/themes/Dark/up.svg new file mode 100644 index 0000000..370b8f8 --- /dev/null +++ b/UI/data/themes/Dark/up.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/up_arrow.png b/UI/data/themes/Dark/up_arrow.png deleted file mode 100644 index 89a5d47..0000000 Binary files a/UI/data/themes/Dark/up_arrow.png and /dev/null differ diff --git a/UI/data/themes/Dark/updown.png b/UI/data/themes/Dark/updown.png deleted file mode 100644 index 69cadbb..0000000 Binary files a/UI/data/themes/Dark/updown.png and /dev/null differ diff --git a/UI/data/themes/Dark/updown.svg b/UI/data/themes/Dark/updown.svg new file mode 100644 index 0000000..a91e740 --- /dev/null +++ b/UI/data/themes/Dark/updown.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Dark/visible.svg b/UI/data/themes/Dark/visible.svg new file mode 100644 index 0000000..ffe51ec --- /dev/null +++ b/UI/data/themes/Dark/visible.svg @@ -0,0 +1 @@ + diff --git a/UI/data/themes/Default.qss b/UI/data/themes/Default.qss deleted file mode 100644 index 37f4b20..0000000 --- a/UI/data/themes/Default.qss +++ /dev/null @@ -1,117 +0,0 @@ -/* Intentionnally left blank */ -/* Themes are created using Qt CSS, you can visit */ -/* http://doc.qt.io/qt-5/stylesheet-reference.html and */ -/* http://doc.qt.io/qt-5/stylesheet-examples.html for examples. */ - -/* OBS will use the theme filename for the settings. */ -/* You can ship images using relative paths in qss. */ -/* Dark Theme is a good place to start if you need */ -/* a template. */ - - -/* We need to set back the icons, or the preview wont stick. */ - -* [themeID="addIconSmall"] { - qproperty-icon: url(:/res/images/add.png); -} - -* [themeID="removeIconSmall"] { - qproperty-icon: url(:/res/images/list_remove.png); -} - -* [themeID="propertiesIconSmall"] { - qproperty-icon: url(:/res/images/properties.png); -} - -* [themeID="configIconSmall"] { - qproperty-icon: url(:/res/images/configuration21_16.png); -} - -* [themeID="upArrowIconSmall"] { - qproperty-icon: url(:/res/images/up.png); -} - -* [themeID="refreshIconSmall"] { - qproperty-icon: url(:/res/images/refresh.png); -} - -* [themeID="downArrowIconSmall"] { - qproperty-icon: url(:/res/images/down.png); -} - -MuteCheckBox { - outline: none; -} - -MuteCheckBox::indicator:checked { - image: url(:/res/images/mute.png); -} - -MuteCheckBox::indicator:unchecked { - image: url(:/res/images/unmute.png); -} - -SourceTreeSubItemCheckBox { - background: transparent; - outline: none; -} - -SourceTreeSubItemCheckBox::indicator { - width: 10px; - height: 10px; -} - -SourceTreeSubItemCheckBox::indicator:checked { - image: url(:/res/images/expand.png); -} - -SourceTreeSubItemCheckBox::indicator:unchecked { - image: url(:/res/images/collapse.png); -} - -OBSHotkeyLabel[hotkeyPairHover=true] { - color: red; -} - - -/* Volume Control */ - -VolumeMeter { - qproperty-backgroundNominalColor: rgb(15, 100, 15); - qproperty-backgroundWarningColor: rgb(100, 100, 15); - qproperty-backgroundErrorColor: rgb(100, 15, 15); - qproperty-foregroundNominalColor: rgb(50, 200, 50); - qproperty-foregroundWarningColor: rgb(255, 200, 50); - qproperty-foregroundErrorColor: rgb(200, 50, 50); - qproperty-magnitudeColor: rgb(0, 0, 0); - qproperty-majorTickColor: rgb(0, 0, 0); - qproperty-minorTickColor: rgb(50, 50, 50); -} - - -/* Label warning/error */ - -QLabel#warningLabel { - color: rgb(192, 128, 0); - font-weight: bold; -} - -QLabel#errorLabel { - color: rgb(192, 0, 0); - font-weight: bold; -} - -* [themeID="warning"] { - color: rgb(192, 128, 0); - font-weight: bold; -} - -* [themeID="error"] { - color: rgb(192, 0, 0); - font-weight: bold; -} - -* [themeID="good"] { - color: rgb(0, 128, 0); - font-weight: bold; -} diff --git a/UI/data/themes/Rachni.qss b/UI/data/themes/Rachni.qss index e5a8362..88bde15 100644 --- a/UI/data/themes/Rachni.qss +++ b/UI/data/themes/Rachni.qss @@ -152,6 +152,15 @@ QSizeGrip { height: 12px; } +QListWidget QLineEdit { + padding-top: 0; + padding-bottom: 0; + padding-right: 0; + padding-left: 2px; + border: none; + border-radius: none; +} + /***********************/ /* --- List widget --- */ /***********************/ @@ -222,9 +231,9 @@ QGroupBox { QGroupBox::title { color: rgb(240, 98, 146); /* Pink (Secondary) */ left: 20px; + top: -7px; padding-left: 5px; padding-right: 4px; - padding-top: -14px; } /*****************/ @@ -471,31 +480,31 @@ QToolButton:pressed { } * [themeID="addIconSmall"] { - qproperty-icon: url(./Dark/plus.png); + qproperty-icon: url(./Dark/plus.svg); } * [themeID="removeIconSmall"] { - qproperty-icon: url(./Dark/minus.png); + qproperty-icon: url(./Dark/minus.svg); } * [themeID="propertiesIconSmall"] { - qproperty-icon: url(./Dark/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="configIconSmall"] { - qproperty-icon: url(./Dark/cogwheel.png); + qproperty-icon: url(./Dark/settings/general.svg); } * [themeID="refreshIconSmall"] { - qproperty-icon: url(./Dark/refresh.png); + qproperty-icon: url(./Dark/refresh.svg); } * [themeID="upArrowIconSmall"] { - qproperty-icon: url(./Dark/up_arrow.png); + qproperty-icon: url(./Dark/up.svg); } * [themeID="downArrowIconSmall"] { - qproperty-icon: url(./Dark/down_arrow.png); + qproperty-icon: url(./Dark/down.svg); } /***********************/ @@ -729,36 +738,36 @@ MuteCheckBox { } MuteCheckBox::indicator:checked { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:unchecked { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:unchecked:hover { background-color: rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:unchecked:focus { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } MuteCheckBox::indicator:checked:hover { background-color: rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:checked:focus { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:checked:disabled { - image: url(./Dark/mute.png); + image: url(./Dark/mute.svg); } MuteCheckBox::indicator:unchecked:disabled { - image: url(./Dark/unmute.png); + image: url(./Dark/settings/audio.svg); } /****************************/ @@ -777,12 +786,12 @@ SourceTreeSubItemCheckBox::indicator { SourceTreeSubItemCheckBox::indicator:checked, SourceTreeSubItemCheckBox::indicator:checked:hover { - image: url(./Dark/expand.png); + image: url(./Dark/expand.svg); } SourceTreeSubItemCheckBox::indicator:unchecked, SourceTreeSubItemCheckBox::indicator:unchecked:hover { - image: url(./Dark/collapse.png); + image: url(./Dark/down.svg); } /*************************/ @@ -960,6 +969,8 @@ QPushButton:checked#exitButton { QPushButton[themeID="addIconSmall"], QPushButton[themeID="removeIconSmall"], QPushButton[themeID="configIconSmall"], +QPushButton[themeID="trashIcon"], +QPushButton[themeID="revertIcon"], QPushButton#transitionRemove, QPushButton#moveAsyncFilterUp, QPushButton#moveAsyncFilterDown, @@ -973,6 +984,8 @@ QPushButton#moveEffectFilterUp { QPushButton:hover[themeID="addIconSmall"], QPushButton:hover[themeID="removeIconSmall"], QPushButton:hover[themeID="configIconSmall"], +QPushButton:hover[themeID="trashIcon"], +QPushButton:hover[themeID="revertIcon"], QPushButton:hover#transitionRemove, QPushButton:hover#moveAsyncFilterUp, QPushButton:hover#moveAsyncFilterDown, @@ -986,39 +999,6 @@ QPushButton:hover#moveEffectFilterUp { outline: none; } -/******************************/ -/* --- Hotkey Buttons --- */ -/******************************/ -/* Fix for the hotkey buttons */ -/* looking terrible with my */ -/* color choices. */ -/******************************/ - -QPushButton[themeID="hotkeyButtons"] { - background-color: rgb(58, 64, 69); /* Light Blue-gray */ - color: rgb(239, 240, 241); /* White */ - border-radius: 2px; - border: none; - margin: 4px; - padding-top: 6px; - padding-bottom: 6px; -} - -QPushButton:hover[themeID="hotkeyButtons"] { - background-color: rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ - border: 1px solid rgba(240, 98, 146, 0.5); /* Pink (Secondary) */ -} - -QPushButton:pressed[themeID="hotkeyButtons"] { - background-color: rgb(240, 98, 146); /* Pink (Secondary) */ - border: 1px solid rgb(240, 98, 146); /* Pink (Secondary) */ -} - -QPushButton:disabled[themeID="hotkeyButtons"] { - background-color: rgb(58, 64, 69); /* Light Blue-gray */ - color: rgb(162, 161, 162); /* Lighter Gray */ -} - /******************/ /* --- Labels --- */ /******************/ @@ -1165,6 +1145,21 @@ QSlider::handle:hover { QSlider::handle:disabled { background-color: rgb(122, 121, 122); } +/**********************/ +/* --- Table View --- */ +/**********************/ + +QTableView { + gridline-color: rgb(118, 121, 124); /* Light Gray */ +} + +QHeaderView::section { + background-color: rgb(35, 38, 41); /* Dark Gray */ + color: rgb(239, 240, 241); /* "White" */ + border: 1px solid rgb(118, 121, 124); /* Light Gray */ + border-radius: 2px; + padding: 4px; +} /****************/ /* --- Misc --- */ @@ -1191,7 +1186,6 @@ QFrame[frameShape="0"] { border: 1px transparent; } - /* Misc style tweaks for dark themes */ * [themeID="error"] { color: rgb(255, 89, 76); /* Red Error */ @@ -1214,3 +1208,118 @@ QToolTip { background-color: rgb(49, 54, 59); /* Blue-gray */ color: rgb(240, 98, 146); /* Pink (Secondary) */ } + +/* About dialog */ + +* [themeID="aboutName"] { + font-size: 36px; + font-weight: bold; +} + +* [themeID="aboutVersion"] { + font-size: 16px; + margin-bottom: 20px; +} + +* [themeID="aboutInfo"] { + margin-bottom: 20px; +} + +* [themeID="aboutHLayout"] { + background-color: rgb(35, 38, 41); /* Dark Gray */ +} + +/* Preview background color */ + +OBSQTDisplay { + qproperty-displayBackgroundColor: rgb(35, 38, 41); +} + +/* Preview/Program labels */ + +* [themeID="previewProgramLabels"] { + font-size: 18px; + font-weight: bold; + color: rgb(122,121,122); +} + +/* Settings Icons */ + +OBSBasicSettings { + qproperty-generalIcon: url(./Dark/settings/general.svg); + qproperty-streamIcon: url(./Dark/settings/stream.svg); + qproperty-outputIcon: url(./Dark/settings/output.svg); + qproperty-audioIcon: url(./Dark/settings/audio.svg); + qproperty-videoIcon: url(./Dark/settings/video.svg); + qproperty-hotkeysIcon: url(./Dark/settings/hotkeys.svg); + qproperty-advancedIcon: url(./Dark/settings/advanced.svg); +} + +OBSBasicSettings QListWidget::item { + padding-top: 5px; + padding-bottom: 5px; +} + +/* Locked CheckBox */ + +LockedCheckBox { + outline: none; + background: transparent; +} + +LockedCheckBox::indicator { + width: 16px; + height: 16px; +} + +LockedCheckBox::indicator:checked { + image: url(./Dark/locked.svg); +} + +LockedCheckBox::indicator:unchecked { + image: url(:res/images/unlocked.svg); +} + +LockedCheckBox::indicator:checked:hover { + image: url(./Dark/locked.svg); +} + +LockedCheckBox::indicator:unchecked:hover { + image: url(:res/images/unlocked.svg); +} + +/* Visibilty CheckBox */ + +VisibilityCheckBox { + outline: none; + background: transparent; +} + +VisibilityCheckBox::indicator { + width: 16px; + height: 16px; +} + +VisibilityCheckBox::indicator:checked { + image: url(./Dark/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked { + image: url(:res/images/invisible.svg); +} + +VisibilityCheckBox::indicator:checked:hover { + image: url(./Dark/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked:hover { + image: url(:res/images/invisible.svg); +} + +* [themeID="trashIcon"] { + qproperty-icon: url(./Dark/trash.svg); +} + +* [themeID="revertIcon"] { + qproperty-icon: url(./Dark/revert.svg); +} diff --git a/UI/data/themes/System.qss b/UI/data/themes/System.qss new file mode 100644 index 0000000..c68e0c4 --- /dev/null +++ b/UI/data/themes/System.qss @@ -0,0 +1,206 @@ +/* Intentionnally left blank */ +/* Themes are created using Qt CSS, you can visit */ +/* http://doc.qt.io/qt-5/stylesheet-reference.html and */ +/* http://doc.qt.io/qt-5/stylesheet-examples.html for examples. */ + +/* OBS will use the theme filename for the settings. */ +/* You can ship images using relative paths in qss. */ +/* Dark Theme is a good place to start if you need */ +/* a template. */ + + +/* We need to set back the icons, or the preview wont stick. */ + +* [themeID="addIconSmall"] { + qproperty-icon: url(:/res/images/plus.svg); +} + +* [themeID="removeIconSmall"] { + qproperty-icon: url(:/res/images/minus.svg); +} + +* [themeID="propertiesIconSmall"] { + qproperty-icon: url(:/settings/images/settings/general.svg); +} + +* [themeID="configIconSmall"] { + qproperty-icon: url(:/settings/images/settings/general.svg); +} + +* [themeID="upArrowIconSmall"] { + qproperty-icon: url(:/res/images/up.svg); +} + +* [themeID="refreshIconSmall"] { + qproperty-icon: url(:/res/images/refresh.svg); +} + +* [themeID="downArrowIconSmall"] { + qproperty-icon: url(:/res/images/down.svg); +} + +MuteCheckBox { + outline: none; +} + +MuteCheckBox::indicator:checked { + image: url(:/res/images/mute.svg); +} + +MuteCheckBox::indicator:unchecked { + image: url(:/settings/images/settings/audio.svg); +} + +SourceTreeSubItemCheckBox { + background: transparent; + outline: none; +} + +SourceTreeSubItemCheckBox::indicator { + width: 10px; + height: 10px; +} + +SourceTreeSubItemCheckBox::indicator:checked { + image: url(:/res/images/expand.svg); +} + +SourceTreeSubItemCheckBox::indicator:unchecked { + image: url(:/res/images/down.svg); +} + +OBSHotkeyLabel[hotkeyPairHover=true] { + color: red; +} + + +/* Volume Control */ + +VolumeMeter { + qproperty-backgroundNominalColor: rgb(15, 100, 15); + qproperty-backgroundWarningColor: rgb(100, 100, 15); + qproperty-backgroundErrorColor: rgb(100, 15, 15); + qproperty-foregroundNominalColor: rgb(50, 200, 50); + qproperty-foregroundWarningColor: rgb(255, 200, 50); + qproperty-foregroundErrorColor: rgb(200, 50, 50); + qproperty-magnitudeColor: rgb(0, 0, 0); + qproperty-majorTickColor: rgb(0, 0, 0); + qproperty-minorTickColor: rgb(50, 50, 50); +} + + +/* Label warning/error */ + +QLabel#warningLabel { + color: rgb(192, 128, 0); + font-weight: bold; +} + +QLabel#errorLabel { + color: rgb(192, 0, 0); + font-weight: bold; +} + +* [themeID="warning"] { + color: rgb(192, 128, 0); + font-weight: bold; +} + +* [themeID="error"] { + color: rgb(192, 0, 0); + font-weight: bold; +} + +* [themeID="good"] { + color: rgb(0, 128, 0); + font-weight: bold; +} + +/* About dialog */ + +* [themeID="aboutName"] { + font-size: 36px; + font-weight: bold; +} + +* [themeID="aboutVersion"] { + font-size: 16px; + margin-bottom: 20px; +} + +* [themeID="aboutInfo"] { + margin-bottom: 20px; +} + +* [themeID="aboutHLayout"] { + background-color: #DCD9D7; +} + +/* Preview background color */ + +OBSQTDisplay { + qproperty-displayBackgroundColor: rgb(76, 76, 76); +} + +/* Preview/Program labels */ + +* [themeID="previewProgramLabels"] { + font-size: 18px; + font-weight: bold; + color: rgb(122,121,122); +} + +/* Settings Icons */ + +OBSBasicSettings { + qproperty-generalIcon: url(:settings/images/settings/general.svg); + qproperty-streamIcon: url(:settings/images/settings/stream.svg); + qproperty-outputIcon: url(:settings/images/settings/output.svg); + qproperty-audioIcon: url(:settings/images/settings/audio.svg); + qproperty-videoIcon: url(:settings/images/settings/video.svg); + qproperty-hotkeysIcon: url(:settings/images/settings/hotkeys.svg); + qproperty-advancedIcon: url(:settings/images/settings/advanced.svg); +} + +OBSBasicSettings QListWidget::item { + padding-top: 5px; + padding-bottom: 5px; +} + +/* Locked CheckBox */ + +LockedCheckBox { + outline: none; + background: transparent; +} + +LockedCheckBox::indicator:checked { + image: url(:res/images/locked.svg); +} + +LockedCheckBox::indicator:unchecked { + image: url(:res/images/unlocked.svg); +} + +/* Visibilty CheckBox */ + +VisibilityCheckBox { + outline: none; + background: transparent; +} + +VisibilityCheckBox::indicator:checked { + image: url(:res/images/visible.svg); +} + +VisibilityCheckBox::indicator:unchecked { + image: url(:res/images/invisible.svg); +} + +* [themeID="trashIcon"] { + qproperty-icon: url(:res/images/trash.svg); +} + +* [themeID="revertIcon"] { + qproperty-icon: url(:res/images/revert.svg); +} diff --git a/UI/display-helpers.hpp b/UI/display-helpers.hpp index 27ef174..de0592f 100644 --- a/UI/display-helpers.hpp +++ b/UI/display-helpers.hpp @@ -17,6 +17,10 @@ #pragma once +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +#define SUPPORTS_FRACTIONAL_SCALING +#endif + static inline void GetScaleAndCenterPos( int baseCX, int baseCY, int windowCX, int windowCY, int &x, int &y, float &scale) @@ -51,5 +55,9 @@ static inline void GetCenterPosFromFixedScale( static inline QSize GetPixelSize(QWidget *widget) { +#ifdef SUPPORTS_FRACTIONAL_SCALING + return widget->size() * widget->devicePixelRatioF(); +#else return widget->size() * widget->devicePixelRatio(); +#endif } diff --git a/UI/double-slider.cpp b/UI/double-slider.cpp index 14a9586..80fa5d6 100644 --- a/UI/double-slider.cpp +++ b/UI/double-slider.cpp @@ -2,7 +2,7 @@ #include -DoubleSlider::DoubleSlider(QWidget *parent) : QSlider(parent) +DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent) { connect(this, SIGNAL(valueChanged(int)), this, SLOT(intValChanged(int))); diff --git a/UI/double-slider.hpp b/UI/double-slider.hpp index fff6b5b..c0ec8e3 100644 --- a/UI/double-slider.hpp +++ b/UI/double-slider.hpp @@ -1,8 +1,9 @@ #pragma once #include +#include "slider-ignorewheel.hpp" -class DoubleSlider : public QSlider { +class DoubleSlider : public SliderIgnoreScroll { Q_OBJECT double minVal, maxVal, minStep; diff --git a/UI/expand-checkbox.hpp b/UI/expand-checkbox.hpp index 375a4ce..b83160d 100644 --- a/UI/expand-checkbox.hpp +++ b/UI/expand-checkbox.hpp @@ -1,3 +1,5 @@ +#pragma once + #include class ExpandCheckBox : public QCheckBox { diff --git a/UI/forms/AutoConfigStreamPage.ui b/UI/forms/AutoConfigStreamPage.ui index 594f99e..c52e379 100644 --- a/UI/forms/AutoConfigStreamPage.ui +++ b/UI/forms/AutoConfigStreamPage.ui @@ -13,243 +13,414 @@ - - - QFormLayout::ExpandingFieldsGrow + + + 0 - - Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing + + 0 - - - - Basic.AutoConfig.StreamPage.Service + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + - - service - - - - - - - - - - Basic.AutoConfig.StreamPage.StreamKey - - - true - - - key - - - - - - - - - - - - - - - QLineEdit::Password - - - - - - - Show - - - - - - - - - Basic.AutoConfig.StreamPage.PerformBandwidthTest - - - true - - - - - - - Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip - - - Basic.AutoConfig.StreamPage.PreferHardwareEncoding - - - true - - - - - - - Qt::Horizontal - - - QSizePolicy::Fixed - - - - 90 - 20 - - - - - - - - Basic.AutoConfig.StreamPage.Server - - - - - - - Basic.Settings.Stream.StreamType - - - - - - - - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - BandwidthTest.Region - - - - - - BandwidthTest.Region.Asia - - - + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + - + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 0 + + + + + + - BandwidthTest.Region.US + Basic.AutoConfig.StreamPage.Service + + + service - - - - BandwidthTest.Region.EU - - - - - - - BandwidthTest.Region.Other - - + + - - - - - - - 500 - - - 10000 - - - 2500 - - - - - - - Basic.Settings.Output.VideoBitrate - - - bitrate + + + + 1 + + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 17 + + + + + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 17 + + + + + + + + + + Basic.AutoConfig.StreamPage.UseStreamKey + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFormLayout::ExpandingFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Basic.AutoConfig.StreamPage.Server + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + Basic.AutoConfig.StreamPage.StreamKey + + + true + + + key + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + QLineEdit::Password + + + + + + + Show + + + + + + + + + + Basic.Settings.Output.VideoBitrate + + + bitrate + + + + + + + + + + 500 + + + 10000 + + + 2500 + + + + + + + Basic.AutoConfig.StreamPage.PreferHardwareEncoding.ToolTip + + + Basic.AutoConfig.StreamPage.PreferHardwareEncoding + + + true + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 87 + 17 + + + + + + + + Basic.AutoConfig.StreamPage.PerformBandwidthTest + + + true + + + + + + + BandwidthTest.Region + + + + + + BandwidthTest.Region.Asia + + + + + + + BandwidthTest.Region.US + + + + + + + BandwidthTest.Region.EU + + + + + + + BandwidthTest.Region.Other + + + + + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Basic.AutoConfig.StreamPage.DisconnectAccount + + + + + - - streamType - service - server - customServer - key - show - preferHardware - doBandwidthTest - regionUS - regionEU - regionAsia - regionOther - - + + + connectAccount2 + clicked() + connectAccount + click() + + + 382 + 279 + + + 114 + 82 + + + + diff --git a/UI/forms/OBSAbout.ui b/UI/forms/OBSAbout.ui new file mode 100644 index 0000000..790a965 --- /dev/null +++ b/UI/forms/OBSAbout.ui @@ -0,0 +1,219 @@ + + + OBSAbout + + + + 0 + 0 + 840 + 519 + + + + About + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 30 + + + 30 + + + 10 + + + 6 + + + 6 + + + + + + 256 + 256 + + + + + 256 + 256 + + + + + + + :res/images/obs.png + + + true + + + + + + + 0 + + + + + OBS Studio + + + + + + + Version + + + + + + + About.Info + + + true + + + + + + + Contribute + + + true + + + + + + + Donate + + + + + + + Get Involved + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + true + + + + + + + + + + + + 0 + 60 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + About + + + Qt::AlignCenter + + + + + + + Authors + + + Qt::AlignCenter + + + + + + + License + + + Qt::AlignCenter + + + + + + + + + + + ClickableLabel + QLabel +
clickable-label.hpp
+
+
+ + +
diff --git a/UI/forms/OBSBasic.ui b/UI/forms/OBSBasic.ui index 983a869..b082729 100644 --- a/UI/forms/OBSBasic.ui +++ b/UI/forms/OBSBasic.ui @@ -67,8 +67,18 @@ - 4 + 0 + + + + StudioMode.Preview + + + Qt::AlignBottom|Qt::AlignHCenter + + + @@ -106,7 +116,7 @@ 0 0 1079 - 21 + 22 @@ -152,6 +162,8 @@ + + @@ -176,6 +188,8 @@ + + @@ -293,6 +307,7 @@ + @@ -326,7 +341,7 @@ - + QDockWidget::AllDockWidgetFeatures @@ -458,7 +473,7 @@ - + QDockWidget::AllDockWidgetFeatures @@ -591,7 +606,7 @@
- + QDockWidget::AllDockWidgetFeatures @@ -641,7 +656,7 @@ 0 0 - 230 + 64 16 @@ -695,7 +710,7 @@ 0 0 16 - 230 + 28 @@ -728,7 +743,7 @@ - + QDockWidget::AllDockWidgetFeatures @@ -975,7 +990,7 @@ - + QDockWidget::AllDockWidgetFeatures @@ -1351,6 +1366,16 @@ Ctrl+D + + + Basic.MainMenu.Edit.Transform.VerticalCenter + + + + + Basic.MainMenu.Edit.Transform.HorizontalCenter + + Basic.MainMenu.Edit.Transform.FlipHorizontal @@ -1656,6 +1681,22 @@ Basic.MainMenu.Help.Discord + + + true + + + true + + + Basic.Stats + + + + + Basic.MainMenu.Help.About + + @@ -1686,6 +1727,12 @@ QListView
source-tree.hpp
+ + OBSDock + QDockWidget +
window-dock.hpp
+ 1 +
diff --git a/UI/forms/OBSBasicFilters.ui b/UI/forms/OBSBasicFilters.ui index b25d5d3..572a31f 100644 --- a/UI/forms/OBSBasicFilters.ui +++ b/UI/forms/OBSBasicFilters.ui @@ -425,6 +425,42 @@ + + + + :/res/images/list_remove.png:/res/images/list_remove.png + + + Remove + + + Del + + + + + + :/res/images/up.png:/res/images/up.png + + + Basic.MainMenu.Edit.Order.MoveUp + + + Ctrl+Up + + + + + + :/res/images/down.png:/res/images/down.png + + + Basic.MainMenu.Edit.Order.MoveDown + + + Ctrl+Down + +
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui index c92fc9e..328a887 100644 --- a/UI/forms/OBSBasicSettings.ui +++ b/UI/forms/OBSBasicSettings.ui @@ -44,8 +44,8 @@ - 48 - 48 + 32 + 32 @@ -57,7 +57,7 @@ - :/settings/images/settings/system-settings-3.png:/settings/images/settings/system-settings-3.png + :/settings/images/settings/general.svg:/settings/images/settings/general.svg @@ -66,7 +66,7 @@ - :/settings/images/settings/network.png:/settings/images/settings/network.png + :/settings/images/settings/stream.svg:/settings/images/settings/stream.svg @@ -75,7 +75,7 @@ - :/settings/images/settings/network-bluetooth.png:/settings/images/settings/network-bluetooth.png + :/settings/images/settings/output.svg:/settings/images/settings/output.svg @@ -84,7 +84,7 @@ - :/settings/images/settings/decibel_audio_player.png:/settings/images/settings/decibel_audio_player.png + :/settings/images/settings/audio.svg:/settings/images/settings/audio.svg @@ -93,7 +93,7 @@ - :/settings/images/settings/video-display-3.png:/settings/images/settings/video-display-3.png + :/settings/images/settings/video.svg:/settings/images/settings/video.svg @@ -102,7 +102,7 @@ - :/settings/images/settings/preferences-desktop-keyboard-shortcuts.png:/settings/images/settings/preferences-desktop-keyboard-shortcuts.png + :/settings/images/settings/hotkeys.svg:/settings/images/settings/hotkeys.svg @@ -111,7 +111,7 @@ - :/settings/images/settings/advanced.png:/settings/images/settings/advanced.png + :/settings/images/settings/advanced.svg:/settings/images/settings/advanced.svg @@ -137,6 +137,12 @@ + + QFrame::NoFrame + + + QFrame::Plain + true @@ -145,8 +151,8 @@ 0 0 - 801 - 836 + 808 + 989 @@ -540,6 +546,58 @@ + + + + StudioMode.Preview + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + Basic.Settings.General.OverflowAlwaysVisible + + + + + + + Qt::Horizontal + + + + 170 + 5 + + + + + + + + Basic.Settings.General.OverflowSelectionHidden + + + + + + + Basic.Settings.General.OverflowHidden + + + + + + @@ -582,6 +640,16 @@ + + + + Basic.Settings.General.TogglePreviewProgramLabels + + + true + + + @@ -686,89 +754,391 @@ 0 - + - + 0 0 - - - 0 + + + QFormLayout::AllNonFixedFieldsGrow - - 0 + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - 0 - - - 0 - - - - - - 0 - 0 - + + + + Basic.AutoConfig.StreamPage.Service - - - 0 + + service + + + + + + + 20 + + + + + + + Qt::Horizontal + + + + 170 + 0 + + + + + + + + + + + + 0 + 0 + + + + 1 + + + + + + + Qt::Horizontal - - 0 + + QSizePolicy::Fixed - - 0 - - - 0 + + + 170 + 19 + + + + + - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - - 170 - 0 - - - - Basic.Settings.Stream.StreamType - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - streamType - - - - - - - - - - - - - Qt::Horizontal + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + Qt::Horizontal + + + + 40 + 10 + + + + - - - + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 170 + 19 + + + + + + + + + + Basic.AutoConfig.StreamPage.UseStreamKey + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + Basic.AutoConfig.StreamPage.Server + + + + + + + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + Basic.AutoConfig.StreamPage.StreamKey + + + true + + + key + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + QLineEdit::Password + + + + + + + Show + + + + + + + + + + Qt::Horizontal + + + + 170 + 8 + + + + + + + + + + Basic.AutoConfig.StreamPage.ConnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Basic.AutoConfig.StreamPage.DisconnectAccount + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Basic.Settings.Stream.Custom.UseAuthentication + + + + + + + + + + Basic.Settings.Stream.Custom.Username + + + authUsername + + + + + + + Basic.Settings.Stream.Custom.Password + + + authPw + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QLineEdit::Password + + + + + + + Show + + + + + + + + + + Basic.Settings.Stream.BandwidthTestMode + + + + + @@ -792,13 +1162,19 @@ true + + QFrame::NoFrame + + + QFrame::Plain + 0 0 - 818 - 697 + 747 + 808 @@ -874,13 +1250,6 @@ - - - - Qt::Horizontal - - - @@ -1654,13 +2023,6 @@ - - - - Qt::Horizontal - - - @@ -1680,6 +2042,270 @@ 0 + + + + + 0 + 0 + + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 0 + + + + + + 0 + 0 + + + + + 170 + 0 + + + + Basic.Settings.Output.Simple.SavePath + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + advOutRecPath + + + + + + + + + true + + + + + + + true + + + Browse + + + + + + + + + Basic.Settings.Output.NoSpaceFileName + + + true + + + + + + + Basic.Settings.Output.Format + + + advOutRecFormat + + + + + + + + flv + + + + + mp4 + + + + + mov + + + + + mkv + + + + + ts + + + + + m3u8 + + + + + + + + Basic.Settings.Output.Adv.AudioTrack + + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + + + + + 2 + + + + + + + 3 + + + + + + + 4 + + + + + + + 5 + + + + + + + 6 + + + + + + + + + + Basic.Settings.Output.Encoder + + + advOutRecEncoder + + + + + + + + + + + 0 + 0 + + + + Qt::RightToLeft + + + Basic.Settings.Output.Adv.Rescale + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + true + + + + + + + + + + Basic.Settings.Output.CustomMuxerSettings + + + advOutMuxCustom + + + + + + + + + @@ -1695,270 +2321,6 @@ 0 - - - - - 0 - 0 - - - - - QFormLayout::AllNonFixedFieldsGrow - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 0 - - - - - - 0 - 0 - - - - - 170 - 0 - - - - Basic.Settings.Output.Simple.SavePath - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - advOutRecPath - - - - - - - - - true - - - - - - - true - - - Browse - - - - - - - - - Basic.Settings.Output.NoSpaceFileName - - - true - - - - - - - Basic.Settings.Output.Format - - - advOutRecFormat - - - - - - - - flv - - - - - mp4 - - - - - mov - - - - - mkv - - - - - ts - - - - - m3u8 - - - - - - - - Basic.Settings.Output.Adv.AudioTrack - - - - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 1 - - - - - - - 2 - - - - - - - 3 - - - - - - - 4 - - - - - - - 5 - - - - - - - 6 - - - - - - - - - - Basic.Settings.Output.Encoder - - - advOutRecEncoder - - - - - - - - - - - 0 - 0 - - - - Qt::RightToLeft - - - Basic.Settings.Output.Adv.Rescale - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - false - - - true - - - - - - - - - - Basic.Settings.Output.CustomMuxerSettings - - - advOutMuxCustom - - - - - - - - - @@ -2247,7 +2609,7 @@ 0 - + 1 @@ -2257,35 +2619,35 @@ - + 2 - + 3 - + 4 - + 5 - + 6 @@ -3121,13 +3483,6 @@ - - - - Qt::Horizontal - - - @@ -3237,272 +3592,479 @@ - - - QFormLayout::AllNonFixedFieldsGrow + + + 0 - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + 0 - - - - Basic.Settings.Audio.SampleRate + + 0 + + + 0 + + + + + QFrame::NoFrame - - sampleRate + + QFrame::Plain - - - - - - 44.1khz - - - 0 - - - - 44.1khz - - - - - 48khz - - - - - - - - Basic.Settings.Audio.Channels - - - channelSetup - - - - - - - Mono - - - 0 - - - - Mono - - - - - Stereo - - - - - 2.1 - - - - - 4.0 - - - - - 4.1 - - - - - 5.1 - - - - - 7.1 - - - - - - - - - 170 - 0 - - - - Basic.Settings.Audio.DesktopDevice - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - desktopAudioDevice1 - - - - - - - true - - - - - - - Basic.Settings.Audio.DesktopDevice2 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - desktopAudioDevice2 - - - - - - - true - - - - - - - Basic.Settings.Audio.AuxDevice - - - auxAudioDevice1 - - - - - - - true - - - - - - - Basic.Settings.Audio.AuxDevice2 - - - auxAudioDevice2 - - - - - - - true - - - - - - - Basic.Settings.Audio.AuxDevice3 - - - auxAudioDevice3 - - - - - - - true - - - - - - - Basic.Settings.Audio.MeterDecayRate - - - meterDecayRate - - - - - - - Basic.Settings.Audio.MeterDecayRate.Fast - - - 0 - - - - Basic.Settings.Audio.MeterDecayRate.Fast - - - - - Basic.Settings.Audio.MeterDecayRate.Medium - - - - - Basic.Settings.Audio.MeterDecayRate.Slow - - - - - - - - Basic.Settings.Audio.PeakMeterType - - - - - - - 0 - - - - Basic.Settings.Audio.PeakMeterType.SamplePeak - - - - - Basic.Settings.Audio.PeakMeterType.TruePeak - - - - - - true - + + + 0 + 0 + 594 + 807 + + + + QFrame::Plain + + + true + + 0 0 - 800 - 69 + 594 + 807 + + + 0 + + + 0 + + + 0 + + + 9 + + + + + + + + Basic.Settings.General + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + + 170 + 0 + + + + Basic.Settings.Audio.SampleRate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + sampleRate + + + + + + + 44.1khz + + + 0 + + + + 44.1khz + + + + + 48khz + + + + + + + + Basic.Settings.Audio.Channels + + + channelSetup + + + + + + + Mono + + + 0 + + + + Mono + + + + + Stereo + + + + + 2.1 + + + + + 4.0 + + + + + 4.1 + + + + + 5.1 + + + + + 7.1 + + + + + + + + + + + Basic.Settings.Audio.Devices + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + + 170 + 0 + + + + Basic.Settings.Audio.DesktopDevice + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + desktopAudioDevice1 + + + + + + + true + + + + + + + Basic.Settings.Audio.DesktopDevice2 + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + desktopAudioDevice2 + + + + + + + true + + + + + + + Basic.Settings.Audio.AuxDevice + + + auxAudioDevice1 + + + + + + + true + + + + + + + Basic.Settings.Audio.AuxDevice2 + + + auxAudioDevice2 + + + + + + + true + + + + + + + Basic.Settings.Audio.AuxDevice3 + + + auxAudioDevice3 + + + + + + + true + + + + + + + true + + + + + + + Basic.Settings.Audio.AuxDevice4 + + + auxAudioDevice4 + + + + + + + + + + Basic.Settings.Audio.Meters + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + + 170 + 0 + + + + Basic.Settings.Audio.MeterDecayRate + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + meterDecayRate + + + + + + + Basic.Settings.Audio.MeterDecayRate.Fast + + + 0 + + + + Basic.Settings.Audio.MeterDecayRate.Fast + + + + + Basic.Settings.Audio.MeterDecayRate.Medium + + + + + Basic.Settings.Audio.MeterDecayRate.Slow + + + + + + + + Basic.Settings.Audio.PeakMeterType + + + peakMeterType + + + + + + + 0 + + + + Basic.Settings.Audio.PeakMeterType.SamplePeak + + + + + Basic.Settings.Audio.PeakMeterType.TruePeak + + + + + + + + + + + Basic.Settings.Advanced + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + Basic.Settings.Advanced.Audio.MonitoringDevice + + + monitoringDevice + + + + + + + + + + Qt::Horizontal + + + + 170 + 20 + + + + + + + + Basic.Settings.Advanced.Audio.DisableAudioDucking + + + + + + + + + + Basic.Settings.Hotkeys + + + + QFormLayout::AllNonFixedFieldsGrow + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + 2 + + + + + + + + - + @@ -3515,7 +4077,7 @@ - + @@ -3528,19 +4090,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -3696,6 +4245,11 @@ 24 NTSC + + + 25 PAL + + 29.97 @@ -3711,6 +4265,11 @@ 48 + + + 50 PAL + + 59.94 @@ -3823,15 +4382,15 @@ 0 - - color: rgb(255, 0, 4); - true + + error + @@ -3845,8 +4404,8 @@ 0 0 - 818 - 697 + 98 + 28 @@ -3892,8 +4451,8 @@ 0 0 - 803 - 807 + 765 + 993 @@ -4159,57 +4718,6 @@ - - - - Basic.Settings.Audio - - - - QFormLayout::AllNonFixedFieldsGrow - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - 2 - - - - - Basic.Settings.Advanced.Audio.MonitoringDevice - - - monitoringDevice - - - - - - - - - - Basic.Settings.Advanced.Audio.DisableAudioDucking - - - - - - - Qt::Horizontal - - - - 170 - 20 - - - - - - - @@ -4245,7 +4753,7 @@ - + 0 @@ -4277,7 +4785,7 @@ - + Basic.Settings.Output.ReplayBuffer.Prefix @@ -4300,6 +4808,26 @@ + + + + Basic.Settings.Advanced.AutoRemux + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -4668,28 +5196,28 @@ - - color: rgb(255, 0, 4); - true + + error + - - color: rgb(255, 0, 4); - true + + error + @@ -4711,15 +5239,59 @@ listWidget - streamType + scrollArea_2 + language + theme + enableAutoUpdates + openStatsOnStartup + warnBeforeStreamStart + warnBeforeStreamStop + recordWhenStreaming + keepRecordStreamStops + replayWhileStreaming + keepReplayStreamStops + snappingEnabled + snapDistance + screenSnapping + sourceSnapping + centerSnapping + hideProjectorCursor + projectorAlwaysOnTop + saveProjectors + systemTrayEnabled + systemTrayWhenStarted + systemTrayAlways + overflowHide + overflowAlwaysVisible + overflowSelectionHide + doubleClickSwitch + studioPortraitLayout + multiviewMouseSwitch + multiviewDrawNames + multiviewDrawAreas + multiviewLayout + service + connectAccount + useStreamKey + server + customServer + key + show + connectAccount2 + disconnectAccount + useAuth + authUsername + authPw + authPwShow + scrollArea_3 outputMode simpleOutputVBitrate + simpleOutStrEncoder simpleOutputABitrate simpleOutAdvanced + simpleOutEnforce simpleOutPreset simpleOutCustom - simpleOutEnforce - simpleOutStrEncoder simpleOutputPath simpleOutputBrowse simpleNoSpace @@ -4756,10 +5328,12 @@ advOutRecUseRescale advOutRecRescale advOutMuxCustom + advOutFFType advOutFFRecPath advOutFFPathBrowse - advOutFFURL + advOutFFNoSpace advOutFFFormat + advOutFFMCfg advOutFFVBitrate advOutFFVGOPSize advOutFFUseRescale @@ -4776,9 +5350,7 @@ advOutFFTrack6 advOutFFAEncoder advOutFFACfg - advOutFFType - advOutFFMCfg - advOutFFNoSpace + advOutFFURL advOutTrack1Bitrate advOutTrack1Name advOutTrack2Bitrate @@ -4791,6 +5363,9 @@ advOutTrack5Name advOutTrack6Bitrate advOutTrack6Name + advReplayBuf + advRBSecMax + advRBMegsMax sampleRate channelSetup desktopAudioDevice1 @@ -4798,7 +5373,11 @@ auxAudioDevice1 auxAudioDevice2 auxAudioDevice3 - audioSourceScrollArea + auxAudioDevice4 + meterDecayRate + peakMeterType + monitoringDevice + disableAudioDucking baseResolution outputResolution downscaleFilter @@ -4816,9 +5395,9 @@ colorRange disableOSXVSync resetOSXVSync - monitoringDevice filenameFormatting overwriteIfExists + autoRemux simpleRBPrefix simpleRBSuffix streamDelayEnable @@ -4830,27 +5409,8 @@ bindToIP enableNewSocketLoop enableLowLatencyMode - warnBeforeStreamStop - recordWhenStreaming - keepRecordStreamStops - replayWhileStreaming - keepReplayStreamStops - snappingEnabled - screenSnapping - centerSnapping - sourceSnapping - snapDistance - hideProjectorCursor - projectorAlwaysOnTop - saveProjectors - systemTrayEnabled - systemTrayWhenStarted - systemTrayAlways - enableAutoUpdates - warnBeforeStreamStart - scrollArea_2 - language - theme + browserHWAccel + disableFocusHotkeys @@ -4899,8 +5459,8 @@ 16 - 250 - 39 + 401 + 64 @@ -4911,12 +5471,12 @@ setVisible(bool) - 250 - 39 + 251 + 64 - 250 - 39 + 251 + 64 @@ -4927,12 +5487,12 @@ setVisible(bool) - 250 - 39 + 251 + 64 - 250 - 39 + 251 + 64 @@ -4943,12 +5503,12 @@ setVisible(bool) - 250 - 39 + 251 + 64 - 250 - 39 + 251 + 64 @@ -4959,12 +5519,12 @@ setVisible(bool) - 250 - 39 + 251 + 64 - 250 - 39 + 251 + 64 @@ -4975,12 +5535,12 @@ setCurrentIndex(int) - 232 - 41 + 260 + 73 - 241 - 30 + 242 + 85 @@ -4991,12 +5551,12 @@ setEnabled(bool) - 259 - 60 + 260 + 85 - 228 - 50 + 229 + 85 @@ -5007,12 +5567,12 @@ setEnabled(bool) - 259 - 39 + 260 + 64 - 228 - 29 + 229 + 64 @@ -5023,12 +5583,12 @@ setEnabled(bool) - 168 - 56 + 260 + 85 - 228 - 50 + 229 + 85 @@ -5039,12 +5599,12 @@ setCurrentIndex(int) - 250 - 50 + 260 + 85 - 250 - 52 + 260 + 85 @@ -5055,12 +5615,12 @@ setVisible(bool) - 250 - 39 + 251 + 64 - 250 - 39 + 251 + 64 @@ -5071,11 +5631,11 @@ setEnabled(bool) - 950 + 933 579 - 950 + 933 602 @@ -5087,11 +5647,11 @@ setEnabled(bool) - 950 + 933 579 - 950 + 933 625 @@ -5119,7 +5679,7 @@ setEnabled(bool) - 950 + 933 340 @@ -5135,11 +5695,11 @@ setEnabled(bool) - 950 + 933 340 - 950 + 933 366 @@ -5151,11 +5711,11 @@ setEnabled(bool) - 950 + 933 340 - 950 + 933 389 @@ -5167,11 +5727,11 @@ setEnabled(bool) - 950 + 933 340 - 950 + 933 412 @@ -5183,11 +5743,11 @@ setEnabled(bool) - 950 + 933 340 - 950 + 933 435 @@ -5199,11 +5759,11 @@ setEnabled(bool) - 950 + 933 222 - 950 + 933 245 @@ -5215,11 +5775,11 @@ setEnabled(bool) - 950 + 933 268 - 950 + 933 291 @@ -5288,5 +5848,21 @@ + + connectAccount2 + clicked() + connectAccount + click() + + + 484 + 142 + + + 454 + 87 + + + diff --git a/UI/forms/OBSLicenseAgreement.ui b/UI/forms/OBSLicenseAgreement.ui deleted file mode 100644 index e9c2d49..0000000 --- a/UI/forms/OBSLicenseAgreement.ui +++ /dev/null @@ -1,108 +0,0 @@ - - - OBSLicenseAgreement - - - - 0 - 0 - 457 - 430 - - - - - 200 - 300 - - - - LicenseAgreement - - - - - - LicenseAgreement.PleaseReview - - - Qt::RichText - - - true - - - true - - - Qt::TextBrowserInteraction - - - - - - - - - - true - - - - - - - - - - Qt::Horizontal - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - OK - - - - - - - - - - - - agree - clicked() - OBSLicenseAgreement - accept() - - - 138 - 419 - - - 40 - 424 - - - - - diff --git a/UI/forms/OBSRemux.ui b/UI/forms/OBSRemux.ui index 4c74e56..0f762b3 100644 --- a/UI/forms/OBSRemux.ui +++ b/UI/forms/OBSRemux.ui @@ -6,77 +6,62 @@ 0 0 - 491 - 124 + 850 + 400 RemuxRecordings - - - - - Remux.SourceFile - - - - - - - Remux.TargetFile - - - - - - - - - - - - - Browse - - - - - - - - - - - - - - - Browse - - - - - - - - - 24 - - - - - - - - - QDialogButtonBox::Ok|QDialogButtonBox::Close - - - - - - + + + + + Remux.HelpText + + + + + + + 6 + + + + + QDialogButtonBox::Close|QDialogButtonBox::Ok|QDialogButtonBox::Reset|QDialogButtonBox::RestoreDefaults + + + + + + + + + QAbstractItemView::NoSelection + + + 23 + + + 23 + + + false + + + 23 + + + + + + + 24 + + + + diff --git a/UI/forms/images/add.png b/UI/forms/images/add.png deleted file mode 100644 index 5413c1e..0000000 Binary files a/UI/forms/images/add.png and /dev/null differ diff --git a/UI/forms/images/collapse.png b/UI/forms/images/collapse.png deleted file mode 100644 index 04707a4..0000000 Binary files a/UI/forms/images/collapse.png and /dev/null differ diff --git a/UI/forms/images/configuration21_16.png b/UI/forms/images/configuration21_16.png deleted file mode 100644 index 3ddd717..0000000 Binary files a/UI/forms/images/configuration21_16.png and /dev/null differ diff --git a/UI/forms/images/down.png b/UI/forms/images/down.png deleted file mode 100644 index 35a8c4b..0000000 Binary files a/UI/forms/images/down.png and /dev/null differ diff --git a/UI/forms/images/down.svg b/UI/forms/images/down.svg new file mode 100644 index 0000000..c827bbd --- /dev/null +++ b/UI/forms/images/down.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/editscene.png b/UI/forms/images/editscene.png deleted file mode 100644 index 65b96e8..0000000 Binary files a/UI/forms/images/editscene.png and /dev/null differ diff --git a/UI/forms/images/expand.png b/UI/forms/images/expand.png deleted file mode 100644 index 1222bcd..0000000 Binary files a/UI/forms/images/expand.png and /dev/null differ diff --git a/UI/forms/images/expand.svg b/UI/forms/images/expand.svg new file mode 100644 index 0000000..6f87ea9 --- /dev/null +++ b/UI/forms/images/expand.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/invisible.svg b/UI/forms/images/invisible.svg new file mode 100644 index 0000000..0d1484d --- /dev/null +++ b/UI/forms/images/invisible.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/invisible_mask.png b/UI/forms/images/invisible_mask.png deleted file mode 100644 index 479e13e..0000000 Binary files a/UI/forms/images/invisible_mask.png and /dev/null differ diff --git a/UI/forms/images/list_remove.png b/UI/forms/images/list_remove.png deleted file mode 100644 index 5858662..0000000 Binary files a/UI/forms/images/list_remove.png and /dev/null differ diff --git a/UI/forms/images/live.png b/UI/forms/images/live.png deleted file mode 100644 index 804f72c..0000000 Binary files a/UI/forms/images/live.png and /dev/null differ diff --git a/UI/forms/images/locked.svg b/UI/forms/images/locked.svg new file mode 100644 index 0000000..bcb2cb7 --- /dev/null +++ b/UI/forms/images/locked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/UI/forms/images/locked_mask.png b/UI/forms/images/locked_mask.png deleted file mode 100644 index 4f05b1a..0000000 Binary files a/UI/forms/images/locked_mask.png and /dev/null differ diff --git a/UI/forms/images/minus.svg b/UI/forms/images/minus.svg new file mode 100644 index 0000000..8a2e2f9 --- /dev/null +++ b/UI/forms/images/minus.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/mute.png b/UI/forms/images/mute.png deleted file mode 100644 index 97cb10a..0000000 Binary files a/UI/forms/images/mute.png and /dev/null differ diff --git a/UI/forms/images/mute.svg b/UI/forms/images/mute.svg new file mode 100644 index 0000000..d6c9c5d --- /dev/null +++ b/UI/forms/images/mute.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/no_sources.svg b/UI/forms/images/no_sources.svg new file mode 100644 index 0000000..55eb492 --- /dev/null +++ b/UI/forms/images/no_sources.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/UI/forms/images/plus.svg b/UI/forms/images/plus.svg new file mode 100644 index 0000000..de42f6b --- /dev/null +++ b/UI/forms/images/plus.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/properties.png b/UI/forms/images/properties.png deleted file mode 100644 index 3ddd717..0000000 Binary files a/UI/forms/images/properties.png and /dev/null differ diff --git a/UI/forms/images/refresh.png b/UI/forms/images/refresh.png deleted file mode 100644 index e3e4c5b..0000000 Binary files a/UI/forms/images/refresh.png and /dev/null differ diff --git a/UI/forms/images/refresh.svg b/UI/forms/images/refresh.svg new file mode 100644 index 0000000..2da126a --- /dev/null +++ b/UI/forms/images/refresh.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/revert.svg b/UI/forms/images/revert.svg new file mode 100644 index 0000000..d1e1314 --- /dev/null +++ b/UI/forms/images/revert.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/advanced.png b/UI/forms/images/settings/advanced.png deleted file mode 100644 index 91593e0..0000000 Binary files a/UI/forms/images/settings/advanced.png and /dev/null differ diff --git a/UI/forms/images/settings/advanced.svg b/UI/forms/images/settings/advanced.svg new file mode 100644 index 0000000..27fdfc8 --- /dev/null +++ b/UI/forms/images/settings/advanced.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/applications-system-2.png b/UI/forms/images/settings/applications-system-2.png deleted file mode 100644 index 30f418d..0000000 Binary files a/UI/forms/images/settings/applications-system-2.png and /dev/null differ diff --git a/UI/forms/images/settings/audio.svg b/UI/forms/images/settings/audio.svg new file mode 100644 index 0000000..2cbca00 --- /dev/null +++ b/UI/forms/images/settings/audio.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/decibel_audio_player.png b/UI/forms/images/settings/decibel_audio_player.png deleted file mode 100644 index 21d6858..0000000 Binary files a/UI/forms/images/settings/decibel_audio_player.png and /dev/null differ diff --git a/UI/forms/images/settings/general.svg b/UI/forms/images/settings/general.svg new file mode 100644 index 0000000..3521280 --- /dev/null +++ b/UI/forms/images/settings/general.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/hotkeys.svg b/UI/forms/images/settings/hotkeys.svg new file mode 100644 index 0000000..9a406bb --- /dev/null +++ b/UI/forms/images/settings/hotkeys.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/network-bluetooth.png b/UI/forms/images/settings/network-bluetooth.png deleted file mode 100644 index 764e766..0000000 Binary files a/UI/forms/images/settings/network-bluetooth.png and /dev/null differ diff --git a/UI/forms/images/settings/network.png b/UI/forms/images/settings/network.png deleted file mode 100644 index ada03d7..0000000 Binary files a/UI/forms/images/settings/network.png and /dev/null differ diff --git a/UI/forms/images/settings/output.svg b/UI/forms/images/settings/output.svg new file mode 100644 index 0000000..455c202 --- /dev/null +++ b/UI/forms/images/settings/output.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/UI/forms/images/settings/preferences-desktop-keyboard-shortcuts.png b/UI/forms/images/settings/preferences-desktop-keyboard-shortcuts.png deleted file mode 100644 index 2abb1b5..0000000 Binary files a/UI/forms/images/settings/preferences-desktop-keyboard-shortcuts.png and /dev/null differ diff --git a/UI/forms/images/settings/preferences-system-network-3.png b/UI/forms/images/settings/preferences-system-network-3.png deleted file mode 100644 index 3cfc3cb..0000000 Binary files a/UI/forms/images/settings/preferences-system-network-3.png and /dev/null differ diff --git a/UI/forms/images/settings/stream.svg b/UI/forms/images/settings/stream.svg new file mode 100644 index 0000000..6474c06 --- /dev/null +++ b/UI/forms/images/settings/stream.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/settings/system-settings-3.png b/UI/forms/images/settings/system-settings-3.png deleted file mode 100644 index afc55ff..0000000 Binary files a/UI/forms/images/settings/system-settings-3.png and /dev/null differ diff --git a/UI/forms/images/settings/video-display-3.png b/UI/forms/images/settings/video-display-3.png deleted file mode 100644 index 71e8379..0000000 Binary files a/UI/forms/images/settings/video-display-3.png and /dev/null differ diff --git a/UI/forms/images/settings/video.svg b/UI/forms/images/settings/video.svg new file mode 100644 index 0000000..f278de5 --- /dev/null +++ b/UI/forms/images/settings/video.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/sound.ico b/UI/forms/images/sound.ico deleted file mode 100644 index c7b86de..0000000 Binary files a/UI/forms/images/sound.ico and /dev/null differ diff --git a/UI/forms/images/sound_muted.ico b/UI/forms/images/sound_muted.ico deleted file mode 100644 index e68529b..0000000 Binary files a/UI/forms/images/sound_muted.ico and /dev/null differ diff --git a/UI/forms/images/trash.svg b/UI/forms/images/trash.svg new file mode 100644 index 0000000..fdc9bc2 --- /dev/null +++ b/UI/forms/images/trash.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/unlocked.svg b/UI/forms/images/unlocked.svg new file mode 100644 index 0000000..33641a3 --- /dev/null +++ b/UI/forms/images/unlocked.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/UI/forms/images/unlocked_mask.png b/UI/forms/images/unlocked_mask.png deleted file mode 100644 index 192be78..0000000 Binary files a/UI/forms/images/unlocked_mask.png and /dev/null differ diff --git a/UI/forms/images/unmute.png b/UI/forms/images/unmute.png deleted file mode 100644 index e849e3e..0000000 Binary files a/UI/forms/images/unmute.png and /dev/null differ diff --git a/UI/forms/images/up.png b/UI/forms/images/up.png deleted file mode 100644 index d881a91..0000000 Binary files a/UI/forms/images/up.png and /dev/null differ diff --git a/UI/forms/images/up.svg b/UI/forms/images/up.svg new file mode 100644 index 0000000..758bb33 --- /dev/null +++ b/UI/forms/images/up.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/visible.svg b/UI/forms/images/visible.svg new file mode 100644 index 0000000..26b604e --- /dev/null +++ b/UI/forms/images/visible.svg @@ -0,0 +1 @@ + diff --git a/UI/forms/images/visible_mask.png b/UI/forms/images/visible_mask.png deleted file mode 100644 index 67e8326..0000000 Binary files a/UI/forms/images/visible_mask.png and /dev/null differ diff --git a/UI/forms/obs.qrc b/UI/forms/obs.qrc index a68bc70..7c647c7 100644 --- a/UI/forms/obs.qrc +++ b/UI/forms/obs.qrc @@ -1,33 +1,29 @@ - images/mute.png - images/unmute.png - images/refresh.png - images/configuration21_16.png - images/invisible_mask.png - images/visible_mask.png - images/list_remove.png - images/add.png - images/down.png - images/editscene.png - images/live.png - images/properties.png - images/up.png + images/mute.svg + images/refresh.svg + images/no_sources.svg + images/minus.svg + images/plus.svg + images/down.svg + images/up.svg images/obs.png images/tray_active.png - images/locked_mask.png - images/unlocked_mask.png - images/collapse.png - images/expand.png + images/expand.svg + images/unlocked.svg + images/locked.svg + images/invisible.svg + images/visible.svg + images/trash.svg + images/revert.svg - images/settings/advanced.png - images/settings/network.png - images/settings/video-display-3.png - images/settings/decibel_audio_player.png - images/settings/applications-system-2.png - images/settings/system-settings-3.png - images/settings/network-bluetooth.png - images/settings/preferences-desktop-keyboard-shortcuts.png + images/settings/output.svg + images/settings/stream.svg + images/settings/advanced.svg + images/settings/video.svg + images/settings/audio.svg + images/settings/general.svg + images/settings/hotkeys.svg diff --git a/UI/frontend-plugins/CMakeLists.txt b/UI/frontend-plugins/CMakeLists.txt index bd2d336..908b5c7 100644 --- a/UI/frontend-plugins/CMakeLists.txt +++ b/UI/frontend-plugins/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(decklink-output-ui) add_subdirectory(frontend-tools) diff --git a/UI/frontend-plugins/decklink-output-ui/CMakeLists.txt b/UI/frontend-plugins/decklink-output-ui/CMakeLists.txt new file mode 100644 index 0000000..da82a6b --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/CMakeLists.txt @@ -0,0 +1,61 @@ +project(decklink-output-ui) + +if(APPLE) + find_library(COCOA Cocoa) + include_directories(${COCOA}) +endif() + +if(UNIX AND NOT APPLE) + find_package(X11 REQUIRED) + link_libraries(${X11_LIBRARIES}) + include_directories(${X11_INCLUDE_DIR}) +endif() + +set(decklink-ouput-ui_HEADERS + ${decklink-ouput-ui_HEADERS} + ../../properties-view.hpp + ../../properties-view.moc.hpp + ../../vertical-scroll-area.hpp + ../../double-slider.hpp + ../../slider-ignorewheel.hpp + ../../combobox-ignorewheel.hpp + ../../spinbox-ignorewheel.hpp + ./DecklinkOutputUI.h + decklink-ui-main.h + ) +set(decklink-ouput-ui_SOURCES + ${decklink-ouput-ui_SOURCES} + ../../properties-view.cpp + ../../vertical-scroll-area.cpp + ../../double-slider.cpp + ../../slider-ignorewheel.cpp + ../../combobox-ignorewheel.cpp + ../../spinbox-ignorewheel.cpp + ./DecklinkOutputUI.cpp + decklink-ui-main.cpp + ) +set(decklink-ouput-ui_UI + ${decklink-ouput-ui_UI} + forms/output.ui + ) + +if(APPLE) + set(decklink-ouput-ui_PLATFORM_LIBS + ${COCOA}) +endif() + +qt5_wrap_ui(decklink-ouput-ui_UI_HEADERS + ${decklink-ouput-ui_UI}) + +add_library(decklink-ouput-ui MODULE + ${decklink-ouput-ui_HEADERS} + ${decklink-ouput-ui_SOURCES} + ${decklink-ouput-ui_UI_HEADERS} + ) +target_link_libraries(decklink-ouput-ui + ${frontend-tools_PLATFORM_LIBS} + obs-frontend-api + Qt5::Widgets + libobs) + +install_obs_plugin_with_data(decklink-ouput-ui data) diff --git a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp new file mode 100644 index 0000000..59f25b0 --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.cpp @@ -0,0 +1,139 @@ +#include "DecklinkOutputUI.h" +#include +#include +#include +#include "decklink-ui-main.h" + +DecklinkOutputUI::DecklinkOutputUI(QWidget *parent) + : QDialog(parent), + ui(new Ui_Output) +{ + ui->setupUi(this); + + setSizeGripEnabled(true); + + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + propertiesView = nullptr; + previewPropertiesView = nullptr; + + connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput())); + connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput())); + + connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput())); + connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput())); +} + +void DecklinkOutputUI::ShowHideDialog() +{ + SetupPropertiesView(); + SetupPreviewPropertiesView(); + + setVisible(!isVisible()); +} + +void DecklinkOutputUI::SetupPropertiesView() +{ + if (propertiesView) + delete propertiesView; + + obs_data_t *settings = obs_data_create(); + + OBSData data = load_settings(); + if (data) + obs_data_apply(settings, data); + + propertiesView = new OBSPropertiesView(settings, + "decklink_output", + (PropertiesReloadCallback) obs_get_output_properties, + 170); + + ui->propertiesLayout->addWidget(propertiesView); + obs_data_release(settings); + + connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged())); +} + +void DecklinkOutputUI::SaveSettings() +{ + BPtr modulePath = obs_module_get_config_path(obs_current_module(), ""); + + os_mkdirs(modulePath); + + BPtr path = obs_module_get_config_path(obs_current_module(), + "decklinkOutputProps.json"); + + obs_data_t *settings = propertiesView->GetSettings(); + if (settings) + obs_data_save_json_safe(settings, path, "tmp", "bak"); +} + +void DecklinkOutputUI::SetupPreviewPropertiesView() +{ + if (previewPropertiesView) + delete previewPropertiesView; + + obs_data_t *settings = obs_data_create(); + + OBSData data = load_preview_settings(); + if (data) + obs_data_apply(settings, data); + + previewPropertiesView = new OBSPropertiesView(settings, + "decklink_output", + (PropertiesReloadCallback) obs_get_output_properties, + 170); + + ui->previewPropertiesLayout->addWidget(previewPropertiesView); + obs_data_release(settings); + + connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged())); +} + +void DecklinkOutputUI::SavePreviewSettings() +{ + char *modulePath = obs_module_get_config_path(obs_current_module(), ""); + + os_mkdirs(modulePath); + + char *path = obs_module_get_config_path(obs_current_module(), + "decklinkPreviewOutputProps.json"); + + obs_data_t *settings = previewPropertiesView->GetSettings(); + if (settings) + obs_data_save_json_safe(settings, path, "tmp", "bak"); +} + + +void DecklinkOutputUI::StartOutput() +{ + SaveSettings(); + output_start(); +} + +void DecklinkOutputUI::StopOutput() +{ + output_stop(); +} + +void DecklinkOutputUI::PropertiesChanged() +{ + SaveSettings(); +} + + +void DecklinkOutputUI::StartPreviewOutput() +{ + SavePreviewSettings(); + preview_output_start(); +} + +void DecklinkOutputUI::StopPreviewOutput() +{ + preview_output_stop(); +} + +void DecklinkOutputUI::PreviewPropertiesChanged() +{ + SavePreviewSettings(); +} \ No newline at end of file diff --git a/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h new file mode 100644 index 0000000..418e280 --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/DecklinkOutputUI.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include "ui_output.h" +#include "../../UI/properties-view.hpp" + +class DecklinkOutputUI : public QDialog { +Q_OBJECT +private: + OBSPropertiesView *propertiesView; + OBSPropertiesView *previewPropertiesView; + +public slots: + void StartOutput(); + void StopOutput(); + void PropertiesChanged(); + + void StartPreviewOutput(); + void StopPreviewOutput(); + void PreviewPropertiesChanged(); + +public: + std::unique_ptr ui; + DecklinkOutputUI(QWidget *parent); + + void ShowHideDialog(); + + void SetupPropertiesView(); + void SaveSettings(); + + void SetupPreviewPropertiesView(); + void SavePreviewSettings(); +}; diff --git a/UI/frontend-plugins/decklink-output-ui/data/.keepme b/UI/frontend-plugins/decklink-output-ui/data/.keepme new file mode 100644 index 0000000..e69de29 diff --git a/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp new file mode 100644 index 0000000..98c2c7b --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.cpp @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "DecklinkOutputUI.h" +#include "../../../plugins/decklink/const.h" + +OBS_DECLARE_MODULE() +OBS_MODULE_USE_DEFAULT_LOCALE("decklink-output-ui", "en-US") + +DecklinkOutputUI *doUI; + +bool main_output_running = false; +bool preview_output_running = false; + +obs_output_t *output; + +struct preview_output { + bool enabled; + obs_source_t *current_source; + obs_output_t *output; + + video_t *video_queue; + gs_texrender_t *texrender; + gs_stagesurf_t *stagesurface; + uint8_t *video_data; + uint32_t video_linesize; + + obs_video_info ovi; +}; + +static struct preview_output context = {0}; + +OBSData load_settings() +{ + BPtr path = obs_module_get_config_path(obs_current_module(), + "decklinkOutputProps.json"); + BPtr jsonData = os_quick_read_utf8_file(path); + if (!!jsonData) { + obs_data_t *data = obs_data_create_from_json(jsonData); + OBSData dataRet(data); + obs_data_release(data); + + return dataRet; + } + + return nullptr; +} + +void output_start() +{ + if (!main_output_running) { + OBSData settings = load_settings(); + + if (settings != nullptr) { + output = obs_output_create("decklink_output", + "decklink_output", settings, NULL); + + obs_output_start(output); + obs_data_release(settings); + + main_output_running = true; + } + } +} + +void output_stop() +{ + if (main_output_running) { + obs_output_stop(output); + obs_output_release(output); + main_output_running = false; + } +} + + +OBSData load_preview_settings() +{ + BPtr path = obs_module_get_config_path(obs_current_module(), + "decklinkPreviewOutputProps.json"); + BPtr jsonData = os_quick_read_utf8_file(path); + if (!!jsonData) { + obs_data_t *data = obs_data_create_from_json(jsonData); + OBSData dataRet(data); + obs_data_release(data); + + return dataRet; + } + + return nullptr; +} + +void on_preview_scene_changed(enum obs_frontend_event event, void *param); +void render_preview_source(void *param, uint32_t cx, uint32_t cy); + +void preview_output_start() +{ + if (!preview_output_running) { + OBSData settings = load_preview_settings(); + + if (settings != nullptr) { + context.output = obs_output_create("decklink_output", + "decklink_preview_output", settings, NULL); + + obs_get_video_info(&context.ovi); + + uint32_t width = context.ovi.base_width; + uint32_t height = context.ovi.base_height; + + obs_enter_graphics(); + context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE); + context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA); + obs_leave_graphics(); + + const video_output_info *mainVOI = video_output_get_info(obs_get_video()); + + video_output_info vi = {0}; + vi.format = VIDEO_FORMAT_BGRA; + vi.width = width; + vi.height = height; + vi.fps_den = context.ovi.fps_den; + vi.fps_num = context.ovi.fps_num; + vi.cache_size = 16; + vi.colorspace = mainVOI->colorspace; + vi.range = mainVOI->range; + vi.name = "decklink_preview_output"; + + video_output_open(&context.video_queue, &vi); + + obs_frontend_add_event_callback(on_preview_scene_changed, &context); + if (obs_frontend_preview_program_mode_active()) { + context.current_source = obs_frontend_get_current_preview_scene(); + } else { + context.current_source = obs_frontend_get_current_scene(); + } + obs_add_main_render_callback(render_preview_source, &context); + + obs_output_set_media(context.output, context.video_queue, obs_get_audio()); + obs_output_start(context.output); + + preview_output_running = true; + } + } +} + +void preview_output_stop() +{ + if (preview_output_running) { + obs_output_stop(context.output); + video_output_stop(context.video_queue); + + obs_remove_main_render_callback(render_preview_source, &context); + obs_frontend_remove_event_callback(on_preview_scene_changed, &context); + + obs_source_release(context.current_source); + + obs_enter_graphics(); + gs_stagesurface_destroy(context.stagesurface); + gs_texrender_destroy(context.texrender); + obs_leave_graphics(); + + video_output_close(context.video_queue); + + preview_output_running = false; + } +} + +void on_preview_scene_changed(enum obs_frontend_event event, void *param) +{ + auto ctx = (struct preview_output*)param; + switch (event) { + case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED: + case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED: + obs_source_release(ctx->current_source); + ctx->current_source = obs_frontend_get_current_preview_scene(); + break; + case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED: + obs_source_release(ctx->current_source); + ctx->current_source = obs_frontend_get_current_scene(); + break; + case OBS_FRONTEND_EVENT_SCENE_CHANGED: + if (!obs_frontend_preview_program_mode_active()) { + obs_source_release(ctx->current_source); + ctx->current_source = obs_frontend_get_current_scene(); + } + break; + default: + break; + } +} + +void render_preview_source(void *param, uint32_t cx, uint32_t cy) +{ + auto ctx = (struct preview_output*)param; + + if (!ctx->current_source) return; + + uint32_t width = obs_source_get_base_width(ctx->current_source); + uint32_t height = obs_source_get_base_height(ctx->current_source); + + gs_texrender_reset(ctx->texrender); + + if (gs_texrender_begin(ctx->texrender, width, height)) { + struct vec4 background; + vec4_zero(&background); + + gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0); + gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f); + + gs_blend_state_push(); + gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); + + obs_source_video_render(ctx->current_source); + + gs_blend_state_pop(); + gs_texrender_end(ctx->texrender); + + struct video_frame output_frame; + if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns())) + { + gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender)); + + if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) { + uint32_t linesize = output_frame.linesize[0]; + for (uint32_t i = 0; i < ctx->ovi.base_height; i++) { + uint32_t dst_offset = linesize * i; + uint32_t src_offset = ctx->video_linesize * i; + memcpy(output_frame.data[0] + dst_offset, + ctx->video_data + src_offset, + linesize); + } + + gs_stagesurface_unmap(ctx->stagesurface); + ctx->video_data = nullptr; + } + + video_output_unlock_frame(ctx->video_queue); + } + } +} + +void addOutputUI(void) +{ + QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction( + obs_module_text("Decklink Output")); + + QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window(); + + obs_frontend_push_ui_translation(obs_module_get_string); + doUI = new DecklinkOutputUI(window); + obs_frontend_pop_ui_translation(); + + auto cb = []() { + doUI->ShowHideDialog(); + }; + + action->connect(action, &QAction::triggered, cb); +} + +static void OBSEvent(enum obs_frontend_event event, void *) +{ + if (event == OBS_FRONTEND_EVENT_FINISHED_LOADING) { + OBSData settings = load_settings(); + + if (settings && obs_data_get_bool(settings, "auto_start")) + output_start(); + + OBSData previewSettings = load_preview_settings(); + + if (previewSettings && obs_data_get_bool(previewSettings, "auto_start")) + preview_output_start(); + } +} + +bool obs_module_load(void) +{ + addOutputUI(); + + obs_frontend_add_event_callback(OBSEvent, nullptr); + + return true; +} diff --git a/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.h b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.h new file mode 100644 index 0000000..ec91b8c --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/decklink-ui-main.h @@ -0,0 +1,8 @@ +#pragma once + +void output_start(); +void output_stop(); +OBSData load_settings(); +void preview_output_start(); +void preview_output_stop(); +OBSData load_preview_settings(); \ No newline at end of file diff --git a/UI/frontend-plugins/decklink-output-ui/forms/output.ui b/UI/frontend-plugins/decklink-output-ui/forms/output.ui new file mode 100644 index 0000000..bfaa385 --- /dev/null +++ b/UI/frontend-plugins/decklink-output-ui/forms/output.ui @@ -0,0 +1,128 @@ + + + Output + + + + 0 + 0 + 785 + 497 + + + + + 0 + 0 + + + + Decklink Output + + + true + + + false + + + + QLayout::SetDefaultConstraint + + + + + Output + + + + + + + + + + -1 + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Start + + + + + + + Stop + + + + + + + + + Preview Output + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Start + + + + + + + Stop + + + + + + + + + Keyer output requires RGB mode in advanced settings. + + + + + + + + diff --git a/UI/frontend-plugins/frontend-tools/CMakeLists.txt b/UI/frontend-plugins/frontend-tools/CMakeLists.txt index ca29cad..d595485 100644 --- a/UI/frontend-plugins/frontend-tools/CMakeLists.txt +++ b/UI/frontend-plugins/frontend-tools/CMakeLists.txt @@ -28,6 +28,9 @@ set(frontend-tools_HEADERS ../../horizontal-scroll-area.hpp ../../vertical-scroll-area.hpp ../../double-slider.hpp + ../../slider-ignorewheel.hpp + ../../combobox-ignorewheel.hpp + ../../spinbox-ignorewheel.hpp ) set(frontend-tools_SOURCES ${frontend-tools_SOURCES} @@ -38,6 +41,9 @@ set(frontend-tools_SOURCES ../../horizontal-scroll-area.cpp ../../vertical-scroll-area.cpp ../../double-slider.cpp + ../../slider-ignorewheel.cpp + ../../combobox-ignorewheel.cpp + ../../spinbox-ignorewheel.cpp ) set(frontend-tools_UI ${frontend-tools_UI} diff --git a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp index 06c0307..e8429c4 100644 --- a/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp +++ b/UI/frontend-plugins/frontend-tools/auto-scene-switcher.cpp @@ -89,6 +89,8 @@ SceneSwitcher::SceneSwitcher(QWidget *parent) { ui->setupUi(this); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + lock_guard lock(switcher->m); switcher->Prune(); diff --git a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp index f8b6425..2861949 100644 --- a/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp +++ b/UI/frontend-plugins/frontend-tools/captions-mssapi-stream.cpp @@ -249,8 +249,9 @@ STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag) stg->cbSize.QuadPart = (ULONGLONG)buf->size; if (flag == STATFLAG_DEFAULT) { - stg->pwcsName = (wchar_t*)CoTaskMemAlloc(sizeof(stat_name)); - memcpy(stg->pwcsName, stat_name, sizeof(stat_name)); + size_t byte_size = (wcslen(stat_name) + 1) * sizeof(wchar_t); + stg->pwcsName = (wchar_t*)CoTaskMemAlloc(byte_size); + memcpy(stg->pwcsName, stat_name, byte_size); } return S_OK; diff --git a/UI/frontend-plugins/frontend-tools/captions.cpp b/UI/frontend-plugins/frontend-tools/captions.cpp index 5c68d87..a53c09b 100644 --- a/UI/frontend-plugins/frontend-tools/captions.cpp +++ b/UI/frontend-plugins/frontend-tools/captions.cpp @@ -90,6 +90,8 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) : { ui->setupUi(this); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + auto cb = [this] (obs_source_t *source) { uint32_t caps = obs_source_get_output_flags(source); diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini b/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini new file mode 100644 index 0000000..7c74e15 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/ar-SA.ini @@ -0,0 +1,42 @@ +SceneSwitcher="مبدل المَشاهِد التلقائي" +SceneSwitcher.OnNoMatch="عندما لا تتطابق أي نافذة:" +SceneSwitcher.OnNoMatch.DontSwitch="لا تقم بالتبديل" +SceneSwitcher.OnNoMatch.SwitchTo="التبديل إلى:" +SceneSwitcher.CheckInterval="التأكد من عنوان النافذة النشطة كل:" +SceneSwitcher.ActiveOrNotActive="حالة مبدل المشاهد:" +InvalidRegex.Title="تعبير نمطي غير صحيح" +InvalidRegex.Text="التعبير النمطي الذي أدخلته غير صحيح." +Active="مفعّل" +Inactive="غير مُفعّل" +Start="ابدأ" +Stop="ايقاف" + +Captions="ترجمة فورية (تجريبي)" +Captions.AudioSource="مصدر الصوت" +Captions.CurrentSystemLanguage="لغة النظام الحالية (%1)" +Captions.Provider="موفر الخدمة" +Captions.Error.GenericFail="فشل في تشغيل الترجمة الفورية" + +OutputTimer="مؤقِّت الإخراج" +OutputTimer.Stream="إيقاف البث بعد:" +OutputTimer.Record="إيقاف التسجيل بعد:" +OutputTimer.Stream.StoppingIn="سيتم إيقاف البث بعد:" +OutputTimer.Record.StoppingIn="سيتم إيقاف التسجيل بعد:" +OutputTimer.Stream.EnableEverytime="تفعيل مؤقِّت البث في كل مرة" +OutputTimer.Record.EnableEverytime="تفعيل مؤقِّت التسجيل في كل مرة" + +Scripts="سكريبتات" +LoadedScripts="السكريبتات المحملة" +AddScripts="إضافة سكريبت" +RemoveScripts="إزالة السكريبت" +ReloadScripts="إعادة تحميل السكربتات" +PythonSettings="إعدادات بايثون" +PythonSettings.PythonInstallPath32bit="مسار تثبيت بايثون (32 بت)" +PythonSettings.PythonInstallPath64bit="مسار تثبيت بايثون (64 بت)" +PythonSettings.BrowsePythonPath="استعراض مسار البايثون" +ScriptLogWindow="سجل السكريبت" +Description="الوصف" + +FileFilter.ScriptFiles="ملفات السكريبت" +FileFilter.AllFiles="كافة الملفات" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/bg-BG.ini b/UI/frontend-plugins/frontend-tools/data/locale/bg-BG.ini new file mode 100644 index 0000000..86bb093 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/bg-BG.ini @@ -0,0 +1,35 @@ +SceneSwitcher="Автоматичен превключвател на сцени" +SceneSwitcher.OnNoMatch.DontSwitch="Не превключвай" +SceneSwitcher.OnNoMatch.SwitchTo="Превключи на:" +SceneSwitcher.CheckInterval="Проверка название на активния прозорец всеки:" +SceneSwitcher.ActiveOrNotActive="Превключвателят на сцени е:" +Active="Активен" +Inactive="Изключен" +Start="Начало" +Stop="Край" + +Captions="Надписи (експериментално)" +Captions.AudioSource="Аудио източник" +Captions.CurrentSystemLanguage="Текущ основен език (%1)" +Captions.Provider="Доставчик" +Captions.Error.GenericFail="Неуспешно зареждане на надписи" + +OutputTimer.Stream="Прекъсни излъчването след:" +OutputTimer.Record="Прекъсни записването след:" +OutputTimer.Stream.StoppingIn="Излъчването ще спре след:" +OutputTimer.Record.StoppingIn="Записването ще спре след:" +OutputTimer.Stream.EnableEverytime="Показвай брояча на излъчването всеки път" + +Scripts="Скриптове" +LoadedScripts="Заредени скриптове" +AddScripts="Добавяне скриптове" +RemoveScripts="Премахване скриптове" +ReloadScripts="Опресняване скриптове" +PythonSettings="Настройки Python" +PythonSettings.PythonInstallPath32bit="Път за инсталация на Python (32 бита)" +PythonSettings.PythonInstallPath64bit="Път за инсталация на Python (64 бита)" +ScriptLogWindow="Записи на скриптове" +Description="Описание" + +FileFilter.AllFiles="Всички файлове" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini index db752c7..72eb53f 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/da-DK.ini @@ -1,9 +1,9 @@ -SceneSwitcher="Automatisk sceneomskifter" +SceneSwitcher="Automatisk sceneskifter" SceneSwitcher.OnNoMatch="Når intet vindue matcher:" SceneSwitcher.OnNoMatch.DontSwitch="Skift ikke" SceneSwitcher.OnNoMatch.SwitchTo="Skift til:" -SceneSwitcher.CheckInterval="Kontroller aktivt vinduestitel hvert:" -SceneSwitcher.ActiveOrNotActive="Sceneomskifter er:" +SceneSwitcher.CheckInterval="Tjek aktiv vinduestitel hver:" +SceneSwitcher.ActiveOrNotActive="Sceneskifter er:" InvalidRegex.Title="Ugyldigt regulært udtryk" InvalidRegex.Text="Det af dig angivne regulære udtryk er ugyldigt." Active="Aktiv" @@ -11,19 +11,19 @@ Inactive="Inaktiv" Start="Start" Stop="Stop" -Captions="Undertekster (eksperimentel)" +Captions="Billedtekster (eksperimentel)" Captions.AudioSource="Lydkilde" Captions.CurrentSystemLanguage="Aktuelt systemsprog (%1)" Captions.Provider="Leverandør" -Captions.Error.GenericFail="Kunne ikke starte tekster" +Captions.Error.GenericFail="Kunne ikke starte billedtekster" -OutputTimer="Output-timer" +OutputTimer="Outputtimer" OutputTimer.Stream="Stands streaming efter:" OutputTimer.Record="Stands optagelse efter:" OutputTimer.Stream.StoppingIn="Streaming standser om:" -OutputTimer.Record.StoppingIn="Streaming standser om:" -OutputTimer.Stream.EnableEverytime="Aktivér streaming-timer hver gang" -OutputTimer.Record.EnableEverytime="Aktivér optage-timer hver gang" +OutputTimer.Record.StoppingIn="Optagelse standser om:" +OutputTimer.Stream.EnableEverytime="Aktivér streamingtimer hver gang" +OutputTimer.Record.EnableEverytime="Aktivér optagetimer hver gang" Scripts="Scripts" LoadedScripts="Indlæste scripts" @@ -33,7 +33,7 @@ ReloadScripts="Genindlæs scripts" PythonSettings="Python-indstillinger" PythonSettings.PythonInstallPath32bit="Python-installationssti (32bit)" PythonSettings.PythonInstallPath64bit="Python-installationssti (64bit)" -PythonSettings.BrowsePythonPath="Gennemse Python-sti" +PythonSettings.BrowsePythonPath="Find Python-sti" ScriptLogWindow="Scriptlog" Description="Beskrivelse" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini index 7d444c0..555c8df 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/de-DE.ini @@ -8,8 +8,8 @@ InvalidRegex.Title="Ungültiger regulärer Ausdruck" InvalidRegex.Text="Der reguläre Ausdruck, den Sie eingegeben haben, ist ungültig." Active="Aktiv" Inactive="Inaktiv" -Start="Start" -Stop="Stop" +Start="Starten" +Stop="Stoppen" Captions="Untertitel (experimentell)" Captions.AudioSource="Audioquelle" @@ -22,8 +22,8 @@ OutputTimer.Stream="Stoppe Stream nach:" OutputTimer.Record="Stoppe Aufnahme nach:" OutputTimer.Stream.StoppingIn="Stream stoppt in:" OutputTimer.Record.StoppingIn="Aufnahme stoppt in:" -OutputTimer.Stream.EnableEverytime="Streaming-Timer jedes Mal aktivieren" -OutputTimer.Record.EnableEverytime="Aufnahme-Timer jedes Mal aktivieren" +OutputTimer.Stream.EnableEverytime="Streamingtimer jedes Mal aktivieren" +OutputTimer.Record.EnableEverytime="Aufnahmetimer jedes Mal aktivieren" Scripts="Skripte" LoadedScripts="Geladene Skripte" @@ -31,8 +31,8 @@ AddScripts="Skripte hinzufügen" RemoveScripts="Skripte entfernen" ReloadScripts="Skripte neu laden" PythonSettings="Python-Einstellungen" -PythonSettings.PythonInstallPath32bit="Python Installationspfad (32bit)" -PythonSettings.PythonInstallPath64bit="Python Installationspfad (64bit)" +PythonSettings.PythonInstallPath32bit="Python-Installationspfad (32bit)" +PythonSettings.PythonInstallPath64bit="Python-Installationspfad (64bit)" PythonSettings.BrowsePythonPath="Python-Pfad öffnen" ScriptLogWindow="Skriptprotokoll" Description="Beschreibung" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini index 38ce98c..1b6fef5 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/es-ES.ini @@ -25,11 +25,11 @@ OutputTimer.Record.StoppingIn="Finalizando grabación en:" OutputTimer.Stream.EnableEverytime="Activar temporizador en cada transmisión" OutputTimer.Record.EnableEverytime="Activar temporizador en cada grabación" -Scripts="Guion" -LoadedScripts="Guiones cargados" -AddScripts="Agregar Guiones" -RemoveScripts="Quitar Guiones" -ReloadScripts="Recargar Guiones" +Scripts="Scripts" +LoadedScripts="Scripts Cargados" +AddScripts="Añadir Scripts" +RemoveScripts="Eliminar Scripts" +ReloadScripts="Recargar Scripts" PythonSettings="Configuración de Python" PythonSettings.PythonInstallPath32bit="Dirección de la instalación de Python (32bit)" PythonSettings.PythonInstallPath64bit="Dirección de la instalación de Python (64bit)" @@ -37,6 +37,6 @@ PythonSettings.BrowsePythonPath="Buscar Ruta de Phyton" ScriptLogWindow="Registro de secuencia de comandos" Description="Descripción" -FileFilter.ScriptFiles="Archivos de Guiones" +FileFilter.ScriptFiles="Archivos de Script" FileFilter.AllFiles="Todos los archivos" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/fa-IR.ini b/UI/frontend-plugins/frontend-tools/data/locale/fa-IR.ini new file mode 100644 index 0000000..dac6ec2 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/fa-IR.ini @@ -0,0 +1,25 @@ +SceneSwitcher.OnNoMatch="وقتی هیچ پنجره‌ای همخوانی نداشت:" +SceneSwitcher.OnNoMatch.DontSwitch="سوییچ نکن" +SceneSwitcher.OnNoMatch.SwitchTo="سویچ کن به:" +Active="فعال" +Inactive="غیر فعال" +Start="شروع" +Stop="توقف" + + +OutputTimer.Stream.EnableEverytime="هربار زمان سنج پخش جریانی را فعال کنید" +OutputTimer.Record.EnableEverytime="هربار زمان سنج ضبط را فعال کنید" + +Scripts="اسکریپت ها" +LoadedScripts="اسکریپت های بارگیری شده" +AddScripts="اضافه کردن اسکریپت ها" +RemoveScripts="پاک کردن اسکریپت ها" +ReloadScripts="بارگیری مجدد اسکریپت ها" +PythonSettings="تنظیمات پایتون" +PythonSettings.BrowsePythonPath="مرور مسیر پایتون" +ScriptLogWindow="اسکریپت نویسی" +Description="توضیحات" + +FileFilter.ScriptFiles="فایل های اسکریپت" +FileFilter.AllFiles="همه‌ی فایل ها" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini index 4b9abd7..6ebdffd 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/fr-FR.ini @@ -3,8 +3,8 @@ SceneSwitcher.OnNoMatch="Si aucune fenêtre ne correspond :" SceneSwitcher.OnNoMatch.DontSwitch="Ne rien faire" SceneSwitcher.OnNoMatch.SwitchTo="Basculer vers :" SceneSwitcher.CheckInterval="Vérifier le titre de la fenêtre active toutes les :" -SceneSwitcher.ActiveOrNotActive="Etat du sélecteur automatique :" -InvalidRegex.Title="Expression invalide" +SceneSwitcher.ActiveOrNotActive="État du sélecteur automatique :" +InvalidRegex.Title="Expression régulière invalide" InvalidRegex.Text="L'expression régulière saisie est invalide." Active="Actif" Inactive="Inactif" @@ -18,12 +18,12 @@ Captions.Provider="Sous-Titres" Captions.Error.GenericFail="Impossible de démarrer les sous-titres" OutputTimer="Minuterie des sorties" -OutputTimer.Stream="Arrêter le streaming dans :" -OutputTimer.Record="Arrêter l'enregistrement dans :" +OutputTimer.Stream="Arrêter le streaming après :" +OutputTimer.Record="Arrêter l'enregistrement après :" OutputTimer.Stream.StoppingIn="Arrêt du streaming dans :" OutputTimer.Record.StoppingIn="Arrêt de l'enregistrement dans :" -OutputTimer.Stream.EnableEverytime="Activer le minuteur automatiquement à chaque stream" -OutputTimer.Record.EnableEverytime="Activer le minuteur automatiquement à chaque enregistrement" +OutputTimer.Stream.EnableEverytime="Démarrer le minuteur automatiquement à chaque stream" +OutputTimer.Record.EnableEverytime="Démarrer le minuteur automatiquement à chaque enregistrement" Scripts="Scripts" LoadedScripts="Scripts chargés" @@ -33,7 +33,7 @@ ReloadScripts="Recharger les Scripts" PythonSettings="Paramètres Python" PythonSettings.PythonInstallPath32bit="Chemin d’installation Python (32 bits)" PythonSettings.PythonInstallPath64bit="Chemin d’installation Python (64 bits)" -PythonSettings.BrowsePythonPath="Parcourir le chemin de Python" +PythonSettings.BrowsePythonPath="Localiser l'installation de Python" ScriptLogWindow="Journal de script" Description="Description" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini b/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini index da8fbed..f0de18e 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/hr-HR.ini @@ -16,7 +16,7 @@ Captions="Opisi (experimentalno)" OutputTimer="Tempomat snimanja i emitovanja" OutputTimer.Stream="Zaustavi emitovanje nakon:" OutputTimer.Record="Zaustavi snimanje nakon:" -OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:" +OutputTimer.Stream.StoppingIn="Prekidanje emitiranja za:" OutputTimer.Record.StoppingIn="Prekidanje snimanja za:" OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put" OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini index d07ae54..45e909c 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/it-IT.ini @@ -1,4 +1,4 @@ -SceneSwitcher="Cambia scena automatico" +SceneSwitcher="Cambio scena automatico" SceneSwitcher.OnNoMatch="Quando nessuna finestra coincide:" SceneSwitcher.OnNoMatch.DontSwitch="Non passare" SceneSwitcher.OnNoMatch.SwitchTo="Passa a:" @@ -17,13 +17,13 @@ Captions.CurrentSystemLanguage="Lingua del sistema (%1)" Captions.Provider="Sintetizzatore" Captions.Error.GenericFail="Impossibile avviare i sottititoli" -OutputTimer="Timer di uscita" -OutputTimer.Stream="Termina diretta dopo:" -OutputTimer.Record="Termina registrazione dopo:" -OutputTimer.Stream.StoppingIn="La diretta terminerà in:" -OutputTimer.Record.StoppingIn="La registrazione terminerà in:" -OutputTimer.Stream.EnableEverytime="Abilita il timer per lo streaming ogni volta" -OutputTimer.Record.EnableEverytime="Abilita il timer per la registrazione ogni volta" +OutputTimer="Conto alla rovescia" +OutputTimer.Stream="Termina la diretta dopo:" +OutputTimer.Record="Termina la registrazione dopo:" +OutputTimer.Stream.StoppingIn="La diretta terminerà tra:" +OutputTimer.Record.StoppingIn="La registrazione terminerà tra:" +OutputTimer.Stream.EnableEverytime="Attiva il conto alla rovescia per le dirette ogni volta" +OutputTimer.Record.EnableEverytime="Attiva il conto alla rovescia per le registrazioni ogni volta" Scripts="Script" LoadedScripts="Script caricati" @@ -31,9 +31,9 @@ AddScripts="Aggiungi script" RemoveScripts="Rimuovi script" ReloadScripts="Ricarica script" PythonSettings="Impostazioni di Python" -PythonSettings.PythonInstallPath32bit="Percorso d'installazione di Python (32bit)" -PythonSettings.PythonInstallPath64bit="Percorso d'installazione di Python (64bit)" -PythonSettings.BrowsePythonPath="Sfoglia Percorso Python" +PythonSettings.PythonInstallPath32bit="Percorso d'installazione di Python (32 bit)" +PythonSettings.PythonInstallPath64bit="Percorso d'installazione di Python (64 bit)" +PythonSettings.BrowsePythonPath="Sfoglia il percorso di Python" ScriptLogWindow="Log degli script" Description="Descrizione" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini b/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini index d6288a3..fe12723 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ka-GE.ini @@ -20,7 +20,7 @@ Captions.Error.GenericFail="წარწერების დადება OutputTimer="ჩაწერის და ნაკადის წამზომი" OutputTimer.Stream="ნაკადი გაეშვას არაუმეტეს:" OutputTimer.Record="ჩაწერა გაგრძელდეს არაუმეტეს:" -OutputTimer.Stream.StoppingIn="ნაკადის შეჩერების დროა:" +OutputTimer.Stream.StoppingIn="ნაკადის შეწყვეტის დრო:" OutputTimer.Record.StoppingIn="ჩაწერის შეწყვეტის დრო:" OutputTimer.Stream.EnableEverytime="ნაკადის წამზომის ჩართვა ყოველ ჯერზე" OutputTimer.Record.EnableEverytime="ჩაწერის წამზომის ჩართვა ყოველ ჯერზე" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/mn-MN.ini b/UI/frontend-plugins/frontend-tools/data/locale/mn-MN.ini new file mode 100644 index 0000000..5884e0d --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/mn-MN.ini @@ -0,0 +1,32 @@ +SceneSwitcher.OnNoMatch.DontSwitch="Бүү соль" +SceneSwitcher.OnNoMatch.SwitchTo="Үүнрүү шилжүүл:" +Active="Идэвхтэй" +Inactive="Идэвхгүй" +Start="Эхлэх" +Stop="Зогсоох" + +Captions.AudioSource="Аудио эх сурвалж" +Captions.CurrentSystemLanguage="Одоогийн системийн хэл (%1)" +Captions.Provider="Үйлчилгээ үзүүлэгч" + +OutputTimer="Гаралтын цагийн тохируулга" +OutputTimer.Stream="Цацалтыг үүний дараа зогсоох:" +OutputTimer.Record="Бичлэгийг үүний дараа зогсоох:" +OutputTimer.Stream.StoppingIn="Урсгалыг зогсооход:" +OutputTimer.Record.StoppingIn="Бичлэгийг зогсооход:" + +Scripts="Скриптүүд" +LoadedScripts="Уншигдсан скриптүүд" +AddScripts="Скрипт нэмэх" +RemoveScripts="Скрипт хасах" +ReloadScripts="Скрипт дахин унших" +PythonSettings="Python тохиргоо" +PythonSettings.PythonInstallPath32bit="Python суусан байрлал (32 бит)" +PythonSettings.PythonInstallPath64bit="Python суусан байрлал (64 бит)" +PythonSettings.BrowsePythonPath="Python-ы замыг заах" +ScriptLogWindow="Скриптийн тэмдэглэл" +Description="Тайлбар" + +FileFilter.ScriptFiles="Скрипт файлууд" +FileFilter.AllFiles="Бүх файлууд" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini index 65481a8..618338a 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/pl-PL.ini @@ -1,4 +1,4 @@ -SceneSwitcher="Automatyczne Przełączanie Scen" +SceneSwitcher="Automatyczne przełączanie scen" SceneSwitcher.OnNoMatch="Gdy nie pasuje żadne okno:" SceneSwitcher.OnNoMatch.DontSwitch="Nie przełączaj" SceneSwitcher.OnNoMatch.SwitchTo="Przełącz na:" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini b/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini index a11f5d0..2167c08 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/pt-PT.ini @@ -14,6 +14,7 @@ Stop="Parar" Captions="Legendas (Experimental)" Captions.AudioSource="Fonte de audio" Captions.CurrentSystemLanguage="Linguagem de Sistema Atual (%1)" +Captions.Provider="Fornecedor" Captions.Error.GenericFail="Ocorreu um erro a iniciar legendas" OutputTimer="Temporizador de saída" @@ -24,5 +25,15 @@ OutputTimer.Record.StoppingIn="A gravação irá parar em:" OutputTimer.Stream.EnableEverytime="Ativar temporizador de transmissão sempre" OutputTimer.Record.EnableEverytime="Ativar temporizador de gravação sempre" +Scripts="Scripts" +LoadedScripts="Scripts Carregados" +AddScripts="Adicionar Scripts" +RemoveScripts="Remover Scripts" +ReloadScripts="Recarregar Scripts" +PythonSettings="Definições do Python" +PythonSettings.PythonInstallPath32bit="Caminho da Instalação do Python (32bits)" +PythonSettings.PythonInstallPath64bit="Caminho da Instalação do Python (64bits)" +Description="Descrição" +FileFilter.AllFiles="Todos os Ficheiros" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini index 11aa798..3e20647 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ro-RO.ini @@ -1,18 +1,33 @@ -SceneSwitcher="Schimbator automat de scenă" +SceneSwitcher="Schimbător automat de scene" SceneSwitcher.OnNoMatch="Când nicio fereastră nu se potrivește:" +SceneSwitcher.OnNoMatch.DontSwitch="Nu schimba" SceneSwitcher.OnNoMatch.SwitchTo="Schimbă la:" +SceneSwitcher.CheckInterval="Verifică titlul ferestrei active la fiecare:" +SceneSwitcher.ActiveOrNotActive="Schimbătorul de scene este:" Active="Activ" Inactive="Inactiv" -Start="Pornire" -Stop="Oprire" +Start="Pornește" +Stop="Oprește" Captions="Subtitrări (experimentale)" Captions.AudioSource="Sursa audio" -Captions.CurrentSystemLanguage="Limba curentă a sistemului (%1)" +Captions.CurrentSystemLanguage="Limba actuală a sistemului (%1)" Captions.Provider="Furnizor" -OutputTimer.Record="Opriți inregistrarea dupa:" -OutputTimer.Record.StoppingIn="Oprire înregistrare în:" - +OutputTimer.Record="Opriți înregistrarea după:" +OutputTimer.Stream.StoppingIn="Se oprește transmisiunea în:" +OutputTimer.Record.StoppingIn="Înregistrarea se oprește în:" + +Scripts="Scripturi" +LoadedScripts="Scripturi încărcate" +AddScripts="Adaugă scripturi" +RemoveScripts="Elimină scripturi" +ReloadScripts="Reîncarcă scripturile" +PythonSettings="Setări Python" +PythonSettings.PythonInstallPath32bit="Calea instalării Python (32bit)" +PythonSettings.PythonInstallPath64bit="Calea instalării Python (64bit)" +PythonSettings.BrowsePythonPath="Răsfoiește calea Python" +ScriptLogWindow="Jurnalul scripturilor" +Description="Descriere" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini index b5de83b..c3b8be2 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/ru-RU.ini @@ -17,10 +17,10 @@ Captions.CurrentSystemLanguage="Текущий язык системы (%1)" Captions.Provider="Поставщик" Captions.Error.GenericFail="Не удалось запустить субтитры" -OutputTimer="Таймер записи и трансляции" -OutputTimer.Stream="Завершить трансляцию через:" +OutputTimer="Таймер записи и стрима" +OutputTimer.Stream="Завершить стрим через:" OutputTimer.Record="Завершить запись через:" -OutputTimer.Stream.StoppingIn="Трансляция будет завершена через:" +OutputTimer.Stream.StoppingIn="Стрим будет завершён через:" OutputTimer.Record.StoppingIn="Запись будет завершена через:" OutputTimer.Stream.EnableEverytime="Включать таймер трансляции каждый раз" OutputTimer.Record.EnableEverytime="Включать таймер записи каждый раз" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini b/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini index 8208407..83de074 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/sk-SK.ini @@ -25,5 +25,18 @@ OutputTimer.Record.StoppingIn="Nahrávanie za zastaví za:" OutputTimer.Stream.EnableEverytime="Povoliť časovač streamovania zakaždým" OutputTimer.Record.EnableEverytime="Zapnúť časovač nahrávania zakaždým" +Scripts="Skripty" +LoadedScripts="Načítané skripty" +AddScripts="Pridať skripty" +RemoveScripts="Odstrániť skripty" +ReloadScripts="Znovu-načítať skripty" +PythonSettings="Python nastavenia" +PythonSettings.PythonInstallPath32bit="Python inštalačná cesta (32bitová)" +PythonSettings.PythonInstallPath64bit="Python inštalačná cesta (64bitová)" +PythonSettings.BrowsePythonPath="Prehliadať cestu k Pythonu" +ScriptLogWindow="Log skriptu" +Description="Popis" +FileFilter.ScriptFiles="Súbory skriptu" +FileFilter.AllFiles="Všetky súbory" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini b/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini index bf7c94f..52a522c 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/sr-CS.ini @@ -11,14 +11,32 @@ Inactive="Neaktivan" Start="Pokreni" Stop="Zaustavi" +Captions="Natpisi (Eksperimentalno)" +Captions.AudioSource="Izvor zvuka" +Captions.CurrentSystemLanguage="Trenutni jezik sistema (%1)" +Captions.Provider="Provajder" +Captions.Error.GenericFail="Nemogućnost prikazivanja natpisa" OutputTimer="Tempomat snimanja i emitovanja" OutputTimer.Stream="Zaustavi emitovanje nakon:" OutputTimer.Record="Zaustavi snimanje nakon:" OutputTimer.Stream.StoppingIn="Prekidanje emitovanja za:" OutputTimer.Record.StoppingIn="Prekidanje snimanja za:" -OutputTimer.Stream.EnableEverytime="Omogući štopovanje emitovanja svaki put" -OutputTimer.Record.EnableEverytime="Omogući štopovanje snimanja svaki put" +OutputTimer.Stream.EnableEverytime="Uključi tajmer strimovanja svaki put" +OutputTimer.Record.EnableEverytime="Uključi tajmer snimanja svaki put" +Scripts="Skripte" +LoadedScripts="Učitane skripte" +AddScripts="Dodaj skripte" +RemoveScripts="Izbaci skripte" +ReloadScripts="Ponovo učitaj skripte" +PythonSettings="Python podešavanja" +PythonSettings.PythonInstallPath32bit="Putanja do foldera sa Python instalacijom (32bit)" +PythonSettings.PythonInstallPath64bit="Putanja do foldera sa Python instalacijom (64bit)" +PythonSettings.BrowsePythonPath="Pretraži putanju do Python foldera" +ScriptLogWindow="Prijava skripte" +Description="Opis" +FileFilter.ScriptFiles="Fajlovi skripte" +FileFilter.AllFiles="Svi fajlovi" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini b/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini index f1e7a07..5d3cf49 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/sr-SP.ini @@ -11,14 +11,32 @@ Inactive="Неактиван" Start="Покрени" Stop="Заустави" +Captions="Натписи (експериментално)" +Captions.AudioSource="Извор звука" +Captions.CurrentSystemLanguage="Тренутни језик система (%1)" +Captions.Provider="Провајдер" +Captions.Error.GenericFail="Немогућност приказивања натписа" OutputTimer="Темпомат снимања и емитовања" OutputTimer.Stream="Заустави емитовање након:" OutputTimer.Record="Заустави снимање након:" OutputTimer.Stream.StoppingIn="Прекидање емитовања за:" OutputTimer.Record.StoppingIn="Прекидање снимања за:" -OutputTimer.Stream.EnableEverytime="Омогући штоповање емитовање сваки пут" -OutputTimer.Record.EnableEverytime="Омогући штоповање снимања сваки пут" +OutputTimer.Stream.EnableEverytime="Укључи тајмер стримовања сваки пут" +OutputTimer.Record.EnableEverytime="Укључи тајмер снимања сваки пут" +Scripts="Скрипте" +LoadedScripts="Учитане скрипте" +AddScripts="Додај скрипте" +RemoveScripts="Избаци скрипте" +ReloadScripts="Поново учитај скрипте" +PythonSettings="Python подешавања" +PythonSettings.PythonInstallPath32bit="Путања до фолдера са Python инсталацијом (32bit)" +PythonSettings.PythonInstallPath64bit="Путања до фолдера са Python инсталацијом (64bit)" +PythonSettings.BrowsePythonPath="Претражи путању до Python фолдера" +ScriptLogWindow="Пријава скрипте" +Description="Опис" +FileFilter.ScriptFiles="Фајлови скрипте" +FileFilter.AllFiles="Сви фајлови" diff --git a/UI/frontend-plugins/frontend-tools/data/locale/ta-IN.ini b/UI/frontend-plugins/frontend-tools/data/locale/ta-IN.ini new file mode 100644 index 0000000..d6aa356 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/ta-IN.ini @@ -0,0 +1,27 @@ +SceneSwitcher="தானியங்கு காட்சி நிலைமாற்றி" +SceneSwitcher.OnNoMatch.DontSwitch="மாற வேண்டாம்" +SceneSwitcher.OnNoMatch.SwitchTo="மாற்று:" +SceneSwitcher.CheckInterval="செயலில் உள்ள சாளர தலைப்பை சரிபார்க்கவும்:" +SceneSwitcher.ActiveOrNotActive="காட்சி இடமாற்றி உள்ளது:" +InvalidRegex.Title="செல்லாத வழக்கமான வெளிப்பாடு" +InvalidRegex.Text="நீங்கள் உள்ளிட்ட வழக்கமான தொடர் தவறானது." +Active="செயலில்" +Inactive="செயலற்ற" +Start="தொடங்கு" +Stop="நிறுத்து" + +Captions="தலைப்புகளை (சோதனை)" +Captions.AudioSource="ஒலி ஆதாரம்" +Captions.CurrentSystemLanguage="தற்போதைய அமைப்பு மொழி (%1)" +Captions.Provider="வழங்குநர்" +Captions.Error.GenericFail="தலைப்புகள் தொடங்குவதில் தோல்வி" + +OutputTimer="வெளியீடு நேரம்" +OutputTimer.Stream="நேரலை நிறுத்த நேரம்:" +OutputTimer.Record="பதிவு நிறுத்த நேரம்:" +OutputTimer.Stream.StoppingIn="நேரலை முடிவடையும் நேரம்:" +OutputTimer.Record.StoppingIn="பதிவு முடிவடையும் நேரம்:" + +Scripts="எழுத்து" + + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini b/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini new file mode 100644 index 0000000..d53ebb1 --- /dev/null +++ b/UI/frontend-plugins/frontend-tools/data/locale/th-TH.ini @@ -0,0 +1,13 @@ +Active="ใช้งานอยู่" +Inactive="ไม่ใช้งาน" +Start="เริ่ม" +Stop="หยุด" + + + +Scripts="สคริปต์" +AddScripts="เพิ่มสคริปต์" +Description="คำอธิบาย" + +FileFilter.AllFiles="ไฟล์ทั้งหมด" + diff --git a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini index 316d412..acd3d5f 100644 --- a/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini +++ b/UI/frontend-plugins/frontend-tools/data/locale/zh-CN.ini @@ -15,7 +15,7 @@ Captions="字幕 (实验)" Captions.AudioSource="音频源" Captions.CurrentSystemLanguage="当前系统语言 (%1)" Captions.Provider="提供程序" -Captions.Error.GenericFail="启动捕获失败" +Captions.Error.GenericFail="字幕启动失败" OutputTimer="输出计时器" OutputTimer.Stream="停止流处理后:" diff --git a/UI/frontend-plugins/frontend-tools/data/scripts/instant-replay.lua b/UI/frontend-plugins/frontend-tools/data/scripts/instant-replay.lua index 8137990..b1f82ff 100644 --- a/UI/frontend-plugins/frontend-tools/data/scripts/instant-replay.lua +++ b/UI/frontend-plugins/frontend-tools/data/scripts/instant-replay.lua @@ -2,6 +2,7 @@ obs = obslua source_name = "" hotkey_id = obs.OBS_INVALID_HOTKEY_ID attempts = 0 +last_replay = "" ---------------------------------------------------------- @@ -22,27 +23,45 @@ function try_play() obs.obs_output_release(replay_buffer) + if path == last_replay then + path = nil + end + -- If the path is valid and the source exists, update it with the -- replay file to play back the replay. Otherwise, stop attempting to - -- replay after 10 seconds + -- replay after 10 retries if path == nil then attempts = attempts + 1 if attempts >= 10 then obs.remove_current_callback() end else + last_replay = path local source = obs.obs_get_source_by_name(source_name) if source ~= nil then local settings = obs.obs_data_create() - obs.obs_data_set_string(settings, "local_file", path) - obs.obs_data_set_bool(settings, "is_local_file", true) - obs.obs_data_set_bool(settings, "close_when_inactive", true) - obs.obs_data_set_bool(settings, "restart_on_activate", true) + source_id = obs.obs_source_get_id(source) + if source_id == "ffmpeg_source" then + obs.obs_data_set_string(settings, "local_file", path) + obs.obs_data_set_bool(settings, "is_local_file", true) - -- updating will automatically cause the source to - -- refresh if the source is currently active, otherwise - -- the source will play whenever its scene is activated - obs.obs_source_update(source, settings) + -- updating will automatically cause the source to + -- refresh if the source is currently active + obs.obs_source_update(source, settings) + elseif source_id == "vlc_source" then + -- "playlist" + array = obs.obs_data_array_create() + item = obs.obs_data_create() + obs.obs_data_set_string(item, "value", path) + obs.obs_data_array_push_back(array, item) + obs.obs_data_set_array(settings, "playlist", array) + + -- updating will automatically cause the source to + -- refresh if the source is currently active + obs.obs_source_update(source, settings) + obs.obs_data_release(item) + obs.obs_data_array_release(array) + end obs.obs_data_release(settings) obs.obs_source_release(source) @@ -65,11 +84,11 @@ function instant_replay(pressed) local ph = obs.obs_output_get_proc_handler(replay_buffer) obs.proc_handler_call(ph, "save", nil) - -- Set a 1-second timer to attempt playback every 1 second + -- Set a 2-second timer to attempt playback every 1 second -- until the replay is available if obs.obs_output_active(replay_buffer) then attempts = 0 - obs.timer_add(try_play, 1000) + obs.timer_add(try_play, 2000) else obs.script_log(obs.LOG_WARNING, "Tried to save an instant replay, but the replay buffer is not active!") end @@ -90,7 +109,7 @@ end -- A function named script_description returns the description shown to -- the user function script_description() - return "When the \"Instant Replay\" hotkey is triggered, saves a replay with the replay buffer, and then plays it in a media source as soon as the replay is ready. Requires an active replay buffer.\n\nMade by Jim" + return "When the \"Instant Replay\" hotkey is triggered, saves a replay with the replay buffer, and then plays it in a media source as soon as the replay is ready. Requires an active replay buffer.\n\nMade by Jim and Exeldro" end -- A function named script_properties defines the properties that the user @@ -106,6 +125,11 @@ function script_properties() if source_id == "ffmpeg_source" then local name = obs.obs_source_get_name(source) obs.obs_property_list_add_string(p, name, name) + elseif source_id == "vlc_source" then + local name = obs.obs_source_get_name(source) + obs.obs_property_list_add_string(p, name, name) + else + -- obs.script_log(obs.LOG_INFO, source_id) end end end diff --git a/UI/frontend-plugins/frontend-tools/output-timer.cpp b/UI/frontend-plugins/frontend-tools/output-timer.cpp index f6de097..c889f4f 100644 --- a/UI/frontend-plugins/frontend-tools/output-timer.cpp +++ b/UI/frontend-plugins/frontend-tools/output-timer.cpp @@ -18,6 +18,8 @@ OutputTimer::OutputTimer(QWidget *parent) { ui->setupUi(this); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this, SLOT(StreamingTimerButton())); QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this, diff --git a/UI/frontend-plugins/frontend-tools/scripts.cpp b/UI/frontend-plugins/frontend-tools/scripts.cpp index 364757e..160032b 100644 --- a/UI/frontend-plugins/frontend-tools/scripts.cpp +++ b/UI/frontend-plugins/frontend-tools/scripts.cpp @@ -230,6 +230,15 @@ void ScriptsTool::ReloadScript(const char *path) const char *script_path = obs_script_get_path(script); if (strcmp(script_path, path) == 0) { obs_script_reload(script); + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + obs_properties_t *prop = + obs_script_get_properties(script); + obs_properties_apply_settings(prop, settings); + obs_properties_destroy(prop); + break; } } @@ -317,6 +326,14 @@ void ScriptsTool::on_addScripts_clicked() QListWidgetItem *item = new QListWidgetItem(script_file); item->setData(Qt::UserRole, QString(file)); ui->scripts->addItem(item); + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + obs_properties_t *prop = + obs_script_get_properties(script); + obs_properties_apply_settings(prop, settings); + obs_properties_destroy(prop); } } } diff --git a/UI/frontend-plugins/frontend-tools/scripts.hpp b/UI/frontend-plugins/frontend-tools/scripts.hpp index f638c3f..e6e5560 100644 --- a/UI/frontend-plugins/frontend-tools/scripts.hpp +++ b/UI/frontend-plugins/frontend-tools/scripts.hpp @@ -1,3 +1,5 @@ +#pragma once + #include #include diff --git a/UI/hotkey-edit.cpp b/UI/hotkey-edit.cpp index e76dc37..30af64a 100644 --- a/UI/hotkey-edit.cpp +++ b/UI/hotkey-edit.cpp @@ -272,13 +272,17 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) edit->setToolTip(toolTip); auto revert = new QPushButton; - revert->setProperty("themeID", "hotkeyButtons"); - revert->setText(QTStr("Revert")); + revert->setProperty("themeID", "revertIcon"); + revert->setToolTip(QTStr("Revert")); + revert->setFixedSize(24, 24); + revert->setFlat(true); revert->setEnabled(false); auto clear = new QPushButton; - clear->setProperty("themeID", "hotkeyButtons"); - clear->setText(QTStr("Clear")); + clear->setProperty("themeID", "trashIcon"); + clear->setToolTip(QTStr("Clear")); + clear->setFixedSize(24, 24); + clear->setFlat(true); clear->setEnabled(!obs_key_combination_is_empty(combo)); QObject::connect(edit, &OBSHotkeyEdit::KeyChanged, @@ -289,15 +293,15 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) }); auto add = new QPushButton; - add->setProperty("themeID", "hotkeyButtons"); - add->setText("+"); - add->setMinimumWidth(50); + add->setProperty("themeID", "addIconSmall"); + add->setFixedSize(24, 24); + add->setFlat(true); auto remove = new QPushButton; - remove->setProperty("themeID", "hotkeyButtons"); - remove->setText("-"); + remove->setProperty("themeID", "removeIconSmall"); remove->setEnabled(removeButtons.size() > 0); - remove->setMinimumWidth(50); + remove->setFixedSize(24, 24); + remove->setFlat(true); auto CurrentIndex = [&, remove] { @@ -320,6 +324,7 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx) }); QHBoxLayout *subLayout = new QHBoxLayout; + subLayout->setContentsMargins(0, 4, 0, 0); subLayout->addWidget(edit); subLayout->addWidget(revert); subLayout->addWidget(clear); diff --git a/UI/hotkey-edit.hpp b/UI/hotkey-edit.hpp index 3299e28..e7e7422 100644 --- a/UI/hotkey-edit.hpp +++ b/UI/hotkey-edit.hpp @@ -15,6 +15,8 @@ along with this program. If not, see . ******************************************************************************/ +#pragma once + #include #include #include diff --git a/UI/installer/mp-installer.nsi b/UI/installer/mp-installer.nsi index 06802c8..b46cf07 100644 --- a/UI/installer/mp-installer.nsi +++ b/UI/installer/mp-installer.nsi @@ -42,6 +42,10 @@ RequestExecutionLevel admin !define MUI_FINISHPAGE_RUN_TEXT "Launch OBS Studio ${SHORTVERSION}" !define MUI_FINISHPAGE_RUN_FUNCTION "LaunchOBS" +; GPL is not an EULA, no need to agree to it. +!define MUI_LICENSEPAGE_BUTTON $(^NextBtn) +!define MUI_LICENSEPAGE_TEXT_BOTTOM "You are now aware of your rights. Click Next to continue." + !define MUI_PAGE_CUSTOMFUNCTION_LEAVE PreReqCheck !insertmacro MUI_PAGE_WELCOME diff --git a/UI/locked-checkbox.cpp b/UI/locked-checkbox.cpp deleted file mode 100644 index 91a049f..0000000 --- a/UI/locked-checkbox.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include "locked-checkbox.hpp" - -#include - -LockedCheckBox::LockedCheckBox() : QCheckBox() -{ - lockedImage = - QPixmap::fromImage(QImage(":/res/images/locked_mask.png")); - unlockedImage = - QPixmap::fromImage(QImage(":/res/images/unlocked_mask.png")); - setMinimumSize(16, 16); - - setStyleSheet("outline: none;"); -} - -void LockedCheckBox::paintEvent(QPaintEvent *event) -{ - UNUSED_PARAMETER(event); - - QPixmap &pixmap = isChecked() ? lockedImage : unlockedImage; - QImage image(pixmap.size(), QImage::Format_ARGB32); - - QPainter draw(&image); - draw.setCompositionMode(QPainter::CompositionMode_Source); - draw.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap); - draw.setCompositionMode(QPainter::CompositionMode_SourceIn); - draw.fillRect(QRectF(QPointF(0.0f, 0.0f), pixmap.size()), - palette().color(foregroundRole())); - - QPainter p(this); - p.drawPixmap(0, 0, image.width(), image.height(), - QPixmap::fromImage(image)); -} diff --git a/UI/locked-checkbox.hpp b/UI/locked-checkbox.hpp index 017470f..0eb2d82 100644 --- a/UI/locked-checkbox.hpp +++ b/UI/locked-checkbox.hpp @@ -1,17 +1,7 @@ -#include -#include +#pragma once -class QPaintEvernt; +#include class LockedCheckBox : public QCheckBox { Q_OBJECT - - QPixmap lockedImage; - QPixmap unlockedImage; - -public: - LockedCheckBox(); - -protected: - void paintEvent(QPaintEvent *event) override; }; diff --git a/UI/obf.c b/UI/obf.c new file mode 100644 index 0000000..0ca8cc5 --- /dev/null +++ b/UI/obf.c @@ -0,0 +1,27 @@ +#include "obf.h" +#include + +#define LOWER_HALFBYTE(x) ((x) & 0xF) +#define UPPER_HALFBYTE(x) (((x) >> 4) & 0xF) + +void deobfuscate_str(char *str, uint64_t val) +{ + uint8_t *dec_val = (uint8_t*)&val; + int i = 0; + + while (*str != 0) { + int pos = i / 2; + bool bottom = (i % 2) == 0; + uint8_t *ch = (uint8_t*)str; + uint8_t xor = bottom ? + LOWER_HALFBYTE(dec_val[pos]) : + UPPER_HALFBYTE(dec_val[pos]); + + *ch ^= xor; + + if (++i == sizeof(uint64_t) * 2) + i = 0; + + str++; + } +} diff --git a/UI/obf.h b/UI/obf.h new file mode 100644 index 0000000..e264e19 --- /dev/null +++ b/UI/obf.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern void deobfuscate_str(char *str, uint64_t val); + +#ifdef __cplusplus +} +#endif diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp index 52b15a0..a2c7ab4 100644 --- a/UI/obs-app.cpp +++ b/UI/obs-app.cpp @@ -39,7 +39,6 @@ #include "obs-app.hpp" #include "window-basic-main.hpp" #include "window-basic-settings.hpp" -#include "window-license-agreement.hpp" #include "crash-report.hpp" #include "platform.hpp" @@ -51,10 +50,13 @@ #include #else #include +#include #endif #include +#include "ui-config.h" + using namespace std; static log_handler_t def_log_handler; @@ -78,6 +80,9 @@ string opt_starting_collection; string opt_starting_profile; string opt_starting_scene; +bool remuxAfterRecord = false; +string remuxFilename; + // GPU hint exports for AMD/NVIDIA laptops #ifdef _MSC_VER extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1; @@ -416,10 +421,12 @@ bool OBSApp::InitGlobalConfigDefaults() "ShowListboxToolbars", true); config_set_default_bool(globalConfig, "BasicWindow", "ShowStatusBar", true); + config_set_default_bool(globalConfig, "BasicWindow", + "StudioModeLabels", true); if (!config_get_bool(globalConfig, "General", "Pre21Defaults")) { config_set_default_string(globalConfig, "General", - "CurrentTheme", "Dark"); + "CurrentTheme", DEFAULT_THEME); } config_set_default_bool(globalConfig, "BasicWindow", @@ -709,6 +716,17 @@ bool OBSApp::InitGlobalConfig() changed = true; } + if (!config_has_user_value(globalConfig, "General", "Pre23Defaults")) { + uint32_t lastVersion = config_get_int(globalConfig, "General", + "LastVersion"); + bool useOldDefaults = lastVersion && + lastVersion < MAKE_SEMANTIC_VERSION(23, 0, 0); + + config_set_bool(globalConfig, "General", "Pre23Defaults", + useOldDefaults); + changed = true; + } + if (config_has_user_value(globalConfig, "BasicWindow", "MultiviewLayout")) { const char *layout = config_get_string(globalConfig, @@ -1011,18 +1029,21 @@ bool OBSApp::InitTheme() const char *themeName = config_get_string(globalConfig, "General", "CurrentTheme"); + if (!themeName) { /* Use deprecated "Theme" value if available */ themeName = config_get_string(globalConfig, "General", "Theme"); if (!themeName) - themeName = "Default"; + themeName = DEFAULT_THEME; + if (!themeName) + themeName = "Dark"; } - if (strcmp(themeName, "Default") != 0 && SetTheme(themeName)) - return true; + if (strcmp(themeName, "Default") == 0) + themeName = "System"; - return SetTheme("Default"); + return SetTheme(themeName); } OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store) @@ -1030,6 +1051,8 @@ OBSApp::OBSApp(int &argc, char **argv, profiler_name_store_t *store) profilerNameStore(store) { sleepInhibitor = os_inhibit_sleep_create("OBS Video/audio"); + + setWindowIcon(QIcon::fromTheme("obs", QIcon(":/res/images/obs.png"))); } OBSApp::~OBSApp() @@ -1159,6 +1182,20 @@ void OBSApp::AppInit() config_set_default_string(globalConfig, "Basic", "SceneCollectionFile", Str("Untitled")); + if (!config_has_user_value(globalConfig, "Basic", "Profile")) { + config_set_string(globalConfig, "Basic", "Profile", + Str("Untitled")); + config_set_string(globalConfig, "Basic", "ProfileDir", + Str("Untitled")); + } + + if (!config_has_user_value(globalConfig, "Basic", "SceneCollection")) { + config_set_string(globalConfig, "Basic", + "SceneCollection", Str("Untitled")); + config_set_string(globalConfig, "Basic", + "SceneCollectionFile", Str("Untitled")); + } + #ifdef _WIN32 bool disableAudioDucking = config_get_bool(globalConfig, "Audio", "DisableAudioDucking"); @@ -1212,60 +1249,59 @@ void OBSApp::EnableInFocusHotkeys(bool enable) ResetHotkeyState(applicationState() != Qt::ApplicationActive); } +Q_DECLARE_METATYPE(VoidFunc) + +void OBSApp::Exec(VoidFunc func) +{ + func(); +} + bool OBSApp::OBSInit() { ProfileScope("OBSApp::OBSInit"); - bool licenseAccepted = config_get_bool(globalConfig, "General", - "LicenseAccepted"); - OBSLicenseAgreement agreement(nullptr); + setAttribute(Qt::AA_UseHighDpiPixmaps); - if (licenseAccepted || agreement.exec() == QDialog::Accepted) { - if (!licenseAccepted) { - config_set_bool(globalConfig, "General", - "LicenseAccepted", true); - config_save(globalConfig); - } + qRegisterMetaType(); - if (!StartupOBS(locale.c_str(), GetProfilerNameStore())) - return false; + if (!StartupOBS(locale.c_str(), GetProfilerNameStore())) + return false; #ifdef _WIN32 - bool browserHWAccel = config_get_bool(globalConfig, "General", - "BrowserHWAccel"); + bool browserHWAccel = config_get_bool(globalConfig, "General", + "BrowserHWAccel"); - obs_data_t *settings = obs_data_create(); - obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel); - obs_apply_private_data(settings); - obs_data_release(settings); + obs_data_t *settings = obs_data_create(); + obs_data_set_bool(settings, "BrowserHWAccel", browserHWAccel); + obs_apply_private_data(settings); + obs_data_release(settings); - blog(LOG_INFO, "Browser Hardware Acceleration: %s", - browserHWAccel ? "true" : "false"); + blog(LOG_INFO, "Current Date/Time: %s", CurrentDateTimeString().c_str()); + + blog(LOG_INFO, "Browser Hardware Acceleration: %s", + browserHWAccel ? "true" : "false"); #endif - blog(LOG_INFO, "Portable mode: %s", - portable_mode ? "true" : "false"); + blog(LOG_INFO, "Portable mode: %s", + portable_mode ? "true" : "false"); - setQuitOnLastWindowClosed(false); + setQuitOnLastWindowClosed(false); - mainWindow = new OBSBasic(); + mainWindow = new OBSBasic(); - mainWindow->setAttribute(Qt::WA_DeleteOnClose, true); - connect(mainWindow, SIGNAL(destroyed()), this, SLOT(quit())); + mainWindow->setAttribute(Qt::WA_DeleteOnClose, true); + connect(mainWindow, SIGNAL(destroyed()), this, SLOT(quit())); - mainWindow->OBSInit(); + mainWindow->OBSInit(); - connect(this, &QGuiApplication::applicationStateChanged, - [this](Qt::ApplicationState state) - { - ResetHotkeyState( - state != Qt::ApplicationActive); - }); - ResetHotkeyState(applicationState() != Qt::ApplicationActive); - return true; - } else { - return false; - } + connect(this, &QGuiApplication::applicationStateChanged, + [this](Qt::ApplicationState state) + { + ResetHotkeyState( + state != Qt::ApplicationActive); + }); + ResetHotkeyState(applicationState() != Qt::ApplicationActive); + return true; } string OBSApp::GetVersionString() const @@ -1506,8 +1542,18 @@ string GenerateTimeDateFilename(const char *extension, bool noSpace) string GenerateSpecifiedFilename(const char *extension, bool noSpace, const char *format) { + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + bool autoRemux = config_get_bool(main->Config(), "Video", "AutoRemux"); + + if ((strcmp(extension, "mp4") == 0) && autoRemux) + extension = "mkv"; + BPtr filename = os_generate_formatted_filename(extension, !noSpace, format); + + remuxFilename = string(filename); + remuxAfterRecord = autoRemux; + return string(filename); } @@ -1646,6 +1692,10 @@ static int run_program(fstream &logFile, int argc, char *argv[]) ScopeProfiler prof{run_program_init}; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif + QCoreApplication::addLibraryPath("."); OBSApp program(argc, argv, profilerNameStore.get()); @@ -2177,10 +2227,37 @@ static void upgrade_settings(void) os_closedir(dir); } +void ctrlc_handler (int s) { + UNUSED_PARAMETER(s); + + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + main->close(); +} + int main(int argc, char *argv[]) { #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); + + struct sigaction sig_handler; + + sig_handler.sa_handler = ctrlc_handler; + sigemptyset(&sig_handler.sa_mask); + sig_handler.sa_flags = 0; + + sigaction(SIGINT, &sig_handler, NULL); + + + /* Block SIGPIPE in all threads, this can happen if a thread calls write on + a closed pipe. */ + sigset_t sigpipe_mask; + sigemptyset(&sigpipe_mask); + sigaddset(&sigpipe_mask, SIGPIPE); + sigset_t saved_mask; + if (pthread_sigmask(SIG_BLOCK, &sigpipe_mask, &saved_mask) == -1) { + perror("pthread_sigmask"); + exit(1); + } #endif #ifdef _WIN32 @@ -2196,6 +2273,8 @@ int main(int argc, char *argv[]) move_to_xdg(); #endif + obs_set_cmdline_args(argc, argv); + for (int i = 1; i < argc; i++) { if (arg_is(argv[i], "--portable", "-p")) { portable_mode = true; diff --git a/UI/obs-app.hpp b/UI/obs-app.hpp index 9fd7448..2815331 100644 --- a/UI/obs-app.hpp +++ b/UI/obs-app.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ public: const char *disambiguation, int n) const override; }; +typedef std::function VoidFunc; + class OBSApp : public QApplication { Q_OBJECT @@ -166,6 +169,9 @@ public: translatorHooks.pop_front(); } +public slots: + void Exec(VoidFunc func); + signals: void StyleChanged(); }; @@ -197,6 +203,10 @@ static inline int GetProfilePath(char *path, size_t size, const char *file) } extern bool portable_mode; + +extern bool remuxAfterRecord; +extern std::string remuxFilename; + extern bool opt_start_streaming; extern bool opt_start_recording; extern bool opt_start_replaybuffer; diff --git a/UI/obs-frontend-api/obs-frontend-api.cpp b/UI/obs-frontend-api/obs-frontend-api.cpp index c3c933a..3fe84f4 100644 --- a/UI/obs-frontend-api/obs-frontend-api.cpp +++ b/UI/obs-frontend-api/obs-frontend-api.cpp @@ -71,6 +71,13 @@ void *obs_frontend_get_main_window_handle(void) : nullptr; } +void *obs_frontend_get_system_tray(void) +{ + return !!callbacks_valid() + ? c->obs_frontend_get_system_tray() + : nullptr; +} + char **obs_frontend_get_scene_names(void) { if (!callbacks_valid()) @@ -125,6 +132,19 @@ void obs_frontend_set_current_transition(obs_source_t *transition) c->obs_frontend_set_current_transition(transition); } +int obs_frontend_get_transition_duration(void) +{ + return !!callbacks_valid() + ? c->obs_frontend_get_transition_duration() + : 0; +} + +void obs_frontend_set_transition_duration(int duration) +{ + if (callbacks_valid()) + c->obs_frontend_set_transition_duration(duration); +} + char **obs_frontend_get_scene_collections(void) { if (!callbacks_valid()) @@ -249,6 +269,13 @@ void obs_frontend_add_tools_menu_item(const char *name, private_data); } +void *obs_frontend_add_dock(void *dock) +{ + return !!callbacks_valid() + ? c->obs_frontend_add_dock(dock) + : nullptr; +} + void obs_frontend_add_event_callback(obs_frontend_event_cb callback, void *private_data) { @@ -388,6 +415,12 @@ void obs_frontend_set_preview_program_mode(bool enable) c->obs_frontend_set_preview_program_mode(enable); } +void obs_frontend_preview_program_trigger_transition(void) +{ + if (callbacks_valid()) + c->obs_frontend_preview_program_trigger_transition(); +} + void obs_frontend_set_preview_enabled(bool enable) { if (callbacks_valid()) diff --git a/UI/obs-frontend-api/obs-frontend-api.h b/UI/obs-frontend-api/obs-frontend-api.h index ae67494..52f0bee 100644 --- a/UI/obs-frontend-api/obs-frontend-api.h +++ b/UI/obs-frontend-api/obs-frontend-api.h @@ -82,6 +82,7 @@ static inline void obs_frontend_source_list_free( EXPORT void *obs_frontend_get_main_window(void); EXPORT void *obs_frontend_get_main_window_handle(void); +EXPORT void *obs_frontend_get_system_tray(void); EXPORT char **obs_frontend_get_scene_names(void); EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources); @@ -92,6 +93,8 @@ EXPORT void obs_frontend_get_transitions( struct obs_frontend_source_list *sources); EXPORT obs_source_t *obs_frontend_get_current_transition(void); EXPORT void obs_frontend_set_current_transition(obs_source_t *transition); +EXPORT int obs_frontend_get_transition_duration(void); +EXPORT void obs_frontend_set_transition_duration(int duration); EXPORT char **obs_frontend_get_scene_collections(void); EXPORT char *obs_frontend_get_current_scene_collection(void); @@ -108,6 +111,9 @@ EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name); EXPORT void obs_frontend_add_tools_menu_item(const char *name, obs_frontend_cb callback, void *private_data); +/* takes QDockWidget and returns QAction */ +EXPORT void *obs_frontend_add_dock(void *dock); + typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event, void *private_data); @@ -168,6 +174,7 @@ EXPORT void obs_frontend_save_streaming_service(void); EXPORT bool obs_frontend_preview_program_mode_active(void); EXPORT void obs_frontend_set_preview_program_mode(bool enable); +EXPORT void obs_frontend_preview_program_trigger_transition(void); EXPORT void obs_frontend_set_preview_enabled(bool enable); EXPORT bool obs_frontend_preview_enabled(void); diff --git a/UI/obs-frontend-api/obs-frontend-internal.hpp b/UI/obs-frontend-api/obs-frontend-internal.hpp index b1a9064..3ed9283 100644 --- a/UI/obs-frontend-api/obs-frontend-internal.hpp +++ b/UI/obs-frontend-api/obs-frontend-internal.hpp @@ -9,6 +9,7 @@ struct obs_frontend_callbacks { virtual ~obs_frontend_callbacks() {} virtual void *obs_frontend_get_main_window(void)=0; virtual void *obs_frontend_get_main_window_handle(void)=0; + virtual void *obs_frontend_get_system_tray(void)=0; virtual void obs_frontend_get_scenes( struct obs_frontend_source_list *sources)=0; @@ -20,6 +21,8 @@ struct obs_frontend_callbacks { virtual obs_source_t *obs_frontend_get_current_transition(void)=0; virtual void obs_frontend_set_current_transition( obs_source_t *transition)=0; + virtual int obs_frontend_get_transition_duration(void)=0; + virtual void obs_frontend_set_transition_duration(int duration)=0; virtual void obs_frontend_get_scene_collections( std::vector &strings)=0; @@ -50,6 +53,8 @@ struct obs_frontend_callbacks { virtual void obs_frontend_add_tools_menu_item(const char *name, obs_frontend_cb callback, void *private_data)=0; + virtual void *obs_frontend_add_dock(void *dock)=0; + virtual void obs_frontend_add_event_callback( obs_frontend_event_cb callback, void *private_data)=0; virtual void obs_frontend_remove_event_callback( @@ -86,6 +91,8 @@ struct obs_frontend_callbacks { virtual bool obs_frontend_preview_program_mode_active(void)=0; virtual void obs_frontend_set_preview_program_mode(bool enable)=0; + virtual void obs_frontend_preview_program_trigger_transition(void)=0; + virtual bool obs_frontend_preview_enabled(void)=0; virtual void obs_frontend_set_preview_enabled(bool enable)=0; diff --git a/UI/obs.rc b/UI/obs.rc deleted file mode 100644 index 505bd21..0000000 --- a/UI/obs.rc +++ /dev/null @@ -1 +0,0 @@ -IDI_ICON1 ICON DISCARDABLE "../cmake/winrc/obs-studio.ico" diff --git a/UI/obs.rc.in b/UI/obs.rc.in new file mode 100644 index 0000000..523d41f --- /dev/null +++ b/UI/obs.rc.in @@ -0,0 +1,26 @@ +IDI_ICON1 ICON DISCARDABLE "../cmake/winrc/obs-studio.ico" + +1 VERSIONINFO +FILEVERSION ${UI_VERSION_MAJOR},${UI_VERSION_MINOR},${UI_VERSION_PATCH},0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "OBS" + VALUE "FileDescription", "OBS Studio" + VALUE "FileVersion", "${UI_VERSION}" + VALUE "InternalName", "obs" + VALUE "OriginalFilename", "obs" + VALUE "ProductName", "OBS Studio" + VALUE "ProductVersion", "${UI_VERSION}" + VALUE "Comments", "Free and open source software for video recording and live streaming" + VALUE "LegalCopyright", "(C) Hugh Bailey" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 0x04B0 + END +END \ No newline at end of file diff --git a/UI/properties-view.cpp b/UI/properties-view.cpp index 4a286b6..a1f9ba8 100644 --- a/UI/properties-view.cpp +++ b/UI/properties-view.cpp @@ -18,7 +18,12 @@ #include #include #include +#include +#include #include "double-slider.hpp" +#include "slider-ignorewheel.hpp" +#include "spinbox-ignorewheel.hpp" +#include "combobox-ignorewheel.hpp" #include "qt-wrappers.hpp" #include "properties-view.hpp" #include "properties-view.moc.hpp" @@ -147,6 +152,8 @@ void OBSPropertiesView::RefreshProperties() QLabel *noPropertiesLabel = new QLabel(NO_PROPERTIES_STRING); layout->addWidget(noPropertiesLabel); } + + emit PropertiesRefreshed(); } void OBSPropertiesView::SetScrollPos(int h, int v) @@ -320,7 +327,7 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout, const char *name = obs_property_name(prop); int val = (int)obs_data_get_int(settings, name); - QSpinBox *spin = new QSpinBox(); + QSpinBox *spin = new SpinBoxIgnoreScroll(); if (!obs_property_enabled(prop)) spin->setEnabled(false); @@ -328,18 +335,20 @@ void OBSPropertiesView::AddInt(obs_property_t *prop, QFormLayout *layout, int minVal = obs_property_int_min(prop); int maxVal = obs_property_int_max(prop); int stepVal = obs_property_int_step(prop); + const char *suffix = obs_property_int_suffix(prop); spin->setMinimum(minVal); spin->setMaximum(maxVal); spin->setSingleStep(stepVal); spin->setValue(val); spin->setToolTip(QT_UTF8(obs_property_long_description(prop))); + spin->setSuffix(QT_UTF8(suffix)); WidgetInfo *info = new WidgetInfo(this, prop, spin); children.emplace_back(info); if (type == OBS_NUMBER_SLIDER) { - QSlider *slider = new QSlider(); + QSlider *slider = new SliderIgnoreScroll(); slider->setMinimum(minVal); slider->setMaximum(maxVal); slider->setPageStep(stepVal); @@ -377,12 +386,14 @@ void OBSPropertiesView::AddFloat(obs_property_t *prop, QFormLayout *layout, double minVal = obs_property_float_min(prop); double maxVal = obs_property_float_max(prop); double stepVal = obs_property_float_step(prop); + const char *suffix = obs_property_float_suffix(prop); spin->setMinimum(minVal); spin->setMaximum(maxVal); spin->setSingleStep(stepVal); spin->setValue(val); spin->setToolTip(QT_UTF8(obs_property_long_description(prop))); + spin->setSuffix(QT_UTF8(suffix)); WidgetInfo *info = new WidgetInfo(this, prop, spin); children.emplace_back(info); @@ -480,7 +491,7 @@ static string from_obs_data_autoselect(obs_data_t *data, const char *name, QWidget *OBSPropertiesView::AddList(obs_property_t *prop, bool &warning) { const char *name = obs_property_name(prop); - QComboBox *combo = new QComboBox(); + QComboBox *combo = new ComboBoxIgnoreScroll(); obs_combo_type type = obs_property_list_type(prop); obs_combo_format format = obs_property_list_format(prop); size_t count = obs_property_list_item_count(prop); @@ -912,7 +923,7 @@ static QWidget *CreateSimpleFPSValues(OBSFrameRatePropertyWidget *fpsProps, auto items = vector{}; items.reserve(sizeof(common_fps)/sizeof(common_frame_rate)); - auto combo = fpsProps->simpleFPS = new QComboBox{}; + auto combo = fpsProps->simpleFPS = new ComboBoxIgnoreScroll{}; combo->addItem("", QVariant::fromValue(make_fps(0, 0))); for (const auto &fps : common_fps) { @@ -992,7 +1003,7 @@ static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps, auto str = QTStr("Basic.PropertiesView.FPS.ValidFPSRanges"); auto rlabel = new QLabel{str}; - auto combo = fpsProps->fpsRange = new QComboBox{}; + auto combo = fpsProps->fpsRange = new ComboBoxIgnoreScroll{}; auto convert_fps = media_frames_per_second_to_fps; //auto convert_fi = media_frames_per_second_to_frame_interval; @@ -1013,8 +1024,8 @@ static QWidget *CreateRationalFPS(OBSFrameRatePropertyWidget *fpsProps, layout->addRow(rlabel, combo); - auto num_edit = fpsProps->numEdit = new QSpinBox{}; - auto den_edit = fpsProps->denEdit = new QSpinBox{}; + auto num_edit = fpsProps->numEdit = new SpinBoxIgnoreScroll{}; + auto den_edit = fpsProps->denEdit = new SpinBoxIgnoreScroll{}; num_edit->setRange(0, INT_MAX); den_edit->setRange(0, INT_MAX); @@ -1043,7 +1054,7 @@ static OBSFrameRatePropertyWidget *CreateFrameRateWidget(obs_property_t *prop, swap(widget->fps_ranges, fps_ranges); - auto combo = widget->modeSelect = new QComboBox{}; + auto combo = widget->modeSelect = new ComboBoxIgnoreScroll{}; combo->addItem(QTStr("Basic.PropertiesView.FPS.Simple"), QVariant::fromValue(frame_rate_tag::simple())); combo->addItem(QTStr("Basic.PropertiesView.FPS.Rational"), @@ -1328,6 +1339,44 @@ void OBSPropertiesView::AddFrameRate(obs_property_t *prop, bool &warning, }); } +void OBSPropertiesView::AddGroup(obs_property_t *prop, QFormLayout *layout) +{ + const char *name = obs_property_name(prop); + bool val = obs_data_get_bool(settings, name); + const char *desc = obs_property_description(prop); + enum obs_group_type type = obs_property_group_type(prop); + + // Create GroupBox + QGroupBox *groupBox = new QGroupBox(QT_UTF8(desc)); + groupBox->setCheckable(type == OBS_GROUP_CHECKABLE); + groupBox->setChecked(groupBox->isCheckable() ? val : true); + groupBox->setAccessibleName("group"); + groupBox->setEnabled(obs_property_enabled(prop)); + + // Create Layout and build content + QFormLayout *subLayout = new QFormLayout(); + subLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + groupBox->setLayout(subLayout); + + obs_properties_t *content = obs_property_group_content(prop); + obs_property_t *el = obs_properties_first(content); + while (el != nullptr) { + AddProperty(el, subLayout); + obs_property_next(&el); + } + + // Insert into UI + layout->setWidget(layout->rowCount(), + QFormLayout::ItemRole::SpanningRole, groupBox); + + // Register Group Widget + WidgetInfo *info = new WidgetInfo(this, prop, groupBox); + children.emplace_back(info); + + // Signals + connect(groupBox, SIGNAL(toggled()), info, SLOT(ControlChanged())); +} + void OBSPropertiesView::AddProperty(obs_property_t *property, QFormLayout *layout) { @@ -1377,6 +1426,8 @@ void OBSPropertiesView::AddProperty(obs_property_t *property, case OBS_PROPERTY_FRAME_RATE: AddFrameRate(property, warning, layout, label); break; + case OBS_PROPERTY_GROUP: + AddGroup(property, layout); } if (widget && !obs_property_enabled(property)) @@ -1384,7 +1435,8 @@ void OBSPropertiesView::AddProperty(obs_property_t *property, if (!label && type != OBS_PROPERTY_BOOL && - type != OBS_PROPERTY_BUTTON) + type != OBS_PROPERTY_BUTTON && + type != OBS_PROPERTY_GROUP) label = new QLabel(QT_UTF8(obs_property_description(property))); if (warning && label) //TODO: select color based on background color @@ -1625,8 +1677,7 @@ bool WidgetInfo::ColorChanged(const char *setting) long long val = obs_data_get_int(view->settings, setting); QColor color = color_from_int(val); - QColorDialog::ColorDialogOptions options = - QColorDialog::ShowAlphaChannel; + QColorDialog::ColorDialogOptions options = 0; /* The native dialog on OSX has all kinds of problems, like closing * other open QDialogs on exit, and @@ -1703,6 +1754,13 @@ bool WidgetInfo::FontChanged(const char *setting) return true; } +void WidgetInfo::GroupChanged(const char *setting) +{ + QGroupBox *groupbox = static_cast(widget); + obs_data_set_bool(view->settings, setting, + groupbox->isCheckable() ? groupbox->isChecked() : true); +} + void WidgetInfo::EditableListChanged() { const char *setting = obs_property_name(property); @@ -1772,6 +1830,7 @@ void WidgetInfo::ControlChanged() if (!FrameRateChanged(widget, setting, view->settings)) return; break; + case OBS_PROPERTY_GROUP: GroupChanged(setting); return; } if (view->callback && !view->deferUpdate) @@ -1977,9 +2036,21 @@ void WidgetInfo::EditListEdit() QListWidgetItem *item = selectedItems[0]; if (type == OBS_EDITABLE_LIST_TYPE_FILES) { - QString path = QFileDialog::getOpenFileName( + QDir pathDir(item->text()); + QString path; + + if (pathDir.exists()) + path = QFileDialog::getExistingDirectory( + App()->GetMainWindow(), + QTStr("Browse"), + item->text(), + QFileDialog::ShowDirsOnly | + QFileDialog::DontResolveSymlinks); + else + path = QFileDialog::getOpenFileName( App()->GetMainWindow(), QTStr("Browse"), item->text(), QT_UTF8(filter)); + if (path.isEmpty()) return; diff --git a/UI/properties-view.hpp b/UI/properties-view.hpp index 4a153c7..ee9d255 100644 --- a/UI/properties-view.hpp +++ b/UI/properties-view.hpp @@ -33,6 +33,7 @@ private: void ListChanged(const char *setting); bool ColorChanged(const char *setting); bool FontChanged(const char *setting); + void GroupChanged(const char *setting); void EditableListChanged(); void ButtonClicked(); @@ -103,6 +104,8 @@ private: void AddFrameRate(obs_property_t *prop, bool &warning, QFormLayout *layout, QLabel *&label); + void AddGroup(obs_property_t *prop, QFormLayout *layout); + void AddProperty(obs_property_t *property, QFormLayout *layout); void resizeEvent(QResizeEvent *event) override; @@ -118,6 +121,7 @@ public slots: signals: void PropertiesResized(); void Changed(); + void PropertiesRefreshed(); public: OBSPropertiesView(OBSData settings, void *obj, diff --git a/UI/qt-display.cpp b/UI/qt-display.cpp index 90bd9be..f2ca597 100644 --- a/UI/qt-display.cpp +++ b/UI/qt-display.cpp @@ -6,6 +6,27 @@ #include #include +static inline long long color_to_int(QColor color) +{ + auto shift = [&](unsigned val, int shift) + { + return ((val & 0xff) << shift); + }; + + return shift(color.red(), 0) | + shift(color.green(), 8) | + shift(color.blue(), 16) | + shift(color.alpha(), 24); +} + +static inline QColor rgba_to_color(uint32_t rgba) +{ + return QColor::fromRgb(rgba & 0xFF, + (rgba >> 8) & 0xFF, + (rgba >> 16) & 0xFF, + (rgba >> 24) & 0xFF); +} + OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) { @@ -41,6 +62,26 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags) connect(windowHandle(), &QWindow::screenChanged, sizeChanged); } +QColor OBSQTDisplay::GetDisplayBackgroundColor() const +{ + return rgba_to_color(backgroundColor); +} + +void OBSQTDisplay::SetDisplayBackgroundColor(const QColor &color) +{ + uint32_t newBackgroundColor = (uint32_t)color_to_int(color); + + if (newBackgroundColor != backgroundColor) { + backgroundColor = newBackgroundColor; + UpdateDisplayBackgroundColor(); + } +} + +void OBSQTDisplay::UpdateDisplayBackgroundColor() +{ + obs_display_set_background_color(display, backgroundColor); +} + void OBSQTDisplay::CreateDisplay() { if (display || !windowHandle()->isExposed()) @@ -56,7 +97,7 @@ void OBSQTDisplay::CreateDisplay() QTToGSWindow(winId(), info.window); - display = obs_display_create(&info); + display = obs_display_create(&info, backgroundColor); emit DisplayCreated(this); } diff --git a/UI/qt-display.hpp b/UI/qt-display.hpp index 438100b..de4fdac 100644 --- a/UI/qt-display.hpp +++ b/UI/qt-display.hpp @@ -3,8 +3,13 @@ #include #include +#define GREY_COLOR_BACKGROUND 0xFF4C4C4C + class OBSQTDisplay : public QWidget { Q_OBJECT + Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor + READ GetDisplayBackgroundColor + WRITE SetDisplayBackgroundColor) OBSDisplay display; @@ -18,9 +23,16 @@ signals: void DisplayResized(); public: - OBSQTDisplay(QWidget *parent = 0, Qt::WindowFlags flags = 0); + OBSQTDisplay(QWidget *parent = nullptr, + Qt::WindowFlags flags = nullptr); virtual QPaintEngine *paintEngine() const override; inline obs_display_t *GetDisplay() const {return display;} + + uint32_t backgroundColor = GREY_COLOR_BACKGROUND; + + QColor GetDisplayBackgroundColor() const; + void SetDisplayBackgroundColor(const QColor &color); + void UpdateDisplayBackgroundColor(); }; diff --git a/UI/qt-wrappers.cpp b/UI/qt-wrappers.cpp index eac5ea0..5d8a9cb 100644 --- a/UI/qt-wrappers.cpp +++ b/UI/qt-wrappers.cpp @@ -19,6 +19,7 @@ #include "obs-app.hpp" #include +#include #include #include #include @@ -89,6 +90,33 @@ void OBSMessageBox::information( mb.exec(); } +void OBSMessageBox::warning( + QWidget *parent, + const QString &title, + const QString &text, + bool enableRichText) +{ + QMessageBox mb(QMessageBox::Warning, + title, text, QMessageBox::Ok, + parent); + if (enableRichText) + mb.setTextFormat(Qt::RichText); + mb.setButtonText(QMessageBox::Ok, QTStr("OK")); + mb.exec(); +} + +void OBSMessageBox::critical( + QWidget *parent, + const QString &title, + const QString &text) +{ + QMessageBox mb(QMessageBox::Critical, + title, text, QMessageBox::Ok, + parent); + mb.setButtonText(QMessageBox::Ok, QTStr("OK")); + mb.exec(); +} + void QTToGSWindow(WId windowId, gs_window &gswindow) { #ifdef _WIN32 @@ -203,3 +231,87 @@ void DeleteLayout(QLayout *layout) delete layout; } + +class QuickThread : public QThread { +public: + explicit inline QuickThread(std::function func_) + : func(func_) + {} + +private: + virtual void run() override + { + func(); + } + + std::function func; +}; + +QThread *CreateQThread(std::function func) +{ + return new QuickThread(func); +} + +volatile long insideEventLoop = 0; + +void ExecuteFuncSafeBlock(std::function func) +{ + QEventLoop eventLoop; + + auto wait = [&] () + { + func(); + QMetaObject::invokeMethod(&eventLoop, "quit", + Qt::QueuedConnection); + }; + + os_atomic_inc_long(&insideEventLoop); + QScopedPointer thread(CreateQThread(wait)); + thread->start(); + eventLoop.exec(); + thread->wait(); + os_atomic_dec_long(&insideEventLoop); +} + +void ExecuteFuncSafeBlockMsgBox( + std::function func, + const QString &title, + const QString &text) +{ + QMessageBox dlg; + dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowCloseButtonHint); + dlg.setWindowTitle(title); + dlg.setText(text); + dlg.setStandardButtons(0); + + auto wait = [&] () + { + func(); + QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection); + }; + + os_atomic_inc_long(&insideEventLoop); + QScopedPointer thread(CreateQThread(wait)); + thread->start(); + dlg.exec(); + thread->wait(); + os_atomic_dec_long(&insideEventLoop); +} + +static bool enable_message_boxes = false; + +void EnableThreadedMessageBoxes(bool enable) +{ + enable_message_boxes = enable; +} + +void ExecThreadedWithoutBlocking( + std::function func, + const QString &title, + const QString &text) +{ + if (!enable_message_boxes) + ExecuteFuncSafeBlock(func); + else + ExecuteFuncSafeBlockMsgBox(func, title, text); +} diff --git a/UI/qt-wrappers.hpp b/UI/qt-wrappers.hpp index 5273f92..ab30109 100644 --- a/UI/qt-wrappers.hpp +++ b/UI/qt-wrappers.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -47,6 +48,15 @@ public: QWidget *parent, const QString &title, const QString &text); + static void warning( + QWidget *parent, + const QString &title, + const QString &text, + bool enableRichText = false); + static void critical( + QWidget *parent, + const QString &title, + const QString &text); }; void OBSErrorBox(QWidget *parent, const char *msg, ...); @@ -64,6 +74,22 @@ QDataStream &operator>>(QDataStream &in, OBSScene &scene); QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si); QDataStream &operator>>(QDataStream &in, OBSSceneItem &si); +QThread *CreateQThread(std::function func); + +void ExecuteFuncSafeBlock(std::function func); +void ExecuteFuncSafeBlockMsgBox( + std::function func, + const QString &title, + const QString &text); + +/* allows executing without message boxes if starting up, otherwise with a + * message box */ +void EnableThreadedMessageBoxes(bool enable); +void ExecThreadedWithoutBlocking( + std::function func, + const QString &title, + const QString &text); + class SignalBlocker { QWidget *widget; bool blocked; diff --git a/UI/remote-text.cpp b/UI/remote-text.cpp index e4b5c39..41525c9 100644 --- a/UI/remote-text.cpp +++ b/UI/remote-text.cpp @@ -61,7 +61,11 @@ void RemoteTextThread::run() contentTypeString.c_str()); } + for (std::string &h : extraHeaders) + header = curl_slist_append(header, h.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, ""); curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header); curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, @@ -71,6 +75,10 @@ void RemoteTextThread::run() curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str); + if (timeoutSec) + curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, + timeoutSec); + #if LIBCURL_VERSION_NUM >= 0x072400 // A lot of servers don't yet support ALPN curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0); @@ -118,7 +126,8 @@ bool GetRemoteFile( const char *contentType, const char *postData, std::vector extraHeaders, - std::string *signature) + std::string *signature, + int timeoutSec) { vector header_in_list; char error_in[CURL_ERROR_SIZE]; @@ -151,6 +160,7 @@ bool GetRemoteFile( header = curl_slist_append(header, h.c_str()); curl_easy_setopt(curl.get(), CURLOPT_URL, url); + curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, ""); curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header); curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, @@ -166,6 +176,10 @@ bool GetRemoteFile( &header_in_list); } + if (timeoutSec) + curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, + timeoutSec); + #if LIBCURL_VERSION_NUM >= 0x072400 // A lot of servers don't yet support ALPN curl_easy_setopt(curl.get(), CURLOPT_SSL_ENABLE_ALPN, 0); diff --git a/UI/remote-text.hpp b/UI/remote-text.hpp index 7758843..d5663e1 100644 --- a/UI/remote-text.hpp +++ b/UI/remote-text.hpp @@ -28,6 +28,10 @@ class RemoteTextThread : public QThread { std::string contentType; std::string postData; + std::vector extraHeaders; + + int timeoutSec = 0; + void run() override; signals: @@ -37,8 +41,25 @@ public: inline RemoteTextThread( std::string url_, std::string contentType_ = std::string(), - std::string postData_ = std::string()) - : url(url_), contentType(contentType_), postData(postData_) + std::string postData_ = std::string(), + int timeoutSec_ = 0) + : url (url_), + contentType (contentType_), + postData (postData_), + timeoutSec (timeoutSec_) + {} + + inline RemoteTextThread( + std::string url_, + std::vector &&extraHeaders_, + std::string contentType_ = std::string(), + std::string postData_ = std::string(), + int timeoutSec_ = 0) + : url (url_), + contentType (contentType_), + postData (postData_), + extraHeaders (std::move(extraHeaders_)), + timeoutSec (timeoutSec_) {} }; @@ -50,4 +71,5 @@ bool GetRemoteFile( const char *contentType = nullptr, const char *postData = nullptr, std::vector extraHeaders = std::vector(), - std::string *signature = nullptr); + std::string *signature = nullptr, + int timeoutSec = 0); diff --git a/UI/slider-ignorewheel.cpp b/UI/slider-ignorewheel.cpp new file mode 100644 index 0000000..f2708e9 --- /dev/null +++ b/UI/slider-ignorewheel.cpp @@ -0,0 +1,22 @@ +#include "slider-ignorewheel.hpp" + +SliderIgnoreScroll::SliderIgnoreScroll(QWidget *parent) : QSlider(parent) +{ + setFocusPolicy(Qt::StrongFocus); +} + +SliderIgnoreScroll::SliderIgnoreScroll(Qt::Orientation orientation, + QWidget *parent) + : QSlider(parent) +{ + setFocusPolicy(Qt::StrongFocus); + setOrientation(orientation); +} + +void SliderIgnoreScroll::wheelEvent(QWheelEvent *event) +{ + if (!hasFocus()) + event->ignore(); + else + QSlider::wheelEvent(event); +} diff --git a/UI/slider-ignorewheel.hpp b/UI/slider-ignorewheel.hpp new file mode 100644 index 0000000..7778c90 --- /dev/null +++ b/UI/slider-ignorewheel.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include +#include + +class SliderIgnoreScroll : public QSlider { + Q_OBJECT + +public: + SliderIgnoreScroll(QWidget *parent = nullptr); + SliderIgnoreScroll(Qt::Orientation orientation, QWidget *parent = nullptr); + +protected: + virtual void wheelEvent(QWheelEvent *event) override; +}; diff --git a/UI/source-label.hpp b/UI/source-label.hpp index 03b9be6..6bba24e 100644 --- a/UI/source-label.hpp +++ b/UI/source-label.hpp @@ -15,6 +15,8 @@ along with this program. If not, see . ******************************************************************************/ +#pragma once + #include #include diff --git a/UI/source-list-widget.cpp b/UI/source-list-widget.cpp deleted file mode 100644 index d537fbc..0000000 --- a/UI/source-list-widget.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include - -#include "qt-wrappers.hpp" -#include "source-list-widget.hpp" - -Q_DECLARE_METATYPE(OBSSceneItem); - -void SourceListWidget::mouseDoubleClickEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - QListWidget::mouseDoubleClickEvent(event); -} - -void SourceListWidget::dropEvent(QDropEvent *event) -{ - QListWidget::dropEvent(event); - if (!event->isAccepted() || !count()) - return; - - auto GetSceneItem = [&](int i) - { - return item(i)->data(Qt::UserRole).value(); - }; - - std::vector newOrder; - newOrder.reserve(count()); - for (int i = count() - 1; i >= 0; i--) - newOrder.push_back(GetSceneItem(i)); - - auto UpdateOrderAtomically = [&](obs_scene_t *scene) - { - ignoreReorder = true; - obs_scene_reorder_items(scene, newOrder.data(), - newOrder.size()); - ignoreReorder = false; - }; - using UpdateOrderAtomically_t = decltype(UpdateOrderAtomically); - - auto scene = obs_sceneitem_get_scene(GetSceneItem(0)); - obs_scene_atomic_update(scene, [](void *data, obs_scene_t *scene) - { - (*static_cast(data))(scene); - }, static_cast(&UpdateOrderAtomically)); -} diff --git a/UI/source-list-widget.hpp b/UI/source-list-widget.hpp deleted file mode 100644 index d2215b0..0000000 --- a/UI/source-list-widget.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -class QMouseEvent; - -class SourceListWidget : public QListWidget { - Q_OBJECT - - bool ignoreReorder = false; -public: - inline SourceListWidget(QWidget *parent = nullptr) - : QListWidget(parent) - { - } - - bool IgnoreReorder() const { return ignoreReorder; } - -protected: - virtual void mouseDoubleClickEvent(QMouseEvent *event) override; - virtual void dropEvent(QDropEvent *event) override; -}; diff --git a/UI/source-tree.cpp b/UI/source-tree.cpp index 1652988..e46ad54 100644 --- a/UI/source-tree.cpp +++ b/UI/source-tree.cpp @@ -5,6 +5,7 @@ #include "visibility-checkbox.hpp" #include "locked-checkbox.hpp" #include "expand-checkbox.hpp" +#include "platform.hpp" #include #include @@ -35,6 +36,7 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) sceneitem (sceneitem_) { setAttribute(Qt::WA_TranslucentBackground); + setMouseTracking(true); obs_source_t *source = obs_sceneitem_get_source(sceneitem); const char *name = obs_source_get_name(source); @@ -58,13 +60,15 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) vis = new VisibilityCheckBox(); vis->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - vis->setMaximumSize(16, 16); + vis->setFixedSize(16, 16); vis->setChecked(obs_sceneitem_visible(sceneitem)); + vis->setStyleSheet("background: none"); lock = new LockedCheckBox(); lock->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - lock->setMaximumSize(16, 16); + lock->setFixedSize(16, 16); lock->setChecked(obs_sceneitem_locked(sceneitem)); + lock->setStyleSheet("background: none"); label = new QLabel(QT_UTF8(name)); label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); @@ -77,10 +81,11 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_) #endif boxLayout = new QHBoxLayout(); - boxLayout->setContentsMargins(1, 1, 2, 1); + boxLayout->setContentsMargins(1, 1, 1, 1); boxLayout->setSpacing(1); boxLayout->addWidget(label); boxLayout->addWidget(vis); + boxLayout->setSpacing(2); boxLayout->addWidget(lock); #ifdef __APPLE__ /* Hack: Fixes a bug where scrollbars would be above the lock icon */ @@ -129,6 +134,12 @@ void SourceTreeItem::DisconnectSignals() removeSignal.Disconnect(); } +void SourceTreeItem::Clear() +{ + DisconnectSignals(); + sceneitem = nullptr; +} + void SourceTreeItem::ReconnectSignals() { if (!sceneitem) @@ -150,10 +161,8 @@ void SourceTreeItem::ReconnectSignals() Q_ARG(OBSSceneItem, curItem)); curItem = nullptr; } - if (!curItem) { - this_->DisconnectSignals(); - this_->sceneitem = nullptr; - } + if (!curItem) + QMetaObject::invokeMethod(this_, "Clear"); }; auto itemVisible = [] (void *data, calldata_t *cd) @@ -244,11 +253,18 @@ void SourceTreeItem::mouseDoubleClickEvent(QMouseEvent *event) } } +bool SourceTreeItem::IsEditing() +{ + return editor != nullptr; +} + void SourceTreeItem::EnterEditMode() { setFocusPolicy(Qt::StrongFocus); boxLayout->removeWidget(label); editor = new QLineEdit(label->text()); + editor->setStyleSheet("background: none"); + editor->selectAll(); editor->installEventFilter(this); boxLayout->insertWidget(1, editor); setFocusProxy(editor); @@ -690,8 +706,14 @@ int SourceTreeModel::rowCount(const QModelIndex &parent) const return parent.isValid() ? 0 : items.count(); } -QVariant SourceTreeModel::data(const QModelIndex &, int) const +QVariant SourceTreeModel::data(const QModelIndex &index, int role) const { + if (role == Qt::AccessibleTextRole) { + OBSSceneItem item = items[index.row()]; + obs_source_t *source = obs_sceneitem_get_source(item); + return QVariant(QT_UTF8(obs_source_get_name(source))); + } + return QVariant(); } @@ -896,6 +918,12 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_) "*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \ "*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \ "*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}")); + + setMouseTracking(true); + + UpdateNoSourcesMessage(); + connect(App(), &OBSApp::StyleChanged, + this, &SourceTree::UpdateNoSourcesMessage); } void SourceTree::ResetWidgets() @@ -1249,6 +1277,24 @@ void SourceTree::dropEvent(QDropEvent *event) QListView::dropEvent(event); } +void SourceTree::mouseMoveEvent(QMouseEvent *event) +{ + QPoint pos = event->pos(); + SourceTreeItem *item = qobject_cast(childAt(pos)); + + OBSBasicPreview *preview = OBSBasicPreview::Get(); + preview->hoveredListItem = !!item ? item->sceneitem : nullptr; + + QListView::mouseMoveEvent(event); +} + +void SourceTree::leaveEvent(QEvent *event) +{ + OBSBasicPreview *preview = OBSBasicPreview::Get(); + preview->hoveredListItem = nullptr; + QListView::leaveEvent(event); +} + void SourceTree::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected) @@ -1279,10 +1325,14 @@ void SourceTree::Edit(int row) if (row < 0 || row >= stm->items.count()) return; - QWidget *widget = indexWidget(stm->createIndex(row, 0)); + QModelIndex index = stm->createIndex(row, 0); + QWidget *widget = indexWidget(index); SourceTreeItem *itemWidget = reinterpret_cast(widget); + if (itemWidget->IsEditing()) + return; + itemWidget->EnterEditMode(); - edit(stm->createIndex(row, 0)); + edit(index); } bool SourceTree::MultipleBaseSelected() const @@ -1388,3 +1438,56 @@ void SourceTree::AddGroup() { GetStm()->AddGroup(); } + +void SourceTree::UpdateNoSourcesMessage() +{ + std::string darkPath; + GetDataFilePath("themes/Dark/no_sources.svg", darkPath); + + QColor color = palette().text().color(); + bool lightTheme = (color.redF() < 0.5); + QString file = lightTheme + ? ":res/images/no_sources.svg" + : darkPath.c_str(); + iconNoSources.load(file); + + QTextOption opt(Qt::AlignHCenter); + opt.setWrapMode(QTextOption::WordWrap); + textNoSources.setTextOption(opt); + textNoSources.setText(QTStr("NoSources.Label").replace("\n", "
")); + + textPrepared = false; +} + +void SourceTree::paintEvent(QPaintEvent *event) +{ + SourceTreeModel *stm = GetStm(); + if (stm && !stm->items.count()) { + QPainter p(viewport()); + + if (!textPrepared) { + textNoSources.prepare(QTransform(), p.font()); + textPrepared = true; + } + + QRectF iconRect = iconNoSources.viewBoxF(); + + QSizeF iconSize = iconRect.size(); + QSizeF textSize = textNoSources.size(); + QSizeF thisSize = size(); + + qreal totalHeight = textSize.height() + iconSize.height(); + + qreal x = thisSize.width() / 2.0 - textSize.width() / 2.0; + qreal y = thisSize.height() / 2.0 - totalHeight / 2.0; + p.drawStaticText(x, y, textNoSources); + + x = thisSize.width() / 2.0 - iconSize.width() / 2.0; + y += textSize.height(); + iconRect.moveTo(x, y); + + iconNoSources.render(&p, iconRect); + } else { + QListView::paintEvent(event); + } +} diff --git a/UI/source-tree.hpp b/UI/source-tree.hpp index f77ae90..46577d2 100644 --- a/UI/source-tree.hpp +++ b/UI/source-tree.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include class QLabel; @@ -47,6 +49,7 @@ class SourceTreeItem : public QWidget { public: explicit SourceTreeItem(SourceTree *tree, OBSSceneItem sceneitem); + bool IsEditing(); private: QSpacerItem *spacer = nullptr; @@ -71,6 +74,8 @@ private: virtual void paintEvent(QPaintEvent* event) override; private slots: + void Clear(); + void EnterEditMode(); void ExitEditMode(bool save); @@ -130,6 +135,12 @@ class SourceTree : public QListView { friend class SourceTreeModel; friend class SourceTreeItem; + bool textPrepared = false; + QStaticText textNoSources; + QSvgRenderer iconNoSources; + + void UpdateNoSourcesMessage(); + void ResetWidgets(); void UpdateWidget(const QModelIndex &idx, obs_sceneitem_t *item); void UpdateWidgets(bool force = false); @@ -172,6 +183,9 @@ public slots: protected: virtual void mouseDoubleClickEvent(QMouseEvent *event) override; virtual void dropEvent(QDropEvent *event) override; + virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void leaveEvent(QEvent *event) override; + virtual void paintEvent(QPaintEvent *event) override; virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; }; diff --git a/UI/spinbox-ignorewheel.cpp b/UI/spinbox-ignorewheel.cpp new file mode 100644 index 0000000..0452b93 --- /dev/null +++ b/UI/spinbox-ignorewheel.cpp @@ -0,0 +1,14 @@ +#include "spinbox-ignorewheel.hpp" + +SpinBoxIgnoreScroll::SpinBoxIgnoreScroll(QWidget *parent) : QSpinBox(parent) +{ + setFocusPolicy(Qt::StrongFocus); +} + +void SpinBoxIgnoreScroll::wheelEvent(QWheelEvent *event) +{ + if (!hasFocus()) + event->ignore(); + else + QSpinBox::wheelEvent(event); +} diff --git a/UI/spinbox-ignorewheel.hpp b/UI/spinbox-ignorewheel.hpp new file mode 100644 index 0000000..535197e --- /dev/null +++ b/UI/spinbox-ignorewheel.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include +#include + +class SpinBoxIgnoreScroll : public QSpinBox { + Q_OBJECT + +public: + SpinBoxIgnoreScroll(QWidget *parent = nullptr); + +protected: + virtual void wheelEvent(QWheelEvent *event) override; +}; diff --git a/UI/ui-config.h.in b/UI/ui-config.h.in new file mode 100644 index 0000000..fe31138 --- /dev/null +++ b/UI/ui-config.h.in @@ -0,0 +1,31 @@ +#pragma once + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef ON +#define ON 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef OFF +#define OFF 0 +#endif + +#define TWITCH_ENABLED @TWITCH_ENABLED@ +#define TWITCH_CLIENTID "@TWITCH_CLIENTID@" +#define TWITCH_HASH 0x@TWITCH_HASH@ + +#define MIXER_ENABLED @MIXER_ENABLED@ +#define MIXER_CLIENTID "@MIXER_CLIENTID@" +#define MIXER_HASH 0x@MIXER_HASH@ + +#define RESTREAM_ENABLED @RESTREAM_ENABLED@ +#define RESTREAM_CLIENTID "@RESTREAM_CLIENTID@" +#define RESTREAM_HASH 0x@RESTREAM_HASH@ + +#define DEFAULT_THEME "Dark" diff --git a/UI/visibility-checkbox.cpp b/UI/visibility-checkbox.cpp deleted file mode 100644 index 5b73084..0000000 --- a/UI/visibility-checkbox.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include "visibility-checkbox.hpp" - -#include - -VisibilityCheckBox::VisibilityCheckBox() : QCheckBox() -{ - checkedImage = - QPixmap::fromImage(QImage(":/res/images/visible_mask.png")); - uncheckedImage = - QPixmap::fromImage(QImage(":/res/images/invisible_mask.png")); - setMinimumSize(16, 16); - - setStyleSheet("outline: none;"); -} - -void VisibilityCheckBox::paintEvent(QPaintEvent *event) -{ - UNUSED_PARAMETER(event); - - QPixmap &pixmap = isChecked() ? checkedImage : uncheckedImage; - QImage image(pixmap.size(), QImage::Format_ARGB32); - - QPainter draw(&image); - draw.setCompositionMode(QPainter::CompositionMode_Source); - draw.drawPixmap(0, 0, pixmap.width(), pixmap.height(), pixmap); - draw.setCompositionMode(QPainter::CompositionMode_SourceIn); - draw.fillRect(QRectF(QPointF(0.0f, 0.0f), pixmap.size()), - palette().color(foregroundRole())); - - QPainter p(this); - p.drawPixmap(0, 0, image.width(), image.height(), - QPixmap::fromImage(image)); -} diff --git a/UI/visibility-checkbox.hpp b/UI/visibility-checkbox.hpp index 47c5d89..ff21df2 100644 --- a/UI/visibility-checkbox.hpp +++ b/UI/visibility-checkbox.hpp @@ -1,17 +1,7 @@ -#include -#include +#pragma once -class QPaintEvernt; +#include class VisibilityCheckBox : public QCheckBox { Q_OBJECT - - QPixmap checkedImage; - QPixmap uncheckedImage; - -public: - VisibilityCheckBox(); - -protected: - void paintEvent(QPaintEvent *event) override; }; diff --git a/UI/volume-control.cpp b/UI/volume-control.cpp index 80fbe1f..91f1032 100644 --- a/UI/volume-control.cpp +++ b/UI/volume-control.cpp @@ -2,11 +2,11 @@ #include "qt-wrappers.hpp" #include "obs-app.hpp" #include "mute-checkbox.hpp" +#include "slider-ignorewheel.hpp" #include "slider-absoluteset-style.hpp" #include #include #include -#include #include #include #include @@ -14,6 +14,7 @@ using namespace std; #define CLAMP(x, min, max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x))) +#define FADER_PRECISION 4096.0 QWeakPointer VolumeMeter::updateTimer; @@ -47,7 +48,8 @@ void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata) void VolControl::VolumeChanged() { slider->blockSignals(true); - slider->setValue((int) (obs_fader_get_deflection(obs_fader) * 100.0f)); + slider->setValue((int) (obs_fader_get_deflection(obs_fader) * + FADER_PRECISION)); slider->blockSignals(false); updateText(); @@ -66,7 +68,7 @@ void VolControl::SetMuted(bool checked) void VolControl::SliderChanged(int vol) { - obs_fader_set_deflection(obs_fader, float(vol) * 0.01f); + obs_fader_set_deflection(obs_fader, float(vol) / FADER_PRECISION); updateText(); } @@ -116,13 +118,14 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) : source (std::move(source_)), levelTotal (0.0f), levelCount (0.0f), - obs_fader (obs_fader_create(OBS_FADER_CUBIC)), + obs_fader (obs_fader_create(OBS_FADER_LOG)), obs_volmeter (obs_volmeter_create(OBS_FADER_LOG)), vertical (vertical) { nameLabel = new QLabel(); volLabel = new QLabel(); mute = new MuteCheckBox(); + QString sourceName = obs_source_get_name(source); setObjectName(sourceName); @@ -153,7 +156,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) QHBoxLayout *meterLayout = new QHBoxLayout; volMeter = new VolumeMeter(nullptr, obs_volmeter, true); - slider = new QSlider(Qt::Vertical); + slider = new SliderIgnoreScroll(Qt::Vertical); nameLayout->setAlignment(Qt::AlignCenter); meterLayout->setAlignment(Qt::AlignCenter); @@ -188,6 +191,8 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) mainLayout->addItem(meterLayout); mainLayout->addItem(controlLayout); + volMeter->setFocusProxy(slider); + setMaximumWidth(110); } else { QHBoxLayout *volLayout = new QHBoxLayout; @@ -195,7 +200,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) QHBoxLayout *botLayout = new QHBoxLayout; volMeter = new VolumeMeter(nullptr, obs_volmeter, false); - slider = new QSlider(Qt::Horizontal); + slider = new SliderIgnoreScroll(Qt::Horizontal); textLayout->setContentsMargins(0, 0, 0, 0); textLayout->addWidget(nameLabel); @@ -217,6 +222,8 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) mainLayout->addItem(textLayout); mainLayout->addWidget(volMeter); mainLayout->addItem(botLayout); + + volMeter->setFocusProxy(slider); } setLayout(mainLayout); @@ -227,8 +234,9 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical) nameLabel->setText(sourceName); nameLabel->setFont(font); volLabel->setFont(font); + slider->setMinimum(0); - slider->setMaximum(100); + slider->setMaximum(int(FADER_PRECISION)); bool muted = obs_source_muted(source); mute->setChecked(muted); @@ -498,6 +506,16 @@ void VolumeMeter::setPeakMeterType(enum obs_peak_meter_type peakMeterType) } } +void VolumeMeter::mousePressEvent(QMouseEvent *event) +{ + setFocus(Qt::MouseFocusReason); +} + +void VolumeMeter::wheelEvent(QWheelEvent *event) +{ + QApplication::sendEvent(focusProxy(), event); +} + VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter, bool vertical) : QWidget(parent), obs_volmeter(obs_volmeter), @@ -528,6 +546,8 @@ VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter, peakHoldDuration = 20.0; // 20 seconds inputPeakHoldDuration = 1.0; // 1 second + channels = (int)audio_output_get_channels(obs_get_audio()); + handleChannelCofigurationChange(); updateTimerRef = updateTimer.toStrongRef(); if (!updateTimerRef) { @@ -1007,16 +1027,22 @@ void VolumeMeter::paintEvent(QPaintEvent *event) for (int channelNr = 0; channelNr < displayNrAudioChannels; channelNr++) { + + int channelNrFixed = (displayNrAudioChannels == 1 && + channels > 2) + ? 2 + : channelNr; + if (vertical) paintVMeter(painter, channelNr * 4, 8, 3, height - 10, - displayMagnitude[channelNr], - displayPeak[channelNr], - displayPeakHold[channelNr]); + displayMagnitude[channelNrFixed], + displayPeak[channelNrFixed], + displayPeakHold[channelNrFixed]); else paintHMeter(painter, 5, channelNr * 4, width - 5, 3, - displayMagnitude[channelNr], - displayPeak[channelNr], - displayPeakHold[channelNr]); + displayMagnitude[channelNrFixed], + displayPeak[channelNrFixed], + displayPeakHold[channelNrFixed]); if (idle) continue; @@ -1026,10 +1052,10 @@ void VolumeMeter::paintEvent(QPaintEvent *event) // having too much visual impact. if (vertical) paintInputMeter(painter, channelNr * 4, 3, 3, 3, - displayInputPeakHold[channelNr]); + displayInputPeakHold[channelNrFixed]); else paintInputMeter(painter, 0, channelNr * 4, 3, 3, - displayInputPeakHold[channelNr]); + displayInputPeakHold[channelNrFixed]); } lastRedrawTime = ts; diff --git a/UI/volume-control.hpp b/UI/volume-control.hpp index fde0d12..e24ef5c 100644 --- a/UI/volume-control.hpp +++ b/UI/volume-control.hpp @@ -144,6 +144,7 @@ private: qreal inputPeakHoldDuration; uint64_t lastRedrawTime = 0; + int channels = 0; bool clipping = false; bool vertical; @@ -197,6 +198,8 @@ public: qreal getInputPeakHoldDuration() const; void setInputPeakHoldDuration(qreal v); void setPeakMeterType(enum obs_peak_meter_type peakMeterType); + virtual void mousePressEvent(QMouseEvent *event) override; + virtual void wheelEvent(QWheelEvent *event) override; protected: void paintEvent(QPaintEvent *event) override; diff --git a/UI/win-update/updater/CMakeLists.txt b/UI/win-update/updater/CMakeLists.txt index 65b8a1c..e7cfd82 100644 --- a/UI/win-update/updater/CMakeLists.txt +++ b/UI/win-update/updater/CMakeLists.txt @@ -28,11 +28,12 @@ set(updater_SOURCES http.cpp hash.cpp updater.rc + updater.manifest ) add_definitions(-DNOMINMAX -DUNICODE -D_UNICODE) if(MSVC) - add_compile_options("$<$:/MT>") + add_compile_options($,/MTd,/MT>) endif() add_executable(updater WIN32 diff --git a/UI/win-update/updater/updater.cpp b/UI/win-update/updater/updater.cpp index f3735cb..56d3812 100644 --- a/UI/win-update/updater/updater.cpp +++ b/UI/win-update/updater/updater.cpp @@ -576,10 +576,18 @@ static inline bool FileExists(const wchar_t *path) static bool NonCorePackageInstalled(const char *name) { - if (strcmp(name, "obs-browser") == 0) { - return FileExists(L"obs-plugins\\32bit\\obs-browser.dll"); - } else if (strcmp(name, "realsense") == 0) { - return FileExists(L"obs-plugins\\32bit\\win-ivcam.dll"); + if (is32bit) { + if (strcmp(name, "obs-browser") == 0) { + return FileExists(L"obs-plugins\\32bit\\obs-browser.dll"); + } else if (strcmp(name, "realsense") == 0) { + return FileExists(L"obs-plugins\\32bit\\win-ivcam.dll"); + } + } else { + if (strcmp(name, "obs-browser") == 0) { + return FileExists(L"obs-plugins\\64bit\\obs-browser.dll"); + } else if (strcmp(name, "realsense") == 0) { + return FileExists(L"obs-plugins\\64bit\\win-ivcam.dll"); + } } return false; @@ -1133,6 +1141,12 @@ static bool Update(wchar_t *cmdLine) SetDlgItemTextW(hwndMain, IDC_STATUS, L"Searching for available updates..."); + HWND hProgress = GetDlgItem(hwndMain, IDC_PROGRESS); + LONG_PTR style = GetWindowLongPtr(hProgress, GWL_STYLE); + SetWindowLongPtr(hProgress, GWL_STYLE, style | PBS_MARQUEE); + + SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETMARQUEE, 1, 0); + /* ------------------------------------- * * Check if updating portable build */ @@ -1237,16 +1251,20 @@ static bool Update(wchar_t *cmdLine) for (size_t i = 0; i < packageCount; i++) { if (!AddPackageUpdateFiles(packages, i, tempPath)) { - Status(L"Failed to process update packages"); + Status(L"Update failed: Failed to process update packages"); return false; } } + SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETMARQUEE, 0, 0); + SetWindowLongPtr(hProgress, GWL_STYLE, style); + /* ------------------------------------- * * Exit if updates already installed */ if (!updates.size()) { Status(L"All available updates are already installed."); + SetDlgItemText(hwndMain, IDC_BUTTON, L"Launch OBS"); return true; } @@ -1452,8 +1470,10 @@ static DWORD WINAPI UpdateThread(void *arg) if (WaitForSingleObject(cancelRequested, 0) == WAIT_OBJECT_0) Status(L"Update aborted."); - SendDlgItemMessage(hwndMain, IDC_PROGRESS, PBM_SETSTATE, - PBST_ERROR, 0); + HWND hProgress = GetDlgItem(hwndMain, IDC_PROGRESS); + LONG_PTR style = GetWindowLongPtr(hProgress, GWL_STYLE); + SetWindowLongPtr(hProgress, GWL_STYLE, style & ~PBS_MARQUEE); + SendMessage(hProgress, PBM_SETSTATE, PBST_ERROR, 0); SetDlgItemText(hwndMain, IDC_BUTTON, L"Exit"); EnableWindow(GetDlgItem(hwndMain, IDC_BUTTON), true); diff --git a/UI/win-update/updater/updater.manifest b/UI/win-update/updater/updater.manifest new file mode 100644 index 0000000..d486163 --- /dev/null +++ b/UI/win-update/updater/updater.manifest @@ -0,0 +1,25 @@ + + + + + + system + true + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UI/win-update/win-update-helpers.cpp b/UI/win-update/win-update-helpers.cpp index b969e32..98cffbc 100644 --- a/UI/win-update/win-update-helpers.cpp +++ b/UI/win-update/win-update-helpers.cpp @@ -21,7 +21,7 @@ std::string vstrprintf(const char *format, va_list args) return std::string(); std::string str; - int size = (int)vsnprintf(nullptr, 0, format, args); + int size = (int)vsnprintf(nullptr, 0, format, args) + 1; str.resize(size); vsnprintf(&str[0], size, format, args); return str; diff --git a/UI/win-update/win-update.cpp b/UI/win-update/win-update.cpp index 2bd77b8..34d2157 100644 --- a/UI/win-update/win-update.cpp +++ b/UI/win-update/win-update.cpp @@ -242,7 +242,7 @@ try { return true; } catch (string text) { - blog(LOG_WARNING, "%s: %s", __FUNCTION__, text.c_str()); + blog(LOG_DEBUG, "%s: %s", __FUNCTION__, text.c_str()); return false; } @@ -586,7 +586,7 @@ try { auto ActiveOrGameCaptureLocked = [this] () { - if (video_output_active(obs_get_video())) { + if (obs_video_active()) { if (manualUpdate) info(QTStr("Updater.Running.Title"), QTStr("Updater.Running.Text")); diff --git a/UI/window-basic-about.cpp b/UI/window-basic-about.cpp new file mode 100644 index 0000000..eb9ca7b --- /dev/null +++ b/UI/window-basic-about.cpp @@ -0,0 +1,169 @@ +#include "window-basic-about.hpp" +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" +#include "remote-text.hpp" +#include +#include +#include +#include + +using namespace json11; + +OBSAbout::OBSAbout(QWidget *parent) + : QDialog(parent), + ui(new Ui::OBSAbout) +{ + ui->setupUi(this); + + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + + QString bitness; + QString ver; + + if(sizeof(void*) == 4) + bitness = " (32 bit)"; + else if(sizeof(void*) == 8) + bitness = " (64 bit)"; + +#ifdef HAVE_OBSCONFIG_H + ver += OBS_VERSION; +#else + ver += LIBOBS_API_MAJOR_VER + "." + + LIBOBS_API_MINOR_VER + "." + + LIBOBS_API_PATCH_VER; +#endif + + ui->version->setText(ver + bitness); + + ui->contribute->setText(QTStr("About.Contribute")); + ui->donate->setText("  " + + QTStr("About.Donate") + ""); + ui->donate->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->donate->setOpenExternalLinks(true); + + ui->getInvolved->setText("  " + + QTStr("About.GetInvolved") + ""); + ui->getInvolved->setTextInteractionFlags(Qt::TextBrowserInteraction); + ui->getInvolved->setOpenExternalLinks(true); + + ui->about->setText("" + QTStr("About") + ""); + ui->authors->setText("" + QTStr("About.Authors") + ""); + ui->license->setText("" + QTStr("About.License") + ""); + + ui->name->setProperty("themeID", "aboutName"); + ui->version->setProperty("themeID", "aboutVersion"); + ui->about->setProperty("themeID", "aboutHLayout"); + ui->authors->setProperty("themeID", "aboutHLayout"); + ui->license->setProperty("themeID", "aboutHLayout"); + ui->info->setProperty("themeID", "aboutInfo"); + + connect(ui->about, SIGNAL(clicked()), this, SLOT(ShowAbout())); + connect(ui->authors, SIGNAL(clicked()), this, SLOT(ShowAuthors())); + connect(ui->license, SIGNAL(clicked()), this, SLOT(ShowLicense())); + + QPointer about(this); + + OBSBasic *main = OBSBasic::Get(); + if (main->patronJson.empty() && !main->patronJsonThread) { + RemoteTextThread *thread = new RemoteTextThread( + "https://obsproject.com/patreon/about-box.json", + "application/json"); + QObject::connect(thread, &RemoteTextThread::Result, + main, &OBSBasic::UpdatePatronJson); + QObject::connect(thread, SIGNAL(Result(const QString &, const QString &)), + this, SLOT(ShowAbout())); + main->patronJsonThread.reset(thread); + thread->start(); + } else { + ShowAbout(); + } +} + +void OBSAbout::ShowAbout() +{ + OBSBasic *main = OBSBasic::Get(); + + if (main->patronJson.empty()) + return; + + std::string error; + Json json = Json::parse(main->patronJson, error); + const Json::array &patrons = json.array_items(); + QString text; + + text += "

Top Patreon contributors:

"; + text += "

"; + bool first = true; + bool top = true; + + for (const Json &patron : patrons) { + std::string name = patron["name"].string_value(); + std::string link = patron["link"].string_value(); + int amount = patron["amount"].int_value(); + + if (top && amount < 10000) { + text += "

"; + top = false; + } else if (!first) { + text += "
"; + } + + if (!link.empty()) { + text += ""; + } + text += QT_UTF8(name.c_str()).toHtmlEscaped(); + if (!link.empty()) + text += ""; + + if (first) + first = false; + } + + ui->textBrowser->setHtml(text); +} + +void OBSAbout::ShowAuthors() +{ + std::string path; + QString error = "Error! File could not be read.\n\n \ + Go to: https://github.com/obsproject/obs-studio/blob/master/AUTHORS"; + + if (!GetDataFilePath("authors/AUTHORS", path)) { + ui->textBrowser->setPlainText(error); + return; + } + + ui->textBrowser->setPlainText(QString::fromStdString(path)); + + BPtr text = os_quick_read_utf8_file(path.c_str()); + + if (!text || !*text) { + ui->textBrowser->setPlainText(error); + return; + } + + ui->textBrowser->setPlainText(QT_UTF8(text)); +} + +void OBSAbout::ShowLicense() +{ + std::string path; + QString error = "Error! File could not be read.\n\n \ + Go to: https://github.com/obsproject/obs-studio/blob/master/COPYING"; + + if (!GetDataFilePath("license/gplv2.txt", path)) { + ui->textBrowser->setPlainText(error); + return; + } + + BPtr text = os_quick_read_utf8_file(path.c_str()); + + if (!text || !*text) { + ui->textBrowser->setPlainText(error); + return; + } + + ui->textBrowser->setPlainText(QT_UTF8(text)); +} diff --git a/UI/window-basic-about.hpp b/UI/window-basic-about.hpp new file mode 100644 index 0000000..bb507fe --- /dev/null +++ b/UI/window-basic-about.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +#include "ui_OBSAbout.h" + +class OBSAbout : public QDialog { + Q_OBJECT + +public: + explicit OBSAbout(QWidget *parent = 0); + + std::unique_ptr ui; + +private slots: + void ShowAbout(); + void ShowAuthors(); + void ShowLicense(); +}; diff --git a/UI/window-basic-adv-audio.cpp b/UI/window-basic-adv-audio.cpp index e6b47f7..03b4233 100644 --- a/UI/window-basic-adv-audio.cpp +++ b/UI/window-basic-adv-audio.cpp @@ -37,7 +37,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) label = new QLabel(QTStr("Basic.AdvAudio.Mono")); label->setAlignment(Qt::AlignHCenter); mainLayout->addWidget(label, 0, idx++); - label = new QLabel(QTStr("Basic.AdvAudio.Panning")); + label = new QLabel(QTStr("Basic.AdvAudio.Balance")); label->setAlignment(Qt::AlignHCenter); mainLayout->addWidget(label, 0, idx++); label = new QLabel(QTStr("Basic.AdvAudio.SyncOffset")); @@ -89,6 +89,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent) resize(1000, 340); setWindowTitle(QTStr("Basic.AdvAudio")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); setSizeGripEnabled(true); setWindowModality(Qt::NonModal); setAttribute(Qt::WA_DeleteOnClose, true); diff --git a/UI/window-basic-auto-config-test.cpp b/UI/window-basic-auto-config-test.cpp index e79cc58..d4ba22c 100644 --- a/UI/window-basic-auto-config-test.cpp +++ b/UI/window-basic-auto-config-test.cpp @@ -219,6 +219,10 @@ void AutoConfigTestPage::TestBandwidthThread() string_depad_key(key); key += "?bandwidthtest"; } + else if(wiz->serviceName == "Restream.io" || wiz->serviceName == "Restream.io - RTMP") { + string_depad_key(key); + key += "?test=true"; + } obs_data_set_string(service_settings, "service", wiz->serviceName.c_str()); @@ -246,8 +250,9 @@ void AutoConfigTestPage::TestBandwidthThread() GetServers(servers); /* just use the first server if it only has one alternate server, - * or if using Mixer due to its "auto" server */ - if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL") { + * or if using Mixer or Restream due to their "auto" servers */ + if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" || + wiz->serviceName.substr(0, 11)=="Restream.io") { servers.resize(1); } else if (wiz->service == AutoConfig::Service::Twitch && @@ -791,8 +796,17 @@ void AutoConfigTestPage::FindIdealHardwareResolution() if (!force && rate > maxDataRate) return; - int minBitrate = EstimateMinBitrate(cx, cy, fps_num, fps_den) - * 114 / 100; + AutoConfig::Encoder encType = wiz->streamingEncoder; + bool nvenc = encType == AutoConfig::Encoder::NVENC; + + int minBitrate = EstimateMinBitrate(cx, cy, fps_num, fps_den); + + /* most hardware encoders don't have a good quality to bitrate + * ratio, so increase the minimum bitrate estimate for them. + * NVENC currently is the exception because of the improvements + * its made to its quality in recent generations. */ + if (!nvenc) minBitrate = minBitrate * 114 / 100; + if (wiz->type == AutoConfig::Type::Recording) force = true; if (force || wiz->idealBitrate >= minBitrate) @@ -849,9 +863,6 @@ void AutoConfigTestPage::TestStreamEncoderThread() } } - if (preferHardware && !softwareTested && wiz->hardwareEncodingAvailable) - FindIdealHardwareResolution(); - if (!softwareTested) { if (wiz->nvencAvailable) wiz->streamingEncoder = AutoConfig::Encoder::NVENC; @@ -863,6 +874,9 @@ void AutoConfigTestPage::TestStreamEncoderThread() wiz->streamingEncoder = AutoConfig::Encoder::x264; } + if (preferHardware && !softwareTested && wiz->hardwareEncodingAvailable) + FindIdealHardwareResolution(); + QMetaObject::invokeMethod(this, "NextStage"); } diff --git a/UI/window-basic-auto-config.cpp b/UI/window-basic-auto-config.cpp index 7ddf2af..b3cc2b3 100644 --- a/UI/window-basic-auto-config.cpp +++ b/UI/window-basic-auto-config.cpp @@ -12,6 +12,17 @@ #include "ui_AutoConfigVideoPage.h" #include "ui_AutoConfigStreamPage.h" +#ifdef BROWSER_AVAILABLE +#include +#include "auth-oauth.hpp" +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + #define wiz reinterpret_cast(wizard()) /* ------------------------------------------------------------------------- */ @@ -210,6 +221,11 @@ bool AutoConfigVideoPage::validatePage() /* ------------------------------------------------------------------------- */ +enum class ListOpt : int { + ShowAll = 1, + Custom +}; + AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) : QWizardPage (parent), ui (new Ui_AutoConfigStreamPage) @@ -217,17 +233,28 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) ui->setupUi(this); ui->bitrateLabel->setVisible(false); ui->bitrate->setVisible(false); + ui->connectAccount2->setVisible(false); + ui->disconnectAccount->setVisible(false); - ui->streamType->addItem(obs_service_get_display_name("rtmp_common")); - ui->streamType->addItem(obs_service_get_display_name("rtmp_custom")); + int vertSpacing = ui->topLayout->verticalSpacing(); + + QMargins m = ui->topLayout->contentsMargins(); + m.setBottom(vertSpacing / 2); + ui->topLayout->setContentsMargins(m); + + m = ui->loginPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->loginPageLayout->setContentsMargins(m); + + m = ui->streamkeyPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->streamkeyPageLayout->setContentsMargins(m); setTitle(QTStr("Basic.AutoConfig.StreamPage")); setSubTitle(QTStr("Basic.AutoConfig.StreamPage.SubTitle")); LoadServices(false); - connect(ui->streamType, SIGNAL(currentIndexChanged(int)), - this, SLOT(ServiceChanged())); connect(ui->service, SIGNAL(currentIndexChanged(int)), this, SLOT(ServiceChanged())); connect(ui->customServer, SIGNAL(textChanged(const QString &)), @@ -238,8 +265,6 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) connect(ui->service, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateServerList())); - connect(ui->streamType, SIGNAL(currentIndexChanged(int)), - this, SLOT(UpdateKeyLink())); connect(ui->service, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateKeyLink())); @@ -270,12 +295,17 @@ int AutoConfigStreamPage::nextId() const return AutoConfig::TestPage; } +inline bool AutoConfigStreamPage::IsCustom() const +{ + return ui->service->currentData().toInt() == (int)ListOpt::Custom; +} + bool AutoConfigStreamPage::validatePage() { OBSData service_settings = obs_data_create(); obs_data_release(service_settings); - wiz->customServer = ui->streamType->currentIndex() == 1; + wiz->customServer = IsCustom(); const char *serverType = wiz->customServer ? "rtmp_custom" @@ -358,9 +388,99 @@ void AutoConfigStreamPage::on_show_clicked() } } +void AutoConfigStreamPage::OnOAuthStreamKeyConnected() +{ +#ifdef BROWSER_AVAILABLE + OAuthStreamKey *a = reinterpret_cast(auth.get()); + + if (a) { + bool validKey = !a->key().empty(); + + if (validKey) + ui->key->setText(QT_UTF8(a->key().c_str())); + + ui->streamKeyWidget->setVisible(!validKey); + ui->streamKeyLabel->setVisible(!validKey); + ui->connectAccount2->setVisible(!validKey); + ui->disconnectAccount->setVisible(validKey); + } + + ui->stackedWidget->setCurrentIndex((int)Section::StreamKey); + UpdateCompleted(); +#endif +} + +void AutoConfigStreamPage::OnAuthConnected() +{ + std::string service = QT_TO_UTF8(ui->service->currentText()); + Auth::Type type = Auth::AuthType(service); + + if (type == Auth::Type::OAuth_StreamKey) { + OnOAuthStreamKeyConnected(); + } +} + +void AutoConfigStreamPage::on_connectAccount_clicked() +{ +#ifdef BROWSER_AVAILABLE + std::string service = QT_TO_UTF8(ui->service->currentText()); + + auth = OAuthStreamKey::Login(this, service); + if (!!auth) + OnAuthConnected(); +#endif +} + +#define DISCONNECT_COMFIRM_TITLE \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title" +#define DISCONNECT_COMFIRM_TEXT \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text" + +void AutoConfigStreamPage::on_disconnectAccount_clicked() +{ + QMessageBox::StandardButton button; + + button = OBSMessageBox::question(this, + QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); + + if (button == QMessageBox::No) { + return; + } + + OBSBasic *main = OBSBasic::Get(); + + main->auth.reset(); + auth.reset(); + + std::string service = QT_TO_UTF8(ui->service->currentText()); + +#ifdef BROWSER_AVAILABLE + OAuth::DeleteCookies(service); +#endif + + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(true); + ui->disconnectAccount->setVisible(false); + ui->key->setText(""); +} + +void AutoConfigStreamPage::on_useStreamKey_clicked() +{ + ui->stackedWidget->setCurrentIndex((int)Section::StreamKey); + UpdateCompleted(); +} + +static inline bool is_auth_service(const std::string &service) +{ + return Auth::AuthType(service) != Auth::Type::None; +} + void AutoConfigStreamPage::ServiceChanged() { - bool showMore = ui->service->currentData().toBool(); + bool showMore = + ui->service->currentData().toInt() == (int)ListOpt::ShowAll; if (showMore) return; @@ -368,23 +488,43 @@ void AutoConfigStreamPage::ServiceChanged() bool regionBased = service == "Twitch" || service == "Smashcast"; bool testBandwidth = ui->doBandwidthTest->isChecked(); - bool custom = ui->streamType->currentIndex() == 1; + bool custom = IsCustom(); + + ui->disconnectAccount->setVisible(false); + +#ifdef BROWSER_AVAILABLE + if (cef) { + if (lastService != service.c_str()) { + bool can_auth = is_auth_service(service); + int page = can_auth + ? (int)Section::Connect + : (int)Section::StreamKey; + + ui->stackedWidget->setCurrentIndex(page); + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(can_auth); + auth.reset(); + + if (lastService.isEmpty()) + lastService = service.c_str(); + } + } else { + ui->connectAccount2->setVisible(false); + } +#else + ui->connectAccount2->setVisible(false); +#endif /* Test three closest servers if "Auto" is available for Twitch */ if (service == "Twitch" && wiz->twitchAuto) regionBased = false; - ui->service->setVisible(!custom); - ui->serviceLabel->setVisible(!custom); - - ui->formLayout->removeWidget(ui->serviceLabel); - ui->formLayout->removeWidget(ui->service); - - ui->formLayout->removeWidget(ui->serverLabel); - ui->formLayout->removeWidget(ui->serverStackedWidget); + ui->streamkeyPageLayout->removeWidget(ui->serverLabel); + ui->streamkeyPageLayout->removeWidget(ui->serverStackedWidget); if (custom) { - ui->formLayout->insertRow(1, ui->serverLabel, + ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, ui->serverStackedWidget); ui->region->setVisible(false); @@ -392,10 +532,8 @@ void AutoConfigStreamPage::ServiceChanged() ui->serverStackedWidget->setVisible(true); ui->serverLabel->setVisible(true); } else { - ui->formLayout->insertRow(1, ui->serviceLabel, ui->service); - if (!testBandwidth) - ui->formLayout->insertRow(2, ui->serverLabel, + ui->streamkeyPageLayout->insertRow(2, ui->serverLabel, ui->serverStackedWidget); ui->region->setVisible(regionBased && testBandwidth); @@ -409,12 +547,22 @@ void AutoConfigStreamPage::ServiceChanged() ui->bitrateLabel->setHidden(testBandwidth); ui->bitrate->setHidden(testBandwidth); +#ifdef BROWSER_AVAILABLE + OBSBasic *main = OBSBasic::Get(); + + if (!!main->auth && + service.find(main->auth->service()) != std::string::npos) { + auth = main->auth; + OnAuthConnected(); + } +#endif + UpdateCompleted(); } void AutoConfigStreamPage::UpdateKeyLink() { - bool custom = ui->streamType->currentIndex() == 1; + bool custom = IsCustom(); QString serviceName = ui->service->currentText(); bool isYoutube = false; @@ -478,18 +626,22 @@ void AutoConfigStreamPage::LoadServices(bool showAll) for (QString &name : names) ui->service->addItem(name); + if (!showAll) { + ui->service->addItem( + QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"), + QVariant((int)ListOpt::ShowAll)); + } + + ui->service->insertItem(0, + QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), + QVariant((int)ListOpt::Custom)); + if (!lastService.isEmpty()) { int idx = ui->service->findText(lastService); if (idx != -1) ui->service->setCurrentIndex(idx); } - if (!showAll) { - ui->service->addItem( - QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"), - QVariant(true)); - } - obs_properties_destroy(props); ui->service->blockSignals(false); @@ -498,7 +650,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll) void AutoConfigStreamPage::UpdateServerList() { QString serviceName = ui->service->currentText(); - bool showMore = ui->service->currentData().toBool(); + bool showMore = + ui->service->currentData().toInt() == (int)ListOpt::ShowAll; if (showMore) { LoadServices(true); @@ -533,10 +686,11 @@ void AutoConfigStreamPage::UpdateServerList() void AutoConfigStreamPage::UpdateCompleted() { - if (ui->key->text().isEmpty()) { + if (ui->stackedWidget->currentIndex() == (int)Section::Connect || + (ui->key->text().isEmpty() && !auth)) { ready = false; } else { - bool custom = ui->streamType->currentIndex() == 1; + bool custom = IsCustom(); if (custom) { ready = !ui->customServer->text().isEmpty(); } else { @@ -555,6 +709,8 @@ void AutoConfigStreamPage::UpdateCompleted() AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent) { + EnableThreadedMessageBoxes(true); + calldata_t cd = {0}; calldata_set_int(&cd, "seconds", 5); @@ -572,13 +728,14 @@ AutoConfig::AutoConfig(QWidget *parent) #ifdef _WIN32 setWizardStyle(QWizard::ModernStyle); #endif - AutoConfigStreamPage *streamPage = new AutoConfigStreamPage(); + streamPage = new AutoConfigStreamPage(); setPage(StartPage, new AutoConfigStartPage()); setPage(VideoPage, new AutoConfigVideoPage()); setPage(StreamPage, streamPage); setPage(TestPage, new AutoConfigTestPage()); setWindowTitle(QTStr("Basic.AutoConfig")); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); obs_video_info ovi; obs_get_video_info(&ovi); @@ -636,6 +793,7 @@ AutoConfig::AutoConfig(QWidget *parent) streamPage->UpdateServerList(); streamPage->UpdateKeyLink(); + streamPage->lastService.clear(); if (!customServer) { QComboBox *serverList = streamPage->ui->server; @@ -646,7 +804,9 @@ AutoConfig::AutoConfig(QWidget *parent) serverList->setCurrentIndex(idx); } else { streamPage->ui->customServer->setText(server.c_str()); - streamPage->ui->streamType->setCurrentIndex(1); + int idx = streamPage->ui->service->findData( + QVariant((int)ListOpt::Custom)); + streamPage->ui->service->setCurrentIndex(idx); } if (!key.empty()) @@ -656,12 +816,17 @@ AutoConfig::AutoConfig(QWidget *parent) streamPage->ui->bitrate->setValue(bitrate); streamPage->ServiceChanged(); - streamPage->ui->preferHardware->setChecked(os_get_physical_cores() <= 4); - TestHardwareEncoding(); if (!hardwareEncodingAvailable) { delete streamPage->ui->preferHardware; streamPage->ui->preferHardware = nullptr; + } else { + /* Newer generations of NVENC have a high enough quality to + * bitrate ratio that if NVENC is available, it makes sense to + * just always prefer hardware encoding by default */ + bool preferHardware = nvencAvailable || + os_get_physical_cores() <= 4; + streamPage->ui->preferHardware->setChecked(preferHardware); } setOptions(0); @@ -676,6 +841,7 @@ AutoConfig::~AutoConfig() { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); main->EnableOutputs(true); + EnableThreadedMessageBoxes(false); } void AutoConfig::TestHardwareEncoding() @@ -788,6 +954,9 @@ void AutoConfig::SaveStreamSettings() main->SetService(newService); main->SaveService(); + main->auth = streamPage->auth; + if (!!main->auth) + main->auth->LoadUI(); /* ---------------------------------- */ /* save stream settings */ diff --git a/UI/window-basic-auto-config.hpp b/UI/window-basic-auto-config.hpp index 3478df2..9426a75 100644 --- a/UI/window-basic-auto-config.hpp +++ b/UI/window-basic-auto-config.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -17,6 +18,9 @@ class Ui_AutoConfigVideoPage; class Ui_AutoConfigStreamPage; class Ui_AutoConfigTestPage; +class AutoConfigStreamPage; +class Auth; + class AutoConfig : public QWizard { Q_OBJECT @@ -60,6 +64,8 @@ class AutoConfig : public QWizard { static inline const char *GetEncoderId(Encoder enc); + AutoConfigStreamPage *streamPage = nullptr; + Service service = Service::Other; Quality recordingQuality = Quality::Stream; Encoder recordingEncoder = Encoder::Stream; @@ -155,11 +161,19 @@ class AutoConfigStreamPage : public QWizardPage { friend class AutoConfig; + enum class Section : int { + Connect, + StreamKey, + }; + + std::shared_ptr auth; + Ui_AutoConfigStreamPage *ui; QString lastService; bool ready = false; void LoadServices(bool showAll); + inline bool IsCustom() const; public: AutoConfigStreamPage(QWidget *parent = nullptr); @@ -169,8 +183,14 @@ public: virtual int nextId() const override; virtual bool validatePage() override; + void OnAuthConnected(); + void OnOAuthStreamKeyConnected(); + public slots: void on_show_clicked(); + void on_connectAccount_clicked(); + void on_disconnectAccount_clicked(); + void on_useStreamKey_clicked(); void ServiceChanged(); void UpdateKeyLink(); void UpdateServerList(); diff --git a/UI/window-basic-filters.cpp b/UI/window-basic-filters.cpp index 564deac..fa2ef99 100644 --- a/UI/window-basic-filters.cpp +++ b/UI/window-basic-filters.cpp @@ -71,6 +71,15 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_) const char *name = obs_source_get_name(source); setWindowTitle(QTStr("Basic.Filters.Title").arg(QT_UTF8(name))); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + +#ifndef QT_NO_SHORTCUT + ui->actionRemoveFilter->setShortcut(QApplication::translate("OBSBasicFilters", "Del", nullptr)); +#endif // QT_NO_SHORTCUT + + addAction(ui->actionRemoveFilter); + addAction(ui->actionMoveUp); + addAction(ui->actionMoveDown); installEventFilter(CreateShortcutFilter()); @@ -425,7 +434,7 @@ void OBSBasicFilters::AddNewFilter(const char *id) return; if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); AddNewFilter(id); @@ -435,7 +444,7 @@ void OBSBasicFilters::AddNewFilter(const char *id) existing_filter = obs_source_get_filter_by_name(source, name.c_str()); if (existing_filter) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); obs_source_release(existing_filter); @@ -507,20 +516,20 @@ void OBSBasicFilters::OBSSourceReordered(void *param, calldata_t *data) UNUSED_PARAMETER(data); } -void OBSBasicFilters::SourceRemoved(void *data, calldata_t *params) +void OBSBasicFilters::SourceRemoved(void *param, calldata_t *data) { - UNUSED_PARAMETER(params); + UNUSED_PARAMETER(data); - QMetaObject::invokeMethod(static_cast(data), + QMetaObject::invokeMethod(static_cast(param), "close"); } -void OBSBasicFilters::SourceRenamed(void *data, calldata_t *params) +void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data) { - const char *name = calldata_string(params, "new_name"); + const char *name = calldata_string(data, "new_name"); QString title = QTStr("Basic.Filters.Title").arg(QT_UTF8(name)); - QMetaObject::invokeMethod(static_cast(data), + QMetaObject::invokeMethod(static_cast(param), "setWindowTitle", Q_ARG(QString, title)); } @@ -659,6 +668,30 @@ void OBSBasicFilters::on_effectFilters_currentRowChanged(int row) UpdatePropertiesView(row, false); } +void OBSBasicFilters::on_actionRemoveFilter_triggered() +{ + if (ui->asyncFilters->hasFocus()) + on_removeAsyncFilter_clicked(); + else if (ui->effectFilters->hasFocus()) + on_removeEffectFilter_clicked(); +} + +void OBSBasicFilters::on_actionMoveUp_triggered() +{ + if (ui->asyncFilters->hasFocus()) + on_moveAsyncFilterUp_clicked(); + else if (ui->effectFilters->hasFocus()) + on_moveEffectFilterUp_clicked(); +} + +void OBSBasicFilters::on_actionMoveDown_triggered() +{ + if (ui->asyncFilters->hasFocus()) + on_moveAsyncFilterDown_clicked(); + else if (ui->effectFilters->hasFocus()) + on_moveEffectFilterDown_clicked(); +} + void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async) { QListWidget *list = async ? ui->asyncFilters : ui->effectFilters; diff --git a/UI/window-basic-filters.hpp b/UI/window-basic-filters.hpp index 9fdbce3..5ab28a0 100644 --- a/UI/window-basic-filters.hpp +++ b/UI/window-basic-filters.hpp @@ -100,6 +100,10 @@ private slots: void on_effectFilters_customContextMenuRequested(const QPoint &pos); void on_effectFilters_GotFocus(); + void on_actionRemoveFilter_triggered(); + void on_actionMoveUp_triggered(); + void on_actionMoveDown_triggered(); + void AsyncFilterNameEdited(QWidget *editor, QAbstractItemDelegate::EndEditHint endHint); void EffectFilterNameEdited(QWidget *editor, diff --git a/UI/window-basic-main-browser.cpp b/UI/window-basic-main-browser.cpp new file mode 100644 index 0000000..c29fe07 --- /dev/null +++ b/UI/window-basic-main-browser.cpp @@ -0,0 +1,164 @@ +/****************************************************************************** + Copyright (C) 2018 by Hugh Bailey + + 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, see . +******************************************************************************/ + +#include +#include +#include +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" + +#include + +#ifdef BROWSER_AVAILABLE +#include +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +static std::string GenId() +{ + std::random_device rd; + std::mt19937_64 e2(rd()); + std::uniform_int_distribution dist(0, 0xFFFFFFFFFFFFFFFF); + + uint64_t id = dist(e2); + + char id_str[20]; + snprintf(id_str, sizeof(id_str), "%16llX", (unsigned long long)id); + return std::string(id_str); +} + +void CheckExistingCookieId() +{ + OBSBasic *main = OBSBasic::Get(); + if (config_has_user_value(main->Config(), "Panels", "CookieId")) + return; + + config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str()); +} + +#ifdef BROWSER_AVAILABLE +static void InitPanelCookieManager() +{ + if (!cef) + return; + if (panel_cookies) + return; + + CheckExistingCookieId(); + + OBSBasic *main = OBSBasic::Get(); + const char *cookie_id = config_get_string(main->Config(), + "Panels", "CookieId"); + + std::string sub_path; + sub_path += "obs_profile_cookies/"; + sub_path += cookie_id; + + panel_cookies = cef->create_cookie_manager(sub_path); +} +#endif + +void DestroyPanelCookieManager() +{ +#ifdef BROWSER_AVAILABLE + if (panel_cookies) { + panel_cookies->FlushStore(); + delete panel_cookies; + panel_cookies = nullptr; + } +#endif +} + +void DeleteCookies() +{ +#ifdef BROWSER_AVAILABLE + if (panel_cookies) { + panel_cookies->DeleteCookies("", ""); + } +#endif +} + +void DuplicateCurrentCookieProfile(ConfigFile &config) +{ +#ifdef BROWSER_AVAILABLE + if (cef) { + OBSBasic *main = OBSBasic::Get(); + std::string cookie_id = config_get_string(main->Config(), + "Panels", "CookieId"); + + std::string src_path; + src_path += "obs_profile_cookies/"; + src_path += cookie_id; + + std::string new_id = GenId(); + + std::string dst_path; + dst_path += "obs_profile_cookies/"; + dst_path += new_id; + + BPtr src_path_full = cef->get_cookie_path(src_path); + BPtr dst_path_full = cef->get_cookie_path(dst_path); + + QDir srcDir(src_path_full.Get()); + QDir dstDir(dst_path_full.Get()); + + if (srcDir.exists()) { + if (!dstDir.exists()) + dstDir.mkdir(dst_path_full.Get()); + + QStringList files = srcDir.entryList(QDir::Files); + for (const QString &file : files) { + QString src = QString(src_path_full); + QString dst = QString(dst_path_full); + src += QDir::separator() + file; + dst += QDir::separator() + file; + QFile::copy(src, dst); + } + } + + config_set_string(config, "Panels", "CookieId", + cookie_id.c_str()); + config_set_string(main->Config(), "Panels", "CookieId", + new_id.c_str()); + } +#else + UNUSED_PARAMETER(config); +#endif +} + +void OBSBasic::InitBrowserPanelSafeBlock() +{ +#ifdef BROWSER_AVAILABLE + if (!cef) + return; + if (cef->init_browser()) { + InitPanelCookieManager(); + return; + } + + ExecThreadedWithoutBlocking( + [] {cef->wait_for_browser_init();}, + QTStr("BrowserPanelInit.Title"), + QTStr("BrowserPanelInit.Text")); + InitPanelCookieManager(); +#endif +} diff --git a/UI/window-basic-main-dropfiles.cpp b/UI/window-basic-main-dropfiles.cpp index cd5c481..50dd3d3 100644 --- a/UI/window-basic-main-dropfiles.cpp +++ b/UI/window-basic-main-dropfiles.cpp @@ -148,7 +148,7 @@ void OBSBasic::dropEvent(QDropEvent *event) if (mimeData->hasUrls()) { QList urls = mimeData->urls(); - for (int i = 0; i < urls.size() && i < 5; i++) { + for (int i = 0; i < urls.size(); i++) { QString file = urls.at(i).toLocalFile(); QFileInfo fileInfo(file); diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp index 2f9bfa8..6b3e46f 100644 --- a/UI/window-basic-main-outputs.cpp +++ b/UI/window-basic-main-outputs.cpp @@ -8,6 +8,12 @@ using namespace std; +extern bool EncoderAvailable(const char *encoder); + +volatile bool streaming_active = false; +volatile bool recording_active = false; +volatile bool replaybuf_active = false; + static void OBSStreamStarting(void *data, calldata_t *params) { BasicOutputHandler *output = static_cast(data); @@ -39,6 +45,7 @@ static void OBSStartStreaming(void *data, calldata_t *params) { BasicOutputHandler *output = static_cast(data); output->streamingActive = true; + os_atomic_set_bool(&streaming_active, true); QMetaObject::invokeMethod(output->main, "StreamingStart"); UNUSED_PARAMETER(params); @@ -54,8 +61,10 @@ static void OBSStopStreaming(void *data, calldata_t *params) output->streamingActive = false; output->delayActive = false; + os_atomic_set_bool(&streaming_active, false); QMetaObject::invokeMethod(output->main, - "StreamingStop", Q_ARG(int, code), Q_ARG(QString, arg_last_error)); + "StreamingStop", Q_ARG(int, code), + Q_ARG(QString, arg_last_error)); } static void OBSStartRecording(void *data, calldata_t *params) @@ -63,6 +72,7 @@ static void OBSStartRecording(void *data, calldata_t *params) BasicOutputHandler *output = static_cast(data); output->recordingActive = true; + os_atomic_set_bool(&recording_active, true); QMetaObject::invokeMethod(output->main, "RecordingStart"); UNUSED_PARAMETER(params); @@ -72,10 +82,15 @@ static void OBSStopRecording(void *data, calldata_t *params) { BasicOutputHandler *output = static_cast(data); int code = (int)calldata_int(params, "code"); + const char *last_error = calldata_string(params, "last_error"); + + QString arg_last_error = QString::fromUtf8(last_error); output->recordingActive = false; + os_atomic_set_bool(&recording_active, false); QMetaObject::invokeMethod(output->main, - "RecordingStop", Q_ARG(int, code)); + "RecordingStop", Q_ARG(int, code), + Q_ARG(QString, arg_last_error)); UNUSED_PARAMETER(params); } @@ -93,6 +108,7 @@ static void OBSStartReplayBuffer(void *data, calldata_t *params) BasicOutputHandler *output = static_cast(data); output->replayBufferActive = true; + os_atomic_set_bool(&replaybuf_active, true); QMetaObject::invokeMethod(output->main, "ReplayBufferStart"); UNUSED_PARAMETER(params); @@ -104,6 +120,7 @@ static void OBSStopReplayBuffer(void *data, calldata_t *params) int code = (int)calldata_int(params, "code"); output->replayBufferActive = false; + os_atomic_set_bool(&replaybuf_active, false); QMetaObject::invokeMethod(output->main, "ReplayBufferStop", Q_ARG(int, code)); @@ -242,6 +259,8 @@ void SimpleOutput::LoadRecordingPreset_Lossless() obs_data_set_string(settings, "video_encoder", "utvideo"); obs_data_set_string(settings, "audio_encoder", "pcm_s16le"); + int aMixes = 1; + obs_output_set_mixers(fileOutput, aMixes); obs_output_update(fileOutput, settings); obs_data_release(settings); } @@ -300,7 +319,10 @@ void SimpleOutput::LoadRecordingPreset() } else if (strcmp(encoder, SIMPLE_ENCODER_AMD) == 0) { LoadRecordingPreset_h264("amd_amf_h264"); } else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) { - LoadRecordingPreset_h264("ffmpeg_nvenc"); + const char *id = EncoderAvailable("jim_nvenc") + ? "jim_nvenc" + : "ffmpeg_nvenc"; + LoadRecordingPreset_h264(id); } usingRecordingPreset = true; @@ -315,14 +337,22 @@ SimpleOutput::SimpleOutput(OBSBasic *main_) : BasicOutputHandler(main_) { const char *encoder = config_get_string(main->Config(), "SimpleOutput", "StreamEncoder"); - if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) + + if (strcmp(encoder, SIMPLE_ENCODER_QSV) == 0) { LoadStreamingPreset_h264("obs_qsv11"); - else if (strcmp(encoder, SIMPLE_ENCODER_AMD) == 0) + + } else if (strcmp(encoder, SIMPLE_ENCODER_AMD) == 0) { LoadStreamingPreset_h264("amd_amf_h264"); - else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) - LoadStreamingPreset_h264("ffmpeg_nvenc"); - else + + } else if (strcmp(encoder, SIMPLE_ENCODER_NVENC) == 0) { + const char *id = EncoderAvailable("jim_nvenc") + ? "jim_nvenc" + : "ffmpeg_nvenc"; + LoadStreamingPreset_h264(id); + + } else { LoadStreamingPreset_h264("obs_x264"); + } if (!CreateAACEncoder(aacStreaming, aacStreamEncID, GetAudioBitrate(), "simple_aac", 0)) @@ -649,6 +679,10 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) if (!Active()) SetupOutputs(); + Auth *auth = main->GetAuth(); + if (auth) + auth->OnStreamConfig(); + /* --------------------- */ const char *type = obs_service_get_output_type(service); @@ -685,28 +719,39 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) obs_output_get_signal_handler(streamOutput), "stop", OBSStopStreaming, this); - const char *codec = - obs_output_get_supported_audio_codecs(streamOutput); - if (!codec) { - return false; - } + bool isEncoded = obs_output_get_flags(streamOutput) + & OBS_OUTPUT_ENCODED; - if (strcmp(codec, "aac") != 0) { - const char *id = FindAudioEncoderFromCodec(codec); - int audioBitrate = GetAudioBitrate(); - obs_data_t *settings = obs_data_create(); - obs_data_set_int(settings, "bitrate", audioBitrate); - - aacStreaming = obs_audio_encoder_create(id, - "alt_audio_enc", nullptr, 0, nullptr); - obs_encoder_release(aacStreaming); - if (!aacStreaming) + if (isEncoded) { + const char *codec = + obs_output_get_supported_audio_codecs( + streamOutput); + if (!codec) { + blog(LOG_WARNING, "Failed to load audio codec"); return false; + } - obs_encoder_update(aacStreaming, settings); - obs_encoder_set_audio(aacStreaming, obs_get_audio()); + if (strcmp(codec, "aac") != 0) { + const char *id = FindAudioEncoderFromCodec( + codec); + int audioBitrate = GetAudioBitrate(); + obs_data_t *settings = obs_data_create(); + obs_data_set_int(settings, "bitrate", + audioBitrate); - obs_data_release(settings); + aacStreaming = obs_audio_encoder_create(id, + "alt_audio_enc", nullptr, 0, + nullptr); + obs_encoder_release(aacStreaming); + if (!aacStreaming) + return false; + + obs_encoder_update(aacStreaming, settings); + obs_encoder_set_audio(aacStreaming, + obs_get_audio()); + + obs_data_release(settings); + } } outputType = type; @@ -760,12 +805,15 @@ bool SimpleOutput::StartStreaming(obs_service_t *service) } const char *error = obs_output_get_last_error(streamOutput); - bool has_last_error = error && *error; + bool hasLastError = error && *error; + if (hasLastError) + lastError = error; + else + lastError = string(); - blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", - type, - has_last_error ? " Last Error: " : "", - has_last_error ? error : ""); + blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type, + hasLastError ? " Last Error: " : "", + hasLastError ? error : ""); return false; } @@ -848,7 +896,7 @@ bool SimpleOutput::ConfigureRecording(bool updateReplayBuffer) if (!dir) { if (main->isVisible()) - OBSMessageBox::information(main, + OBSMessageBox::warning(main, QTStr("Output.BadPath.Title"), QTStr("Output.BadPath.Text")); else @@ -1207,9 +1255,14 @@ inline void AdvancedOutput::SetupStreaming() "Rescale"); const char *rescaleRes = config_get_string(main->Config(), "AdvOut", "RescaleRes"); + uint32_t caps = obs_encoder_get_caps(h264Streaming); unsigned int cx = 0; unsigned int cy = 0; + if ((caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) { + rescale = false; + } + if (rescale && rescaleRes && *rescaleRes) { if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) { cx = 0; @@ -1243,6 +1296,11 @@ inline void AdvancedOutput::SetupRecording() obs_output_set_video_encoder(replayBuffer, h264Streaming); } else { + uint32_t caps = obs_encoder_get_caps(h264Recording); + if ((caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) { + rescale = false; + } + if (rescale && rescaleRes && *rescaleRes) { if (sscanf(rescaleRes, "%ux%u", &cx, &cy) != 2) { cx = 0; @@ -1302,8 +1360,8 @@ inline void AdvancedOutput::SetupFFmpeg() "FFVCustom"); int aBitrate = config_get_int(main->Config(), "AdvOut", "FFABitrate"); - int aTrack = config_get_int(main->Config(), "AdvOut", - "FFAudioTrack"); + int aMixes = config_get_int(main->Config(), "AdvOut", + "FFAudioMixes"); const char *aEncoder = config_get_string(main->Config(), "AdvOut", "FFAEncoder"); int aEncoderId = config_get_int(main->Config(), "AdvOut", @@ -1337,7 +1395,7 @@ inline void AdvancedOutput::SetupFFmpeg() } } - obs_output_set_mixer(fileOutput, aTrack - 1); + obs_output_set_mixers(fileOutput, aMixes); obs_output_set_media(fileOutput, obs_get_video(), obs_get_audio()); obs_output_update(fileOutput, settings); @@ -1424,6 +1482,10 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) if (!Active()) SetupOutputs(); + Auth *auth = main->GetAuth(); + if (auth) + auth->OnStreamConfig(); + /* --------------------- */ int trackIndex = config_get_int(main->Config(), "AdvOut", @@ -1463,30 +1525,42 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) obs_output_get_signal_handler(streamOutput), "stop", OBSStopStreaming, this); - const char *codec = - obs_output_get_supported_audio_codecs(streamOutput); - if (!codec) { - return false; - } + bool isEncoded = obs_output_get_flags(streamOutput) + & OBS_OUTPUT_ENCODED; - if (strcmp(codec, "aac") == 0) { - streamAudioEnc = aacTrack[trackIndex - 1]; - } else { - const char *id = FindAudioEncoderFromCodec(codec); - int audioBitrate = GetAudioBitrate(trackIndex - 1); - obs_data_t *settings = obs_data_create(); - obs_data_set_int(settings, "bitrate", audioBitrate); - - streamAudioEnc = obs_audio_encoder_create(id, - "alt_audio_enc", nullptr, - trackIndex - 1, nullptr); - if (!streamAudioEnc) + if (isEncoded) { + const char *codec = + obs_output_get_supported_audio_codecs( + streamOutput); + if (!codec) { + blog(LOG_WARNING, "Failed to load audio codec"); return false; + } - obs_encoder_update(streamAudioEnc, settings); - obs_encoder_set_audio(streamAudioEnc, obs_get_audio()); + if (strcmp(codec, "aac") == 0) { + streamAudioEnc = aacTrack[trackIndex - 1]; + } else { + obs_data_t *settings = obs_data_create(); + const char *id = + FindAudioEncoderFromCodec(codec); + int audioBitrate = + GetAudioBitrate(trackIndex - 1); + + obs_data_set_int(settings, "bitrate", + audioBitrate); + streamAudioEnc = obs_audio_encoder_create(id, + "alt_audio_enc", nullptr, + trackIndex - 1, nullptr); - obs_data_release(settings); + if (!streamAudioEnc) + return false; + + obs_encoder_update(streamAudioEnc, settings); + obs_encoder_set_audio(streamAudioEnc, + obs_get_audio()); + + obs_data_release(settings); + } } outputType = type; @@ -1538,12 +1612,15 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service) } const char *error = obs_output_get_last_error(streamOutput); - bool has_last_error = error && *error; + bool hasLastError = error && *error; + if (hasLastError) + lastError = error; + else + lastError = string(); - blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", - type, - has_last_error ? " Last Error: " : "", - has_last_error ? error : ""); + blog(LOG_WARNING, "Stream output type '%s' failed to start!%s%s", type, + hasLastError ? " Last Error: " : "", + hasLastError ? error : ""); return false; } @@ -1586,7 +1663,7 @@ bool AdvancedOutput::StartRecording() if (!dir) { if (main->isVisible()) - OBSMessageBox::information(main, + OBSMessageBox::warning(main, QTStr("Output.BadPath.Title"), QTStr("Output.BadPath.Text")); else @@ -1686,7 +1763,7 @@ bool AdvancedOutput::StartReplayBuffer() if (!dir) { if (main->isVisible()) - OBSMessageBox::information(main, + OBSMessageBox::warning(main, QTStr("Output.BadPath.Title"), QTStr("Output.BadPath.Text")); else diff --git a/UI/window-basic-main-outputs.hpp b/UI/window-basic-main-outputs.hpp index 4c4842d..c053d0b 100644 --- a/UI/window-basic-main-outputs.hpp +++ b/UI/window-basic-main-outputs.hpp @@ -15,6 +15,7 @@ struct BasicOutputHandler { OBSBasic *main; std::string outputType; + std::string lastError; OBSSignal startRecording; OBSSignal stopRecording; diff --git a/UI/window-basic-main-profiles.cpp b/UI/window-basic-main-profiles.cpp index f5db4cd..aa512d5 100644 --- a/UI/window-basic-main-profiles.cpp +++ b/UI/window-basic-main-profiles.cpp @@ -25,6 +25,11 @@ #include "window-namedialog.hpp" #include "qt-wrappers.hpp" +extern void DestroyPanelCookieManager(); +extern void DuplicateCurrentCookieProfile(ConfigFile &config); +extern void CheckExistingCookieId(); +extern void DeleteCookies(); + void EnumProfiles(std::function &&cb) { char path[512]; @@ -102,13 +107,13 @@ static bool GetProfileName(QWidget *parent, std::string &name, return false; } if (name.empty()) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); continue; } if (ProfileExists(name.c_str())) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NameExists.Title"), QTStr("NameExists.Text")); continue; @@ -143,7 +148,7 @@ static bool GetProfileName(QWidget *parent, std::string &name, static bool CopyProfile(const char *fromPartial, const char *to) { os_glob_t *glob; - char path[512]; + char path[514]; char dir[512]; int ret; @@ -182,7 +187,7 @@ static bool CopyProfile(const char *fromPartial, const char *to) } bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, - const char *init_text) + const char *init_text, bool rename) { std::string newName; std::string newDir; @@ -228,10 +233,20 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text, config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir.c_str()); + Auth::Save(); + if (create_new) { + auth.reset(); + DestroyPanelCookieManager(); + } else if (!rename) { + DuplicateCurrentCookieProfile(config); + } + config_set_string(config, "General", "Name", newName.c_str()); + basicConfig.SaveSafe("tmp"); config.SaveSafe("tmp"); config.Swap(basicConfig); InitBasicConfigDefaults(); + InitBasicConfigDefaults2(); RefreshProfiles(); if (create_new) @@ -380,7 +395,7 @@ void OBSBasic::on_actionRenameProfile_triggered() /* Duplicate and delete in case there are any issues in the process */ bool success = AddProfile(false, Str("RenameProfile.Title"), - Str("AddProfile.Text"), curName.c_str()); + Str("AddProfile.Text"), curName.c_str(), true); if (success) { DeleteProfile(curName.c_str(), curDir.c_str()); RefreshProfiles(); @@ -446,8 +461,14 @@ void OBSBasic::on_actionRemoveProfile_triggered() config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); + Auth::Save(); + auth.reset(); + DeleteCookies(); + DestroyPanelCookieManager(); + config.Swap(basicConfig); InitBasicConfigDefaults(); + InitBasicConfigDefaults2(); ResetProfileData(); DeleteProfile(oldName.c_str(), oldDir.c_str()); RefreshProfiles(); @@ -459,6 +480,8 @@ void OBSBasic::on_actionRemoveProfile_triggered() UpdateTitleBar(); + Auth::Load(); + if (api) { api->on_event(OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED); api->on_event(OBS_FRONTEND_EVENT_PROFILE_CHANGED); @@ -503,7 +526,7 @@ void OBSBasic::on_actionImportProfile_triggered() profileDir + "/recordEncoder.json"); RefreshProfiles(); } else { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("Basic.MainMenu.Profile.Import"), QTStr("Basic.MainMenu.Profile.Exists")); } @@ -603,13 +626,20 @@ void OBSBasic::ChangeProfile() config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir); + Auth::Save(); + auth.reset(); + DestroyPanelCookieManager(); + config.Swap(basicConfig); InitBasicConfigDefaults(); + InitBasicConfigDefaults2(); ResetProfileData(); RefreshProfiles(); config_save_safe(App()->GlobalConfig(), "tmp", nullptr); UpdateTitleBar(); + Auth::Load(); + CheckForSimpleModeX264Fallback(); blog(LOG_INFO, "Switched to profile '%s' (%s)", diff --git a/UI/window-basic-main-scene-collections.cpp b/UI/window-basic-main-scene-collections.cpp index 9759a27..84da0f3 100644 --- a/UI/window-basic-main-scene-collections.cpp +++ b/UI/window-basic-main-scene-collections.cpp @@ -114,13 +114,13 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name, return false; } if (name.empty()) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); continue; } if (SceneCollectionExists(name.c_str())) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NameExists.Title"), QTStr("NameExists.Text")); continue; @@ -439,6 +439,8 @@ void OBSBasic::on_actionImportSceneCollection_triggered() void OBSBasic::on_actionExportSceneCollection_triggered() { + SaveProjectNow(); + char path[512]; QString home = QDir::homePath(); diff --git a/UI/window-basic-main-transitions.cpp b/UI/window-basic-main-transitions.cpp index 952f5d4..daec936 100644 --- a/UI/window-basic-main-transitions.cpp +++ b/UI/window-basic-main-transitions.cpp @@ -254,6 +254,12 @@ void OBSBasic::TransitionStopped() OBSSource scene = OBSGetStrongRef(swapScene); if (scene) SetCurrentScene(scene); + + // Make sure we re-enable the transition button + if (transitionButton) + transitionButton->setEnabled(true); + + EnableQuickTransitionWidgets(); } if (api) { @@ -294,7 +300,7 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, return; OBSWeakSource lastProgramScene; - + if (usingPreviewProgram) { lastProgramScene = programScene; programScene = OBSGetWeakRef(source); @@ -321,6 +327,12 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, OBSSource transition = obs_get_output_source(0); obs_source_release(transition); + bool stillTransitioning = obs_transition_get_time(transition) < 1.0f; + + // If actively transitioning, block new transitions from starting + if (usingPreviewProgram && stillTransitioning) + goto cleanup; + if (force) { obs_transition_set(transition, source); if (api) @@ -355,6 +367,15 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct, TransitionFullyStopped(); } + // If transition has begun, disable Transition button + if (usingPreviewProgram && stillTransitioning) { + if (transitionButton) + transitionButton->setEnabled(false); + + DisableQuickTransitionWidgets(); + } + +cleanup: if (usingPreviewProgram && sceneDuplicationMode) obs_scene_release(scene); } @@ -432,7 +453,7 @@ void OBSBasic::AddTransition() if (accepted) { if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); AddTransition(); @@ -441,7 +462,7 @@ void OBSBasic::AddTransition() source = FindTransition(name.c_str()); if (source) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); @@ -538,7 +559,7 @@ void OBSBasic::RenameTransition() if (accepted) { if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); RenameTransition(); @@ -547,7 +568,7 @@ void OBSBasic::RenameTransition() source = FindTransition(name.c_str()); if (source) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); @@ -675,6 +696,7 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct) void OBSBasic::CreateProgramDisplay() { program = new OBSQTDisplay(); + program->setContextMenuPolicy(Qt::CustomContextMenu); connect(program.data(), &QWidget::customContextMenuRequested, this, &OBSBasic::on_program_customContextMenuRequested); @@ -725,7 +747,7 @@ void OBSBasic::CreateProgramOptions() QHBoxLayout *mainButtonLayout = new QHBoxLayout(); mainButtonLayout->setSpacing(2); - QPushButton *transitionButton = new QPushButton(QTStr("Transition")); + transitionButton = new QPushButton(QTStr("Transition")); QHBoxLayout *quickTransitions = new QHBoxLayout(); quickTransitions->setSpacing(2); @@ -809,7 +831,7 @@ void OBSBasic::CreateProgramOptions() menu.exec(QCursor::pos()); }; - connect(transitionButton, &QAbstractButton::clicked, + connect(transitionButton.data(), &QAbstractButton::clicked, this, &OBSBasic::TransitionClicked); connect(addQuickTransition, &QAbstractButton::clicked, onAdd); connect(configTransitions, &QAbstractButton::clicked, onConfig); @@ -1124,11 +1146,55 @@ void OBSBasic::RefreshQuickTransitions() AddQuickTransitionId(qt.id); } +void OBSBasic::DisableQuickTransitionWidgets() +{ + if (!IsPreviewProgramMode()) + return; + + QVBoxLayout *programLayout = + reinterpret_cast(programOptions->layout()); + + for (int idx = 0;; idx++) { + QLayoutItem *item = programLayout->itemAt(idx); + if (!item) + break; + + QWidget *widget = item->widget(); + if (!widget) + continue; + + widget->setEnabled(false); + } +} + +void OBSBasic::EnableQuickTransitionWidgets() +{ + if (!IsPreviewProgramMode()) + return; + + QVBoxLayout *programLayout = + reinterpret_cast(programOptions->layout()); + + for (int idx = 0;; idx++) { + QLayoutItem *item = programLayout->itemAt(idx); + if (!item) + break; + + QWidget *widget = item->widget(); + if (!widget) + continue; + + widget->setEnabled(true); + } +} + void OBSBasic::SetPreviewProgramMode(bool enabled) { if (IsPreviewProgramMode() == enabled) return; + ui->previewLabel->setHidden(!enabled); + ui->modeSwitch->setChecked(enabled); os_atomic_set_bool(&previewProgramMode, enabled); @@ -1167,10 +1233,31 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) RefreshQuickTransitions(); + programLabel = new QLabel(QTStr("StudioMode.Program")); + programLabel->setSizePolicy(QSizePolicy::Preferred, + QSizePolicy::Preferred); + programLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom); + programLabel->setProperty("themeID", "previewProgramLabels"); + + programWidget = new QWidget(); + programLayout = new QVBoxLayout(); + + programLayout->setContentsMargins(0, 0, 0, 0); + programLayout->setSpacing(0); + + programLayout->addWidget(programLabel); + programLayout->addWidget(program); + + bool labels = config_get_bool(GetGlobalConfig(), + "BasicWindow", "StudioModeLabels"); + + programLabel->setHidden(!labels); + + programWidget->setLayout(programLayout); + ui->previewLayout->addWidget(programOptions); - ui->previewLayout->addWidget(program); + ui->previewLayout->addWidget(programWidget); ui->previewLayout->setAlignment(programOptions, Qt::AlignCenter); - program->show(); if (api) api->on_event(OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED); @@ -1188,6 +1275,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) delete programOptions; delete program; + delete programLabel; + delete programWidget; if (lastScene) { OBSSource actualLastScene = OBSGetStrongRef(lastScene); @@ -1219,6 +1308,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled) void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy) { + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderProgram"); + OBSBasic *window = static_cast(data); obs_video_info ovi; @@ -1247,6 +1338,8 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy) gs_projection_pop(); gs_viewport_pop(); + GS_DEBUG_MARKER_END(); + UNUSED_PARAMETER(cx); UNUSED_PARAMETER(cy); } diff --git a/UI/window-basic-main.cpp b/UI/window-basic-main.cpp index b2cebfe..33a17d8 100644 --- a/UI/window-basic-main.cpp +++ b/UI/window-basic-main.cpp @@ -17,7 +17,7 @@ along with this program. If not, see . ******************************************************************************/ -#include +#include #include #include #include @@ -25,10 +25,8 @@ #include #include #include -#include #include #include -#include #include #include @@ -36,7 +34,6 @@ #include #include #include -#include #include "obs-app.hpp" #include "platform.hpp" @@ -49,7 +46,6 @@ #include "window-basic-main.hpp" #include "window-basic-stats.hpp" #include "window-basic-main-outputs.hpp" -#include "window-basic-properties.hpp" #include "window-log-reply.hpp" #include "window-projector.hpp" #include "window-remux.hpp" @@ -57,7 +53,8 @@ #include "display-helpers.hpp" #include "volume-control.hpp" #include "remote-text.hpp" -#include "source-tree.hpp" +#include +#include #ifdef _WIN32 #include "win-update/win-update.hpp" @@ -72,19 +69,25 @@ #include #include -#ifdef _WIN32 -#include -#endif - #include using namespace json11; using namespace std; -#ifdef _WIN32 -static CREATE_BROWSER_WIDGET_PROC create_browser_widget = nullptr; +#ifdef BROWSER_AVAILABLE +#include #endif +#include "ui-config.h" + +struct QCef; +struct QCefCookieManager; + +QCef *cef = nullptr; +QCefCookieManager *panel_cookies = nullptr; + +void DestroyPanelCookieManager(); + namespace { template @@ -95,6 +98,8 @@ struct SignalContainer { } +extern volatile long insideEventLoop; + Q_DECLARE_METATYPE(OBSScene); Q_DECLARE_METATYPE(OBSSceneItem); Q_DECLARE_METATYPE(OBSSource); @@ -167,12 +172,47 @@ static int CountVideoSources() return count; } +void assignDockToggle(QDockWidget *dock, QAction *action) +{ + auto handleWindowToggle = [action] (bool vis) + { + action->blockSignals(true); + action->setChecked(vis); + action->blockSignals(false); + }; + auto handleMenuToggle = [dock] (bool check) + { + dock->blockSignals(true); + dock->setVisible(check); + dock->blockSignals(false); + }; + + dock->connect(dock->toggleViewAction(), &QAction::toggled, + handleWindowToggle); + dock->connect(action, &QAction::toggled, + handleMenuToggle); +} + +extern void RegisterTwitchAuth(); +extern void RegisterMixerAuth(); +extern void RegisterRestreamAuth(); + OBSBasic::OBSBasic(QWidget *parent) : OBSMainWindow (parent), ui (new Ui::OBSBasic) { setAttribute(Qt::WA_NativeWindow); +#if TWITCH_ENABLED + RegisterTwitchAuth(); +#endif +#if MIXER_ENABLED + RegisterMixerAuth(); +#endif +#if RESTREAM_ENABLED + RegisterRestreamAuth(); +#endif + setAcceptDrops(true); api = InitializeAPIInterface(this); @@ -182,6 +222,15 @@ OBSBasic::OBSBasic(QWidget *parent) startingDockLayout = saveState(); + statsDock = new OBSDock(); + statsDock->setObjectName(QStringLiteral("statsDock")); + statsDock->setFeatures(QDockWidget::AllDockWidgetFeatures); + statsDock->setWindowTitle(QTStr("Basic.Stats")); + addDockWidget(Qt::BottomDockWidgetArea, statsDock); + statsDock->setVisible(false); + statsDock->setFloating(true); + statsDock->resize(700, 200); + copyActionsDynamicProperties(); char styleSheetPath[512]; @@ -209,6 +258,8 @@ OBSBasic::OBSBasic(QWidget *parent) ui->scenes->setAttribute(Qt::WA_MacShowFocusRect, false); ui->sources->setAttribute(Qt::WA_MacShowFocusRect, false); + ui->scenes->setItemDelegate(new SceneRenameDelegate(ui->scenes)); + auto displayResize = [this]() { struct obs_video_info ovi; @@ -219,7 +270,9 @@ OBSBasic::OBSBasic(QWidget *parent) connect(windowHandle(), &QWindow::screenChanged, displayResize); connect(ui->preview, &OBSQTDisplay::DisplayResized, displayResize); - installEventFilter(CreateShortcutFilter()); + delete shortcutFilter; + shortcutFilter = CreateShortcutFilter(); + installEventFilter(shortcutFilter); stringstream name; name << "OBS " << App()->GetVersionString(); @@ -241,12 +294,29 @@ OBSBasic::OBSBasic(QWidget *parent) ui->statusbar, SLOT(UpdateCPUUsage())); cpuUsageTimer->start(3000); + QAction *renameScene = new QAction(ui->scenesDock); + renameScene->setShortcutContext(Qt::WidgetWithChildrenShortcut); + connect(renameScene, SIGNAL(triggered()), this, SLOT(EditSceneName())); + ui->scenesDock->addAction(renameScene); + + QAction *renameSource = new QAction(ui->sourcesDock); + renameSource->setShortcutContext(Qt::WidgetWithChildrenShortcut); + connect(renameSource, SIGNAL(triggered()), this, + SLOT(EditSceneItemName())); + ui->sourcesDock->addAction(renameSource); + #ifdef __APPLE__ + renameScene->setShortcut({Qt::Key_Return}); + renameSource->setShortcut({Qt::Key_Return}); + ui->actionRemoveSource->setShortcuts({Qt::Key_Backspace}); ui->actionRemoveScene->setShortcuts({Qt::Key_Backspace}); ui->action_Settings->setMenuRole(QAction::PreferencesRole); ui->actionE_xit->setMenuRole(QAction::QuitRole); +#else + renameScene->setShortcut({Qt::Key_F2}); + renameSource->setShortcut({Qt::Key_F2}); #endif auto addNudge = [this](const QKeySequence &seq, const char *s) @@ -263,32 +333,12 @@ OBSBasic::OBSBasic(QWidget *parent) addNudge(Qt::Key_Left, SLOT(NudgeLeft())); addNudge(Qt::Key_Right, SLOT(NudgeRight())); - auto assignDockToggle = [] (QDockWidget *dock, QAction *action) - { - auto handleWindowToggle = [action] (bool vis) - { - action->blockSignals(true); - action->setChecked(vis); - action->blockSignals(false); - }; - auto handleMenuToggle = [dock] (bool check) - { - dock->blockSignals(true); - dock->setVisible(check); - dock->blockSignals(false); - }; - - dock->connect(dock->toggleViewAction(), &QAction::toggled, - handleWindowToggle); - dock->connect(action, &QAction::toggled, - handleMenuToggle); - }; - assignDockToggle(ui->scenesDock, ui->toggleScenes); assignDockToggle(ui->sourcesDock, ui->toggleSources); assignDockToggle(ui->mixerDock, ui->toggleMixer); assignDockToggle(ui->transitionsDock, ui->toggleTransitions); assignDockToggle(ui->controlsDock, ui->toggleControls); + assignDockToggle(statsDock, ui->toggleStats); //hide all docking panes ui->toggleScenes->setChecked(false); @@ -296,6 +346,9 @@ OBSBasic::OBSBasic(QWidget *parent) ui->toggleMixer->setChecked(false); ui->toggleTransitions->setChecked(false); ui->toggleControls->setChecked(false); + ui->toggleStats->setChecked(false); + + QPoint curPos; //restore parent window geometry const char *geometry = config_get_string(App()->GlobalConfig(), @@ -313,7 +366,29 @@ OBSBasic::OBSBasic(QWidget *parent) Qt::AlignCenter, size(), rect)); } + + curPos = pos(); + } else { + QRect desktopRect = QGuiApplication::primaryScreen()->geometry(); + QSize adjSize = desktopRect.size() / 2 - size() / 2; + curPos = QPoint(adjSize.width(), adjSize.height()); } + + QPoint curSize(width(), height()); + QPoint statsDockSize(statsDock->width(), statsDock->height()); + QPoint statsDockPos = curSize / 2 - statsDockSize / 2; + QPoint newPos = curPos + statsDockPos; + statsDock->move(newPos); + + ui->previewLabel->setProperty("themeID", "previewProgramLabels"); + + bool labels = config_get_bool(GetGlobalConfig(), + "BasicWindow", "StudioModeLabels"); + + if (!previewProgramMode) + ui->previewLabel->setHidden(true); + else + ui->previewLabel->setHidden(!labels); } static void SaveAudioDevice(const char *name, int channel, obs_data_t *parent, @@ -349,6 +424,7 @@ static obs_data_t *GenerateSaveData(obs_data_array_t *sceneOrder, SaveAudioDevice(AUX_AUDIO_1, 3, saveData, audioSources); SaveAudioDevice(AUX_AUDIO_2, 4, saveData, audioSources); SaveAudioDevice(AUX_AUDIO_3, 5, saveData, audioSources); + SaveAudioDevice(AUX_AUDIO_4, 6, saveData, audioSources); /* -------------------------------- */ /* save non-group sources */ @@ -677,6 +753,11 @@ void OBSBasic::LoadSceneListOrder(obs_data_array_t *array) void OBSBasic::LoadSavedProjectors(obs_data_array_t *array) { + for (SavedProjectorInfo *info : savedProjectorsArray) { + delete info; + } + savedProjectorsArray.clear(); + size_t num = obs_data_array_count(array); for (size_t i = 0; i < num; i++) { @@ -708,13 +789,18 @@ static void LogFilter(obs_source_t*, obs_source_t *filter, void *v_val) blog(LOG_INFO, "%s- filter: '%s' (%s)", indent.c_str(), name, id); } -static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void*) +static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void *v_val) { obs_source_t *source = obs_sceneitem_get_source(item); const char *name = obs_source_get_name(source); const char *id = obs_source_get_id(source); + int indent_count = (int)(intptr_t)v_val; + string indent; - blog(LOG_INFO, " - source: '%s' (%s)", name, id); + for (int i = 0; i < indent_count; i++) + indent += " "; + + blog(LOG_INFO, "%s- source: '%s' (%s)", indent.c_str(), name, id); obs_monitoring_type monitoring_type = obs_source_get_monitoring_type(source); @@ -725,10 +811,12 @@ static bool LogSceneItem(obs_scene_t*, obs_sceneitem_t *item, void*) ? "monitor only" : "monitor and output"; - blog(LOG_INFO, " - monitoring: %s", type); + blog(LOG_INFO, " %s- monitoring: %s", indent.c_str(), type); } - - obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)2); + int child_indent = 1 + indent_count; + obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)child_indent); + if (obs_sceneitem_is_group(item)) + obs_sceneitem_group_enum_items(item, LogSceneItem, (void*)(intptr_t)child_indent); return true; } @@ -745,7 +833,7 @@ void OBSBasic::LogScenes() const char *name = obs_source_get_name(source); blog(LOG_INFO, "- scene '%s':", name); - obs_scene_enum_items(scene, LogSceneItem, nullptr); + obs_scene_enum_items(scene, LogSceneItem, (void*)(intptr_t)1); obs_source_enum_filters(source, LogFilter, (void*)(intptr_t)1); } @@ -814,6 +902,7 @@ void OBSBasic::Load(const char *file) LoadAudioDevice(AUX_AUDIO_1, 3, data); LoadAudioDevice(AUX_AUDIO_2, 4, data); LoadAudioDevice(AUX_AUDIO_3, 5, data); + LoadAudioDevice(AUX_AUDIO_4, 6, data); if (!sources) { sources = groups; @@ -952,6 +1041,9 @@ retryScene: opt_start_replaybuffer = false; } + copyString = nullptr; + copyFiltersString = nullptr; + LogScenes(); disableSaving--; @@ -1050,6 +1142,8 @@ static const double scaled_vals[] = 0.0 }; +extern void CheckExistingCookieId(); + bool OBSBasic::InitBasicConfigDefaults() { QList screens = QGuiApplication::screens(); @@ -1076,6 +1170,21 @@ bool OBSBasic::InitBasicConfigDefaults() cy = 1080; } + bool changed = false; + + /* ----------------------------------------------------- */ + /* move over old FFmpeg track settings */ + if (config_has_user_value(basicConfig, "AdvOut", "FFAudioTrack") && + !config_has_user_value(basicConfig, "AdvOut", "Pre22.1Settings")) { + + int track = (int)config_get_int(basicConfig, "AdvOut", + "FFAudioTrack"); + config_set_int(basicConfig, "AdvOut", "FFAudioMixes", + 1LL << (track - 1)); + config_set_bool(basicConfig, "AdvOut", "Pre22.1Settings", true); + changed = true; + } + /* ----------------------------------------------------- */ /* move over mixer values in advanced if older config */ if (config_has_user_value(basicConfig, "AdvOut", "RecTrackIndex") && @@ -1086,11 +1195,16 @@ bool OBSBasic::InitBasicConfigDefaults() track = 1ULL << (track - 1); config_set_uint(basicConfig, "AdvOut", "RecTracks", track); config_remove_value(basicConfig, "AdvOut", "RecTrackIndex"); - config_save_safe(basicConfig, "tmp", nullptr); + changed = true; } /* ----------------------------------------------------- */ + if (changed) + config_save_safe(basicConfig, "tmp", nullptr); + + /* ----------------------------------------------------- */ + config_set_default_string(basicConfig, "Output", "Mode", "Simple"); config_set_default_string(basicConfig, "SimpleOutput", "FilePath", @@ -1099,8 +1213,6 @@ bool OBSBasic::InitBasicConfigDefaults() "flv"); config_set_default_uint (basicConfig, "SimpleOutput", "VBitrate", 2500); - config_set_default_string(basicConfig, "SimpleOutput", "StreamEncoder", - SIMPLE_ENCODER_X264); config_set_default_uint (basicConfig, "SimpleOutput", "ABitrate", 160); config_set_default_bool (basicConfig, "SimpleOutput", "UseAdvanced", false); @@ -1108,10 +1220,10 @@ bool OBSBasic::InitBasicConfigDefaults() true); config_set_default_string(basicConfig, "SimpleOutput", "Preset", "veryfast"); + config_set_default_string(basicConfig, "SimpleOutput", "NVENCPreset", + "hq"); config_set_default_string(basicConfig, "SimpleOutput", "RecQuality", "Stream"); - config_set_default_string(basicConfig, "SimpleOutput", "RecEncoder", - SIMPLE_ENCODER_X264); config_set_default_bool(basicConfig, "SimpleOutput", "RecRB", false); config_set_default_int(basicConfig, "SimpleOutput", "RecRBTime", 20); config_set_default_int(basicConfig, "SimpleOutput", "RecRBSize", 512); @@ -1147,7 +1259,7 @@ bool OBSBasic::InitBasicConfigDefaults() config_set_default_bool (basicConfig, "AdvOut", "FFIgnoreCompat", false); config_set_default_uint (basicConfig, "AdvOut", "FFABitrate", 160); - config_set_default_uint (basicConfig, "AdvOut", "FFAudioTrack", 1); + config_set_default_uint (basicConfig, "AdvOut", "FFAudioMixes", 1); config_set_default_uint (basicConfig, "AdvOut", "Track1Bitrate", 160); config_set_default_uint (basicConfig, "AdvOut", "Track2Bitrate", 160); @@ -1235,9 +1347,25 @@ bool OBSBasic::InitBasicConfigDefaults() VOLUME_METER_DECAY_FAST); config_set_default_uint (basicConfig, "Audio", "PeakMeterType", 0); + CheckExistingCookieId(); + return true; } +extern bool EncoderAvailable(const char *encoder); + +void OBSBasic::InitBasicConfigDefaults2() +{ + bool oldEncDefaults = config_get_bool(App()->GlobalConfig(), + "General", "Pre23Defaults"); + bool useNV = EncoderAvailable("ffmpeg_nvenc") && !oldEncDefaults; + + config_set_default_string(basicConfig, "SimpleOutput", "StreamEncoder", + useNV ? SIMPLE_ENCODER_NVENC : SIMPLE_ENCODER_X264); + config_set_default_string(basicConfig, "SimpleOutput", "RecEncoder", + useNV ? SIMPLE_ENCODER_NVENC : SIMPLE_ENCODER_X264); +} + bool OBSBasic::InitBasicConfig() { ProfileScope("OBSBasic::InitBasicConfig"); @@ -1465,10 +1593,12 @@ void OBSBasic::OBSInit() blog(LOG_INFO, "---------------------------------"); obs_post_load_modules(); -#ifdef _WIN32 - create_browser_widget = obs_browser_init_panel(); +#ifdef BROWSER_AVAILABLE + cef = obs_browser_init_panel(); #endif + InitBasicConfigDefaults2(); + CheckForSimpleModeX264Fallback(); blog(LOG_INFO, STARTUP_SEPARATOR); @@ -1510,14 +1640,12 @@ void OBSBasic::OBSInit() SET_VISIBILITY("ShowStatusBar", toggleStatusBar); #undef SET_VISIBILITY -#ifndef __APPLE__ { ProfileScope("OBSBasic::Load"); disableSaving--; Load(savePath); disableSaving++; } -#endif TimedCheckForUpdates(); loaded = true; @@ -1539,9 +1667,7 @@ void OBSBasic::OBSInit() } #endif -#ifndef __APPLE__ RefreshSceneCollections(); -#endif RefreshProfiles(); disableSaving--; @@ -1573,6 +1699,10 @@ void OBSBasic::OBSInit() show(); #endif + /* setup stats dock */ + OBSBasicStats *statsDlg = new OBSBasicStats(statsDock, false); + statsDock->setWidget(statsDlg); + const char *dockStateStr = config_get_string(App()->GlobalConfig(), "BasicWindow", "DockState"); if (!dockStateStr) { @@ -1584,8 +1714,19 @@ void OBSBasic::OBSInit() on_resetUI_triggered(); } - config_set_default_bool(App()->GlobalConfig(), "BasicWindow", - "DocksLocked", true); + bool pre23Defaults = config_get_bool(App()->GlobalConfig(), + "General", "Pre23Defaults"); + if (pre23Defaults) { + bool resetDockLock23 = config_get_bool(App()->GlobalConfig(), + "General", "ResetDockLock23"); + if (!resetDockLock23) { + config_set_bool(App()->GlobalConfig(), + "General", "ResetDockLock23", true); + config_remove_value(App()->GlobalConfig(), + "BasicWindow", "DocksLocked"); + config_save_safe(App()->GlobalConfig(), "tmp", nullptr); + } + } bool docksLocked = config_get_bool(App()->GlobalConfig(), "BasicWindow", "DocksLocked"); @@ -1621,7 +1762,9 @@ void OBSBasic::OBSInit() msg); if (button == QMessageBox::Yes) { - on_autoConfigure_triggered(); + QMetaObject::invokeMethod(this, + "on_autoConfigure_triggered", + Qt::QueuedConnection); } else { msg = QTStr("Basic.FirstStartup.RunWizard.NoClicked"); OBSMessageBox::information(this, @@ -1644,6 +1787,8 @@ void OBSBasic::OBSInit() multiviewProjectorMenu = new QMenu(QTStr("MultiviewProjector")); ui->viewMenu->addMenu(multiviewProjectorMenu); + AddProjectorMenuMonitors(multiviewProjectorMenu, this, + SLOT(OpenMultiviewProjector())); connect(ui->viewMenu->menuAction(), &QAction::hovered, this, &OBSBasic::UpdateMultiviewProjectorMenu); ui->viewMenu->addAction(QTStr("MultiviewWindowed"), @@ -1660,28 +1805,12 @@ void OBSBasic::OBSInit() ui->actionCheckForUpdates = nullptr; #endif -#ifdef __APPLE__ - /* This is an incredibly unpleasant hack for macOS to isolate CEF - * initialization until after all tasks related to Qt startup and main - * window initialization have completed. There is a macOS-specific bug - * within either CEF and/or Qt that can cause a crash if both Qt and - * CEF are loading at the same time. - * - * CEF will typically load fine after about two iterations from this - * point, and all Qt tasks are typically fully completed after about - * four or five iterations, but to be "ultra" safe, an arbitrarily - * large number such as 10 is used. This hack is extremely unpleasant, - * but is worth doing instead of being forced to isolate the entire - * browser plugin in to a separate process as before. - * - * Again, this hack is specific to macOS only. Fortunately, on other - * operating systems, such issues do not occur. */ - QMetaObject::invokeMethod(this, "DeferredLoad", - Qt::QueuedConnection, - Q_ARG(QString, QT_UTF8(savePath)), - Q_ARG(int, 10)); -#else OnFirstLoad(); + +#ifdef __APPLE__ + QMetaObject::invokeMethod(this, "DeferredSysTrayLoad", + Qt::QueuedConnection, + Q_ARG(int, 10)); #endif } @@ -1690,9 +1819,9 @@ void OBSBasic::OnFirstLoad() if (api) api->on_event(OBS_FRONTEND_EVENT_FINISHED_LOADING); -#ifdef _WIN32 +#if defined(BROWSER_AVAILABLE) && defined(_WIN32) /* Attempt to load init screen if available */ - if (create_browser_widget) { + if (cef) { WhatsNewInfoThread *wnit = new WhatsNewInfoThread(); if (wnit) { connect(wnit, &WhatsNewInfoThread::Result, @@ -1704,22 +1833,19 @@ void OBSBasic::OnFirstLoad() } } #endif + + Auth::Load(); } -void OBSBasic::DeferredLoad(const QString &file, int requeueCount) +void OBSBasic::DeferredSysTrayLoad(int requeueCount) { if (--requeueCount > 0) { - QMetaObject::invokeMethod(this, "DeferredLoad", + QMetaObject::invokeMethod(this, "DeferredSysTrayLoad", Qt::QueuedConnection, - Q_ARG(QString, file), Q_ARG(int, requeueCount)); return; } - Load(QT_TO_UTF8(file)); - RefreshSceneCollections(); - OnFirstLoad(); - /* Minimizng to tray on initial startup does not work on mac * unless it is done in the deferred load */ SystemTray(true); @@ -1728,6 +1854,7 @@ void OBSBasic::DeferredLoad(const QString &file, int requeueCount) /* shows a "what's new" page on startup of new versions using CEF */ void OBSBasic::ReceivedIntroJson(const QString &text) { +#ifdef BROWSER_AVAILABLE #ifdef _WIN32 std::string err; Json json = Json::parse(QT_TO_UTF8(text), err); @@ -1781,7 +1908,7 @@ void OBSBasic::ReceivedIntroJson(const QString &text) #if OBS_RELEASE_CANDIDATE > 0 if (lastVersion < OBS_RELEASE_CANDIDATE_VER) { #else - if (lastVersion < LIBOBS_API_VER) { + if ((lastVersion & ~0xFFFF) < (LIBOBS_API_VER & ~0xFFFF)) { #endif config_set_int(App()->GlobalConfig(), "General", "InfoIncrement", -1); @@ -1798,32 +1925,49 @@ void OBSBasic::ReceivedIntroJson(const QString &text) config_set_int(App()->GlobalConfig(), "General", "InfoIncrement", info_increment); - QDialog dlg(this); - dlg.setWindowTitle("What's New"); - dlg.resize(700, 600); + /* Don't show What's New dialog for new users */ +#if !defined(OBS_RELEASE_CANDIDATE) || OBS_RELEASE_CANDIDATE == 0 + if (!lastVersion) { + return; + } +#endif + cef->init_browser(); + ExecuteFuncSafeBlock([] {cef->wait_for_browser_init();}); - QCefWidget *cefWidget = create_browser_widget(nullptr, info_url); + QDialog *dlg = new QDialog(this); + dlg->setAttribute(Qt::WA_DeleteOnClose, true); + dlg->setWindowTitle("What's New"); + dlg->resize(700, 600); + + Qt::WindowFlags flags = dlg->windowFlags(); + Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint; + dlg->setWindowFlags(flags & (~helpFlag)); + + QCefWidget *cefWidget = cef->create_widget(nullptr, info_url); if (!cefWidget) { return; } connect(cefWidget, SIGNAL(titleChanged(const QString &)), - &dlg, SLOT(setWindowTitle(const QString &))); + dlg, SLOT(setWindowTitle(const QString &))); QPushButton *close = new QPushButton(QTStr("Close")); connect(close, &QAbstractButton::clicked, - &dlg, &QDialog::accept); + dlg, &QDialog::accept); QHBoxLayout *bottomLayout = new QHBoxLayout(); bottomLayout->addStretch(); bottomLayout->addWidget(close); bottomLayout->addStretch(); - QVBoxLayout *topLayout = new QVBoxLayout(&dlg); + QVBoxLayout *topLayout = new QVBoxLayout(dlg); topLayout->addWidget(cefWidget); topLayout->addLayout(bottomLayout); - dlg.exec(); + dlg->show(); +#else + UNUSED_PARAMETER(text); +#endif #else UNUSED_PARAMETER(text); #endif @@ -1879,6 +2023,7 @@ void OBSBasic::InitHotkeys() t.apple_keypad_decimal = Str("Hotkeys.AppleKeypadDecimal"); t.apple_keypad_equal = Str("Hotkeys.AppleKeypadEqual"); t.mouse_num = Str("Hotkeys.MouseButton"); + t.escape = Str("Hotkeys.Escape"); obs_hotkeys_set_translations(&t); obs_hotkeys_set_audio_hotkeys_translations(Str("Mute"), Str("Unmute"), @@ -2014,6 +2159,19 @@ void OBSBasic::CreateHotkeys() this, this); LoadHotkeyPair(replayBufHotkeys, "OBSBasic.StartReplayBuffer", "OBSBasic.StopReplayBuffer"); + + togglePreviewHotkeys = obs_hotkey_pair_register_frontend( + "OBSBasic.EnablePreview", + Str("Basic.Main.PreviewConextMenu.Enable"), + "OBSBasic.DisablePreview", + Str("Basic.Main.Preview.Disable"), + MAKE_CALLBACK(!basic.previewEnabled, + basic.EnablePreview, "Enabling preview"), + MAKE_CALLBACK(basic.previewEnabled, + basic.DisablePreview, "Disabling preview"), + this, this); + LoadHotkeyPair(togglePreviewHotkeys, + "OBSBasic.EnablePreview", "OBSBasic.DisablePreview"); #undef MAKE_CALLBACK auto togglePreviewProgram = [] (void *data, obs_hotkey_id, @@ -2051,6 +2209,7 @@ void OBSBasic::ClearHotkeys() obs_hotkey_pair_unregister(streamingHotkeys); obs_hotkey_pair_unregister(recordingHotkeys); obs_hotkey_pair_unregister(replayBufHotkeys); + obs_hotkey_pair_unregister(togglePreviewHotkeys); obs_hotkey_unregister(forceStreamingStopHotkey); obs_hotkey_unregister(togglePreviewProgramHotkey); obs_hotkey_unregister(transitionHotkey); @@ -2062,6 +2221,19 @@ OBSBasic::~OBSBasic() updateCheckThread->wait(); delete multiviewProjectorMenu; + delete previewProjector; + delete studioProgramProjector; + delete previewProjectorSource; + delete previewProjectorMain; + delete sourceProjector; + delete sceneProjectorMenu; + delete scaleFilteringMenu; + delete colorMenu; + delete colorWidgetAction; + delete colorSelect; + delete deinterlaceMenu; + delete perSceneTransitionMenu; + delete shortcutFilter; delete trayMenu; delete programOptions; delete program; @@ -2096,6 +2268,9 @@ OBSBasic::~OBSBasic() if (advAudioWindow) delete advAudioWindow; + if (about) + delete about; + obs_display_remove_draw_callback(ui->preview->GetDisplay(), OBSBasic::RenderMain, this); @@ -2152,6 +2327,12 @@ OBSBasic::~OBSBasic() } } #endif + +#ifdef BROWSER_AVAILABLE + DestroyPanelCookieManager(); + delete cef; + cef = nullptr; +#endif } void OBSBasic::SaveProjectNow() @@ -2587,7 +2768,7 @@ void OBSBasic::MixerRenameSource() return; if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); continue; @@ -2597,7 +2778,7 @@ void OBSBasic::MixerRenameSource() obs_source_release(sourceTest); if (sourceTest) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); continue; @@ -2618,6 +2799,9 @@ void OBSBasic::VolControlContextMenu() QAction unhideAllAction(QTStr("UnhideAll"), this); QAction mixerRenameAction(QTStr("Rename"), this); + QAction copyFiltersAction(QTStr("Copy.Filters"), this); + QAction pasteFiltersAction(QTStr("Paste.Filters"), this); + QAction filtersAction(QTStr("Filters"), this); QAction propertiesAction(QTStr("Properties"), this); QAction advPropAction(QTStr("Basic.MainMenu.Edit.AdvAudio"), this); @@ -2639,6 +2823,13 @@ void OBSBasic::VolControlContextMenu() this, &OBSBasic::MixerRenameSource, Qt::DirectConnection); + connect(©FiltersAction, &QAction::triggered, + this, &OBSBasic::AudioMixerCopyFilters, + Qt::DirectConnection); + connect(&pasteFiltersAction, &QAction::triggered, + this, &OBSBasic::AudioMixerPasteFilters, + Qt::DirectConnection); + connect(&filtersAction, &QAction::triggered, this, &OBSBasic::GetAudioSourceFilters, Qt::DirectConnection); @@ -2662,6 +2853,11 @@ void OBSBasic::VolControlContextMenu() mixerRenameAction.setProperty("volControl", QVariant::fromValue(vol)); + copyFiltersAction.setProperty("volControl", + QVariant::fromValue(vol)); + pasteFiltersAction.setProperty("volControl", + QVariant::fromValue(vol)); + filtersAction.setProperty("volControl", QVariant::fromValue(vol)); propertiesAction.setProperty("volControl", @@ -2669,11 +2865,19 @@ void OBSBasic::VolControlContextMenu() /* ------------------- */ + if (copyFiltersString == nullptr) + pasteFiltersAction.setEnabled(false); + else + pasteFiltersAction.setEnabled(true); + QMenu popup; popup.addAction(&unhideAllAction); popup.addAction(&hideAction); popup.addAction(&mixerRenameAction); popup.addSeparator(); + popup.addAction(©FiltersAction); + popup.addAction(&pasteFiltersAction); + popup.addSeparator(); popup.addAction(&toggleControlLayoutAction); popup.addSeparator(); popup.addAction(&filtersAction); @@ -2939,7 +3143,7 @@ void OBSBasic::DuplicateSelectedScene() return; if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); continue; @@ -2947,7 +3151,7 @@ void OBSBasic::DuplicateSelectedScene() obs_source_t *source = obs_get_source_by_name(name.c_str()); if (source) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); @@ -3107,6 +3311,8 @@ void OBSBasic::DrawBackdrop(float cx, float cy) if (!box) return; + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawBackdrop"); + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color"); gs_technique_t *tech = gs_effect_get_technique(solid, "Solid"); @@ -3129,10 +3335,14 @@ void OBSBasic::DrawBackdrop(float cx, float cy) gs_technique_end(tech); gs_load_vertexbuffer(nullptr); + + GS_DEBUG_MARKER_END(); } void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) { + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderMain"); + OBSBasic *window = static_cast(data); obs_video_info ovi; @@ -3144,6 +3354,18 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) gs_viewport_push(); gs_projection_push(); + obs_display_t *display = window->ui->preview->GetDisplay(); + uint32_t width, height; + obs_display_size(display, &width, &height); + float right = float(width) - window->previewX; + float bottom = float(height) - window->previewY; + + gs_ortho(-window->previewX, right, + -window->previewY, bottom, + -100.0f, 100.0f); + + window->ui->preview->DrawOverflow(); + /* --------------------------------------- */ gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height), @@ -3165,9 +3387,6 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) /* --------------------------------------- */ - QSize previewSize = GetPixelSize(window->ui->preview); - float right = float(previewSize.width()) - window->previewX; - float bottom = float(previewSize.height()) - window->previewY; gs_ortho(-window->previewX, right, -window->previewY, bottom, @@ -3181,6 +3400,8 @@ void OBSBasic::RenderMain(void *data, uint32_t cx, uint32_t cy) gs_projection_pop(); gs_viewport_pop(); + GS_DEBUG_MARKER_END(); + UNUSED_PARAMETER(cx); UNUSED_PARAMETER(cy); } @@ -3203,6 +3424,11 @@ void OBSBasic::SetService(obs_service_t *newService) service = newService; } +int OBSBasic::GetTransitionDuration() +{ + return ui->transitionDuration->value(); +} + bool OBSBasic::StreamingActive() const { if (!outputHandler) @@ -3266,10 +3492,19 @@ void OBSBasic::ResetUI() bool studioPortraitLayout = config_get_bool(GetGlobalConfig(), "BasicWindow", "StudioPortraitLayout"); + bool labels = config_get_bool(GetGlobalConfig(), + "BasicWindow", "StudioModeLabels"); + if (studioPortraitLayout) ui->previewLayout->setDirection(QBoxLayout::TopToBottom); else ui->previewLayout->setDirection(QBoxLayout::LeftToRight); + + if (previewProgramMode) + ui->previewLabel->setHidden(!labels); + + if (programLabel) + programLabel->setHidden(!labels); } int OBSBasic::ResetVideo() @@ -3543,15 +3778,20 @@ void OBSBasic::ClearSceneData() void OBSBasic::closeEvent(QCloseEvent *event) { + /* Do not close window if inside of a temporary event loop because we + * could be inside of an Auth::LoadUI call. Keep trying once per + * second until we've exit any known sub-loops. */ + if (os_atomic_load_long(&insideEventLoop) != 0) { + QTimer::singleShot(1000, this, SLOT(close())); + event->ignore(); + return; + } + if (isVisible()) config_set_string(App()->GlobalConfig(), "BasicWindow", "geometry", saveGeometry().toBase64().constData()); - config_set_string(App()->GlobalConfig(), - "BasicWindow", "DockState", - saveState().toBase64().constData()); - if (outputHandler && outputHandler->Active()) { SetShowing(true); @@ -3580,7 +3820,13 @@ void OBSBasic::closeEvent(QCloseEvent *event) signalHandlers.clear(); + Auth::Save(); SaveProjectNow(); + auth.reset(); + + config_set_string(App()->GlobalConfig(), + "BasicWindow", "DockState", + saveState().toBase64().constData()); if (api) api->on_event(OBS_FRONTEND_EVENT_EXIT); @@ -3640,9 +3886,28 @@ void OBSBasic::on_actionRemux_triggered() void OBSBasic::on_action_Settings_triggered() { + static bool settings_already_executing = false; + + /* Do not load settings window if inside of a temporary event loop + * because we could be inside of an Auth::LoadUI call. Keep trying + * once per second until we've exit any known sub-loops. */ + if (os_atomic_load_long(&insideEventLoop) != 0) { + QTimer::singleShot(1000, this, + SLOT(on_action_Settings_triggered())); + return; + } + + if (settings_already_executing) { + return; + } + + settings_already_executing = true; + OBSBasicSettings settings(this); settings.exec(); SystemTray(false); + + settings_already_executing = false; } void OBSBasic::on_actionAdvAudioProperties_triggered() @@ -3712,7 +3977,7 @@ static void AddProjectorMenuMonitors(QMenu *parent, QObject *target, QRect screenGeometry = screens[i]->geometry(); QString str = QString("%1 %2: %3x%4 @ %5,%6"). arg(QTStr("Display"), - QString::number(i), + QString::number(i + 1), QString::number(screenGeometry.width()), QString::number(screenGeometry.height()), QString::number(screenGeometry.x()), @@ -3726,7 +3991,6 @@ static void AddProjectorMenuMonitors(QMenu *parent, QObject *target, void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) { QListWidgetItem *item = ui->scenes->itemAt(pos); - QPointer sceneProjectorMenu; QMenu popup(this); QMenu order(QTStr("Basic.MainMenu.Edit.Order"), this); @@ -3734,9 +3998,19 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) this, SLOT(on_actionAddScene_triggered())); if (item) { + QAction *pasteFilters = new QAction( + QTStr("Paste.Filters"), this); + pasteFilters->setEnabled(copyFiltersString); + connect(pasteFilters, SIGNAL(triggered()), this, + SLOT(ScenePasteFilters())); + popup.addSeparator(); popup.addAction(QTStr("Duplicate"), this, SLOT(DuplicateSelectedScene())); + popup.addAction(QTStr("Copy.Filters"), + this, SLOT(SceneCopyFilters())); + popup.addAction(pasteFilters); + popup.addSeparator(); popup.addAction(QTStr("Rename"), this, SLOT(EditSceneName())); popup.addAction(QTStr("Remove"), @@ -3756,6 +4030,7 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) popup.addSeparator(); + delete sceneProjectorMenu; sceneProjectorMenu = new QMenu(QTStr("SceneProjector")); AddProjectorMenuMonitors(sceneProjectorMenu, this, SLOT(OpenSceneProjector())); @@ -3772,8 +4047,9 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos) popup.addSeparator(); - QMenu *transitionMenu = CreatePerSceneTransitionMenu(); - popup.addMenu(transitionMenu); + delete perSceneTransitionMenu; + perSceneTransitionMenu = CreatePerSceneTransitionMenu(); + popup.addMenu(perSceneTransitionMenu); /* ---------------------- */ @@ -3828,7 +4104,7 @@ void OBSBasic::on_actionAddScene_triggered() if (accepted) { if (name.empty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); on_actionAddScene_triggered(); @@ -3837,7 +4113,7 @@ void OBSBasic::on_actionAddScene_triggered() obs_source_t *source = obs_get_source_by_name(name.c_str()); if (source) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NameExists.Title"), QTStr("NameExists.Text")); @@ -3933,9 +4209,8 @@ void OBSBasic::SetDeinterlacingOrder() obs_source_set_deinterlace_field_order(source, order); } -QMenu *OBSBasic::AddDeinterlacingMenu(obs_source_t *source) +QMenu *OBSBasic::AddDeinterlacingMenu(QMenu *menu, obs_source_t *source) { - QMenu *menu = new QMenu(QTStr("Deinterlacing")); obs_deinterlace_mode deinterlaceMode = obs_source_get_deinterlace_mode(source); obs_deinterlace_field_order deinterlaceOrder = @@ -3985,9 +4260,8 @@ void OBSBasic::SetScaleFilter() obs_sceneitem_set_scale_filter(sceneItem, mode); } -QMenu *OBSBasic::AddScaleFilteringMenu(obs_sceneitem_t *item) +QMenu *OBSBasic::AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item) { - QMenu *menu = new QMenu(QTStr("ScaleFiltering")); obs_scale_type scaleFilter = obs_sceneitem_get_scale_filter(item); QAction *action; @@ -4003,14 +4277,15 @@ QMenu *OBSBasic::AddScaleFilteringMenu(obs_sceneitem_t *item) ADD_MODE("ScaleFiltering.Bilinear", OBS_SCALE_BILINEAR); ADD_MODE("ScaleFiltering.Bicubic", OBS_SCALE_BICUBIC); ADD_MODE("ScaleFiltering.Lanczos", OBS_SCALE_LANCZOS); + ADD_MODE("ScaleFiltering.Area", OBS_SCALE_AREA); #undef ADD_MODE return menu; } -QMenu *OBSBasic::AddBackgroundColorMenu(obs_sceneitem_t *item) +QMenu *OBSBasic::AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, + ColorSelect *select, obs_sceneitem_t *item) { - QMenu *menu = new QMenu(QTStr("ChangeBG")); QAction *action; menu->setStyleSheet(QString( @@ -4043,8 +4318,6 @@ QMenu *OBSBasic::AddBackgroundColorMenu(obs_sceneitem_t *item) menu->addSeparator(); - QWidgetAction *widgetAction = new QWidgetAction(menu); - ColorSelect *select = new ColorSelect(menu); widgetAction->setDefaultWidget(select); for (int i = 1; i < 9; i++) { @@ -4065,11 +4338,23 @@ QMenu *OBSBasic::AddBackgroundColorMenu(obs_sceneitem_t *item) return menu; } +ColorSelect::ColorSelect(QWidget *parent) + : QWidget(parent), + ui(new Ui::ColorSelect) +{ + ui->setupUi(this); +} + void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) { QMenu popup(this); - QPointer previewProjector; - QPointer sourceProjector; + delete previewProjectorSource; + delete sourceProjector; + delete scaleFilteringMenu; + delete colorMenu; + delete colorWidgetAction; + delete colorSelect; + delete deinterlaceMenu; if (preview) { QAction *action = popup.addAction( @@ -4084,11 +4369,11 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) popup.addAction(ui->actionLockPreview); popup.addMenu(ui->scalingMenu); - previewProjector = new QMenu(QTStr("PreviewProjector")); - AddProjectorMenuMonitors(previewProjector, this, + previewProjectorSource = new QMenu(QTStr("PreviewProjector")); + AddProjectorMenuMonitors(previewProjectorSource, this, SLOT(OpenPreviewProjector())); - popup.addMenu(previewProjector); + popup.addMenu(previewProjectorSource); QAction *previewWindow = popup.addAction( QTStr("PreviewWindow"), @@ -4141,7 +4426,11 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) OBS_SOURCE_AUDIO; QAction *action; - popup.addMenu(AddBackgroundColorMenu(sceneItem)); + colorMenu = new QMenu(QTStr("ChangeBG")); + colorWidgetAction = new QWidgetAction(colorMenu); + colorSelect = new ColorSelect(colorMenu); + popup.addMenu(AddBackgroundColorMenu(colorMenu, + colorWidgetAction, colorSelect, sceneItem)); popup.addAction(QTStr("Rename"), this, SLOT(EditSceneItemName())); popup.addAction(QTStr("Remove"), this, @@ -4171,11 +4460,25 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview) } if (isAsyncVideo) { - popup.addMenu(AddDeinterlacingMenu(source)); + deinterlaceMenu = new QMenu(QTStr("Deinterlacing")); + popup.addMenu(AddDeinterlacingMenu(deinterlaceMenu, source)); popup.addSeparator(); } - popup.addMenu(AddScaleFilteringMenu(sceneItem)); + QAction *resizeOutput = popup.addAction( + QTStr("ResizeOutputSizeOfSource"), this, + SLOT(ResizeOutputSizeOfSource())); + + int width = obs_source_get_width(source); + int height = obs_source_get_height(source); + + resizeOutput->setEnabled(!obs_video_active()); + + if (width == 0 || height == 0) + resizeOutput->setEnabled(false); + + scaleFilteringMenu = new QMenu(QTStr("ScaleFiltering")); + popup.addMenu(AddScaleFilteringMenu(scaleFilteringMenu, sceneItem)); popup.addSeparator(); popup.addMenu(sourceProjector); @@ -4561,7 +4864,7 @@ void OBSBasic::logUploadFinished(const QString &text, const QString &error) ui->menuLogFiles->setEnabled(true); if (text.isEmpty()) { - OBSMessageBox::information(this, + OBSMessageBox::critical(this, QTStr("LogReturnDialog.ErrorUploadingLog"), error); return; @@ -4590,11 +4893,11 @@ static void RenameListItem(OBSBasic *parent, QListWidget *listWidget, listItem->setText(QT_UTF8(prevName)); if (foundSource) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NameExists.Title"), QTStr("NameExists.Text")); } else if (name.empty()) { - OBSMessageBox::information(parent, + OBSMessageBox::warning(parent, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); } @@ -4675,6 +4978,9 @@ void OBSBasic::StartStreaming() } if (!outputHandler->StartStreaming(service)) { + QString message = !outputHandler->lastError.empty() + ? QTStr(outputHandler->lastError.c_str()) + : QTStr("Output.StartFailedGeneric"); ui->streamButton->setText(QTStr("Basic.Main.StartStreaming")); ui->streamButton->setEnabled(true); ui->streamButton->setChecked(false); @@ -4684,9 +4990,8 @@ void OBSBasic::StartStreaming() sysTrayStream->setEnabled(true); } - QMessageBox::critical(this, - QTStr("Output.StartStreamFailed"), - QTStr("Output.StartFailedGeneric")); + QMessageBox::critical(this, QTStr("Output.StartStreamFailed"), + message); return; } @@ -4731,7 +5036,8 @@ inline void OBSBasic::OnActivate() UpdateProcessPriority(); if (trayIcon) - trayIcon->setIcon(QIcon(":/res/images/tray_active.png")); + trayIcon->setIcon(QIcon::fromTheme("obs-tray-active", + QIcon(":/res/images/tray_active.png"))); } } @@ -4744,7 +5050,8 @@ inline void OBSBasic::OnDeactivate() ClearProcessPriority(); if (trayIcon) - trayIcon->setIcon(QIcon(":/res/images/obs.png")); + trayIcon->setIcon(QIcon::fromTheme("obs-tray", + QIcon(":/res/images/obs.png"))); } } @@ -4844,6 +5151,9 @@ void OBSBasic::StreamDelayStopping(int sec) ui->streamButton->setMenu(startStreamMenu); ui->statusbar->StreamDelayStopping(sec); + + if (api) + api->on_event(OBS_FRONTEND_EVENT_STREAMING_STOPPING); } void OBSBasic::StreamingStart() @@ -4880,9 +5190,10 @@ void OBSBasic::StreamStopping() void OBSBasic::StreamingStop(int code, QString last_error) { - const char *errorDescription; + const char *errorDescription = ""; DStr errorMessage; bool use_last_error = false; + bool encode_error = false; switch (code) { case OBS_OUTPUT_BAD_PATH: @@ -4898,6 +5209,10 @@ void OBSBasic::StreamingStop(int code, QString last_error) errorDescription = Str("Output.ConnectFail.InvalidStream"); break; + case OBS_OUTPUT_ENCODE_ERROR: + encode_error = true; + break; + default: case OBS_OUTPUT_ERROR: use_last_error = true; @@ -4936,10 +5251,16 @@ void OBSBasic::StreamingStop(int code, QString last_error) blog(LOG_INFO, STREAMING_STOP); - if (code != OBS_OUTPUT_SUCCESS && isVisible()) { + if (encode_error) { + OBSMessageBox::information(this, + QTStr("Output.StreamEncodeError.Title"), + QTStr("Output.StreamEncodeError.Msg")); + + } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { OBSMessageBox::information(this, QTStr("Output.ConnectFail.Title"), QT_UTF8(errorMessage)); + } else if (code != OBS_OUTPUT_SUCCESS && !isVisible()) { SysTrayNotify(QT_UTF8(errorDescription), QSystemTrayIcon::Warning); } @@ -4951,6 +5272,47 @@ void OBSBasic::StreamingStop(int code, QString last_error) } } +void OBSBasic::AutoRemux() +{ + const char *mode = config_get_string(basicConfig, "Output", "Mode"); + bool advanced = astrcmpi(mode, "Advanced") == 0; + + const char *path = !advanced + ? config_get_string(basicConfig, "SimpleOutput", "FilePath") + : config_get_string(basicConfig, "AdvOut", "RecFilePath"); + + /* do not save if using FFmpeg output in advanced output mode */ + if (advanced) { + const char *type = config_get_string(basicConfig, "AdvOut", + "RecType"); + if (astrcmpi(type, "FFmpeg") == 0) { + return; + } + } + + QString input; + input += path; + input += "/"; + input += remuxFilename.c_str(); + + QFileInfo fi(remuxFilename.c_str()); + + /* do not remux if lossless */ + if (fi.suffix().compare("avi", Qt::CaseInsensitive) == 0) { + return; + } + + QString output; + output += path; + output += "/"; + output += fi.completeBaseName(); + output += ".mp4"; + + OBSRemux *remux = new OBSRemux(path, this, true); + remux->show(); + remux->AutoRemux(input, output); +} + void OBSBasic::StartRecording() { if (outputHandler->RecordingActive()) @@ -5007,7 +5369,7 @@ void OBSBasic::RecordingStart() blog(LOG_INFO, RECORDING_START); } -void OBSBasic::RecordingStop(int code) +void OBSBasic::RecordingStop(int code, QString last_error) { ui->statusbar->RecordingStopped(); ui->recordButton->setText(QTStr("Basic.Main.StartRecording")); @@ -5019,19 +5381,37 @@ void OBSBasic::RecordingStop(int code) blog(LOG_INFO, RECORDING_STOP); if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) { - OBSMessageBox::information(this, + OBSMessageBox::critical(this, QTStr("Output.RecordFail.Title"), QTStr("Output.RecordFail.Unsupported")); + } else if (code == OBS_OUTPUT_ENCODE_ERROR && isVisible()) { + OBSMessageBox::warning(this, + QTStr("Output.RecordError.Title"), + QTStr("Output.RecordError.EncodeErrorMsg")); + } else if (code == OBS_OUTPUT_NO_SPACE && isVisible()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("Output.RecordNoSpace.Title"), QTStr("Output.RecordNoSpace.Msg")); } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { - OBSMessageBox::information(this, + + const char *errorDescription; + DStr errorMessage; + bool use_last_error = true; + + errorDescription = Str("Output.RecordError.Msg"); + + if (use_last_error && !last_error.isEmpty()) + dstr_printf(errorMessage, "%s\n\n%s", errorDescription, + QT_TO_UTF8(last_error)); + else + dstr_copy(errorMessage, errorDescription); + + OBSMessageBox::critical(this, QTStr("Output.RecordError.Title"), - QTStr("Output.RecordError.Msg")); + QT_UTF8(errorMessage)); } else if (code == OBS_OUTPUT_UNSUPPORTED && !isVisible()) { SysTrayNotify(QTStr("Output.RecordFail.Unsupported"), @@ -5049,6 +5429,9 @@ void OBSBasic::RecordingStop(int code) if (api) api->on_event(OBS_FRONTEND_EVENT_RECORDING_STOPPED); + if (remuxAfterRecord) + AutoRemux(); + OnDeactivate(); } @@ -5081,6 +5464,7 @@ void OBSBasic::StartReplayBuffer() OBSMessageBox::information(this, RP_NO_HOTKEY_TITLE, RP_NO_HOTKEY_TEXT); + replayBufferButton->setChecked(false); return; } @@ -5126,6 +5510,7 @@ void OBSBasic::ReplayBufferStart() return; replayBufferButton->setText(QTStr("Basic.Main.StopReplayBuffer")); + replayBufferButton->setChecked(true); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText(replayBufferButton->text()); @@ -5159,6 +5544,7 @@ void OBSBasic::ReplayBufferStop(int code) return; replayBufferButton->setText(QTStr("Basic.Main.StartReplayBuffer")); + replayBufferButton->setChecked(false); if (sysTrayReplayBuffer) sysTrayReplayBuffer->setText(replayBufferButton->text()); @@ -5166,17 +5552,17 @@ void OBSBasic::ReplayBufferStop(int code) blog(LOG_INFO, REPLAY_BUFFER_STOP); if (code == OBS_OUTPUT_UNSUPPORTED && isVisible()) { - OBSMessageBox::information(this, + OBSMessageBox::critical(this, QTStr("Output.RecordFail.Title"), QTStr("Output.RecordFail.Unsupported")); } else if (code == OBS_OUTPUT_NO_SPACE && isVisible()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("Output.RecordNoSpace.Title"), QTStr("Output.RecordNoSpace.Msg")); } else if (code != OBS_OUTPUT_SUCCESS && isVisible()) { - OBSMessageBox::information(this, + OBSMessageBox::critical(this, QTStr("Output.RecordError.Title"), QTStr("Output.RecordError.Msg")); @@ -5207,14 +5593,16 @@ bool OBSBasic::NoSourcesConfirmation() msg += "\n\n"; msg += QTStr("NoSources.Text.AddSource"); - QMessageBox messageBox(QMessageBox::Question, - QTStr("NoSources.title"), - msg, - QMessageBox::Yes | QMessageBox::No, - this); - messageBox.setDefaultButton(QMessageBox::No); + QMessageBox messageBox(this); + messageBox.setWindowTitle(QTStr("NoSources.Title")); + messageBox.setText(msg); + QAbstractButton *Yes = messageBox.addButton(QTStr("Yes"), + QMessageBox::YesRole); + messageBox.addButton(QTStr("No"), QMessageBox::NoRole); + messageBox.setIcon(QMessageBox::Question); + messageBox.exec(); - if (QMessageBox::No == messageBox.exec()) + if (messageBox.clickedButton() != Yes) return false; } @@ -5249,7 +5637,21 @@ void OBSBasic::on_streamButton_clicked() bool confirm = config_get_bool(GetGlobalConfig(), "BasicWindow", "WarnBeforeStartingStream"); - if (confirm && isVisible()) { + obs_data_t *settings = obs_service_get_settings(service); + bool bwtest = obs_data_get_bool(settings, "bwtest"); + obs_data_release(settings); + + if (bwtest && isVisible()) { + QMessageBox::StandardButton button = + OBSMessageBox::question(this, + QTStr("ConfirmBWTest.Title"), + QTStr("ConfirmBWTest.Text")); + + if (button == QMessageBox::No) { + ui->streamButton->setChecked(false); + return; + } + } else if (confirm && isVisible()) { QMessageBox::StandardButton button = OBSMessageBox::question(this, QTStr("ConfirmStart.Title"), @@ -5361,7 +5763,7 @@ void OBSBasic::on_previewDisabledLabel_customContextMenuRequested( const QPoint &pos) { QMenu popup(this); - QPointer previewProjector; + delete previewProjectorMain; QAction *action = popup.addAction( QTStr("Basic.Main.PreviewConextMenu.Enable"), @@ -5369,15 +5771,15 @@ void OBSBasic::on_previewDisabledLabel_customContextMenuRequested( action->setCheckable(true); action->setChecked(obs_display_enabled(ui->preview->GetDisplay())); - previewProjector = new QMenu(QTStr("PreviewProjector")); - AddProjectorMenuMonitors(previewProjector, this, + previewProjectorMain = new QMenu(QTStr("PreviewProjector")); + AddProjectorMenuMonitors(previewProjectorMain, this, SLOT(OpenPreviewProjector())); QAction *previewWindow = popup.addAction( QTStr("PreviewWindow"), this, SLOT(OpenPreviewWindow())); - popup.addMenu(previewProjector); + popup.addMenu(previewProjectorMain); popup.addAction(previewWindow); popup.exec(QCursor::pos()); @@ -5421,7 +5823,7 @@ void OBSBasic::GetFPSCommon(uint32_t &num, uint32_t &den) const } else if (strcmp(val, "24 NTSC") == 0) { num = 24000; den = 1001; - } else if (strcmp(val, "25") == 0) { + } else if (strcmp(val, "25 PAL") == 0) { num = 25; den = 1; } else if (strcmp(val, "29.97") == 0) { @@ -5430,6 +5832,9 @@ void OBSBasic::GetFPSCommon(uint32_t &num, uint32_t &den) const } else if (strcmp(val, "48") == 0) { num = 48; den = 1; + } else if (strcmp(val, "50 PAL") == 0) { + num = 50; + den = 1; } else if (strcmp(val, "59.94") == 0) { num = 60000; den = 1001; @@ -5740,20 +6145,39 @@ void OBSBasic::on_actionStretchToScreen_triggered() &boundsType); } -static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *) +enum class CenterType { + Scene, + Vertical, + Horizontal +}; + +static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *param) { + CenterType centerType = *reinterpret_cast(param); + vec3 tl, br, itemCenter, screenCenter, offset; obs_video_info ovi; + obs_transform_info oti; if (obs_sceneitem_is_group(item)) - obs_sceneitem_group_enum_items(item, center_to_scene, nullptr); + obs_sceneitem_group_enum_items(item, center_to_scene, + ¢erType); if (!obs_sceneitem_selected(item)) return true; obs_get_video_info(&ovi); + obs_sceneitem_get_info(item, &oti); + + if (centerType == CenterType::Scene) + vec3_set(&screenCenter, float(ovi.base_width), + float(ovi.base_height), 0.0f); + else if (centerType == CenterType::Vertical) + vec3_set(&screenCenter, float(oti.bounds.x), + float(ovi.base_height), 0.0f); + else if (centerType == CenterType::Horizontal) + vec3_set(&screenCenter, float(ovi.base_width), + float(oti.bounds.y), 0.0f); - vec3_set(&screenCenter, float(ovi.base_width), - float(ovi.base_height), 0.0f); vec3_mulf(&screenCenter, &screenCenter, 0.5f); GetItemBox(item, tl, br); @@ -5765,13 +6189,31 @@ static bool center_to_scene(obs_scene_t *, obs_sceneitem_t *item, void *) vec3_sub(&offset, &screenCenter, &itemCenter); vec3_add(&tl, &tl, &offset); + if (centerType == CenterType::Vertical) + tl.x = oti.pos.x; + else if (centerType == CenterType::Horizontal) + tl.y = oti.pos.y; + SetItemTL(item, tl); return true; }; void OBSBasic::on_actionCenterToScreen_triggered() { - obs_scene_enum_items(GetCurrentScene(), center_to_scene, nullptr); + CenterType centerType = CenterType::Scene; + obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType); +} + +void OBSBasic::on_actionVerticalCenter_triggered() +{ + CenterType centerType = CenterType::Vertical; + obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType); +} + +void OBSBasic::on_actionHorizontalCenter_triggered() +{ + CenterType centerType = CenterType::Horizontal; + obs_scene_enum_items(GetCurrentScene(), center_to_scene, ¢erType); } void OBSBasic::EnablePreviewDisplay(bool enable) @@ -5787,6 +6229,24 @@ void OBSBasic::TogglePreview() EnablePreviewDisplay(previewEnabled); } +void OBSBasic::EnablePreview() +{ + if (previewProgramMode) + return; + + previewEnabled = true; + EnablePreviewDisplay(true); +} + +void OBSBasic::DisablePreview() +{ + if (previewProgramMode) + return; + + previewEnabled = false; + EnablePreviewDisplay(false); +} + static bool nudge_callback(obs_scene_t*, obs_sceneitem_t *item, void *param) { if (obs_sceneitem_locked(item)) @@ -6001,7 +6461,7 @@ void OBSBasic::OpenSavedProjectors() } } - if (projector && !info->geometry.empty()) { + if (projector && !info->geometry.empty() && info->monitor < 0) { QByteArray byteArray = QByteArray::fromBase64( QByteArray(info->geometry.c_str())); projector->restoreGeometry(byteArray); @@ -6075,6 +6535,36 @@ int OBSBasic::GetProfilePath(char *path, size_t size, const char *file) const void OBSBasic::on_resetUI_triggered() { + /* prune deleted extra docks */ + for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + if (!extraDocks[i]) { + extraDocks.removeAt(i); + } + } + + if (extraDocks.size()) { + QMessageBox::StandardButton button = QMessageBox::question( + this, + QTStr("ResetUIWarning.Title"), + QTStr("ResetUIWarning.Text")); + + if (button == QMessageBox::No) + return; + } + + /* undock/hide/center extra docks */ + for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + if (extraDocks[i]) { + extraDocks[i]->setVisible(true); + extraDocks[i]->setFloating(true); + extraDocks[i]->move( + frameGeometry().topLeft() + + rect().center() - + extraDocks[i]->rect().center()); + extraDocks[i]->setVisible(false); + } + } + restoreState(startingDockLayout); #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) @@ -6109,6 +6599,8 @@ void OBSBasic::on_resetUI_triggered() ui->mixerDock->setVisible(true); ui->transitionsDock->setVisible(true); ui->controlsDock->setVisible(true); + statsDock->setVisible(false); + statsDock->setFloating(true); resizeDocks(docks, {cy, cy, cy, cy, cy}, Qt::Vertical); resizeDocks(docks, sizes, Qt::Horizontal); @@ -6121,11 +6613,23 @@ void OBSBasic::on_lockUI_toggled(bool lock) ? QDockWidget::NoDockWidgetFeatures : QDockWidget::AllDockWidgetFeatures; - ui->scenesDock->setFeatures(features); - ui->sourcesDock->setFeatures(features); - ui->mixerDock->setFeatures(features); - ui->transitionsDock->setFeatures(features); - ui->controlsDock->setFeatures(features); + QDockWidget::DockWidgetFeatures mainFeatures = features; + mainFeatures &= ~QDockWidget::QDockWidget::DockWidgetClosable; + + ui->scenesDock->setFeatures(mainFeatures); + ui->sourcesDock->setFeatures(mainFeatures); + ui->mixerDock->setFeatures(mainFeatures); + ui->transitionsDock->setFeatures(mainFeatures); + ui->controlsDock->setFeatures(mainFeatures); + statsDock->setFeatures(features); + + for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + if (!extraDocks[i]) { + extraDocks.removeAt(i); + } else { + extraDocks[i]->setFeatures(features); + } + } } void OBSBasic::on_toggleListboxToolbars_toggled(bool visible) @@ -6283,8 +6787,8 @@ void OBSBasic::ToggleShowHide() void OBSBasic::SystemTrayInit() { - trayIcon.reset(new QSystemTrayIcon(QIcon(":/res/images/obs.png"), - this)); + trayIcon.reset(new QSystemTrayIcon(QIcon::fromTheme("obs-tray", + QIcon(":/res/images/obs.png")), this)); trayIcon->setToolTip("OBS Studio"); showHide = new QAction(QTStr("Basic.SystemTray.Show"), @@ -6298,6 +6802,23 @@ void OBSBasic::SystemTrayInit() exit = new QAction(QTStr("Exit"), trayIcon.data()); + trayMenu = new QMenu; + previewProjector = new QMenu(QTStr("PreviewProjector")); + studioProgramProjector = new QMenu(QTStr("StudioProgramProjector")); + AddProjectorMenuMonitors(previewProjector, this, + SLOT(OpenPreviewProjector())); + AddProjectorMenuMonitors(studioProgramProjector, this, + SLOT(OpenStudioProgramProjector())); + trayMenu->addAction(showHide); + trayMenu->addMenu(previewProjector); + trayMenu->addMenu(studioProgramProjector); + trayMenu->addAction(sysTrayStream); + trayMenu->addAction(sysTrayRecord); + trayMenu->addAction(sysTrayReplayBuffer); + trayMenu->addAction(exit); + trayIcon->setContextMenu(trayMenu); + trayIcon->show(); + if (outputHandler && !outputHandler->replayBuffer) sysTrayReplayBuffer->setEnabled(false); @@ -6315,39 +6836,26 @@ void OBSBasic::SystemTrayInit() this, &OBSBasic::ReplayBufferClicked); connect(exit, SIGNAL(triggered()), this, SLOT(close())); - - trayMenu = new QMenu; } void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger) { - ToggleShowHide(); - } else if (reason == QSystemTrayIcon::Context) { - QMenu *previewProjector = new QMenu(QTStr("PreviewProjector")); - AddProjectorMenuMonitors(previewProjector, this, - SLOT(OpenPreviewProjector())); - QMenu *studioProgramProjector = new QMenu( - QTStr("StudioProgramProjector")); - AddProjectorMenuMonitors(studioProgramProjector, this, - SLOT(OpenStudioProgramProjector())); + // Refresh projector list + previewProjector->clear(); + studioProgramProjector->clear(); + AddProjectorMenuMonitors(previewProjector, this, + SLOT(OpenPreviewProjector())); + AddProjectorMenuMonitors(studioProgramProjector, this, + SLOT(OpenStudioProgramProjector())); - trayMenu->clear(); - trayMenu->addAction(showHide); - trayMenu->addMenu(previewProjector); - trayMenu->addMenu(studioProgramProjector); - trayMenu->addAction(sysTrayStream); - trayMenu->addAction(sysTrayRecord); - trayMenu->addAction(sysTrayReplayBuffer); - trayMenu->addAction(exit); - trayMenu->popup(QCursor::pos()); - } + if (reason == QSystemTrayIcon::Trigger) + ToggleShowHide(); } void OBSBasic::SysTrayNotify(const QString &text, QSystemTrayIcon::MessageIcon n) { - if (QSystemTrayIcon::supportsMessages()) { + if (trayIcon && QSystemTrayIcon::supportsMessages()) { QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon(n); trayIcon->showMessage("OBS Studio", text, icon, 10000); @@ -6358,6 +6866,8 @@ void OBSBasic::SystemTray(bool firstStarted) { if (!QSystemTrayIcon::isSystemTrayAvailable()) return; + if (!trayIcon && !firstStarted) + return; bool sysTrayWhenStarted = config_get_bool(GetGlobalConfig(), "BasicWindow", "SysTrayWhenStarted"); @@ -6440,6 +6950,48 @@ void OBSBasic::on_actionPasteDup_triggered() on_actionPasteTransform_triggered(); } +void OBSBasic::AudioMixerCopyFilters() +{ + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); + obs_source_t *source = vol->GetSource(); + + copyFiltersString = obs_source_get_name(source); +} + +void OBSBasic::AudioMixerPasteFilters() +{ + QAction *action = reinterpret_cast(sender()); + VolControl *vol = action->property("volControl").value(); + obs_source_t *dstSource = vol->GetSource(); + + OBSSource source = obs_get_source_by_name(copyFiltersString); + obs_source_release(source); + + if (source == dstSource) + return; + + obs_source_copy_filters(dstSource, source); +} + +void OBSBasic::SceneCopyFilters() +{ + copyFiltersString = obs_source_get_name(GetCurrentSceneSource()); +} + +void OBSBasic::ScenePasteFilters() +{ + OBSSource source = obs_get_source_by_name(copyFiltersString); + obs_source_release(source); + + OBSSource dstSource = GetCurrentSceneSource(); + + if (source == dstSource) + return; + + obs_source_copy_filters(dstSource, source); +} + void OBSBasic::on_actionCopyFilters_triggered() { OBSSceneItem item = GetCurrentSceneItem(); @@ -6664,9 +7216,132 @@ void OBSBasic::on_stats_triggered() stats = statsDlg; } -ColorSelect::ColorSelect(QWidget *parent) - : QWidget(parent), - ui(new Ui::ColorSelect) +void OBSBasic::on_actionShowAbout_triggered() { - ui->setupUi(this); + if (about) + about->close(); + + about = new OBSAbout(this); + about->show(); + + about->setAttribute(Qt::WA_DeleteOnClose, true); +} + +void OBSBasic::ResizeOutputSizeOfSource() +{ + if (ui->streamButton->isChecked() || ui->recordButton->isChecked() || + (replayBufferButton && replayBufferButton->isChecked())) + return; + + QMessageBox resize_output(this); + resize_output.setText(QTStr("ResizeOutputSizeOfSource.Text") + + "\n\n" + QTStr("ResizeOutputSizeOfSource.Continue")); + QAbstractButton *Yes = resize_output.addButton(QTStr("Yes"), + QMessageBox::YesRole); + resize_output.addButton(QTStr("No"), QMessageBox::NoRole); + resize_output.setIcon(QMessageBox::Warning); + resize_output.setWindowTitle(QTStr("ResizeOutputSizeOfSource")); + resize_output.exec(); + + if (resize_output.clickedButton() != Yes) + return; + + OBSSource source = obs_sceneitem_get_source(GetCurrentSceneItem()); + + int width = obs_source_get_width(source); + int height = obs_source_get_height(source); + + config_set_uint(basicConfig, "Video", "BaseCX", width); + config_set_uint(basicConfig, "Video", "BaseCY", height); + config_set_uint(basicConfig, "Video", "OutputCX", width); + config_set_uint(basicConfig, "Video", "OutputCY", height); + + ResetVideo(); + on_actionFitToScreen_triggered(); +} + +QAction *OBSBasic::AddDockWidget(QDockWidget *dock) +{ + QAction *action = ui->viewMenuDocks->addAction(dock->windowTitle()); + action->setCheckable(true); + assignDockToggle(dock, action); + extraDocks.push_back(dock); + + bool lock = ui->lockUI->isChecked(); + QDockWidget::DockWidgetFeatures features = lock + ? QDockWidget::NoDockWidgetFeatures + : QDockWidget::AllDockWidgetFeatures; + + dock->setFeatures(features); + + /* prune deleted docks */ + for (int i = extraDocks.size() - 1; i >= 0 ; i--) { + if (!extraDocks[i]) { + extraDocks.removeAt(i); + } + } + + return action; +} + +OBSBasic *OBSBasic::Get() +{ + return reinterpret_cast(App()->GetMainWindow()); +} + +bool OBSBasic::StreamingActive() +{ + if (!outputHandler) + return false; + return outputHandler->StreamingActive(); +} + +bool OBSBasic::RecordingActive() +{ + if (!outputHandler) + return false; + return outputHandler->RecordingActive(); +} + +bool OBSBasic::ReplayBufferActive() +{ + if (!outputHandler) + return false; + return outputHandler->ReplayBufferActive(); +} + +SceneRenameDelegate::SceneRenameDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ +} + +void SceneRenameDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + QStyledItemDelegate::setEditorData(editor, index); + QLineEdit *lineEdit = qobject_cast(editor); + if (lineEdit) + lineEdit->selectAll(); +} + +bool SceneRenameDelegate::eventFilter(QObject *editor, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Escape) { + QLineEdit *lineEdit = qobject_cast(editor); + if (lineEdit) + lineEdit->undo(); + } + } + + return QStyledItemDelegate::eventFilter(editor, event); +} + +void OBSBasic::UpdatePatronJson(const QString &text, const QString &error) +{ + if (!error.isEmpty()) + return; + + patronJson = QT_TO_UTF8(text); } diff --git a/UI/window-basic-main.hpp b/UI/window-basic-main.hpp index 24e0036..8641f53 100644 --- a/UI/window-basic-main.hpp +++ b/UI/window-basic-main.hpp @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include #include @@ -30,6 +32,8 @@ #include "window-basic-adv-audio.hpp" #include "window-basic-filters.hpp" #include "window-projector.hpp" +#include "window-basic-about.hpp" +#include "auth-base.hpp" #include @@ -52,6 +56,7 @@ class OBSBasicStats; #define AUX_AUDIO_1 Str("AuxAudioDevice1") #define AUX_AUDIO_2 Str("AuxAudioDevice2") #define AUX_AUDIO_3 Str("AuxAudioDevice3") +#define AUX_AUDIO_4 Str("AuxAudioDevice4") #define SIMPLE_ENCODER_X264 "x264" #define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu" @@ -97,13 +102,26 @@ private: std::shared_ptr renamedSignal; }; +class ColorSelect : public QWidget { + +public: + explicit ColorSelect(QWidget *parent = 0); + +private: + std::unique_ptr ui; +}; + class OBSBasic : public OBSMainWindow { Q_OBJECT + friend class OBSAbout; friend class OBSBasicPreview; friend class OBSBasicStatusBar; friend class OBSBasicSourceSelect; friend class OBSBasicSettings; + friend class Auth; + friend class AutoConfig; + friend class AutoConfigStreamPage; friend struct OBSStudioAPI; enum class MoveDir { @@ -124,10 +142,14 @@ class OBSBasic : public OBSMainWindow { private: obs_frontend_callbacks *api = nullptr; + std::shared_ptr auth; + std::vector volumes; std::vector signalHandlers; + QList> extraDocks; + bool loaded = false; long disableSaving = 1; bool projectChanged = false; @@ -135,7 +157,7 @@ private: bool fullscreenInterface = false; const char *copyString; - const char *copyFiltersString; + const char *copyFiltersString = nullptr; bool copyVisible = true; QScopedPointer updateCheckThread; @@ -147,6 +169,8 @@ private: QPointer transformWindow; QPointer advAudioWindow; QPointer filters; + QPointer statsDock; + QPointer about; QPointer cpuUsageTimer; os_cpu_usage_info_t *cpuUsageInfo = nullptr; @@ -182,6 +206,7 @@ private: QPointer startStreamMenu; + QPointer transitionButton; QPointer replayBufferButton; QScopedPointer trayIcon; @@ -191,8 +216,28 @@ private: QPointer showHide; QPointer exit; QPointer trayMenu; + QPointer previewProjector; + QPointer studioProgramProjector; + QPointer multiviewProjectorMenu; + QPointer previewProjectorSource; + QPointer previewProjectorMain; + QPointer sceneProjectorMenu; + QPointer sourceProjector; + QPointer scaleFilteringMenu; + QPointer colorMenu; + QPointer colorWidgetAction; + QPointer colorSelect; + QPointer deinterlaceMenu; + QPointer perSceneTransitionMenu; + QPointer shortcutFilter; + + QPointer programWidget; + QPointer programLayout; + QPointer programLabel; + + QScopedPointer patronJsonThread; + std::string patronJson; - QPointer multiviewProjectorMenu; void UpdateMultiviewProjectorMenu(); void DrawBackdrop(float cx, float cy); @@ -218,6 +263,7 @@ private: bool InitService(); bool InitBasicConfigDefaults(); + void InitBasicConfigDefaults2(); bool InitBasicConfig(); void InitOBSCallbacks(); @@ -271,7 +317,7 @@ private: void LoadProfile(); void ResetProfileData(); bool AddProfile(bool create_new, const char *title, const char *text, - const char *init_text = nullptr); + const char *init_text = nullptr, bool rename = false); void DeleteProfile(const char *profile_name, const char *profile_dir); void RefreshProfiles(); void ChangeProfile(); @@ -282,7 +328,7 @@ private: int GetTopSelectedSourceItem(); obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, - replayBufHotkeys; + replayBufHotkeys, togglePreviewHotkeys; obs_hotkey_id forceStreamingStopHotkey; void InitDefaultTransitions(); @@ -304,6 +350,8 @@ private: obs_data_array_t *SaveQuickTransitions(); void ClearQuickTransitionWidgets(); void RefreshQuickTransitions(); + void DisableQuickTransitionWidgets(); + void EnableQuickTransitionWidgets(); void CreateDefaultQuickTransitions(); QMenu *CreatePerSceneTransitionMenu(); @@ -394,7 +442,7 @@ public slots: void RecordingStart(); void RecordStopping(); - void RecordingStop(int code); + void RecordingStop(int code, QString last_error); void StartReplayBuffer(); void StopReplayBuffer(); @@ -419,6 +467,8 @@ public slots: bool create_new, const QString &name = QString()); + void UpdatePatronJson(const QString &text, const QString &error); + private slots: void AddSceneItem(OBSSceneItem item); void AddScene(OBSSource source); @@ -477,6 +527,17 @@ private slots: SourceTreeItem *GetItemWidgetFromSceneItem(obs_sceneitem_t *sceneItem); + void on_actionShowAbout_triggered(); + + void AudioMixerCopyFilters(); + void AudioMixerPasteFilters(); + + void EnablePreview(); + void DisablePreview(); + + void SceneCopyFilters(); + void ScenePasteFilters(); + private: /* OBS Callbacks */ static void SceneReordered(void *data, calldata_t *params); @@ -499,6 +560,8 @@ private: static void HotkeyTriggered(void *data, obs_hotkey_id id, bool pressed); + void AutoRemux(); + public: OBSSource GetProgramSource(); OBSScene GetCurrentScene(); @@ -514,6 +577,8 @@ public: obs_service_t *GetService(); void SetService(obs_service_t *service); + int GetTransitionDuration(); + inline bool IsPreviewProgramMode() const { return os_atomic_load_bool(&previewProgramMode); @@ -555,6 +620,8 @@ public: void SaveService(); bool LoadService(); + inline Auth *GetAuth() {return auth.get();} + inline void EnableOutputs(bool enable) { if (enable) { @@ -565,9 +632,10 @@ public: } } - QMenu *AddDeinterlacingMenu(obs_source_t *source); - QMenu *AddScaleFilteringMenu(obs_sceneitem_t *item); - QMenu *AddBackgroundColorMenu(obs_sceneitem_t *item); + QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source); + QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item); + QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction, + ColorSelect *select, obs_sceneitem_t *item); void CreateSourcePopupMenu(int idx, bool preview); void UpdateTitleBar(); @@ -582,6 +650,10 @@ public: void CreatePropertiesWindow(obs_source_t *source); void CreateFiltersWindow(obs_source_t *source); + QAction *AddDockWidget(QDockWidget *dock); + + static OBSBasic *Get(); + protected: virtual void closeEvent(QCloseEvent *event) override; virtual void changeEvent(QEvent *event) override; @@ -615,6 +687,8 @@ private slots: void on_actionFitToScreen_triggered(); void on_actionStretchToScreen_triggered(); void on_actionCenterToScreen_triggered(); + void on_actionVerticalCenter_triggered(); + void on_actionHorizontalCenter_triggered(); void on_scenes_currentItemChanged(QListWidgetItem *current, QListWidgetItem *prev); @@ -730,13 +804,19 @@ private slots: void OpenMultiviewWindow(); void OpenSceneWindow(); - void DeferredLoad(const QString &file, int requeueCount); + void DeferredSysTrayLoad(int requeueCount); void StackedMixerAreaContextMenuRequested(); + void ResizeOutputSizeOfSource(); + public slots: void on_actionResetTransform_triggered(); + bool StreamingActive(); + bool RecordingActive(); + bool ReplayBufferActive(); + public: explicit OBSBasic(QWidget *parent = 0); virtual ~OBSBasic(); @@ -748,15 +828,20 @@ public: virtual int GetProfilePath(char *path, size_t size, const char *file) const override; + static void InitBrowserPanelSafeBlock(); + private: std::unique_ptr ui; }; -class ColorSelect : public QWidget { +class SceneRenameDelegate : public QStyledItemDelegate { + Q_OBJECT public: - explicit ColorSelect(QWidget *parent = 0); + SceneRenameDelegate(QObject *parent); + virtual void setEditorData(QWidget *editor, const QModelIndex &index) + const override; -private: - std::unique_ptr ui; +protected: + virtual bool eventFilter(QObject *editor, QEvent *event) override; }; diff --git a/UI/window-basic-preview.cpp b/UI/window-basic-preview.cpp index bc4b2b9..2d9fa59 100644 --- a/UI/window-basic-preview.cpp +++ b/UI/window-basic-preview.cpp @@ -3,14 +3,19 @@ #include #include +#include #include #include #include "window-basic-preview.hpp" #include "window-basic-main.hpp" #include "obs-app.hpp" +#include "platform.hpp" #define HANDLE_RADIUS 4.0f #define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f) +#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) +#define SUPPORTS_FRACTIONAL_SCALING +#endif /* TODO: make C++ math classes and clean up code here later */ @@ -21,10 +26,23 @@ OBSBasicPreview::OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags) setMouseTracking(true); } +OBSBasicPreview::~OBSBasicPreview() +{ + if (overflow) { + obs_enter_graphics(); + gs_texture_destroy(overflow); + obs_leave_graphics(); + } +} + vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event) { OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); +#ifdef SUPPORTS_FRACTIONAL_SCALING + float pixelRatio = main->devicePixelRatioF(); +#else float pixelRatio = main->devicePixelRatio(); +#endif float scale = pixelRatio / main->previewScale; vec2 pos; vec2_set(&pos, @@ -369,7 +387,11 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos) if (!scene) return; +#ifdef SUPPORTS_FRACTIONAL_SCALING + float scale = main->previewScale / main->devicePixelRatioF(); +#else float scale = main->previewScale / main->devicePixelRatio(); +#endif vec2 scaled_pos = pos; vec2_divf(&scaled_pos, &scaled_pos, scale); HandleFindData data(scaled_pos, scale); @@ -491,7 +513,11 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event) } OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); +#ifdef SUPPORTS_FRACTIONAL_SCALING + float pixelRatio = main->devicePixelRatioF(); +#else float pixelRatio = main->devicePixelRatio(); +#endif float x = float(event->x()) - main->previewX / pixelRatio; float y = float(event->y()) - main->previewY / pixelRatio; Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); @@ -588,6 +614,9 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event) mouseDown = false; mouseMoved = false; cropping = false; + + OBSSceneItem item = GetItemAtPos(pos, true); + hoveredPreviewItem = item; } } @@ -1134,6 +1163,8 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) return; if (mouseDown) { + hoveredPreviewItem = nullptr; + vec2 pos = GetMouseEventPos(event); if (!mouseMoved && !mouseOverItems && @@ -1170,10 +1201,22 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event) } mouseMoved = true; + } else { + vec2 pos = GetMouseEventPos(event); + OBSSceneItem item = GetItemAtPos(pos, true); + + hoveredPreviewItem = item; } } -static void DrawCircleAtPos(float x, float y) +void OBSBasicPreview::leaveEvent(QEvent *event) +{ + hoveredPreviewItem = nullptr; + + UNUSED_PARAMETER(event); +} + +static void DrawSquareAtPos(float x, float y) { struct vec3 pos; vec3_set(&pos, x, y, 0.0f); @@ -1185,11 +1228,68 @@ static void DrawCircleAtPos(float x, float y) gs_matrix_push(); gs_matrix_identity(); gs_matrix_translate(&pos); - gs_matrix_scale3f(HANDLE_RADIUS, HANDLE_RADIUS, 1.0f); - gs_draw(GS_LINESTRIP, 0, 0); + + gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f); + gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f); + gs_draw(GS_TRISTRIP, 0, 0); gs_matrix_pop(); } +static void DrawLine(float x1, float y1, float x2, float y2, float thickness, + vec2 scale) +{ + float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f; + float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f; + + gs_render_start(true); + + gs_vertex2f(x1, y1); + gs_vertex2f(x1 + (xSide * (thickness / scale.x)), + y1 + (ySide * (thickness / scale.y))); + gs_vertex2f(x2 + (xSide * (thickness / scale.x)), + y2 + (ySide * (thickness / scale.y))); + gs_vertex2f(x2, y2); + gs_vertex2f(x1, y1); + + gs_vertbuffer_t *line = gs_render_save(); + + gs_load_vertexbuffer(line); + gs_draw(GS_TRISTRIP, 0, 0); + gs_vertexbuffer_destroy(line); +} + +static void DrawRect(float thickness, vec2 scale) +{ + gs_render_start(true); + + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(0.0f + (thickness / scale.x), 0.0f); + gs_vertex2f(0.0f + (thickness / scale.x), 1.0f); + gs_vertex2f(0.0f, 1.0f); + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(0.0f, 1.0f); + gs_vertex2f(0.0f, 1.0f - (thickness / scale.y)); + gs_vertex2f(1.0f, 1.0f - (thickness / scale.y)); + gs_vertex2f(1.0f, 1.0f); + gs_vertex2f(0.0f, 1.0f); + gs_vertex2f(1.0f, 1.0f); + gs_vertex2f(1.0f - (thickness / scale.x), 1.0f); + gs_vertex2f(1.0f - (thickness / scale.x), 0.0f); + gs_vertex2f(1.0f, 0.0f); + gs_vertex2f(1.0f, 1.0f); + gs_vertex2f(1.0f, 0.0f); + gs_vertex2f(1.0f, 0.0f + (thickness / scale.y)); + gs_vertex2f(0.0f, 0.0f + (thickness / scale.y)); + gs_vertex2f(0.0f, 0.0f); + gs_vertex2f(1.0f, 0.0f); + + gs_vertbuffer_t *rect = gs_render_save(); + + gs_load_vertexbuffer(rect); + gs_draw(GS_TRISTRIP, 0, 0); + gs_vertexbuffer_destroy(rect); +} + static inline bool crop_enabled(const obs_sceneitem_crop *crop) { return crop->left > 0 || @@ -1198,6 +1298,96 @@ static inline bool crop_enabled(const obs_sceneitem_crop *crop) crop->bottom > 0; } +bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene, + obs_sceneitem_t *item, void *param) +{ + if (obs_sceneitem_locked(item)) + return true; + + if (!SceneItemHasVideo(item)) + return true; + + bool select = config_get_bool(GetGlobalConfig(), "BasicWindow", + "OverflowSelectionHidden"); + + if (!select && !obs_sceneitem_visible(item)) + return true; + + if (obs_sceneitem_is_group(item)) { + matrix4 mat; + obs_sceneitem_get_draw_transform(item, &mat); + + gs_matrix_push(); + gs_matrix_mul(&mat); + obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param); + gs_matrix_pop(); + } + + bool always = config_get_bool(GetGlobalConfig(), "BasicWindow", + "OverflowAlwaysVisible"); + + if (!always && !obs_sceneitem_selected(item)) + return true; + + OBSBasicPreview *prev = reinterpret_cast(param); + + matrix4 boxTransform; + matrix4 invBoxTransform; + obs_sceneitem_get_box_transform(item, &boxTransform); + matrix4_inv(&invBoxTransform, &boxTransform); + + vec3 bounds[] = { + {{{0.f, 0.f, 0.f}}}, + {{{1.f, 0.f, 0.f}}}, + {{{0.f, 1.f, 0.f}}}, + {{{1.f, 1.f, 0.f}}}, + }; + + bool visible = std::all_of(std::begin(bounds), std::end(bounds), + [&](const vec3 &b) + { + vec3 pos; + vec3_transform(&pos, &b, &boxTransform); + vec3_transform(&pos, &pos, &invBoxTransform); + return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y); + }); + + if (!visible) + return true; + + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSelectedOverflow"); + + obs_transform_info info; + obs_sceneitem_get_info(item, &info); + + gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT); + gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image"); + gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale"); + + vec2 s; + vec2_set(&s, boxTransform.x.x / 96, boxTransform.y.y / 96); + + gs_effect_set_vec2(scale, &s); + gs_effect_set_texture(image, prev->overflow); + + gs_matrix_push(); + gs_matrix_mul(&boxTransform); + + obs_sceneitem_crop crop; + obs_sceneitem_get_crop(item, &crop); + + while (gs_effect_loop(solid, "Draw")) { + gs_draw_sprite(prev->overflow, 0, 1, 1); + } + + gs_matrix_pop(); + + GS_DEBUG_MARKER_END(); + + UNUSED_PARAMETER(scene); + return true; +} + bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item, void *param) { @@ -1217,10 +1407,15 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, gs_matrix_pop(); } - if (!obs_sceneitem_selected(item)) - return true; + OBSBasicPreview *prev = reinterpret_cast(param); + OBSBasic *main = OBSBasic::Get(); - OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + bool hovered = prev->hoveredPreviewItem == item || + prev->hoveredListItem == item; + bool selected = obs_sceneitem_selected(item); + + if (!selected && !hovered) + return true; matrix4 boxTransform; matrix4 invBoxTransform; @@ -1234,6 +1429,14 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, {{{1.f, 1.f, 0.f}}}, }; + vec4 red; + vec4 green; + vec4 blue; + + vec4_set(&red, 1.0f, 0.0f, 0.0f, 1.0f); + vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f); + vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f); + bool visible = std::all_of(std::begin(bounds), std::end(bounds), [&](const vec3 &b) { @@ -1246,62 +1449,115 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene, if (!visible) return true; + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSelectedItem"); + + matrix4 curTransform; + vec2 boxScale; + gs_matrix_get(&curTransform); + obs_sceneitem_get_box_scale(item, &boxScale); + boxScale.x *= curTransform.x.x; + boxScale.y *= curTransform.y.y; + obs_transform_info info; obs_sceneitem_get_info(item, &info); - gs_load_vertexbuffer(main->circle); - gs_matrix_push(); gs_matrix_mul(&boxTransform); - DrawCircleAtPos(0.0f, 0.0f); - DrawCircleAtPos(0.0f, 1.0f); - DrawCircleAtPos(1.0f, 0.0f); - DrawCircleAtPos(1.0f, 1.0f); - DrawCircleAtPos(0.5f, 0.0f); - DrawCircleAtPos(0.0f, 0.5f); - DrawCircleAtPos(0.5f, 1.0f); - DrawCircleAtPos(1.0f, 0.5f); - obs_sceneitem_crop crop; obs_sceneitem_get_crop(item, &crop); + gs_effect_t *eff = gs_get_effect(); + gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color"); + if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) { - vec4 color; - gs_effect_t *eff = gs_get_effect(); - gs_eparam_t *param = gs_effect_get_param_by_name(eff, "color"); +#define DRAW_SIDE(side, x1, y1, x2, y2) \ + if (hovered && !selected) \ + gs_effect_set_vec4(colParam, &blue); \ + else if (crop.side > 0) \ + gs_effect_set_vec4(colParam, &green); \ + DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \ + gs_effect_set_vec4(colParam, &red); -#define DRAW_SIDE(side, vb) \ - if (crop.side > 0) \ - vec4_set(&color, 0.0f, 1.0f, 0.0f, 1.0f); \ - else \ - vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f); \ - gs_effect_set_vec4(param, &color); \ - gs_load_vertexbuffer(main->vb); \ - gs_draw(GS_LINESTRIP, 0, 0); - - DRAW_SIDE(left, boxLeft); - DRAW_SIDE(top, boxTop); - DRAW_SIDE(right, boxRight); - DRAW_SIDE(bottom, boxBottom); + DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f); + DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f); + DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f); + DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f); #undef DRAW_SIDE } else { - gs_load_vertexbuffer(main->box); - gs_draw(GS_LINESTRIP, 0, 0); + if (!selected) { + gs_effect_set_vec4(colParam, &blue); + DrawRect(HANDLE_RADIUS / 2, boxScale); + } else { + DrawRect(HANDLE_RADIUS / 2, boxScale); + } + } + + gs_load_vertexbuffer(main->box); + gs_effect_set_vec4(colParam, &red); + + if (selected) { + DrawSquareAtPos(0.0f, 0.0f); + DrawSquareAtPos(0.0f, 1.0f); + DrawSquareAtPos(1.0f, 0.0f); + DrawSquareAtPos(1.0f, 1.0f); + DrawSquareAtPos(0.5f, 0.0f); + DrawSquareAtPos(0.0f, 0.5f); + DrawSquareAtPos(0.5f, 1.0f); + DrawSquareAtPos(1.0f, 0.5f); } gs_matrix_pop(); + GS_DEBUG_MARKER_END(); + UNUSED_PARAMETER(scene); UNUSED_PARAMETER(param); return true; } +void OBSBasicPreview::DrawOverflow() +{ + if (locked) + return; + + bool hidden = config_get_bool(GetGlobalConfig(), "BasicWindow", + "OverflowHidden"); + + if (hidden) + return; + + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawOverflow"); + + if (!overflow) { + std::string path; + GetDataFilePath("images/overflow.png", path); + overflow = gs_texture_create_from_file(path.c_str()); + } + + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); + + OBSScene scene = main->GetCurrentScene(); + + if (scene) { + gs_matrix_push(); + gs_matrix_scale3f(main->previewScale, main->previewScale, 1.0f); + obs_scene_enum_items(scene, DrawSelectedOverflow, this); + gs_matrix_pop(); + } + + gs_load_vertexbuffer(nullptr); + + GS_DEBUG_MARKER_END(); +} + void OBSBasicPreview::DrawSceneEditing() { if (locked) return; + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSceneEditing"); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID); @@ -1327,6 +1583,8 @@ void OBSBasicPreview::DrawSceneEditing() gs_technique_end_pass(tech); gs_technique_end(tech); + + GS_DEBUG_MARKER_END(); } void OBSBasicPreview::ResetScrollingOffset() @@ -1345,3 +1603,8 @@ void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) { scrollingOffset.y *= newScalingAmountVal / scalingAmount; scalingAmount = newScalingAmountVal; } + +OBSBasicPreview *OBSBasicPreview::Get() +{ + return OBSBasic::Get()->ui->preview; +} diff --git a/UI/window-basic-preview.hpp b/UI/window-basic-preview.hpp index c177dd9..e285456 100644 --- a/UI/window-basic-preview.hpp +++ b/UI/window-basic-preview.hpp @@ -31,6 +31,8 @@ enum class ItemHandle : uint32_t { class OBSBasicPreview : public OBSQTDisplay { Q_OBJECT + friend class SourceTree; + private: obs_sceneitem_crop startCrop; vec2 startItemPos; @@ -43,6 +45,8 @@ private: matrix4 itemToScreen; matrix4 invGroupTransform; + gs_texture_t *overflow = nullptr; + vec2 startPos; vec2 lastMoveOffset; vec2 scrollingFrom; @@ -57,7 +61,12 @@ private: int32_t scalingLevel = 0; float scalingAmount = 1.0f; + obs_sceneitem_t *hoveredPreviewItem = nullptr; + obs_sceneitem_t *hoveredListItem = nullptr; + static vec2 GetMouseEventPos(QMouseEvent *event); + static bool DrawSelectedOverflow(obs_scene_t *scene, + obs_sceneitem_t *item, void *param); static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item, void *param); @@ -84,6 +93,9 @@ private: public: OBSBasicPreview(QWidget *parent, Qt::WindowFlags flags = 0); + ~OBSBasicPreview(); + + static OBSBasicPreview *Get(); virtual void keyPressEvent(QKeyEvent *event) override; virtual void keyReleaseEvent(QKeyEvent *event) override; @@ -93,7 +105,9 @@ public: virtual void mousePressEvent(QMouseEvent *event) override; virtual void mouseReleaseEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void leaveEvent(QEvent *event) override; + void DrawOverflow(); void DrawSceneEditing(); inline void SetLocked(bool newLockedVal) {locked = newLockedVal;} diff --git a/UI/window-basic-properties.cpp b/UI/window-basic-properties.cpp index a03f187..3864abd 100644 --- a/UI/window-basic-properties.cpp +++ b/UI/window-basic-properties.cpp @@ -29,6 +29,8 @@ using namespace std; +static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color); + OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) : QDialog (parent), preview (new OBSQTDisplay(this)), @@ -49,6 +51,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) int cy = (int)config_get_int(App()->GlobalConfig(), "PropertiesWindow", "cy"); + enum obs_source_type type = obs_source_get_type(source); + buttonBox->setObjectName(QStringLiteral("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | @@ -64,6 +68,8 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) else resize(720, 580); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + QMetaObject::connectSlotsByName(this); /* The OBSData constructor increments the reference once */ @@ -93,6 +99,13 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) setLayout(new QVBoxLayout(this)); layout()->addWidget(windowSplitter); + + if (type == OBS_SOURCE_TYPE_TRANSITION) { + AddPreviewButton(); + connect(view, SIGNAL(PropertiesRefreshed()), + this, SLOT(AddPreviewButton())); + } + layout()->addWidget(buttonBox); layout()->setAlignment(buttonBox, Qt::AlignBottom); @@ -114,7 +127,11 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) obs_display_add_draw_callback(preview->GetDisplay(), OBSBasicProperties::DrawPreview, this); }; - enum obs_source_type type = obs_source_get_type(source); + auto addTransitionDrawCallback = [this] () + { + obs_display_add_draw_callback(preview->GetDisplay(), + OBSBasicProperties::DrawTransitionPreview, this); + }; uint32_t caps = obs_source_get_output_flags(source); bool drawable_type = type == OBS_SOURCE_TYPE_INPUT || type == OBS_SOURCE_TYPE_SCENE; @@ -124,6 +141,59 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) preview->show(); connect(preview.data(), &OBSQTDisplay::DisplayCreated, addDrawCallback); + + } else if (type == OBS_SOURCE_TYPE_TRANSITION) { + sourceA = obs_source_create_private("scene", "sourceA", + nullptr); + sourceB = obs_source_create_private("scene", "sourceB", + nullptr); + + obs_source_release(sourceA); + obs_source_release(sourceB); + + uint32_t colorA = 0xFFB26F52; + uint32_t colorB = 0xFF6FB252; + + CreateTransitionScene(sourceA, "A", colorA); + CreateTransitionScene(sourceB, "B", colorB); + + /** + * The cloned source is made from scratch, rather than using + * obs_source_duplicate, as the stinger transition would not + * play correctly otherwise. + */ + + obs_data_t *settings = obs_source_get_settings(source); + + sourceClone = obs_source_create_private( + obs_source_get_id(source), "clone", settings); + obs_source_release(sourceClone); + + obs_source_inc_active(sourceClone); + obs_transition_set(sourceClone, sourceA); + + obs_data_release(settings); + + auto updateCallback = [=]() + { + obs_data_t *settings = obs_source_get_settings(source); + obs_source_update(sourceClone, settings); + + obs_transition_clear(sourceClone); + obs_transition_set(sourceClone, sourceA); + obs_transition_force_stop(sourceClone); + + obs_data_release(settings); + + direction = true; + }; + + connect(view, &OBSPropertiesView::Changed, updateCallback); + + preview->show(); + connect(preview.data(), &OBSQTDisplay::DisplayCreated, + addTransitionDrawCallback); + } else { preview->hide(); } @@ -131,10 +201,119 @@ OBSBasicProperties::OBSBasicProperties(QWidget *parent, OBSSource source_) OBSBasicProperties::~OBSBasicProperties() { + if (sourceClone) { + obs_source_dec_active(sourceClone); + } obs_source_dec_showing(source); main->SaveProject(); } +void OBSBasicProperties::AddPreviewButton() +{ + QPushButton *playButton = new QPushButton( + QTStr("PreviewTransition"), this); + VScrollArea *area = view; + area->widget()->layout()->addWidget(playButton); + + playButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + + auto play = [=] () + { + OBSSource start; + OBSSource end; + + if (direction) { + start = sourceA; + end = sourceB; + } else { + start = sourceB; + end = sourceA; + } + + obs_transition_set(sourceClone, start); + obs_transition_start(sourceClone, + OBS_TRANSITION_MODE_AUTO, + main->GetTransitionDuration(), end); + direction = !direction; + + start = nullptr; + end = nullptr; + }; + + connect(playButton, &QPushButton::clicked, play); +} + +static obs_source_t *CreateLabel(const char *name, size_t h) +{ + obs_data_t *settings = obs_data_create(); + obs_data_t *font = obs_data_create(); + + std::string text; + text += " "; + text += name; + text += " "; + +#if defined(_WIN32) + obs_data_set_string(font, "face", "Arial"); +#elif defined(__APPLE__) + obs_data_set_string(font, "face", "Helvetica"); +#else + obs_data_set_string(font, "face", "Monospace"); +#endif + obs_data_set_int(font, "flags", 1); // Bold text + obs_data_set_int(font, "size", min(int(h), 300)); + + obs_data_set_obj(settings, "font", font); + obs_data_set_string(settings, "text", text.c_str()); + obs_data_set_bool(settings, "outline", false); + +#ifdef _WIN32 + const char *text_source_id = "text_gdiplus"; +#else + const char *text_source_id = "text_ft2_source"; +#endif + + obs_source_t *txtSource = obs_source_create_private(text_source_id, + name, settings); + + obs_data_release(font); + obs_data_release(settings); + + return txtSource; +} + +static void CreateTransitionScene(OBSSource scene, char *text, uint32_t color) +{ + obs_data_t *settings = obs_data_create(); + obs_data_set_int(settings, "width", obs_source_get_width(scene)); + obs_data_set_int(settings, "height", obs_source_get_height(scene)); + obs_data_set_int(settings, "color", color); + + obs_source_t *colorBG = obs_source_create_private("color_source", + "background", settings); + + obs_scene_add(obs_scene_from_source(scene), colorBG); + + obs_source_t *label = CreateLabel(text, obs_source_get_height(scene)); + obs_sceneitem_t *item = obs_scene_add(obs_scene_from_source(scene), + label); + + vec2 size; + vec2_set(&size, obs_source_get_width(scene), +#ifdef _WIN32 + obs_source_get_height(scene)); +#else + obs_source_get_height(scene) * 0.8); +#endif + + obs_sceneitem_set_bounds(item, &size); + obs_sceneitem_set_bounds_type(item, OBS_BOUNDS_SCALE_INNER); + + obs_data_release(settings); + obs_source_release(colorBG); + obs_source_release(label); +} + void OBSBasicProperties::SourceRemoved(void *data, calldata_t *params) { QMetaObject::invokeMethod(static_cast(data), @@ -189,7 +368,7 @@ void OBSBasicProperties::on_buttonBox_clicked(QAbstractButton *button) if (!view->DeferUpdate()) obs_source_update(source, nullptr); - view->RefreshProperties(); + view->ReloadProperties(); } } @@ -224,6 +403,38 @@ void OBSBasicProperties::DrawPreview(void *data, uint32_t cx, uint32_t cy) gs_viewport_pop(); } +void OBSBasicProperties::DrawTransitionPreview(void *data, uint32_t cx, + uint32_t cy) +{ + OBSBasicProperties *window = static_cast(data); + + if (!window->source) + return; + + uint32_t sourceCX = max(obs_source_get_width(window->source), 1u); + uint32_t sourceCY = max(obs_source_get_height(window->source), 1u); + + int x, y; + int newCX, newCY; + float scale; + + GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale); + + newCX = int(scale * float(sourceCX)); + newCY = int(scale * float(sourceCY)); + + gs_viewport_push(); + gs_projection_push(); + gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), + -100.0f, 100.0f); + gs_set_viewport(x, y, newCX, newCY); + + obs_source_video_render(window->sourceClone); + + gs_projection_pop(); + gs_viewport_pop(); +} + void OBSBasicProperties::Cleanup() { config_set_int(App()->GlobalConfig(), "PropertiesWindow", "cx", @@ -233,6 +444,8 @@ void OBSBasicProperties::Cleanup() obs_display_remove_draw_callback(preview->GetDisplay(), OBSBasicProperties::DrawPreview, this); + obs_display_remove_draw_callback(preview->GetDisplay(), + OBSBasicProperties::DrawTransitionPreview, this); } void OBSBasicProperties::reject() diff --git a/UI/window-basic-properties.hpp b/UI/window-basic-properties.hpp index b21a2cf..69a9771 100644 --- a/UI/window-basic-properties.hpp +++ b/UI/window-basic-properties.hpp @@ -45,16 +45,25 @@ private: QDialogButtonBox *buttonBox; QSplitter *windowSplitter; + OBSSource sourceA; + OBSSource sourceB; + OBSSource sourceClone; + bool direction = true; + static void SourceRemoved(void *data, calldata_t *params); static void SourceRenamed(void *data, calldata_t *params); static void UpdateProperties(void *data, calldata_t *params); static void DrawPreview(void *data, uint32_t cx, uint32_t cy); + static void DrawTransitionPreview(void *data, uint32_t cx, + uint32_t cy); + void UpdateCallback(void *obj, obs_data_t *settings); bool ConfirmQuit(); int CheckSettings(); void Cleanup(); private slots: void on_buttonBox_clicked(QAbstractButton *button); + void AddPreviewButton(); public: OBSBasicProperties(QWidget *parent, OBSSource source_); diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp new file mode 100644 index 0000000..6986244 --- /dev/null +++ b/UI/window-basic-settings-stream.cpp @@ -0,0 +1,505 @@ +#include + +#include "window-basic-settings.hpp" +#include "obs-frontend-api.h" +#include "obs-app.hpp" +#include "window-basic-main.hpp" +#include "qt-wrappers.hpp" + +#ifdef BROWSER_AVAILABLE +#include +#include "auth-oauth.hpp" +#endif + +struct QCef; +struct QCefCookieManager; + +extern QCef *cef; +extern QCefCookieManager *panel_cookies; + +enum class ListOpt : int { + ShowAll = 1, + Custom, +}; + +enum class Section : int { + Connect, + StreamKey, +}; + +inline bool OBSBasicSettings::IsCustomService() const +{ + return ui->service->currentData().toInt() == (int)ListOpt::Custom; +} + +void OBSBasicSettings::InitStreamPage() +{ + ui->connectAccount2->setVisible(false); + ui->disconnectAccount->setVisible(false); + ui->bandwidthTestEnable->setVisible(false); + + int vertSpacing = ui->topStreamLayout->verticalSpacing(); + + QMargins m = ui->topStreamLayout->contentsMargins(); + m.setBottom(vertSpacing / 2); + ui->topStreamLayout->setContentsMargins(m); + + m = ui->loginPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->loginPageLayout->setContentsMargins(m); + + m = ui->streamkeyPageLayout->contentsMargins(); + m.setTop(vertSpacing / 2); + ui->streamkeyPageLayout->setContentsMargins(m); + + LoadServices(false); + + connect(ui->service, SIGNAL(currentIndexChanged(int)), + this, SLOT(UpdateServerList())); + connect(ui->service, SIGNAL(currentIndexChanged(int)), + this, SLOT(UpdateKeyLink())); +} + +void OBSBasicSettings::LoadStream1Settings() +{ + obs_service_t *service_obj = main->GetService(); + const char *type = obs_service_get_type(service_obj); + + loading = true; + + obs_data_t *settings = obs_service_get_settings(service_obj); + + const char *service = obs_data_get_string(settings, "service"); + const char *server = obs_data_get_string(settings, "server"); + const char *key = obs_data_get_string(settings, "key"); + + if (strcmp(type, "rtmp_custom") == 0) { + ui->service->setCurrentIndex(0); + ui->customServer->setText(server); + + bool use_auth = obs_data_get_bool(settings, "use_auth"); + const char *username = obs_data_get_string(settings, "username"); + const char *password = obs_data_get_string(settings, "password"); + ui->authUsername->setText(QT_UTF8(username)); + ui->authPw->setText(QT_UTF8(password)); + ui->useAuth->setChecked(use_auth); + } else { + int idx = ui->service->findText(service); + if (idx == -1) { + if (service && *service) + ui->service->insertItem(1, service); + idx = 1; + } + ui->service->setCurrentIndex(idx); + + bool bw_test = obs_data_get_bool(settings, "bwtest"); + ui->bandwidthTestEnable->setChecked(bw_test); + } + + UpdateServerList(); + + if (strcmp(type, "rtmp_common") == 0) { + int idx = ui->server->findData(server); + if (idx == -1) { + if (server && *server) + ui->server->insertItem(0, server, server); + idx = 0; + } + ui->server->setCurrentIndex(idx); + } + + ui->key->setText(key); + + lastService.clear(); + on_service_currentIndexChanged(0); + + obs_data_release(settings); + + UpdateKeyLink(); + + bool streamActive = obs_frontend_streaming_active(); + ui->streamPage->setEnabled(!streamActive); + + loading = false; +} + +void OBSBasicSettings::SaveStream1Settings() +{ + bool customServer = IsCustomService(); + const char *service_id = customServer + ? "rtmp_custom" + : "rtmp_common"; + + obs_service_t *oldService = main->GetService(); + OBSData hotkeyData = obs_hotkeys_save_service(oldService); + obs_data_release(hotkeyData); + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + if (!customServer) { + obs_data_set_string(settings, "service", + QT_TO_UTF8(ui->service->currentText())); + obs_data_set_string(settings, "server", + QT_TO_UTF8(ui->server->currentData().toString())); + } else { + obs_data_set_string(settings, "server", + QT_TO_UTF8(ui->customServer->text())); + obs_data_set_bool(settings, "use_auth", + ui->useAuth->isChecked()); + if (ui->useAuth->isChecked()) { + obs_data_set_string(settings, "username", + QT_TO_UTF8(ui->authUsername->text())); + obs_data_set_string(settings, "password", + QT_TO_UTF8(ui->authPw->text())); + } + } + + obs_data_set_bool(settings, "bwtest", ui->bandwidthTestEnable->isChecked()); + obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text())); + + OBSService newService = obs_service_create(service_id, + "default_service", settings, hotkeyData); + obs_service_release(newService); + + if (!newService) + return; + + main->SetService(newService); + main->SaveService(); + main->auth = auth; + if (!!main->auth) + main->auth->LoadUI(); +} + +void OBSBasicSettings::UpdateKeyLink() +{ + bool custom = IsCustomService(); + QString serviceName = ui->service->currentText(); + + if (custom) + serviceName = ""; + + QString text = QTStr("Basic.AutoConfig.StreamPage.StreamKey"); + if (serviceName == "Twitch") { + text += " "; + text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; + } else if (serviceName == "YouTube / YouTube Gaming") { + text += " "; + text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite"); + text += ""; + } + + ui->streamKeyLabel->setText(text); +} + +void OBSBasicSettings::LoadServices(bool showAll) +{ + obs_properties_t *props = obs_get_service_properties("rtmp_common"); + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + obs_data_set_bool(settings, "show_all", showAll); + + obs_property_t *prop = obs_properties_get(props, "show_all"); + obs_property_modified(prop, settings); + + ui->service->blockSignals(true); + ui->service->clear(); + + QStringList names; + + obs_property_t *services = obs_properties_get(props, "service"); + size_t services_count = obs_property_list_item_count(services); + for (size_t i = 0; i < services_count; i++) { + const char *name = obs_property_list_item_string(services, i); + names.push_back(name); + } + + if (showAll) + names.sort(); + + for (QString &name : names) + ui->service->addItem(name); + + if (!showAll) { + ui->service->addItem( + QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"), + QVariant((int)ListOpt::ShowAll)); + } + + ui->service->insertItem(0, + QTStr("Basic.AutoConfig.StreamPage.Service.Custom"), + QVariant((int)ListOpt::Custom)); + + if (!lastService.isEmpty()) { + int idx = ui->service->findText(lastService); + if (idx != -1) + ui->service->setCurrentIndex(idx); + } + + obs_properties_destroy(props); + + ui->service->blockSignals(false); +} + +static inline bool is_auth_service(const std::string &service) +{ + return Auth::AuthType(service) != Auth::Type::None; +} + +void OBSBasicSettings::on_service_currentIndexChanged(int) +{ + bool showMore = + ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + if (showMore) + return; + + std::string service = QT_TO_UTF8(ui->service->currentText()); + bool custom = IsCustomService(); + + ui->disconnectAccount->setVisible(false); + ui->bandwidthTestEnable->setVisible(false); + +#ifdef BROWSER_AVAILABLE + if (cef) { + if (lastService != service.c_str()) { + QString key = ui->key->text(); + bool can_auth = is_auth_service(service); + int page = can_auth && (!loading || key.isEmpty()) + ? (int)Section::Connect + : (int)Section::StreamKey; + + ui->streamStackWidget->setCurrentIndex(page); + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(can_auth); + } + } else { + ui->connectAccount2->setVisible(false); + } +#else + ui->connectAccount2->setVisible(false); +#endif + + ui->useAuth->setVisible(custom); + ui->authUsernameLabel->setVisible(custom); + ui->authUsername->setVisible(custom); + ui->authPwLabel->setVisible(custom); + ui->authPwWidget->setVisible(custom); + + if (custom) { + ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, + ui->serverStackedWidget); + + ui->serverStackedWidget->setCurrentIndex(1); + ui->serverStackedWidget->setVisible(true); + ui->serverLabel->setVisible(true); + on_useAuth_toggled(); + } else { + ui->serverStackedWidget->setCurrentIndex(0); + } + +#ifdef BROWSER_AVAILABLE + auth.reset(); + + if (!!main->auth && + service.find(main->auth->service()) != std::string::npos) { + auth = main->auth; + OnAuthConnected(); + } +#endif +} + +void OBSBasicSettings::UpdateServerList() +{ + QString serviceName = ui->service->currentText(); + bool showMore = + ui->service->currentData().toInt() == (int)ListOpt::ShowAll; + + if (showMore) { + LoadServices(true); + ui->service->showPopup(); + return; + } else { + lastService = serviceName; + } + + obs_properties_t *props = obs_get_service_properties("rtmp_common"); + obs_property_t *services = obs_properties_get(props, "service"); + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName)); + obs_property_modified(services, settings); + + obs_property_t *servers = obs_properties_get(props, "server"); + + ui->server->clear(); + + size_t servers_count = obs_property_list_item_count(servers); + for (size_t i = 0; i < servers_count; i++) { + const char *name = obs_property_list_item_name(servers, i); + const char *server = obs_property_list_item_string(servers, i); + ui->server->addItem(name, server); + } + + obs_properties_destroy(props); +} + +void OBSBasicSettings::on_show_clicked() +{ + if (ui->key->echoMode() == QLineEdit::Password) { + ui->key->setEchoMode(QLineEdit::Normal); + ui->show->setText(QTStr("Hide")); + } else { + ui->key->setEchoMode(QLineEdit::Password); + ui->show->setText(QTStr("Show")); + } +} + +void OBSBasicSettings::on_authPwShow_clicked() +{ + if (ui->authPw->echoMode() == QLineEdit::Password) { + ui->authPw->setEchoMode(QLineEdit::Normal); + ui->authPwShow->setText(QTStr("Hide")); + } else { + ui->authPw->setEchoMode(QLineEdit::Password); + ui->authPwShow->setText(QTStr("Show")); + } +} + +OBSService OBSBasicSettings::SpawnTempService() +{ + bool custom = IsCustomService(); + const char *service_id = custom ? "rtmp_custom" : "rtmp_common"; + + OBSData settings = obs_data_create(); + obs_data_release(settings); + + if (!custom) { + obs_data_set_string(settings, "service", + QT_TO_UTF8(ui->service->currentText())); + obs_data_set_string(settings, "server", + QT_TO_UTF8(ui->server->currentData().toString())); + } else { + obs_data_set_string(settings, "server", + QT_TO_UTF8(ui->customServer->text())); + } + obs_data_set_string(settings, "key", QT_TO_UTF8(ui->key->text())); + + OBSService newService = obs_service_create(service_id, + "temp_service", settings, nullptr); + obs_service_release(newService); + + return newService; +} + +void OBSBasicSettings::OnOAuthStreamKeyConnected() +{ +#ifdef BROWSER_AVAILABLE + OAuthStreamKey *a = reinterpret_cast(auth.get()); + + if (a) { + bool validKey = !a->key().empty(); + + if (validKey) + ui->key->setText(QT_UTF8(a->key().c_str())); + + ui->streamKeyWidget->setVisible(false); + ui->streamKeyLabel->setVisible(false); + ui->connectAccount2->setVisible(false); + ui->disconnectAccount->setVisible(true); + + if (strcmp(a->service(), "Twitch") == 0) + ui->bandwidthTestEnable->setVisible(true); + } + + ui->streamStackWidget->setCurrentIndex((int)Section::StreamKey); +#endif +} + +void OBSBasicSettings::OnAuthConnected() +{ + std::string service = QT_TO_UTF8(ui->service->currentText()); + Auth::Type type = Auth::AuthType(service); + + if (type == Auth::Type::OAuth_StreamKey) { + OnOAuthStreamKeyConnected(); + } + + if (!loading) { + stream1Changed = true; + EnableApplyButton(true); + } +} + +void OBSBasicSettings::on_connectAccount_clicked() +{ +#ifdef BROWSER_AVAILABLE + std::string service = QT_TO_UTF8(ui->service->currentText()); + + auth = OAuthStreamKey::Login(this, service); + if (!!auth) + OnAuthConnected(); +#endif +} + +#define DISCONNECT_COMFIRM_TITLE \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title" +#define DISCONNECT_COMFIRM_TEXT \ + "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text" + +void OBSBasicSettings::on_disconnectAccount_clicked() +{ + QMessageBox::StandardButton button; + + button = OBSMessageBox::question(this, + QTStr(DISCONNECT_COMFIRM_TITLE), + QTStr(DISCONNECT_COMFIRM_TEXT)); + + if (button == QMessageBox::No) { + return; + } + + main->auth.reset(); + auth.reset(); + + std::string service = QT_TO_UTF8(ui->service->currentText()); + +#ifdef BROWSER_AVAILABLE + OAuth::DeleteCookies(service); +#endif + + ui->streamKeyWidget->setVisible(true); + ui->streamKeyLabel->setVisible(true); + ui->connectAccount2->setVisible(true); + ui->disconnectAccount->setVisible(false); + ui->bandwidthTestEnable->setVisible(false); + ui->key->setText(""); +} + +void OBSBasicSettings::on_useStreamKey_clicked() +{ + ui->streamStackWidget->setCurrentIndex((int)Section::StreamKey); +} + +void OBSBasicSettings::on_useAuth_toggled() +{ + if (!IsCustomService()) + return; + + bool use_auth = ui->useAuth->isChecked(); + + ui->authUsernameLabel->setVisible(use_auth); + ui->authUsername->setVisible(use_auth); + ui->authPwLabel->setVisible(use_auth); + ui->authPwWidget->setVisible(use_auth); +} diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp index 4701b7b..b66f65e 100644 --- a/UI/window-basic-settings.cpp +++ b/UI/window-basic-settings.cpp @@ -48,6 +48,7 @@ #include "window-projector.hpp" #include +#include "ui-config.h" using namespace std; @@ -280,8 +281,12 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) { string path; + EnableThreadedMessageBoxes(true); + ui->setupUi(this); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + main->EnableOutputs(false); PopulateAACBitrates({ui->simpleOutputABitrate, @@ -291,10 +296,6 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) ui->listWidget->setAttribute(Qt::WA_MacShowFocusRect, false); - auto policy = ui->audioSourceScrollArea->sizePolicy(); - policy.setVerticalStretch(true); - ui->audioSourceScrollArea->setSizePolicy(policy); - HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->theme, COMBO_CHANGED, GENERAL_CHANGED); HookWidget(ui->enableAutoUpdates, CHECK_CHANGED, GENERAL_CHANGED); @@ -316,14 +317,25 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->centerSnapping, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->sourceSnapping, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->snapDistance, DSCROLL_CHANGED,GENERAL_CHANGED); + HookWidget(ui->overflowHide, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->overflowAlwaysVisible,CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->overflowSelectionHide,CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->doubleClickSwitch, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->studioPortraitLayout, CHECK_CHANGED, GENERAL_CHANGED); + HookWidget(ui->prevProgLabelToggle, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->multiviewMouseSwitch, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->multiviewDrawNames, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->multiviewDrawAreas, CHECK_CHANGED, GENERAL_CHANGED); HookWidget(ui->multiviewLayout, COMBO_CHANGED, GENERAL_CHANGED); + HookWidget(ui->service, COMBO_CHANGED, STREAM1_CHANGED); + HookWidget(ui->server, COMBO_CHANGED, STREAM1_CHANGED); + HookWidget(ui->customServer, EDIT_CHANGED, STREAM1_CHANGED); + HookWidget(ui->key, EDIT_CHANGED, STREAM1_CHANGED); + HookWidget(ui->bandwidthTestEnable, CHECK_CHANGED, STREAM1_CHANGED); + HookWidget(ui->useAuth, CHECK_CHANGED, STREAM1_CHANGED); + HookWidget(ui->authUsername, EDIT_CHANGED, STREAM1_CHANGED); + HookWidget(ui->authPw, EDIT_CHANGED, STREAM1_CHANGED); HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED); - HookWidget(ui->streamType, COMBO_CHANGED, STREAM1_CHANGED); HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleNoSpace, CHECK_CHANGED, OUTPUTS_CHANGED); HookWidget(ui->simpleOutRecFormat, COMBO_CHANGED, OUTPUTS_CHANGED); @@ -410,6 +422,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->auxAudioDevice1, COMBO_CHANGED, AUDIO_CHANGED); HookWidget(ui->auxAudioDevice2, COMBO_CHANGED, AUDIO_CHANGED); HookWidget(ui->auxAudioDevice3, COMBO_CHANGED, AUDIO_CHANGED); + HookWidget(ui->auxAudioDevice4, COMBO_CHANGED, AUDIO_CHANGED); HookWidget(ui->baseResolution, CBEDIT_CHANGED, VIDEO_RES); HookWidget(ui->outputResolution, CBEDIT_CHANGED, VIDEO_RES); HookWidget(ui->downscaleFilter, COMBO_CHANGED, VIDEO_CHANGED); @@ -447,6 +460,13 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) HookWidget(ui->enableNewSocketLoop, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->enableLowLatencyMode, CHECK_CHANGED, ADV_CHANGED); HookWidget(ui->disableFocusHotkeys, CHECK_CHANGED, ADV_CHANGED); + HookWidget(ui->autoRemux, CHECK_CHANGED, ADV_CHANGED); + + ui->simpleOutputVBitrate->setSingleStep(50); + ui->simpleOutputVBitrate->setSuffix(" Kbps"); + ui->advOutFFVBitrate->setSingleStep(50); + ui->advOutFFVBitrate->setSuffix(" Kbps"); + ui->advOutFFABitrate->setSuffix(" Kbps"); #if !defined(_WIN32) && !defined(__APPLE__) delete ui->enableAutoUpdates; @@ -454,8 +474,8 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) #endif #if !defined(_WIN32) && !defined(__APPLE__) && !HAVE_PULSEAUDIO - delete ui->advAudioGroupBox; - ui->advAudioGroupBox = nullptr; + delete ui->audioAdvGroupBox; + ui->audioAdvGroupBox = nullptr; #endif #ifdef _WIN32 @@ -558,7 +578,6 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) installEventFilter(CreateShortcutFilter()); - LoadServiceTypes(); LoadEncoderTypes(); LoadColorRanges(); LoadFormats(); @@ -689,6 +708,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) obs_properties_destroy(ppts); + InitStreamPage(); LoadSettings(false); // Add warning checks to advanced output recording section controls @@ -708,6 +728,10 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent) this, SLOT(AdvOutRecCheckWarnings())); AdvOutRecCheckWarnings(); + ui->buttonBox->button(QDialogButtonBox::Apply)->setIcon(QIcon()); + ui->buttonBox->button(QDialogButtonBox::Ok)->setIcon(QIcon()); + ui->buttonBox->button(QDialogButtonBox::Cancel)->setIcon(QIcon()); + SimpleRecordingQualityChanged(); UpdateAutomaticReplayBufferCheckboxes(); @@ -722,6 +746,8 @@ OBSBasicSettings::~OBSBasicSettings() delete ui->filenameFormatting->completer(); main->EnableOutputs(true); App()->EnableInFocusHotkeys(!disableHotkeysInFocus); + + EnableThreadedMessageBoxes(false); } void OBSBasicSettings::SaveCombo(QComboBox *widget, const char *section, @@ -768,23 +794,6 @@ void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section, config_set_int(main->Config(), section, value, widget->value()); } -void OBSBasicSettings::LoadServiceTypes() -{ - const char *type; - size_t idx = 0; - - while (obs_enum_service_types(idx++, &type)) { - const char *name = obs_service_get_display_name(type); - QString qName = QT_UTF8(name); - QString qType = QT_UTF8(type); - - ui->streamType->addItem(qName, qType); - } - - type = obs_service_get_type(main->GetService()); - SetComboByValue(ui->streamType, type); -} - #define TEXT_USE_STREAM_ENC \ QTStr("Basic.Settings.Output.Adv.Recording.UseStreamEncoder") @@ -1001,17 +1010,31 @@ void OBSBasicSettings::LoadThemeList() } } + QString defaultTheme; + defaultTheme += DEFAULT_THEME; + defaultTheme += " "; + defaultTheme += QTStr("Default"); + /* Check shipped themes. */ QDirIterator uIt(QString(themeDir.c_str()), QStringList() << "*.qss", QDir::Files); while (uIt.hasNext()) { uIt.next(); QString name = uIt.fileName().section(".",0,0); - if (!uniqueSet.contains(name)) + + if (name == DEFAULT_THEME) + name = defaultTheme; + + if (!uniqueSet.contains(name) && name != "Default") ui->theme->addItem(name); } - int idx = ui->theme->findText(App()->GetTheme()); + std::string themeName = App()->GetTheme(); + + if (themeName == DEFAULT_THEME) + themeName = QT_TO_UTF8(defaultTheme); + + int idx = ui->theme->findText(themeName.c_str()); if (idx != -1) ui->theme->setCurrentIndex(idx); } @@ -1100,6 +1123,18 @@ void OBSBasicSettings::LoadGeneralSettings() "BasicWindow", "ProjectorAlwaysOnTop"); ui->projectorAlwaysOnTop->setChecked(projectorAlwaysOnTop); + bool overflowHide = config_get_bool(GetGlobalConfig(), + "BasicWindow", "OverflowHidden"); + ui->overflowHide->setChecked(overflowHide); + + bool overflowAlwaysVisible = config_get_bool(GetGlobalConfig(), + "BasicWindow", "OverflowAlwaysVisible"); + ui->overflowAlwaysVisible->setChecked(overflowAlwaysVisible); + + bool overflowSelectionHide = config_get_bool(GetGlobalConfig(), + "BasicWindow", "OverflowSelectionHidden"); + ui->overflowSelectionHide->setChecked(overflowSelectionHide); + bool doubleClickSwitch = config_get_bool(GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick"); ui->doubleClickSwitch->setChecked(doubleClickSwitch); @@ -1108,6 +1143,10 @@ void OBSBasicSettings::LoadGeneralSettings() "BasicWindow", "StudioPortraitLayout"); ui->studioPortraitLayout->setChecked(studioPortraitLayout); + bool prevProgLabels = config_get_bool(GetGlobalConfig(), + "BasicWindow", "StudioModeLabels"); + ui->prevProgLabelToggle->setChecked(prevProgLabels); + bool multiviewMouseSwitch = config_get_bool(GetGlobalConfig(), "BasicWindow", "MultiviewMouseSwitch"); ui->multiviewMouseSwitch->setChecked(multiviewMouseSwitch); @@ -1143,37 +1182,6 @@ void OBSBasicSettings::LoadGeneralSettings() loading = false; } -void OBSBasicSettings::LoadStream1Settings() -{ - QLayout *layout = ui->streamContainer->layout(); - obs_service_t *service = main->GetService(); - const char *type = obs_service_get_type(service); - - loading = true; - - obs_data_t *settings = obs_service_get_settings(service); - - delete streamProperties; - streamProperties = new OBSPropertiesView(settings, type, - (PropertiesReloadCallback)obs_get_service_properties, - 170); - - streamProperties->setProperty("changed", QVariant(false)); - layout->addWidget(streamProperties); - - QObject::connect(streamProperties, SIGNAL(Changed()), - this, STREAM1_CHANGED); - - obs_data_release(settings); - - loading = false; - - if (main->StreamingActive()) { - ui->streamType->setEnabled(false); - ui->streamContainer->setEnabled(false); - } -} - void OBSBasicSettings::LoadRendererList() { #ifdef _WIN32 @@ -1416,7 +1424,7 @@ void OBSBasicSettings::LoadVideoSettings() { loading = true; - if (video_output_active(obs_get_video())) { + if (obs_video_active()) { ui->videoPage->setEnabled(false); ui->videoMsg->setText( QTStr("Basic.Settings.Video.CurrentlyActive")); @@ -1772,8 +1780,8 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings() "FFVCustom"); int audioBitrate = config_get_int(main->Config(), "AdvOut", "FFABitrate"); - int audioTrack = config_get_int(main->Config(), "AdvOut", - "FFAudioTrack"); + int audioMixes = config_get_int(main->Config(), "AdvOut", + "FFAudioMixes"); const char *aEncoder = config_get_string(main->Config(), "AdvOut", "FFAEncoder"); int aEncoderId = config_get_int(main->Config(), "AdvOut", @@ -1799,14 +1807,12 @@ void OBSBasicSettings::LoadAdvOutputFFmpegSettings() SelectEncoder(ui->advOutFFAEncoder, aEncoder, aEncoderId); ui->advOutFFACfg->setText(aEncCustom); - switch (audioTrack) { - case 1: ui->advOutFFTrack1->setChecked(true); break; - case 2: ui->advOutFFTrack2->setChecked(true); break; - case 3: ui->advOutFFTrack3->setChecked(true); break; - case 4: ui->advOutFFTrack4->setChecked(true); break; - case 5: ui->advOutFFTrack5->setChecked(true); break; - case 6: ui->advOutFFTrack6->setChecked(true); break; - } + ui->advOutFFTrack1->setChecked(audioMixes & (1 << 0)); + ui->advOutFFTrack2->setChecked(audioMixes & (1 << 1)); + ui->advOutFFTrack3->setChecked(audioMixes & (1 << 2)); + ui->advOutFFTrack4->setChecked(audioMixes & (1 << 3)); + ui->advOutFFTrack5->setChecked(audioMixes & (1 << 4)); + ui->advOutFFTrack6->setChecked(audioMixes & (1 << 5)); } void OBSBasicSettings::LoadAdvOutputAudioSettings() @@ -1895,7 +1901,7 @@ void OBSBasicSettings::LoadOutputSettings() LoadAdvOutputFFmpegSettings(); LoadAdvOutputAudioSettings(); - if (video_output_active(obs_get_video())) { + if (obs_video_active()) { ui->outputMode->setEnabled(false); ui->outputModeLabel->setEnabled(false); ui->simpleRecordingGroupBox->setEnabled(false); @@ -1962,7 +1968,7 @@ void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t *prop, deviceId = obs_data_get_string(settings, "device_id"); } - widget->addItem(QTStr("Disabled"), "disabled"); + widget->addItem(QTStr("Basic.Settings.Audio.Disabled"), "disabled"); for (size_t i = 0; i < count; i++) { const char *name = obs_property_list_item_name(prop, i); @@ -2004,6 +2010,7 @@ void OBSBasicSettings::LoadAudioDevices() LoadListValues(ui->auxAudioDevice1, inputs, 3); LoadListValues(ui->auxAudioDevice2, inputs, 4); LoadListValues(ui->auxAudioDevice3, inputs, 5); + LoadListValues(ui->auxAudioDevice4, inputs, 6); obs_properties_destroy(input_props); } @@ -2020,17 +2027,21 @@ void OBSBasicSettings::LoadAudioDevices() void OBSBasicSettings::LoadAudioSources() { + if (ui->audioSourceLayout->rowCount() > 0) { + QLayoutItem *forDeletion = ui->audioSourceLayout->takeAt(0); + delete forDeletion->widget(); + delete forDeletion; + } auto layout = new QFormLayout(); layout->setVerticalSpacing(15); layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - ui->audioSourceScrollArea->takeWidget()->deleteLater(); audioSourceSignals.clear(); audioSources.clear(); auto widget = new QWidget(); widget->setLayout(layout); - ui->audioSourceScrollArea->setWidget(widget); + ui->audioSourceLayout->addRow(widget); const char *enablePtm = Str("Basic.Settings.Audio.EnablePushToMute"); const char *ptmDelay = Str("Basic.Settings.Audio.PushToMuteDelay"); @@ -2109,6 +2120,8 @@ void OBSBasicSettings::LoadAudioSources() ptmCB, pttSB, pttCB, pttSB); auto label = new OBSSourceLabel(source); + label->setMinimumSize(QSize(170, 0)); + label->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter); connect(label, &OBSSourceLabel::Removed, [=]() { @@ -2134,9 +2147,9 @@ void OBSBasicSettings::LoadAudioSources() if (layout->rowCount() == 0) - ui->audioSourceScrollArea->hide(); + ui->audioHotkeysGroupBox->hide(); else - ui->audioSourceScrollArea->show(); + ui->audioHotkeysGroupBox->show(); } void OBSBasicSettings::LoadAudioSettings() @@ -2234,6 +2247,8 @@ void OBSBasicSettings::LoadAdvancedSettings() "RecRBTime"); int rbSize = config_get_int(main->Config(), "AdvOut", "RecRBSize"); + bool autoRemux = config_get_bool(main->Config(), "Video", + "AutoRemux"); loading = true; @@ -2260,6 +2275,7 @@ void OBSBasicSettings::LoadAdvancedSettings() ui->streamDelaySec->setValue(delaySec); ui->streamDelayPreserve->setChecked(preserveDelay); ui->streamDelayEnable->setChecked(enableDelay); + ui->autoRemux->setChecked(autoRemux); SetComboByName(ui->colorFormat, videoColorFormat); @@ -2269,7 +2285,7 @@ void OBSBasicSettings::LoadAdvancedSettings() if (!SetComboByValue(ui->bindToIP, bindIP)) SetInvalidValue(ui->bindToIP, bindIP, bindIP); - if (video_output_active(obs_get_video())) { + if (obs_video_active()) { ui->advancedVideoContainer->setEnabled(false); } @@ -2313,12 +2329,22 @@ void OBSBasicSettings::LoadAdvancedSettings() loading = false; } +#define TRUNCATE_TEXT_LENGTH 80 + template static inline void LayoutHotkey(obs_hotkey_id id, obs_hotkey_t *key, Func &&fun, const map> &keys) { auto *label = new OBSHotkeyLabel; - label->setText(obs_hotkey_get_description(key)); + QString text = QT_UTF8(obs_hotkey_get_description(key)); + + if (text.length() > TRUNCATE_TEXT_LENGTH) { + label->setProperty("fullName", text); + text = text.left(TRUNCATE_TEXT_LENGTH); + text += "...'"; + } + + label->setText(text); OBSHotkeyWidget *hw = nullptr; @@ -2344,7 +2370,19 @@ static QLabel *makeLabel(T &t, Func &&getName) template static QLabel *makeLabel(const OBSSource &source, Func &&) { - return new OBSSourceLabel(source); + OBSSourceLabel *label = new OBSSourceLabel(source); + label->setStyleSheet("font-weight: bold;"); + QString name = QT_UTF8(obs_source_get_name(source)); + + if (name.length() > TRUNCATE_TEXT_LENGTH) { + label->setToolTip(name); + name = name.left(TRUNCATE_TEXT_LENGTH); + name += "..."; + } + + label->setText(name); + + return label; } template @@ -2356,13 +2394,8 @@ static inline void AddHotkeys(QFormLayout &layout, if (hotkeys.empty()) return; - auto line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - layout.setItem(layout.rowCount(), QFormLayout::SpanningRole, new QSpacerItem(0, 10)); - layout.addRow(line); using tuple_type = std::tuple, QPointer>; @@ -2423,6 +2456,47 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) widget->setLayout(layout); ui->hotkeyPage->setWidget(widget); + auto filterLayout = new QGridLayout(); + auto filterWidget = new QWidget(); + filterWidget->setLayout(filterLayout); + + auto filterLabel = new QLabel(QTStr("Basic.Settings.Hotkeys.Filter")); + auto filter = new QLineEdit(); + + auto setRowVisible = [=](int row, bool visible, QLayoutItem *label) { + label->widget()->setVisible(visible); + + auto field = layout->itemAt(row, QFormLayout::FieldRole); + if (field) + field->widget()->setVisible(visible); + }; + + auto searchFunction = [=](const QString &text) { + for (int i = 0; i < layout->rowCount(); i++) { + auto label = layout->itemAt(i, QFormLayout::LabelRole); + if (label) { + OBSHotkeyLabel *item = + qobject_cast( + label->widget()); + if(item) { + if (item->text().toLower() + .contains(text.toLower())) + setRowVisible(i, true, label); + else + setRowVisible(i, false, label); + } + } + } + }; + + connect(filter, &QLineEdit::textChanged, + this, searchFunction); + + filterLayout->addWidget(filterLabel, 0, 0); + filterLayout->addWidget(filter, 0, 1); + + layout->addRow(filterWidget); + using namespace std; using encoders_elem_t = tuple, QPointer>; @@ -2582,7 +2656,12 @@ void OBSBasicSettings::LoadHotkeySettings(obs_hotkey_id ignoreKey) auto Update = [&](OBSHotkeyLabel *label, const QString &name, OBSHotkeyLabel *other, const QString &otherName) { - label->setToolTip(tt.arg(otherName)); + QString string = other->property("fullName").value(); + + if (string.isEmpty() || string.isNull()) + string = otherName; + + label->setToolTip(tt.arg(string)); label->setText(name + " *"); label->pairPartner = other; }; @@ -2627,13 +2706,19 @@ void OBSBasicSettings::SaveGeneralSettings() int themeIndex = ui->theme->currentIndex(); QString themeData = ui->theme->itemText(themeIndex); - string theme = themeData.toStdString(); + QString defaultTheme; + defaultTheme += DEFAULT_THEME; + defaultTheme += " "; + defaultTheme += QTStr("Default"); + + if (themeData == defaultTheme) + themeData = DEFAULT_THEME; if (WidgetChanged(ui->theme)) { config_set_string(GetGlobalConfig(), "General", "CurrentTheme", - theme.c_str()); + QT_TO_UTF8(themeData)); - App()->SetTheme(theme); + App()->SetTheme(themeData.toUtf8().constData()); } #if defined(_WIN32) || defined(__APPLE__) @@ -2666,6 +2751,18 @@ void OBSBasicSettings::SaveGeneralSettings() config_set_double(GetGlobalConfig(), "BasicWindow", "SnapDistance", ui->snapDistance->value()); + if (WidgetChanged(ui->overflowAlwaysVisible)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "OverflowAlwaysVisible", + ui->overflowAlwaysVisible->isChecked()); + if (WidgetChanged(ui->overflowHide)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "OverflowHidden", + ui->overflowHide->isChecked()); + if (WidgetChanged(ui->overflowSelectionHide)) + config_set_bool(GetGlobalConfig(), "BasicWindow", + "OverflowSelectionHidden", + ui->overflowSelectionHide->isChecked()); if (WidgetChanged(ui->doubleClickSwitch)) config_set_bool(GetGlobalConfig(), "BasicWindow", "TransitionOnDoubleClick", @@ -2731,6 +2828,14 @@ void OBSBasicSettings::SaveGeneralSettings() main->ResetUI(); } + if (WidgetChanged(ui->prevProgLabelToggle)) { + config_set_bool(GetGlobalConfig(), "BasicWindow", + "StudioModeLabels", + ui->prevProgLabelToggle->isChecked()); + + main->ResetUI(); + } + bool multiviewChanged = false; if (WidgetChanged(ui->multiviewMouseSwitch)) { config_set_bool(GetGlobalConfig(), "BasicWindow", @@ -2764,26 +2869,6 @@ void OBSBasicSettings::SaveGeneralSettings() OBSProjector::UpdateMultiviewProjectors(); } -void OBSBasicSettings::SaveStream1Settings() -{ - QString streamType = GetComboData(ui->streamType); - - obs_service_t *oldService = main->GetService(); - obs_data_t *hotkeyData = obs_hotkeys_save_service(oldService); - - obs_service_t *newService = obs_service_create(QT_TO_UTF8(streamType), - "default_service", streamProperties->GetSettings(), - hotkeyData); - - obs_data_release(hotkeyData); - if (!newService) - return; - - main->SetService(newService); - main->SaveService(); - obs_service_release(newService); -} - void OBSBasicSettings::SaveVideoSettings() { QString baseResolution = ui->baseResolution->currentText(); @@ -2892,6 +2977,7 @@ void OBSBasicSettings::SaveAdvancedSettings() SaveSpinBox(ui->reconnectRetryDelay, "Output", "RetryDelay"); SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries"); SaveComboData(ui->bindToIP, "Output", "BindIP"); + SaveCheckBox(ui->autoRemux, "Video", "AutoRemux"); #if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO QString newDevice = ui->monitoringDevice->currentData().toString(); @@ -3085,11 +3171,13 @@ void OBSBasicSettings::SaveOutputSettings() SaveSpinBox(ui->advOutFFABitrate, "AdvOut", "FFABitrate"); SaveEncoder(ui->advOutFFAEncoder, "AdvOut", "FFAEncoder"); SaveEdit(ui->advOutFFACfg, "AdvOut", "FFACustom"); - SaveTrackIndex(main->Config(), "AdvOut", "FFAudioTrack", - ui->advOutFFTrack1, ui->advOutFFTrack2, - ui->advOutFFTrack3, ui->advOutFFTrack4, - ui->advOutFFTrack5, ui->advOutFFTrack6); - + config_set_int(main->Config(), "AdvOut", "FFAudioMixes", + (ui->advOutFFTrack1->isChecked() ? (1 << 0) : 0) | + (ui->advOutFFTrack2->isChecked() ? (1 << 1) : 0) | + (ui->advOutFFTrack3->isChecked() ? (1 << 2) : 0) | + (ui->advOutFFTrack4->isChecked() ? (1 << 3) : 0) | + (ui->advOutFFTrack5->isChecked() ? (1 << 4) : 0) | + (ui->advOutFFTrack6->isChecked() ? (1 << 5) : 0)); SaveCombo(ui->advOutTrack1Bitrate, "AdvOut", "Track1Bitrate"); SaveCombo(ui->advOutTrack2Bitrate, "AdvOut", "Track2Bitrate"); SaveCombo(ui->advOutTrack3Bitrate, "AdvOut", "Track3Bitrate"); @@ -3225,6 +3313,8 @@ void OBSBasicSettings::SaveAudioSettings() "Basic.AuxDevice2", 4); UpdateAudioDevice(true, ui->auxAudioDevice3, "Basic.AuxDevice3", 5); + UpdateAudioDevice(true, ui->auxAudioDevice4, + "Basic.AuxDevice4", 6); main->SaveProject(); } @@ -3357,8 +3447,17 @@ void OBSBasicSettings::closeEvent(QCloseEvent *event) void OBSBasicSettings::on_theme_activated(int idx) { - string currT = ui->theme->itemText(idx).toStdString(); - App()->SetTheme(currT); + QString currT = ui->theme->itemText(idx); + + QString defaultTheme; + defaultTheme += DEFAULT_THEME; + defaultTheme += " "; + defaultTheme += QTStr("Default"); + + if (currT == defaultTheme) + currT = DEFAULT_THEME; + + App()->SetTheme(currT.toUtf8().constData()); } void OBSBasicSettings::on_listWidget_itemSelectionChanged() @@ -3395,30 +3494,6 @@ void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button) } } -void OBSBasicSettings::on_streamType_currentIndexChanged(int idx) -{ - if (loading) - return; - - QLayout *layout = ui->streamContainer->layout(); - QString streamType = ui->streamType->itemData(idx).toString(); - obs_data_t *settings = obs_service_defaults(QT_TO_UTF8(streamType)); - - delete streamProperties; - streamProperties = new OBSPropertiesView(settings, - QT_TO_UTF8(streamType), - (PropertiesReloadCallback)obs_get_service_properties, - 170); - - streamProperties->setProperty("changed", QVariant(true)); - layout->addWidget(streamProperties); - - QObject::connect(streamProperties, SIGNAL(Changed()), - this, STREAM1_CHANGED); - - obs_data_release(settings); -} - void OBSBasicSettings::on_simpleOutputBrowse_clicked() { QString dir = QFileDialog::getExistingDirectory(this, @@ -3460,35 +3535,50 @@ void OBSBasicSettings::on_advOutFFPathBrowse_clicked() void OBSBasicSettings::on_advOutEncoder_currentIndexChanged(int idx) { - if (loading) - return; - QString encoder = GetComboData(ui->advOutEncoder); - bool loadSettings = encoder == curAdvStreamEncoder; + if (!loading) { + bool loadSettings = encoder == curAdvStreamEncoder; - delete streamEncoderProps; - streamEncoderProps = CreateEncoderPropertyView(QT_TO_UTF8(encoder), - loadSettings ? "streamEncoder.json" : nullptr, true); - ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); + delete streamEncoderProps; + streamEncoderProps = CreateEncoderPropertyView( + QT_TO_UTF8(encoder), + loadSettings ? "streamEncoder.json" : nullptr, + true); + ui->advOutputStreamTab->layout()->addWidget(streamEncoderProps); + } + + uint32_t caps = obs_get_encoder_caps(QT_TO_UTF8(encoder)); + + if (caps & OBS_ENCODER_CAP_PASS_TEXTURE) { + ui->advOutUseRescale->setChecked(false); + ui->advOutUseRescale->setVisible(false); + ui->advOutRescale->setVisible(false); + } else { + ui->advOutUseRescale->setVisible(true); + ui->advOutRescale->setVisible(true); + } UNUSED_PARAMETER(idx); } void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx) { - if (loading) + if (!loading) { + delete recordEncoderProps; + recordEncoderProps = nullptr; + } + + if (idx <= 0) { + ui->advOutRecUseRescale->setChecked(false); + ui->advOutRecUseRescale->setVisible(false); + ui->advOutRecRescaleContainer->setVisible(false); return; + } - ui->advOutRecUseRescale->setEnabled(idx > 0); - ui->advOutRecRescaleContainer->setEnabled(idx > 0); - - delete recordEncoderProps; - recordEncoderProps = nullptr; - - if (idx > 0) { - QString encoder = GetComboData(ui->advOutRecEncoder); - bool loadSettings = encoder == curAdvRecordEncoder; + QString encoder = GetComboData(ui->advOutRecEncoder); + bool loadSettings = encoder == curAdvRecordEncoder; + if (!loading) { recordEncoderProps = CreateEncoderPropertyView( QT_TO_UTF8(encoder), loadSettings ? "recordEncoder.json" : nullptr, @@ -3497,6 +3587,17 @@ void OBSBasicSettings::on_advOutRecEncoder_currentIndexChanged(int idx) connect(recordEncoderProps, SIGNAL(Changed()), this, SLOT(AdvReplayBufferChanged())); } + + uint32_t caps = obs_get_encoder_caps(QT_TO_UTF8(encoder)); + + if (caps & OBS_ENCODER_CAP_PASS_TEXTURE) { + ui->advOutRecUseRescale->setChecked(false); + ui->advOutRecUseRescale->setVisible(false); + ui->advOutRecRescaleContainer->setVisible(false); + } else { + ui->advOutRecUseRescale->setVisible(true); + ui->advOutRecRescaleContainer->setVisible(true); + } } void OBSBasicSettings::on_advOutFFIgnoreCompat_stateChanged(int) @@ -3865,10 +3966,18 @@ void OBSBasicSettings::AdvOutRecCheckWarnings() warningMsg = QTStr("OutputWarnings.MultiTrackRecording"); } - if (ui->advOutRecFormat->currentText().compare("mp4") == 0) { + if (ui->advOutRecFormat->currentText().compare("mp4") == 0 || + ui->advOutRecFormat->currentText().compare("mov") == 0) { if (!warningMsg.isEmpty()) warningMsg += "\n\n"; warningMsg += QTStr("OutputWarnings.MP4Recording"); + ui->autoRemux->setText( + QTStr("Basic.Settings.Advanced.AutoRemux") + + " " + + QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); + } else { + ui->autoRemux->setText( + QTStr("Basic.Settings.Advanced.AutoRemux")); } delete advOutRecWarning; @@ -3945,7 +4054,7 @@ void OBSBasicSettings::UpdateStreamDelayEstimate() UpdateAutomaticReplayBufferCheckboxes(); } -static bool EncoderAvailable(const char *encoder) +bool EncoderAvailable(const char *encoder) { const char *val; int i = 0; @@ -4243,7 +4352,6 @@ void OBSBasicSettings::AdvReplayBufferChanged() ui->advRBEstimate->setText(QTStr(ESTIMATE_UNKNOWN_STR)); ui->advReplayBufferGroupBox->setVisible(!lossless && replayBufferEnabled); - ui->line_4->setVisible(!lossless && replayBufferEnabled); ui->advReplayBuf->setEnabled(!lossless); UpdateAutomaticReplayBufferCheckboxes(); @@ -4261,11 +4369,7 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged() OBSService service; if (stream1Changed) { - QString streamType = GetComboData(ui->streamType); - service = obs_service_create_private( - QT_TO_UTF8(streamType), nullptr, - streamProperties->GetSettings()); - obs_service_release(service); + service = SpawnTempService(); } else { service = main->GetService(); } @@ -4321,10 +4425,18 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged() } } - if (ui->simpleOutRecFormat->currentText().compare("mp4") == 0) { + if (ui->simpleOutRecFormat->currentText().compare("mp4") == 0 || + ui->simpleOutRecFormat->currentText().compare("mov") == 0) { if (!warning.isEmpty()) warning += "\n\n"; warning += QTStr("OutputWarnings.MP4Recording"); + ui->autoRemux->setText( + QTStr("Basic.Settings.Advanced.AutoRemux") + + " " + + QTStr("Basic.Settings.Advanced.AutoRemux.MP4")); + } else { + ui->autoRemux->setText( + QTStr("Basic.Settings.Advanced.AutoRemux")); } if (warning.isEmpty()) @@ -4421,3 +4533,38 @@ void OBSBasicSettings::on_disableOSXVSync_clicked() } #endif } + +void OBSBasicSettings::SetGeneralIcon(const QIcon &icon) +{ + ui->listWidget->item(0)->setIcon(icon); +} + +void OBSBasicSettings::SetStreamIcon(const QIcon &icon) +{ + ui->listWidget->item(1)->setIcon(icon); +} + +void OBSBasicSettings::SetOutputIcon(const QIcon &icon) +{ + ui->listWidget->item(2)->setIcon(icon); +} + +void OBSBasicSettings::SetAudioIcon(const QIcon &icon) +{ + ui->listWidget->item(3)->setIcon(icon); +} + +void OBSBasicSettings::SetVideoIcon(const QIcon &icon) +{ + ui->listWidget->item(4)->setIcon(icon); +} + +void OBSBasicSettings::SetHotkeysIcon(const QIcon &icon) +{ + ui->listWidget->item(5)->setIcon(icon); +} + +void OBSBasicSettings::SetAdvancedIcon(const QIcon &icon) +{ + ui->listWidget->item(6)->setIcon(icon); +} diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp index 585e535..f899da0 100644 --- a/UI/window-basic-settings.hpp +++ b/UI/window-basic-settings.hpp @@ -20,12 +20,15 @@ #include #include +#include #include #include #include -#include +#include + +#include "auth-base.hpp" class OBSBasic; class QAbstractButton; @@ -84,12 +87,28 @@ using OBSFFFormatDesc = std::unique_ptr ui; + std::shared_ptr auth; + bool generalChanged = false; bool stream1Changed = false; bool outputsChanged = false; @@ -185,7 +204,6 @@ private: bool QueryChanges(); - void LoadServiceTypes(); void LoadEncoderTypes(); void LoadColorRanges(); void LoadFormats(); @@ -207,6 +225,24 @@ private: void LoadLanguageList(); void LoadThemeList(); + /* stream */ + void InitStreamPage(); + inline bool IsCustomService() const; + void LoadServices(bool showAll); + void OnOAuthStreamKeyConnected(); + void OnAuthConnected(); + QString lastService; +private slots: + void UpdateServerList(); + void UpdateKeyLink(); + void on_show_clicked(); + void on_authPwShow_clicked(); + void on_connectAccount_clicked(); + void on_disconnectAccount_clicked(); + void on_useStreamKey_clicked(); + void on_useAuth_toggled(); +private: + /* output */ void LoadSimpleOutputSettings(); void LoadAdvOutputStreamingSettings(); @@ -255,7 +291,7 @@ private slots: void on_listWidget_itemSelectionChanged(); void on_buttonBox_clicked(QAbstractButton *button); - void on_streamType_currentIndexChanged(int idx); + void on_service_currentIndexChanged(int idx); void on_simpleOutputBrowse_clicked(); void on_advOutRecPathBrowse_clicked(); void on_advOutFFPathBrowse_clicked(); @@ -306,6 +342,16 @@ private slots: void SimpleStreamingEncoderChanged(); + OBSService SpawnTempService(); + + void SetGeneralIcon(const QIcon &icon); + void SetStreamIcon(const QIcon &icon); + void SetOutputIcon(const QIcon &icon); + void SetAudioIcon(const QIcon &icon); + void SetVideoIcon(const QIcon &icon); + void SetHotkeysIcon(const QIcon &icon); + void SetAdvancedIcon(const QIcon &icon); + protected: virtual void closeEvent(QCloseEvent *event); diff --git a/UI/window-basic-source-select.cpp b/UI/window-basic-source-select.cpp index da81782..171dc64 100644 --- a/UI/window-basic-source-select.cpp +++ b/UI/window-basic-source-select.cpp @@ -215,7 +215,7 @@ void OBSBasicSourceSelect::on_buttonBox_accepted() AddExisting(QT_TO_UTF8(item->text()), visible, false); } else { if (ui->sourceName->text().isEmpty()) { - OBSMessageBox::information(this, + OBSMessageBox::warning(this, QTStr("NoNameEntered.Title"), QTStr("NoNameEntered.Text")); return; @@ -254,6 +254,8 @@ OBSBasicSourceSelect::OBSBasicSourceSelect(OBSBasic *parent, const char *id_) ui (new Ui::OBSBasicSourceSelect), id (id_) { + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + ui->setupUi(this); ui->sourceList->setAttribute(Qt::WA_MacShowFocusRect, false); diff --git a/UI/window-basic-stats.cpp b/UI/window-basic-stats.cpp index b758c2f..0258067 100644 --- a/UI/window-basic-stats.cpp +++ b/UI/window-basic-stats.cpp @@ -4,6 +4,7 @@ #include "window-basic-main.hpp" #include "platform.hpp" #include "obs-app.hpp" +#include "qt-wrappers.hpp" #include #include @@ -15,6 +16,7 @@ #include #define TIMER_INTERVAL 2000 +#define REC_TIME_LEFT_INTERVAL 30000 static void setThemeID(QWidget *widget, const QString &themeID) { @@ -28,15 +30,32 @@ static void setThemeID(QWidget *widget, const QString &themeID) } } -OBSBasicStats::OBSBasicStats(QWidget *parent) +void OBSBasicStats::OBSFrontendEvent(enum obs_frontend_event event, void *ptr) +{ + OBSBasicStats *stats = reinterpret_cast(ptr); + + switch ((int)event) { + case OBS_FRONTEND_EVENT_RECORDING_STARTED: + stats->StartRecTimeLeft(); + break; + case OBS_FRONTEND_EVENT_RECORDING_STOPPED: + stats->ResetRecTimeLeft(); + break; + } +} + +OBSBasicStats::OBSBasicStats(QWidget *parent, bool closeable) : QWidget (parent), cpu_info (os_cpu_usage_info_start()), - timer (this) + timer (this), + recTimeLeft (this) { QVBoxLayout *mainLayout = new QVBoxLayout(); QGridLayout *topLayout = new QGridLayout(); outputLayout = new QGridLayout(); + bitrates.reserve(REC_TIME_LEFT_INTERVAL / TIMER_INTERVAL); + int row = 0; auto newStatBare = [&] (QString name, QWidget *label, int col) @@ -57,10 +76,12 @@ OBSBasicStats::OBSBasicStats(QWidget *parent) cpuUsage = new QLabel(this); hddSpace = new QLabel(this); + recordTimeLeft = new QLabel(this); memUsage = new QLabel(this); newStat("CPUUsage", cpuUsage, 0); newStat("HDDSpaceAvailable", hddSpace, 0); + newStat("DiskFullIn", recordTimeLeft, 0); newStat("MemoryUsage", memUsage, 0); fps = new QLabel(this); @@ -75,13 +96,15 @@ OBSBasicStats::OBSBasicStats(QWidget *parent) newStat("SkippedFrames", skippedFrames, 2); /* --------------------------------------------- */ - - QPushButton *closeButton = new QPushButton(QTStr("Close")); + QPushButton *closeButton = nullptr; + if(closeable) + closeButton = new QPushButton(QTStr("Close")); QPushButton *resetButton = new QPushButton(QTStr("Reset")); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addStretch(); buttonLayout->addWidget(resetButton); - buttonLayout->addWidget(closeButton); + if(closeable) + buttonLayout->addWidget(closeButton); /* --------------------------------------------- */ @@ -125,26 +148,35 @@ OBSBasicStats::OBSBasicStats(QWidget *parent) setLayout(mainLayout); /* --------------------------------------------- */ - - connect(closeButton, &QPushButton::clicked, [this] () {close();}); + if(closeable) + connect(closeButton, &QPushButton::clicked, + [this] () {close();}); connect(resetButton, &QPushButton::clicked, [this] () {Reset();}); - installEventFilter(CreateShortcutFilter()); + delete shortcutFilter; + shortcutFilter = CreateShortcutFilter(); + installEventFilter(shortcutFilter); resize(800, 280); - setWindowFlags(Qt::Window | - Qt::WindowMinimizeButtonHint | - Qt::WindowCloseButtonHint); + setWindowTitle(QTStr("Basic.Stats")); - setWindowIcon(QIcon(":/res/images/obs.png")); + setWindowIcon(QIcon::fromTheme("obs", QIcon(":/res/images/obs.png"))); + setWindowModality(Qt::NonModal); setAttribute(Qt::WA_DeleteOnClose, true); QObject::connect(&timer, &QTimer::timeout, this, &OBSBasicStats::Update); timer.setInterval(TIMER_INTERVAL); - timer.start(); + + if (isVisible()) + timer.start(); + Update(); + QObject::connect(&recTimeLeft, &QTimer::timeout, this, + &OBSBasicStats::RecordingTimeLeft); + recTimeLeft.setInterval(REC_TIME_LEFT_INTERVAL); + OBSBasic *main = reinterpret_cast(App()->GetMainWindow()); const char *geometry = config_get_string(main->Config(), @@ -163,6 +195,8 @@ OBSBasicStats::OBSBasicStats(QWidget *parent) size(), rect)); } } + + obs_frontend_add_event_callback(OBSFrontendEvent, this); } void OBSBasicStats::closeEvent(QCloseEvent *event) @@ -180,6 +214,9 @@ void OBSBasicStats::closeEvent(QCloseEvent *event) OBSBasicStats::~OBSBasicStats() { + obs_frontend_remove_event_callback(OBSFrontendEvent, this); + + delete shortcutFilter; os_cpu_usage_info_destroy(cpu_info); } @@ -272,7 +309,7 @@ void OBSBasicStats::Update() #define MBYTE (1024ULL * 1024ULL) #define GBYTE (1024ULL * 1024ULL * 1024ULL) #define TBYTE (1024ULL * 1024ULL * 1024ULL * 1024ULL) - uint64_t num_bytes = os_get_free_disk_space(path); + num_bytes = os_get_free_disk_space(path); QString abrv = QStringLiteral(" MB"); long double num; @@ -385,6 +422,45 @@ void OBSBasicStats::Update() outputLabels[0].Update(strOutput, false); outputLabels[1].Update(recOutput, true); + + if (obs_output_active(recOutput)) { + long double kbps = outputLabels[1].kbps; + bitrates.push_back(kbps); + } +} + +void OBSBasicStats::StartRecTimeLeft() +{ + recordTimeLeft->setText(QTStr("Calculating")); + recTimeLeft.start(); +} + +void OBSBasicStats::ResetRecTimeLeft() +{ + bitrates.clear(); + recTimeLeft.stop(); + recordTimeLeft->setText(QTStr("")); +} + +void OBSBasicStats::RecordingTimeLeft() +{ + long double averageBitrate = accumulate(bitrates.begin(), + bitrates.end(), 0.0) / + (long double)bitrates.size(); + long double bytesPerSec = (averageBitrate / 8.0l) * 1000.0l; + long double secondsUntilFull = (long double)num_bytes / bytesPerSec; + + bitrates.clear(); + + int totalMinutes = (int)secondsUntilFull / 60; + int minutes = totalMinutes % 60; + int hours = totalMinutes / 60; + + QString text; + text.sprintf("%d %s, %d %s", hours, QT_TO_UTF8(QTStr("Hours")), + minutes, QT_TO_UTF8(QTStr("Minutes"))); + recordTimeLeft->setText(text); + recordTimeLeft->setMinimumWidth(recordTimeLeft->width()); } void OBSBasicStats::Reset() @@ -420,8 +496,7 @@ void OBSBasicStats::OutputLabels::Update(obs_output_t *output, bool rec) uint64_t bitsBetween = (bytesSent - lastBytesSent) * 8; long double timePassed = (long double)(curTime - lastBytesSentTime) / 1000000000.0l; - long double kbps = (long double)bitsBetween / - timePassed / 1000.0l; + kbps = (long double)bitsBetween / timePassed / 1000.0l; if (timePassed < 0.01l) kbps = 0.0l; @@ -500,3 +575,13 @@ void OBSBasicStats::OutputLabels::Reset(obs_output_t *output) first_total = obs_output_get_total_frames(output); first_dropped = obs_output_get_frames_dropped(output); } + +void OBSBasicStats::showEvent(QShowEvent *) +{ + timer.start(TIMER_INTERVAL); +} + +void OBSBasicStats::hideEvent(QHideEvent *) +{ + timer.stop(); +} diff --git a/UI/window-basic-stats.hpp b/UI/window-basic-stats.hpp index a719b7d..8a44e42 100644 --- a/UI/window-basic-stats.hpp +++ b/UI/window-basic-stats.hpp @@ -17,6 +17,7 @@ class OBSBasicStats : public QWidget { QLabel *fps = nullptr; QLabel *cpuUsage = nullptr; QLabel *hddSpace = nullptr; + QLabel *recordTimeLeft = nullptr; QLabel *memUsage = nullptr; QLabel *renderTime = nullptr; @@ -28,6 +29,9 @@ class OBSBasicStats : public QWidget { os_cpu_usage_info_t *cpu_info = nullptr; QTimer timer; + QTimer recTimeLeft; + uint64_t num_bytes = 0; + std::vector bitrates; struct OutputLabels { QPointer name; @@ -44,6 +48,8 @@ class OBSBasicStats : public QWidget { void Update(obs_output_t *output, bool rec); void Reset(obs_output_t *output); + + long double kbps = 0.0l; }; QList outputLabels; @@ -54,9 +60,24 @@ class OBSBasicStats : public QWidget { virtual void closeEvent(QCloseEvent *event) override; + static void OBSFrontendEvent(enum obs_frontend_event event, void *ptr); + public: - OBSBasicStats(QWidget *parent = nullptr); + OBSBasicStats(QWidget *parent = nullptr, bool closable = true); ~OBSBasicStats(); static void InitializeValues(); + + void StartRecTimeLeft(); + void ResetRecTimeLeft(); + +private: + QPointer shortcutFilter; + +private slots: + void RecordingTimeLeft(); + +protected: + virtual void showEvent(QShowEvent *event) override; + virtual void hideEvent(QHideEvent *event) override; }; diff --git a/UI/window-basic-transform.cpp b/UI/window-basic-transform.cpp index 1f529dd..7501d27 100644 --- a/UI/window-basic-transform.cpp +++ b/UI/window-basic-transform.cpp @@ -46,6 +46,8 @@ OBSBasicTransform::OBSBasicTransform(OBSBasic *parent) { ui->setupUi(this); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + HookWidget(ui->positionX, DSCROLL_CHANGED, SLOT(OnControlChanged())); HookWidget(ui->positionY, DSCROLL_CHANGED, SLOT(OnControlChanged())); HookWidget(ui->rotation, DSCROLL_CHANGED, SLOT(OnControlChanged())); diff --git a/UI/window-dock.cpp b/UI/window-dock.cpp new file mode 100644 index 0000000..840c4f7 --- /dev/null +++ b/UI/window-dock.cpp @@ -0,0 +1,38 @@ +#include "window-dock.hpp" +#include "obs-app.hpp" + +#include +#include + +void OBSDock::closeEvent(QCloseEvent *event) +{ + auto msgBox = [] () + { + QMessageBox msgbox(App()->GetMainWindow()); + msgbox.setWindowTitle(QTStr("DockCloseWarning.Title")); + msgbox.setText(QTStr("DockCloseWarning.Text")); + msgbox.setIcon(QMessageBox::Icon::Information); + msgbox.addButton(QMessageBox::Ok); + + QCheckBox *cb = new QCheckBox(QTStr("DoNotShowAgain")); + msgbox.setCheckBox(cb); + + msgbox.exec(); + + if (cb->isChecked()) { + config_set_bool(App()->GlobalConfig(), "General", + "WarnedAboutClosingDocks", true); + config_save_safe(App()->GlobalConfig(), "tmp", nullptr); + } + }; + + bool warned = config_get_bool(App()->GlobalConfig(), "General", + "WarnedAboutClosingDocks"); + if (!warned) { + QMetaObject::invokeMethod(App(), "Exec", + Qt::QueuedConnection, + Q_ARG(VoidFunc, msgBox)); + } + + QDockWidget::closeEvent(event); +} diff --git a/UI/window-dock.hpp b/UI/window-dock.hpp new file mode 100644 index 0000000..ccb1cf0 --- /dev/null +++ b/UI/window-dock.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +class OBSDock : public QDockWidget { + Q_OBJECT + +public: + inline OBSDock(QWidget *parent = nullptr) : QDockWidget(parent) {} + + virtual void closeEvent(QCloseEvent *event); +}; diff --git a/UI/window-license-agreement.cpp b/UI/window-license-agreement.cpp deleted file mode 100644 index a7a5f3b..0000000 --- a/UI/window-license-agreement.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include -#include -#include -#include "window-license-agreement.hpp" -#include "qt-wrappers.hpp" - -using namespace std; - -OBSLicenseAgreement::OBSLicenseAgreement(QWidget *parent) - : QDialog (parent), - ui (new Ui::OBSLicenseAgreement) -{ - ui->setupUi(this); - - string path; - if (!GetDataFilePath("license/gplv2.txt", path)) - throw "Could not find license file"; - - BPtr licenseText = os_quick_read_utf8_file(path.c_str()); - if (!licenseText || !*licenseText || strlen(licenseText) < 1000) - throw "Invalid license file data"; - - ui->license->setPlainText(QT_UTF8(licenseText)); -} diff --git a/UI/window-license-agreement.hpp b/UI/window-license-agreement.hpp deleted file mode 100644 index aa3a6f4..0000000 --- a/UI/window-license-agreement.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include "ui_OBSLicenseAgreement.h" - -class OBSLicenseAgreement : public QDialog { - Q_OBJECT - -private: - std::unique_ptr ui; - -public: - OBSLicenseAgreement(QWidget *parent); -}; diff --git a/UI/window-namedialog.cpp b/UI/window-namedialog.cpp index 0a90e97..18b2fee 100644 --- a/UI/window-namedialog.cpp +++ b/UI/window-namedialog.cpp @@ -45,6 +45,7 @@ bool NameDialog::AskForName(QWidget *parent, const QString &title, NameDialog dialog(parent); dialog.setWindowTitle(title); + dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); dialog.ui->label->setText(text); dialog.ui->userText->setMaxLength(maxSize); dialog.ui->userText->setText(placeHolder); diff --git a/UI/window-projector.cpp b/UI/window-projector.cpp index 2ee09f7..294c31d 100644 --- a/UI/window-projector.cpp +++ b/UI/window-projector.cpp @@ -30,15 +30,13 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, type = type_; if (isWindow) { - setWindowIcon(QIcon(":/res/images/obs.png")); + setWindowIcon(QIcon::fromTheme("obs", + QIcon(":/res/images/obs.png"))); UpdateProjectorTitle(projectorTitle); windowedProjectors.push_back(this); resize(480, 270); - - SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), - "BasicWindow", "ProjectorAlwaysOnTop")); } else { setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint); @@ -51,10 +49,11 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, addAction(action); connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered())); - - SetAlwaysOnTop(this, true); } + SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(), + "BasicWindow", "ProjectorAlwaysOnTop")); + setAttribute(Qt::WA_DeleteOnClose, true); //disable application quit when last window closed @@ -68,14 +67,13 @@ OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor, obs_display_add_draw_callback(GetDisplay(), isMultiview ? OBSRenderMultiview : OBSRender, this); - obs_display_set_background_color(GetDisplay(), 0x000000); }; connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback); bool hideCursor = config_get_bool(GetGlobalConfig(), "BasicWindow", "HideProjectorCursor"); - if (hideCursor && !isWindow) { + if (hideCursor && !isWindow && type != ProjectorType::Multiview) { QPixmap empty(16, 16); empty.fill(Qt::transparent); setCursor(QCursor(empty)); @@ -228,28 +226,6 @@ static OBSSource CreateLabel(const char *name, size_t h) return txtSource; } -static inline void renderVB(gs_effect_t *effect, gs_vertbuffer_t *vb, - int cx, int cy) -{ - if (!vb) - return; - - matrix4 transform; - matrix4_identity(&transform); - transform.x.x = cx; - transform.y.y = cy; - - gs_load_vertexbuffer(vb); - - gs_matrix_push(); - gs_matrix_mul(&transform); - - while (gs_effect_loop(effect, "Solid")) - gs_draw(GS_LINESTRIP, 0, 0); - - gs_matrix_pop(); -} - static inline uint32_t labelOffset(obs_source_t *label, uint32_t cx) { uint32_t w = obs_source_get_width(label); @@ -591,6 +567,9 @@ void OBSProjector::OBSRenderMultiview(void *data, uint32_t cx, uint32_t cy) window->offset = labelOffset(programLabel, window->pvwprgCX); calcPreviewProgram(true); + paintAreaWithColor(window->sourceX, window->sourceY, window->ppiCX, + window->ppiCY, backgroundColor); + // Scale and Draw the program gs_matrix_push(); gs_matrix_translate3f(window->sourceX, window->sourceY, 0.0f); @@ -673,6 +652,7 @@ void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy) obs_source_dec_showing(source); obs_source_inc_showing(curSource); source = curSource; + window->source = source; } } diff --git a/UI/window-remux.cpp b/UI/window-remux.cpp index 92de804..f6fa08b 100644 --- a/UI/window-remux.cpp +++ b/UI/window-remux.cpp @@ -20,9 +20,18 @@ #include "obs-app.hpp" #include +#include #include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include "qt-wrappers.hpp" @@ -31,42 +40,664 @@ using namespace std; -OBSRemux::OBSRemux(const char *path, QWidget *parent) - : QDialog (parent), - worker (new RemuxWorker), - ui (new Ui::OBSRemux), - recPath (path) +enum RemuxEntryColumn { + State, + InputPath, + OutputPath, + + Count +}; + +enum RemuxEntryRole { + EntryStateRole = Qt::UserRole, + NewPathsToProcessRole +}; + +/********************************************************** + Delegate - Presents cells in the grid. +**********************************************************/ + +RemuxEntryPathItemDelegate::RemuxEntryPathItemDelegate(bool isOutput, + const QString &defaultPath) + : QStyledItemDelegate(), + isOutput(isOutput), + defaultPath(defaultPath) { +} + +QWidget *RemuxEntryPathItemDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem & /* option */, + const QModelIndex &index) const +{ + RemuxEntryState state = index.model() + ->index(index.row(), RemuxEntryColumn::State) + .data(RemuxEntryRole::EntryStateRole) + .value(); + if (state == RemuxEntryState::Pending || + state == RemuxEntryState::InProgress) { + // Never allow modification of rows that are + // in progress. + return Q_NULLPTR; + } else if (isOutput && state != RemuxEntryState::Ready) { + // Do not allow modification of output rows + // that aren't associated with a valid input. + return Q_NULLPTR; + } else if (!isOutput && state == RemuxEntryState::Complete) { + // Don't allow modification of rows that are + // already complete. + return Q_NULLPTR; + } else { + QSizePolicy buttonSizePolicy( + QSizePolicy::Policy::Minimum, + QSizePolicy::Policy::Expanding, + QSizePolicy::ControlType::PushButton); + + QWidget *container = new QWidget(parent); + + auto browseCallback = [this, container]() + { + const_cast(this) + ->handleBrowse(container); + }; + + auto clearCallback = [this, container]() + { + const_cast(this) + ->handleClear(container); + }; + + QHBoxLayout *layout = new QHBoxLayout(); + layout->setMargin(0); + layout->setSpacing(0); + + QLineEdit *text = new QLineEdit(); + text->setObjectName(QStringLiteral("text")); + text->setSizePolicy(QSizePolicy( + QSizePolicy::Policy::Expanding, + QSizePolicy::Policy::Expanding, + QSizePolicy::ControlType::LineEdit)); + layout->addWidget(text); + + QToolButton *browseButton = new QToolButton(); + browseButton->setText("..."); + browseButton->setSizePolicy(buttonSizePolicy); + layout->addWidget(browseButton); + + container->connect(browseButton, &QToolButton::clicked, + browseCallback); + + // The "clear" button is not shown in output cells + // or the insertion point's input cell. + if (!isOutput && state != RemuxEntryState::Empty) { + QToolButton *clearButton = new QToolButton(); + clearButton->setText("X"); + clearButton->setSizePolicy(buttonSizePolicy); + layout->addWidget(clearButton); + + container->connect(clearButton, + &QToolButton::clicked, + clearCallback); + } + + container->setLayout(layout); + container->setFocusProxy(text); + return container; + } +} + +void RemuxEntryPathItemDelegate::setEditorData(QWidget *editor, + const QModelIndex &index) const +{ + QLineEdit *text = editor->findChild(); + text->setText(index.data().toString()); + QObject::connect(text, SIGNAL(textEdited(QString)), this, SLOT(updateText())); + editor->setProperty(PATH_LIST_PROP, QVariant()); +} + +void RemuxEntryPathItemDelegate::setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const +{ + // We use the PATH_LIST_PROP property to pass a list of + // path strings from the editor widget into the model's + // NewPathsToProcessRole. This is only used when paths + // are selected through the "browse" or "delete" buttons + // in the editor. If the user enters new text in the + // text box, we simply pass that text on to the model + // as normal text data in the default role. + QVariant pathListProp = editor->property(PATH_LIST_PROP); + if (pathListProp.isValid()) { + QStringList list = editor->property(PATH_LIST_PROP) + .toStringList(); + if (isOutput) { + if (list.size() > 0) + model->setData(index, list); + } else + model->setData(index, list, + RemuxEntryRole::NewPathsToProcessRole); + } else { + QLineEdit *lineEdit = editor->findChild(); + model->setData(index, lineEdit->text()); + } +} + +void RemuxEntryPathItemDelegate::paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + RemuxEntryState state = index.model() + ->index(index.row(), RemuxEntryColumn::State) + .data(RemuxEntryRole::EntryStateRole) + .value(); + + QStyleOptionViewItem localOption = option; + initStyleOption(&localOption, index); + + if (isOutput) { + if (state != Ready) { + QColor background = localOption.palette + .color(QPalette::ColorGroup::Disabled, + QPalette::ColorRole::Background); + + localOption.backgroundBrush = QBrush(background); + } + } + + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, + &localOption, painter); +} + +void RemuxEntryPathItemDelegate::handleBrowse(QWidget *container) +{ + QString OutputPattern = + "(*.mp4 *.flv *.mov *.mkv *.ts *.m3u8)"; + QString InputPattern = + "(*.flv *.mov *.mkv *.ts *.m3u8)"; + + QLineEdit *text = container->findChild(); + + QString currentPath = text->text(); + if (currentPath.isEmpty()) + currentPath = defaultPath; + + bool isSet = false; + if (isOutput) { + QString newPath = QFileDialog::getSaveFileName( + container, QTStr("Remux.SelectTarget"), + currentPath, OutputPattern); + + if (!newPath.isEmpty()) { + container->setProperty(PATH_LIST_PROP, + QStringList() << newPath); + isSet = true; + } + } else { + QStringList paths = QFileDialog::getOpenFileNames( + container, + QTStr("Remux.SelectRecording"), + currentPath, + QTStr("Remux.OBSRecording") + + QString(" ") + InputPattern); + + if (!paths.empty()) { + container->setProperty(PATH_LIST_PROP, paths); + isSet = true; + } + } + + if (isSet) + emit commitData(container); +} + +void RemuxEntryPathItemDelegate::handleClear(QWidget *container) +{ + // An empty string list will indicate that the entry is being + // blanked and should be deleted. + container->setProperty(PATH_LIST_PROP, QStringList()); + + emit commitData(container); +} + +void RemuxEntryPathItemDelegate::updateText() { + QLineEdit *lineEdit = dynamic_cast(sender()); + QWidget *editor = lineEdit->parentWidget(); + emit commitData(editor); +} + +/********************************************************** + Model - Manages the queue's data +**********************************************************/ + +int RemuxQueueModel::rowCount(const QModelIndex &) const +{ + return queue.length() + (isProcessing ? 0 : 1); +} + +int RemuxQueueModel::columnCount(const QModelIndex &) const +{ + return RemuxEntryColumn::Count; +} + +QVariant RemuxQueueModel::data(const QModelIndex &index, int role) const +{ + QVariant result = QVariant(); + + if (index.row() >= queue.length()) { + return QVariant(); + } else if (role == Qt::DisplayRole) { + switch (index.column()) { + case RemuxEntryColumn::InputPath: + result = queue[index.row()].sourcePath; + break; + case RemuxEntryColumn::OutputPath: + result = queue[index.row()].targetPath; + break; + } + } else if (role == Qt::DecorationRole && + index.column() == RemuxEntryColumn::State) { + result = getIcon(queue[index.row()].state); + } else if (role == RemuxEntryRole::EntryStateRole) { + result = queue[index.row()].state; + } + + return result; +} + +QVariant RemuxQueueModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + QVariant result = QVariant(); + + if (role == Qt::DisplayRole && + orientation == Qt::Orientation::Horizontal) { + switch (section) { + case RemuxEntryColumn::State: + result = QString(); + break; + case RemuxEntryColumn::InputPath: + result = QTStr("Remux.SourceFile"); + break; + case RemuxEntryColumn::OutputPath: + result = QTStr("Remux.TargetFile"); + break; + } + } + + return result; +} + +Qt::ItemFlags RemuxQueueModel::flags(const QModelIndex &index) const +{ + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + + if (index.column() == RemuxEntryColumn::InputPath) { + flags |= Qt::ItemIsEditable; + } else if (index.column() == RemuxEntryColumn::OutputPath && + index.row() != queue.length()) { + flags |= Qt::ItemIsEditable; + } + + return flags; +} + +bool RemuxQueueModel::setData(const QModelIndex &index, const QVariant &value, + int role) +{ + bool success = false; + + if (role == RemuxEntryRole::NewPathsToProcessRole) { + QStringList pathList = value.toStringList(); + + if (pathList.size() == 0) { + if (index.row() < queue.size()) { + beginRemoveRows(QModelIndex(), index.row(), + index.row()); + queue.removeAt(index.row()); + endRemoveRows(); + } + } else { + if (pathList.size() > 1 && index.row() < queue.length()) { + queue[index.row()].sourcePath = pathList[0]; + checkInputPath(index.row()); + + pathList.removeAt(0); + + success = true; + } + + if (pathList.size() > 0) { + int row = index.row(); + int lastRow = row + pathList.size() - 1; + beginInsertRows(QModelIndex(), row, lastRow); + + for (QString path : pathList) { + RemuxQueueEntry entry; + entry.sourcePath = path; + + queue.insert(row, entry); + row++; + } + endInsertRows(); + + for (row = index.row(); row <= lastRow; row++) { + checkInputPath(row); + } + + success = true; + } + } + } else if (index.row() == queue.length()) { + QString path = value.toString(); + + if (!path.isEmpty()) { + RemuxQueueEntry entry; + entry.sourcePath = path; + + beginInsertRows(QModelIndex(), queue.length() + 1, + queue.length() + 1); + queue.append(entry); + endInsertRows(); + + checkInputPath(index.row()); + success = true; + } + } else { + QString path = value.toString(); + + if (path.isEmpty()) { + if (index.column() == RemuxEntryColumn::InputPath) { + beginRemoveRows(QModelIndex(), index.row(), + index.row()); + queue.removeAt(index.row()); + endRemoveRows(); + } + } else { + switch (index.column()) { + case RemuxEntryColumn::InputPath: + queue[index.row()].sourcePath = value.toString(); + checkInputPath(index.row()); + success = true; + break; + case RemuxEntryColumn::OutputPath: + queue[index.row()].targetPath = value.toString(); + emit dataChanged(index, index); + success = true; + break; + } + } + } + + return success; +} + +QVariant RemuxQueueModel::getIcon(RemuxEntryState state) +{ + QVariant icon; + QStyle *style = QApplication::style(); + + switch (state) { + case RemuxEntryState::Complete: + icon = style->standardIcon( + QStyle::SP_DialogApplyButton); + break; + + case RemuxEntryState::InProgress: + icon = style->standardIcon( + QStyle::SP_ArrowRight); + break; + + case RemuxEntryState::Error: + icon = style->standardIcon( + QStyle::SP_DialogCancelButton); + break; + + case RemuxEntryState::InvalidPath: + icon = style->standardIcon( + QStyle::SP_MessageBoxWarning); + break; + + default: + break; + } + + return icon; +} + +void RemuxQueueModel::checkInputPath(int row) +{ + RemuxQueueEntry &entry = queue[row]; + + if (entry.sourcePath.isEmpty()) { + entry.state = RemuxEntryState::Empty; + } else { + QFileInfo fileInfo(entry.sourcePath); + if (fileInfo.exists()) + entry.state = RemuxEntryState::Ready; + else + entry.state = RemuxEntryState::InvalidPath; + + if (entry.state == RemuxEntryState::Ready) + entry.targetPath = fileInfo.path() + QDir::separator() + + fileInfo.completeBaseName() + ".mp4"; + } + + if (entry.state == RemuxEntryState::Ready && isProcessing) + entry.state = RemuxEntryState::Pending; + + emit dataChanged(index(row, 0), index(row, RemuxEntryColumn::Count)); +} + +QFileInfoList RemuxQueueModel::checkForOverwrites() const +{ + QFileInfoList list; + + for (const RemuxQueueEntry &entry : queue) { + if (entry.state == RemuxEntryState::Ready) { + QFileInfo fileInfo(entry.targetPath); + if (fileInfo.exists()) { + list.append(fileInfo); + } + } + } + + return list; +} + +bool RemuxQueueModel::checkForErrors() const +{ + bool hasErrors = false; + + for (const RemuxQueueEntry &entry : queue) { + if (entry.state == RemuxEntryState::Error) { + hasErrors = true; + break; + } + } + + return hasErrors; +} + +void RemuxQueueModel::clearAll() +{ + beginRemoveRows(QModelIndex(), 0, queue.size() - 1); + queue.clear(); + endRemoveRows(); +} + +void RemuxQueueModel::clearFinished() +{ + int index = 0; + + for (index = 0; index < queue.size(); index++) { + const RemuxQueueEntry &entry = queue[index]; + if (entry.state == RemuxEntryState::Complete) { + beginRemoveRows(QModelIndex(), index, index); + queue.removeAt(index); + endRemoveRows(); + index--; + } + } +} + +bool RemuxQueueModel::canClearFinished() const +{ + bool canClearFinished = false; + for (const RemuxQueueEntry &entry : queue) + if (entry.state == RemuxEntryState::Complete) { + canClearFinished = true; + break; + } + + return canClearFinished; +} + +void RemuxQueueModel::beginProcessing() +{ + for (RemuxQueueEntry &entry : queue) + if (entry.state == RemuxEntryState::Ready) + entry.state = RemuxEntryState::Pending; + + // Signal that the insertion point no longer exists. + beginRemoveRows(QModelIndex(), queue.length(), queue.length()); + endRemoveRows(); + + isProcessing = true; + + emit dataChanged(index(0, RemuxEntryColumn::State), + index(queue.length(), RemuxEntryColumn::State)); +} + +void RemuxQueueModel::endProcessing() +{ + for (RemuxQueueEntry &entry : queue) { + if (entry.state == RemuxEntryState::Pending) { + entry.state = RemuxEntryState::Ready; + } + } + + // Signal that the insertion point exists again. + + if (!autoRemux) { + beginInsertRows(QModelIndex(), queue.length(), queue.length()); + endInsertRows(); + } + + isProcessing = false; + + emit dataChanged(index(0, RemuxEntryColumn::State), + index(queue.length(), RemuxEntryColumn::State)); +} + +bool RemuxQueueModel::beginNextEntry(QString &inputPath, QString &outputPath) +{ + bool anyStarted = false; + + for (int row = 0; row < queue.length(); row++) { + RemuxQueueEntry &entry = queue[row]; + if (entry.state == RemuxEntryState::Pending) { + entry.state = RemuxEntryState::InProgress; + + inputPath = entry.sourcePath; + outputPath = entry.targetPath; + + QModelIndex index = this->index(row, + RemuxEntryColumn::State); + emit dataChanged(index, index); + + anyStarted = true; + break; + } + } + + return anyStarted; +} + +void RemuxQueueModel::finishEntry(bool success) +{ + for (int row = 0; row < queue.length(); row++) { + RemuxQueueEntry &entry = queue[row]; + if (entry.state == RemuxEntryState::InProgress) { + if (success) + entry.state = RemuxEntryState::Complete; + else + entry.state = RemuxEntryState::Error; + + QModelIndex index = this->index(row, + RemuxEntryColumn::State); + emit dataChanged(index, index); + + break; + } + } +} + +/********************************************************** + The actual remux window implementation +**********************************************************/ + +OBSRemux::OBSRemux(const char *path, QWidget *parent, bool autoRemux_) + : QDialog (parent), + queueModel(new RemuxQueueModel), + worker (new RemuxWorker()), + ui (new Ui::OBSRemux), + recPath (path), + autoRemux (autoRemux_) +{ + setAcceptDrops(true); + + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + ui->setupUi(this); ui->progressBar->setVisible(false); ui->buttonBox->button(QDialogButtonBox::Ok)-> setEnabled(false); - ui->targetFile->setEnabled(false); - ui->browseTarget->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> + setEnabled(false); + + if (autoRemux) { + resize(280, 40); + ui->tableView->hide(); + ui->buttonBox->hide(); + ui->label->hide(); + } ui->progressBar->setMinimum(0); ui->progressBar->setMaximum(1000); ui->progressBar->setValue(0); + ui->tableView->setModel(queueModel); + ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::InputPath, + new RemuxEntryPathItemDelegate(false, recPath)); + ui->tableView->setItemDelegateForColumn(RemuxEntryColumn::OutputPath, + new RemuxEntryPathItemDelegate(true, recPath)); + ui->tableView->horizontalHeader()->setSectionResizeMode( + QHeaderView::ResizeMode::Stretch); + ui->tableView->horizontalHeader()->setSectionResizeMode( + RemuxEntryColumn::State, + QHeaderView::ResizeMode::Fixed); + ui->tableView->setEditTriggers( + QAbstractItemView::EditTrigger::CurrentChanged); + installEventFilter(CreateShortcutFilter()); - connect(ui->browseSource, &QPushButton::clicked, - [&]() { BrowseInput(); }); - connect(ui->browseTarget, &QPushButton::clicked, - [&]() { BrowseOutput(); }); - - connect(ui->sourceFile, &QLineEdit::textChanged, - this, &OBSRemux::inputChanged); - ui->buttonBox->button(QDialogButtonBox::Ok)-> setText(QTStr("Remux.Remux")); + ui->buttonBox->button(QDialogButtonBox::Reset)-> + setText(QTStr("Remux.ClearFinished")); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> + setText(QTStr("Remux.ClearAll")); + ui->buttonBox->button(QDialogButtonBox::Reset)-> + setDisabled(true); connect(ui->buttonBox->button(QDialogButtonBox::Ok), - SIGNAL(clicked()), this, SLOT(Remux())); - + SIGNAL(clicked()), this, SLOT(beginRemux())); + connect(ui->buttonBox->button(QDialogButtonBox::Reset), + SIGNAL(clicked()), this, SLOT(clearFinished())); + connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults), + SIGNAL(clicked()), this, SLOT(clearAll())); connect(ui->buttonBox->button(QDialogButtonBox::Close), - SIGNAL(clicked()), this, SLOT(close())); + SIGNAL(clicked()), this, SLOT(close())); worker->moveToThread(&remuxer); remuxer.start(); @@ -79,107 +710,212 @@ OBSRemux::OBSRemux(const char *path, QWidget *parent) connect(worker_, &RemuxWorker::remuxFinished, this, &OBSRemux::remuxFinished); connect(this, &OBSRemux::remux, worker_, &RemuxWorker::remux); + + // Guessing the GCC bug mentioned above would also affect + // QPointer? Unsure. + RemuxQueueModel *queueModel_ = queueModel; + connect(queueModel_, + SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, + SLOT(rowCountChanged(const QModelIndex &, int, int))); + connect(queueModel_, + SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, + SLOT(rowCountChanged(const QModelIndex &, int, int))); + + QModelIndex index = queueModel->createIndex(0, 1); + QMetaObject::invokeMethod(ui->tableView, + "setCurrentIndex", Qt::QueuedConnection, + Q_ARG(const QModelIndex &, index)); } -bool OBSRemux::Stop() +bool OBSRemux::stopRemux() { - if (!worker->job) + if (!worker->isWorking) return true; + // By locking the worker thread's mutex, we ensure that its + // update poll will be blocked as long as we're in here with + // the popup open. + QMutexLocker lock(&worker->updateMutex); + + bool exit = false; + if (QMessageBox::critical(nullptr, - QTStr("Remux.ExitUnfinishedTitle"), - QTStr("Remux.ExitUnfinished"), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No) == + QTStr("Remux.ExitUnfinishedTitle"), + QTStr("Remux.ExitUnfinished"), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No) == QMessageBox::Yes) { - os_event_signal(worker->stop); - return true; + exit = true; } - return false; + if (exit) { + // Inform the worker it should no longer be + // working. It will interrupt accordingly in + // its next update callback. + worker->isWorking = false; + } + + return exit; } OBSRemux::~OBSRemux() { - Stop(); + stopRemux(); remuxer.quit(); remuxer.wait(); } -#define RECORDING_PATTERN "(*.flv *.mp4 *.mov *.mkv *.ts *.m3u8)" - -void OBSRemux::BrowseInput() +void OBSRemux::rowCountChanged(const QModelIndex &, int, int) { - QString path = ui->sourceFile->text(); - if (path.isEmpty()) - path = recPath; - - path = QFileDialog::getOpenFileName(this, - QTStr("Remux.SelectRecording"), path, - QTStr("Remux.OBSRecording") + QString(" ") + - RECORDING_PATTERN); - - inputChanged(path); + // See if there are still any rows ready to remux. Change + // the state of the "go" button accordingly. + // There must be more than one row, since there will always be + // at least one row for the empty insertion point. + if (queueModel->rowCount() > 1) { + ui->buttonBox->button(QDialogButtonBox::Ok)-> + setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> + setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Reset)-> + setEnabled(queueModel->canClearFinished()); + } else { + ui->buttonBox->button(QDialogButtonBox::Ok)-> + setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> + setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Reset)-> + setEnabled(false); + } } -void OBSRemux::inputChanged(const QString &path) +void OBSRemux::dropEvent(QDropEvent *ev) { - if (!QFileInfo::exists(path)) { - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(false); + QStringList urlList; + + for (QUrl url : ev->mimeData()->urls()) { + QFileInfo fileInfo(url.toLocalFile()); + + if (fileInfo.isDir()) { + QStringList directoryFilter; + directoryFilter << + "*.flv" << + "*.mp4" << + "*.mov" << + "*.mkv" << + "*.ts" << + "*.m3u8"; + + QDirIterator dirIter(fileInfo.absoluteFilePath(), + directoryFilter, QDir::Files, + QDirIterator::Subdirectories); + + while (dirIter.hasNext()) { + urlList.append(dirIter.next()); + } + } else { + urlList.append(fileInfo.canonicalFilePath()); + } + } + + if (urlList.empty()) { + QMessageBox::information(nullptr, + QTStr("Remux.NoFilesAddedTitle"), + QTStr("Remux.NoFilesAdded"), QMessageBox::Ok); + } else if (!autoRemux) { + QModelIndex insertIndex = queueModel->index( + queueModel->rowCount() - 1, + RemuxEntryColumn::InputPath); + queueModel->setData(insertIndex, urlList, + RemuxEntryRole::NewPathsToProcessRole); + } +} + +void OBSRemux::dragEnterEvent(QDragEnterEvent *ev) +{ + if (ev->mimeData()->hasUrls() && !worker->isWorking) + ev->accept(); +} + +void OBSRemux::beginRemux() +{ + if (worker->isWorking) { + stopRemux(); return; } - ui->sourceFile->setText(path); - ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(true); + bool proceedWithRemux = true; + QFileInfoList overwriteFiles = queueModel->checkForOverwrites(); - QFileInfo fi(path); - QString mp4 = fi.path() + "/" + fi.baseName() + ".mp4"; - ui->targetFile->setText(mp4); + if (!overwriteFiles.empty()) { + QString message = QTStr("Remux.FileExists"); + message += "\n\n"; - ui->targetFile->setEnabled(true); - ui->browseTarget->setEnabled(true); -} + for (QFileInfo fileInfo : overwriteFiles) + message += fileInfo.canonicalFilePath() + "\n"; -void OBSRemux::BrowseOutput() -{ - QString path(ui->targetFile->text()); - path = QFileDialog::getSaveFileName(this, QTStr("Remux.SelectTarget"), - path, RECORDING_PATTERN); + if (OBSMessageBox::question(this, + QTStr("Remux.FileExistsTitle"), message) + != QMessageBox::Yes) + proceedWithRemux = false; + } - if (path.isEmpty()) + if (!proceedWithRemux) return; - ui->targetFile->setText(path); -} - -void OBSRemux::Remux() -{ - if (QFileInfo::exists(ui->targetFile->text())) - if (OBSMessageBox::question(this, QTStr("Remux.FileExistsTitle"), - QTStr("Remux.FileExists")) != - QMessageBox::Yes) - return; - - media_remux_job_t mr_job = nullptr; - if (!media_remux_job_create(&mr_job, QT_TO_UTF8(ui->sourceFile->text()), - QT_TO_UTF8(ui->targetFile->text()))) - return; - - worker->job = job_t(mr_job, media_remux_job_destroy); - worker->lastProgress = 0.f; + // Set all jobs to "pending" first. + queueModel->beginProcessing(); ui->progressBar->setVisible(true); ui->buttonBox->button(QDialogButtonBox::Ok)-> - setEnabled(false); + setText(QTStr("Remux.Stop")); + setAcceptDrops(false); - emit remux(); + remuxNextEntry(); +} + +void OBSRemux::AutoRemux(QString inFile, QString outFile) +{ + if (inFile != "" && outFile != "" && autoRemux) { + emit remux(inFile, outFile); + autoRemuxFile = inFile; + } +} + +void OBSRemux::remuxNextEntry() +{ + worker->lastProgress = 0.f; + + QString inputPath, outputPath; + if (queueModel->beginNextEntry(inputPath, outputPath)) { + emit remux(inputPath, outputPath); + } else { + queueModel->autoRemux = autoRemux; + queueModel->endProcessing(); + + if (!autoRemux) { + OBSMessageBox::information(this, + QTStr("Remux.FinishedTitle"), + queueModel->checkForErrors() + ? QTStr("Remux.FinishedError") + : QTStr("Remux.Finished")); + } + + ui->progressBar->setVisible(autoRemux); + ui->buttonBox->button(QDialogButtonBox::Ok)-> + setText(QTStr("Remux.Remux")); + ui->buttonBox->button(QDialogButtonBox::RestoreDefaults)-> + setEnabled(true); + ui->buttonBox->button(QDialogButtonBox::Reset)-> + setEnabled(queueModel->canClearFinished()); + setAcceptDrops(true); + } } void OBSRemux::closeEvent(QCloseEvent *event) { - if (!Stop()) + if (!stopRemux()) event->ignore(); else QDialog::closeEvent(event); @@ -187,7 +923,7 @@ void OBSRemux::closeEvent(QCloseEvent *event) void OBSRemux::reject() { - if (!Stop()) + if (!stopRemux()) return; QDialog::reject(); @@ -200,27 +936,33 @@ void OBSRemux::updateProgress(float percent) void OBSRemux::remuxFinished(bool success) { - worker->job.reset(); - - OBSMessageBox::information(this, QTStr("Remux.FinishedTitle"), - success ? - QTStr("Remux.Finished") : QTStr("Remux.FinishedError")); - - ui->progressBar->setVisible(false); ui->buttonBox->button(QDialogButtonBox::Ok)-> setEnabled(true); + + queueModel->finishEntry(success); + + if (autoRemux && autoRemuxFile != "") { + QTimer::singleShot(3000, this, SLOT(close())); + } + + remuxNextEntry(); } -RemuxWorker::RemuxWorker() +void OBSRemux::clearFinished() { - os_event_init(&stop, OS_EVENT_TYPE_MANUAL); + queueModel->clearFinished(); } -RemuxWorker::~RemuxWorker() +void OBSRemux::clearAll() { - os_event_destroy(stop); + queueModel->clearAll(); } +/********************************************************** + Worker thread - Executes the libobs remux operation as a + background process. +**********************************************************/ + void RemuxWorker::UpdateProgress(float percent) { if (abs(lastProgress - percent) < 0.1f) @@ -230,16 +972,38 @@ void RemuxWorker::UpdateProgress(float percent) lastProgress = percent; } -void RemuxWorker::remux() +void RemuxWorker::remux(const QString &source, const QString &target) { + isWorking = true; + auto callback = [](void *data, float percent) { - auto rw = static_cast(data); + RemuxWorker *rw = static_cast(data); + + QMutexLocker lock(&rw->updateMutex); + rw->UpdateProgress(percent); - return !!os_event_try(rw->stop); + + return rw->isWorking; }; - bool success = media_remux_job_process(job.get(), callback, this); + bool stopped = false; + bool success = false; - emit remuxFinished(os_event_try(stop) && success); + media_remux_job_t mr_job = nullptr; + if (media_remux_job_create(&mr_job, + QT_TO_UTF8(source), + QT_TO_UTF8(target))) { + + success = media_remux_job_process(mr_job, callback, + this); + + media_remux_job_destroy(mr_job); + + stopped = !isWorking; + } + + isWorking = false; + + emit remuxFinished(!stopped && success); } diff --git a/UI/window-remux.hpp b/UI/window-remux.hpp index d689828..c98d45a 100644 --- a/UI/window-remux.hpp +++ b/UI/window-remux.hpp @@ -17,19 +17,36 @@ #pragma once +#include +#include #include #include +#include #include #include "ui_OBSRemux.h" #include #include +class RemuxQueueModel; class RemuxWorker; +enum RemuxEntryState +{ + Empty, + Ready, + Pending, + InProgress, + Complete, + InvalidPath, + Error +}; +Q_DECLARE_METATYPE(RemuxEntryState); + class OBSRemux : public QDialog { Q_OBJECT + QPointer queueModel; QThread remuxer; QPointer worker; @@ -37,46 +54,106 @@ class OBSRemux : public QDialog { const char *recPath; - void BrowseInput(); - void BrowseOutput(); - - bool Stop(); - virtual void closeEvent(QCloseEvent *event) override; virtual void reject() override; + bool autoRemux; + QString autoRemuxFile; + public: - explicit OBSRemux(const char *recPath, QWidget *parent = nullptr); + explicit OBSRemux(const char *recPath, QWidget *parent = nullptr, + bool autoRemux = false); virtual ~OBSRemux() override; using job_t = std::shared_ptr; + void AutoRemux(QString inFile, QString outFile); + +protected: + void dropEvent(QDropEvent *ev); + void dragEnterEvent(QDragEnterEvent *ev); + + void remuxNextEntry(); + private slots: - void inputChanged(const QString &str); + void rowCountChanged(const QModelIndex &parent, int first, int last); public slots: void updateProgress(float percent); void remuxFinished(bool success); - void Remux(); + void beginRemux(); + bool stopRemux(); + void clearFinished(); + void clearAll(); signals: - void remux(); + void remux(const QString &source, const QString &target); +}; + +class RemuxQueueModel : public QAbstractTableModel { + Q_OBJECT + + friend class OBSRemux; + +public: + RemuxQueueModel(QObject *parent = 0) + : QAbstractTableModel(parent) + , isProcessing(false) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role); + + QFileInfoList checkForOverwrites() const; + bool checkForErrors() const; + void beginProcessing(); + void endProcessing(); + bool beginNextEntry(QString &inputPath, QString &outputPath); + void finishEntry(bool success); + bool canClearFinished() const; + void clearFinished(); + void clearAll(); + + bool autoRemux = false; + +private: + struct RemuxQueueEntry + { + RemuxEntryState state; + + QString sourcePath; + QString targetPath; + }; + + QList queue; + bool isProcessing; + + static QVariant getIcon(RemuxEntryState state); + + void checkInputPath(int row); }; class RemuxWorker : public QObject { Q_OBJECT - OBSRemux::job_t job; - os_event_t *stop; + QMutex updateMutex; + + bool isWorking; float lastProgress; void UpdateProgress(float percent); - explicit RemuxWorker(); - virtual ~RemuxWorker(); + explicit RemuxWorker() + : isWorking(false) { } + virtual ~RemuxWorker() {}; private slots: - void remux(); + void remux(const QString &source, const QString &target); signals: void updateProgress(float percent); @@ -84,3 +161,34 @@ signals: friend class OBSRemux; }; + +class RemuxEntryPathItemDelegate : public QStyledItemDelegate { + Q_OBJECT + +public: + RemuxEntryPathItemDelegate(bool isOutput, const QString &defaultPath); + + virtual QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem & /* option */, + const QModelIndex &index) const override; + + virtual void setEditorData(QWidget *editor, const QModelIndex &index) + const override; + virtual void setModelData(QWidget *editor, + QAbstractItemModel *model, + const QModelIndex &index) const override; + virtual void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + +private: + bool isOutput; + QString defaultPath; + const char *PATH_LIST_PROP = "pathList"; + + void handleBrowse(QWidget *container); + void handleClear(QWidget *container); + +private slots: + void updateText(); +}; diff --git a/UI/xdg-data/CMakeLists.txt b/UI/xdg-data/CMakeLists.txt new file mode 100644 index 0000000..9acd14e --- /dev/null +++ b/UI/xdg-data/CMakeLists.txt @@ -0,0 +1,24 @@ +if(NOT DEFINED APPDATA_RELEASE_DATE) + if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + execute_process(COMMAND git log --tags -1 --pretty=%cd --date=short + OUTPUT_VARIABLE APPDATA_RELEASE_DATE + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + file(TIMESTAMP "${CMAKE_SOURCE_DIR}/CMakeLists.txt" APPDATA_RELEASE_DATE "%Y-%m-%d") + endif() +endif() + +configure_file( + com.obsproject.Studio.appdata.xml.in + com.obsproject.Studio.appdata.xml) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/com.obsproject.Studio.appdata.xml + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo) + +install(FILES com.obsproject.Studio.desktop + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) + +install(FILES ../forms/images/obs.png + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/256x256/apps + RENAME com.obsproject.Studio.png) diff --git a/UI/xdg-data/com.obsproject.Studio.appdata.xml.in b/UI/xdg-data/com.obsproject.Studio.appdata.xml.in new file mode 100644 index 0000000..6844e88 --- /dev/null +++ b/UI/xdg-data/com.obsproject.Studio.appdata.xml.in @@ -0,0 +1,23 @@ + + + com.obsproject.Studio + com.obsproject.Studio.desktop + CC0-1.0 + GPL-2.0 + OBS Studio + OBS Project + Live streaming and video recording software + +

Free and open source software for video capturing, recording, and live streaming.

+
+ https://obsproject.com + + + https://obsproject.com/assets/images/OBSDemoApp.jpg + + + + + + +
diff --git a/UI/dist/obs.desktop b/UI/xdg-data/com.obsproject.Studio.desktop similarity index 67% rename from UI/dist/obs.desktop rename to UI/xdg-data/com.obsproject.Studio.desktop index f70a77c..05f80d3 100644 --- a/UI/dist/obs.desktop +++ b/UI/xdg-data/com.obsproject.Studio.desktop @@ -1,11 +1,13 @@ [Desktop Entry] Version=1.0 -Name=OBS +Name=OBS Studio GenericName=Streaming/Recording Software +GenericName[fr]=Logiciel d'enregistrement/diffusion Comment=Free and Open Source Streaming/Recording Software +Comment[fr]=Logiciel libre d'enregistrement et de diffusion sur Internet Comment[ru]=Бесплатная программа с открытым кодом для записи/трансляции видео Exec=obs -Icon=obs +Icon=com.obsproject.Studio Terminal=false Type=Application Categories=AudioVideo;Recorder; diff --git a/appveyor.yml b/appveyor.yml index e679bfc..aa698b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,38 +1,39 @@ -image: Visual Studio 2017 +image: + - Ubuntu + - Visual Studio 2017 + environment: CURL_VERSION: 7.56.1 CEF_VERSION: 3.3440.1805.gbe070f9 + APPVEYOR_YML_DISABLE_PS_LINUX: true + TWITCH-CLIENTID: + secure: D3vFGk41HZaJWAZu5slwAHZhB868mGI2aIMS03L2rt4= + TWITCH-HASH: + secure: IRP5JLwBmPMjA7ADbZu6x2u4thqeEF9HaU1xolhaj74= + MIXER-CLIENTID: + secure: lQXRRvkeZDVSTUcSaR/kthiKu89K18IubKN913PC0ldjHBQ6sWa8a/t4i1f441N3RPfzAbTrXf2ijRCYYub2Qw== + MIXER-HASH: + secure: fIxeDxHkiNodwPeNGX+E9tSpyjg/XuT+U9N+jtpT7xU= + RESTREAM-CLIENTID: + secure: 4KGqX7PbL100GhXWzMFziaHrD/XT9/QKFTGinmPqwOkfRSMMEkUyL998/z3cclUd + RESTREAM-HASH: + secure: +tu/wCCG3tXnFpjzzXF6zyAOJyt8w48qx47K1bIn/Gs= install: - git submodule update --init --recursive - - if exist dependencies2017.zip (curl -kLO https://obsproject.com/downloads/dependencies2017.zip -f --retry 5 -z dependencies2017.zip) else (curl -kLO https://obsproject.com/downloads/dependencies2017.zip -f --retry 5 -C -) - - if exist vlc.zip (curl -kLO https://obsproject.com/downloads/vlc.zip -f --retry 5 -z vlc.zip) else (curl -kLO https://obsproject.com/downloads/vlc.zip -f --retry 5 -C -) - - if exist cef_binary_%CEF_VERSION%_windows32.zip (curl -kLO https://obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows32.zip) else (curl -kLO https://obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows32.zip -f --retry 5 -C -) - - if exist cef_binary_%CEF_VERSION%_windows64.zip (curl -kLO https://obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -z cef_binary_%CEF_VERSION%_windows64.zip) else (curl -kLO https://obsproject.com/downloads/cef_binary_%CEF_VERSION%_windows64.zip -f --retry 5 -C -) - - 7z x dependencies2017.zip -odependencies2017 - - 7z x vlc.zip -ovlc - - 7z x cef_binary_%CEF_VERSION%_windows32.zip -oCEF_32 - - 7z x cef_binary_%CEF_VERSION%_windows64.zip -oCEF_64 - - set DepsPath32=%CD%\dependencies2017\win32 - - set DepsPath64=%CD%\dependencies2017\win64 - - set VLCPath=%CD%\vlc - - set QTDIR32=C:\Qt\5.11.1\msvc2015 - - set QTDIR64=C:\Qt\5.11.1\msvc2017_64 - - set CEF_32=%CD%\CEF_32\cef_binary_%CEF_VERSION%_windows32 - - set CEF_64=%CD%\CEF_64\cef_binary_%CEF_VERSION%_windows64 - - set build_config=RelWithDebInfo - - mkdir build build32 build64 - - cd ./build32 - - cmake -G "Visual Studio 15 2017" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_32% .. - - cd ../build64 - - cmake -G "Visual Studio 15 2017 Win64" -DCOPIED_DEPENDENCIES=false -DCOPY_DEPENDENCIES=true -DBUILD_CAPTIONS=true -DCOMPILE_D3D12_HOOK=true -DBUILD_BROWSER=true -DCEF_ROOT_DIR=%CEF_64% .. + - cmd: C:\projects\obs-studio\CI\install-qt-win.cmd + - cmd: C:\projects\obs-studio\CI\install-script-win.cmd + - sh: ./CI/install-dependencies-linux-ubuntu16.sh + - sh: ./CI/before-script-linux.sh + - sh: ./CI/install-script-linux.sh build_script: - - call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build32\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - - call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build64\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + - cmd: call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build32\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + - cmd: call msbuild /m /p:Configuration=%build_config% C:\projects\obs-studio\build64\obs-studio.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" + - sh: cd ./build && make -j4 && cd - before_deploy: - - C:\projects\obs-studio\CI\before-deploy-win.cmd + - cmd: C:\projects\obs-studio\CI\before-deploy-win.cmd deploy_script: - ps: Push-AppveyorArtifact "build.zip" -FileName "$(git describe).zip" @@ -44,6 +45,7 @@ cache: - vlc.zip - 'cef_binary_%CEF_VERSION%_windows32.zip' - 'cef_binary_%CEF_VERSION%_windows64.zip' + - Qt_5.10.1.7z notifications: - provider: Webhook diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000..45fcdaf --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,108 @@ +# https://aka.ms/yaml + +variables: + CMAKE_PREFIX_PATH: /usr/local/opt/qt5/lib/cmake + CEF_BUILD_VERSION: 3.3282.1726.gc8368c8 + CEF_VERSION: 3.3440.1805.gbe070f9 + TWITCH-CLIENTID: $(twitch_clientid) + TWITCH-HASH: $(twitch_hash) + MIXER-CLIENTID: $(mixer_clientid) + MIXER-HASH: $(mixer_hash) + RESTREAM-CLIENTID: $(restream_clientid) + RESTREAM-HASH: $(restream_hash) + +jobs: +- job: 'Build_macOS' + pool: + vmImage: 'macos-10.13' + steps: + - script: git submodule update --init --recursive + displayName: 'Checkout Submodules' + - script: ./CI/install-dependencies-osx.sh + displayName: 'Install Dependencies' + + - script: ./CI/before-script-osx.sh + displayName: 'Cmake' + + - bash: | + cd ./build + make -j4 + cd - + displayName: 'Build' + + - script: ./CI/before-deploy-osx.sh + condition: ne(variables['Build.Reason'], 'PullRequest') + displayName: 'Before Deploy' + + - task: PublishBuildArtifacts@1 + condition: ne(variables['Build.Reason'], 'PullRequest') + inputs: + pathtoPublish: './nightly' + artifactName: build + +- job: 'Build_Windows32' + pool: + vmImage: 'vs2017-win2016' + steps: + - script: git submodule update --init --recursive + displayName: 'Checkout Submodules' + - script: ./CI/install-qt-win.cmd + displayName: 'Install QT' + - script: ./CI/install-script-win.cmd + displayName: 'Download / Setup Deps / Run CMake' + - task: MSBuild@1 + displayName: 'Build 32-bit' + inputs: + msbuildArguments: '/m /p:Configuration=RelWithDebInfo' + solution: .\build32\obs-studio.sln + - script: ./CI/before-deploy-win.cmd + condition: ne(variables['Build.Reason'], 'PullRequest') + displayName: 'Before deploy' + - task: PublishBuildArtifacts@1 + condition: ne(variables['Build.Reason'], 'PullRequest') + inputs: + pathtoPublish: './build' + artifactName: winbuild + +- job: 'Build_Windows64' + pool: + vmImage: 'vs2017-win2016' + steps: + - script: git submodule update --init --recursive + displayName: 'Checkout Submodules' + - script: ./CI/install-qt-win.cmd + displayName: 'Install QT' + - script: ./CI/install-script-win.cmd + displayName: 'Download / Setup Deps / Run CMake' + - task: MSBuild@1 + displayName: 'Build 64-bit' + inputs: + msbuildArguments: '/m /p:Configuration=RelWithDebInfo' + solution: .\build64\obs-studio.sln + - script: ./CI/before-deploy-win.cmd + condition: ne(variables['Build.Reason'], 'PullRequest') + displayName: 'Before deploy' + - task: PublishBuildArtifacts@1 + condition: ne(variables['Build.Reason'], 'PullRequest') + inputs: + pathtoPublish: './build' + artifactName: winbuild + +- job: 'Build_Linux' + pool: + vmImage: 'ubuntu-16.04' + steps: + - script: git submodule update --init --recursive + displayName: 'Checkout Submodules' + - script: ./CI/install-dependencies-linux.sh + displayName: 'Install Dependencies' + + - script: ./CI/before-script-linux.sh + displayName: 'CMake' + + - bash: | + cd ./build + make -j4 + cd - + displayName: 'Build' + diff --git a/cmake/Modules/CopyMSVCBins.cmake b/cmake/Modules/CopyMSVCBins.cmake index 855ce0a..d5c67cc 100644 --- a/cmake/Modules/CopyMSVCBins.cmake +++ b/cmake/Modules/CopyMSVCBins.cmake @@ -151,23 +151,36 @@ file(GLOB QT_DEBUG_BIN_FILES "${Qt5Core_DIR}/../../../bin/Qt5Cored.dll" "${Qt5Core_DIR}/../../../bin/Qt5Guid.dll" "${Qt5Core_DIR}/../../../bin/Qt5Widgetsd.dll" + "${Qt5Core_DIR}/../../../bin/Qt5Svgd.dll" + "${Qt5Core_DIR}/../../../bin/Qt5Xmld.dll" "${Qt5Core_DIR}/../../../bin/libGLESv2d.dll" "${Qt5Core_DIR}/../../../bin/libEGLd.dll") file(GLOB QT_DEBUG_PLAT_BIN_FILES "${Qt5Core_DIR}/../../../plugins/platforms/qwindowsd.dll") file(GLOB QT_DEBUG_STYLES_BIN_FILES "${Qt5Core_DIR}/../../../plugins/styles/qwindowsvistastyled.dll") +file(GLOB QT_DEBUG_ICONENGINE_BIN_FILES + "${Qt5Core_DIR}/../../../plugins/iconengines/qsvgicond.dll") +file(GLOB QT_DEBUG_IMAGEFORMATS_BIN_FILES + "${Qt5Core_DIR}/../../../plugins/imageformats/qsvgd.dll") + file(GLOB QT_BIN_FILES "${Qt5Core_DIR}/../../../bin/Qt5Core.dll" "${Qt5Core_DIR}/../../../bin/Qt5Gui.dll" "${Qt5Core_DIR}/../../../bin/Qt5Widgets.dll" + "${Qt5Core_DIR}/../../../bin/Qt5Svg.dll" + "${Qt5Core_DIR}/../../../bin/Qt5Xml.dll" "${Qt5Core_DIR}/../../../bin/libGLESv2.dll" "${Qt5Core_DIR}/../../../bin/libEGL.dll") file(GLOB QT_PLAT_BIN_FILES "${Qt5Core_DIR}/../../../plugins/platforms/qwindows.dll") file(GLOB QT_STYLES_BIN_FILES "${Qt5Core_DIR}/../../../plugins/styles/qwindowsvistastyle.dll") +file(GLOB QT_ICONENGINE_BIN_FILES + "${Qt5Core_DIR}/../../../plugins/iconengines/qsvgicon.dll") +file(GLOB QT_IMAGEFORMATS_BIN_FILES + "${Qt5Core_DIR}/../../../plugins/imageformats/qsvg.dll") file(GLOB QT_ICU_BIN_FILES "${Qt5Core_DIR}/../../../bin/icu*.dll") @@ -201,10 +214,24 @@ set(ALL_STYLES_REL_BIN_FILES set(ALL_STYLES_DBG_BIN_FILES ${QT_DEBUG_STYLES_BIN_FILES}) +set(ALL_ICONENGINE_BIN_FILES) +set(ALL_ICONENGINE_REL_BIN_FILES + ${QT_ICONENGINE_BIN_FILES}) +set(ALL_ICONENGINE_DBG_BIN_FILES + ${QT_DEBUG_ICONENGINE_BIN_FILES}) + +set(ALL_IMAGEFORMATS_BIN_FILES) +set(ALL_IMAGEFORMATS_REL_BIN_FILES + ${QT_IMAGEFORMATS_BIN_FILES}) +set(ALL_IMAGEFORMATS_DBG_BIN_FILES + ${QT_DEBUG_ICONENGINE_BIN_FILES}) + foreach(list ALL_BASE_BIN_FILES ALL_REL_BIN_FILES ALL_DBG_BIN_FILES ALL_PLATFORM_BIN_FILES ALL_PLATFORM_REL_BIN_FILES ALL_PLATFORM_DBG_BIN_FILES - ALL_STYLES_BIN_FILES ALL_STYLES_REL_BIN_FILES ALL_STYLES_DBG_BIN_FILES) + ALL_STYLES_BIN_FILES ALL_STYLES_REL_BIN_FILES ALL_STYLES_DBG_BIN_FILES + ALL_ICONENGINE_BIN_FILES ALL_ICONENGINE_REL_BIN_FILES ALL_ICONENGINE_DGB_BIN_FILES + ALL_IMAGEFORMATS_BIN_FILES ALL_IMAGEFORMATS_REL_BIN_FILES ALL_IMAGEFORMATS_DGB_BIN_FILES) if(${list}) list(REMOVE_DUPLICATES ${list}) endif() @@ -221,9 +248,13 @@ message(STATUS "zlib files: ${ZLIB_BIN_FILES}") message(STATUS "QT Debug files: ${QT_DEBUG_BIN_FILES}") message(STATUS "QT Debug Platform files: ${QT_DEBUG_PLAT_BIN_FILES}") message(STATUS "QT Debug Styles files: ${QT_DEBUG_STYLES_BIN_FILES}") +message(STATUS "QT Debug Iconengine files: ${QT_DEBUG_ICONENGINE_BIN_FILES}") +message(STATUS "QT Debug Imageformat files: ${QT_DEBUG_IMAGEFORMATS_BIN_FILES}") message(STATUS "QT Release files: ${QT_BIN_FILES}") message(STATUS "QT Release Platform files: ${QT_PLAT_BIN_FILES}") message(STATUS "QT Release Styles files: ${QT_STYLES_BIN_FILES}") +message(STATUS "QT Release Iconengine files: ${QT_REL_ICONENGINE_BIN_FILES}") +message(STATUS "QT Release Imageformat files: ${QT_REL_IMAGEFORMATS_BIN_FILES}") message(STATUS "QT ICU files: ${QT_ICU_BIN_FILES}") foreach(BinFile ${ALL_BASE_BIN_FILES}) @@ -271,4 +302,34 @@ foreach(BinFile ${ALL_STYLES_DBG_BIN_FILES}) file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}d/styles/") endforeach() +foreach(BinFile ${ALL_ICONENGINE_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}/iconengines") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}/iconengines/") +endforeach() + +foreach(BinFile ${ALL_ICONENGINE_REL_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}r/iconengines") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}r/iconengines/") +endforeach() + +foreach(BinFile ${ALL_ICONENGINE_DBG_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}d/iconengines") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}d/iconengines/") +endforeach() + +foreach(BinFile ${ALL_IMAGEFORMATS_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}/imageformats") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}/imageformats/") +endforeach() + +foreach(BinFile ${ALL_IMAGEFORMATS_REL_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}r/imageformats") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}r/imageformats/") +endforeach() + +foreach(BinFile ${ALL_IMAGEFORMATS_DBG_BIN_FILES}) + make_directory("${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}d/imageformats") + file(COPY "${BinFile}" DESTINATION "${CMAKE_SOURCE_DIR}/additional_install_files/exec${_bin_suffix}d/imageformats/") +endforeach() + set(COPIED_DEPENDENCIES TRUE CACHE BOOL "Dependencies have been copied, set to false to copy again" FORCE) diff --git a/cmake/Modules/FindLibVLC.cmake b/cmake/Modules/FindLibVLC.cmake index 3f68885..c8cb555 100644 --- a/cmake/Modules/FindLibVLC.cmake +++ b/cmake/Modules/FindLibVLC.cmake @@ -10,7 +10,7 @@ find_package(PkgConfig QUIET) if (PKG_CONFIG_FOUND) - pkg_check_modules(_VLC QUIET VLC) + pkg_check_modules(_VLC QUIET libvlc) endif() if(CMAKE_SIZEOF_VOID_P EQUAL 8) diff --git a/cmake/Modules/ObsHelpers.cmake b/cmake/Modules/ObsHelpers.cmake index c0073d7..627aadf 100644 --- a/cmake/Modules/ObsHelpers.cmake +++ b/cmake/Modules/ObsHelpers.cmake @@ -504,6 +504,30 @@ function(install_obs_data target datadir datadest) endif() endfunction() +function(install_obs_data_file target datafile datadest) + install(FILES ${datafile} + DESTINATION "${OBS_DATA_DESTINATION}/${datadest}") + add_custom_command(TARGET ${target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${OBS_OUTPUT_DIR}/$/data/${datadest}" + VERBATIM) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/${datafile}" "${OBS_OUTPUT_DIR}/$/data/${datadest}" + VERBATIM) + + if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND DEFINED ENV{obsInstallerTempDir}) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "$ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${datadest}" + VERBATIM) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "${CMAKE_CURRENT_SOURCE_DIR}/${datafile}" "$ENV{obsInstallerTempDir}/${OBS_DATA_DESTINATION}/${datadest}" + VERBATIM) + endif() +endfunction() + function(install_obs_datatarget target datadest) install(TARGETS ${target} LIBRARY DESTINATION "${OBS_DATA_DESTINATION}/${datadest}" diff --git a/debian/control b/debian/control index e83a484..71f655c 100644 --- a/debian/control +++ b/debian/control @@ -23,6 +23,7 @@ Build-Depends: libjansson-dev (>= 2.5), libluajit-5.1-dev, libpulse-dev, + libqt5svg5-dev, libqt5x11extras5-dev, libspeexdsp-dev, libswresample-dev, diff --git a/debian/patches/0001-Use-common-license.patch b/debian/patches/0001-Use-common-license.patch index d9c1450..15168f0 100644 --- a/debian/patches/0001-Use-common-license.patch +++ b/debian/patches/0001-Use-common-license.patch @@ -8,18 +8,22 @@ copy UI/window-license-agreement.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) -diff --git a/UI/window-license-agreement.cpp b/UI/window-license-agreement.cpp -index a7a5f3b..60cad40 100644 ---- a/UI/window-license-agreement.cpp -+++ b/UI/window-license-agreement.cpp -@@ -13,9 +13,7 @@ OBSLicenseAgreement::OBSLicenseAgreement(QWidget *parent) +--- a/UI/window-basic-about.cpp ++++ b/UI/window-basic-about.cpp +@@ -149,15 +149,10 @@ + + void OBSAbout::ShowLicense() { - ui->setupUi(this); +- std::string path; ++ std::string path("/usr/share/common-licenses/GPL-2"); + QString error = "Error! File could not be read.\n\n \ + Go to: https://github.com/obsproject/obs-studio/blob/master/COPYING"; -- string path; -- if (!GetDataFilePath("license/gplv2.txt", path)) -- throw "Could not find license file"; -+ string path("/usr/share/common-licenses/GPL-2"); +- if (!GetDataFilePath("license/gplv2.txt", path)) { +- ui->textBrowser->setPlainText(error); +- return; +- } +- + BPtr text = os_quick_read_utf8_file(path.c_str()); - BPtr licenseText = os_quick_read_utf8_file(path.c_str()); - if (!licenseText || !*licenseText || strlen(licenseText) < 1000) + if (!text || !*text) { diff --git a/debian/patches/0003-Use-path-in-usr-lib.patch b/debian/patches/0003-Use-path-in-usr-lib.patch index 8d657b7..ed4fa6d 100644 --- a/debian/patches/0003-Use-path-in-usr-lib.patch +++ b/debian/patches/0003-Use-path-in-usr-lib.patch @@ -6,18 +6,16 @@ Subject: Use path in /usr/lib plugins/obs-ffmpeg/obs-ffmpeg-mux.c | 4 ++++ 1 file changed, 4 insertions(+) -diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c -index 9b65276..60b0b8b 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c -@@ -237,7 +237,11 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd, +@@ -237,7 +237,11 @@ num_tracks++; } +#ifdef FFMPEG_MUX_FIXED + dstr_init_copy(cmd, FFMPEG_MUX_FIXED); +#else - dstr_init_move_array(cmd, obs_module_file(FFMPEG_MUX)); + dstr_init_move_array(cmd, os_get_executable_path_ptr(FFMPEG_MUX)); +#endif dstr_insert_ch(cmd, 0, '\"'); dstr_cat(cmd, "\" \""); diff --git a/debian/patches/0007-Add-SONAME.patch b/debian/patches/0006-Add-SONAME.patch similarity index 100% rename from debian/patches/0007-Add-SONAME.patch rename to debian/patches/0006-Add-SONAME.patch diff --git a/debian/patches/0006-Do-not-display-license-on-first-startup.patch b/debian/patches/0006-Do-not-display-license-on-first-startup.patch deleted file mode 100644 index baad04b..0000000 --- a/debian/patches/0006-Do-not-display-license-on-first-startup.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Chris Lamb -Date: Mon, 19 Feb 2018 21:32:07 +0100 -Subject: Do not display license on first startup - ---- - UI/obs-app.cpp | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp -index 52b15a0..186128c 100644 ---- a/UI/obs-app.cpp -+++ b/UI/obs-app.cpp -@@ -1216,8 +1216,7 @@ bool OBSApp::OBSInit() - { - ProfileScope("OBSApp::OBSInit"); - -- bool licenseAccepted = config_get_bool(globalConfig, "General", -- "LicenseAccepted"); -+ bool licenseAccepted = true; - OBSLicenseAgreement agreement(nullptr); - - if (licenseAccepted || agreement.exec() == QDialog::Accepted) { diff --git a/debian/patches/series b/debian/patches/series index 066dbfb..cf59670 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -3,5 +3,4 @@ 0003-Use-path-in-usr-lib.patch 0004-Link-with-libm-and-libdl-to-fix-underlinking.patch 0005-Link-with-xcb-and-X-libraries-to-fix-underlinking.patch -0006-Do-not-display-license-on-first-startup.patch -0007-Add-SONAME.patch +0006-Add-SONAME.patch diff --git a/debian/rules b/debian/rules index 34f6fbf..7704f71 100755 --- a/debian/rules +++ b/debian/rules @@ -4,7 +4,7 @@ include /usr/share/dpkg/architecture.mk include /usr/share/dpkg/pkg-info.mk export DEB_LDFLAGS_MAINT_APPEND=-Wl,--as-needed -export DEB_CPPFLAGS_MAINT_APPEND=-DFFMPEG_MUX_FIXED=\"/usr/lib/$(DEB_HOST_MULTIARCH)/obs-plugins/obs-ffmpeg/ffmpeg-mux\" +export DEB_CPPFLAGS_MAINT_APPEND=-DFFMPEG_MUX_FIXED=\"/usr/lib/$(DEB_HOST_MULTIARCH)/obs-plugins/obs-ffmpeg/obs-ffmpeg-mux\" %: dh $@ @@ -22,8 +22,8 @@ override_dh_auto_build: override_dh_install: mkdir -p debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/obs-plugins/obs-ffmpeg - mv debian/tmp/usr/share/obs/obs-plugins/obs-ffmpeg/ffmpeg-mux \ - debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/obs-plugins/obs-ffmpeg/ffmpeg-mux + mv debian/tmp/usr/bin/obs-ffmpeg-mux \ + debian/tmp/usr/lib/$(DEB_HOST_MULTIARCH)/obs-plugins/obs-ffmpeg/obs-ffmpeg-mux dh_install rm -rf debian/obs-studio/usr/share/obs/obs-studio/license diff --git a/deps/ipc-util/CMakeLists.txt b/deps/ipc-util/CMakeLists.txt index 8b2e672..ac61039 100644 --- a/deps/ipc-util/CMakeLists.txt +++ b/deps/ipc-util/CMakeLists.txt @@ -23,7 +23,7 @@ else() endif() if(MSVC) - add_compile_options("$<$:/MT>") + add_compile_options($,/MTd,/MT> /Zl) endif() add_library(ipc-util STATIC diff --git a/deps/media-playback/CMakeLists.txt b/deps/media-playback/CMakeLists.txt index ae5b3c5..3accdd8 100644 --- a/deps/media-playback/CMakeLists.txt +++ b/deps/media-playback/CMakeLists.txt @@ -22,7 +22,12 @@ add_library(media-playback STATIC ${media-playback_SOURCES} ) -if(NOT MSVC) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") + target_compile_options(media-playback + PUBLIC + -mvsx) + add_compile_definitions(NO_WARN_X86_INTRINSICS) +elseif(NOT MSVC) target_compile_options(media-playback PUBLIC -mmmx diff --git a/deps/media-playback/media-playback/closest-format.h b/deps/media-playback/media-playback/closest-format.h index 4a0c25e..8377914 100644 --- a/deps/media-playback/media-playback/closest-format.h +++ b/deps/media-playback/media-playback/closest-format.h @@ -21,6 +21,8 @@ static enum AVPixelFormat closest_format(enum AVPixelFormat fmt) switch (fmt) { case AV_PIX_FMT_YUYV422: return AV_PIX_FMT_YUYV422; + case AV_PIX_FMT_YUV444P: + return AV_PIX_FMT_YUV444P; case AV_PIX_FMT_YUV422P: case AV_PIX_FMT_YUVJ422P: diff --git a/deps/media-playback/media-playback/media.c b/deps/media-playback/media-playback/media.c index e335e23..426380d 100644 --- a/deps/media-playback/media-playback/media.c +++ b/deps/media-playback/media-playback/media.c @@ -34,6 +34,7 @@ static inline enum video_format convert_pixel_format(int f) case AV_PIX_FMT_YUV420P: return VIDEO_FORMAT_I420; case AV_PIX_FMT_NV12: return VIDEO_FORMAT_NV12; case AV_PIX_FMT_YUYV422: return VIDEO_FORMAT_YUY2; + case AV_PIX_FMT_YUV444P: return VIDEO_FORMAT_I444; case AV_PIX_FMT_UYVY422: return VIDEO_FORMAT_UYVY; case AV_PIX_FMT_RGBA: return VIDEO_FORMAT_RGBA; case AV_PIX_FMT_BGRA: return VIDEO_FORMAT_BGRA; diff --git a/deps/obs-scripting/CMakeLists.txt b/deps/obs-scripting/CMakeLists.txt index 835c1b3..92fb1b9 100644 --- a/deps/obs-scripting/CMakeLists.txt +++ b/deps/obs-scripting/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 2.8) if(NOT ENABLE_SCRIPTING) + message(STATUS "Scripting plugin disabled") return() endif() @@ -11,13 +12,54 @@ if(MSVC) w32-pthreads) endif() -find_package(Luajit QUIET) -find_package(PythonDeps QUIET) -find_package(SwigDeps QUIET 2) +option(DISABLE_LUA "Disable Lua scripting support" OFF) +option(DISABLE_PYTHON "Disable Python scripting support" OFF) set(COMPILE_PYTHON FALSE CACHE BOOL "" FORCE) set(COMPILE_LUA FALSE CACHE BOOL "" FORCE) +if(NOT DISABLE_LUA) + find_package(Luajit QUIET) + + if(NOT DISABLE_LUA AND NOT LUAJIT_FOUND) + message(STATUS "Luajit support not found.") + set(LUAJIT_FOUND FALSE) + else() + message(STATUS "Scripting: Luajit supported") + set(COMPILE_LUA TRUE CACHE BOOL "" FORCE) + endif() +else() + message(STATUS "Scripting: Luajit support disabled") + set(LUAJIT_FOUND FALSE) +endif() + +if(NOT DISABLE_PYTHON) + find_package(PythonDeps QUIET) + + if(NOT DISABLE_PYTHON AND NOT PYTHONLIBS_FOUND) + message(STATUS "Python support not found.") + set(PYTHON_FOUND FALSE) + set(PYTHONLIBS_FOUND FALSE) + else() + message(STATUS "Scripting: Python 3 supported") + set(PYTHON_FOUND TRUE) + set(COMPILE_PYTHON TRUE CACHE BOOL "" FORCE) + + get_filename_component(PYTHON_LIB "${PYTHON_LIBRARIES}" NAME) + string(REGEX REPLACE "\\.[^.]*$" "" PYTHON_LIB ${PYTHON_LIB}) + + if(WIN32) + string(REGEX REPLACE "_d" "" PYTHON_LIB "${PYTHON_LIB}") + endif() + endif() +else() + message(STATUS "Scripting: Python 3 support disabled") + set(PYTHON_FOUND FALSE) + set(PYTHONLIBS_FOUND FALSE) +endif() + +find_package(SwigDeps QUIET 2) + if(NOT SWIG_FOUND) message(STATUS "Scripting: SWIG not found; scripting disabled") return() @@ -28,29 +70,6 @@ if(NOT PYTHONLIBS_FOUND AND NOT LUAJIT_FOUND) return() endif() -if(NOT LUAJIT_FOUND) - message(STATUS "Scripting: Luajit not found; Luajit support disabled") -else() - message(STATUS "Scripting: Luajit supported") - set(COMPILE_LUA TRUE CACHE BOOL "" FORCE) -endif() - -if(NOT PYTHONLIBS_FOUND) - message(STATUS "Scripting: Python 3 not found; Python support disabled") - set(PYTHON_FOUND FALSE) - set(PYTHONLIBS_FOUND FALSE) -else() - message(STATUS "Scripting: Python 3 supported") - set(PYTHON_FOUND TRUE) - set(COMPILE_PYTHON TRUE CACHE BOOL "" FORCE) - - get_filename_component(PYTHON_LIB "${PYTHON_LIBRARIES}" NAME) - string(REGEX REPLACE "\\.[^.]*$" "" PYTHON_LIB ${PYTHON_LIB}) - if(WIN32) - string(REGEX REPLACE "_d" "" PYTHON_LIB "${PYTHON_LIB}") - endif() -endif() - set(SCRIPTING_ENABLED ON CACHE BOOL "Interal global cmake variable" FORCE) if(UI_ENABLED) @@ -58,6 +77,10 @@ if(UI_ENABLED) include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/UI/obs-frontend-api") endif() +IF(BUILD_CAPTIONS) + string(TOUPPER "${BUILD_CAPTIONS}" BUILD_CAPTIONS) +endif() + configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/obs-scripting-config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/obs-scripting-config.h") diff --git a/deps/obs-scripting/obs-scripting-config.h.in b/deps/obs-scripting/obs-scripting-config.h.in index 4205126..6fab8d8 100644 --- a/deps/obs-scripting/obs-scripting-config.h.in +++ b/deps/obs-scripting/obs-scripting-config.h.in @@ -21,3 +21,4 @@ #define COMPILE_LUA @LUAJIT_FOUND@ #define COMPILE_PYTHON @PYTHON_FOUND@ #define UI_ENABLED @UI_ENABLED@ +#define BUILD_CAPTIONS @BUILD_CAPTIONS@ diff --git a/deps/obs-scripting/obslua/obslua.i b/deps/obs-scripting/obslua/obslua.i index 98058b8..6a97f2b 100644 --- a/deps/obs-scripting/obslua/obslua.i +++ b/deps/obs-scripting/obslua/obslua.i @@ -84,6 +84,7 @@ static inline void wrap_blog(int log_level, const char *message) %include "graphics/vec2.h" %include "graphics/quat.h" %include "graphics/image-file.h" +%include "obs-scripting-config.h" %include "obs-data.h" %include "obs-source.h" %include "obs-properties.h" @@ -95,7 +96,6 @@ static inline void wrap_blog(int log_level, const char *message) %include "callback/signal.h" %include "util/bmem.h" %include "util/base.h" -%include "obs-scripting-config.h" #if UI_ENABLED %include "obs-frontend-api.h" diff --git a/deps/obs-scripting/obspython/obspython.i b/deps/obs-scripting/obspython/obspython.i index 3c71413..b8a75bb 100644 --- a/deps/obs-scripting/obspython/obspython.i +++ b/deps/obs-scripting/obspython/obspython.i @@ -82,6 +82,7 @@ static inline void wrap_blog(int log_level, const char *message) %include "graphics/vec3.h" %include "graphics/vec2.h" %include "graphics/quat.h" +%include "obs-scripting-config.h" %include "obs-data.h" %include "obs-source.h" %include "obs-properties.h" @@ -93,7 +94,6 @@ static inline void wrap_blog(int log_level, const char *message) %include "callback/signal.h" %include "util/bmem.h" %include "util/base.h" -%include "obs-scripting-config.h" #if UI_ENABLED %include "obs-frontend-api.h" diff --git a/docs/sphinx/reference-frontend-api.rst b/docs/sphinx/reference-frontend-api.rst index 3746135..3b5b86d 100644 --- a/docs/sphinx/reference-frontend-api.rst +++ b/docs/sphinx/reference-frontend-api.rst @@ -235,6 +235,18 @@ Functions --------------------------------------- +.. function:: int obs_frontend_get_transition_duration(void) + + :return: The transition duration (in milliseconds) currently set in the UI. + +--------------------------------------- + +.. function:: void obs_frontend_set_transition_duration(int duration) + + :param duration: Desired transition duration (in milliseconds) + +--------------------------------------- + .. function:: char **obs_frontend_get_scene_collections(void) :return: The list of profile names, ending with NULL. The list is @@ -473,6 +485,12 @@ Functions --------------------------------------- +.. function:: void obs_frontend_preview_program_trigger_transition(void) + + Triggers a preview-to-program transition if studio mode is active. + +--------------------------------------- + .. function:: obs_source_t *obs_frontend_get_current_preview_scene(void) :return: A new reference to the current preview scene if studio mode diff --git a/docs/sphinx/reference-libobs-graphics-effects.rst b/docs/sphinx/reference-libobs-graphics-effects.rst index 1392b41..e7c0ec3 100644 --- a/docs/sphinx/reference-libobs-graphics-effects.rst +++ b/docs/sphinx/reference-libobs-graphics-effects.rst @@ -154,6 +154,36 @@ HLSL format. --------------------- +.. function:: size_t gs_param_get_num_annotations(const gs_eparam_t *param) + + Gets the number of annotations associated with the parameter. + + :param param: Param object + :return: Number of annotations the param has + +--------------------- + +.. function:: gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, size_t annotation) + + Gets an annotation of a param by its index. + + :param param: Param object + :param param: Annotation index + :return: The effect parameter object (annotation), or *NULL* if index + invalid + +--------------------- + +.. function:: gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *pardam, const char *annotation) + + Gets parameter of an effect by its name. + + :param param: Param object + :param name: Name of the annotation + :return: The effect parameter object (annotation), or *NULL* if not found + +--------------------- + .. function:: bool gs_effect_loop(gs_effect_t *effect, const char *name) Helper function that automatically begins techniques/passes. @@ -332,3 +362,39 @@ HLSL format. :param param: Effect parameter :param sampler: Sampler state object + +--------------------- + +.. function:: void *gs_effect_get_val(gs_eparam_t *param) + + Returns a copy of the param's current value. + + :param param: Effect parameter + :return: A pointer to the copied byte value of the param's current value. Freed with :c:func:`bfree()`. + +--------------------- + +.. function:: void gs_effect_get_default_val(gs_eparam_t *param) + + Returns a copy of the param's default value. + + :param param: Effect parameter + :return: A pointer to the copied byte value of the param's default value. Freed with :c:func:`bfree()`. + +--------------------- + +.. function:: size_t gs_effect_get_val_size(gs_eparam_t *param) + + Returns the size in bytes of the param's current value. + + :param param: Effect parameter + :return: The size in bytes of the param's current value. + +--------------------- + +.. function:: size_t gs_effect_get_default_val_size(gs_eparam_t *param) + + Returns the size in bytes of the param's default value. + + :param param: Effect parameter + :return: The size in bytes of the param's default value. diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index 404dd23..e7c65b6 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -117,6 +117,18 @@ Output Definition Structure (obs_output_info) This is called when the output recieves raw audio data. Only applies to outputs that are not encoded. + **This callback must be used with single-track raw outputs.** + + :param frames: The raw audio frames + +.. member:: void (*obs_output_info.raw_audio2)(void *data, size_t idx, struct audio_data *frames) + + This is called when the output recieves raw audio data. Only applies + to outputs that are not encoded. + + **This callback must be used with multi-track raw outputs.** + + :param idx: The audio track index :param frames: The raw audio frames .. member:: void (*obs_output_info.encoded_packet)(void *data, struct encoder_packet *packet) @@ -125,7 +137,10 @@ Output Definition Structure (obs_output_info) Only applies to outputs that are encoded. Packets will always be given in monotonic timestamp order. - :param packet: The video or audio packet + :param packet: The video or audio packet. If NULL, an encoder error + occurred, and the output should call + :c:func:`obs_output_signal_stop()` with the error code + **OBS_OUTPUT_ENCODE_ERROR**. .. member:: void (*obs_output_info.update)(void *data, obs_data_t *settings) @@ -240,6 +255,7 @@ Output Signals | OBS_OUTPUT_DISCONNECTED - Unexpectedly disconnected | OBS_OUTPUT_UNSUPPORTED - The settings, video/audio format, or codecs are unsupported by this output | OBS_OUTPUT_NO_SPACE - Ran out of disk space + | OBS_OUTPUT_ENCODE_ERROR - Encoder error **starting** (ptr output) @@ -472,7 +488,19 @@ General Output Functions .. function:: void obs_output_set_mixer(obs_output_t *output, size_t mixer_idx) size_t obs_output_get_mixer(const obs_output_t *output) - Sets/gets the current audio mixer for non-encoded outputs. + Sets/gets the current audio mixer for non-encoded outputs. For + multi-track outputs, this would be the equivalent of setting the mask + only for the specified mixer index. + +--------------------- + +.. function:: void obs_output_set_mixers(obs_output_t *output, size_t mixers) + size_t obs_output_get_mixers(const obs_output_t *output) + + Sets/gets the current audio mixers (via mask) for non-encoded + multi-track outputs. If used with single-track outputs, the + single-track output will use either the first set mixer track in the + bitmask, or the first track if none is set in the bitmask. --------------------- diff --git a/docs/sphinx/reference-scenes.rst b/docs/sphinx/reference-scenes.rst index c8faf3d..883b67e 100644 --- a/docs/sphinx/reference-scenes.rst +++ b/docs/sphinx/reference-scenes.rst @@ -279,6 +279,12 @@ Scene Item Functions --------------------- +.. function:: int64_t obs_sceneitem_get_id(const obs_sceneitem_t *item) + + :return: The unique numeric identifier of the scene item. + +--------------------- + .. function:: void obs_sceneitem_set_pos(obs_sceneitem_t *item, const struct vec2 *pos) void obs_sceneitem_get_pos(const obs_sceneitem_t *item, struct vec2 *pos) diff --git a/libobs-d3d11/CMakeLists.txt b/libobs-d3d11/CMakeLists.txt index e30828b..34543c7 100644 --- a/libobs-d3d11/CMakeLists.txt +++ b/libobs-d3d11/CMakeLists.txt @@ -30,6 +30,7 @@ set_target_properties(libobs-d3d11 PREFIX "") target_link_libraries(libobs-d3d11 libobs + d3d9 d3d11 dxgi) diff --git a/libobs-d3d11/d3d11-rebuild.cpp b/libobs-d3d11/d3d11-rebuild.cpp index 376b8ea..6912cf7 100644 --- a/libobs-d3d11/d3d11-rebuild.cpp +++ b/libobs-d3d11/d3d11-rebuild.cpp @@ -17,14 +17,14 @@ #include "d3d11-subsystem.hpp" -inline void gs_vertex_buffer::Rebuild() +void gs_vertex_buffer::Rebuild() { uvBuffers.clear(); uvSizes.clear(); BuildBuffers(); } -inline void gs_index_buffer::Rebuild(ID3D11Device *dev) +void gs_index_buffer::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateBuffer(&bd, &srd, &indexBuffer); if (FAILED(hr)) @@ -55,7 +55,7 @@ void gs_texture_2d::RebuildSharedTextureFallback() isShared = false; } -inline void gs_texture_2d::Rebuild(ID3D11Device *dev) +void gs_texture_2d::Rebuild(ID3D11Device *dev) { HRESULT hr; if (isShared) { @@ -89,9 +89,61 @@ inline void gs_texture_2d::Rebuild(ID3D11Device *dev) if (FAILED(hr)) throw HRError("Failed to create GDI surface", hr); } + + acquired = false; + + if ((td.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0) { + ComQIPtr dxgi_res(texture); + if (dxgi_res) + GetSharedHandle(dxgi_res); + device_texture_acquire_sync(this, 0, INFINITE); + } } -inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev) +void gs_texture_2d::RebuildNV12_Y(ID3D11Device *dev) +{ + gs_texture_2d *tex_uv = pairedNV12texture; + HRESULT hr; + + hr = dev->CreateTexture2D(&td, nullptr, &texture); + if (FAILED(hr)) + throw HRError("Failed to create 2D texture", hr); + + hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes); + if (FAILED(hr)) + throw HRError("Failed to create resource view", hr); + + if (isRenderTarget) + InitRenderTargets(); + + tex_uv->RebuildNV12_UV(dev); + + acquired = false; + + if ((td.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0) { + ComQIPtr dxgi_res(texture); + if (dxgi_res) + GetSharedHandle(dxgi_res); + device_texture_acquire_sync(this, 0, INFINITE); + } +} + +void gs_texture_2d::RebuildNV12_UV(ID3D11Device *dev) +{ + gs_texture_2d *tex_y = pairedNV12texture; + HRESULT hr; + + texture = tex_y->texture; + + hr = dev->CreateShaderResourceView(texture, &resourceDesc, &shaderRes); + if (FAILED(hr)) + throw HRError("Failed to create resource view", hr); + + if (isRenderTarget) + InitRenderTargets(); +} + +void gs_zstencil_buffer::Rebuild(ID3D11Device *dev) { HRESULT hr; hr = dev->CreateTexture2D(&td, nullptr, &texture); @@ -103,21 +155,21 @@ inline void gs_zstencil_buffer::Rebuild(ID3D11Device *dev) throw HRError("Failed to create depth stencil view", hr); } -inline void gs_stage_surface::Rebuild(ID3D11Device *dev) +void gs_stage_surface::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateTexture2D(&td, nullptr, &texture); if (FAILED(hr)) throw HRError("Failed to create staging surface", hr); } -inline void gs_sampler_state::Rebuild(ID3D11Device *dev) +void gs_sampler_state::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateSamplerState(&sd, state.Assign()); if (FAILED(hr)) throw HRError("Failed to create sampler state", hr); } -inline void gs_vertex_shader::Rebuild(ID3D11Device *dev) +void gs_vertex_shader::Rebuild(ID3D11Device *dev) { HRESULT hr; hr = dev->CreateVertexShader(data.data(), data.size(), nullptr, &shader); @@ -142,7 +194,7 @@ inline void gs_vertex_shader::Rebuild(ID3D11Device *dev) } } -inline void gs_pixel_shader::Rebuild(ID3D11Device *dev) +void gs_pixel_shader::Rebuild(ID3D11Device *dev) { HRESULT hr; @@ -164,7 +216,7 @@ inline void gs_pixel_shader::Rebuild(ID3D11Device *dev) } } -inline void gs_swap_chain::Rebuild(ID3D11Device *dev) +void gs_swap_chain::Rebuild(ID3D11Device *dev) { HRESULT hr = device->factory->CreateSwapChain(dev, &swapDesc, &swap); if (FAILED(hr)) @@ -172,21 +224,21 @@ inline void gs_swap_chain::Rebuild(ID3D11Device *dev) Init(); } -inline void SavedBlendState::Rebuild(ID3D11Device *dev) +void SavedBlendState::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateBlendState(&bd, &state); if (FAILED(hr)) throw HRError("Failed to create blend state", hr); } -inline void SavedZStencilState::Rebuild(ID3D11Device *dev) +void SavedZStencilState::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateDepthStencilState(&dsd, &state); if (FAILED(hr)) throw HRError("Failed to create depth stencil state", hr); } -inline void SavedRasterState::Rebuild(ID3D11Device *dev) +void SavedRasterState::Rebuild(ID3D11Device *dev) { HRESULT hr = dev->CreateRasterizerState(&rd, &state); if (FAILED(hr)) @@ -287,7 +339,14 @@ try { ((gs_index_buffer*)obj)->Rebuild(dev); break; case gs_type::gs_texture_2d: - ((gs_texture_2d*)obj)->Rebuild(dev); + { + gs_texture_2d *tex = (gs_texture_2d*)obj; + if (!tex->nv12) { + tex->Rebuild(dev); + } else if (!tex->chroma) { + tex->RebuildNV12_Y(dev); + } + } break; case gs_type::gs_zstencil_buffer: ((gs_zstencil_buffer*)obj)->Rebuild(dev); diff --git a/libobs-d3d11/d3d11-shader.cpp b/libobs-d3d11/d3d11-shader.cpp index 453ff24..1a71048 100644 --- a/libobs-d3d11/d3d11-shader.cpp +++ b/libobs-d3d11/d3d11-shader.cpp @@ -137,8 +137,11 @@ void gs_shader::BuildConstantBuffer() case GS_SHADER_PARAM_BOOL: case GS_SHADER_PARAM_INT: case GS_SHADER_PARAM_FLOAT: size = sizeof(float); break; + case GS_SHADER_PARAM_INT2: case GS_SHADER_PARAM_VEC2: size = sizeof(vec2); break; + case GS_SHADER_PARAM_INT3: case GS_SHADER_PARAM_VEC3: size = sizeof(float)*3; break; + case GS_SHADER_PARAM_INT4: case GS_SHADER_PARAM_VEC4: size = sizeof(vec4); break; case GS_SHADER_PARAM_MATRIX4X4: size = sizeof(float)*4*4; diff --git a/libobs-d3d11/d3d11-stagesurf.cpp b/libobs-d3d11/d3d11-stagesurf.cpp index c08b462..efad5df 100644 --- a/libobs-d3d11/d3d11-stagesurf.cpp +++ b/libobs-d3d11/d3d11-stagesurf.cpp @@ -41,3 +41,28 @@ gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width, if (FAILED(hr)) throw HRError("Failed to create staging surface", hr); } + +gs_stage_surface::gs_stage_surface(gs_device_t *device, uint32_t width, + uint32_t height) + : gs_obj (device, gs_type::gs_stage_surface), + width (width), + height (height), + format (GS_UNKNOWN), + dxgiFormat (DXGI_FORMAT_NV12) +{ + HRESULT hr; + + memset(&td, 0, sizeof(td)); + td.Width = width; + td.Height = height; + td.MipLevels = 1; + td.ArraySize = 1; + td.Format = dxgiFormat; + td.SampleDesc.Count = 1; + td.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + td.Usage = D3D11_USAGE_STAGING; + + hr = device->device->CreateTexture2D(&td, NULL, texture.Assign()); + if (FAILED(hr)) + throw HRError("Failed to create staging surface", hr); +} diff --git a/libobs-d3d11/d3d11-subsystem.cpp b/libobs-d3d11/d3d11-subsystem.cpp index aa335aa..6b7a005 100644 --- a/libobs-d3d11/d3d11-subsystem.cpp +++ b/libobs-d3d11/d3d11-subsystem.cpp @@ -18,7 +18,10 @@ #include #include #include +#include +#include #include +#include #include "d3d11-subsystem.hpp" struct UnsupportedHWError : HRError { @@ -227,6 +230,120 @@ const static D3D_FEATURE_LEVEL featureLevels[] = D3D_FEATURE_LEVEL_9_3, }; +/* ------------------------------------------------------------------------- */ + +#define VERT_IN_OUT "\ +struct VertInOut { \ + float4 pos : POSITION; \ +}; " + +#define NV12_Y_PS VERT_IN_OUT "\ +float main(VertInOut vert_in) : TARGET \ +{ \ + return 1.0; \ +}" + +#define NV12_UV_PS VERT_IN_OUT "\ +float2 main(VertInOut vert_in) : TARGET \ +{ \ + return float2(1.0, 1.0); \ +}" + +#define NV12_VS VERT_IN_OUT "\ +VertInOut main(VertInOut vert_in) \ +{ \ + VertInOut vert_out; \ + vert_out.pos = float4(vert_in.pos.xyz, 1.0); \ + return vert_out; \ +} " + +/* ------------------------------------------------------------------------- */ + +#define NV12_CX 128 +#define NV12_CY 128 + +bool gs_device::HasBadNV12Output() +try { + vec3 points[4]; + vec3_set(&points[0], -1.0f, -1.0f, 0.0f); + vec3_set(&points[1], -1.0f, 1.0f, 0.0f); + vec3_set(&points[2], 1.0f, -1.0f, 0.0f); + vec3_set(&points[3], 1.0f, 1.0f, 0.0f); + + gs_texture_2d nv12_y(this, NV12_CX, NV12_CY, GS_R8, 1, nullptr, + GS_RENDER_TARGET | GS_SHARED_KM_TEX, GS_TEXTURE_2D, + false, true); + gs_texture_2d nv12_uv(this, nv12_y.texture, + GS_RENDER_TARGET | GS_SHARED_KM_TEX); + gs_vertex_shader nv12_vs(this, "", NV12_VS); + gs_pixel_shader nv12_y_ps(this, "", NV12_Y_PS); + gs_pixel_shader nv12_uv_ps(this, "", NV12_UV_PS); + gs_stage_surface nv12_stage(this, NV12_CX, NV12_CY); + + gs_vb_data *vbd = gs_vbdata_create(); + vbd->num = 4; + vbd->points = (vec3*)bmemdup(&points, sizeof(points)); + + gs_vertex_buffer buf(this, vbd, 0); + + device_load_vertexbuffer(this, &buf); + device_load_vertexshader(this, &nv12_vs); + + context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + device_set_viewport(this, 0, 0, NV12_CX, NV12_CY); + device_set_cull_mode(this, GS_NEITHER); + device_enable_depth_test(this, false); + device_enable_blending(this, false); + LoadVertexBufferData(); + + device_set_render_target(this, &nv12_y, nullptr); + device_load_pixelshader(this, &nv12_y_ps); + UpdateBlendState(); + UpdateRasterState(); + UpdateZStencilState(); + context->Draw(4, 0); + + device_set_viewport(this, 0, 0, NV12_CX/2, NV12_CY/2); + device_set_render_target(this, &nv12_uv, nullptr); + device_load_pixelshader(this, &nv12_uv_ps); + UpdateBlendState(); + UpdateRasterState(); + UpdateZStencilState(); + context->Draw(4, 0); + + device_load_pixelshader(this, nullptr); + device_load_vertexshader(this, nullptr); + device_set_render_target(this, nullptr, nullptr); + + device_stage_texture(this, &nv12_stage, &nv12_y); + + uint8_t *data; + uint32_t linesize; + bool bad_driver = false; + + if (gs_stagesurface_map(&nv12_stage, &data, &linesize)) { + bad_driver = data[linesize * NV12_CY] == 0; + gs_stagesurface_unmap(&nv12_stage); + } else { + throw "Could not map surface"; + } + + if (bad_driver) { + blog(LOG_WARNING, "Bad NV12 texture handling detected! " + "Disabling NV12 texture support."); + } + return bad_driver; + +} catch (HRError error) { + blog(LOG_WARNING, "HasBadNV12Output failed: %s (%08lX)", + error.str, error.hr); + return false; +} catch (const char *error) { + blog(LOG_WARNING, "HasBadNV12Output failed: %s", error); + return false; +} + void gs_device::InitDevice(uint32_t adapterIdx) { wstring adapterName; @@ -244,11 +361,10 @@ void gs_device::InitDevice(uint32_t adapterIdx) adapterName = (adapter->GetDesc(&desc) == S_OK) ? desc.Description : L""; - char *adapterNameUTF8; + BPtr adapterNameUTF8; os_wcs_to_utf8_ptr(adapterName.c_str(), 0, &adapterNameUTF8); blog(LOG_INFO, "Loading up D3D11 on adapter %s (%" PRIu32 ")", - adapterNameUTF8, adapterIdx); - bfree(adapterNameUTF8); + adapterNameUTF8.Get(), adapterIdx); hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createFlags, featureLevels, @@ -260,6 +376,49 @@ void gs_device::InitDevice(uint32_t adapterIdx) blog(LOG_INFO, "D3D11 loaded successfully, feature level used: %u", (unsigned int)levelUsed); + + /* ---------------------------------------- */ + /* check for nv12 texture output support */ + + nv12Supported = false; + + ComQIPtr d3d11_1(device); + if (!d3d11_1) { + return; + } + + /* needs to support extended resource sharing */ + D3D11_FEATURE_DATA_D3D11_OPTIONS opts = {}; + hr = d3d11_1->CheckFeatureSupport( + D3D11_FEATURE_D3D11_OPTIONS, + &opts, sizeof(opts)); + if (FAILED(hr) || !opts.ExtendedResourceSharing) { + return; + } + + /* needs to support the actual format */ + UINT support = 0; + hr = device->CheckFormatSupport( + DXGI_FORMAT_NV12, + &support); + if (FAILED(hr)) { + return; + } + + if ((support & D3D11_FORMAT_SUPPORT_TEXTURE2D) == 0) { + return; + } + + /* must be usable as a render target */ + if ((support & D3D11_FORMAT_SUPPORT_RENDER_TARGET) == 0) { + return; + } + + if (HasBadNV12Output()) { + return; + } + + nv12Supported = true; } static inline void ConvertStencilSide(D3D11_DEPTH_STENCILOP_DESC &desc, @@ -505,7 +664,7 @@ static inline void EnumD3DAdapters( ComPtr factory; ComPtr adapter; HRESULT hr; - UINT i = 0; + UINT i; IID factoryIID = (GetWinVer() >= 0x602) ? dxgiFactory2 : __uuidof(IDXGIFactory1); @@ -514,7 +673,7 @@ static inline void EnumD3DAdapters( if (FAILED(hr)) throw HRError("Failed to create DXGIFactory", hr); - while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) { + for (i = 0; factory->EnumAdapters1(i, adapter.Assign()) == S_OK; ++i) { DXGI_ADAPTER_DESC desc; char name[512] = ""; @@ -528,7 +687,7 @@ static inline void EnumD3DAdapters( os_wcs_to_utf8(desc.Description, 0, name, sizeof(name)); - if (!callback(param, name, i - 1)) + if (!callback(param, name, i)) break; } } @@ -550,10 +709,10 @@ bool device_enum_adapters( static inline void LogAdapterMonitors(IDXGIAdapter1 *adapter) { - UINT i = 0; + UINT i; ComPtr output; - while (adapter->EnumOutputs(i++, &output) == S_OK) { + for (i = 0; adapter->EnumOutputs(i, &output) == S_OK; ++i) { DXGI_OUTPUT_DESC desc; if (FAILED(output->GetDesc(&desc))) continue; @@ -575,7 +734,7 @@ static inline void LogD3DAdapters() ComPtr factory; ComPtr adapter; HRESULT hr; - UINT i = 0; + UINT i; blog(LOG_INFO, "Available Video Adapters: "); @@ -586,7 +745,7 @@ static inline void LogD3DAdapters() if (FAILED(hr)) throw HRError("Failed to create DXGIFactory", hr); - while (factory->EnumAdapters1(i++, adapter.Assign()) == S_OK) { + for (i = 0; factory->EnumAdapters1(i, adapter.Assign()) == S_OK; ++i) { DXGI_ADAPTER_DESC desc; char name[512] = ""; @@ -736,8 +895,7 @@ gs_texture_t *device_texture_create(gs_device_t *device, uint32_t width, gs_texture *texture = NULL; try { texture = new gs_texture_2d(device, width, height, color_format, - levels, data, flags, GS_TEXTURE_2D, false, - false); + levels, data, flags, GS_TEXTURE_2D, false); } catch (HRError error) { blog(LOG_ERROR, "device_texture_create (D3D11): %s (%08lX)", error.str, error.hr); @@ -756,8 +914,7 @@ gs_texture_t *device_cubetexture_create(gs_device_t *device, uint32_t size, gs_texture *texture = NULL; try { texture = new gs_texture_2d(device, size, size, color_format, - levels, data, flags, GS_TEXTURE_CUBE, false, - false); + levels, data, flags, GS_TEXTURE_CUBE, false); } catch (HRError error) { blog(LOG_ERROR, "device_cubetexture_create (D3D11): %s " "(%08lX)", @@ -1317,7 +1474,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, throw "Source texture must be a 2D texture"; if (!dst) throw "Destination surface is NULL"; - if (dst->format != src->format) + if (dst->format != GS_UNKNOWN && dst->format != src->format) throw "Source and destination formats do not match"; if (dst->width != src2d->width || dst->height != src2d->height) @@ -2056,6 +2213,29 @@ extern "C" EXPORT bool device_shared_texture_available(void) return true; } +extern "C" EXPORT bool device_nv12_available(gs_device_t *device) +{ + return device->nv12Supported; +} + +extern "C" EXPORT void device_debug_marker_begin(gs_device_t *, + const char *markername, const float color[4]) +{ + D3DCOLOR bgra = D3DCOLOR_ARGB((DWORD)(255.0f * color[3]), + (DWORD)(255.0f * color[0]), (DWORD)(255.0f * color[1]), + (DWORD)(255.0f * color[2])); + + wchar_t wide[64]; + os_utf8_to_wcs(markername, 0, wide, _countof(wide)); + + D3DPERF_BeginEvent(bgra, wide); +} + +extern "C" EXPORT void device_debug_marker_end(gs_device_t *) +{ + D3DPERF_EndEvent(); +} + extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device, uint32_t width, uint32_t height) { @@ -2063,7 +2243,7 @@ extern "C" EXPORT gs_texture_t *device_texture_create_gdi(gs_device_t *device, try { texture = new gs_texture_2d(device, width, height, GS_BGRA, 1, nullptr, GS_RENDER_TARGET, GS_TEXTURE_2D, - true, false); + true); } catch (HRError error) { blog(LOG_ERROR, "device_texture_create_gdi (D3D11): %s (%08lX)", error.str, error.hr); @@ -2132,3 +2312,112 @@ extern "C" EXPORT gs_texture_t *device_texture_open_shared(gs_device_t *device, return texture; } + +extern "C" EXPORT uint32_t device_texture_get_shared_handle(gs_texture_t *tex) +{ + gs_texture_2d *tex2d = reinterpret_cast(tex); + if (tex->type != GS_TEXTURE_2D) + return GS_INVALID_HANDLE; + + return tex2d->isShared ? tex2d->sharedHandle : GS_INVALID_HANDLE; +} + +int device_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms) +{ + gs_texture_2d *tex2d = reinterpret_cast(tex); + if (tex->type != GS_TEXTURE_2D) + return -1; + + if (tex2d->acquired) + return 0; + + ComQIPtr keyedMutex(tex2d->texture); + if (!keyedMutex) + return -1; + + HRESULT hr = keyedMutex->AcquireSync(key, ms); + if (hr == S_OK) { + tex2d->acquired = true; + return 0; + } else if (hr == WAIT_TIMEOUT) { + return ETIMEDOUT; + } + + return -1; +} + +extern "C" EXPORT int device_texture_release_sync(gs_texture_t *tex, + uint64_t key) +{ + gs_texture_2d *tex2d = reinterpret_cast(tex); + if (tex->type != GS_TEXTURE_2D) + return -1; + + if (!tex2d->acquired) + return 0; + + ComQIPtr keyedMutex(tex2d->texture); + if (!keyedMutex) + return -1; + + HRESULT hr = keyedMutex->ReleaseSync(key); + if (hr == S_OK) { + tex2d->acquired = false; + return 0; + } + + return -1; +} + +extern "C" EXPORT bool device_texture_create_nv12(gs_device_t *device, + gs_texture_t **p_tex_y, gs_texture_t **p_tex_uv, + uint32_t width, uint32_t height, uint32_t flags) +{ + if (!device->nv12Supported) + return false; + + *p_tex_y = nullptr; + *p_tex_uv = nullptr; + + gs_texture_2d *tex_y; + gs_texture_2d *tex_uv; + + try { + tex_y = new gs_texture_2d(device, width, height, GS_R8, 1, + nullptr, flags, GS_TEXTURE_2D, false, true); + tex_uv = new gs_texture_2d(device, tex_y->texture, flags); + + } catch (HRError error) { + blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s (%08lX)", + error.str, error.hr); + LogD3D11ErrorDetails(error, device); + return false; + + } catch (const char *error) { + blog(LOG_ERROR, "gs_texture_create_nv12 (D3D11): %s", error); + return false; + } + + tex_y->pairedNV12texture = tex_uv; + tex_uv->pairedNV12texture = tex_y; + + *p_tex_y = tex_y; + *p_tex_uv = tex_uv; + return true; +} + +extern "C" EXPORT gs_stagesurf_t *device_stagesurface_create_nv12( + gs_device_t *device, uint32_t width, uint32_t height) +{ + gs_stage_surface *surf = NULL; + try { + surf = new gs_stage_surface(device, width, height); + } catch (HRError error) { + blog(LOG_ERROR, "device_stagesurface_create (D3D11): %s " + "(%08lX)", + error.str, error.hr); + LogD3D11ErrorDetails(error, device); + } + + return surf; +} diff --git a/libobs-d3d11/d3d11-subsystem.hpp b/libobs-d3d11/d3d11-subsystem.hpp index 54070a1..d373be5 100644 --- a/libobs-d3d11/d3d11-subsystem.hpp +++ b/libobs-d3d11/d3d11-subsystem.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include @@ -80,6 +80,7 @@ static inline DXGI_FORMAT ConvertGSTextureFormat(gs_color_format format) case GS_DXT1: return DXGI_FORMAT_BC1_UNORM; case GS_DXT3: return DXGI_FORMAT_BC2_UNORM; case GS_DXT5: return DXGI_FORMAT_BC3_UNORM; + case GS_R8G8: return DXGI_FORMAT_R8G8_UNORM; } return DXGI_FORMAT_UNKNOWN; @@ -90,6 +91,7 @@ static inline gs_color_format ConvertDXGITextureFormat(DXGI_FORMAT format) switch ((unsigned long)format) { case DXGI_FORMAT_A8_UNORM: return GS_A8; case DXGI_FORMAT_R8_UNORM: return GS_R8; + case DXGI_FORMAT_R8G8_UNORM: return GS_R8G8; case DXGI_FORMAT_R8G8B8A8_UNORM: return GS_RGBA; case DXGI_FORMAT_B8G8R8X8_UNORM: return GS_BGRX; case DXGI_FORMAT_B8G8R8A8_UNORM: return GS_BGRA; @@ -267,7 +269,7 @@ struct gs_vertex_buffer : gs_obj { uvBuffers.clear(); } - inline void Rebuild(); + void Rebuild(); gs_vertex_buffer(gs_device_t *device, struct gs_vb_data *data, uint32_t flags); @@ -294,7 +296,7 @@ struct gs_index_buffer : gs_obj { void InitBuffer(); - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() {indexBuffer.Release();} @@ -310,7 +312,7 @@ struct gs_texture : gs_obj { ComPtr shaderRes; D3D11_SHADER_RESOURCE_VIEW_DESC resourceDesc = {}; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline gs_texture(gs_texture_type type, uint32_t levels, gs_color_format format) @@ -344,13 +346,19 @@ struct gs_texture_2d : gs_texture { ComPtr gdiSurface; uint32_t width = 0, height = 0; + uint32_t flags = 0; DXGI_FORMAT dxgiFormat = DXGI_FORMAT_UNKNOWN; bool isRenderTarget = false; bool isGDICompatible = false; bool isDynamic = false; bool isShared = false; bool genMipmaps = false; - uint32_t sharedHandle = 0; + uint32_t sharedHandle = GS_INVALID_HANDLE; + + gs_texture_2d *pairedNV12texture = nullptr; + bool nv12 = false; + bool chroma = false; + bool acquired = false; vector> data; vector srd; @@ -361,9 +369,12 @@ struct gs_texture_2d : gs_texture { void InitResourceView(); void InitRenderTargets(); void BackupTexture(const uint8_t **data); + void GetSharedHandle(IDXGIResource *dxgi_res); void RebuildSharedTextureFallback(); - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); + void RebuildNV12_Y(ID3D11Device *dev); + void RebuildNV12_UV(ID3D11Device *dev); inline void Release() { @@ -382,8 +393,11 @@ struct gs_texture_2d : gs_texture { gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height, gs_color_format colorFormat, uint32_t levels, const uint8_t **data, uint32_t flags, - gs_texture_type type, bool gdiCompatible, bool shared); + gs_texture_type type, bool gdiCompatible, + bool nv12 = false); + gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12, + uint32_t flags); gs_texture_2d(gs_device_t *device, uint32_t handle); }; @@ -400,7 +414,7 @@ struct gs_zstencil_buffer : gs_obj { void InitBuffer(); - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -427,7 +441,7 @@ struct gs_stage_surface : gs_obj { gs_color_format format; DXGI_FORMAT dxgiFormat; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -436,6 +450,7 @@ struct gs_stage_surface : gs_obj { gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height, gs_color_format colorFormat); + gs_stage_surface(gs_device_t *device, uint32_t width, uint32_t height); }; struct gs_sampler_state : gs_obj { @@ -443,7 +458,7 @@ struct gs_sampler_state : gs_obj { D3D11_SAMPLER_DESC sd = {}; gs_sampler_info info; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() {state.Release();} @@ -532,7 +547,7 @@ struct gs_vertex_shader : gs_shader { bool hasTangents; uint32_t nTexUnits; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -579,7 +594,7 @@ struct gs_pixel_shader : gs_shader { ComPtr shader; vector> samplers; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -615,7 +630,7 @@ struct gs_swap_chain : gs_obj { void Resize(uint32_t cx, uint32_t cy); void Init(); - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -644,7 +659,7 @@ struct BlendState { srcFactorC (GS_BLEND_SRCALPHA), destFactorC (GS_BLEND_INVSRCALPHA), srcFactorA (GS_BLEND_ONE), - destFactorA (GS_BLEND_ONE), + destFactorA (GS_BLEND_INVSRCALPHA), redEnabled (true), greenEnabled (true), blueEnabled (true), @@ -662,7 +677,7 @@ struct SavedBlendState : BlendState { ComPtr state; D3D11_BLEND_DESC bd; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -719,7 +734,7 @@ struct SavedZStencilState : ZStencilState { ComPtr state; D3D11_DEPTH_STENCIL_DESC dsd; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -754,7 +769,7 @@ struct SavedRasterState : RasterState { ComPtr state; D3D11_RASTERIZER_DESC rd; - inline void Rebuild(ID3D11Device *dev); + void Rebuild(ID3D11Device *dev); inline void Release() { @@ -779,6 +794,7 @@ struct gs_device { ComPtr device; ComPtr context; uint32_t adpIdx = 0; + bool nv12Supported = false; gs_texture_2d *curRenderTarget = nullptr; gs_zstencil_buffer *curZStencilBuffer = nullptr; @@ -845,6 +861,11 @@ struct gs_device { void RebuildDevice(); + bool HasBadNV12Output(); + gs_device(uint32_t adapterIdx); ~gs_device(); }; + +extern "C" EXPORT int device_texture_acquire_sync(gs_texture_t *tex, + uint64_t key, uint32_t ms); diff --git a/libobs-d3d11/d3d11-texture2d.cpp b/libobs-d3d11/d3d11-texture2d.cpp index 9855466..a3fa205 100644 --- a/libobs-d3d11/d3d11-texture2d.cpp +++ b/libobs-d3d11/d3d11-texture2d.cpp @@ -71,6 +71,20 @@ void gs_texture_2d::BackupTexture(const uint8_t **data) } } +void gs_texture_2d::GetSharedHandle(IDXGIResource *dxgi_res) +{ + HANDLE handle; + HRESULT hr; + + hr = dxgi_res->GetSharedHandle(&handle); + if (FAILED(hr)) { + blog(LOG_WARNING, "GetSharedHandle: Failed to " + "get shared handle: %08lX", hr); + } else { + sharedHandle = (uint32_t)(uintptr_t)handle; + } +} + void gs_texture_2d::InitTexture(const uint8_t **data) { HRESULT hr; @@ -80,7 +94,7 @@ void gs_texture_2d::InitTexture(const uint8_t **data) td.Height = height; td.MipLevels = genMipmaps ? 0 : levels; td.ArraySize = type == GS_TEXTURE_CUBE ? 6 : 1; - td.Format = dxgiFormat; + td.Format = nv12 ? DXGI_FORMAT_NV12 : dxgiFormat; td.BindFlags = D3D11_BIND_SHADER_RESOURCE; td.SampleDesc.Count = 1; td.CPUAccessFlags = isDynamic ? D3D11_CPU_ACCESS_WRITE : 0; @@ -96,6 +110,11 @@ void gs_texture_2d::InitTexture(const uint8_t **data) if (isGDICompatible) td.MiscFlags |= D3D11_RESOURCE_MISC_GDI_COMPATIBLE; + if ((flags & GS_SHARED_KM_TEX) != 0) + td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; + else if ((flags & GS_SHARED_TEX) != 0) + td.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + if (data) { BackupTexture(data); InitSRD(srd); @@ -112,6 +131,36 @@ void gs_texture_2d::InitTexture(const uint8_t **data) if (FAILED(hr)) throw HRError("Failed to create GDI surface", hr); } + + if (isShared) { + ComPtr dxgi_res; + + texture->SetEvictionPriority(DXGI_RESOURCE_PRIORITY_MAXIMUM); + + hr = texture->QueryInterface(__uuidof(IDXGIResource), + (void**)&dxgi_res); + if (FAILED(hr)) { + blog(LOG_WARNING, "InitTexture: Failed to query " + "interface: %08lX", hr); + } else { + GetSharedHandle(dxgi_res); + + if (flags & GS_SHARED_KM_TEX) { + ComPtr km; + hr = texture->QueryInterface( + __uuidof(IDXGIKeyedMutex), + (void**)&km); + if (FAILED(hr)) { + throw HRError("Failed to query " + "IDXGIKeyedMutex", + hr); + } + + km->AcquireSync(0, INFINITE); + acquired = true; + } + } + } } void gs_texture_2d::InitResourceView() @@ -123,10 +172,12 @@ void gs_texture_2d::InitResourceView() if (type == GS_TEXTURE_CUBE) { resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - resourceDesc.TextureCube.MipLevels = genMipmaps ? -1 : 1; + resourceDesc.TextureCube.MipLevels = + genMipmaps || !levels ? -1 : levels; } else { resourceDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - resourceDesc.Texture2D.MipLevels = genMipmaps ? -1 : 1; + resourceDesc.Texture2D.MipLevels = + genMipmaps || !levels ? -1 : levels; } hr = device->device->CreateShaderResourceView(texture, &resourceDesc, @@ -139,7 +190,12 @@ void gs_texture_2d::InitRenderTargets() { HRESULT hr; if (type == GS_TEXTURE_2D) { - hr = device->device->CreateRenderTargetView(texture, NULL, + D3D11_RENDER_TARGET_VIEW_DESC rtv; + rtv.Format = dxgiFormat; + rtv.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtv.Texture2D.MipSlice = 0; + + hr = device->device->CreateRenderTargetView(texture, &rtv, renderTarget[0].Assign()); if (FAILED(hr)) throw HRError("Failed to create render target view", @@ -162,20 +218,25 @@ void gs_texture_2d::InitRenderTargets() } } +#define SHARED_FLAGS (GS_SHARED_TEX | GS_SHARED_KM_TEX) + gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width, uint32_t height, gs_color_format colorFormat, uint32_t levels, - const uint8_t **data, uint32_t flags, gs_texture_type type, - bool gdiCompatible, bool shared) + const uint8_t **data, uint32_t flags_, gs_texture_type type, + bool gdiCompatible, bool nv12_) : gs_texture (device, gs_type::gs_texture_2d, type, levels, colorFormat), width (width), height (height), + flags (flags_), dxgiFormat (ConvertGSTextureFormat(format)), - isRenderTarget ((flags & GS_RENDER_TARGET) != 0), + isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0), isGDICompatible (gdiCompatible), - isDynamic ((flags & GS_DYNAMIC) != 0), - isShared (shared), - genMipmaps ((flags & GS_BUILD_MIPMAPS) != 0) + isDynamic ((flags_ & GS_DYNAMIC) != 0), + isShared ((flags_ & SHARED_FLAGS) != 0), + genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0), + sharedHandle (GS_INVALID_HANDLE), + nv12 (nv12_) { InitTexture(data); InitResourceView(); @@ -184,6 +245,33 @@ gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t width, InitRenderTargets(); } +gs_texture_2d::gs_texture_2d(gs_device_t *device, ID3D11Texture2D *nv12tex, + uint32_t flags_) + : gs_texture (device, gs_type::gs_texture_2d, GS_TEXTURE_2D), + isRenderTarget ((flags_ & GS_RENDER_TARGET) != 0), + isDynamic ((flags_ & GS_DYNAMIC) != 0), + isShared ((flags_ & SHARED_FLAGS) != 0), + genMipmaps ((flags_ & GS_BUILD_MIPMAPS) != 0), + nv12 (true) +{ + texture = nv12tex; + texture->GetDesc(&td); + + this->type = GS_TEXTURE_2D; + this->format = GS_R8G8; + this->flags = flags_; + this->levels = 1; + this->device = device; + this->chroma = true; + this->width = td.Width / 2; + this->height = td.Height / 2; + this->dxgiFormat = DXGI_FORMAT_R8G8_UNORM; + + InitResourceView(); + if (isRenderTarget) + InitRenderTargets(); +} + gs_texture_2d::gs_texture_2d(gs_device_t *device, uint32_t handle) : gs_texture (device, gs_type::gs_texture_2d, GS_TEXTURE_2D), diff --git a/libobs-opengl/gl-helpers.c b/libobs-opengl/gl-helpers.c index 8a7a757..c6e9012 100644 --- a/libobs-opengl/gl-helpers.c +++ b/libobs-opengl/gl-helpers.c @@ -57,13 +57,11 @@ bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, return success; } -static bool gl_copy_fbo(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, - enum gs_color_format format) +static bool gl_copy_fbo(struct gs_texture *dst, uint32_t dst_x, uint32_t dst_y, + struct gs_texture *src, uint32_t src_x, uint32_t src_y, + uint32_t width, uint32_t height) { - struct fbo_info *fbo = get_fbo(device, width, height, format); + struct fbo_info *fbo = get_fbo(src, width, height); GLint last_fbo; bool success = false; @@ -74,11 +72,11 @@ static bool gl_copy_fbo(struct gs_device *device, return false; if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, fbo->fbo)) return false; - if (!gl_bind_texture(dst_target, dst)) + if (!gl_bind_texture(dst->gl_target, dst->texture)) goto fail; glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + 0, - src_target, src, 0); + src->gl_target, src->texture, 0); if (!gl_success("glFrameBufferTexture2D")) goto fail; @@ -86,7 +84,7 @@ static bool gl_copy_fbo(struct gs_device *device, if (!gl_success("glReadBuffer")) goto fail; - glCopyTexSubImage2D(dst_target, 0, dst_x, dst_y, src_x, src_y, + glCopyTexSubImage2D(dst->gl_target, 0, dst_x, dst_y, src_x, src_y, width, height); if (!gl_success("glCopyTexSubImage2D")) goto fail; @@ -94,7 +92,7 @@ static bool gl_copy_fbo(struct gs_device *device, success = true; fail: - if (!gl_bind_texture(dst_target, 0)) + if (!gl_bind_texture(dst->gl_target, 0)) success = false; if (!gl_bind_framebuffer(GL_READ_FRAMEBUFFER, last_fbo)) success = false; @@ -102,29 +100,28 @@ fail: return success; } -bool gl_copy_texture(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, enum gs_color_format format) +bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, + uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, + uint32_t src_x, uint32_t src_y, uint32_t width, + uint32_t height) { bool success = false; if (device->copy_type == COPY_TYPE_ARB) { - glCopyImageSubData(src, src_target, 0, src_x, src_y, 0, - dst, dst_target, 0, dst_x, dst_y, 0, - width, height, 1); + glCopyImageSubData(src->texture, src->gl_target, 0, src_x, + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubData"); } else if (device->copy_type == COPY_TYPE_NV) { - glCopyImageSubDataNV(src, src_target, 0, src_x, src_y, 0, - dst, dst_target, 0, dst_x, dst_y, 0, - width, height, 1); + glCopyImageSubDataNV(src->texture, src->gl_target, 0, src_x, + src_y, 0, dst->texture, dst->gl_target, 0, + dst_x, dst_y, 0, width, height, 1); success = gl_success("glCopyImageSubDataNV"); } else if (device->copy_type == COPY_TYPE_FBO_BLIT) { - success = gl_copy_fbo(device, dst, dst_target, dst_x, dst_y, - src, src_target, src_x, src_y, - width, height, format); + success = gl_copy_fbo(dst, dst_x, dst_y, src, src_x, src_y, + width, height); if (!success) blog(LOG_ERROR, "gl_copy_texture failed"); } diff --git a/libobs-opengl/gl-helpers.h b/libobs-opengl/gl-helpers.h index f1f9122..fe9959a 100644 --- a/libobs-opengl/gl-helpers.h +++ b/libobs-opengl/gl-helpers.h @@ -148,11 +148,10 @@ extern bool gl_init_face(GLenum target, GLenum type, uint32_t num_levels, uint32_t width, uint32_t height, uint32_t size, const uint8_t ***p_data); -extern bool gl_copy_texture(struct gs_device *device, - GLuint dst, GLenum dst_target, uint32_t dst_x, uint32_t dst_y, - GLuint src, GLenum src_target, uint32_t src_x, uint32_t src_y, - uint32_t width, uint32_t height, - enum gs_color_format format); +extern bool gl_copy_texture(struct gs_device *device, struct gs_texture *dst, + uint32_t dst_x, uint32_t dst_y, struct gs_texture *src, + uint32_t src_x, uint32_t src_y, uint32_t width, + uint32_t height); extern bool gl_create_buffer(GLenum target, GLuint *buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); diff --git a/libobs-opengl/gl-indexbuffer.c b/libobs-opengl/gl-indexbuffer.c index 187835e..aef280f 100644 --- a/libobs-opengl/gl-indexbuffer.c +++ b/libobs-opengl/gl-indexbuffer.c @@ -38,7 +38,7 @@ gs_indexbuffer_t *device_indexbuffer_create(gs_device_t *device, uint32_t flags) { struct gs_index_buffer *ib = bzalloc(sizeof(struct gs_index_buffer)); - size_t width = type == GS_UNSIGNED_LONG ? sizeof(long) : sizeof(short); + size_t width = type == GS_UNSIGNED_LONG ? 4 : 2; ib->device = device; ib->data = indices; diff --git a/libobs-opengl/gl-shader.c b/libobs-opengl/gl-shader.c index 1ffcce4..cab4d7f 100644 --- a/libobs-opengl/gl-shader.c +++ b/libobs-opengl/gl-shader.c @@ -220,8 +220,20 @@ static bool gl_shader_init(struct gs_shader *shader, if (!gl_success("glGetShaderiv")) return false; - if (!compiled) + if (!compiled) { + GLint infoLength = 0; + glGetShaderiv(shader->obj, GL_INFO_LOG_LENGTH, &infoLength); + + char *infoLog = malloc(sizeof(char) * infoLength); + + GLsizei returnedLength = 0; + glGetShaderInfoLog(shader->obj, infoLength, &returnedLength, infoLog); + blog(LOG_ERROR, "Error compiling shader:\n%s\n", infoLog); + + free(infoLog); + success = false; + } gl_get_shader_info(shader->obj, file, error_string); @@ -455,6 +467,24 @@ static void program_set_param_data(struct gs_program *program, gl_success("glUniform1iv"); } + } else if (pp->param->type == GS_SHADER_PARAM_INT2) { + if (validate_param(pp, sizeof(int) * 2)) { + glUniform2iv(pp->obj, 1, (int*)array); + gl_success("glUniform2iv"); + } + + } else if (pp->param->type == GS_SHADER_PARAM_INT3) { + if (validate_param(pp, sizeof(int) * 3)) { + glUniform3iv(pp->obj, 1, (int*)array); + gl_success("glUniform3iv"); + } + + } else if (pp->param->type == GS_SHADER_PARAM_INT4) { + if (validate_param(pp, sizeof(int) * 4)) { + glUniform4iv(pp->obj, 1, (int*)array); + gl_success("glUniform4iv"); + } + } else if (pp->param->type == GS_SHADER_PARAM_FLOAT) { if (validate_param(pp, sizeof(float))) { glUniform1fv(pp->obj, 1, (float*)array); @@ -698,6 +728,9 @@ void gs_shader_set_val(gs_sparam_t *param, const void *val, size_t size) case GS_SHADER_PARAM_FLOAT: expected_size = sizeof(float); break; case GS_SHADER_PARAM_BOOL: case GS_SHADER_PARAM_INT: expected_size = sizeof(int); break; + case GS_SHADER_PARAM_INT2: expected_size = sizeof(int) * 2; break; + case GS_SHADER_PARAM_INT3: expected_size = sizeof(int) * 3; break; + case GS_SHADER_PARAM_INT4: expected_size = sizeof(int) * 4; break; case GS_SHADER_PARAM_VEC2: expected_size = sizeof(float)*2; break; case GS_SHADER_PARAM_VEC3: expected_size = sizeof(float)*3; break; case GS_SHADER_PARAM_VEC4: expected_size = sizeof(float)*4; break; diff --git a/libobs-opengl/gl-stagesurf.c b/libobs-opengl/gl-stagesurf.c index aa1637c..35dd212 100644 --- a/libobs-opengl/gl-stagesurf.c +++ b/libobs-opengl/gl-stagesurf.c @@ -124,7 +124,7 @@ void device_stage_texture(gs_device_t *device, gs_stagesurf_t *dst, if (!gl_bind_buffer(GL_PIXEL_PACK_BUFFER, dst->pack_buffer)) goto failed; - fbo = get_fbo(device, dst->width, dst->height, dst->format); + fbo = get_fbo(src, dst->width, dst->height); if (!gl_get_integer_v(GL_READ_FRAMEBUFFER_BINDING, &last_fbo)) goto failed_unbind_buffer; @@ -152,6 +152,8 @@ failed_unbind_buffer: failed: if (!success) blog(LOG_ERROR, "device_stage_texture (GL) failed"); + + UNUSED_PARAMETER(device); } #else diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index 063e1fd..d91a38d 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -259,16 +259,10 @@ fail: void device_destroy(gs_device_t *device) { if (device) { - size_t i; - - for (i = 0; i < device->fbos.num; i++) - fbo_info_destroy(device->fbos.array[i]); - while (device->first_program) gs_program_destroy(device->first_program); da_free(device->proj_stack); - da_free(device->fbos); gl_platform_destroy(device->plat); bfree(device); } @@ -658,46 +652,37 @@ static bool get_tex_dimensions(gs_texture_t *tex, uint32_t *width, * This automatically manages FBOs so that render targets are always given * an FBO that matches their width/height/format to maximize optimization */ -struct fbo_info *get_fbo(struct gs_device *device, - uint32_t width, uint32_t height, enum gs_color_format format) +struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, uint32_t height) { - size_t i; + if (tex->fbo && tex->fbo->width == width && + tex->fbo->height == height && + tex->fbo->format == tex->format) + return tex->fbo; + GLuint fbo; - struct fbo_info *ptr; - - for (i = 0; i < device->fbos.num; i++) { - ptr = device->fbos.array[i]; - - if (ptr->width == width && ptr->height == height && - ptr->format == format) - return ptr; - } - glGenFramebuffers(1, &fbo); if (!gl_success("glGenFramebuffers")) return NULL; - ptr = bmalloc(sizeof(struct fbo_info)); - ptr->fbo = fbo; - ptr->width = width; - ptr->height = height; - ptr->format = format; - ptr->cur_render_target = NULL; - ptr->cur_render_side = 0; - ptr->cur_zstencil_buffer = NULL; + tex->fbo = bmalloc(sizeof(struct fbo_info)); + tex->fbo->fbo = fbo; + tex->fbo->width = width; + tex->fbo->height = height; + tex->fbo->format = tex->format; + tex->fbo->cur_render_target = NULL; + tex->fbo->cur_render_side = 0; + tex->fbo->cur_zstencil_buffer = NULL; - da_push_back(device->fbos, &ptr); - return ptr; + return tex->fbo; } -static inline struct fbo_info *get_fbo_by_tex(struct gs_device *device, - gs_texture_t *tex) +static inline struct fbo_info *get_fbo_by_tex(gs_texture_t *tex) { uint32_t width, height; if (!get_tex_dimensions(tex, &width, &height)) return NULL; - return get_fbo(device, width, height, tex->format); + return get_fbo(tex, width, height); } static bool set_current_fbo(gs_device_t *device, struct fbo_info *fbo) @@ -783,7 +768,7 @@ static bool set_target(gs_device_t *device, gs_texture_t *tex, int side, if (!tex) return set_current_fbo(device, NULL); - fbo = get_fbo_by_tex(device, tex); + fbo = get_fbo_by_tex(tex); if (!fbo) return false; @@ -885,9 +870,8 @@ void device_copy_texture_region(gs_device_t *device, goto fail; } - if (!gl_copy_texture(device, dst->texture, dst->gl_target, dst_x, dst_y, - src->texture, src->gl_target, src_x, src_y, - nw, nh, src->format)) + if (!gl_copy_texture(device, dst, dst_x, dst_y, src, src_x, src_y, nw, + nh)) goto fail; return; @@ -1357,6 +1341,22 @@ void device_projection_pop(gs_device_t *device) da_pop_back(device->proj_stack); } +void device_debug_marker_begin(gs_device_t *device, + const char *markername, const float color[4]) +{ + UNUSED_PARAMETER(device); + UNUSED_PARAMETER(color); + + glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION, 0, -1, markername); +} + +void device_debug_marker_end(gs_device_t *device) +{ + UNUSED_PARAMETER(device); + + glPopDebugGroupKHR(); +} + void gs_swapchain_destroy(gs_swapchain_t *swapchain) { if (!swapchain) diff --git a/libobs-opengl/gl-subsystem.h b/libobs-opengl/gl-subsystem.h index 4467876..d5b89c9 100644 --- a/libobs-opengl/gl-subsystem.h +++ b/libobs-opengl/gl-subsystem.h @@ -36,7 +36,7 @@ enum copy_type { COPY_TYPE_FBO_BLIT }; -static inline GLint convert_gs_format(enum gs_color_format format) +static inline GLenum convert_gs_format(enum gs_color_format format) { switch (format) { case GS_A8: return GL_RED; @@ -51,6 +51,7 @@ static inline GLint convert_gs_format(enum gs_color_format format) case GS_RGBA32F: return GL_RGBA; case GS_RG16F: return GL_RG; case GS_RG32F: return GL_RG; + case GS_R8G8: return GL_RG; case GS_R16F: return GL_RED; case GS_R32F: return GL_RED; case GS_DXT1: return GL_RGB; @@ -62,7 +63,7 @@ static inline GLint convert_gs_format(enum gs_color_format format) return 0; } -static inline GLint convert_gs_internal_format(enum gs_color_format format) +static inline GLenum convert_gs_internal_format(enum gs_color_format format) { switch (format) { case GS_A8: return GL_R8; /* NOTE: use GL_TEXTURE_SWIZZLE_x */ @@ -77,6 +78,7 @@ static inline GLint convert_gs_internal_format(enum gs_color_format format) case GS_RGBA32F: return GL_RGBA32F; case GS_RG16F: return GL_RG16F; case GS_RG32F: return GL_RG32F; + case GS_R8G8: return GL_R16; case GS_R16F: return GL_R16F; case GS_R32F: return GL_R32F; case GS_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; @@ -103,6 +105,7 @@ static inline GLenum get_gl_format_type(enum gs_color_format format) case GS_RGBA32F: return GL_FLOAT; case GS_RG16F: return GL_UNSIGNED_SHORT; case GS_RG32F: return GL_FLOAT; + case GS_R8G8: return GL_UNSIGNED_SHORT; case GS_R16F: return GL_UNSIGNED_SHORT; case GS_R32F: return GL_FLOAT; case GS_DXT1: return GL_UNSIGNED_BYTE; @@ -399,7 +402,7 @@ struct gs_texture { enum gs_color_format format; GLenum gl_format; GLenum gl_target; - GLint gl_internal_format; + GLenum gl_internal_format; GLenum gl_type; GLuint texture; uint32_t levels; @@ -409,6 +412,7 @@ struct gs_texture { bool gen_mipmaps; gs_samplerstate_t *cur_sampler; + struct fbo_info *fbo; }; struct gs_texture_2d { @@ -501,12 +505,11 @@ struct gs_device { DARRAY(struct matrix4) proj_stack; - DARRAY(struct fbo_info*) fbos; struct fbo_info *cur_fbo; }; -extern struct fbo_info *get_fbo(struct gs_device *device, - uint32_t width, uint32_t height, enum gs_color_format format); +extern struct fbo_info *get_fbo(gs_texture_t *tex, uint32_t width, + uint32_t height); extern void gl_update(gs_device_t *device); diff --git a/libobs-opengl/gl-texture2d.c b/libobs-opengl/gl-texture2d.c index 1ad6c92..da18b9f 100644 --- a/libobs-opengl/gl-texture2d.c +++ b/libobs-opengl/gl-texture2d.c @@ -138,6 +138,9 @@ void gs_texture_destroy(gs_texture_t *tex) if (tex->texture) gl_delete_textures(1, &tex->texture); + if (tex->fbo) + fbo_info_destroy(tex->fbo); + bfree(tex); } diff --git a/libobs-opengl/gl-texturecube.c b/libobs-opengl/gl-texturecube.c index f15d6b2..6086675 100644 --- a/libobs-opengl/gl-texturecube.c +++ b/libobs-opengl/gl-texturecube.c @@ -92,10 +92,11 @@ void gs_cubetexture_destroy(gs_texture_t *tex) if (!tex) return; - if (tex->texture) { - glDeleteTextures(1, &tex->texture); - gl_success("glDeleteTextures"); - } + if (tex->texture) + gl_delete_textures(1, &tex->texture); + + if (tex->fbo) + fbo_info_destroy(tex->fbo); bfree(tex); } diff --git a/libobs-opengl/gl-windows.c b/libobs-opengl/gl-windows.c index a266930..c6c8499 100644 --- a/libobs-opengl/gl-windows.c +++ b/libobs-opengl/gl-windows.c @@ -532,7 +532,7 @@ void device_enter_context(gs_device_t *device) hdc = device->cur_swap->wi->hdc; if (!wgl_make_current(hdc, device->plat->hrc)) - blog(LOG_ERROR, "device_load_swapchain (GL) failed"); + blog(LOG_ERROR, "device_enter_context (GL) failed"); } void device_leave_context(gs_device_t *device) diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt index bddfa5c..fed3e69 100644 --- a/libobs/CMakeLists.txt +++ b/libobs/CMakeLists.txt @@ -116,7 +116,8 @@ elseif(APPLE) util/platform-nix.c util/platform-cocoa.m) set(libobs_PLATFORM_HEADERS - util/threading-posix.h) + util/threading-posix.h + util/apple/cfstring-utils.h) set(libobs_audio_monitoring_SOURCES audio-monitoring/osx/coreaudio-enum-devices.c audio-monitoring/osx/coreaudio-output.c @@ -383,6 +384,7 @@ set(libobs_libobs_SOURCES obs-view.c obs-scene.c obs-audio.c + obs-video-gpu-encode.c obs-video.c) set(libobs_libobs_HEADERS ${libobs_PLATFORM_HEADERS} @@ -446,6 +448,14 @@ if(BUILD_CAPTIONS) endif() add_library(libobs SHARED ${libobs_SOURCES} ${libobs_HEADERS}) +if(UNIX AND NOT APPLE) + set(DEST_DIR "${CMAKE_INSTALL_PREFIX}") + foreach(LIB "obs" "rt") + set(PRIVATE_LIBS "${PRIVATE_LIBS} -l${LIB}") + endforeach() + CONFIGURE_FILE("libobs.pc.in" "libobs.pc" @ONLY) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libobs.pc" DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/pkgconfig") +endif() set_target_properties(libobs PROPERTIES OUTPUT_NAME obs @@ -455,7 +465,12 @@ target_compile_definitions(libobs PUBLIC HAVE_OBSCONFIG_H) -if(NOT MSVC) +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") + target_compile_options(libobs + PUBLIC + -mvsx) + add_compile_definitions(NO_WARN_X86_INTRINSICS) +elseif(NOT MSVC) target_compile_options(libobs PUBLIC -mmmx diff --git a/libobs/audio-monitoring/osx/coreaudio-enum-devices.c b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c index 9f06cb6..8e6ea9e 100644 --- a/libobs/audio-monitoring/osx/coreaudio-enum-devices.c +++ b/libobs/audio-monitoring/osx/coreaudio-enum-devices.c @@ -3,23 +3,18 @@ #include "../../obs-internal.h" #include "../../util/dstr.h" +#include "../../util/apple/cfstring-utils.h" #include "mac-helpers.h" -static inline bool cf_to_cstr(CFStringRef ref, char *buf, size_t size) -{ - if (!ref) return false; - return (bool)CFStringGetCString(ref, buf, size, kCFStringEncodingUTF8); -} - static bool obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb, void *data, AudioDeviceID id, bool allow_inputs) { UInt32 size = 0; CFStringRef cf_name = NULL; CFStringRef cf_uid = NULL; - char name[1024]; - char uid[1024]; + char *name = NULL; + char *uid = NULL; OSStatus stat; bool cont = true; @@ -46,12 +41,14 @@ static bool obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb, if (!success(stat, "get audio device name")) goto fail; - if (!cf_to_cstr(cf_name, name, sizeof(name))) { + name = cfstr_copy_cstr(cf_name, kCFStringEncodingUTF8); + if (!name) { blog(LOG_WARNING, "%s: failed to convert name", __FUNCTION__); goto fail; } - if (!cf_to_cstr(cf_uid, uid, sizeof(uid))) { + uid = cfstr_copy_cstr(cf_uid, kCFStringEncodingUTF8); + if (!uid) { blog(LOG_WARNING, "%s: failed to convert uid", __FUNCTION__); goto fail; } @@ -59,6 +56,8 @@ static bool obs_enum_audio_monitoring_device(obs_enum_audio_device_cb cb, cont = cb(data, name, uid); fail: + bfree(name); + bfree(uid); if (cf_name) CFRelease(cf_name); if (cf_uid) diff --git a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c index fc41d7a..4bbbc9b 100644 --- a/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c +++ b/libobs/audio-monitoring/pulse/pulseaudio-wrapper.c @@ -307,14 +307,15 @@ int_fast32_t pulseaudio_connect_playback(pa_stream *s, const char *name, return -1; size_t dev_len = strlen(name) - 8; - char device[dev_len]; + char *device = bzalloc(dev_len + 1); memcpy(device, name, dev_len); - device[dev_len] = '\0'; pulseaudio_lock(); int_fast32_t ret = pa_stream_connect_playback(s, device, attr, flags, NULL, NULL); pulseaudio_unlock(); + + bfree(device); return ret; } diff --git a/libobs/audio-monitoring/win32/wasapi-output.h b/libobs/audio-monitoring/win32/wasapi-output.h index c3523b5..8c42868 100644 --- a/libobs/audio-monitoring/win32/wasapi-output.h +++ b/libobs/audio-monitoring/win32/wasapi-output.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include diff --git a/libobs/data/area.effect b/libobs/data/area.effect new file mode 100644 index 0000000..c9369f8 --- /dev/null +++ b/libobs/data/area.effect @@ -0,0 +1,64 @@ +uniform float4x4 ViewProj; +uniform float2 base_dimension_i; +uniform texture2d image; + +struct VertInOut { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertInOut VSDefault(VertInOut vert_in) +{ + VertInOut vert_out; + vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = vert_in.uv; + return vert_out; +} + +float4 PSDrawAreaRGBA(VertInOut vert_in) : TARGET +{ + float4 totalcolor = float4(0.0, 0.0, 0.0, 0.0); + + float2 uv = vert_in.uv; + float2 uvdelta = float2(ddx(uv.x), ddy(uv.y)); + + // Handle potential OpenGL flip. + uvdelta.y = abs(uvdelta.y); + + float2 uvhalfdelta = 0.5 * uvdelta; + float2 uvmin = uv - uvhalfdelta; + float2 uvmax = uv + uvhalfdelta; + + int2 loadindexmin = int2(uvmin / base_dimension_i); + int2 loadindexmax = int2(uvmax / base_dimension_i); + + float2 targetpos = uv / uvdelta; + float2 targetposmin = targetpos - 0.5; + float2 targetposmax = targetpos + 0.5; + float2 scale = base_dimension_i / uvdelta; + for (int loadindexy = loadindexmin.y; loadindexy <= loadindexmax.y; ++loadindexy) + { + for (int loadindexx = loadindexmin.x; loadindexx <= loadindexmax.x; ++loadindexx) + { + int2 loadindex = int2(loadindexx, loadindexy); + float2 potentialtargetmin = float2(loadindex) * scale; + float2 potentialtargetmax = potentialtargetmin + scale; + float2 targetmin = max(potentialtargetmin, targetposmin); + float2 targetmax = min(potentialtargetmax, targetposmax); + float area = (targetmax.x - targetmin.x) * (targetmax.y - targetmin.y); + float4 sample = image.Load(int3(loadindex, 0)); + totalcolor += area * sample; + } + } + + return totalcolor; +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDrawAreaRGBA(vert_in); + } +} diff --git a/libobs/data/bicubic_scale.effect b/libobs/data/bicubic_scale.effect index 67ebb89..0f55292 100644 --- a/libobs/data/bicubic_scale.effect +++ b/libobs/data/bicubic_scale.effect @@ -7,8 +7,6 @@ uniform float4x4 ViewProj; uniform texture2d image; uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float2 base_dimension_i; uniform float undistort_factor = 1.0; @@ -132,13 +130,19 @@ float4 PSDrawBicubicRGBA(VertData v_in, bool undistort) : TARGET return DrawBicubic(v_in, undistort); } -float4 PSDrawBicubicMatrix(VertData v_in) : TARGET +float4 PSDrawBicubicRGBADivide(VertData v_in) : TARGET { float4 rgba = DrawBicubic(v_in, false); - float4 yuv; + float alpha = rgba.a; + float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; + return float4(rgba.rgb * multiplier, alpha); +} - yuv.xyz = clamp(rgba.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); +float4 PSDrawBicubicMatrix(VertData v_in) : TARGET +{ + float3 rgb = DrawBicubic(v_in, false).rgb; + float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; + return float4(yuv, 1.0); } technique Draw @@ -150,6 +154,15 @@ technique Draw } } +technique DrawAlphaDivide +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDrawBicubicRGBADivide(v_in); + } +} + technique DrawUndistort { pass diff --git a/libobs/data/bilinear_lowres_scale.effect b/libobs/data/bilinear_lowres_scale.effect index bb158d7..e887072 100644 --- a/libobs/data/bilinear_lowres_scale.effect +++ b/libobs/data/bilinear_lowres_scale.effect @@ -6,8 +6,6 @@ uniform float4x4 ViewProj; uniform texture2d image; uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float2 base_dimension_i; sampler_state textureSampler { @@ -56,12 +54,19 @@ float4 PSDrawLowresBilinearRGBA(VertData v_in) : TARGET return DrawLowresBilinear(v_in); } +float4 PSDrawLowresBilinearRGBADivide(VertData v_in) : TARGET +{ + float4 rgba = DrawLowresBilinear(v_in); + float alpha = rgba.a; + float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; + return float4(rgba.rgb * multiplier, alpha); +} + float4 PSDrawLowresBilinearMatrix(VertData v_in) : TARGET { - float4 yuv = DrawLowresBilinear(v_in); - - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); + float3 rgb = DrawLowresBilinear(v_in).rgb; + float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; + return float4(yuv, 1.0); } technique Draw @@ -73,6 +78,15 @@ technique Draw } } +technique DrawAlphaDivide +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDrawLowresBilinearRGBADivide(v_in); + } +} + technique DrawMatrix { pass diff --git a/libobs/data/default.effect b/libobs/data/default.effect index 37e0110..54e07fa 100644 --- a/libobs/data/default.effect +++ b/libobs/data/default.effect @@ -1,7 +1,5 @@ uniform float4x4 ViewProj; uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d image; sampler_state def_sampler { @@ -28,11 +26,19 @@ float4 PSDrawBare(VertInOut vert_in) : TARGET return image.Sample(def_sampler, vert_in.uv); } +float4 PSDrawAlphaDivide(VertInOut vert_in) : TARGET +{ + float4 rgba = image.Sample(def_sampler, vert_in.uv); + float alpha = rgba.a; + float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; + return float4(rgba.rgb * multiplier, alpha); +} + float4 PSDrawMatrix(VertInOut vert_in) : TARGET { - float4 yuv = image.Sample(def_sampler, vert_in.uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); + float3 rgb = image.Sample(def_sampler, vert_in.uv).rgb; + float3 yuv = mul(float4(rgb, 1.0), color_matrix).xyz; + return float4(yuv, 1.0); } technique Draw @@ -44,6 +50,15 @@ technique Draw } } +technique DrawAlphaDivide +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDrawAlphaDivide(vert_in); + } +} + technique DrawMatrix { pass diff --git a/libobs/data/deinterlace_base.effect b/libobs/data/deinterlace_base.effect index 8755da7..da4a138 100644 --- a/libobs/data/deinterlace_base.effect +++ b/libobs/data/deinterlace_base.effect @@ -18,9 +18,6 @@ uniform float4x4 ViewProj; uniform texture2d image; -uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform texture2d previous_image; uniform float2 dimensions; @@ -267,7 +264,7 @@ VertData VSDefault(VertData v_in) return vert_out; } -#define TECHNIQUE(rgba_ps, matrix_ps) \ +#define TECHNIQUE(rgba_ps) \ technique Draw \ { \ pass \ @@ -275,19 +272,4 @@ technique Draw \ vertex_shader = VSDefault(v_in); \ pixel_shader = rgba_ps(v_in); \ } \ -} \ -float4 matrix_ps(VertData v_in) : TARGET \ -{ \ - float4 yuv = rgba_ps(v_in); \ - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); \ - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); \ -} \ -\ -technique DrawMatrix \ -{ \ - pass \ - { \ - vertex_shader = VSDefault(v_in); \ - pixel_shader = matrix_ps(v_in); \ - } \ } diff --git a/libobs/data/deinterlace_blend.effect b/libobs/data/deinterlace_blend.effect index 7def8e2..ab12376 100644 --- a/libobs/data/deinterlace_blend.effect +++ b/libobs/data/deinterlace_blend.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE( PSBlendRGBA, PSBlendMatrix); +TECHNIQUE(PSBlendRGBA); diff --git a/libobs/data/deinterlace_blend_2x.effect b/libobs/data/deinterlace_blend_2x.effect index 33c102c..392e4fd 100644 --- a/libobs/data/deinterlace_blend_2x.effect +++ b/libobs/data/deinterlace_blend_2x.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSBlendRGBA_2x, PSBlendMatrix_2x); +TECHNIQUE(PSBlendRGBA_2x); diff --git a/libobs/data/deinterlace_discard.effect b/libobs/data/deinterlace_discard.effect index e1ce6e1..20dc6ce 100644 --- a/libobs/data/deinterlace_discard.effect +++ b/libobs/data/deinterlace_discard.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSDiscardRGBA, PSDiscardMatrix); +TECHNIQUE(PSDiscardRGBA); diff --git a/libobs/data/deinterlace_discard_2x.effect b/libobs/data/deinterlace_discard_2x.effect index fe6eb9e..66299c2 100644 --- a/libobs/data/deinterlace_discard_2x.effect +++ b/libobs/data/deinterlace_discard_2x.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSDiscardRGBA_2x, PSDiscardMatrix_2x); +TECHNIQUE(PSDiscardRGBA_2x); diff --git a/libobs/data/deinterlace_linear.effect b/libobs/data/deinterlace_linear.effect index 19aa513..1291bf0 100644 --- a/libobs/data/deinterlace_linear.effect +++ b/libobs/data/deinterlace_linear.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSLinearRGBA, PSLinearMatrix); +TECHNIQUE(PSLinearRGBA); diff --git a/libobs/data/deinterlace_linear_2x.effect b/libobs/data/deinterlace_linear_2x.effect index 69224ae..989c8ca 100644 --- a/libobs/data/deinterlace_linear_2x.effect +++ b/libobs/data/deinterlace_linear_2x.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSLinearRGBA_2x, PSLinearxMatrixA_2x); +TECHNIQUE(PSLinearRGBA_2x); diff --git a/libobs/data/deinterlace_yadif.effect b/libobs/data/deinterlace_yadif.effect index e22fe06..0a064cc 100644 --- a/libobs/data/deinterlace_yadif.effect +++ b/libobs/data/deinterlace_yadif.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSYadifMode0RGBA, PSYadifMode0Matrix); +TECHNIQUE(PSYadifMode0RGBA); diff --git a/libobs/data/deinterlace_yadif_2x.effect b/libobs/data/deinterlace_yadif_2x.effect index 6c1d329..b5dfe72 100644 --- a/libobs/data/deinterlace_yadif_2x.effect +++ b/libobs/data/deinterlace_yadif_2x.effect @@ -18,4 +18,4 @@ #include "deinterlace_base.effect" -TECHNIQUE(PSYadifMode0RGBA_2x, PSYadifMode0Matrix_2x); +TECHNIQUE(PSYadifMode0RGBA_2x); diff --git a/libobs/data/format_conversion.effect b/libobs/data/format_conversion.effect index edf1a9e..b3d274e 100644 --- a/libobs/data/format_conversion.effect +++ b/libobs/data/format_conversion.effect @@ -42,6 +42,10 @@ uniform int int_input_width; uniform int int_u_plane_offset; uniform int int_v_plane_offset; +uniform float4x4 color_matrix; +uniform float3 color_range_min = {0.0, 0.0, 0.0}; +uniform float3 color_range_max = {1.0, 1.0, 1.0}; + uniform texture2d image; sampler_state def_sampler { @@ -126,6 +130,16 @@ float4 PSNV12(VertInOut vert_in) : TARGET } } +float PSNV12_Y(VertInOut vert_in) : TARGET +{ + return image.Sample(def_sampler, vert_in.uv.xy).y; +} + +float2 PSNV12_UV(VertInOut vert_in) : TARGET +{ + return image.Sample(def_sampler, vert_in.uv.xy).xz; +} + float4 PSPlanar420(VertInOut vert_in) : TARGET { float v_mul = floor(vert_in.uv.y * input_height); @@ -273,8 +287,10 @@ float4 PSPacked422_Reverse(VertInOut vert_in, int u_pos, int v_pos, x += input_width_i_d2; float4 texel = image.Sample(def_sampler, float2(x, y)); - return float4(odd > 0.5 ? texel[y1_pos] : texel[y0_pos], - texel[u_pos], texel[v_pos], 1.0); + float3 yuv = float3(odd > 0.5 ? texel[y1_pos] : texel[y0_pos], + texel[u_pos], texel[v_pos]); + yuv = clamp(yuv, color_range_min, color_range_max); + return saturate(mul(float4(yuv, 1.0), color_matrix)); } float4 PSPlanar420_Reverse(VertInOut vert_in) : TARGET @@ -287,12 +303,32 @@ float4 PSPlanar420_Reverse(VertInOut vert_in) : TARGET int chroma1 = int_u_plane_offset + chroma_offset; int chroma2 = int_v_plane_offset + chroma_offset; - return float4( + float3 yuv = float3( GetIntOffsetColor(lum_offset), GetIntOffsetColor(chroma1), - GetIntOffsetColor(chroma2), - 1.0 + GetIntOffsetColor(chroma2) ); + yuv = clamp(yuv, color_range_min, color_range_max); + return saturate(mul(float4(yuv, 1.0), color_matrix)); +} + +float4 PSPlanar444_Reverse(VertInOut vert_in) : TARGET +{ + int x = int(vert_in.uv.x * width + PRECISION_OFFSET); + int y = int(vert_in.uv.y * height + PRECISION_OFFSET); + + int lum_offset = y * int_width + x; + int chroma_offset = y * int_width + x; + int chroma1 = int_u_plane_offset + chroma_offset; + int chroma2 = int_v_plane_offset + chroma_offset; + + float3 yuv = float3( + GetIntOffsetColor(lum_offset), + GetIntOffsetColor(chroma1), + GetIntOffsetColor(chroma2) + ); + yuv = clamp(yuv, color_range_min, color_range_max); + return saturate(mul(float4(yuv, 1.0), color_matrix)); } float4 PSNV12_Reverse(VertInOut vert_in) : TARGET @@ -304,12 +340,42 @@ float4 PSNV12_Reverse(VertInOut vert_in) : TARGET int chroma_offset = (y / 2) * (int_width / 2) + x / 2; int chroma = int_u_plane_offset + chroma_offset * 2; - return float4( + float3 yuv = float3( GetIntOffsetColor(lum_offset), GetIntOffsetColor(chroma), - GetIntOffsetColor(chroma + 1), - 1.0 + GetIntOffsetColor(chroma + 1) ); + yuv = clamp(yuv, color_range_min, color_range_max); + return saturate(mul(float4(yuv, 1.0), color_matrix)); +} + +float4 PSY800_Limited(VertInOut vert_in) : TARGET +{ + int x = int(vert_in.uv.x * width + PRECISION_OFFSET); + int y = int(vert_in.uv.y * height + PRECISION_OFFSET); + + float limited = image.Load(int3(x, y, 0)).x; + float full = saturate((limited - (16.0 / 255.0)) * (255.0 / 219.0)); + return float4(full, full, full, 1.0); +} + +float4 PSY800_Full(VertInOut vert_in) : TARGET +{ + int x = int(vert_in.uv.x * width + PRECISION_OFFSET); + int y = int(vert_in.uv.y * height + PRECISION_OFFSET); + + float3 full = image.Load(int3(x, y, 0)).xxx; + return float4(full, 1.0); +} + +float4 PSRGB_Limited(VertInOut vert_in) : TARGET +{ + int x = int(vert_in.uv.x * width + PRECISION_OFFSET); + int y = int(vert_in.uv.y * height + PRECISION_OFFSET); + + float4 rgba = image.Load(int3(x, y, 0)); + rgba.rgb = saturate((rgba.rgb - (16.0 / 255.0)) * (255.0 / 219.0)); + return rgba; } technique Planar420 @@ -339,6 +405,24 @@ technique NV12 } } +technique NV12_Y +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSNV12_Y(vert_in); + } +} + +technique NV12_UV +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSNV12_UV(vert_in); + } +} + technique UYVY_Reverse { pass @@ -375,6 +459,15 @@ technique I420_Reverse } } +technique I444_Reverse +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSPlanar444_Reverse(vert_in); + } +} + technique NV12_Reverse { pass @@ -383,3 +476,30 @@ technique NV12_Reverse pixel_shader = PSNV12_Reverse(vert_in); } } + +technique Y800_Limited +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSY800_Limited(vert_in); + } +} + +technique Y800_Full +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSY800_Full(vert_in); + } +} + +technique RGB_Limited +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSRGB_Limited(vert_in); + } +} diff --git a/libobs/data/lanczos_scale.effect b/libobs/data/lanczos_scale.effect index 4fc6453..061acc4 100644 --- a/libobs/data/lanczos_scale.effect +++ b/libobs/data/lanczos_scale.effect @@ -7,8 +7,6 @@ uniform float4x4 ViewProj; uniform texture2d image; uniform float4x4 color_matrix; -uniform float3 color_range_min = {0.0, 0.0, 0.0}; -uniform float3 color_range_max = {1.0, 1.0, 1.0}; uniform float2 base_dimension_i; uniform float undistort_factor = 1.0; @@ -140,13 +138,19 @@ float4 PSDrawLanczosRGBA(FragData v_in, bool undistort) : TARGET return DrawLanczos(v_in, undistort); } -float4 PSDrawLanczosMatrix(FragData v_in) : TARGET +float4 PSDrawLanczosRGBADivide(FragData v_in) : TARGET { float4 rgba = DrawLanczos(v_in, false); - float4 yuv; + float alpha = rgba.a; + float multiplier = (alpha > 0.0) ? (1.0 / alpha) : 0.0; + return float4(rgba.rgb * multiplier, alpha); +} - yuv.xyz = clamp(rgba.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); +float4 PSDrawLanczosMatrix(FragData v_in) : TARGET +{ + float3 rgb = DrawLanczos(v_in, false).rgb; + float3 yuv = mul(float4(saturate(rgb), 1.0), color_matrix).xyz; + return float4(yuv, 1.0); } technique Draw @@ -158,6 +162,15 @@ technique Draw } } +technique DrawAlphaDivide +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSDrawLanczosRGBADivide(v_in); + } +} + technique DrawUndistort { pass diff --git a/libobs/data/repeat.effect b/libobs/data/repeat.effect new file mode 100644 index 0000000..95ca047 --- /dev/null +++ b/libobs/data/repeat.effect @@ -0,0 +1,36 @@ +uniform float4x4 ViewProj; +uniform texture2d image; +uniform float2 scale; + +sampler_state def_sampler { + Filter = Linear; + AddressU = Repeat; + AddressV = Repeat; +}; + +struct VertInOut { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertInOut VSDefault(VertInOut vert_in) +{ + VertInOut vert_out; + vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = vert_in.uv * scale; + return vert_out; +} + +float4 PSDrawBare(VertInOut vert_in) : TARGET +{ + return image.Sample(def_sampler, vert_in.uv); +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(vert_in); + pixel_shader = PSDrawBare(vert_in); + } +} diff --git a/libobs/graphics/device-exports.h b/libobs/graphics/device-exports.h index 5bb29c2..2158e58 100644 --- a/libobs/graphics/device-exports.h +++ b/libobs/graphics/device-exports.h @@ -142,6 +142,9 @@ EXPORT void device_frustum(gs_device_t *device, float left, float right, float top, float bottom, float znear, float zfar); EXPORT void device_projection_push(gs_device_t *device); EXPORT void device_projection_pop(gs_device_t *device); +EXPORT void device_debug_marker_begin(gs_device_t *device, + const char *markername, const float color[4]); +EXPORT void device_debug_marker_end(gs_device_t *device); #ifdef __cplusplus } diff --git a/libobs/graphics/effect-parser.c b/libobs/graphics/effect-parser.c index d721b41..70e9842 100644 --- a/libobs/graphics/effect-parser.c +++ b/libobs/graphics/effect-parser.c @@ -21,6 +21,39 @@ #include "effect-parser.h" #include "effect.h" +static inline bool ep_parse_param_assign(struct effect_parser *ep, + struct ep_param *param); + +static enum gs_shader_param_type get_effect_param_type(const char *type) +{ + if (strcmp(type, "float") == 0) + return GS_SHADER_PARAM_FLOAT; + else if (strcmp(type, "float2") == 0) + return GS_SHADER_PARAM_VEC2; + else if (strcmp(type, "float3") == 0) + return GS_SHADER_PARAM_VEC3; + else if (strcmp(type, "float4") == 0) + return GS_SHADER_PARAM_VEC4; + else if (strcmp(type, "int2") == 0) + return GS_SHADER_PARAM_INT2; + else if (strcmp(type, "int3") == 0) + return GS_SHADER_PARAM_INT3; + else if (strcmp(type, "int4") == 0) + return GS_SHADER_PARAM_INT4; + else if (astrcmp_n(type, "texture", 7) == 0) + return GS_SHADER_PARAM_TEXTURE; + else if (strcmp(type, "float4x4") == 0) + return GS_SHADER_PARAM_MATRIX4X4; + else if (strcmp(type, "bool") == 0) + return GS_SHADER_PARAM_BOOL; + else if (strcmp(type, "int") == 0) + return GS_SHADER_PARAM_INT; + else if (strcmp(type, "string") == 0) + return GS_SHADER_PARAM_STRING; + + return GS_SHADER_PARAM_UNKNOWN; +} + void ep_free(struct effect_parser *ep) { size_t i; @@ -92,6 +125,18 @@ static inline struct ep_param *ep_getparam(struct effect_parser *ep, return NULL; } +static inline struct ep_param *ep_getannotation(struct ep_param *param, + const char *name) +{ + size_t i; + for (i = 0; i < param->annotations.num; i++) { + if (strcmp(name, param->annotations.array[i].name) == 0) + return param->annotations.array+i; + } + + return NULL; +} + static inline struct ep_func *ep_getfunc_strref(struct effect_parser *ep, const struct strref *ref) { @@ -262,6 +307,145 @@ error: ep_struct_free(&eps); } +static inline int ep_parse_param_annotation_var(struct effect_parser *ep, + struct ep_param *var) +{ + int code; + + /* -------------------------------------- */ + /* variable type */ + + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; + + if (cf_token_is(&ep->cfp, ";")) + return PARSE_CONTINUE; + if (cf_token_is(&ep->cfp, ">")) + return PARSE_BREAK; + + code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";"); + if (code != PARSE_SUCCESS) + return code; + + bfree(var->type); + cf_copy_token(&ep->cfp, &var->type); + + /* -------------------------------------- */ + /* variable name */ + + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; + + if (cf_token_is(&ep->cfp, ";")) { + cf_adderror_expecting(&ep->cfp, "variable name"); + return PARSE_UNEXPECTED_CONTINUE; + } + if (cf_token_is(&ep->cfp, ">")) { + cf_adderror_expecting(&ep->cfp, "variable name"); + return PARSE_UNEXPECTED_BREAK; + } + + code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";"); + if (code != PARSE_SUCCESS) + return code; + + bfree(var->name); + cf_copy_token(&ep->cfp, &var->name); + + /* -------------------------------------- */ + /* variable mapping if any (POSITION, TEXCOORD, etc) */ + + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; + + if (cf_token_is(&ep->cfp, ":")) { + cf_adderror_expecting(&ep->cfp, "= or ;"); + return PARSE_UNEXPECTED_BREAK; + } else if (cf_token_is(&ep->cfp, ">")) { + cf_adderror_expecting(&ep->cfp, "= or ;"); + return PARSE_UNEXPECTED_BREAK; + } else if (cf_token_is(&ep->cfp, "=")) { + if (!ep_parse_param_assign(ep, var)) { + cf_adderror_expecting(&ep->cfp, "assignment value"); + return PARSE_UNEXPECTED_BREAK; + } + } + + /* -------------------------------------- */ + + if (!cf_token_is(&ep->cfp, ";")) { + if (!cf_go_to_valid_token(&ep->cfp, ";", ">")) { + cf_adderror_expecting(&ep->cfp, "; or >"); + return PARSE_EOF; + } + return PARSE_CONTINUE; + } + + return PARSE_SUCCESS; +} + +static int ep_parse_annotations(struct effect_parser *ep, + struct darray *annotations) +{ + if (!cf_token_is(&ep->cfp, "<")) { + cf_adderror_expecting(&ep->cfp, "<"); + goto error; + } + + /* get annotation variables */ + while (true) { + bool do_break = false; + struct ep_param var; + + ep_param_init(&var, bstrdup(""), bstrdup(""), false, false, + false); + + switch (ep_parse_param_annotation_var(ep, &var)) { + case PARSE_UNEXPECTED_CONTINUE: + cf_adderror_syntax_error(&ep->cfp); + /* Falls through. */ + case PARSE_CONTINUE: + ep_param_free(&var); + continue; + + case PARSE_UNEXPECTED_BREAK: + cf_adderror_syntax_error(&ep->cfp); + /* Falls through. */ + case PARSE_BREAK: + ep_param_free(&var); + do_break = true; + break; + + case PARSE_EOF: + ep_param_free(&var); + goto error; + } + + if (do_break) + break; + + darray_push_back(sizeof(struct ep_param), annotations, &var); + } + + if (!cf_token_is(&ep->cfp, ">")) { + cf_adderror_expecting(&ep->cfp, ">"); + goto error; + } + if (!cf_next_valid_token(&ep->cfp)) + goto error; + + return true; + +error: + return false; +} + +static int ep_parse_param_annotations(struct effect_parser *ep, + struct ep_param *param) +{ + return ep_parse_annotations(ep, ¶m->annotations.da); +} + static inline int ep_parse_pass_command_call(struct effect_parser *ep, struct darray *call) { @@ -328,7 +512,7 @@ static int ep_parse_pass(struct effect_parser *ep, struct ep_pass *pass) if (!cf_token_is(&ep->cfp, "{")) { pass->name = bstrdup_n(ep->cfp.cur_token->str.array, - ep->cfp.cur_token->str.len); + ep->cfp.cur_token->str.len); if (!cf_next_valid_token(&ep->cfp)) return PARSE_EOF; } @@ -356,9 +540,19 @@ static void ep_parse_technique(struct effect_parser *ep) if (cf_next_name(&ep->cfp, &ept.name, "name", ";") != PARSE_SUCCESS) goto error; - if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS) - goto error; + if (!cf_next_valid_token(&ep->cfp)) + return; + + if (!cf_token_is(&ep->cfp, "{")) { + if (!cf_go_to_token(&ep->cfp, ";", NULL)) { + cf_adderror_expecting(&ep->cfp, ";"); + return; + } + + cf_adderror_expecting(&ep->cfp, "{"); + goto error; + } if (!cf_next_valid_token(&ep->cfp)) goto error; @@ -756,6 +950,30 @@ static inline int ep_parse_param_assign_texture(struct effect_parser *ep, return PARSE_SUCCESS; } +static inline int ep_parse_param_assign_string(struct effect_parser *ep, + struct ep_param *param) +{ + int code; + char *str = NULL; + + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; + + code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, "string", ";"); + if (code != PARSE_SUCCESS) + return code; + + str = cf_literal_to_str(ep->cfp.cur_token->str.array, + ep->cfp.cur_token->str.len); + + if (str) { + da_copy_array(param->default_val, str, strlen(str) + 1); + bfree(str); + } + + return PARSE_SUCCESS; +} + static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, struct ep_param *param, bool is_float) { @@ -789,30 +1007,51 @@ static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, return PARSE_SUCCESS; } -/* - * parses assignment for float1, float2, float3, float4, and any combination - * for float3x3, float4x4, etc - */ -static inline int ep_parse_param_assign_float_array(struct effect_parser *ep, +static inline int ep_parse_param_assign_bool(struct effect_parser *ep, struct ep_param *param) { - const char *float_type = param->type+5; - int float_count = 0, code, i; + if (!cf_next_valid_token(&ep->cfp)) + return PARSE_EOF; + + if (cf_token_is(&ep->cfp, "true")) { + long l = 1; + da_push_back_array(param->default_val, &l, sizeof(long)); + return PARSE_SUCCESS; + } else if (cf_token_is(&ep->cfp, "false")) { + long l = 0; + da_push_back_array(param->default_val, &l, sizeof(long)); + return PARSE_SUCCESS; + } + + cf_adderror_expecting(&ep->cfp, "true or false"); + + return PARSE_EOF; +} + +/* + * parses assignment for float1, float2, float3, float4, int1, int2, int3, int4, + * and any combination for float3x3, float4x4, int3x3, int4x4, etc +*/ +static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep, + struct ep_param *param, bool is_float) +{ + const char *intfloat_type = param->type + (is_float ? 5 : 3); + int intfloat_count = 0, code, i; /* -------------------------------------------- */ - if (float_type[0] < '1' || float_type[0] > '4') + if (intfloat_type[0] < '1' || intfloat_type[0] > '4') cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR, NULL, NULL, NULL); - float_count = float_type[0]-'0'; + intfloat_count = intfloat_type[0]-'0'; - if (float_type[1] == 'x') { - if (float_type[2] < '1' || float_type[2] > '4') + if (intfloat_type[1] == 'x') { + if (intfloat_type[2] < '1' || intfloat_type[2] > '4') cf_adderror(&ep->cfp, "Invalid column count", LEX_ERROR, NULL, NULL, NULL); - float_count *= float_type[2]-'0'; + intfloat_count *= intfloat_type[2]-'0'; } /* -------------------------------------------- */ @@ -820,10 +1059,10 @@ static inline int ep_parse_param_assign_float_array(struct effect_parser *ep, code = cf_next_token_should_be(&ep->cfp, "{", ";", NULL); if (code != PARSE_SUCCESS) return code; - for (i = 0; i < float_count; i++) { - char *next = ((i+1) < float_count) ? "," : "}"; + for (i = 0; i < intfloat_count; i++) { + char *next = ((i+1) < intfloat_count) ? "," : "}"; - code = ep_parse_param_assign_intfloat(ep, param, true); + code = ep_parse_param_assign_intfloat(ep, param, is_float); if (code != PARSE_SUCCESS) return code; code = cf_next_token_should_be(&ep->cfp, next, ";", NULL); @@ -842,8 +1081,14 @@ static int ep_parse_param_assignment_val(struct effect_parser *ep, return ep_parse_param_assign_intfloat(ep, param, false); else if (strcmp(param->type, "float") == 0) return ep_parse_param_assign_intfloat(ep, param, true); + else if (astrcmp_n(param->type, "int", 3) == 0) + return ep_parse_param_assign_intfloat_array(ep, param, false); else if (astrcmp_n(param->type, "float", 5) == 0) - return ep_parse_param_assign_float_array(ep, param); + return ep_parse_param_assign_intfloat_array(ep, param, true); + else if (astrcmp_n(param->type, "string", 6) == 0) + return ep_parse_param_assign_string(ep, param); + else if (strcmp(param->type, "bool") == 0) + return ep_parse_param_assign_bool(ep, param); cf_adderror(&ep->cfp, "Invalid type '$1' used for assignment", LEX_ERROR, param->type, NULL, NULL); @@ -879,6 +1124,9 @@ static void ep_parse_param(struct effect_parser *ep, goto complete; if (cf_token_is(&ep->cfp, "[") && !ep_parse_param_array(ep, ¶m)) goto error; + if (cf_token_is(&ep->cfp, "<") && !ep_parse_param_annotations(ep, + ¶m)) + goto error; if (cf_token_is(&ep->cfp, "=") && !ep_parse_param_assign(ep, ¶m)) goto error; /* @@ -945,7 +1193,6 @@ static void ep_parse_other(struct effect_parser *ep) goto error; if (cf_next_name(&ep->cfp, &name, "name", ";") != PARSE_SUCCESS) goto error; - if (!cf_next_valid_token(&ep->cfp)) goto error; @@ -971,6 +1218,213 @@ static bool ep_compile(struct effect_parser *ep); extern const char *gs_preprocessor_name(void); +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) +static void debug_get_default_value(struct gs_effect_param *param, + char* buffer, unsigned long long buf_size) +{ + if (param->default_val.num == 0) { + snprintf(buffer, buf_size, "(null)"); + return; + } + + switch (param->type) { + case GS_SHADER_PARAM_STRING: + snprintf(buffer, buf_size, "'%.*s'", + param->default_val.num, + param->default_val.array); + break; + case GS_SHADER_PARAM_INT: + snprintf(buffer, buf_size, "%ld", + *(int*)(param->default_val.array + 0)); + break; + case GS_SHADER_PARAM_INT2: + snprintf(buffer, buf_size, "%ld,%ld", + *(int*)(param->default_val.array + 0), + *(int*)(param->default_val.array + 4)); + break; + case GS_SHADER_PARAM_INT3: + snprintf(buffer, buf_size, "%ld,%ld,%ld", + *(int*)(param->default_val.array + 0), + *(int*)(param->default_val.array + 4), + *(int*)(param->default_val.array + 8)); + break; + case GS_SHADER_PARAM_INT4: + snprintf(buffer, buf_size, "%ld,%ld,%ld,%ld", + *(int*)(param->default_val.array + 0), + *(int*)(param->default_val.array + 4), + *(int*)(param->default_val.array + 8), + *(int*)(param->default_val.array + 12)); + break; + case GS_SHADER_PARAM_FLOAT: + snprintf(buffer, buf_size, "%e", + *(float*)(param->default_val.array + 0)); + break; + case GS_SHADER_PARAM_VEC2: + snprintf(buffer, buf_size, "%e,%e", + *(float*)(param->default_val.array + 0), + *(float*)(param->default_val.array + 4)); + break; + case GS_SHADER_PARAM_VEC3: + snprintf(buffer, buf_size, "%e,%e,%e", + *(float*)(param->default_val.array + 0), + *(float*)(param->default_val.array + 4), + *(float*)(param->default_val.array + 8)); + break; + case GS_SHADER_PARAM_VEC4: + snprintf(buffer, buf_size, "%e,%e,%e,%e", + *(float*)(param->default_val.array + 0), + *(float*)(param->default_val.array + 4), + *(float*)(param->default_val.array + 8), + *(float*)(param->default_val.array + 12)); + break; + case GS_SHADER_PARAM_MATRIX4X4: + snprintf(buffer, buf_size, + "[[%e,%e,%e,%e],[%e,%e,%e,%e]," + "[%e,%e,%e,%e],[%e,%e,%e,%e]]", + *(float*)(param->default_val.array + 0), + *(float*)(param->default_val.array + 4), + *(float*)(param->default_val.array + 8), + *(float*)(param->default_val.array + 12), + *(float*)(param->default_val.array + 16), + *(float*)(param->default_val.array + 20), + *(float*)(param->default_val.array + 24), + *(float*)(param->default_val.array + 28), + *(float*)(param->default_val.array + 32), + *(float*)(param->default_val.array + 36), + *(float*)(param->default_val.array + 40), + *(float*)(param->default_val.array + 44), + *(float*)(param->default_val.array + 48), + *(float*)(param->default_val.array + 52), + *(float*)(param->default_val.array + 56), + *(float*)(param->default_val.array + 60)); + break; + case GS_SHADER_PARAM_BOOL: + snprintf(buffer, buf_size, "%s", + (*param->default_val.array) != 0 + ? "true\0" + : "false\0"); + break; + case GS_SHADER_PARAM_UNKNOWN: + case GS_SHADER_PARAM_TEXTURE: + snprintf(buffer, buf_size, ""); + break; + } +} + +static void debug_param(struct gs_effect_param *param, + struct ep_param *param_in, unsigned long long idx, const char* offset) +{ + char _debug_type[4096]; + switch (param->type) { + case GS_SHADER_PARAM_STRING: + snprintf(_debug_type, sizeof(_debug_type), "string"); + break; + case GS_SHADER_PARAM_INT: + snprintf(_debug_type, sizeof(_debug_type), "int"); + break; + case GS_SHADER_PARAM_INT2: + snprintf(_debug_type, sizeof(_debug_type), "int2"); + break; + case GS_SHADER_PARAM_INT3: + snprintf(_debug_type, sizeof(_debug_type), "int3"); + break; + case GS_SHADER_PARAM_INT4: + snprintf(_debug_type, sizeof(_debug_type), "int4"); + break; + case GS_SHADER_PARAM_FLOAT: + snprintf(_debug_type, sizeof(_debug_type), "float"); + break; + case GS_SHADER_PARAM_VEC2: + snprintf(_debug_type, sizeof(_debug_type), "float2"); + break; + case GS_SHADER_PARAM_VEC3: + snprintf(_debug_type, sizeof(_debug_type), "float3"); + break; + case GS_SHADER_PARAM_VEC4: + snprintf(_debug_type, sizeof(_debug_type), "float4"); + break; + case GS_SHADER_PARAM_MATRIX4X4: + snprintf(_debug_type, sizeof(_debug_type), "float4x4"); + break; + case GS_SHADER_PARAM_BOOL: + snprintf(_debug_type, sizeof(_debug_type), "bool"); + break; + case GS_SHADER_PARAM_UNKNOWN: + snprintf(_debug_type, sizeof(_debug_type), "unknown"); + break; + case GS_SHADER_PARAM_TEXTURE: + snprintf(_debug_type, sizeof(_debug_type), "texture"); + break; + } + + char _debug_buf[4096]; + debug_get_default_value(param, _debug_buf, sizeof(_debug_buf)); + if (param->annotations.num > 0) { + blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s and %lld annotations:", + offset, + idx, + sizeof(_debug_type), _debug_type, + param->name, + sizeof(_debug_buf), _debug_buf, + param->annotations.num); + } else { + blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s.", + offset, + idx, + sizeof(_debug_type), _debug_type, + param->name, + sizeof(_debug_buf), _debug_buf); + } + +} + +static void debug_param_annotation(struct gs_effect_param *param, + struct ep_param *param_in, unsigned long long idx, const char* offset) +{ + char _debug_buf[4096]; + debug_get_default_value(param, _debug_buf, sizeof(_debug_buf)); + blog(LOG_DEBUG, "%s[%4lld] %s '%s' with value %.*s", + offset, + idx, + param_in->type, + param->name, + sizeof(_debug_buf), _debug_buf); +} + +static void debug_print_string(const char* offset, const char* str) +{ + // Bypass 4096 limit in def_log_handler. + char const *begin = str; + unsigned long long line = 1; + for (char const *here = begin; here[0] != '\0'; here++) { + char const * str = begin; + unsigned long long len = here - begin; + bool is_line = false; + + if (here[0] == '\r') { + is_line = true; + if (here[1] == '\n') { + here += 1; + } + begin = here + 1; + } else if (here[0] == '\n') { + is_line = true; + begin = here + 1; + } + + if (is_line) { + blog(LOG_DEBUG, "\t\t\t\t[%4lld] %.*s", line, + len, str); + line++; + } + } + if (begin[0] != '\0') { + // Final line was not written. + blog(LOG_DEBUG, "\t\t\t\t[%4lld] %*s", line, strlen(begin), begin); + } +} +#endif + bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, const char *effect_string, const char *file) { @@ -1020,10 +1474,21 @@ bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, } } +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "================================================================================"); + blog(LOG_DEBUG, "Effect Parser reformatted shader '%s' to:", file); + debug_print_string("\t", ep->cfp.lex.reformatted); +#endif + success = !error_data_has_errors(&ep->cfp.error_list); if (success) success = ep_compile(ep); + +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "================================================================================"); +#endif + return success; } @@ -1309,6 +1774,9 @@ static void ep_makeshaderstring(struct effect_parser *ep, dstr_init(&call_str); + if (!token) + return; + while (token->type != CFTOKEN_NONE && is_whitespace(*token->str.array)) token++; @@ -1339,6 +1807,39 @@ static void ep_makeshaderstring(struct effect_parser *ep, ep_reset_written(ep); } +static void ep_compile_annotations(struct darray *ep_annotations, + struct darray *gsp_annotations, struct effect_parser *ep) +{ + darray_resize(sizeof(struct gs_effect_param), + gsp_annotations, ep_annotations->num); + + size_t i; + for (i = 0; i < ep_annotations->num; i++) { + struct gs_effect_param *param = ((struct gs_effect_param *) + gsp_annotations->array)+i; + struct ep_param *param_in = ((struct ep_param *) + ep_annotations->array)+i; + + param->name = bstrdup(param_in->name); + param->section = EFFECT_ANNOTATION; + param->effect = ep->effect; + da_move(param->default_val, param_in->default_val); + + param->type = get_effect_param_type(param_in->type); + +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + debug_param(param, param_in, i, "\t\t"); +#endif + } +} + +static void ep_compile_param_annotations(struct ep_param *ep_param_input, + struct gs_effect_param *gs_effect_input, struct effect_parser *ep) +{ + ep_compile_annotations(&(ep_param_input->annotations.da), + &(gs_effect_input->annotations.da), ep); +} + static void ep_compile_param(struct effect_parser *ep, size_t idx) { struct gs_effect_param *param; @@ -1353,27 +1854,18 @@ static void ep_compile_param(struct effect_parser *ep, size_t idx) param->effect = ep->effect; da_move(param->default_val, param_in->default_val); - if (strcmp(param_in->type, "bool") == 0) - param->type = GS_SHADER_PARAM_BOOL; - else if (strcmp(param_in->type, "float") == 0) - param->type = GS_SHADER_PARAM_FLOAT; - else if (strcmp(param_in->type, "int") == 0) - param->type = GS_SHADER_PARAM_INT; - else if (strcmp(param_in->type, "float2") == 0) - param->type = GS_SHADER_PARAM_VEC2; - else if (strcmp(param_in->type, "float3") == 0) - param->type = GS_SHADER_PARAM_VEC3; - else if (strcmp(param_in->type, "float4") == 0) - param->type = GS_SHADER_PARAM_VEC4; - else if (strcmp(param_in->type, "float4x4") == 0) - param->type = GS_SHADER_PARAM_MATRIX4X4; - else if (param_in->is_texture) - param->type = GS_SHADER_PARAM_TEXTURE; + param->type = get_effect_param_type(param_in->type); if (strcmp(param_in->name, "ViewProj") == 0) ep->effect->view_proj = param; else if (strcmp(param_in->name, "World") == 0) ep->effect->world = param; + +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + debug_param(param, param_in, idx, "\t"); +#endif + + ep_compile_param_annotations(param_in, param, ep); } static bool ep_compile_pass_shaderparams(struct effect_parser *ep, @@ -1397,6 +1889,10 @@ static bool ep_compile_pass_shaderparams(struct effect_parser *ep, param->sparam = gs_shader_get_param_by_name(shader, param_name->array); +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + debug_param(param->eparam, 0, i, "\t\t\t\t"); +#endif + if (!param->sparam) { blog(LOG_ERROR, "Effect shader parameter not found"); return false; @@ -1441,6 +1937,7 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, pass->vertshader = gs_vertexshader_create(shader_str.array, location.array, NULL); + shader = pass->vertshader; pass_params = &pass->vertshader_params.da; } else if (type == GS_SHADER_PIXEL) { @@ -1454,12 +1951,12 @@ static inline bool ep_compile_pass_shader(struct effect_parser *ep, pass_params = &pass->pixelshader_params.da; } -#if 0 - blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++"); - blog(LOG_DEBUG, " %s", location.array); - blog(LOG_DEBUG, "-----------------------------------"); - blog(LOG_DEBUG, "%s", shader_str.array); - blog(LOG_DEBUG, "+++++++++++++++++++++++++++++++++++"); +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "\t\t\t%s Shader:", + type == GS_SHADER_VERTEX ? "Vertex" : "Fragment"); + blog(LOG_DEBUG, "\t\t\tCode:"); + debug_print_string("\t\t\t\t\t", shader_str.array); + blog(LOG_DEBUG, "\t\t\tParameters:"); #endif if (shader) @@ -1491,14 +1988,23 @@ static bool ep_compile_pass(struct effect_parser *ep, pass->name = bstrdup(pass_in->name); pass->section = EFFECT_PASS; - if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, - GS_SHADER_VERTEX)) - success = false; +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "\t\t[%4lld] Pass '%s':", + idx, pass->name); +#endif if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, - GS_SHADER_PIXEL)) + GS_SHADER_VERTEX)) { success = false; - + blog(LOG_ERROR, "Pass (%zu) <%s> missing vertex shader!", + idx, pass->name ? pass->name : ""); + } + if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, + GS_SHADER_PIXEL)) { + success = false; + blog(LOG_ERROR, "Pass (%zu) <%s> missing pixel shader!", + idx, pass->name ? pass->name : ""); + } return success; } @@ -1518,6 +2024,11 @@ static inline bool ep_compile_technique(struct effect_parser *ep, size_t idx) da_resize(tech->passes, tech_in->passes.num); +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "\t[%4lld] Technique '%s' has %lld passes:", + idx, tech->name, tech->passes.num); +#endif + for (i = 0; i < tech->passes.num; i++) { if (!ep_compile_pass(ep, tech, tech_in, i)) success = false; @@ -1536,8 +2047,17 @@ static bool ep_compile(struct effect_parser *ep) da_resize(ep->effect->params, ep->params.num); da_resize(ep->effect->techniques, ep->techniques.num); +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "Shader has %lld parameters:", ep->params.num); +#endif + for (i = 0; i < ep->params.num; i++) ep_compile_param(ep, i); + +#if defined(_DEBUG) && defined(_DEBUG_SHADERS) + blog(LOG_DEBUG, "Shader has %lld techniques:", ep->techniques.num); +#endif + for (i = 0; i < ep->techniques.num; i++) { if (!ep_compile_technique(ep, i)) success = false; diff --git a/libobs/graphics/effect-parser.h b/libobs/graphics/effect-parser.h index c0eb6f0..1281399 100644 --- a/libobs/graphics/effect-parser.h +++ b/libobs/graphics/effect-parser.h @@ -20,6 +20,7 @@ #include "../util/darray.h" #include "../util/cf-parser.h" #include "graphics.h" +#include "shader-parser.h" #ifdef __cplusplus extern "C" { @@ -72,6 +73,7 @@ struct ep_param { struct gs_effect_param *param; bool is_const, is_property, is_uniform, is_texture, written; int writeorder, array_count; + DARRAY(struct ep_param) annotations; }; extern void ep_param_writevar(struct dstr *dst, struct darray *use_params); @@ -91,6 +93,7 @@ static inline void ep_param_init(struct ep_param *epp, epp->array_count = 0; da_init(epp->default_val); da_init(epp->properties); + da_init(epp->annotations); } static inline void ep_param_free(struct ep_param *epp) @@ -99,6 +102,10 @@ static inline void ep_param_free(struct ep_param *epp) bfree(epp->name); da_free(epp->default_val); da_free(epp->properties); + + for (size_t i = 0; i < epp->annotations.num; i++) + ep_param_free(epp->annotations.array + i); + da_free(epp->annotations); } /* ------------------------------------------------------------------------- */ diff --git a/libobs/graphics/effect.c b/libobs/graphics/effect.c index 4b2a716..ddd5d5a 100644 --- a/libobs/graphics/effect.c +++ b/libobs/graphics/effect.c @@ -286,6 +286,63 @@ gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect, return NULL; } +size_t gs_param_get_num_annotations(const gs_eparam_t *param) +{ + return param ? param->annotations.num : 0; +} + +gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, + size_t annotation) +{ + if (!param) return NULL; + + struct gs_effect_param *params = param->annotations.array; + if (annotation > param->annotations.num) + return NULL; + + return params + annotation; +} + +gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, + const char *name) +{ + if (!param) return NULL; + struct gs_effect_param *params = param->annotations.array; + + for (size_t i = 0; i < param->annotations.num; i++) { + struct gs_effect_param *g_param = params + i; + if (strcmp(g_param->name, name) == 0) + return g_param; + } + return NULL; +} + +gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique, + size_t pass) +{ + if (!technique) return NULL; + struct gs_effect_pass *passes = technique->passes.array; + + if (pass > technique->passes.num) + return NULL; + + return passes + pass; +} + +gs_epass_t *gs_technique_get_pass_by_name(const gs_technique_t *technique, + const char *name) +{ + if (!technique) return NULL; + struct gs_effect_pass *passes = technique->passes.array; + + for (size_t i = 0; i < technique->passes.num; i++) { + struct gs_effect_pass *g_pass = passes + i; + if (strcmp(g_pass->name, name) == 0) + return g_pass; + } + return NULL; +} + gs_eparam_t *gs_effect_get_viewproj_matrix(const gs_effect_t *effect) { return effect ? effect->view_proj : NULL; @@ -332,6 +389,45 @@ static inline void effect_setval_inline(gs_eparam_t *param, } } +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +static inline void effect_getval_inline(gs_eparam_t *param, void *data, + size_t size) +{ + if (!param) { + blog(LOG_ERROR, "effect_getval_inline: invalid param"); + return; + } + + if (!data) { + blog(LOG_ERROR, "effect_getval_inline: invalid data"); + return; + } + + size_t bytes = min(size, param->cur_val.num); + + memcpy(data, param->cur_val.array, bytes); +} + +static inline void effect_getdefaultval_inline(gs_eparam_t *param, void *data, + size_t size) +{ + if (!param) { + blog(LOG_ERROR, "effect_getdefaultval_inline: invalid param"); + return; + } + + if (!data) { + blog(LOG_ERROR, "effect_getdefaultval_inline: invalid data"); + return; + } + + size_t bytes = min(size, param->default_val.num); + + memcpy(data, param->default_val.array, bytes); +} + void gs_effect_set_bool(gs_eparam_t *param, bool val) { int b_val = (int)val; @@ -385,6 +481,54 @@ void gs_effect_set_val(gs_eparam_t *param, const void *val, size_t size) effect_setval_inline(param, val, size); } +void *gs_effect_get_val(gs_eparam_t *param) +{ + if (!param) { + blog(LOG_ERROR, "gs_effect_get_val: invalid param"); + return NULL; + } + size_t size = param->cur_val.num; + void *data; + + if (size) + data = (void*)bzalloc(size); + else + return NULL; + + effect_getval_inline(param, data, size); + + return data; +} + +size_t gs_effect_get_val_size(gs_eparam_t *param) +{ + return param ? param->cur_val.num : 0; +} + +void *gs_effect_get_default_val(gs_eparam_t *param) +{ + if (!param) { + blog(LOG_ERROR, "gs_effect_get_default_val: invalid param"); + return NULL; + } + size_t size = param->default_val.num; + void *data; + + if (size) + data = (void*)bzalloc(size); + else + return NULL; + + effect_getdefaultval_inline(param, data, size); + + return data; +} + +size_t gs_effect_get_default_val_size(gs_eparam_t *param) +{ + return param ? param->default_val.num : 0; +} + void gs_effect_set_default(gs_eparam_t *param) { effect_setval_inline(param, param->default_val.array, diff --git a/libobs/graphics/effect.h b/libobs/graphics/effect.h index d76fb85..9a86868 100644 --- a/libobs/graphics/effect.h +++ b/libobs/graphics/effect.h @@ -41,7 +41,8 @@ enum effect_section { EFFECT_PARAM, EFFECT_TECHNIQUE, EFFECT_SAMPLER, - EFFECT_PASS + EFFECT_PASS, + EFFECT_ANNOTATION }; /* ------------------------------------------------------------------------- */ @@ -61,11 +62,13 @@ struct gs_effect_param { /*char *full_name; float scroller_min, scroller_max, scroller_inc, scroller_mul;*/ + DARRAY(struct gs_effect_param) annotations; }; static inline void effect_param_init(struct gs_effect_param *param) { memset(param, 0, sizeof(struct gs_effect_param)); + da_init(param->annotations); } static inline void effect_param_free(struct gs_effect_param *param) @@ -74,6 +77,12 @@ static inline void effect_param_free(struct gs_effect_param *param) //bfree(param->full_name); da_free(param->cur_val); da_free(param->default_val); + + size_t i; + for (i = 0; i < param->annotations.num; i++) + effect_param_free(param->annotations.array + i); + + da_free(param->annotations); } EXPORT void effect_param_parse_property(gs_eparam_t *param, @@ -106,6 +115,7 @@ static inline void effect_pass_free(struct gs_effect_pass *pass) bfree(pass->name); da_free(pass->vertshader_params); da_free(pass->pixelshader_params); + gs_shader_destroy(pass->vertshader); gs_shader_destroy(pass->pixelshader); } @@ -130,6 +140,7 @@ static inline void effect_technique_free(struct gs_effect_technique *t) size_t i; for (i = 0; i < t->passes.num; i++) effect_pass_free(t->passes.array+i); + da_free(t->passes); bfree(t->name); } diff --git a/libobs/graphics/graphics-imports.c b/libobs/graphics/graphics-imports.c index 63c19ab..31ef4ab 100644 --- a/libobs/graphics/graphics-imports.c +++ b/libobs/graphics/graphics-imports.c @@ -171,6 +171,11 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT(gs_shader_set_default); GRAPHICS_IMPORT(gs_shader_set_next_sampler); + GRAPHICS_IMPORT_OPTIONAL(device_nv12_available); + + GRAPHICS_IMPORT(device_debug_marker_begin); + GRAPHICS_IMPORT(device_debug_marker_end); + /* OSX/Cocoa specific functions */ #ifdef __APPLE__ GRAPHICS_IMPORT_OPTIONAL(device_texture_create_from_iosurface); @@ -189,6 +194,11 @@ bool load_graphics_imports(struct gs_exports *exports, void *module, GRAPHICS_IMPORT_OPTIONAL(gs_texture_get_dc); GRAPHICS_IMPORT_OPTIONAL(gs_texture_release_dc); GRAPHICS_IMPORT_OPTIONAL(device_texture_open_shared); + GRAPHICS_IMPORT_OPTIONAL(device_texture_get_shared_handle); + GRAPHICS_IMPORT_OPTIONAL(device_texture_acquire_sync); + GRAPHICS_IMPORT_OPTIONAL(device_texture_release_sync); + GRAPHICS_IMPORT_OPTIONAL(device_texture_create_nv12); + GRAPHICS_IMPORT_OPTIONAL(device_stagesurface_create_nv12); #endif return success; diff --git a/libobs/graphics/graphics-internal.h b/libobs/graphics/graphics-internal.h index 6be06d5..2c55484 100644 --- a/libobs/graphics/graphics-internal.h +++ b/libobs/graphics/graphics-internal.h @@ -232,6 +232,12 @@ struct gs_exports { void (*gs_shader_set_next_sampler)(gs_sparam_t *param, gs_samplerstate_t *sampler); + bool (*device_nv12_available)(gs_device_t *device); + + void (*device_debug_marker_begin)(gs_device_t *device, + const char *markername, const float color[4]); + void (*device_debug_marker_end)(gs_device_t *device); + #ifdef __APPLE__ /* OSX/Cocoa specific functions */ gs_texture_t *(*device_texture_create_from_iosurface)(gs_device_t *dev, @@ -261,6 +267,16 @@ struct gs_exports { gs_texture_t *(*device_texture_open_shared)(gs_device_t *device, uint32_t handle); + uint32_t (*device_texture_get_shared_handle)(gs_texture_t *tex); + int (*device_texture_acquire_sync)(gs_texture_t *tex, uint64_t key, + uint32_t ms); + int (*device_texture_release_sync)(gs_texture_t *tex, uint64_t key); + bool (*device_texture_create_nv12)(gs_device_t *device, + gs_texture_t **tex_y, gs_texture_t **tex_uv, + uint32_t width, uint32_t height, uint32_t flags); + + gs_stagesurf_t *(*device_stagesurface_create_nv12)(gs_device_t *device, + uint32_t width, uint32_t height); #endif }; diff --git a/libobs/graphics/graphics.c b/libobs/graphics/graphics.c index b6f5bd0..671d925 100644 --- a/libobs/graphics/graphics.c +++ b/libobs/graphics/graphics.c @@ -160,12 +160,12 @@ static bool graphics_init(struct graphics_subsystem *graphics) graphics->exports.device_blend_function_separate(graphics->device, GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, - GS_BLEND_ONE, GS_BLEND_ONE); + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); graphics->cur_blend_state.enabled = true; graphics->cur_blend_state.src_c = GS_BLEND_SRCALPHA; graphics->cur_blend_state.dest_c = GS_BLEND_INVSRCALPHA; graphics->cur_blend_state.src_a = GS_BLEND_ONE; - graphics->cur_blend_state.dest_a = GS_BLEND_ONE; + graphics->cur_blend_state.dest_a = GS_BLEND_INVSRCALPHA; graphics->exports.device_leave_context(graphics->device); @@ -1240,10 +1240,10 @@ void gs_reset_blend_state(void) if (graphics->cur_blend_state.src_c != GS_BLEND_SRCALPHA || graphics->cur_blend_state.dest_c != GS_BLEND_INVSRCALPHA || graphics->cur_blend_state.src_a != GS_BLEND_ONE || - graphics->cur_blend_state.dest_a != GS_BLEND_ONE) + graphics->cur_blend_state.dest_a != GS_BLEND_INVSRCALPHA) gs_blend_function_separate( GS_BLEND_SRCALPHA, GS_BLEND_INVSRCALPHA, - GS_BLEND_ONE, GS_BLEND_ONE); + GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); } /* ------------------------------------------------------------------------- */ @@ -1517,9 +1517,7 @@ gs_indexbuffer_t *gs_indexbuffer_create(enum gs_index_type type, return NULL; if (indices && num && (flags & GS_DUP_BUFFER) != 0) { - size_t size = type == GS_UNSIGNED_SHORT - ? sizeof(unsigned short) - : sizeof(unsigned long); + size_t size = type == GS_UNSIGNED_SHORT ? 2 : 4; indices = bmemdup(indices, size * num); } @@ -2545,6 +2543,61 @@ enum gs_index_type gs_indexbuffer_get_type(const gs_indexbuffer_t *indexbuffer) return thread_graphics->exports.gs_indexbuffer_get_type(indexbuffer); } +bool gs_nv12_available(void) +{ + if (!gs_valid("gs_nv12_available")) + return false; + + if (!thread_graphics->exports.device_nv12_available) + return false; + + return thread_graphics->exports.device_nv12_available( + thread_graphics->device); +} + +void gs_debug_marker_begin(const float color[4], + const char *markername) +{ + if (!gs_valid("gs_debug_marker_begin")) + return; + + if (!markername) + markername = "(null)"; + + thread_graphics->exports.device_debug_marker_begin( + thread_graphics->device, markername, + color); +} + +void gs_debug_marker_begin_format(const float color[4], + const char *format, ...) +{ + if (!gs_valid("gs_debug_marker_begin")) + return; + + if (format) { + char markername[64]; + va_list args; + va_start(args, format); + vsnprintf(markername, sizeof(markername), format, args); + va_end(args); + thread_graphics->exports.device_debug_marker_begin( + thread_graphics->device, markername, + color); + } else { + gs_debug_marker_begin(color, NULL); + } +} + +void gs_debug_marker_end(void) +{ + if (!gs_valid("gs_debug_marker_end")) + return; + + thread_graphics->exports.device_debug_marker_end( + thread_graphics->device); +} + #ifdef __APPLE__ /** Platform specific functions */ @@ -2692,4 +2745,98 @@ gs_texture_t *gs_texture_open_shared(uint32_t handle) return NULL; } +uint32_t gs_texture_get_shared_handle(gs_texture_t *tex) +{ + graphics_t *graphics = thread_graphics; + if (!gs_valid("gs_texture_get_shared_handle")) + return GS_INVALID_HANDLE; + + if (graphics->exports.device_texture_get_shared_handle) + return graphics->exports.device_texture_get_shared_handle(tex); + return GS_INVALID_HANDLE; +} + +int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms) +{ + graphics_t *graphics = thread_graphics; + if (!gs_valid("gs_texture_acquire_sync")) + return -1; + + if (graphics->exports.device_texture_acquire_sync) + return graphics->exports.device_texture_acquire_sync(tex, + key, ms); + return -1; +} + +int gs_texture_release_sync(gs_texture_t *tex, uint64_t key) +{ + graphics_t *graphics = thread_graphics; + if (!gs_valid("gs_texture_release_sync")) + return -1; + + if (graphics->exports.device_texture_release_sync) + return graphics->exports.device_texture_release_sync(tex, key); + return -1; +} + +bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv, + uint32_t width, uint32_t height, uint32_t flags) +{ + graphics_t *graphics = thread_graphics; + bool success = false; + + if (!gs_valid("gs_texture_create_nv12")) + return false; + + if ((width & 1) == 1 || (height & 1) == 1) { + blog(LOG_ERROR, "NV12 textures must have dimensions " + "divisible by 2."); + return false; + } + + if (graphics->exports.device_texture_create_nv12) { + success = graphics->exports.device_texture_create_nv12( + graphics->device, tex_y, tex_uv, + width, height, flags); + if (success) + return true; + } + + *tex_y = gs_texture_create(width, height, GS_R8, 1, NULL, flags); + *tex_uv = gs_texture_create(width / 2, height / 2, GS_R8G8, 1, NULL, + flags); + + if (!*tex_y || !*tex_uv) { + if (*tex_y) + gs_texture_destroy(*tex_y); + if (*tex_uv) + gs_texture_destroy(*tex_uv); + *tex_y = NULL; + *tex_uv = NULL; + return false; + } + + return true; +} + +gs_stagesurf_t *gs_stagesurface_create_nv12(uint32_t width, uint32_t height) +{ + graphics_t *graphics = thread_graphics; + + if (!gs_valid("gs_stagesurface_create_nv12")) + return NULL; + + if ((width & 1) == 1 || (height & 1) == 1) { + blog(LOG_ERROR, "NV12 textures must have dimensions " + "divisible by 2."); + return NULL; + } + + if (graphics->exports.device_stagesurface_create_nv12) + return graphics->exports.device_stagesurface_create_nv12( + graphics->device, width, height); + + return NULL; +} + #endif diff --git a/libobs/graphics/graphics.h b/libobs/graphics/graphics.h index df9583f..a3f6de8 100644 --- a/libobs/graphics/graphics.h +++ b/libobs/graphics/graphics.h @@ -71,7 +71,8 @@ enum gs_color_format { GS_R32F, GS_DXT1, GS_DXT3, - GS_DXT5 + GS_DXT5, + GS_R8G8, }; enum gs_zstencil_format { @@ -267,6 +268,7 @@ typedef struct gs_shader gs_shader_t; typedef struct gs_shader_param gs_sparam_t; typedef struct gs_effect gs_effect_t; typedef struct gs_effect_technique gs_technique_t; +typedef struct gs_effect_pass gs_epass_t; typedef struct gs_effect_param gs_eparam_t; typedef struct gs_device gs_device_t; typedef struct graphics_subsystem graphics_t; @@ -368,12 +370,21 @@ EXPORT bool gs_technique_begin_pass(gs_technique_t *technique, size_t pass); EXPORT bool gs_technique_begin_pass_by_name(gs_technique_t *technique, const char *name); EXPORT void gs_technique_end_pass(gs_technique_t *technique); +EXPORT gs_epass_t *gs_technique_get_pass_by_idx(const gs_technique_t *technique, + size_t pass); +EXPORT gs_epass_t *gs_technique_get_pass_by_name( + const gs_technique_t *technique, const char *name); EXPORT size_t gs_effect_get_num_params(const gs_effect_t *effect); EXPORT gs_eparam_t *gs_effect_get_param_by_idx(const gs_effect_t *effect, size_t param); EXPORT gs_eparam_t *gs_effect_get_param_by_name(const gs_effect_t *effect, const char *name); +EXPORT size_t gs_param_get_num_annotations(const gs_eparam_t *param); +EXPORT gs_eparam_t *gs_param_get_annotation_by_idx(const gs_eparam_t *param, + size_t annotation); +EXPORT gs_eparam_t *gs_param_get_annotation_by_name(const gs_eparam_t *param, + const char *name); /** Helper function to simplify effect usage. Use with a while loop that * contains drawing functions. Automatically handles techniques, passes, and @@ -402,6 +413,10 @@ EXPORT void gs_effect_set_vec4(gs_eparam_t *param, const struct vec4 *val); EXPORT void gs_effect_set_texture(gs_eparam_t *param, gs_texture_t *val); EXPORT void gs_effect_set_val(gs_eparam_t *param, const void *val, size_t size); EXPORT void gs_effect_set_default(gs_eparam_t *param); +EXPORT size_t gs_effect_get_val_size(gs_eparam_t *param); +EXPORT void *gs_effect_get_val(gs_eparam_t *param); +EXPORT size_t gs_effect_get_default_val_size(gs_eparam_t *param); +EXPORT void *gs_effect_get_default_val(gs_eparam_t *param); EXPORT void gs_effect_set_next_sampler(gs_eparam_t *param, gs_samplerstate_t *sampler); @@ -430,6 +445,8 @@ EXPORT gs_texture_t *gs_texrender_get_texture(const gs_texrender_t *texrender); #define GS_GL_DUMMYTEX (1<<3) /**<< texture with no allocated texture data */ #define GS_DUP_BUFFER (1<<4) /**<< do not pass buffer ownership when * creating a vertex/index buffer */ +#define GS_SHARED_TEX (1<<5) +#define GS_SHARED_KM_TEX (1<<6) /* ---------------- */ /* global functions */ @@ -742,6 +759,36 @@ EXPORT size_t gs_indexbuffer_get_num_indices( EXPORT enum gs_index_type gs_indexbuffer_get_type( const gs_indexbuffer_t *indexbuffer); +EXPORT bool gs_nv12_available(void); + +#define GS_USE_DEBUG_MARKERS 0 +#if GS_USE_DEBUG_MARKERS +static const float GS_DEBUG_COLOR_DEFAULT[] = { 0.5f, 0.5f, 0.5f, 1.0f }; +static const float GS_DEBUG_COLOR_RENDER_VIDEO[] = { 0.0f, 0.5f, 0.0f, 1.0f }; +static const float GS_DEBUG_COLOR_MAIN_TEXTURE[] = { 0.0f, 0.25f, 0.0f, 1.0f }; +static const float GS_DEBUG_COLOR_DISPLAY[] = { 0.0f, 0.5f, 0.5f, 1.0f }; +static const float GS_DEBUG_COLOR_SOURCE[] = { 0.0f, 0.5f, 5.0f, 1.0f }; +static const float GS_DEBUG_COLOR_ITEM[] = { 0.5f, 0.0f, 0.0f, 1.0f }; +static const float GS_DEBUG_COLOR_ITEM_TEXTURE[] = { 0.25f, 0.0f, 0.0f, 1.0f }; +static const float GS_DEBUG_COLOR_CONVERT_FORMAT[] = { 0.5f, 0.5f, 0.0f, 1.0f }; +#define GS_DEBUG_MARKER_BEGIN(color, markername) \ + gs_debug_marker_begin(color, markername) +#define GS_DEBUG_MARKER_BEGIN_FORMAT(color, format, ...) \ + gs_debug_marker_begin_format(color, format, \ + __VA_ARGS__) +#define GS_DEBUG_MARKER_END() gs_debug_marker_end() +#else +#define GS_DEBUG_MARKER_BEGIN(color, markername) ((void)0) +#define GS_DEBUG_MARKER_BEGIN_FORMAT(color, format, ...) ((void)0) +#define GS_DEBUG_MARKER_END() ((void)0) +#endif + +EXPORT void gs_debug_marker_begin(const float color[4], + const char *markername); +EXPORT void gs_debug_marker_begin_format(const float color[4], + const char *format, ...); +EXPORT void gs_debug_marker_end(void); + #ifdef __APPLE__ /** platform specific function for creating (GL_TEXTURE_RECTANGLE) textures @@ -780,6 +827,30 @@ EXPORT void gs_texture_release_dc(gs_texture_t *gdi_tex); /** creates a windows shared texture from a texture handle */ EXPORT gs_texture_t *gs_texture_open_shared(uint32_t handle); + +#define GS_INVALID_HANDLE (uint32_t)-1 +EXPORT uint32_t gs_texture_get_shared_handle(gs_texture_t *tex); + +#define GS_WAIT_INFINITE (uint32_t)-1 + +/** + * acquires a lock on a keyed mutex texture. + * returns -1 on generic failure, ETIMEDOUT if timed out + */ +EXPORT int gs_texture_acquire_sync(gs_texture_t *tex, uint64_t key, uint32_t ms); + +/** + * releases a lock on a keyed mutex texture to another device. + * return 0 on success, -1 on error + */ +EXPORT int gs_texture_release_sync(gs_texture_t *tex, uint64_t key); + +EXPORT bool gs_texture_create_nv12(gs_texture_t **tex_y, gs_texture_t **tex_uv, + uint32_t width, uint32_t height, uint32_t flags); + +EXPORT gs_stagesurf_t *gs_stagesurface_create_nv12( + uint32_t width, uint32_t height); + #endif /* inline functions used by modules */ @@ -804,6 +875,7 @@ static inline uint32_t gs_get_format_bpp(enum gs_color_format format) case GS_DXT1: return 4; case GS_DXT3: return 8; case GS_DXT5: return 8; + case GS_R8G8: return 16; case GS_UNKNOWN: return 0; } diff --git a/libobs/graphics/image-file.c b/libobs/graphics/image-file.c index 4262c0b..402014f 100644 --- a/libobs/graphics/image-file.c +++ b/libobs/graphics/image-file.c @@ -59,7 +59,18 @@ static inline int get_full_decoded_gif_size(gs_image_file_t *image) return image->gif.width * image->gif.height * 4 * image->gif.frame_count; } -static bool init_animated_gif(gs_image_file_t *image, const char *path) +static inline void *alloc_mem(gs_image_file_t *image, uint64_t *mem_usage, + size_t size) +{ + UNUSED_PARAMETER(image); + + if (mem_usage) + *mem_usage += size; + return bzalloc(size); +} + +static bool init_animated_gif(gs_image_file_t *image, const char *path, + uint64_t *mem_usage) { bool is_animated_gif = true; gif_result result; @@ -121,9 +132,9 @@ static bool init_animated_gif(gs_image_file_t *image, const char *path) if (image->is_animated_gif) { gif_decode_frame(&image->gif, 0); - image->animation_frame_cache = bzalloc( + image->animation_frame_cache = alloc_mem(image, mem_usage, image->gif.frame_count * sizeof(uint8_t*)); - image->animation_frame_data = bzalloc( + image->animation_frame_data = alloc_mem(image, mem_usage, get_full_decoded_gif_size(image)); for (unsigned int i = 0; i < image->gif.frame_count; i++) { @@ -137,6 +148,11 @@ static bool init_animated_gif(gs_image_file_t *image, const char *path) image->cx = (uint32_t)image->gif.width; image->cy = (uint32_t)image->gif.height; image->format = GS_RGBA; + + if (mem_usage) { + *mem_usage += image->cx * image->cy * 4; + *mem_usage += size; + } } else { gif_finalise(&image->gif); bfree(image->gif_data); @@ -157,7 +173,8 @@ not_animated: return is_animated_gif; } -void gs_image_file_init(gs_image_file_t *image, const char *file) +static void gs_image_file_init_internal(gs_image_file_t *image, + const char *file, uint64_t *mem_usage) { size_t len; @@ -172,13 +189,18 @@ void gs_image_file_init(gs_image_file_t *image, const char *file) len = strlen(file); if (len > 4 && strcmp(file + len - 4, ".gif") == 0) { - if (init_animated_gif(image, file)) + if (init_animated_gif(image, file, mem_usage)) return; } image->texture_data = gs_create_texture_file_data(file, &image->format, &image->cx, &image->cy); + if (mem_usage) { + *mem_usage += image->cx * image->cy * + gs_get_format_bpp(image->format) / 8; + } + image->loaded = !!image->texture_data; if (!image->loaded) { blog(LOG_WARNING, "Failed to load file '%s'", file); @@ -186,6 +208,11 @@ void gs_image_file_init(gs_image_file_t *image, const char *file) } } +void gs_image_file_init(gs_image_file_t *image, const char *file) +{ + gs_image_file_init_internal(image, file, NULL); +} + void gs_image_file_free(gs_image_file_t *image) { if (!image) @@ -206,6 +233,11 @@ void gs_image_file_free(gs_image_file_t *image) memset(image, 0, sizeof(*image)); } +void gs_image_file2_init(gs_image_file2_t *if2, const char *file) +{ + gs_image_file_init_internal(&if2->image, file, &if2->mem_usage); +} + void gs_image_file_init_texture(gs_image_file_t *image) { if (!image->loaded) diff --git a/libobs/graphics/image-file.h b/libobs/graphics/image-file.h index 3720352..74e944e 100644 --- a/libobs/graphics/image-file.h +++ b/libobs/graphics/image-file.h @@ -20,6 +20,10 @@ #include "graphics.h" #include "libnsgif/libnsgif.h" +#ifdef __cplusplus +extern "C" { +#endif + struct gs_image_file { gs_texture_t *texture; enum gs_color_format format; @@ -42,7 +46,13 @@ struct gs_image_file { gif_bitmap_callback_vt bitmap_callbacks; }; +struct gs_image_file2 { + struct gs_image_file image; + uint64_t mem_usage; +}; + typedef struct gs_image_file gs_image_file_t; +typedef struct gs_image_file2 gs_image_file2_t; EXPORT void gs_image_file_init(gs_image_file_t *image, const char *file); EXPORT void gs_image_file_free(gs_image_file_t *image); @@ -51,3 +61,31 @@ EXPORT void gs_image_file_init_texture(gs_image_file_t *image); EXPORT bool gs_image_file_tick(gs_image_file_t *image, uint64_t elapsed_time_ns); EXPORT void gs_image_file_update_texture(gs_image_file_t *image); + +EXPORT void gs_image_file2_init(gs_image_file2_t *if2, const char *file); + +static void gs_image_file2_free(gs_image_file2_t *if2) +{ + gs_image_file_free(&if2->image); + if2->mem_usage = 0; +} + +static inline void gs_image_file2_init_texture(gs_image_file2_t *if2) +{ + gs_image_file_init_texture(&if2->image); +} + +static inline bool gs_image_file2_tick(gs_image_file2_t *if2, + uint64_t elapsed_time_ns) +{ + return gs_image_file_tick(&if2->image, elapsed_time_ns); +} + +static inline void gs_image_file2_update_texture(gs_image_file2_t *if2) +{ + gs_image_file_update_texture(&if2->image); +} + +#ifdef __cplusplus +} +#endif diff --git a/libobs/graphics/shader-parser.c b/libobs/graphics/shader-parser.c index 5464101..a9b354e 100644 --- a/libobs/graphics/shader-parser.c +++ b/libobs/graphics/shader-parser.c @@ -104,6 +104,8 @@ void shader_sampler_convert(struct shader_sampler *ss, size_t i; memset(info, 0, sizeof(struct gs_sampler_info)); + info->max_anisotropy = 1; + for (i = 0; i < ss->states.num; i++) { const char *state = ss->states.array[i]; const char *value = ss->values.array[i]; diff --git a/libobs/libobs.pc.in b/libobs/libobs.pc.in new file mode 100644 index 0000000..03fe4cd --- /dev/null +++ b/libobs/libobs.pc.in @@ -0,0 +1,11 @@ +prefix=@DEST_DIR@ +exec_prefix=${prefix} +libdir=${prefix}/@OBS_LIBRARY_DESTINATION@ +includedir=${prefix}/include + +Name: libobs +Description: OBS Studio Library +Version: @OBS_VERSION@ +Requires: x11 +Cflags: -I${includedir} +Libs: -L${libdir} @PRIVATE_LIBS@ diff --git a/libobs/media-io/audio-resampler-ffmpeg.c b/libobs/media-io/audio-resampler-ffmpeg.c index 7680125..e731e7e 100644 --- a/libobs/media-io/audio-resampler-ffmpeg.c +++ b/libobs/media-io/audio-resampler-ffmpeg.c @@ -102,6 +102,21 @@ audio_resampler_t *audio_resampler_create(const struct resample_info *dst, return NULL; } + if (rs->input_layout == AV_CH_LAYOUT_MONO && rs->output_ch > 1) { + const double matrix[MAX_AUDIO_CHANNELS][MAX_AUDIO_CHANNELS] = { + {1}, + {1, 1}, + {1, 1, 0}, + {1, 1, 1, 1}, + {1, 1, 1, 0, 1}, + {1, 1, 1, 1, 1, 1}, + {1, 1, 1, 0, 1, 1, 1}, + {1, 1, 1, 0, 1, 1, 1, 1}, + }; + if (swr_set_matrix(rs->context, matrix[rs->output_ch - 1], 1) < 0) + blog(LOG_DEBUG, "swr_set_matrix failed for mono upmix\n"); + } + errcode = swr_init(rs->context); if (errcode != 0) { blog(LOG_ERROR, "avresample_open failed: error code %d", diff --git a/libobs/media-io/video-io.c b/libobs/media-io/video-io.c index f490ceb..43227b7 100644 --- a/libobs/media-io/video-io.c +++ b/libobs/media-io/video-io.c @@ -65,8 +65,8 @@ struct video_output { os_sem_t *update_semaphore; uint64_t frame_time; - uint32_t skipped_frames; - uint32_t total_frames; + volatile long skipped_frames; + volatile long total_frames; bool initialized; @@ -77,6 +77,9 @@ struct video_output { size_t first_added; size_t last_added; struct cached_frame_info cache[MAX_CACHE_SIZE]; + + volatile bool raw_active; + volatile long gpu_refs; }; /* ------------------------------------------------------------------------- */ @@ -156,7 +159,7 @@ static inline bool video_output_cur_frame(struct video_output *video) video->last_added = video->first_added; } else if (skipped) { --frame_info->skipped; - ++video->skipped_frames; + os_atomic_inc_long(&video->skipped_frames); } pthread_mutex_unlock(&video->data_mutex); @@ -182,10 +185,10 @@ static void *video_thread(void *param) profile_start(video_thread_name); while (!video->stop && !video_output_cur_frame(video)) { - video->total_frames++; + os_atomic_inc_long(&video->total_frames); } - video->total_frames++; + os_atomic_inc_long(&video->total_frames); profile_end(video_thread_name); profile_reenable_thread(); @@ -330,6 +333,12 @@ static inline bool video_input_init(struct video_input *input, return true; } +static inline void reset_frames(video_t *video) +{ + os_atomic_set_long(&video->skipped_frames, 0); + os_atomic_set_long(&video->total_frames, 0); +} + bool video_output_connect(video_t *video, const struct video_scale_info *conversion, void (*callback)(void *param, struct video_data *frame), @@ -342,11 +351,6 @@ bool video_output_connect(video_t *video, pthread_mutex_lock(&video->input_mutex); - if (video->inputs.num == 0) { - video->skipped_frames = 0; - video->total_frames = 0; - } - if (video_get_input_idx(video, callback, param) == DARRAY_INVALID) { struct video_input input; memset(&input, 0, sizeof(input)); @@ -368,8 +372,15 @@ bool video_output_connect(video_t *video, input.conversion.height = video->info.height; success = video_input_init(&input, video); - if (success) + if (success) { + if (video->inputs.num == 0) { + if (!os_atomic_load_long(&video->gpu_refs)) { + reset_frames(video); + } + os_atomic_set_bool(&video->raw_active, true); + } da_push_back(video->inputs, &input); + } } pthread_mutex_unlock(&video->input_mutex); @@ -377,6 +388,24 @@ bool video_output_connect(video_t *video, return success; } +static void log_skipped(video_t *video) +{ + long skipped = os_atomic_load_long(&video->skipped_frames); + double percentage_skipped = + (double)skipped / + (double)os_atomic_load_long(&video->total_frames) * + 100.0; + + if (skipped) + blog(LOG_INFO, "Video stopped, number of " + "skipped frames due " + "to encoding lag: " + "%ld/%ld (%0.1f%%)", + video->skipped_frames, + video->total_frames, + percentage_skipped); +} + void video_output_disconnect(video_t *video, void (*callback)(void *param, struct video_data *frame), void *param) @@ -390,20 +419,13 @@ void video_output_disconnect(video_t *video, if (idx != DARRAY_INVALID) { video_input_free(video->inputs.array+idx); da_erase(video->inputs, idx); - } - if (video->inputs.num == 0) { - double percentage_skipped = (double)video->skipped_frames / - (double)video->total_frames * 100.0; - - if (video->skipped_frames) - blog(LOG_INFO, "Video stopped, number of " - "skipped frames due " - "to encoding lag: " - "%"PRIu32"/%"PRIu32" (%0.1f%%)", - video->skipped_frames, - video->total_frames, - percentage_skipped); + if (video->inputs.num == 0) { + os_atomic_set_bool(&video->raw_active, false); + if (!os_atomic_load_long(&video->gpu_refs)) { + log_skipped(video); + } + } } pthread_mutex_unlock(&video->input_mutex); @@ -412,7 +434,7 @@ void video_output_disconnect(video_t *video, bool video_output_active(const video_t *video) { if (!video) return false; - return video->inputs.num != 0; + return os_atomic_load_bool(&video->raw_active); } const struct video_output_info *video_output_get_info(const video_t *video) @@ -521,10 +543,42 @@ double video_output_get_frame_rate(const video_t *video) uint32_t video_output_get_skipped_frames(const video_t *video) { - return video->skipped_frames; + return (uint32_t)os_atomic_load_long(&video->skipped_frames); } uint32_t video_output_get_total_frames(const video_t *video) { - return video->total_frames; + return (uint32_t)os_atomic_load_long(&video->total_frames); +} + +/* Note: These four functions below are a very slight bit of a hack. If the + * texture encoder thread is active while the raw encoder thread is active, the + * total frame count will just be doubled while they're both active. Which is + * fine. What's more important is having a relatively accurate skipped frame + * count. */ + +void video_output_inc_texture_encoders(video_t *video) +{ + if (os_atomic_inc_long(&video->gpu_refs) == 1 && + !os_atomic_load_bool(&video->raw_active)) { + reset_frames(video); + } +} + +void video_output_dec_texture_encoders(video_t *video) +{ + if (os_atomic_dec_long(&video->gpu_refs) == 0 && + !os_atomic_load_bool(&video->raw_active)) { + log_skipped(video); + } +} + +void video_output_inc_texture_frames(video_t *video) +{ + os_atomic_inc_long(&video->total_frames); +} + +void video_output_inc_texture_skipped_frames(video_t *video) +{ + os_atomic_inc_long(&video->skipped_frames); } diff --git a/libobs/media-io/video-io.h b/libobs/media-io/video-io.h index 03ea20b..77acf8f 100644 --- a/libobs/media-io/video-io.h +++ b/libobs/media-io/video-io.h @@ -135,15 +135,23 @@ static inline const char *get_video_colorspace_name(enum video_colorspace cs) return "601"; } -static inline const char *get_video_range_name(enum video_range_type range) +static inline enum video_range_type resolve_video_range( + enum video_format format, enum video_range_type range) { - switch (range) { - case VIDEO_RANGE_FULL: return "Full"; - case VIDEO_RANGE_PARTIAL: - case VIDEO_RANGE_DEFAULT:; + if (range == VIDEO_RANGE_DEFAULT) { + range = format_is_yuv(format) + ? VIDEO_RANGE_PARTIAL + : VIDEO_RANGE_FULL; } - return "Partial"; + return range; +} + +static inline const char *get_video_range_name(enum video_format format, + enum video_range_type range) +{ + range = resolve_video_range(format, range); + return range == VIDEO_RANGE_FULL ? "Full" : "Partial"; } enum video_scale_type { @@ -202,6 +210,11 @@ EXPORT double video_output_get_frame_rate(const video_t *video); EXPORT uint32_t video_output_get_skipped_frames(const video_t *video); EXPORT uint32_t video_output_get_total_frames(const video_t *video); +extern void video_output_inc_texture_encoders(video_t *video); +extern void video_output_dec_texture_encoders(video_t *video); +extern void video_output_inc_texture_frames(video_t *video); +extern void video_output_inc_texture_skipped_frames(video_t *video); + #ifdef __cplusplus } diff --git a/libobs/obs-audio-controls.c b/libobs/obs-audio-controls.c index 0de00c7..2808165 100644 --- a/libobs/obs-audio-controls.c +++ b/libobs/obs-audio-controls.c @@ -932,3 +932,12 @@ void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, pthread_mutex_unlock(&volmeter->callback_mutex); } +float obs_mul_to_db(float mul) +{ + return mul_to_db(mul); +} + +float obs_db_to_mul(float db) +{ + return db_to_mul(db); +} diff --git a/libobs/obs-audio-controls.h b/libobs/obs-audio-controls.h index 384d618..c16b32b 100644 --- a/libobs/obs-audio-controls.h +++ b/libobs/obs-audio-controls.h @@ -273,6 +273,9 @@ EXPORT void obs_volmeter_add_callback(obs_volmeter_t *volmeter, EXPORT void obs_volmeter_remove_callback(obs_volmeter_t *volmeter, obs_volmeter_updated_t callback, void *param); +EXPORT float obs_mul_to_db(float mul); +EXPORT float obs_db_to_mul(float db); + #ifdef __cplusplus } #endif diff --git a/libobs/obs-audio.c b/libobs/obs-audio.c index d644ea7..7bbcc20 100644 --- a/libobs/obs-audio.c +++ b/libobs/obs-audio.c @@ -31,8 +31,8 @@ static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p) struct obs_core_audio *audio = p; if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) { - obs_source_addref(source); - da_push_back(audio->render_order, &source); + obs_source_t *s = obs_source_get_ref(source); + if (s) da_push_back(audio->render_order, &s); } UNUSED_PARAMETER(parent); @@ -227,7 +227,8 @@ static inline void discard_audio(struct obs_core_audio *audio, } static void add_audio_buffering(struct obs_core_audio *audio, - size_t sample_rate, struct ts_info *ts, uint64_t min_ts) + size_t sample_rate, struct ts_info *ts, uint64_t min_ts, + const char *buffering_name) { struct ts_info new_ts; uint64_t offset; @@ -259,8 +260,9 @@ static void add_audio_buffering(struct obs_core_audio *audio, sample_rate; blog(LOG_INFO, "adding %d milliseconds of audio buffering, total " - "audio buffering is now %d milliseconds", - (int)ms, (int)total_ms); + "audio buffering is now %d milliseconds" + " (source: %s)\n", + (int)ms, (int)total_ms, buffering_name); #if DEBUG_AUDIO == 1 blog(LOG_DEBUG, "min_ts (%"PRIu64") < start timestamp " "(%"PRIu64")", min_ts, ts->start); @@ -322,17 +324,21 @@ static bool audio_buffer_insuffient(struct obs_source *source, return false; } -static inline void find_min_ts(struct obs_core_data *data, +static inline const char *find_min_ts(struct obs_core_data *data, uint64_t *min_ts) { + obs_source_t *buffering_source = NULL; struct obs_source *source = data->first_audio_source; while (source) { if (!source->audio_pending && source->audio_ts && - source->audio_ts < *min_ts) + source->audio_ts < *min_ts) { *min_ts = source->audio_ts; + buffering_source = source; + } source = (struct obs_source*)source->next_audio_source; } + return buffering_source ? obs_source_get_name(buffering_source) : NULL; } static inline bool mark_invalid_sources(struct obs_core_data *data, @@ -350,12 +356,13 @@ static inline bool mark_invalid_sources(struct obs_core_data *data, return recalculate; } -static inline void calc_min_ts(struct obs_core_data *data, +static inline const char *calc_min_ts(struct obs_core_data *data, size_t sample_rate, uint64_t *min_ts) { - find_min_ts(data, min_ts); + const char *buffering_name = find_min_ts(data, min_ts); if (mark_invalid_sources(data, sample_rate, *min_ts)) - find_min_ts(data, min_ts); + buffering_name = find_min_ts(data, min_ts); + return buffering_name; } static inline void release_audio_sources(struct obs_core_audio *audio) @@ -425,13 +432,14 @@ bool audio_callback(void *param, /* ------------------------------------------------ */ /* get minimum audio timestamp */ pthread_mutex_lock(&data->audio_sources_mutex); - calc_min_ts(data, sample_rate, &min_ts); + const char *buffering_name = calc_min_ts(data, sample_rate, &min_ts); pthread_mutex_unlock(&data->audio_sources_mutex); /* ------------------------------------------------ */ /* if a source has gone backward in time, buffer */ if (min_ts < ts.start) - add_audio_buffering(audio, sample_rate, &ts, min_ts); + add_audio_buffering(audio, sample_rate, &ts, min_ts, + buffering_name); /* ------------------------------------------------ */ /* mix audio */ diff --git a/libobs/obs-config.h b/libobs/obs-config.h index b6d8dc8..c233ff0 100644 --- a/libobs/obs-config.h +++ b/libobs/obs-config.h @@ -27,21 +27,21 @@ /* * Increment if major breaking API changes */ -#define LIBOBS_API_MAJOR_VER 22 +#define LIBOBS_API_MAJOR_VER 23 /* * Increment if backward-compatible additions * * Reset to zero each major version */ -#define LIBOBS_API_MINOR_VER 0 +#define LIBOBS_API_MINOR_VER 2 /* * Increment if backward-compatible bug fix * * Reset to zero each major or minor version */ -#define LIBOBS_API_PATCH_VER 3 +#define LIBOBS_API_PATCH_VER 1 #define MAKE_SEMANTIC_VERSION(major, minor, patch) \ ((major << 24) | \ diff --git a/libobs/obs-defs.h b/libobs/obs-defs.h index 822111a..694b11c 100644 --- a/libobs/obs-defs.h +++ b/libobs/obs-defs.h @@ -40,6 +40,7 @@ #define OBS_OUTPUT_DISCONNECTED -5 #define OBS_OUTPUT_UNSUPPORTED -6 #define OBS_OUTPUT_NO_SPACE -7 +#define OBS_OUTPUT_ENCODE_ERROR -8 #define OBS_VIDEO_SUCCESS 0 #define OBS_VIDEO_FAIL -1 diff --git a/libobs/obs-display.c b/libobs/obs-display.c index f5d01ab..5244863 100644 --- a/libobs/obs-display.c +++ b/libobs/obs-display.c @@ -46,17 +46,19 @@ bool obs_display_init(struct obs_display *display, return false; } - display->background_color = 0x4C4C4C; display->enabled = true; return true; } -obs_display_t *obs_display_create(const struct gs_init_data *graphics_data) +obs_display_t *obs_display_create(const struct gs_init_data *graphics_data, + uint32_t background_color) { struct obs_display *display = bzalloc(sizeof(struct obs_display)); gs_enter_context(obs->video.graphics); + display->background_color = background_color; + if (!obs_display_init(display, graphics_data)) { obs_display_destroy(display); display = NULL; @@ -173,7 +175,6 @@ static inline void render_display_begin(struct obs_display *display, static inline void render_display_end() { gs_end_scene(); - gs_present(); } void render_display(struct obs_display *display) @@ -183,6 +184,8 @@ void render_display(struct obs_display *display) if (!display || !display->enabled) return; + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DISPLAY, "obs_display"); + /* -------------------------------------------- */ pthread_mutex_lock(&display->draw_info_mutex); @@ -212,6 +215,10 @@ void render_display(struct obs_display *display) pthread_mutex_unlock(&display->draw_callbacks_mutex); render_display_end(); + + GS_DEBUG_MARKER_END(); + + gs_present(); } void obs_display_set_enabled(obs_display_t *display, bool enable) @@ -230,3 +237,19 @@ void obs_display_set_background_color(obs_display_t *display, uint32_t color) if (display) display->background_color = color; } + +void obs_display_size(obs_display_t *display, + uint32_t *width, uint32_t *height) +{ + *width = 0; + *height = 0; + + if (display) { + pthread_mutex_lock(&display->draw_info_mutex); + + *width = display->cx; + *height = display->cy; + + pthread_mutex_unlock(&display->draw_info_mutex); + } +} diff --git a/libobs/obs-encoder.c b/libobs/obs-encoder.c index 83b2d7f..cede06a 100644 --- a/libobs/obs-encoder.c +++ b/libobs/obs-encoder.c @@ -64,8 +64,8 @@ static bool init_encoder(struct obs_encoder *encoder, const char *name, if (pthread_mutex_init(&encoder->outputs_mutex, NULL) != 0) return false; - if (encoder->info.get_defaults) - encoder->info.get_defaults(encoder->context.settings); + if (encoder->orig_info.get_defaults) + encoder->orig_info.get_defaults(encoder->context.settings); return true; } @@ -90,8 +90,10 @@ static struct obs_encoder *create_encoder(const char *id, encoder->info.id = bstrdup(id); encoder->info.type = type; encoder->owns_info_id = true; + encoder->orig_info = encoder->info; } else { encoder->info = *ei; + encoder->orig_info = *ei; } success = init_encoder(encoder, name, settings, hotkey_data); @@ -177,6 +179,12 @@ static inline bool has_scaling(const struct obs_encoder *encoder) video_height != encoder->scaled_height); } +static inline bool gpu_encode_available(const struct obs_encoder *encoder) +{ + return (encoder->info.caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0 && + obs->video.using_nv12_tex; +} + static void add_connection(struct obs_encoder *encoder) { if (encoder->info.type == OBS_ENCODER_AUDIO) { @@ -189,21 +197,37 @@ static void add_connection(struct obs_encoder *encoder) struct video_scale_info info = {0}; get_video_info(encoder, &info); - start_raw_video(encoder->media, &info, receive_video, encoder); + if (gpu_encode_available(encoder)) { + start_gpu_encode(encoder); + } else { + start_raw_video(encoder->media, &info, receive_video, + encoder); + } } set_encoder_active(encoder, true); } -static void remove_connection(struct obs_encoder *encoder) +static void remove_connection(struct obs_encoder *encoder, bool shutdown) { - if (encoder->info.type == OBS_ENCODER_AUDIO) + if (encoder->info.type == OBS_ENCODER_AUDIO) { audio_output_disconnect(encoder->media, encoder->mixer_idx, receive_audio, encoder); - else - stop_raw_video(encoder->media, receive_video, encoder); + } else { + if (gpu_encode_available(encoder)) { + stop_gpu_encode(encoder); + } else { + stop_raw_video(encoder->media, receive_video, encoder); + } + } - obs_encoder_shutdown(encoder); + /* obs_encoder_shutdown locks init_mutex, so don't call it on encode + * errors, otherwise you can get a deadlock with outputs when they end + * data capture, which will lock init_mutex and the video callback + * mutex in the reverse order. instead, call shutdown before starting + * up again */ + if (shutdown) + obs_encoder_shutdown(encoder); set_encoder_active(encoder, false); } @@ -253,11 +277,13 @@ void obs_encoder_destroy(obs_encoder_t *encoder) obs_context_data_remove(&encoder->context); + pthread_mutex_lock(&encoder->init_mutex); pthread_mutex_lock(&encoder->callbacks_mutex); destroy = encoder->callbacks.num == 0; if (!destroy) encoder->destroy_on_stop = true; pthread_mutex_unlock(&encoder->callbacks_mutex); + pthread_mutex_unlock(&encoder->init_mutex); if (destroy) obs_encoder_actually_destroy(encoder); @@ -282,8 +308,11 @@ void obs_encoder_set_name(obs_encoder_t *encoder, const char *name) static inline obs_data_t *get_defaults(const struct obs_encoder_info *info) { obs_data_t *settings = obs_data_create(); - if (info->get_defaults) + if (info->get_defaults2) { + info->get_defaults2(settings, info->type_data); + } else if (info->get_defaults) { info->get_defaults(settings); + } return settings; } @@ -304,11 +333,16 @@ obs_data_t *obs_encoder_get_defaults(const obs_encoder_t *encoder) obs_properties_t *obs_get_encoder_properties(const char *id) { const struct obs_encoder_info *ei = find_encoder(id); - if (ei && ei->get_properties) { + if (ei && (ei->get_properties || ei->get_properties2)) { obs_data_t *defaults = get_defaults(ei); obs_properties_t *properties; - properties = ei->get_properties(NULL); + if (ei->get_properties2) { + properties = ei->get_properties2(NULL, ei->type_data); + } else if (ei->get_properties) { + properties = ei->get_properties(NULL); + } + obs_properties_apply_settings(properties, defaults); obs_data_release(defaults); return properties; @@ -321,12 +355,21 @@ obs_properties_t *obs_encoder_properties(const obs_encoder_t *encoder) if (!obs_encoder_valid(encoder, "obs_encoder_properties")) return NULL; - if (encoder->info.get_properties) { + if (encoder->orig_info.get_properties2) { obs_properties_t *props; - props = encoder->info.get_properties(encoder->context.data); + props = encoder->orig_info.get_properties2( + encoder->context.data, + encoder->orig_info.type_data); + obs_properties_apply_settings(props, encoder->context.settings); + return props; + + } else if (encoder->orig_info.get_properties) { + obs_properties_t *props; + props = encoder->orig_info.get_properties(encoder->context.data); obs_properties_apply_settings(props, encoder->context.settings); return props; } + return NULL; } @@ -388,6 +431,8 @@ static void intitialize_audio_encoder(struct obs_encoder *encoder) reset_audio_buffers(encoder); } +static THREAD_LOCAL bool can_reroute = false; + static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder) { if (encoder_active(encoder)) @@ -397,19 +442,45 @@ static inline bool obs_encoder_initialize_internal(obs_encoder_t *encoder) obs_encoder_shutdown(encoder); - if (encoder->info.create) - encoder->context.data = encoder->info.create( + if (encoder->orig_info.create) { + can_reroute = true; + encoder->info = encoder->orig_info; + encoder->context.data = encoder->orig_info.create( encoder->context.settings, encoder); + can_reroute = false; + } if (!encoder->context.data) return false; - if (encoder->info.type == OBS_ENCODER_AUDIO) + if (encoder->orig_info.type == OBS_ENCODER_AUDIO) intitialize_audio_encoder(encoder); encoder->initialized = true; return true; } +void *obs_encoder_create_rerouted(obs_encoder_t *encoder, const char *reroute_id) +{ + if (!obs_ptr_valid(encoder, "obs_encoder_reroute")) + return NULL; + if (!obs_ptr_valid(reroute_id, "obs_encoder_reroute")) + return NULL; + if (!can_reroute) + return NULL; + + const struct obs_encoder_info *ei = find_encoder(reroute_id); + if (ei) { + if (ei->type != encoder->orig_info.type || + astrcmpi(ei->codec, encoder->orig_info.codec) != 0) { + return NULL; + } + encoder->info = *ei; + return encoder->info.create(encoder->context.settings, encoder); + } + + return NULL; +} + bool obs_encoder_initialize(obs_encoder_t *encoder) { bool success; @@ -510,7 +581,7 @@ static inline bool obs_encoder_stop_internal(obs_encoder_t *encoder, pthread_mutex_unlock(&encoder->callbacks_mutex); if (last) { - remove_connection(encoder); + remove_connection(encoder, true); encoder->initialized = false; if (encoder->destroy_on_stop) { @@ -766,19 +837,65 @@ static inline void send_packet(struct obs_encoder *encoder, cb->new_packet(cb->param, packet); } -static void full_stop(struct obs_encoder *encoder) +void full_stop(struct obs_encoder *encoder) { if (encoder) { + pthread_mutex_lock(&encoder->outputs_mutex); + for (size_t i = 0; i < encoder->outputs.num; i++) { + struct obs_output *output = encoder->outputs.array[i]; + obs_output_force_stop(output); + + pthread_mutex_lock(&output->interleaved_mutex); + output->info.encoded_packet(output->context.data, NULL); + pthread_mutex_unlock(&output->interleaved_mutex); + } + pthread_mutex_unlock(&encoder->outputs_mutex); + pthread_mutex_lock(&encoder->callbacks_mutex); da_free(encoder->callbacks); - remove_connection(encoder); + pthread_mutex_unlock(&encoder->callbacks_mutex); + + remove_connection(encoder, false); + encoder->initialized = false; + } +} + +void send_off_encoder_packet(obs_encoder_t *encoder, bool success, + bool received, struct encoder_packet *pkt) +{ + if (!success) { + blog(LOG_ERROR, "Error encoding with encoder '%s'", + encoder->context.name); + full_stop(encoder); + return; + } + + if (received) { + if (!encoder->first_received) { + encoder->offset_usec = packet_dts_usec(pkt); + encoder->first_received = true; + } + + /* we use system time here to ensure sync with other encoders, + * you do not want to use relative timestamps here */ + pkt->dts_usec = encoder->start_ts / 1000 + + packet_dts_usec(pkt) - encoder->offset_usec; + pkt->sys_dts_usec = pkt->dts_usec; + + pthread_mutex_lock(&encoder->callbacks_mutex); + + for (size_t i = encoder->callbacks.num; i > 0; i--) { + struct encoder_callback *cb; + cb = encoder->callbacks.array+(i-1); + send_packet(encoder, cb, pkt); + } + pthread_mutex_unlock(&encoder->callbacks_mutex); } } static const char *do_encode_name = "do_encode"; -static inline void do_encode(struct obs_encoder *encoder, - struct encoder_frame *frame) +bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame) { profile_start(do_encode_name); if (!encoder->profile_encoder_encode_name) @@ -798,38 +915,11 @@ static inline void do_encode(struct obs_encoder *encoder, success = encoder->info.encode(encoder->context.data, frame, &pkt, &received); profile_end(encoder->profile_encoder_encode_name); - if (!success) { - full_stop(encoder); - blog(LOG_ERROR, "Error encoding with encoder '%s'", - encoder->context.name); - goto error; - } + send_off_encoder_packet(encoder, success, received, &pkt); - if (received) { - if (!encoder->first_received) { - encoder->offset_usec = packet_dts_usec(&pkt); - encoder->first_received = true; - } - - /* we use system time here to ensure sync with other encoders, - * you do not want to use relative timestamps here */ - pkt.dts_usec = encoder->start_ts / 1000 + - packet_dts_usec(&pkt) - encoder->offset_usec; - pkt.sys_dts_usec = pkt.dts_usec; - - pthread_mutex_lock(&encoder->callbacks_mutex); - - for (size_t i = encoder->callbacks.num; i > 0; i--) { - struct encoder_callback *cb; - cb = encoder->callbacks.array+(i-1); - send_packet(encoder, cb, &pkt); - } - - pthread_mutex_unlock(&encoder->callbacks_mutex); - } - -error: profile_end(do_encode_name); + + return success; } static const char *receive_video_name = "receive_video"; @@ -861,9 +951,8 @@ static void receive_video(void *param, struct video_data *frame) enc_frame.frames = 1; enc_frame.pts = encoder->cur_pts; - do_encode(encoder, &enc_frame); - - encoder->cur_pts += encoder->timebase_num; + if (do_encode(encoder, &enc_frame)) + encoder->cur_pts += encoder->timebase_num; wait_for_audio: profile_end(receive_video_name); @@ -971,7 +1060,7 @@ fail: return success; } -static void send_audio_data(struct obs_encoder *encoder) +static bool send_audio_data(struct obs_encoder *encoder) { struct encoder_frame enc_frame; @@ -989,9 +1078,11 @@ static void send_audio_data(struct obs_encoder *encoder) enc_frame.frames = (uint32_t)encoder->framesize; enc_frame.pts = encoder->cur_pts; - do_encode(encoder, &enc_frame); + if (!do_encode(encoder, &enc_frame)) + return false; encoder->cur_pts += encoder->framesize; + return true; } static const char *receive_audio_name = "receive_audio"; @@ -1010,8 +1101,11 @@ static void receive_audio(void *param, size_t mix_idx, struct audio_data *data) if (!buffer_audio(encoder, data)) goto end; - while (encoder->audio_input_buffer[0].size >= encoder->framesize_bytes) - send_audio_data(encoder); + while (encoder->audio_input_buffer[0].size >= encoder->framesize_bytes) { + if (!send_audio_data(encoder)) { + break; + } + } UNUSED_PARAMETER(mix_idx); @@ -1186,13 +1280,13 @@ bool obs_weak_encoder_references_encoder(obs_weak_encoder_t *weak, void *obs_encoder_get_type_data(obs_encoder_t *encoder) { return obs_encoder_valid(encoder, "obs_encoder_get_type_data") - ? encoder->info.type_data : NULL; + ? encoder->orig_info.type_data : NULL; } const char *obs_encoder_get_id(const obs_encoder_t *encoder) { return obs_encoder_valid(encoder, "obs_encoder_get_id") - ? encoder->info.id : NULL; + ? encoder->orig_info.id : NULL; } uint32_t obs_get_encoder_caps(const char *encoder_id) @@ -1200,3 +1294,9 @@ uint32_t obs_get_encoder_caps(const char *encoder_id) struct obs_encoder_info *info = find_encoder(encoder_id); return info ? info->caps : 0; } + +uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder) +{ + return obs_encoder_valid(encoder, "obs_encoder_get_caps") + ? encoder->orig_info.caps : 0; +} diff --git a/libobs/obs-encoder.h b/libobs/obs-encoder.h index 2220c5a..3264423 100644 --- a/libobs/obs-encoder.h +++ b/libobs/obs-encoder.h @@ -30,6 +30,7 @@ extern "C" { #endif #define OBS_ENCODER_CAP_DEPRECATED (1<<0) +#define OBS_ENCODER_CAP_PASS_TEXTURE (1<<1) /** Specifies the encoder type */ enum obs_encoder_type { @@ -234,6 +235,27 @@ struct obs_encoder_info { void (*free_type_data)(void *type_data); uint32_t caps; + + /** + * Gets the default settings for this encoder + * + * @param[out] settings Data to assign default settings to + * @param[in] typedata Type Data + */ + void (*get_defaults2)(obs_data_t *settings, void *type_data); + + /** + * Gets the property information of this encoder + * + * @param[in] data Pointer from create (or null) + * @param[in] typedata Type Data + * @return The properties data + */ + obs_properties_t *(*get_properties2)(void *data, void *type_data); + + bool (*encode_texture)(void *data, uint32_t handle, int64_t pts, + uint64_t lock_key, uint64_t *next_key, + struct encoder_packet *packet, bool *received_packet); }; EXPORT void obs_register_encoder_s(const struct obs_encoder_info *info, diff --git a/libobs/obs-hotkey.c b/libobs/obs-hotkey.c index b150d29..d31076e 100644 --- a/libobs/obs-hotkey.c +++ b/libobs/obs-hotkey.c @@ -1479,6 +1479,7 @@ void obs_hotkeys_set_translations_s( ADD_TRANSLATION(OBS_KEY_META, meta); ADD_TRANSLATION(OBS_KEY_MENU, menu); ADD_TRANSLATION(OBS_KEY_SPACE, space); + ADD_TRANSLATION(OBS_KEY_ESCAPE, escape); #ifdef __APPLE__ const char *numpad_str = t.apple_keypad_num; ADD_TRANSLATION(OBS_KEY_NUMSLASH, apple_keypad_divide); diff --git a/libobs/obs-hotkey.h b/libobs/obs-hotkey.h index 4e4a86a..74a047f 100644 --- a/libobs/obs-hotkey.h +++ b/libobs/obs-hotkey.h @@ -126,6 +126,7 @@ struct obs_hotkeys_translations { const char *apple_keypad_decimal; const char *apple_keypad_equal; const char *mouse_num; /* For example, "Mouse %1" */ + const char *escape; }; /* This function is an optional way to provide translations for specific keys diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index b317fd9..717360f 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -38,6 +38,8 @@ #define NUM_TEXTURES 2 #define MICROSECOND_DEN 1000000 +#define NUM_ENCODE_TEXTURES 3 +#define NUM_ENCODE_TEXTURE_FRAMES_TO_WAIT 1 static inline int64_t packet_dts_usec(struct encoder_packet *packet) { @@ -225,30 +227,55 @@ struct obs_vframe_info { int count; }; +struct obs_tex_frame { + gs_texture_t *tex; + gs_texture_t *tex_uv; + uint32_t handle; + uint64_t timestamp; + uint64_t lock_key; + int count; + bool released; +}; + struct obs_core_video { graphics_t *graphics; gs_stagesurf_t *copy_surfaces[NUM_TEXTURES]; gs_texture_t *render_textures[NUM_TEXTURES]; gs_texture_t *output_textures[NUM_TEXTURES]; gs_texture_t *convert_textures[NUM_TEXTURES]; + gs_texture_t *convert_uv_textures[NUM_TEXTURES]; bool textures_rendered[NUM_TEXTURES]; bool textures_output[NUM_TEXTURES]; bool textures_copied[NUM_TEXTURES]; bool textures_converted[NUM_TEXTURES]; + bool using_nv12_tex; struct circlebuf vframe_info_buffer; + struct circlebuf vframe_info_buffer_gpu; gs_effect_t *default_effect; gs_effect_t *default_rect_effect; gs_effect_t *opaque_effect; gs_effect_t *solid_effect; + gs_effect_t *repeat_effect; gs_effect_t *conversion_effect; gs_effect_t *bicubic_effect; gs_effect_t *lanczos_effect; + gs_effect_t *area_effect; gs_effect_t *bilinear_lowres_effect; gs_effect_t *premultiplied_alpha_effect; gs_samplerstate_t *point_sampler; gs_stagesurf_t *mapped_surface; int cur_texture; long raw_active; + long gpu_encoder_active; + pthread_mutex_t gpu_encoder_mutex; + struct circlebuf gpu_encoder_queue; + struct circlebuf gpu_encoder_avail_queue; + DARRAY(obs_encoder_t *) gpu_encoders; + os_sem_t *gpu_encode_semaphore; + os_event_t *gpu_encode_inactive; + pthread_t gpu_encode_thread; + bool gpu_encode_thread_initialized; + volatile bool gpu_encode_stop; uint64_t video_time; uint64_t video_avg_frame_time_ns; @@ -608,6 +635,7 @@ struct obs_source { float volume; int64_t sync_offset; int64_t last_sync_offset; + float balance; /* async video data */ gs_texture_t *async_texture; @@ -615,12 +643,10 @@ struct obs_source { struct obs_source_frame *cur_async_frame; bool async_gpu_conversion; enum video_format async_format; - enum video_format async_cache_format; - enum gs_color_format async_texture_format; - float async_color_matrix[16]; bool async_full_range; - float async_color_range_min[3]; - float async_color_range_max[3]; + enum video_format async_cache_format; + bool async_cache_full_range; + enum gs_color_format async_texture_format; int async_plane_offset[2]; bool async_flip; bool async_active; @@ -816,6 +842,7 @@ struct obs_weak_output { #define CAPTION_LINE_BYTES (4*CAPTION_LINE_CHARS) struct caption_text { char text[CAPTION_LINE_BYTES+1]; + double display_duration; struct caption_text *next; }; @@ -862,7 +889,7 @@ struct obs_output { obs_encoder_t *video_encoder; obs_encoder_t *audio_encoders[MAX_AUDIO_MIXES]; obs_service_t *service; - size_t mixer_idx; + size_t mixer_mask; uint32_t scaled_width; uint32_t scaled_height; @@ -939,6 +966,9 @@ struct obs_encoder { struct obs_encoder_info info; struct obs_weak_encoder *control; + /* allows re-routing to another encoder */ + struct obs_encoder_info orig_info; + pthread_mutex_t init_mutex; uint32_t samplerate; @@ -1009,6 +1039,13 @@ extern void obs_encoder_add_output(struct obs_encoder *encoder, extern void obs_encoder_remove_output(struct obs_encoder *encoder, struct obs_output *output); +extern bool start_gpu_encode(obs_encoder_t *encoder); +extern void stop_gpu_encode(obs_encoder_t *encoder); + +extern bool do_encode(struct obs_encoder *encoder, struct encoder_frame *frame); +extern void send_off_encoder_packet(obs_encoder_t *encoder, bool success, + bool received, struct encoder_packet *pkt); + void obs_encoder_destroy(obs_encoder_t *encoder); /* ------------------------------------------------------------------------- */ diff --git a/libobs/obs-module.c b/libobs/obs-module.c index 4136965..38276f8 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -26,7 +26,7 @@ extern const char *get_module_extension(void); static inline int req_func_not_found(const char *name, const char *path) { - blog(LOG_ERROR, "Required module function '%s' in module '%s' not " + blog(LOG_DEBUG, "Required module function '%s' in module '%s' not " "found, loading of module failed", name, path); return MODULE_MISSING_EXPORTS; @@ -675,9 +675,15 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size) CHECK_REQUIRED_VAL_(info, raw_video, obs_register_output); - if (info->flags & OBS_OUTPUT_AUDIO) - CHECK_REQUIRED_VAL_(info, raw_audio, - obs_register_output); + if (info->flags & OBS_OUTPUT_AUDIO) { + if (info->flags & OBS_OUTPUT_MULTI_TRACK) { + CHECK_REQUIRED_VAL_(info, raw_audio2, + obs_register_output); + } else { + CHECK_REQUIRED_VAL_(info, raw_audio, + obs_register_output); + } + } } #undef CHECK_REQUIRED_VAL_ @@ -701,7 +707,11 @@ void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size) CHECK_REQUIRED_VAL_(info, get_name, obs_register_encoder); CHECK_REQUIRED_VAL_(info, create, obs_register_encoder); CHECK_REQUIRED_VAL_(info, destroy, obs_register_encoder); - CHECK_REQUIRED_VAL_(info, encode, obs_register_encoder); + + if ((info->caps & OBS_ENCODER_CAP_PASS_TEXTURE) != 0) + CHECK_REQUIRED_VAL_(info, encode_texture, obs_register_encoder); + else + CHECK_REQUIRED_VAL_(info, encode, obs_register_encoder); if (info->type == OBS_ENCODER_AUDIO) CHECK_REQUIRED_VAL_(info, get_frame_size, obs_register_encoder); diff --git a/libobs/obs-nix.c b/libobs/obs-nix.c index 355b832..f7ce93d 100644 --- a/libobs/obs-nix.c +++ b/libobs/obs-nix.c @@ -422,6 +422,17 @@ static int get_keysym(obs_key_t key) case OBS_KEY_F22: return XK_F22; case OBS_KEY_F23: return XK_F23; case OBS_KEY_F24: return XK_F24; + case OBS_KEY_F25: return XK_F25; + case OBS_KEY_F26: return XK_F26; + case OBS_KEY_F27: return XK_F27; + case OBS_KEY_F28: return XK_F28; + case OBS_KEY_F29: return XK_F29; + case OBS_KEY_F30: return XK_F30; + case OBS_KEY_F31: return XK_F31; + case OBS_KEY_F32: return XK_F32; + case OBS_KEY_F33: return XK_F33; + case OBS_KEY_F34: return XK_F34; + case OBS_KEY_F35: return XK_F35; case OBS_KEY_MENU: return XK_Menu; case OBS_KEY_HYPER_L: return XK_Hyper_L; @@ -1114,6 +1125,8 @@ void obs_key_to_str(obs_key_t key, struct dstr *dstr) case OBS_KEY_NUMCOMMA: return translate_key(key, "Numpad ,"); case OBS_KEY_NUMPERIOD: return translate_key(key, "Numpad ."); case OBS_KEY_NUMSLASH: return translate_key(key, "Numpad /"); + case OBS_KEY_SPACE: return translate_key(key, "Space"); + case OBS_KEY_ESCAPE: return translate_key(key, "Escape"); default:; } diff --git a/libobs/obs-output.c b/libobs/obs-output.c index f82382f..b8fe903 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -255,13 +255,17 @@ bool obs_output_actual_start(obs_output_t *output) bool obs_output_start(obs_output_t *output) { bool encoded; + bool has_service; if (!obs_output_valid(output, "obs_output_start")) return false; if (!output->context.data) return false; - encoded = (output->info.flags & OBS_OUTPUT_ENCODED) != 0; + has_service = (output->info.flags & OBS_OUTPUT_SERVICE) != 0; + if (has_service && !obs_service_initialize(output->service, output)) + return false; + encoded = (output->info.flags & OBS_OUTPUT_ENCODED) != 0; if (encoded && output->delay_sec) { return obs_output_delay_start(output); } else { @@ -544,19 +548,46 @@ audio_t *obs_output_audio(const obs_output_t *output) output->audio : NULL; } +static inline size_t get_first_mixer(const obs_output_t *output) +{ + for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) { + if ((((size_t)1 << i) & output->mixer_mask) != 0) { + return i; + } + } + + return 0; +} + void obs_output_set_mixer(obs_output_t *output, size_t mixer_idx) { if (!obs_output_valid(output, "obs_output_set_mixer")) return; if (!active(output)) - output->mixer_idx = mixer_idx; + output->mixer_mask = (size_t)1 << mixer_idx; } size_t obs_output_get_mixer(const obs_output_t *output) { - return obs_output_valid(output, "obs_output_get_mixer") ? - output->mixer_idx : 0; + if (!obs_output_valid(output, "obs_output_get_mixer")) + return 0; + + return get_first_mixer(output); +} + +void obs_output_set_mixers(obs_output_t *output, size_t mixers) +{ + if (!obs_output_valid(output, "obs_output_set_mixers")) + return; + + output->mixer_mask = mixers; +} + +size_t obs_output_get_mixers(const obs_output_t *output) +{ + return obs_output_valid(output, "obs_output_get_mixers") ? + output->mixer_mask : 0; } void obs_output_remove_encoder(struct obs_output *output, @@ -1043,17 +1074,18 @@ static inline void send_interleaved(struct obs_output *output) double frame_timestamp = (out.pts * out.timebase_num) / (double)out.timebase_den; - /* TODO if output->caption_timestamp is more than 5 seconds - * old, send empty frame */ if (output->caption_head && output->caption_timestamp <= frame_timestamp) { - blog(LOG_INFO,"Sending caption: %f \"%s\"", + blog(LOG_DEBUG,"Sending caption: %f \"%s\"", frame_timestamp, &output->caption_head->text[0]); + double display_duration = + output->caption_head->display_duration; + if (add_caption(output, &out)) { output->caption_timestamp = - frame_timestamp + 2.0; + frame_timestamp + display_duration; } } @@ -1476,6 +1508,7 @@ static void default_raw_video_callback(void *param, struct video_data *frame) output->total_frames++; } + static void default_raw_audio_callback(void *param, size_t mix_idx, struct audio_data *frames) { @@ -1483,9 +1516,10 @@ static void default_raw_audio_callback(void *param, size_t mix_idx, if (!data_active(output)) return; - output->info.raw_audio(output->context.data, frames); - - UNUSED_PARAMETER(mix_idx); + if (output->info.raw_audio2) + output->info.raw_audio2(output->context.data, mix_idx, frames); + else + output->info.raw_audio(output->context.data, frames); } static inline void start_audio_encoders(struct obs_output *output, @@ -1499,6 +1533,25 @@ static inline void start_audio_encoders(struct obs_output *output, } } +static inline void start_raw_audio(obs_output_t *output) +{ + if (output->info.raw_audio2) { + for (int idx = 0; idx < MAX_AUDIO_MIXES; idx++) { + if ((output->mixer_mask & ((size_t)1 << idx)) != 0) { + audio_output_connect(output->audio, idx, + get_audio_conversion(output), + default_raw_audio_callback, + output); + } + } + } else { + audio_output_connect(output->audio, get_first_mixer(output), + get_audio_conversion(output), + default_raw_audio_callback, + output); + } +} + static void reset_packet_data(obs_output_t *output) { output->received_audio = false; @@ -1508,7 +1561,7 @@ static void reset_packet_data(obs_output_t *output) output->video_offset = 0; for (size_t i = 0; i < MAX_AUDIO_MIXES; i++) - output->audio_offsets[0] = 0; + output->audio_offsets[i] = 0; free_packets(output); } @@ -1557,9 +1610,7 @@ static void hook_data_capture(struct obs_output *output, bool encoded, get_video_conversion(output), default_raw_video_callback, output); if (has_audio) - audio_output_connect(output->audio, output->mixer_idx, - get_audio_conversion(output), - default_raw_audio_callback, output); + start_raw_audio(output); } } @@ -1653,7 +1704,7 @@ static inline obs_encoder_t *find_inactive_audio_encoder(obs_output_t *output, for (size_t i = 0; i < num_mixes; i++) { struct obs_encoder *audio = output->audio_encoders[i]; - if (!audio->active && !audio->paired_encoder) + if (audio && !audio->active && !audio->paired_encoder) return audio; } @@ -1700,16 +1751,11 @@ bool obs_output_initialize_encoders(obs_output_t *output, uint32_t flags) if (!encoded) return false; - if (has_service && !obs_service_initialize(output->service, output)) - return false; if (has_video && !obs_encoder_initialize(output->video_encoder)) return false; if (has_audio && !initialize_audio_encoders(output, num_mixes)) return false; - if (has_video && has_audio) - pair_encoders(output, num_mixes); - return true; } @@ -1736,6 +1782,7 @@ static bool begin_delayed_capture(obs_output_t *output) bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) { bool encoded, has_video, has_audio, has_service; + size_t num_mixes; if (!obs_output_valid(output, "obs_output_begin_data_capture")) return false; @@ -1752,6 +1799,10 @@ bool obs_output_begin_data_capture(obs_output_t *output, uint32_t flags) has_service)) return false; + num_mixes = num_audio_mixes(output); + if (has_video && has_audio) + pair_encoders(output, num_mixes); + os_atomic_set_bool(&output->data_active, true); hook_data_capture(output, encoded, has_video, has_audio); @@ -1786,6 +1837,25 @@ static inline void stop_audio_encoders(obs_output_t *output, } } +static inline void stop_raw_audio(obs_output_t *output) +{ + if (output->info.raw_audio2) { + for (int idx = 0; idx < MAX_AUDIO_MIXES; idx++) { + if ((output->mixer_mask & ((size_t)1 << idx)) != 0) { + audio_output_disconnect(output->audio, + idx, + default_raw_audio_callback, + output); + } + } + } else { + audio_output_disconnect(output->audio, + get_first_mixer(output), + default_raw_audio_callback, + output); + } +} + static void *end_data_capture_thread(void *data) { bool encoded, has_video, has_audio, has_service; @@ -1812,9 +1882,7 @@ static void *end_data_capture_thread(void *data) stop_raw_video(output->video, default_raw_video_callback, output); if (has_audio) - audio_output_disconnect(output->audio, - output->mixer_idx, - default_raw_audio_callback, output); + stop_raw_audio(output); } if (has_service) @@ -2070,11 +2138,13 @@ const char *obs_output_get_id(const obs_output_t *output) #if BUILD_CAPTIONS static struct caption_text *caption_text_new(const char *text, size_t bytes, - struct caption_text *tail, struct caption_text **head) + struct caption_text *tail, struct caption_text **head, + double display_duration) { struct caption_text *next = bzalloc(sizeof(struct caption_text)); snprintf(&next->text[0], CAPTION_LINE_BYTES + 1, "%.*s", (int)bytes, text); + next->display_duration = display_duration; if (!*head) { *head = next; @@ -2089,6 +2159,14 @@ void obs_output_output_caption_text1(obs_output_t *output, const char *text) { if (!obs_output_valid(output, "obs_output_output_caption_text1")) return; + obs_output_output_caption_text2(output, text, 2.0f); +} + +void obs_output_output_caption_text2(obs_output_t *output, const char *text, + double display_duration) +{ + if (!obs_output_valid(output, "obs_output_output_caption_text2")) + return; if (!active(output)) return; @@ -2101,7 +2179,8 @@ void obs_output_output_caption_text1(obs_output_t *output, const char *text) output->caption_tail = caption_text_new( text, size, output->caption_tail, - &output->caption_head); + &output->caption_head, + display_duration); pthread_mutex_unlock(&output->caption_mutex); } diff --git a/libobs/obs-output.h b/libobs/obs-output.h index df50fa0..db30fe0 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -71,6 +71,9 @@ struct obs_output_info { /* only used with encoded outputs, separated with semicolon */ const char *encoded_video_codecs; const char *encoded_audio_codecs; + + /* raw audio callback for multi track outputs */ + void (*raw_audio2)(void *data, size_t idx, struct audio_data *frames); }; EXPORT void obs_register_output_s(const struct obs_output_info *info, diff --git a/libobs/obs-properties.c b/libobs/obs-properties.c index 615882b..c8fcbe5 100644 --- a/libobs/obs-properties.c +++ b/libobs/obs-properties.c @@ -27,11 +27,13 @@ static inline void *get_property_data(struct obs_property *prop); struct float_data { double min, max, step; enum obs_number_type type; + char *suffix; }; struct int_data { int min, max, step; enum obs_number_type type; + char *suffix; }; struct list_item { @@ -86,6 +88,11 @@ struct frame_rate_data { DARRAY(struct frame_rate_range) ranges; }; +struct group_data { + enum obs_group_type type; + obs_properties_t *content; +}; + static inline void path_data_free(struct path_data *data) { bfree(data->default_path); @@ -140,6 +147,20 @@ static inline void frame_rate_data_free(struct frame_rate_data *data) da_free(data->ranges); } +static inline void group_data_free(struct group_data *data) { + obs_properties_destroy(data->content); +} + +static inline void int_data_free(struct int_data *data) { + if (data->suffix) + bfree(data->suffix); +} + +static inline void float_data_free(struct float_data *data) { + if (data->suffix) + bfree(data->suffix); +} + struct obs_properties; struct obs_property { @@ -166,6 +187,7 @@ struct obs_properties { struct obs_property *first_property; struct obs_property **last; + struct obs_property *parent; }; obs_properties_t *obs_properties_create(void) @@ -223,6 +245,12 @@ static void obs_property_destroy(struct obs_property *property) editable_list_data_free(get_property_data(property)); else if (property->type == OBS_PROPERTY_FRAME_RATE) frame_rate_data_free(get_property_data(property)); + else if (property->type == OBS_PROPERTY_GROUP) + group_data_free(get_property_data(property)); + else if (property->type == OBS_PROPERTY_INT) + int_data_free(get_property_data(property)); + else if (property->type == OBS_PROPERTY_FLOAT) + float_data_free(get_property_data(property)); bfree(property->name); bfree(property->desc); @@ -265,12 +293,51 @@ obs_property_t *obs_properties_get(obs_properties_t *props, const char *name) if (strcmp(property->name, name) == 0) return property; + if (property->type == OBS_PROPERTY_GROUP) { + obs_properties_t *group = + obs_property_group_content(property); + obs_property_t *found = obs_properties_get(group, name); + if (found != NULL) { + return found; + } + } + property = property->next; } return NULL; } +obs_properties_t *obs_properties_get_parent(obs_properties_t *props) +{ + return props->parent ? props->parent->parent : NULL; +} + +void obs_properties_remove_by_name(obs_properties_t *props, const char *name) +{ + if (!props) + return; + + /* obs_properties_t is a forward-linked-list, so we need to keep both + * previous and current pointers around. That way we can fix up the + * pointers for the previous element if we find a match. + */ + struct obs_property *cur = props->first_property; + struct obs_property *prev = props->first_property; + + while (cur) { + if (strcmp(cur->name, name) == 0) { + prev->next = cur->next; + cur->next = 0; + obs_property_destroy(cur); + break; + } + + prev = cur; + cur = cur->next; + } +} + void obs_properties_apply_settings(obs_properties_t *props, obs_data_t *settings) { struct obs_property *p; @@ -313,6 +380,7 @@ static inline size_t get_property_size(enum obs_property_type type) case OBS_PROPERTY_EDITABLE_LIST: return sizeof(struct editable_list_data); case OBS_PROPERTY_FRAME_RATE:return sizeof(struct frame_rate_data); + case OBS_PROPERTY_GROUP: return sizeof(struct group_data); } return 0; @@ -337,7 +405,18 @@ static inline struct obs_property *new_prop(struct obs_properties *props, return p; } -static inline bool has_prop(struct obs_properties *props, const char *name) +static inline obs_properties_t *get_topmost_parent(obs_properties_t *props) +{ + obs_properties_t *parent = props; + obs_properties_t *last_parent = parent; + while (parent) { + last_parent = parent; + parent = obs_properties_get_parent(parent); + } + return last_parent; +} + +static inline bool contains_prop(struct obs_properties *props, const char *name) { struct obs_property *p = props->first_property; @@ -347,12 +426,23 @@ static inline bool has_prop(struct obs_properties *props, const char *name) return true; } + if (p->type == OBS_PROPERTY_GROUP) { + if (contains_prop(obs_property_group_content(p), name)) { + return true; + } + } + p = p->next; } return false; } +static inline bool has_prop(struct obs_properties *props, const char *name) +{ + return contains_prop(get_topmost_parent(props), name); +} + static inline void *get_property_data(struct obs_property *prop) { return (uint8_t*)prop + sizeof(struct obs_property); @@ -553,6 +643,70 @@ obs_property_t *obs_properties_add_frame_rate(obs_properties_t *props, return p; } +static bool check_property_group_recursion(obs_properties_t *parent, + obs_properties_t *group) +{ + /* Scan the group for the parent. */ + obs_property_t *current_property = group->first_property; + while (current_property) { + if (current_property->type == OBS_PROPERTY_GROUP) { + obs_properties_t *cprops = + obs_property_group_content(current_property); + if (cprops == parent) { + /* Contains find_props */ + return true; + } else if (cprops == group) { + /* Contains self, shouldn't be possible but + * lets verify anyway. */ + return true; + } + check_property_group_recursion(cprops, group); + } + + current_property = current_property->next; + } + + return false; +} + +static bool check_property_group_duplicates(obs_properties_t *parent, + obs_properties_t *group) +{ + obs_property_t *current_property = group->first_property; + while (current_property) { + if (has_prop(parent, current_property->name)) { + return true; + } + + current_property = current_property->next; + } + + return false; +} + +obs_property_t *obs_properties_add_group(obs_properties_t *props, + const char *name, const char *desc, enum obs_group_type type, + obs_properties_t *group) +{ + if (!props || has_prop(props, name)) return NULL; + if (!group) return NULL; + + /* Prevent recursion. */ + if (props == group) return NULL; + if (check_property_group_recursion(props, group)) return NULL; + + /* Prevent duplicate properties */ + if (check_property_group_duplicates(props, group)) return NULL; + + obs_property_t *p = new_prop(props, name, desc, OBS_PROPERTY_GROUP); + group->parent = p; + + struct group_data *data = get_property_data(p); + data->type = type; + data->content = group; + return p; +} + /* ------------------------------------------------------------------------- */ static inline bool is_combo(struct obs_property *p) @@ -605,9 +759,11 @@ bool obs_property_modified(obs_property_t *p, obs_data_t *settings) { if (p) { if (p->modified) { - return p->modified(p->parent, p, settings); + obs_properties_t *top = get_topmost_parent(p->parent); + return p->modified(top, p, settings); } else if (p->modified2) { - return p->modified2(p->priv, p->parent, p, settings); + obs_properties_t *top = get_topmost_parent(p->parent); + return p->modified2(p->priv, top, p, settings); } } return false; @@ -620,9 +776,10 @@ bool obs_property_button_clicked(obs_property_t *p, void *obj) struct button_data *data = get_type_data(p, OBS_PROPERTY_BUTTON); if (data && data->callback) { + obs_properties_t *top = get_topmost_parent(p->parent); if (p->priv) - return data->callback(p->parent, p, p->priv); - return data->callback(p->parent, p, + return data->callback(top, p, p->priv); + return data->callback(top, p, (context ? context->data : NULL)); } } @@ -714,6 +871,12 @@ enum obs_number_type obs_property_int_type(obs_property_t *p) return data ? data->type : OBS_NUMBER_SCROLLER; } +const char *obs_property_int_suffix(obs_property_t *p) +{ + struct int_data *data = get_type_data(p, OBS_PROPERTY_INT); + return data ? data->suffix : NULL; +} + double obs_property_float_min(obs_property_t *p) { struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); @@ -732,6 +895,12 @@ double obs_property_float_step(obs_property_t *p) return data ? data->step : 0; } +const char *obs_property_float_suffix(obs_property_t *p) +{ + struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); + return data ? data->suffix : NULL; +} + enum obs_number_type obs_property_float_type(obs_property_t *p) { struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); @@ -789,7 +958,7 @@ void obs_property_int_set_limits(obs_property_t *p, void obs_property_float_set_limits(obs_property_t *p, double min, double max, double step) { - struct float_data *data = get_type_data(p, OBS_PROPERTY_INT); + struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); if (!data) return; @@ -798,6 +967,26 @@ void obs_property_float_set_limits(obs_property_t *p, data->step = step; } +void obs_property_int_set_suffix(obs_property_t *p, const char *suffix) +{ + struct int_data *data = get_type_data(p, OBS_PROPERTY_INT); + if (!data) + return; + + bfree(data->suffix); + data->suffix = bstrdup(suffix); +} + +void obs_property_float_set_suffix(obs_property_t *p, const char *suffix) +{ + struct float_data *data = get_type_data(p, OBS_PROPERTY_FLOAT); + if (!data) + return; + + bfree(data->suffix); + data->suffix = bstrdup(suffix); +} + void obs_property_list_clear(obs_property_t *p) { struct list_data *data = get_list_data(p); @@ -1112,3 +1301,15 @@ enum obs_text_type obs_proprety_text_type(obs_property_t *p) { return obs_property_text_type(p); } + +enum obs_group_type obs_property_group_type(obs_property_t *p) +{ + struct group_data *data = get_type_data(p, OBS_PROPERTY_GROUP); + return data ? data->type : OBS_COMBO_INVALID; +} + +obs_properties_t *obs_property_group_content(obs_property_t *p) +{ + struct group_data *data = get_type_data(p, OBS_PROPERTY_GROUP); + return data ? data->content : NULL; +} diff --git a/libobs/obs-properties.h b/libobs/obs-properties.h index 6867063..cf17941 100644 --- a/libobs/obs-properties.h +++ b/libobs/obs-properties.h @@ -55,6 +55,7 @@ enum obs_property_type { OBS_PROPERTY_FONT, OBS_PROPERTY_EDITABLE_LIST, OBS_PROPERTY_FRAME_RATE, + OBS_PROPERTY_GROUP, }; enum obs_combo_format { @@ -93,6 +94,12 @@ enum obs_number_type { OBS_NUMBER_SLIDER }; +enum obs_group_type { + OBS_COMBO_INVALID, + OBS_GROUP_NORMAL, + OBS_GROUP_CHECKABLE, +}; + #define OBS_FONT_BOLD (1<<0) #define OBS_FONT_ITALIC (1<<1) #define OBS_FONT_UNDERLINE (1<<2) @@ -122,6 +129,21 @@ EXPORT obs_property_t *obs_properties_first(obs_properties_t *props); EXPORT obs_property_t *obs_properties_get(obs_properties_t *props, const char *property); +EXPORT obs_properties_t *obs_properties_get_parent(obs_properties_t *props); + +/** Remove a property from a properties list. + * + * Removes a property from a properties list. Only valid in either + * get_properties or modified_callback(2). modified_callback(2) must return + * true so that all UI properties are rebuilt and returning false is undefined + * behavior. + * + * @param props Properties to remove from. + * @param property Name of the property to remove. + */ +EXPORT void obs_properties_remove_by_name(obs_properties_t *props, + const char *property); + /** * Applies settings to the properties by calling all the necessary * modification callbacks @@ -218,6 +240,11 @@ EXPORT obs_property_t *obs_properties_add_editable_list(obs_properties_t *props, EXPORT obs_property_t *obs_properties_add_frame_rate(obs_properties_t *props, const char *name, const char *description); +EXPORT obs_property_t *obs_properties_add_group(obs_properties_t *props, + const char *name, const char *description, enum obs_group_type type, + obs_properties_t *group); + + /* ------------------------------------------------------------------------- */ /** @@ -259,10 +286,12 @@ EXPORT int obs_property_int_min(obs_property_t *p); EXPORT int obs_property_int_max(obs_property_t *p); EXPORT int obs_property_int_step(obs_property_t *p); EXPORT enum obs_number_type obs_property_int_type(obs_property_t *p); +EXPORT const char * obs_property_int_suffix(obs_property_t *p); EXPORT double obs_property_float_min(obs_property_t *p); EXPORT double obs_property_float_max(obs_property_t *p); EXPORT double obs_property_float_step(obs_property_t *p); EXPORT enum obs_number_type obs_property_float_type(obs_property_t *p); +EXPORT const char * obs_property_float_suffix(obs_property_t *p); EXPORT enum obs_text_type obs_property_text_type(obs_property_t *p); EXPORT enum obs_path_type obs_property_path_type(obs_property_t *p); EXPORT const char * obs_property_path_filter(obs_property_t *p); @@ -274,6 +303,8 @@ EXPORT void obs_property_int_set_limits(obs_property_t *p, int min, int max, int step); EXPORT void obs_property_float_set_limits(obs_property_t *p, double min, double max, double step); +EXPORT void obs_property_int_set_suffix(obs_property_t *p, const char *suffix); +EXPORT void obs_property_float_set_suffix(obs_property_t *p, const char *suffix); EXPORT void obs_property_list_clear(obs_property_t *p); @@ -336,6 +367,9 @@ EXPORT struct media_frames_per_second obs_property_frame_rate_fps_range_min( EXPORT struct media_frames_per_second obs_property_frame_rate_fps_range_max( obs_property_t *p, size_t idx); +EXPORT enum obs_group_type obs_property_group_type(obs_property_t *p); +EXPORT obs_properties_t *obs_property_group_content(obs_property_t *p); + #ifndef SWIG DEPRECATED EXPORT enum obs_text_type obs_proprety_text_type(obs_property_t *p); diff --git a/libobs/obs-scene.c b/libobs/obs-scene.c index a3ba2d8..f23fd49 100644 --- a/libobs/obs-scene.c +++ b/libobs/obs-scene.c @@ -395,6 +395,8 @@ static void update_item_transform(struct obs_scene_item *item, bool update_tex) scale.y = (float)height * item->scale.y; } + item->box_scale = scale; + add_alignment(&base_origin, item->align, (int)scale.x, (int)scale.y); matrix4_identity(&item->box_transform); @@ -462,6 +464,8 @@ static inline bool item_texture_enabled(const struct obs_scene_item *item) static void render_item_texture(struct obs_scene_item *item) { + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_ITEM_TEXTURE, "render_item_texture"); + gs_texture_t *tex = gs_texrender_get_texture(item->item_render); gs_effect_t *effect = obs->video.default_effect; enum obs_scale_type type = item->scale_filter; @@ -486,6 +490,8 @@ static void render_item_texture(struct obs_scene_item *item) effect = obs->video.bicubic_effect; } else if (type == OBS_SCALE_LANCZOS) { effect = obs->video.lanczos_effect; + } else if (type == OBS_SCALE_AREA) { + effect = obs->video.area_effect; } scale_param = gs_effect_get_param_by_name(effect, @@ -501,18 +507,29 @@ static void render_item_texture(struct obs_scene_item *item) } } + gs_blend_state_push(); + gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + while (gs_effect_loop(effect, "Draw")) obs_source_draw(tex, 0, 0, 0, 0, 0); + + gs_blend_state_pop(); + + GS_DEBUG_MARKER_END(); } static inline void render_item(struct obs_scene_item *item) { + GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_ITEM, "Item: %s", + obs_source_get_name(item->source)); + if (item->item_render) { uint32_t width = obs_source_get_width(item->source); uint32_t height = obs_source_get_height(item->source); - if (!width || !height) - return; + if (!width || !height) { + goto cleanup; + } uint32_t cx = calc_cx(item, width); uint32_t cy = calc_cy(item, height); @@ -533,10 +550,8 @@ static inline void render_item(struct obs_scene_item *item) -(float)item->crop.top, 0.0f); - gs_blend_state_push(); - gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO); obs_source_video_render(item->source); - gs_blend_state_pop(); + gs_texrender_end(item->item_render); } } @@ -549,6 +564,9 @@ static inline void render_item(struct obs_scene_item *item) obs_source_video_render(item->source); } gs_matrix_pop(); + +cleanup: + GS_DEBUG_MARKER_END(); } static void scene_video_tick(void *data, float seconds) @@ -748,6 +766,8 @@ static void scene_load_item(struct obs_scene *scene, obs_data_t *item_data) item->scale_filter = OBS_SCALE_BICUBIC; else if (astrcmpi(scale_filter_str, "lanczos") == 0) item->scale_filter = OBS_SCALE_LANCZOS; + else if (astrcmpi(scale_filter_str, "area") == 0) + item->scale_filter = OBS_SCALE_AREA; } if (item->item_render && !item_texture_enabled(item)) { @@ -857,6 +877,8 @@ static void scene_save_item(obs_data_array_t *array, scale_filter = "bicubic"; else if (item->scale_filter == OBS_SCALE_LANCZOS) scale_filter = "lanczos"; + else if (item->scale_filter == OBS_SCALE_AREA) + scale_filter = "area"; else scale_filter = "disable"; @@ -1243,6 +1265,7 @@ static inline void duplicate_item_data(struct obs_scene_item *dst, dst->output_scale = src->output_scale; dst->scale_filter = src->scale_filter; dst->box_transform = src->box_transform; + dst->box_scale = src->box_scale; dst->draw_transform = src->draw_transform; dst->bounds_type = src->bounds_type; dst->bounds_align = src->bounds_align; @@ -2030,6 +2053,13 @@ void obs_sceneitem_get_box_transform(const obs_sceneitem_t *item, matrix4_copy(transform, &item->box_transform); } +void obs_sceneitem_get_box_scale(const obs_sceneitem_t *item, + struct vec2 *scale) +{ + if (item) + *scale = item->box_scale; +} + bool obs_sceneitem_visible(const obs_sceneitem_t *item) { return item ? item->user_visible : false; diff --git a/libobs/obs-scene.h b/libobs/obs-scene.h index 4591db5..6ac57dd 100644 --- a/libobs/obs-scene.h +++ b/libobs/obs-scene.h @@ -65,6 +65,7 @@ struct obs_scene_item { enum obs_scale_type scale_filter; struct matrix4 box_transform; + struct vec2 box_scale; struct matrix4 draw_transform; enum obs_bounds_type bounds_type; diff --git a/libobs/obs-source-deinterlace.c b/libobs/obs-source-deinterlace.c index 1fce870..c3065e9 100644 --- a/libobs/obs-source-deinterlace.c +++ b/libobs/obs-source-deinterlace.c @@ -315,9 +315,6 @@ void deinterlace_render(obs_source_t *s) gs_eparam_t *dimensions = gs_effect_get_param_by_name(effect, "dimensions"); struct vec2 size = {(float)s->async_width, (float)s->async_height}; - bool yuv = format_is_yuv(s->async_format); - bool limited_range = yuv && !s->async_full_range; - const char *tech = yuv ? "DrawMatrix" : "Draw"; gs_texture_t *cur_tex = s->async_texrender ? gs_texrender_get_texture(s->async_texrender) : @@ -334,30 +331,12 @@ void deinterlace_render(obs_source_t *s) gs_effect_set_int(field, s->deinterlace_top_first); gs_effect_set_vec2(dimensions, &size); - if (yuv) { - gs_eparam_t *color_matrix = gs_effect_get_param_by_name( - effect, "color_matrix"); - gs_effect_set_val(color_matrix, s->async_color_matrix, - sizeof(float) * 16); - } - if (limited_range) { - const size_t size = sizeof(float) * 3; - gs_eparam_t *color_range_min = gs_effect_get_param_by_name( - effect, "color_range_min"); - gs_eparam_t *color_range_max = gs_effect_get_param_by_name( - effect, "color_range_max"); - gs_effect_set_val(color_range_min, s->async_color_range_min, - size); - gs_effect_set_val(color_range_max, s->async_color_range_max, - size); - } - frame2_ts = s->deinterlace_frame_ts + s->deinterlace_offset + s->deinterlace_half_duration - TWOX_TOLERANCE; gs_effect_set_bool(frame2, obs->video.video_time >= frame2_ts); - while (gs_effect_loop(effect, tech)) + while (gs_effect_loop(effect, "Draw")) gs_draw_sprite(NULL, s->async_flip ? GS_FLIP_V : 0, s->async_width, s->async_height); } diff --git a/libobs/obs-source-transition.c b/libobs/obs-source-transition.c index 929204f..60db7a6 100644 --- a/libobs/obs-source-transition.c +++ b/libobs/obs-source-transition.c @@ -665,6 +665,11 @@ static inline void handle_stop(obs_source_t *transition) "transition_stop"); } +void obs_transition_force_stop(obs_source_t *transition) +{ + handle_stop(transition); +} + void obs_transition_video_render(obs_source_t *transition, obs_transition_video_render_callback_t callback) { @@ -718,10 +723,16 @@ void obs_transition_video_render(obs_source_t *transition, cx = get_cx(transition); cy = get_cy(transition); - if (cx && cy) + if (cx && cy) { + gs_blend_state_push(); + gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + callback(transition->context.data, tex[0], tex[1], t, cx, cy); + gs_blend_state_pop(); + } + } else if (state.transitioning_audio) { if (state.s[1]) { gs_matrix_push(); diff --git a/libobs/obs-source.c b/libobs/obs-source.c index d77be32..033006a 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -16,6 +16,7 @@ ******************************************************************************/ #include +#include #include "media-io/format-conversion.h" #include "media-io/video-frame.h" @@ -140,6 +141,7 @@ bool obs_source_init(struct obs_source *source) source->user_volume = 1.0f; source->volume = 1.0f; source->sync_offset = 0; + source->balance = 0.5f; pthread_mutex_init_value(&source->filter_mutex); pthread_mutex_init_value(&source->async_mutex); pthread_mutex_init_value(&source->audio_mutex); @@ -1327,15 +1329,21 @@ enum convert_type { CONVERT_420, CONVERT_422_U, CONVERT_422_Y, + CONVERT_444, + CONVERT_800, + CONVERT_RGB_LIMITED, }; -static inline enum convert_type get_convert_type(enum video_format format) +static inline enum convert_type get_convert_type(enum video_format format, + bool full_range) { switch (format) { case VIDEO_FORMAT_I420: return CONVERT_420; case VIDEO_FORMAT_NV12: return CONVERT_NV12; + case VIDEO_FORMAT_I444: + return CONVERT_444; case VIDEO_FORMAT_YVYU: case VIDEO_FORMAT_YUY2: @@ -1344,12 +1352,13 @@ static inline enum convert_type get_convert_type(enum video_format format) return CONVERT_422_U; case VIDEO_FORMAT_Y800: - case VIDEO_FORMAT_I444: + return CONVERT_800; + case VIDEO_FORMAT_NONE: case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: - return CONVERT_NONE; + return full_range ? CONVERT_NONE : CONVERT_RGB_LIMITED; } return CONVERT_NONE; @@ -1358,12 +1367,23 @@ static inline enum convert_type get_convert_type(enum video_format format) static inline bool set_packed422_sizes(struct obs_source *source, const struct obs_source_frame *frame) { - source->async_convert_height = frame->height; source->async_convert_width = frame->width / 2; + source->async_convert_height = frame->height; source->async_texture_format = GS_BGRA; return true; } +static inline bool set_planar444_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width = frame->width; + source->async_convert_height = frame->height * 3; + source->async_texture_format = GS_R8; + source->async_plane_offset[0] = (int)(frame->data[1] - frame->data[0]); + source->async_plane_offset[1] = (int)(frame->data[2] - frame->data[0]); + return true; +} + static inline bool set_planar420_sizes(struct obs_source *source, const struct obs_source_frame *frame) { @@ -1391,10 +1411,28 @@ static inline bool set_nv12_sizes(struct obs_source *source, return true; } +static inline bool set_y800_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width = frame->width; + source->async_convert_height = frame->height; + source->async_texture_format = GS_R8; + return true; +} + +static inline bool set_rgb_limited_sizes(struct obs_source *source, + const struct obs_source_frame *frame) +{ + source->async_convert_width = frame->width; + source->async_convert_height = frame->height; + source->async_texture_format = convert_video_format(frame->format); + return true; +} + static inline bool init_gpu_conversion(struct obs_source *source, const struct obs_source_frame *frame) { - switch (get_convert_type(frame->format)) { + switch (get_convert_type(frame->format, frame->full_range)) { case CONVERT_422_Y: case CONVERT_422_U: return set_packed422_sizes(source, frame); @@ -1404,7 +1442,15 @@ static inline bool init_gpu_conversion(struct obs_source *source, case CONVERT_NV12: return set_nv12_sizes(source, frame); - break; + + case CONVERT_444: + return set_planar444_sizes(source, frame); + + case CONVERT_800: + return set_y800_sizes(source, frame); + + case CONVERT_RGB_LIMITED: + return set_rgb_limited_sizes(source, frame); case CONVERT_NONE: assert(false && "No conversion requested"); @@ -1417,16 +1463,19 @@ static inline bool init_gpu_conversion(struct obs_source *source, bool set_async_texture_size(struct obs_source *source, const struct obs_source_frame *frame) { - enum convert_type cur = get_convert_type(frame->format); + enum convert_type cur = get_convert_type(frame->format, + frame->full_range); - if (source->async_width == frame->width && - source->async_height == frame->height && - source->async_format == frame->format) + if (source->async_width == frame->width && + source->async_height == frame->height && + source->async_format == frame->format && + source->async_full_range == frame->full_range) return true; - source->async_width = frame->width; - source->async_height = frame->height; - source->async_format = frame->format; + source->async_width = frame->width; + source->async_height = frame->height; + source->async_format = frame->format; + source->async_full_range = frame->full_range; gs_enter_context(obs->video.graphics); @@ -1442,8 +1491,10 @@ bool set_async_texture_size(struct obs_source *source, if (cur != CONVERT_NONE && init_gpu_conversion(source, frame)) { source->async_gpu_conversion = true; + enum gs_color_format format = CONVERT_RGB_LIMITED ? + convert_video_format(frame->format) : GS_BGRX; source->async_texrender = - gs_texrender_create(GS_BGRX, GS_ZS_NONE); + gs_texrender_create(format, GS_ZS_NONE); source->async_texture = gs_texture_create( source->async_convert_width, @@ -1472,19 +1523,18 @@ bool set_async_texture_size(struct obs_source *source, static void upload_raw_frame(gs_texture_t *tex, const struct obs_source_frame *frame) { - switch (get_convert_type(frame->format)) { + switch (get_convert_type(frame->format, frame->full_range)) { case CONVERT_422_U: case CONVERT_422_Y: + case CONVERT_800: + case CONVERT_RGB_LIMITED: gs_texture_set_image(tex, frame->data[0], frame->linesize[0], false); break; case CONVERT_420: - gs_texture_set_image(tex, frame->data[0], - frame->width, false); - break; - case CONVERT_NV12: + case CONVERT_444: gs_texture_set_image(tex, frame->data[0], frame->width, false); break; @@ -1495,7 +1545,8 @@ static void upload_raw_frame(gs_texture_t *tex, } } -static const char *select_conversion_technique(enum video_format format) +static const char *select_conversion_technique(enum video_format format, + bool full_range) { switch (format) { case VIDEO_FORMAT_UYVY: @@ -1512,15 +1563,21 @@ static const char *select_conversion_technique(enum video_format format) case VIDEO_FORMAT_NV12: return "NV12_Reverse"; - break; + + case VIDEO_FORMAT_I444: + return "I444_Reverse"; case VIDEO_FORMAT_Y800: + return full_range ? "Y800_Full" : "Y800_Limited"; + case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_NONE: - case VIDEO_FORMAT_I444: - assert(false && "No conversion requested"); + if (full_range) + assert(false && "No conversion requested"); + else + return "RGB_Limited"; break; } return NULL; @@ -1542,6 +1599,8 @@ static bool update_async_texrender(struct obs_source *source, const struct obs_source_frame *frame, gs_texture_t *tex, gs_texrender_t *texrender) { + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_CONVERT_FORMAT, "Convert Format"); + gs_texrender_reset(texrender); upload_raw_frame(tex, frame); @@ -1552,11 +1611,16 @@ static bool update_async_texrender(struct obs_source *source, float convert_width = (float)source->async_convert_width; gs_effect_t *conv = obs->video.conversion_effect; - gs_technique_t *tech = gs_effect_get_technique(conv, - select_conversion_technique(frame->format)); + const char *tech_name = select_conversion_technique(frame->format, + frame->full_range); + gs_technique_t *tech = gs_effect_get_technique(conv, tech_name); - if (!gs_texrender_begin(texrender, cx, cy)) + if (!gs_texrender_begin(texrender, cx, cy)) { + GS_DEBUG_MARKER_END(); return false; + } + + gs_enable_blending(false); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); @@ -1575,6 +1639,19 @@ static bool update_async_texrender(struct obs_source *source, set_eparami(conv, "int_v_plane_offset", (int)source->async_plane_offset[1]); + gs_effect_set_val(gs_effect_get_param_by_name(conv, "color_matrix"), + frame->color_matrix, sizeof(float) * 16); + if (!frame->full_range) { + gs_eparam_t *min_param = gs_effect_get_param_by_name( + conv, "color_range_min"); + gs_effect_set_val(min_param, frame->color_range_min, + sizeof(float) * 3); + gs_eparam_t *max_param = gs_effect_get_param_by_name( + conv, "color_range_max"); + gs_effect_set_val(max_param, frame->color_range_max, + sizeof(float) * 3); + } + gs_ortho(0.f, (float)cx, 0.f, (float)cy, -100.f, 100.f); gs_draw_sprite(tex, 0, cx, cy); @@ -1582,8 +1659,11 @@ static bool update_async_texrender(struct obs_source *source, gs_technique_end_pass(tech); gs_technique_end(tech); + gs_enable_blending(true); + gs_texrender_end(texrender); + GS_DEBUG_MARKER_END(); return true; } @@ -1591,56 +1671,25 @@ bool update_async_texture(struct obs_source *source, const struct obs_source_frame *frame, gs_texture_t *tex, gs_texrender_t *texrender) { - enum convert_type type = get_convert_type(frame->format); - uint8_t *ptr; - uint32_t linesize; + enum convert_type type; source->async_flip = frame->flip; - source->async_full_range = frame->full_range; - memcpy(source->async_color_matrix, frame->color_matrix, - sizeof(frame->color_matrix)); - memcpy(source->async_color_range_min, frame->color_range_min, - sizeof frame->color_range_min); - memcpy(source->async_color_range_max, frame->color_range_max, - sizeof frame->color_range_max); if (source->async_gpu_conversion && texrender) return update_async_texrender(source, frame, tex, texrender); + type = get_convert_type(frame->format, frame->full_range); if (type == CONVERT_NONE) { gs_texture_set_image(tex, frame->data[0], frame->linesize[0], false); return true; } - if (!gs_texture_map(tex, &ptr, &linesize)) - return false; - - if (type == CONVERT_420) - decompress_420((const uint8_t* const*)frame->data, - frame->linesize, - 0, frame->height, ptr, linesize); - - else if (type == CONVERT_NV12) - decompress_nv12((const uint8_t* const*)frame->data, - frame->linesize, - 0, frame->height, ptr, linesize); - - else if (type == CONVERT_422_Y) - decompress_422(frame->data[0], frame->linesize[0], - 0, frame->height, ptr, linesize, true); - - else if (type == CONVERT_422_U) - decompress_422(frame->data[0], frame->linesize[0], - 0, frame->height, ptr, linesize, false); - - gs_texture_unmap(tex); - return true; + return false; } static inline void obs_source_draw_texture(struct obs_source *source, - gs_effect_t *effect, float *color_matrix, - float const *color_range_min, float const *color_range_max) + gs_effect_t *effect) { gs_texture_t *tex = source->async_texture; gs_eparam_t *param; @@ -1648,23 +1697,6 @@ static inline void obs_source_draw_texture(struct obs_source *source, if (source->async_texrender) tex = gs_texrender_get_texture(source->async_texrender); - if (color_range_min) { - size_t const size = sizeof(float) * 3; - param = gs_effect_get_param_by_name(effect, "color_range_min"); - gs_effect_set_val(param, color_range_min, size); - } - - if (color_range_max) { - size_t const size = sizeof(float) * 3; - param = gs_effect_get_param_by_name(effect, "color_range_max"); - gs_effect_set_val(param, color_range_max, size); - } - - if (color_matrix) { - param = gs_effect_get_param_by_name(effect, "color_matrix"); - gs_effect_set_val(param, color_matrix, sizeof(float) * 16); - } - param = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture(param, tex); @@ -1673,24 +1705,18 @@ static inline void obs_source_draw_texture(struct obs_source *source, static void obs_source_draw_async_texture(struct obs_source *source) { - gs_effect_t *effect = gs_get_effect(); - bool yuv = format_is_yuv(source->async_format); - bool limited_range = yuv && !source->async_full_range; - const char *type = yuv ? "DrawMatrix" : "Draw"; + gs_effect_t *effect = gs_get_effect(); bool def_draw = (!effect); - gs_technique_t *tech = NULL; + gs_technique_t *tech = NULL; if (def_draw) { effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); - tech = gs_effect_get_technique(effect, type); + tech = gs_effect_get_technique(effect, "Draw"); gs_technique_begin(tech); gs_technique_begin_pass(tech, 0); } - obs_source_draw_texture(source, effect, - yuv ? source->async_color_matrix : NULL, - limited_range ? source->async_color_range_min : NULL, - limited_range ? source->async_color_range_max : NULL); + obs_source_draw_texture(source, effect); if (def_draw) { gs_technique_end_pass(tech); @@ -1783,6 +1809,24 @@ static inline void obs_source_main_render(obs_source_t *source) static bool ready_async_frame(obs_source_t *source, uint64_t sys_time); +#if GS_USE_DEBUG_MARKERS +static const char *get_type_format(enum obs_source_type type) +{ + switch (type) { + case OBS_SOURCE_TYPE_INPUT: + return "Input: %s"; + case OBS_SOURCE_TYPE_FILTER: + return "Filter: %s"; + case OBS_SOURCE_TYPE_TRANSITION: + return "Transition: %s"; + case OBS_SOURCE_TYPE_SCENE: + return "Scene: %s"; + default: + return "[Unknown]: %s"; + } +} +#endif + static inline void render_video(obs_source_t *source) { if (source->info.type != OBS_SOURCE_TYPE_FILTER && @@ -1806,6 +1850,10 @@ static inline void render_video(obs_source_t *source) return; } + GS_DEBUG_MARKER_BEGIN_FORMAT(GS_DEBUG_COLOR_SOURCE, + get_type_format(source->info.type), + obs_source_get_name(source)); + if (source->filters.num && !source->rendering_filter) obs_source_render_filters(source); @@ -1820,6 +1868,8 @@ static inline void render_video(obs_source_t *source) else obs_source_render_async_video(source); + + GS_DEBUG_MARKER_END(); } void obs_source_video_render(obs_source_t *source) @@ -1835,11 +1885,12 @@ void obs_source_video_render(obs_source_t *source) static uint32_t get_base_width(const obs_source_t *source) { bool is_filter = !!source->filter_parent; + bool func_valid = source->context.data && source->info.get_width; if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) { return source->enabled ? source->transition_actual_cx : 0; - } else if (source->info.get_width && (!is_filter || source->enabled)) { + } else if (func_valid && (!is_filter || source->enabled)) { return source->info.get_width(source->context.data); } else if (is_filter) { @@ -1852,11 +1903,12 @@ static uint32_t get_base_width(const obs_source_t *source) static uint32_t get_base_height(const obs_source_t *source) { bool is_filter = !!source->filter_parent; + bool func_valid = source->context.data && source->info.get_height; if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) { return source->enabled ? source->transition_actual_cy : 0; - } else if (source->info.get_height && (!is_filter || source->enabled)) { + } else if (func_valid && (!is_filter || source->enabled)) { return source->info.get_height(source->context.data); } else if (is_filter) { @@ -2213,41 +2265,6 @@ static inline void copy_frame_data_plane(struct obs_source_frame *dst, dst->linesize[plane] * lines); } -static void copy_frame_data_line_y800(uint32_t *dst, uint8_t *src, uint8_t *end) -{ - while (src < end) { - register uint32_t val = *(src++); - val |= (val << 8); - val |= (val << 16); - *(dst++) = val; - } -} - -static inline void copy_frame_data_y800(struct obs_source_frame *dst, - const struct obs_source_frame *src) -{ - uint32_t *ptr_dst; - uint8_t *ptr_src; - uint8_t *src_end; - - if ((src->linesize[0] * 4) != dst->linesize[0]) { - for (uint32_t cy = 0; cy < src->height; cy++) { - ptr_dst = (uint32_t*) - (dst->data[0] + cy * dst->linesize[0]); - ptr_src = (src->data[0] + cy * src->linesize[0]); - src_end = ptr_src + src->width; - - copy_frame_data_line_y800(ptr_dst, ptr_src, src_end); - } - } else { - ptr_dst = (uint32_t*)dst->data[0]; - ptr_src = (uint8_t *)src->data[0]; - src_end = ptr_src + src->height * src->linesize[0]; - - copy_frame_data_line_y800(ptr_dst, ptr_src, src_end); - } -} - static void copy_frame_data(struct obs_source_frame *dst, const struct obs_source_frame *src) { @@ -2286,11 +2303,8 @@ static void copy_frame_data(struct obs_source_frame *dst, case VIDEO_FORMAT_RGBA: case VIDEO_FORMAT_BGRA: case VIDEO_FORMAT_BGRX: - copy_frame_data_plane(dst, src, 0, dst->height); - break; - case VIDEO_FORMAT_Y800: - copy_frame_data_y800(dst, src); + copy_frame_data_plane(dst, src, 0, dst->height); break; } } @@ -2305,8 +2319,9 @@ static inline bool async_texture_changed(struct obs_source *source, const struct obs_source_frame *frame) { enum convert_type prev, cur; - prev = get_convert_type(source->async_cache_format); - cur = get_convert_type(frame->format); + prev = get_convert_type(source->async_cache_format, + source->async_cache_full_range); + cur = get_convert_type(frame->format, frame->full_range); return source->async_cache_width != frame->width || source->async_cache_height != frame->height || @@ -2342,7 +2357,7 @@ static void clean_cache(obs_source_t *source) } #define MAX_ASYNC_FRAMES 30 - +//if return value is not null then do (os_atomic_dec_long(&output->refs) == 0) && obs_source_frame_destroy(output) static inline struct obs_source_frame *cache_video(struct obs_source *source, const struct obs_source_frame *frame) { @@ -2359,9 +2374,10 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, if (async_texture_changed(source, frame)) { free_async_cache(source); - source->async_cache_width = frame->width; - source->async_cache_height = frame->height; - source->async_cache_format = frame->format; + source->async_cache_width = frame->width; + source->async_cache_height = frame->height; + source->async_cache_format = frame->format; + source->async_cache_full_range = frame->full_range; } for (size_t i = 0; i < source->async_cache.num; i++) { @@ -2380,9 +2396,6 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, struct async_frame new_af; enum video_format format = frame->format; - if (format == VIDEO_FORMAT_Y800) - format = VIDEO_FORMAT_BGRX; - new_frame = obs_source_frame_create(format, frame->width, frame->height); new_af.frame = new_frame; @@ -2399,15 +2412,10 @@ static inline struct obs_source_frame *cache_video(struct obs_source *source, copy_frame_data(new_frame, frame); - if (os_atomic_dec_long(&new_frame->refs) == 0) { - obs_source_frame_destroy(new_frame); - new_frame = NULL; - } - return new_frame; } -void obs_source_output_video(obs_source_t *source, +static void obs_source_output_video_internal(obs_source_t *source, const struct obs_source_frame *frame) { if (!obs_source_valid(source, "obs_source_output_video")) @@ -2422,13 +2430,67 @@ void obs_source_output_video(obs_source_t *source, cache_video(source, frame) : NULL; /* ------------------------------------------- */ - + pthread_mutex_lock(&source->async_mutex); if (output) { - pthread_mutex_lock(&source->async_mutex); - da_push_back(source->async_frames, &output); - pthread_mutex_unlock(&source->async_mutex); - source->async_active = true; + if (os_atomic_dec_long(&output->refs) == 0) { + obs_source_frame_destroy(output); + output = NULL; + } else { + da_push_back(source->async_frames, &output); + source->async_active = true; + } } + pthread_mutex_unlock(&source->async_mutex); +} + +void obs_source_output_video(obs_source_t *source, + const struct obs_source_frame *frame) +{ + if (!frame) { + obs_source_output_video_internal(source, NULL); + return; + } + + struct obs_source_frame new_frame = *frame; + new_frame.full_range = format_is_yuv(frame->format) + ? new_frame.full_range + : true; + + obs_source_output_video_internal(source, &new_frame); +} + +void obs_source_output_video2(obs_source_t *source, + const struct obs_source_frame2 *frame) +{ + if (!frame) { + obs_source_output_video_internal(source, NULL); + return; + } + + struct obs_source_frame new_frame; + enum video_range_type range = resolve_video_range(frame->format, + frame->range); + + for (size_t i = 0; i < MAX_AV_PLANES; i++) { + new_frame.data[i] = frame->data[i]; + new_frame.linesize[i] = frame->linesize[i]; + } + + new_frame.width = frame->width; + new_frame.height = frame->height; + new_frame.timestamp = frame->timestamp; + new_frame.format = frame->format; + new_frame.full_range = range == VIDEO_RANGE_FULL; + new_frame.flip = frame->flip; + + memcpy(&new_frame.color_matrix, &frame->color_matrix, + sizeof(frame->color_matrix)); + memcpy(&new_frame.color_range_min, &frame->color_range_min, + sizeof(frame->color_range_min)); + memcpy(&new_frame.color_range_max, &frame->color_range_max, + sizeof(frame->color_range_max)); + + obs_source_output_video_internal(source, &new_frame); } static inline bool preload_frame_changed(obs_source_t *source, @@ -2442,7 +2504,7 @@ static inline bool preload_frame_changed(obs_source_t *source, in->format != source->async_preload_frame->format; } -void obs_source_preload_video(obs_source_t *source, +static void obs_source_preload_video_internal(obs_source_t *source, const struct obs_source_frame *frame) { if (!obs_source_valid(source, "obs_source_preload_video")) @@ -2471,6 +2533,56 @@ void obs_source_preload_video(obs_source_t *source, obs_leave_graphics(); } +void obs_source_preload_video(obs_source_t *source, + const struct obs_source_frame *frame) +{ + if (!frame) { + obs_source_preload_video_internal(source, NULL); + return; + } + + struct obs_source_frame new_frame = *frame; + new_frame.full_range = format_is_yuv(frame->format) + ? new_frame.full_range + : true; + + obs_source_preload_video_internal(source, &new_frame); +} + +void obs_source_preload_video2(obs_source_t *source, + const struct obs_source_frame2 *frame) +{ + if (!frame) { + obs_source_preload_video_internal(source, NULL); + return; + } + + struct obs_source_frame new_frame; + enum video_range_type range = resolve_video_range(frame->format, + frame->range); + + for (size_t i = 0; i < MAX_AV_PLANES; i++) { + new_frame.data[i] = frame->data[i]; + new_frame.linesize[i] = frame->linesize[i]; + } + + new_frame.width = frame->width; + new_frame.height = frame->height; + new_frame.timestamp = frame->timestamp; + new_frame.format = frame->format; + new_frame.full_range = range == VIDEO_RANGE_FULL; + new_frame.flip = frame->flip; + + memcpy(&new_frame.color_matrix, &frame->color_matrix, + sizeof(frame->color_matrix)); + memcpy(&new_frame.color_range_min, &frame->color_range_min, + sizeof(frame->color_range_min)); + memcpy(&new_frame.color_range_max, &frame->color_range_max, + sizeof(frame->color_range_max)); + + obs_source_preload_video_internal(source, &new_frame); +} + void obs_source_show_preloaded_video(obs_source_t *source) { uint64_t sys_ts; @@ -2481,7 +2593,9 @@ void obs_source_show_preloaded_video(obs_source_t *source) source->async_active = true; pthread_mutex_lock(&source->audio_buf_mutex); - sys_ts = os_gettime_ns(); + sys_ts = (source->monitoring_type != OBS_MONITORING_TYPE_MONITOR_ONLY) + ? os_gettime_ns() + : 0; reset_audio_timing(source, source->last_frame_ts, sys_ts); reset_audio_data(source, sys_ts); pthread_mutex_unlock(&source->audio_buf_mutex); @@ -2589,6 +2703,37 @@ static void downmix_to_mono_planar(struct obs_source *source, uint32_t frames) } } +static void process_audio_balancing(struct obs_source *source, uint32_t frames, + float balance, enum obs_balance_type type) +{ + float **data = (float**)source->audio_data.data; + + switch(type) { + case OBS_BALANCE_TYPE_SINE_LAW: + for (uint32_t frame = 0; frame < frames; frame++) { + data[0][frame] = data[0][frame] * + sinf((1.0f - balance) * (M_PI/2.0f)); + data[1][frame] = data[1][frame] * + sinf(balance * (M_PI/2.0f)); + } + break; + case OBS_BALANCE_TYPE_SQUARE_LAW: + for (uint32_t frame = 0; frame < frames; frame++) { + data[0][frame] = data[0][frame] * sqrtf(1.0f - balance); + data[1][frame] = data[1][frame] * sqrtf(balance); + } + break; + case OBS_BALANCE_TYPE_LINEAR: + for (uint32_t frame = 0; frame < frames; frame++) { + data[0][frame] = data[0][frame] * (1.0f - balance); + data[1][frame] = data[1][frame] * balance; + } + break; + default: + break; + } +} + /* resamples/remixes new audio to the designated main audio output format */ static void process_audio(obs_source_t *source, const struct obs_source_audio *audio) @@ -2622,6 +2767,12 @@ static void process_audio(obs_source_t *source, mono_output = audio_output_get_channels(obs->audio.audio) == 1; + if (!mono_output && source->sample_info.speakers == SPEAKERS_STEREO && + (source->balance > 0.51f || source->balance < 0.49f)) { + process_audio_balancing(source, frames, source->balance, + OBS_BALANCE_TYPE_SINE_LAW); + } + if (!mono_output && (source->flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0) downmix_to_mono_planar(source, frames); } @@ -3503,12 +3654,25 @@ void obs_source_inc_showing(obs_source_t *source) obs_source_activate(source, AUX_VIEW); } +void obs_source_inc_active(obs_source_t *source) +{ + if (obs_source_valid(source, "obs_source_inc_active")) + obs_source_activate(source, MAIN_VIEW); +} + void obs_source_dec_showing(obs_source_t *source) { if (obs_source_valid(source, "obs_source_dec_showing")) obs_source_deactivate(source, AUX_VIEW); } +void obs_source_dec_active(obs_source_t *source) +{ + if (obs_source_valid(source, "obs_source_dec_active")) + obs_source_deactivate(source, MAIN_VIEW); +} + + void obs_source_enum_filters(obs_source_t *source, obs_source_enum_proc_t callback, void *param) { @@ -4165,3 +4329,25 @@ EXPORT void obs_enable_source_type(const char *name, bool enable) else info->output_flags |= OBS_SOURCE_CAP_DISABLED; } + +enum speaker_layout obs_source_get_speaker_layout(obs_source_t *source) +{ + if (!obs_source_valid(source, "obs_source_get_audio_channels")) + return SPEAKERS_UNKNOWN; + + return source->sample_info.speakers; +} + +void obs_source_set_balance_value(obs_source_t *source, float balance) +{ + if (!obs_source_valid(source, "obs_source_set_balance_value")) + return; + + source->balance = balance; +} + +float obs_source_get_balance_value(const obs_source_t *source) +{ + return obs_source_valid(source, "obs_source_get_balance_value") ? + source->balance : 0.5f; +} diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 04215e9..fdda90d 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -38,6 +38,11 @@ enum obs_source_type { OBS_SOURCE_TYPE_SCENE, }; +enum obs_balance_type { + OBS_BALANCE_TYPE_SINE_LAW, + OBS_BALANCE_TYPE_SQUARE_LAW, + OBS_BALANCE_TYPE_LINEAR, +}; /** * @name Source output flags diff --git a/libobs/obs-video-gpu-encode.c b/libobs/obs-video-gpu-encode.c new file mode 100644 index 0000000..aca8dfd --- /dev/null +++ b/libobs/obs-video-gpu-encode.c @@ -0,0 +1,228 @@ +/****************************************************************************** + Copyright (C) 2018 by Hugh Bailey + + 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, see . +******************************************************************************/ + +#include "obs-internal.h" + +static void *gpu_encode_thread(void *unused) +{ + struct obs_core_video *video = &obs->video; + uint64_t interval = video_output_get_frame_time(obs->video.video); + DARRAY(obs_encoder_t *) encoders; + int wait_frames = NUM_ENCODE_TEXTURE_FRAMES_TO_WAIT; + + UNUSED_PARAMETER(unused); + da_init(encoders); + + os_set_thread_name("obs gpu encode thread"); + + while (os_sem_wait(video->gpu_encode_semaphore) == 0) { + struct obs_tex_frame tf; + uint64_t timestamp; + uint64_t lock_key; + uint64_t next_key; + size_t lock_count = 0; + + if (os_atomic_load_bool(&video->gpu_encode_stop)) + break; + + if (wait_frames) { + wait_frames--; + continue; + } + + os_event_reset(video->gpu_encode_inactive); + + /* -------------- */ + + pthread_mutex_lock(&video->gpu_encoder_mutex); + + circlebuf_pop_front(&video->gpu_encoder_queue, &tf, sizeof(tf)); + timestamp = tf.timestamp; + lock_key = tf.lock_key; + next_key = tf.lock_key; + + video_output_inc_texture_frames(video->video); + + for (size_t i = 0; i < video->gpu_encoders.num; i++) { + obs_encoder_t *encoder = video->gpu_encoders.array[i]; + da_push_back(encoders, &encoder); + obs_encoder_addref(encoder); + } + + pthread_mutex_unlock(&video->gpu_encoder_mutex); + + /* -------------- */ + + for (size_t i = 0; i < encoders.num; i++) { + struct encoder_packet pkt = {0}; + bool received = false; + bool success; + + obs_encoder_t *encoder = encoders.array[i]; + struct obs_encoder *pair = encoder->paired_encoder; + + pkt.timebase_num = encoder->timebase_num; + pkt.timebase_den = encoder->timebase_den; + pkt.encoder = encoder; + + if (!encoder->first_received && pair) { + if (!pair->first_received || + pair->first_raw_ts > timestamp) { + continue; + } + } + + if (!encoder->start_ts) + encoder->start_ts = timestamp; + + if (++lock_count == encoders.num) + next_key = 0; + else + next_key++; + + success = encoder->info.encode_texture( + encoder->context.data, tf.handle, + encoder->cur_pts, lock_key, &next_key, + &pkt, &received); + send_off_encoder_packet(encoder, success, received, + &pkt); + + lock_key = next_key; + + encoder->cur_pts += encoder->timebase_num; + } + + /* -------------- */ + + pthread_mutex_lock(&video->gpu_encoder_mutex); + + tf.lock_key = next_key; + + if (--tf.count) { + tf.timestamp += interval; + circlebuf_push_front(&video->gpu_encoder_queue, + &tf, sizeof(tf)); + + video_output_inc_texture_skipped_frames(video->video); + } else { + circlebuf_push_back( + &video->gpu_encoder_avail_queue, + &tf, sizeof(tf)); + } + + pthread_mutex_unlock(&video->gpu_encoder_mutex); + + /* -------------- */ + + os_event_signal(video->gpu_encode_inactive); + + for (size_t i = 0; i < encoders.num; i++) + obs_encoder_release(encoders.array[i]); + + da_resize(encoders, 0); + } + + da_free(encoders); + return NULL; +} + +bool init_gpu_encoding(struct obs_core_video *video) +{ +#ifdef _WIN32 + struct obs_video_info *ovi = &video->ovi; + + video->gpu_encode_stop = false; + + circlebuf_reserve(&video->gpu_encoder_avail_queue, NUM_ENCODE_TEXTURES); + for (size_t i = 0; i < NUM_ENCODE_TEXTURES; i++) { + gs_texture_t *tex; + gs_texture_t *tex_uv; + + gs_texture_create_nv12( + &tex, &tex_uv, + ovi->output_width, ovi->output_height, + GS_RENDER_TARGET | GS_SHARED_KM_TEX); + if (!tex) { + return false; + } + + uint32_t handle = gs_texture_get_shared_handle(tex); + + struct obs_tex_frame frame = { + .tex = tex, + .tex_uv = tex_uv, + .handle = handle + }; + + circlebuf_push_back(&video->gpu_encoder_avail_queue, &frame, + sizeof(frame)); + } + + if (os_sem_init(&video->gpu_encode_semaphore, 0) != 0) + return false; + if (os_event_init(&video->gpu_encode_inactive, OS_EVENT_TYPE_MANUAL) != 0) + return false; + if (pthread_create(&video->gpu_encode_thread, NULL, + gpu_encode_thread, NULL) != 0) + return false; + + os_event_signal(video->gpu_encode_inactive); + + video->gpu_encode_thread_initialized = true; + return true; +#else + UNUSED_PARAMETER(video); + return false; +#endif +} + +void stop_gpu_encoding_thread(struct obs_core_video *video) +{ + if (video->gpu_encode_thread_initialized) { + os_atomic_set_bool(&video->gpu_encode_stop, true); + os_sem_post(video->gpu_encode_semaphore); + pthread_join(video->gpu_encode_thread, NULL); + video->gpu_encode_thread_initialized = false; + } +} + +void free_gpu_encoding(struct obs_core_video *video) +{ + if (video->gpu_encode_semaphore) { + os_sem_destroy(video->gpu_encode_semaphore); + video->gpu_encode_semaphore = NULL; + } + if (video->gpu_encode_inactive) { + os_event_destroy(video->gpu_encode_inactive); + video->gpu_encode_inactive = NULL; + } + +#define free_circlebuf(x) \ + do { \ + while (x.size) { \ + struct obs_tex_frame frame; \ + circlebuf_pop_front(&x, &frame, sizeof(frame)); \ + gs_texture_destroy(frame.tex); \ + gs_texture_destroy(frame.tex_uv); \ + } \ + circlebuf_free(&x); \ + } while (false) + + free_circlebuf(video->gpu_encoder_queue); + free_circlebuf(video->gpu_encoder_avail_queue); +#undef free_circlebuf +} diff --git a/libobs/obs-video.c b/libobs/obs-video.c index aaae79a..4df10d0 100644 --- a/libobs/obs-video.c +++ b/libobs/obs-video.c @@ -58,8 +58,13 @@ static uint64_t tick_sources(uint64_t cur_time, uint64_t last_time) source = data->first_source; while (source) { - obs_source_video_tick(source, seconds); + struct obs_source *cur_source = obs_source_get_ref(source); source = (struct obs_source*)source->context.next; + + if (cur_source) { + obs_source_video_tick(cur_source, seconds); + obs_source_release(cur_source); + } } pthread_mutex_unlock(&data->sources_mutex); @@ -115,9 +120,11 @@ static inline void render_main_texture(struct obs_core_video *video, int cur_texture) { profile_start(render_main_texture_name); + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_MAIN_TEXTURE, + render_main_texture_name); struct vec4 clear_color; - vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 1.0f); + vec4_set(&clear_color, 0.0f, 0.0f, 0.0f, 0.0f); gs_set_render_target(video->render_textures[cur_texture], NULL); gs_clear(GS_CLEAR_COLOR, &clear_color, 1.0f, 0); @@ -140,6 +147,7 @@ static inline void render_main_texture(struct obs_core_video *video, video->textures_rendered[cur_texture] = true; + GS_DEBUG_MARKER_END(); profile_end(render_main_texture_name); } @@ -207,7 +215,14 @@ static inline void render_output_texture(struct obs_core_video *video, 1.0f / (float)video->base_height); gs_effect_t *effect = get_scale_effect(video, width, height); - gs_technique_t *tech = gs_effect_get_technique(effect, "DrawMatrix"); + gs_technique_t *tech; + + if (video->ovi.output_format == VIDEO_FORMAT_RGBA) { + tech = gs_effect_get_technique(effect, "DrawAlphaDivide"); + } else { + tech = gs_effect_get_technique(effect, "DrawMatrix"); + } + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); gs_eparam_t *matrix = gs_effect_get_param_by_name(effect, "color_matrix"); @@ -303,6 +318,57 @@ end: profile_end(render_convert_texture_name); } +static void render_nv12(struct obs_core_video *video, gs_texture_t *target, + int cur_texture, int prev_texture, const char *tech_name, + uint32_t width, uint32_t height) +{ + gs_texture_t *texture = video->output_textures[prev_texture]; + + gs_effect_t *effect = video->conversion_effect; + gs_eparam_t *image = gs_effect_get_param_by_name(effect, "image"); + gs_technique_t *tech = gs_effect_get_technique(effect, tech_name); + size_t passes, i; + + gs_effect_set_texture(image, texture); + + gs_set_render_target(target, NULL); + set_render_size(width, height); + + gs_enable_blending(false); + passes = gs_technique_begin(tech); + for (i = 0; i < passes; i++) { + gs_technique_begin_pass(tech, i); + gs_draw_sprite(texture, 0, width, height); + gs_technique_end_pass(tech); + } + gs_technique_end(tech); + gs_enable_blending(true); + + UNUSED_PARAMETER(cur_texture); +} + +static const char *render_convert_nv12_name = "render_convert_texture_nv12"; +static void render_convert_texture_nv12(struct obs_core_video *video, + int cur_texture, int prev_texture) +{ + profile_start(render_convert_nv12_name); + + if (!video->textures_output[prev_texture]) + goto end; + + render_nv12(video, video->convert_textures[cur_texture], + cur_texture, prev_texture, "NV12_Y", + video->output_width, video->output_height); + render_nv12(video, video->convert_uv_textures[cur_texture], + cur_texture, prev_texture, "NV12_UV", + video->output_width / 2, video->output_height / 2); + + video->textures_converted[cur_texture] = true; + +end: + profile_end(render_convert_nv12_name); +} + static const char *stage_output_texture_name = "stage_output_texture"; static inline void stage_output_texture(struct obs_core_video *video, int cur_texture, int prev_texture) @@ -334,7 +400,100 @@ end: profile_end(stage_output_texture_name); } -static inline void render_video(struct obs_core_video *video, bool raw_active, +#ifdef _WIN32 +static inline bool queue_frame(struct obs_core_video *video, bool raw_active, + struct obs_vframe_info *vframe_info, int prev_texture) +{ + bool duplicate = !video->gpu_encoder_avail_queue.size || + (video->gpu_encoder_queue.size && vframe_info->count > 1); + + if (duplicate) { + struct obs_tex_frame *tf = circlebuf_data( + &video->gpu_encoder_queue, + video->gpu_encoder_queue.size - sizeof(*tf)); + + /* texture-based encoding is stopping */ + if (!tf) { + return false; + } + + tf->count++; + os_sem_post(video->gpu_encode_semaphore); + goto finish; + } + + struct obs_tex_frame tf; + circlebuf_pop_front(&video->gpu_encoder_avail_queue, &tf, sizeof(tf)); + + if (tf.released) { + gs_texture_acquire_sync(tf.tex, tf.lock_key, GS_WAIT_INFINITE); + tf.released = false; + } + + /* the vframe_info->count > 1 case causing a copy can only happen if by + * some chance the very first frame has to be duplicated for whatever + * reason. otherwise, it goes to the 'duplicate' case above, which + * will ensure better performance. */ + if (raw_active || vframe_info->count > 1) { + gs_copy_texture(tf.tex, video->convert_textures[prev_texture]); + } else { + gs_texture_t *tex = video->convert_textures[prev_texture]; + gs_texture_t *tex_uv = video->convert_uv_textures[prev_texture]; + + video->convert_textures[prev_texture] = tf.tex; + video->convert_uv_textures[prev_texture] = tf.tex_uv; + + tf.tex = tex; + tf.tex_uv = tex_uv; + } + + tf.count = 1; + tf.timestamp = vframe_info->timestamp; + tf.released = true; + tf.handle = gs_texture_get_shared_handle(tf.tex); + gs_texture_release_sync(tf.tex, ++tf.lock_key); + circlebuf_push_back(&video->gpu_encoder_queue, &tf, sizeof(tf)); + + os_sem_post(video->gpu_encode_semaphore); + +finish: + return --vframe_info->count; +} + +extern void full_stop(struct obs_encoder *encoder); + +static inline void encode_gpu(struct obs_core_video *video, bool raw_active, + struct obs_vframe_info *vframe_info, int prev_texture) +{ + while (queue_frame(video, raw_active, vframe_info, prev_texture)); +} + +static const char *output_gpu_encoders_name = "output_gpu_encoders"; +static void output_gpu_encoders(struct obs_core_video *video, bool raw_active, + int prev_texture) +{ + profile_start(output_gpu_encoders_name); + + if (!video->textures_converted[prev_texture]) + goto end; + if (!video->vframe_info_buffer_gpu.size) + goto end; + + struct obs_vframe_info vframe_info; + circlebuf_pop_front(&video->vframe_info_buffer_gpu, &vframe_info, + sizeof(vframe_info)); + + pthread_mutex_lock(&video->gpu_encoder_mutex); + encode_gpu(video, raw_active, &vframe_info, prev_texture); + pthread_mutex_unlock(&video->gpu_encoder_mutex); + +end: + profile_end(output_gpu_encoders_name); +} +#endif + +static inline void render_video(struct obs_core_video *video, + bool raw_active, const bool gpu_active, int cur_texture, int prev_texture) { gs_begin_scene(); @@ -344,12 +503,34 @@ static inline void render_video(struct obs_core_video *video, bool raw_active, render_main_texture(video, cur_texture); - if (raw_active) { + if (raw_active || gpu_active) { render_output_texture(video, cur_texture, prev_texture); - if (video->gpu_conversion) - render_convert_texture(video, cur_texture, prev_texture); - stage_output_texture(video, cur_texture, prev_texture); +#ifdef _WIN32 + if (gpu_active) { + gs_flush(); + } +#endif + } + + if (raw_active || gpu_active) { + if (video->gpu_conversion) { + if (video->using_nv12_tex) + render_convert_texture_nv12(video, + cur_texture, prev_texture); + else + render_convert_texture(video, + cur_texture, prev_texture); + } + +#ifdef _WIN32 + if (gpu_active) { + gs_flush(); + output_gpu_encoders(video, raw_active, prev_texture); + } +#endif + if (raw_active) + stage_output_texture(video, cur_texture, prev_texture); } gs_set_render_target(NULL, NULL); @@ -448,6 +629,25 @@ static void set_gpu_converted_data(struct obs_core_video *video, video_frame_copy(output, &frame, info->format, info->height); + } else if (video->using_nv12_tex) { + size_t width = info->width; + size_t height = info->height; + size_t height_d2 = height / 2; + uint8_t *out_y = output->data[0]; + uint8_t *out_uv = output->data[1]; + uint8_t *in = input->data[0]; + + for (size_t y = 0; y < height; y++) { + memcpy(out_y, in, width); + out_y += output->linesize[0]; + in += input->linesize[0]; + } + for (size_t y = 0; y < height_d2; y++) { + memcpy(out_uv, in, width); + out_uv += output->linesize[0]; + in += input->linesize[0]; + } + } else { fix_gpu_converted_alignment(video, output, input); } @@ -525,7 +725,8 @@ static inline void output_video_data(struct obs_core_video *video, } } -static inline void video_sleep(struct obs_core_video *video, bool active, +static inline void video_sleep(struct obs_core_video *video, + bool raw_active, const bool gpu_active, uint64_t *p_time, uint64_t interval_ns) { struct obs_vframe_info vframe_info; @@ -546,9 +747,13 @@ static inline void video_sleep(struct obs_core_video *video, bool active, vframe_info.timestamp = cur_time; vframe_info.count = count; - if (active) + + if (raw_active) circlebuf_push_back(&video->vframe_info_buffer, &vframe_info, sizeof(vframe_info)); + if (gpu_active) + circlebuf_push_back(&video->vframe_info_buffer_gpu, + &vframe_info, sizeof(vframe_info)); } static const char *output_frame_gs_context_name = "gs_context(video->graphics)"; @@ -556,13 +761,13 @@ static const char *output_frame_render_video_name = "render_video"; static const char *output_frame_download_frame_name = "download_frame"; static const char *output_frame_gs_flush_name = "gs_flush"; static const char *output_frame_output_video_data_name = "output_video_data"; -static inline void output_frame(bool raw_active) +static inline void output_frame(bool raw_active, const bool gpu_active) { struct obs_core_video *video = &obs->video; int cur_texture = video->cur_texture; int prev_texture = cur_texture == 0 ? NUM_TEXTURES-1 : cur_texture-1; struct video_data frame; - bool frame_ready; + bool frame_ready = 0; memset(&frame, 0, sizeof(struct video_data)); @@ -570,7 +775,10 @@ static inline void output_frame(bool raw_active) gs_enter_context(video->graphics); profile_start(output_frame_render_video_name); - render_video(video, raw_active, cur_texture, prev_texture); + GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_RENDER_VIDEO, + output_frame_render_video_name); + render_video(video, raw_active, gpu_active, cur_texture, prev_texture); + GS_DEBUG_MARKER_END(); profile_end(output_frame_render_video_name); if (raw_active) { @@ -603,17 +811,31 @@ static inline void output_frame(bool raw_active) #define NBSP "\xC2\xA0" -static void clear_frame_data(void) +static void clear_base_frame_data(void) { struct obs_core_video *video = &obs->video; memset(video->textures_rendered, 0, sizeof(video->textures_rendered)); memset(video->textures_output, 0, sizeof(video->textures_output)); - memset(video->textures_copied, 0, sizeof(video->textures_copied)); memset(video->textures_converted, 0, sizeof(video->textures_converted)); circlebuf_free(&video->vframe_info_buffer); video->cur_texture = 0; } +static void clear_raw_frame_data(void) +{ + struct obs_core_video *video = &obs->video; + memset(video->textures_copied, 0, sizeof(video->textures_copied)); + circlebuf_free(&video->vframe_info_buffer); +} + +#ifdef _WIN32 +static void clear_gpu_frame_data(void) +{ + struct obs_core_video *video = &obs->video; + circlebuf_free(&video->vframe_info_buffer_gpu); +} +#endif + static const char *tick_sources_name = "tick_sources"; static const char *render_displays_name = "render_displays"; static const char *output_frame_name = "output_frame"; @@ -624,7 +846,11 @@ void *obs_graphics_thread(void *param) uint64_t frame_time_total_ns = 0; uint64_t fps_total_ns = 0; uint32_t fps_total_frames = 0; +#ifdef _WIN32 + bool gpu_was_active = false; +#endif bool raw_was_active = false; + bool was_active = false; obs->video.video_time = os_gettime_ns(); @@ -641,10 +867,26 @@ void *obs_graphics_thread(void *param) uint64_t frame_start = os_gettime_ns(); uint64_t frame_time_ns; bool raw_active = obs->video.raw_active > 0; +#ifdef _WIN32 + const bool gpu_active = obs->video.gpu_encoder_active > 0; + const bool active = raw_active || gpu_active; +#else + const bool gpu_active = 0; + const bool active = raw_active; +#endif + if (!was_active && active) + clear_base_frame_data(); if (!raw_was_active && raw_active) - clear_frame_data(); + clear_raw_frame_data(); +#ifdef _WIN32 + if (!gpu_was_active && gpu_active) + clear_gpu_frame_data(); + + gpu_was_active = gpu_active; +#endif raw_was_active = raw_active; + was_active = active; profile_start(video_thread_name); @@ -653,7 +895,7 @@ void *obs_graphics_thread(void *param) profile_end(tick_sources_name); profile_start(output_frame_name); - output_frame(raw_active); + output_frame(raw_active, gpu_active); profile_end(output_frame_name); profile_start(render_displays_name); @@ -666,8 +908,8 @@ void *obs_graphics_thread(void *param) profile_reenable_thread(); - video_sleep(&obs->video, raw_active, &obs->video.video_time, - interval); + video_sleep(&obs->video, raw_active, gpu_active, + &obs->video.video_time, interval); frame_time_total_ns += frame_time_ns; fps_total_ns += (obs->video.video_time - last_time); diff --git a/libobs/obs-windows.c b/libobs/obs-windows.c index e6bbcb0..d2a5bde 100644 --- a/libobs/obs-windows.c +++ b/libobs/obs-windows.c @@ -82,7 +82,7 @@ static void log_processor_info(void) DWORD size, speed; LSTATUS status; - memset(data, 0, 1024); + memset(data, 0, sizeof(data)); status = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", @@ -90,7 +90,7 @@ static void log_processor_info(void) if (status != ERROR_SUCCESS) return; - size = 1024; + size = sizeof(data); status = RegQueryValueExW(key, L"ProcessorNameString", NULL, NULL, (LPBYTE)data, &size); if (status == ERROR_SUCCESS) { @@ -220,6 +220,10 @@ static void log_gaming_features(void) L"HistoricalCaptureEnabled", &game_dvr_bg_recording); get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_MODE_REG_KEY, L"AllowAutoGameMode", &game_mode_enabled); + if (game_mode_enabled.status != ERROR_SUCCESS) { + get_reg_dword(HKEY_CURRENT_USER, WIN10_GAME_MODE_REG_KEY, + L"AutoGameModeEnabled", &game_mode_enabled); + } blog(LOG_INFO, "Windows 10 Gaming Features:"); if (game_bar_enabled.status == ERROR_SUCCESS) { diff --git a/libobs/obs.c b/libobs/obs.c index acd51bb..acefb3e 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -164,17 +164,42 @@ static bool obs_init_gpu_conversion(struct obs_video_info *ovi) calc_gpu_conversion_sizes(ovi); + video->using_nv12_tex = ovi->output_format == VIDEO_FORMAT_NV12 + ? gs_nv12_available() : false; + if (!video->conversion_height) { blog(LOG_INFO, "GPU conversion not available for format: %u", (unsigned int)ovi->output_format); video->gpu_conversion = false; + video->using_nv12_tex = false; + blog(LOG_INFO, "NV12 texture support not available"); return true; } + if (video->using_nv12_tex) + blog(LOG_INFO, "NV12 texture support enabled"); + else + blog(LOG_INFO, "NV12 texture support not available"); + for (size_t i = 0; i < NUM_TEXTURES; i++) { - video->convert_textures[i] = gs_texture_create( - ovi->output_width, video->conversion_height, - GS_RGBA, 1, NULL, GS_RENDER_TARGET); +#ifdef _WIN32 + if (video->using_nv12_tex) { + gs_texture_create_nv12( + &video->convert_textures[i], + &video->convert_uv_textures[i], + ovi->output_width, ovi->output_height, + GS_RENDER_TARGET | GS_SHARED_KM_TEX); + if (!video->convert_uv_textures[i]) + return false; + } else { +#endif + video->convert_textures[i] = gs_texture_create( + ovi->output_width, + video->conversion_height, + GS_RGBA, 1, NULL, GS_RENDER_TARGET); +#ifdef _WIN32 + } +#endif if (!video->convert_textures[i]) return false; @@ -191,11 +216,23 @@ static bool obs_init_textures(struct obs_video_info *ovi) size_t i; for (i = 0; i < NUM_TEXTURES; i++) { - video->copy_surfaces[i] = gs_stagesurface_create( - ovi->output_width, output_height, GS_RGBA); +#ifdef _WIN32 + if (video->using_nv12_tex) { + video->copy_surfaces[i] = gs_stagesurface_create_nv12( + ovi->output_width, ovi->output_height); + if (!video->copy_surfaces[i]) + return false; - if (!video->copy_surfaces[i]) - return false; + } else { +#endif + video->copy_surfaces[i] = gs_stagesurface_create( + ovi->output_width, output_height, + GS_RGBA); + if (!video->copy_surfaces[i]) + return false; +#ifdef _WIN32 + } +#endif video->render_textures[i] = gs_texture_create( ovi->base_width, ovi->base_height, @@ -272,6 +309,11 @@ static int obs_init_graphics(struct obs_video_info *ovi) NULL); bfree(filename); + filename = obs_find_data_file("repeat.effect"); + video->repeat_effect = gs_effect_create_from_file(filename, + NULL); + bfree(filename); + filename = obs_find_data_file("format_conversion.effect"); video->conversion_effect = gs_effect_create_from_file(filename, NULL); @@ -287,6 +329,11 @@ static int obs_init_graphics(struct obs_video_info *ovi) NULL); bfree(filename); + filename = obs_find_data_file("area.effect"); + video->area_effect = gs_effect_create_from_file(filename, + NULL); + bfree(filename); + filename = obs_find_data_file("bilinear_lowres_scale.effect"); video->bilinear_lowres_effect = gs_effect_create_from_file(filename, NULL); @@ -297,6 +344,7 @@ static int obs_init_graphics(struct obs_video_info *ovi) NULL); bfree(filename); + point_sampler.max_anisotropy = 1; video->point_sampler = gs_samplerstate_create(&point_sampler); obs->video.transparent_texture = gs_texture_create(2, 2, GS_RGBA, 1, @@ -351,6 +399,7 @@ static int obs_init_video(struct obs_video_info *ovi) { struct obs_core_video *video = &obs->video; struct video_output_info vi; + pthread_mutexattr_t attr; int errorcode; make_video_info(&vi, ovi); @@ -384,6 +433,13 @@ static int obs_init_video(struct obs_video_info *ovi) gs_leave_context(); + if (pthread_mutexattr_init(&attr) != 0) + return OBS_VIDEO_FAIL; + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0) + return OBS_VIDEO_FAIL; + if (pthread_mutex_init(&video->gpu_encoder_mutex, NULL) < 0) + return OBS_VIDEO_FAIL; + errorcode = pthread_create(&video->video_thread, NULL, obs_graphics_thread, obs); if (errorcode != 0) @@ -431,17 +487,20 @@ static void obs_free_video(void) gs_stagesurface_destroy(video->copy_surfaces[i]); gs_texture_destroy(video->render_textures[i]); gs_texture_destroy(video->convert_textures[i]); + gs_texture_destroy(video->convert_uv_textures[i]); gs_texture_destroy(video->output_textures[i]); - video->copy_surfaces[i] = NULL; - video->render_textures[i] = NULL; - video->convert_textures[i] = NULL; - video->output_textures[i] = NULL; + video->copy_surfaces[i] = NULL; + video->render_textures[i] = NULL; + video->convert_textures[i] = NULL; + video->convert_uv_textures[i] = NULL; + video->output_textures[i] = NULL; } gs_leave_context(); circlebuf_free(&video->vframe_info_buffer); + circlebuf_free(&video->vframe_info_buffer_gpu); memset(&video->textures_rendered, 0, sizeof(video->textures_rendered)); @@ -452,6 +511,11 @@ static void obs_free_video(void) memset(&video->textures_converted, 0, sizeof(video->textures_converted)); + pthread_mutex_destroy(&video->gpu_encoder_mutex); + pthread_mutex_init_value(&video->gpu_encoder_mutex); + da_free(video->gpu_encoders); + + video->gpu_encoder_active = 0; video->cur_texture = 0; } } @@ -473,7 +537,9 @@ static void obs_free_graphics(void) gs_effect_destroy(video->solid_effect); gs_effect_destroy(video->conversion_effect); gs_effect_destroy(video->bicubic_effect); + gs_effect_destroy(video->repeat_effect); gs_effect_destroy(video->lanczos_effect); + gs_effect_destroy(video->area_effect); gs_effect_destroy(video->bilinear_lowres_effect); video->default_effect = NULL; @@ -753,6 +819,7 @@ static bool obs_init(const char *locale, const char *module_config_path, obs = bzalloc(sizeof(struct obs_core)); pthread_mutex_init_value(&obs->audio.monitoring_mutex); + pthread_mutex_init_value(&obs->video.gpu_encoder_mutex); obs->name_store_owned = !store; obs->name_store = store ? store : profiler_name_store_create(); @@ -853,6 +920,42 @@ bool obs_startup(const char *locale, const char *module_config_path, return success; } +static struct obs_cmdline_args cmdline_args = {0, NULL}; +void obs_set_cmdline_args(int argc, const char * const *argv) +{ + char *data; + size_t len; + int i; + + /* Once argc is set (non-zero) we shouldn't call again */ + if (cmdline_args.argc) + return; + + cmdline_args.argc = argc; + + /* Safely copy over argv */ + len = 0; + for (i = 0; i < argc; i++) + len += strlen(argv[i]) + 1; + + cmdline_args.argv = bmalloc(sizeof(char *) * (argc + 1) + len); + data = (char *) cmdline_args.argv + sizeof(char *) * (argc + 1); + + for (i = 0; i < argc; i++) { + cmdline_args.argv[i] = data; + len = strlen(argv[i]) + 1; + memcpy(data, argv[i], len); + data += len; + } + + cmdline_args.argv[argc] = NULL; +} + +struct obs_cmdline_args obs_get_cmdline_args(void) +{ + return cmdline_args; +} + void obs_shutdown(void) { struct obs_module *module; @@ -918,6 +1021,7 @@ void obs_shutdown(void) bfree(core->module_config_path); bfree(core->locale); bfree(core); + bfree(cmdline_args.argv); #ifdef _WIN32 uninitialize_com(); @@ -977,7 +1081,7 @@ int obs_reset_video(struct obs_video_info *ovi) if (!obs) return OBS_VIDEO_FAIL; /* don't allow changing of video settings if active. */ - if (obs->video.video && video_output_active(obs->video.video)) + if (obs->video.video && obs_video_active()) return OBS_VIDEO_CURRENTLY_ACTIVE; if (!size_valid(ovi->output_width, ovi->output_height) || @@ -1018,11 +1122,15 @@ int obs_reset_video(struct obs_video_info *ovi) case OBS_SCALE_LANCZOS: scale_type_name = "Lanczos"; break; + case OBS_SCALE_AREA: + scale_type_name = "Area"; + break; } bool yuv = format_is_yuv(ovi->output_format); const char *yuv_format = get_video_colorspace_name(ovi->colorspace); - const char *yuv_range = get_video_range_name(ovi->range); + const char *yuv_range = get_video_range_name(ovi->output_format, + ovi->range); blog(LOG_INFO, "---------------------------------"); blog(LOG_INFO, "video settings reset:\n" @@ -1323,6 +1431,31 @@ void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), void *param) pthread_mutex_unlock(&obs->data.sources_mutex); } +void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), void *param) +{ + obs_source_t *source; + + if (!obs) return; + + pthread_mutex_lock(&obs->data.sources_mutex); + source = obs->data.first_source; + + while (source) { + obs_source_t *next_source = + (obs_source_t*)source->context.next; + + if (source->info.type == OBS_SOURCE_TYPE_SCENE && + !source->context.private && + !enum_proc(param, source)) { + break; + } + + source = next_source; + } + + pthread_mutex_unlock(&obs->data.sources_mutex); +} + static inline void obs_enum(void *pstart, pthread_mutex_t *mutex, void *proc, void *param) { @@ -1454,10 +1587,14 @@ gs_effect_t *obs_get_base_effect(enum obs_base_effect effect) return obs->video.opaque_effect; case OBS_EFFECT_SOLID: return obs->video.solid_effect; + case OBS_EFFECT_REPEAT: + return obs->video.repeat_effect; case OBS_EFFECT_BICUBIC: return obs->video.bicubic_effect; case OBS_EFFECT_LANCZOS: return obs->video.lanczos_effect; + case OBS_EFFECT_AREA: + return obs->video.area_effect; case OBS_EFFECT_BILINEAR_LOWRES: return obs->video.bilinear_lowres_effect; case OBS_EFFECT_PREMULTIPLIED_ALPHA: @@ -1514,8 +1651,13 @@ void obs_render_main_texture(void) param = gs_effect_get_param_by_name(effect, "image"); gs_effect_set_texture(param, tex); + gs_blend_state_push(); + gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA); + while (gs_effect_loop(effect, "Draw")) gs_draw_sprite(tex, 0, 0, 0); + + gs_blend_state_pop(); } gs_texture_t *obs_get_main_texture(void) @@ -1563,6 +1705,7 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) obs_data_t *settings = obs_data_get_obj(source_data, "settings"); obs_data_t *hotkeys = obs_data_get_obj(source_data, "hotkeys"); double volume; + double balance; int64_t sync; uint32_t flags; uint32_t mixers; @@ -1578,6 +1721,10 @@ static obs_source_t *obs_load_source_type(obs_data_t *source_data) volume = obs_data_get_double(source_data, "volume"); obs_source_set_volume(source, (float)volume); + obs_data_set_default_double(source_data, "balance", 0.5); + balance = obs_data_get_double(source_data, "balance"); + obs_source_set_balance_value(source, (float)balance); + sync = obs_data_get_int(source_data, "sync"); obs_source_set_sync_offset(source, sync); @@ -1694,6 +1841,11 @@ void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) obs_transition_load(source, source_data); obs_source_load(source); + for (size_t i = source->filters.num; i > 0; i--) { + obs_source_t *filter = + source->filters.array[i - 1]; + obs_source_load(filter); + } if (cb) cb(private_data, source); } @@ -1716,6 +1868,7 @@ obs_data_t *obs_save_source(obs_source_t *source) obs_data_t *hotkey_data = source->context.hotkey_data; obs_data_t *hotkeys; float volume = obs_source_get_volume(source); + float balance = obs_source_get_balance_value(source); uint32_t mixers = obs_source_get_audio_mixers(source); int64_t sync = obs_source_get_sync_offset(source); uint32_t flags = obs_source_get_flags(source); @@ -1748,6 +1901,7 @@ obs_data_t *obs_save_source(obs_source_t *source) obs_data_set_int (source_data, "sync", sync); obs_data_set_int (source_data, "flags", flags); obs_data_set_double(source_data, "volume", volume); + obs_data_set_double(source_data, "balance", balance); obs_data_set_bool (source_data, "enabled", enabled); obs_data_set_bool (source_data, "muted", muted); obs_data_set_bool (source_data, "push-to-mute", push_to_mute); @@ -2013,6 +2167,15 @@ bool obs_obj_invalid(void *obj) return !context->data; } +void *obs_obj_get_data(void *obj) +{ + struct obs_context_data *context = obj; + if (!context) + return NULL; + + return context->data; +} + bool obs_set_audio_monitoring_device(const char *name, const char *id) { if (!obs || !name || !id || !*name || !*id) @@ -2189,3 +2352,79 @@ obs_data_t *obs_get_private_data(void) obs_data_addref(private_data); return private_data; } + +extern bool init_gpu_encoding(struct obs_core_video *video); +extern void stop_gpu_encoding_thread(struct obs_core_video *video); +extern void free_gpu_encoding(struct obs_core_video *video); + +bool start_gpu_encode(obs_encoder_t *encoder) +{ + struct obs_core_video *video = &obs->video; + bool success = true; + + obs_enter_graphics(); + pthread_mutex_lock(&video->gpu_encoder_mutex); + + if (!video->gpu_encoders.num) + success = init_gpu_encoding(video); + if (success) + da_push_back(video->gpu_encoders, &encoder); + else + free_gpu_encoding(video); + + pthread_mutex_unlock(&video->gpu_encoder_mutex); + obs_leave_graphics(); + + if (success) { + os_atomic_inc_long(&video->gpu_encoder_active); + video_output_inc_texture_encoders(video->video); + } + + return success; +} + +void stop_gpu_encode(obs_encoder_t *encoder) +{ + struct obs_core_video *video = &obs->video; + bool call_free = false; + + os_atomic_dec_long(&video->gpu_encoder_active); + video_output_dec_texture_encoders(video->video); + + pthread_mutex_lock(&video->gpu_encoder_mutex); + da_erase_item(video->gpu_encoders, &encoder); + if (!video->gpu_encoders.num) + call_free = true; + pthread_mutex_unlock(&video->gpu_encoder_mutex); + + os_event_wait(video->gpu_encode_inactive); + + if (call_free) { + stop_gpu_encoding_thread(video); + + obs_enter_graphics(); + pthread_mutex_lock(&video->gpu_encoder_mutex); + free_gpu_encoding(video); + pthread_mutex_unlock(&video->gpu_encoder_mutex); + obs_leave_graphics(); + } +} + +bool obs_video_active(void) +{ + struct obs_core_video *video = &obs->video; + if (!obs) + return false; + + return os_atomic_load_long(&video->raw_active) > 0 || + os_atomic_load_long(&video->gpu_encoder_active) > 0; +} + +bool obs_nv12_tex_active(void) +{ + struct obs_core_video *video = &obs->video; + if (!obs) + return false; + + return video->using_nv12_tex; +} diff --git a/libobs/obs.h b/libobs/obs.h index 181bd6f..f6e76ca 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -116,7 +116,8 @@ enum obs_scale_type { OBS_SCALE_POINT, OBS_SCALE_BICUBIC, OBS_SCALE_BILINEAR, - OBS_SCALE_LANCZOS + OBS_SCALE_LANCZOS, + OBS_SCALE_AREA, }; /** @@ -219,6 +220,10 @@ struct obs_source_audio { * * If a YUV format is specified, it will be automatically upsampled and * converted to RGB via shader on the graphics processor. + * + * NOTE: Non-YUV formats will always be treated as full range with this + * structure! Use obs_source_frame2 along with obs_source_output_video2 + * instead if partial range support is desired for non-YUV video formats. */ struct obs_source_frame { uint8_t *data[MAX_AV_PLANES]; @@ -239,6 +244,27 @@ struct obs_source_frame { bool prev_frame; }; +struct obs_source_frame2 { + uint8_t *data[MAX_AV_PLANES]; + uint32_t linesize[MAX_AV_PLANES]; + uint32_t width; + uint32_t height; + uint64_t timestamp; + + enum video_format format; + enum video_range_type range; + float color_matrix[16]; + float color_range_min[3]; + float color_range_max[3]; + bool flip; +}; + +/** Access to the argc/argv used to start OBS. What you see is what you get. */ +struct obs_cmdline_args { + int argc; + char **argv; +}; + /* ------------------------------------------------------------------------- */ /* OBS context */ @@ -291,6 +317,24 @@ EXPORT uint32_t obs_get_version(void); /** @return The current core version string */ EXPORT const char *obs_get_version_string(void); +/** + * Sets things up for calls to obs_get_cmdline_args. Called onl yonce at startup + * and safely copies argv/argc from main(). Subsequent calls do nothing. + * + * @param argc The count of command line arguments, from main() + * @param argv An array of command line arguments, copied from main() and ends + * with NULL. + */ +EXPORT void obs_set_cmdline_args(int argc, const char * const *argv); + +/** + * Get the argc/argv used to start OBS + * + * @return The command line arguments used for main(). Don't modify this or + * you'll mess things up for other callers. + */ +EXPORT struct obs_cmdline_args obs_get_cmdline_args(void); + /** * Sets a new locale to use for modules. This will call obs_module_set_locale * for each module with the new locale. @@ -511,6 +555,9 @@ EXPORT audio_t *obs_get_audio(void); /** Gets the main video output handler for this OBS context */ EXPORT video_t *obs_get_video(void); +/** Returns true if video is active, false otherwise */ +EXPORT bool obs_video_active(void); + /** Sets the primary output source for a channel. */ EXPORT void obs_set_output_source(uint32_t channel, obs_source_t *source); @@ -532,6 +579,10 @@ EXPORT obs_source_t *obs_get_output_source(uint32_t channel); EXPORT void obs_enum_sources(bool (*enum_proc)(void*, obs_source_t*), void *param); +/** Enumerates scenes */ +EXPORT void obs_enum_scenes(bool (*enum_proc)(void*, obs_source_t*), + void *param); + /** Enumerates outputs */ EXPORT void obs_enum_outputs(bool (*enum_proc)(void*, obs_output_t*), void *param); @@ -570,6 +621,8 @@ enum obs_base_effect { OBS_EFFECT_LANCZOS, /**< Lanczos downscale */ OBS_EFFECT_BILINEAR_LOWRES, /**< Bilinear low resolution downscale */ OBS_EFFECT_PREMULTIPLIED_ALPHA,/**< Premultiplied alpha */ + OBS_EFFECT_REPEAT, /**< RGB/YUV (repeating) */ + OBS_EFFECT_AREA, /**< Area rescale */ }; /** Returns a commonly used base effect */ @@ -642,6 +695,7 @@ enum obs_obj_type { EXPORT enum obs_obj_type obs_obj_get_type(void *obj); EXPORT const char *obs_obj_get_id(void *obj); EXPORT bool obs_obj_invalid(void *obj); +EXPORT void *obs_obj_get_data(void *obj); typedef bool (*obs_enum_audio_device_cb)(void *data, const char *name, const char *id); @@ -682,6 +736,8 @@ EXPORT uint64_t obs_get_average_frame_time_ns(void); EXPORT uint32_t obs_get_total_frames(void); EXPORT uint32_t obs_get_lagged_frames(void); +EXPORT bool obs_nv12_tex_active(void); + EXPORT void obs_apply_private_data(obs_data_t *settings); EXPORT void obs_set_private_data(obs_data_t *settings); EXPORT obs_data_t *obs_get_private_data(void); @@ -724,7 +780,8 @@ EXPORT void obs_view_render(obs_view_t *view); * @return The new display context, or NULL if failed. */ EXPORT obs_display_t *obs_display_create( - const struct gs_init_data *graphics_data); + const struct gs_init_data *graphics_data, + uint32_t backround_color); /** Destroys a display context */ EXPORT void obs_display_destroy(obs_display_t *display); @@ -756,6 +813,9 @@ EXPORT bool obs_display_enabled(obs_display_t *display); EXPORT void obs_display_set_background_color(obs_display_t *display, uint32_t color); +EXPORT void obs_display_size(obs_display_t *display, + uint32_t *width, uint32_t *height); + /* ------------------------------------------------------------------------- */ /* Sources */ @@ -893,6 +953,15 @@ EXPORT void obs_source_set_volume(obs_source_t *source, float volume); /** Gets the user volume for a source that has audio output */ EXPORT float obs_source_get_volume(const obs_source_t *source); +/* Gets speaker layout of a source */ +EXPORT enum speaker_layout obs_source_get_speaker_layout(obs_source_t *source); + +/** Sets the balance value for a stereo audio source */ +EXPORT void obs_source_set_balance_value(obs_source_t *source, float balance); + +/** Gets the balance value for a stereo audio source */ +EXPORT float obs_source_get_balance_value(const obs_source_t *source); + /** Sets the audio sync offset (in nanoseconds) for a source */ EXPORT void obs_source_set_sync_offset(obs_source_t *source, int64_t offset); @@ -948,6 +1017,18 @@ EXPORT uint32_t obs_source_get_audio_mixers(const obs_source_t *source); */ EXPORT void obs_source_inc_showing(obs_source_t *source); +/** + * Increments the 'active' reference counter to indicate that the source is + * fully active. If the reference counter was 0, will call the 'activate' + * callback. + * + * Unlike obs_source_inc_showing, this will cause children of this source to be + * considered showing as well (currently used by transition previews to make + * the stinger transition show correctly). obs_source_inc_showing should + * generally be used instead. + */ +EXPORT void obs_source_inc_active(obs_source_t *source); + /** * Decrements the 'showing' reference counter to indicate that the source is * no longer being shown somewhere. If the reference counter is set to 0, @@ -955,6 +1036,17 @@ EXPORT void obs_source_inc_showing(obs_source_t *source); */ EXPORT void obs_source_dec_showing(obs_source_t *source); +/** + * Decrements the 'active' reference counter to indicate that the source is no + * longer fully active. If the reference counter is set to 0, will call the + * 'deactivate' callback + * + * Unlike obs_source_dec_showing, this will cause children of this source to be + * considered not showing as well. obs_source_dec_showing should generally be + * used instead. + */ +EXPORT void obs_source_dec_active(obs_source_t *source); + /** Enumerates filters assigned to the source */ EXPORT void obs_source_enum_filters(obs_source_t *source, obs_source_enum_proc_t callback, void *param); @@ -1070,13 +1162,29 @@ EXPORT void obs_source_draw_set_color_matrix( EXPORT void obs_source_draw(gs_texture_t *image, int x, int y, uint32_t cx, uint32_t cy, bool flip); -/** Outputs asynchronous video data. Set to NULL to deactivate the texture */ +/** + * Outputs asynchronous video data. Set to NULL to deactivate the texture + * + * NOTE: Non-YUV formats will always be treated as full range with this + * function! Use obs_source_output_video2 instead if partial range support is + * desired for non-YUV video formats. + */ EXPORT void obs_source_output_video(obs_source_t *source, const struct obs_source_frame *frame); +EXPORT void obs_source_output_video2(obs_source_t *source, + const struct obs_source_frame2 *frame); -/** Preloads asynchronous video data to allow instantaneous playback */ +/** + * Preloads asynchronous video data to allow instantaneous playback + * + * NOTE: Non-YUV formats will always be treated as full range with this + * function! Use obs_source_preload_video2 instead if partial range support is + * desired for non-YUV video formats. + */ EXPORT void obs_source_preload_video(obs_source_t *source, const struct obs_source_frame *frame); +EXPORT void obs_source_preload_video2(obs_source_t *source, + const struct obs_source_frame2 *frame); /** Shows any preloaded video data */ EXPORT void obs_source_show_preloaded_video(obs_source_t *source); @@ -1257,6 +1365,8 @@ typedef float (*obs_transition_audio_mix_callback_t)(void *data, float t); EXPORT float obs_transition_get_time(obs_source_t *transition); +EXPORT void obs_transition_force_stop(obs_source_t *transition); + EXPORT void obs_transition_video_render(obs_source_t *transition, obs_transition_video_render_callback_t callback); @@ -1406,6 +1516,8 @@ EXPORT void obs_sceneitem_get_draw_transform(const obs_sceneitem_t *item, struct matrix4 *transform); EXPORT void obs_sceneitem_get_box_transform(const obs_sceneitem_t *item, struct matrix4 *transform); +EXPORT void obs_sceneitem_get_box_scale(const obs_sceneitem_t *item, + struct vec2 *scale); EXPORT bool obs_sceneitem_visible(const obs_sceneitem_t *item); EXPORT bool obs_sceneitem_set_visible(obs_sceneitem_t *item, bool visible); @@ -1594,6 +1706,12 @@ EXPORT void obs_output_set_mixer(obs_output_t *output, size_t mixer_idx); /** Gets the current audio mixer for non-encoded outputs */ EXPORT size_t obs_output_get_mixer(const obs_output_t *output); +/** Sets the current audio mixes (mask) for a non-encoded multi-track output */ +EXPORT void obs_output_set_mixers(obs_output_t *output, size_t mixers); + +/** Gets the current audio mixes (mask) for a non-encoded multi-track output */ +EXPORT size_t obs_output_get_mixers(const obs_output_t *output); + /** * Sets the current video encoder associated with this output, * required for encoded outputs @@ -1664,6 +1782,8 @@ EXPORT const char *obs_output_get_id(const obs_output_t *output); #if BUILD_CAPTIONS EXPORT void obs_output_output_caption_text1(obs_output_t *output, const char *text); +EXPORT void obs_output_output_caption_text2(obs_output_t *output, + const char *text, double display_duration); #endif EXPORT float obs_output_get_congestion(obs_output_t *output); @@ -1871,6 +1991,7 @@ EXPORT void *obs_encoder_get_type_data(obs_encoder_t *encoder); EXPORT const char *obs_encoder_get_id(const obs_encoder_t *encoder); EXPORT uint32_t obs_get_encoder_caps(const char *encoder_id); +EXPORT uint32_t obs_encoder_get_caps(const obs_encoder_t *encoder); #ifndef SWIG /** Duplicates an encoder packet */ @@ -1886,6 +2007,9 @@ EXPORT void obs_encoder_packet_ref(struct encoder_packet *dst, struct encoder_packet *src); EXPORT void obs_encoder_packet_release(struct encoder_packet *packet); +EXPORT void *obs_encoder_create_rerouted(obs_encoder_t *encoder, + const char *reroute_id); + /* ------------------------------------------------------------------------- */ /* Stream Services */ diff --git a/libobs/util/apple/cfstring-utils.h b/libobs/util/apple/cfstring-utils.h new file mode 100644 index 0000000..d131fbb --- /dev/null +++ b/libobs/util/apple/cfstring-utils.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../c99defs.h" +#include "../dstr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EXPORT char *cfstr_copy_cstr(CFStringRef cfstr, CFStringEncoding cfstr_enc); + +EXPORT bool cfstr_copy_dstr(CFStringRef cfstr, CFStringEncoding cfstr_enc, + struct dstr *str); + +#ifdef __cplusplus +} +#endif diff --git a/libobs/util/circlebuf.h b/libobs/util/circlebuf.h index e6eaca4..b991612 100644 --- a/libobs/util/circlebuf.h +++ b/libobs/util/circlebuf.h @@ -292,7 +292,7 @@ static inline void circlebuf_pop_front(struct circlebuf *cb, void *data, static inline void circlebuf_pop_back(struct circlebuf *cb, void *data, size_t size) { - circlebuf_peek_front(cb, data, size); + circlebuf_peek_back(cb, data, size); cb->size -= size; if (!cb->size) { @@ -311,7 +311,7 @@ static inline void *circlebuf_data(struct circlebuf *cb, size_t idx) uint8_t *ptr = (uint8_t*)cb->data; size_t offset = cb->start_pos + idx; - if (idx > cb->size) + if (idx >= cb->size) return NULL; if (offset >= cb->capacity) diff --git a/libobs/util/config-file.c b/libobs/util/config-file.c index 8040c50..317f810 100644 --- a/libobs/util/config-file.c +++ b/libobs/util/config-file.c @@ -359,6 +359,7 @@ int config_save(config_t *config) FILE *f; struct dstr str, tmp; size_t i, j; + int ret = CONFIG_ERROR; if (!config) return CONFIG_ERROR; @@ -405,9 +406,15 @@ int config_save(config_t *config) } #ifdef _WIN32 - fwrite("\xEF\xBB\xBF", 1, 3, f); + if (fwrite("\xEF\xBB\xBF", 3, 1, f) != 1) + goto cleanup; #endif - fwrite(str.array, 1, str.len, f); + if (fwrite(str.array, str.len, 1, f) != 1) + goto cleanup; + + ret = CONFIG_SUCCESS; + +cleanup: fclose(f); pthread_mutex_unlock(&config->mutex); @@ -415,7 +422,7 @@ int config_save(config_t *config) dstr_free(&tmp); dstr_free(&str); - return CONFIG_SUCCESS; + return ret; } int config_save_safe(config_t *config, const char *temp_ext, @@ -444,6 +451,8 @@ int config_save_safe(config_t *config, const char *temp_ext, config->file = file; if (ret != CONFIG_SUCCESS) { + blog(LOG_ERROR, "config_save_safe: failed to " + "write to %s", temp_file.array); goto cleanup; } diff --git a/libobs/util/pipe-posix.c b/libobs/util/pipe-posix.c index 195f6e0..3d77686 100644 --- a/libobs/util/pipe-posix.c +++ b/libobs/util/pipe-posix.c @@ -73,6 +73,15 @@ size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, size_t len) return fread(data, 1, len, pp->file); } +size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len) +{ + /* XXX: unsupported on posix */ + UNUSED_PARAMETER(pp); + UNUSED_PARAMETER(data); + UNUSED_PARAMETER(len); + return 0; +} + size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, size_t len) { diff --git a/libobs/util/pipe-windows.c b/libobs/util/pipe-windows.c index d3d35e2..5510072 100644 --- a/libobs/util/pipe-windows.c +++ b/libobs/util/pipe-windows.c @@ -24,6 +24,7 @@ struct os_process_pipe { bool read_pipe; HANDLE handle; + HANDLE handle_err; HANDLE process; }; @@ -42,7 +43,7 @@ static bool create_pipe(HANDLE *input, HANDLE *output) } static inline bool create_process(const char *cmd_line, HANDLE stdin_handle, - HANDLE stdout_handle, HANDLE *process) + HANDLE stdout_handle, HANDLE stderr_handle, HANDLE *process) { PROCESS_INFORMATION pi = {0}; wchar_t *cmd_line_w = NULL; @@ -53,6 +54,7 @@ static inline bool create_process(const char *cmd_line, HANDLE stdin_handle, si.dwFlags = STARTF_USESTDHANDLES | STARTF_FORCEOFFFEEDBACK; si.hStdInput = stdin_handle; si.hStdOutput = stdout_handle; + si.hStdError = stderr_handle; os_utf8_to_wcs_ptr(cmd_line, 0, &cmd_line_w); if (cmd_line_w) { @@ -77,6 +79,7 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line, bool read_pipe; HANDLE process; HANDLE output; + HANDLE err_input, err_output; HANDLE input; bool success; @@ -90,26 +93,38 @@ os_process_pipe_t *os_process_pipe_create(const char *cmd_line, return NULL; } + if (!create_pipe(&err_input, &err_output)) { + return NULL; + } + read_pipe = *type == 'r'; success = !!SetHandleInformation(read_pipe ? input : output, - HANDLE_FLAG_INHERIT, false); + HANDLE_FLAG_INHERIT, false); + if (!success) { + goto error; + } + + success = !!SetHandleInformation(err_input, HANDLE_FLAG_INHERIT, false); if (!success) { goto error; } success = create_process(cmd_line, read_pipe ? NULL : input, - read_pipe ? output : NULL, &process); + read_pipe ? output : NULL, err_output, &process); if (!success) { goto error; } pp = bmalloc(sizeof(*pp)); + pp->handle = read_pipe ? input : output; pp->read_pipe = read_pipe; pp->process = process; + pp->handle_err = err_input; CloseHandle(read_pipe ? output : input); + CloseHandle(err_output); return pp; error: @@ -126,6 +141,7 @@ int os_process_pipe_destroy(os_process_pipe_t *pp) DWORD code; CloseHandle(pp->handle); + CloseHandle(pp->handle_err); WaitForSingleObject(pp->process, INFINITE); if (GetExitCodeProcess(pp->process, &code)) @@ -158,6 +174,25 @@ size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, size_t len) return 0; } +size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, size_t len) +{ + DWORD bytes_read; + bool success; + + if (!pp || !pp->handle_err) { + return 0; + } + + success = !!ReadFile(pp->handle_err, data, (DWORD)len, &bytes_read, NULL); + if (success && bytes_read) { + return bytes_read; + } + else + bytes_read = GetLastError(); + + return 0; +} + size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, size_t len) { diff --git a/libobs/util/pipe.h b/libobs/util/pipe.h index cb595fd..5c44514 100644 --- a/libobs/util/pipe.h +++ b/libobs/util/pipe.h @@ -27,5 +27,7 @@ EXPORT int os_process_pipe_destroy(os_process_pipe_t *pp); EXPORT size_t os_process_pipe_read(os_process_pipe_t *pp, uint8_t *data, size_t len); +EXPORT size_t os_process_pipe_read_err(os_process_pipe_t *pp, uint8_t *data, + size_t len); EXPORT size_t os_process_pipe_write(os_process_pipe_t *pp, const uint8_t *data, size_t len); diff --git a/libobs/util/platform-cocoa.m b/libobs/util/platform-cocoa.m index f93341c..ff434d6 100644 --- a/libobs/util/platform-cocoa.m +++ b/libobs/util/platform-cocoa.m @@ -1,6 +1,7 @@ /* - * Copyright (c) 2013-2014 Ruwen Hahn + * Copyright (c) 2013-2018 Ruwen Hahn * Hugh "Jim" Bailey + * Marvin Scholz * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,16 +24,20 @@ #include #include #include +#include #include #include #include #include +#include #include #import +#include "apple/cfstring-utils.h" + /* clock function selection taken from libc++ */ static uint64_t ns_time_simple() { @@ -137,6 +142,35 @@ char *os_get_program_data_path_ptr(const char *name) return os_get_path_ptr_internal(name, NSLocalDomainMask); } +char *os_get_executable_path_ptr(const char *name) +{ + char exe[PATH_MAX]; + char abs_path[PATH_MAX]; + uint32_t size = sizeof(exe); + struct dstr path; + char *slash; + + if (_NSGetExecutablePath(exe, &size) != 0) { + return NULL; + } + + if (!realpath(exe, abs_path)) { + return NULL; + } + + dstr_init_copy(&path, abs_path); + slash = strrchr(path.array, '/'); + if (slash) { + size_t len = slash - path.array + 1; + dstr_resize(&path, len); + } + + if (name && *name) { + dstr_cat(&path, name); + } + return path.array; +} + struct os_cpu_usage_info { int64_t last_cpu_time; int64_t last_sys_time; @@ -417,3 +451,90 @@ uint64_t os_get_proc_virtual_size(void) return 0; return taskinfo.virtual_size; } + +/* Obtains a copy of the contents of a CFString in specified encoding. + * Returns char* (must be bfree'd by caller) or NULL on failure. + */ +char *cfstr_copy_cstr(CFStringRef cfstring, CFStringEncoding cfstring_encoding) +{ + if (!cfstring) + return NULL; + + // Try the quick way to obtain the buffer + const char *tmp_buffer = CFStringGetCStringPtr(cfstring, + cfstring_encoding); + + if (tmp_buffer != NULL) + return bstrdup(tmp_buffer); + + // The quick way did not work, try the more expensive one + CFIndex length = CFStringGetLength(cfstring); + CFIndex max_size = + CFStringGetMaximumSizeForEncoding(length, cfstring_encoding); + + // If result would exceed LONG_MAX, kCFNotFound is returned + if (max_size == kCFNotFound) + return NULL; + + // Account for the null terminator + max_size++; + + char *buffer = bmalloc(max_size); + + if (buffer == NULL) { + return NULL; + } + + // Copy CFString in requested encoding to buffer + Boolean success = + CFStringGetCString(cfstring, buffer, max_size, cfstring_encoding); + + if (!success) { + bfree(buffer); + buffer = NULL; + } + return buffer; +} + +/* Copies the contents of a CFString in specified encoding to a given dstr. + * Returns true on success or false on failure. + * In case of failure, the dstr capacity but not size is changed. + */ +bool cfstr_copy_dstr(CFStringRef cfstring, + CFStringEncoding cfstring_encoding, struct dstr *str) +{ + if (!cfstring) + return false; + + // Try the quick way to obtain the buffer + const char *tmp_buffer = CFStringGetCStringPtr(cfstring, + cfstring_encoding); + + if (tmp_buffer != NULL) { + dstr_copy(str, tmp_buffer); + return true; + } + + // The quick way did not work, try the more expensive one + CFIndex length = CFStringGetLength(cfstring); + CFIndex max_size = + CFStringGetMaximumSizeForEncoding(length, cfstring_encoding); + + // If result would exceed LONG_MAX, kCFNotFound is returned + if (max_size == kCFNotFound) + return NULL; + + // Account for the null terminator + max_size++; + + dstr_ensure_capacity(str, max_size); + + // Copy CFString in requested encoding to dstr buffer + Boolean success = CFStringGetCString( + cfstring, str->array, max_size, cfstring_encoding); + + if (success) + dstr_resize(str, max_size); + + return (bool)success; +} diff --git a/libobs/util/platform-nix.c b/libobs/util/platform-nix.c index b303e30..2fcdd43 100644 --- a/libobs/util/platform-nix.c +++ b/libobs/util/platform-nix.c @@ -33,6 +33,7 @@ #if !defined(__APPLE__) #include #include +#include #ifdef __FreeBSD__ #include #include @@ -66,7 +67,11 @@ void *os_dlopen(const char *path) #endif dstr_cat(&dylib_name, ".so"); +#ifdef __APPLE__ + void *res = dlopen(dylib_name.array, RTLD_LAZY | RTLD_FIRST); +#else void *res = dlopen(dylib_name.array, RTLD_LAZY); +#endif if (!res) blog(LOG_ERROR, "os_dlopen(%s->%s): %s\n", path, dylib_name.array, dlerror()); @@ -265,6 +270,32 @@ char *os_get_program_data_path_ptr(const char *name) return str; } +char *os_get_executable_path_ptr(const char *name) +{ + char exe[PATH_MAX]; + ssize_t count = readlink("/proc/self/exe", exe, PATH_MAX); + const char *path_out = NULL; + struct dstr path; + + if (count == -1) { + return NULL; + } + + path_out = dirname(exe); + if (!path_out) { + return NULL; + } + + dstr_init_copy(&path, path_out); + dstr_cat(&path, "/"); + + if (name && *name) { + dstr_cat(&path, name); + } + + return path.array; +} + #endif bool os_file_exists(const char *path) @@ -848,7 +879,7 @@ static inline bool os_get_proc_memory_usage_internal(statm_t *statm) if (!f) return false; - if (fscanf(f, "%ld %ld %ld %ld %ld %ld %ld", + if (fscanf(f, "%lu %lu %lu %lu %lu %lu %lu", &statm->virtual_size, &statm->resident_size, &statm->share_pages, diff --git a/libobs/util/platform-windows.c b/libobs/util/platform-windows.c index d0c1464..08c9e5b 100644 --- a/libobs/util/platform-windows.c +++ b/libobs/util/platform-windows.c @@ -50,7 +50,7 @@ static inline uint32_t get_winver(void) if (!winver) { struct win_version_info ver; get_win_ver(&ver); - winver = (ver.major << 16) | ver.minor; + winver = (ver.major << 8) | ver.minor; } return winver; @@ -92,6 +92,12 @@ void *os_dlopen(const char *path) if (!h_library) { DWORD error = GetLastError(); + + /* don't print error for libraries that aren't meant to be + * dynamically linked */ + if (error == ERROR_PROC_NOT_FOUND) + return NULL; + char *message = NULL; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | @@ -289,6 +295,31 @@ char *os_get_program_data_path_ptr(const char *name) return os_get_path_ptr_internal(name, CSIDL_COMMON_APPDATA); } +char *os_get_executable_path_ptr(const char *name) +{ + char *ptr; + char *slash; + wchar_t path_utf16[MAX_PATH]; + struct dstr path; + + GetModuleFileNameW(NULL, path_utf16, MAX_PATH); + + os_wcs_to_utf8_ptr(path_utf16, 0, &ptr); + dstr_init_move_array(&path, ptr); + dstr_replace(&path, "\\", "/"); + slash = strrchr(path.array, '/'); + if (slash) { + size_t len = slash - path.array + 1; + dstr_resize(&path, len); + } + + if (name && *name) { + dstr_cat(&path, name); + } + + return path.array; +} + bool os_file_exists(const char *path) { WIN32_FIND_DATAW wfd; @@ -869,6 +900,11 @@ void get_win_ver(struct win_version_info *info) *info = ver; } +uint32_t get_win_ver_int(void) +{ + return get_winver(); +} + struct os_inhibit_info { bool active; }; diff --git a/libobs/util/platform.c b/libobs/util/platform.c index 6826ea4..a8d036e 100644 --- a/libobs/util/platform.c +++ b/libobs/util/platform.c @@ -262,10 +262,19 @@ bool os_quick_write_utf8_file(const char *path, const char *str, size_t len, if (!f) return false; - if (marker) - fwrite("\xEF\xBB\xBF", 1, 3, f); - if (len) - fwrite(str, 1, len, f); + if (marker) { + if (fwrite("\xEF\xBB\xBF", 3, 1, f) != 1) { + fclose(f); + return false; + } + } + + if (len) { + if (fwrite(str, len, 1, f) != 1) { + fclose(f); + return false; + } + } fflush(f); fclose(f); @@ -292,6 +301,8 @@ bool os_quick_write_utf8_file_safe(const char *path, const char *str, dstr_cat(&temp_path, temp_ext); if (!os_quick_write_utf8_file(temp_path.array, str, len, marker)) { + blog(LOG_ERROR, "os_quick_write_utf8_file_safe: failed to " + "write to %s", temp_path.array); goto cleanup; } diff --git a/libobs/util/platform.h b/libobs/util/platform.h index cd5eea2..ed21b01 100644 --- a/libobs/util/platform.h +++ b/libobs/util/platform.h @@ -111,6 +111,8 @@ EXPORT char *os_get_config_path_ptr(const char *name); EXPORT int os_get_program_data_path(char *dst, size_t size, const char *name); EXPORT char *os_get_program_data_path_ptr(const char *name); +EXPORT char *os_get_executable_path_ptr(const char *name); + EXPORT bool os_file_exists(const char *path); EXPORT size_t os_get_abs_path(const char *path, char *abspath, size_t size); diff --git a/libobs/util/threading-posix.c b/libobs/util/threading-posix.c index 435ff1b..d02e3d3 100644 --- a/libobs/util/threading-posix.c +++ b/libobs/util/threading-posix.c @@ -253,6 +253,12 @@ void os_set_thread_name(const char *name) #elif defined(__FreeBSD__) pthread_set_name_np(pthread_self(), name); #elif defined(__GLIBC__) && !defined(__MINGW32__) - pthread_setname_np(pthread_self(), name); + if (strlen(name) <= 15) { + pthread_setname_np(pthread_self(), name); + } else { + char *thread_name = bstrdup_n(name, 15); + pthread_setname_np(pthread_self(), thread_name); + bfree(thread_name); + } #endif } diff --git a/libobs/util/utf8.c b/libobs/util/utf8.c index d0b5c34..0c96de1 100644 --- a/libobs/util/utf8.c +++ b/libobs/util/utf8.c @@ -41,7 +41,7 @@ size_t utf8_to_wchar(const char *in, size_t insize, wchar_t *out, if (has_utf8_bom(in)) { if (i_insize >= 3) { in += 3; - insize -= 3; + i_insize -= 3; } } diff --git a/libobs/util/util_uint128.h b/libobs/util/util_uint128.h index 511ab0a..ac96f3e 100644 --- a/libobs/util/util_uint128.h +++ b/libobs/util/util_uint128.h @@ -51,11 +51,19 @@ static inline util_uint128_t util_add128(util_uint128_t a, util_uint128_t b) return out; } -static inline util_uint128_t util_lshift64(uint64_t a, int num) +static inline util_uint128_t util_lshift64_internal_32(uint64_t a) { util_uint128_t val; - val.low = a << num; - val.high = a >> (64 - num); + val.low = a << 32; + val.high = a >> 32; + return val; +} + +static inline util_uint128_t util_lshift64_internal_64(uint64_t a) +{ + util_uint128_t val; + val.low = 0; + val.high = a; return val; } @@ -69,13 +77,13 @@ static inline util_uint128_t util_mul64_64(uint64_t a, uint64_t b) out.high = 0; m = (a >> 32) * (b & 0xFFFFFFFFULL); - out = util_add128(out, util_lshift64(m, 32)); + out = util_add128(out, util_lshift64_internal_32(m)); m = (a & 0xFFFFFFFFULL) * (b >> 32); - out = util_add128(out, util_lshift64(m, 32)); + out = util_add128(out, util_lshift64_internal_32(m)); m = (a >> 32) * (b >> 32); - out = util_add128(out, util_lshift64(m, 64)); + out = util_add128(out, util_lshift64_internal_64(m)); return out; } diff --git a/libobs/util/windows/ComPtr.hpp b/libobs/util/windows/ComPtr.hpp index 6b320df..2415240 100644 --- a/libobs/util/windows/ComPtr.hpp +++ b/libobs/util/windows/ComPtr.hpp @@ -68,7 +68,7 @@ public: inline ComPtr &operator=(ComPtr &&c) { - if (this != &c) { + if (&ptr != &c.ptr) { Kill(); ptr = c.ptr; c.ptr = nullptr; diff --git a/libobs/util/windows/WinHandle.hpp b/libobs/util/windows/WinHandle.hpp index 708c07b..4ae3812 100644 --- a/libobs/util/windows/WinHandle.hpp +++ b/libobs/util/windows/WinHandle.hpp @@ -17,7 +17,7 @@ #pragma once class WinHandle { - HANDLE handle; + HANDLE handle = INVALID_HANDLE_VALUE; inline void Clear() { @@ -26,7 +26,7 @@ class WinHandle { } public: - inline WinHandle() : handle(NULL) {} + inline WinHandle() {} inline WinHandle(HANDLE handle_) : handle(handle_) {} inline ~WinHandle() {Clear();} diff --git a/libobs/util/windows/win-version.h b/libobs/util/windows/win-version.h index c855448..106cd80 100644 --- a/libobs/util/windows/win-version.h +++ b/libobs/util/windows/win-version.h @@ -32,6 +32,7 @@ struct win_version_info { EXPORT bool is_64_bit_windows(void); EXPORT bool get_dll_ver(const wchar_t *lib, struct win_version_info *info); EXPORT void get_win_ver(struct win_version_info *info); +EXPORT uint32_t get_win_ver_int(void); #ifdef __cplusplus } diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index e6fa3e5..537ed21 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -53,9 +53,13 @@ if(WIN32 OR APPLE) if (BUILD_BROWSER) if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-browser/CMakeLists.txt") add_subdirectory(obs-browser) + set(BROWSER_AVAILABLE_INTERNAL ON CACHE BOOL "Interal global cmake variable" FORCE) else() message(STATUS "obs-browser submodule not found! Please fetch submodules. obs-browser plugin disabled.") + set(BROWSER_AVAILABLE_INTERNAL OFF CACHE BOOL "Interal global cmake variable" FORCE) endif() + else() + set(BROWSER_AVAILABLE_INTERNAL OFF CACHE BOOL "Interal global cmake variable" FORCE) endif() if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/obs-vst/CMakeLists.txt") diff --git a/plugins/coreaudio-encoder/data/locale/bg-BG.ini b/plugins/coreaudio-encoder/data/locale/bg-BG.ini index c786d39..6f7c204 100644 --- a/plugins/coreaudio-encoder/data/locale/bg-BG.ini +++ b/plugins/coreaudio-encoder/data/locale/bg-BG.ini @@ -1,3 +1,4 @@ Bitrate="Битрейт" AllowHEAAC="Позволи HE-AAC" +OutputSamplerate="Изходна честота на дискретизация" diff --git a/plugins/coreaudio-encoder/data/locale/da-DK.ini b/plugins/coreaudio-encoder/data/locale/da-DK.ini index 64cdc29..03bcd28 100644 --- a/plugins/coreaudio-encoder/data/locale/da-DK.ini +++ b/plugins/coreaudio-encoder/data/locale/da-DK.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="CoreAudio AAC encoder" -Bitrate="Bitrate" +CoreAudioAAC="CoreAudio AAC-encoder" +Bitrate="Bit-hastighed" AllowHEAAC="Tillad HE-AAC" -OutputSamplerate="Output Sample Rate" -UseInputSampleRate="Brug Input (OBS) Sample Rate (kan vise ikke-understøttede bithastigheder)" +OutputSamplerate="Output Samplingsfrekvens" +UseInputSampleRate="Benyt Input (OBS) Samplingsfrekvens (kan vise uunderstøttede bit-hastigheder)" diff --git a/plugins/coreaudio-encoder/data/locale/de-DE.ini b/plugins/coreaudio-encoder/data/locale/de-DE.ini index 44895bd..0e6245d 100644 --- a/plugins/coreaudio-encoder/data/locale/de-DE.ini +++ b/plugins/coreaudio-encoder/data/locale/de-DE.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="CoreAudio AAC Codierer" +CoreAudioAAC="CoreAudio AAC Kodierer" Bitrate="Bitrate" AllowHEAAC="Erlaube HE-AAC" -OutputSamplerate="Ausgabe-Abtastrate" +OutputSamplerate="Ausgabeabtastrate" UseInputSampleRate="Verwenden Sie Eingabe (OBS) Abtastrate (kann nicht unterstützte Bitraten auflisten)" diff --git a/plugins/coreaudio-encoder/data/locale/eu-ES.ini b/plugins/coreaudio-encoder/data/locale/eu-ES.ini index c1cb04e..1549f03 100644 --- a/plugins/coreaudio-encoder/data/locale/eu-ES.ini +++ b/plugins/coreaudio-encoder/data/locale/eu-ES.ini @@ -1,6 +1,6 @@ CoreAudioAAC="CoreAudio AAC kodetzailea" Bitrate="Bit-tasa" -AllowHEAAC="Ahalbidetu HE-AAC" +AllowHEAAC="Baimendu HE-AAC" OutputSamplerate="Irteera lagin-emaria" UseInputSampleRate="Erabili sarrerako (OBS) lagin-emaria (sostengurik gabeko bit-tasak ager daitezke zerrendan)" diff --git a/plugins/coreaudio-encoder/data/locale/fa-IR.ini b/plugins/coreaudio-encoder/data/locale/fa-IR.ini new file mode 100644 index 0000000..62fb27b --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/fa-IR.ini @@ -0,0 +1,4 @@ +Bitrate="نرخ بیت" +OutputSamplerate="نرخ صدای نمونه" +UseInputSampleRate="استفاده از ورودی (OBS) میزان نمونه (پشتیبانی نشده bitrates لیست ممکن است)" + diff --git a/plugins/coreaudio-encoder/data/locale/fr-FR.ini b/plugins/coreaudio-encoder/data/locale/fr-FR.ini index 1980507..988e4dc 100644 --- a/plugins/coreaudio-encoder/data/locale/fr-FR.ini +++ b/plugins/coreaudio-encoder/data/locale/fr-FR.ini @@ -1,6 +1,6 @@ CoreAudioAAC="Encodeur AAC CoreAudio" Bitrate="Débit" -AllowHEAAC="Autoriser le HE-AAC" +AllowHEAAC="Autoriser HE-AAC" OutputSamplerate="Fréquence d'échantillonnage de sortie" -UseInputSampleRate="Utiliser la fréquence d’échantillonnage d'entrée (OBS) (pourrait lister des débits non-supportés)" +UseInputSampleRate="Utiliser la fréquence d’échantillonnage d'OBS (pourrait lister des débits non-supportés)" diff --git a/plugins/coreaudio-encoder/data/locale/it-IT.ini b/plugins/coreaudio-encoder/data/locale/it-IT.ini index dc4ea1e..c629344 100644 --- a/plugins/coreaudio-encoder/data/locale/it-IT.ini +++ b/plugins/coreaudio-encoder/data/locale/it-IT.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="Encoder CoreAudio AAC" -Bitrate="Bitrate" +CoreAudioAAC="Codifica CoreAudio AAC" +Bitrate="Velocità in bit" AllowHEAAC="Consenti l'HE-AAC" -OutputSamplerate="Output Sample Rate" -UseInputSampleRate="Usa frequenza di campionamento input (OBS) (potrebbe elencare bitrate non supportati)" +OutputSamplerate="Frequenza di campionamento in uscita" +UseInputSampleRate="Usa la frequenza di campionamento in entrata di OBS (potrebbe elencare velocità in bit non supportate)" diff --git a/plugins/coreaudio-encoder/data/locale/mn-MN.ini b/plugins/coreaudio-encoder/data/locale/mn-MN.ini new file mode 100644 index 0000000..d0becb4 --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/mn-MN.ini @@ -0,0 +1,6 @@ +CoreAudioAAC="CoreAudio AAC кодлогч" +Bitrate="Битийн хурд" +AllowHEAAC="HE-AAC-ийг зөвшөөрөх" +OutputSamplerate="Гаралын түүврийн хурд" +UseInputSampleRate="(OBS-ийн) Оролтын түүврийн хурдыг хэрэглэх (дэмжигдээгүй битийн хурдны жагсаалтны хуудсанд байж магадгүй)" + diff --git a/plugins/coreaudio-encoder/data/locale/pt-PT.ini b/plugins/coreaudio-encoder/data/locale/pt-PT.ini index e2b503c..1debe60 100644 --- a/plugins/coreaudio-encoder/data/locale/pt-PT.ini +++ b/plugins/coreaudio-encoder/data/locale/pt-PT.ini @@ -2,5 +2,5 @@ CoreAudioAAC="Codificador CoreAudio AAC" Bitrate="Bitrate" AllowHEAAC="Permitir HE-AAC" OutputSamplerate="Taxa de amostragem de saída" -UseInputSampleRate="Taxa de amostragem de entrada (OBS) Taxa Amostra (pode listar taxas de bit sem suporte)" +UseInputSampleRate="Taxa de amostragem de entrada (OBS) Taxa Amostra (pode listar taxas de bit sem suporte)" diff --git a/plugins/coreaudio-encoder/data/locale/ro-RO.ini b/plugins/coreaudio-encoder/data/locale/ro-RO.ini index c3f3246..a2df720 100644 --- a/plugins/coreaudio-encoder/data/locale/ro-RO.ini +++ b/plugins/coreaudio-encoder/data/locale/ro-RO.ini @@ -1,4 +1,4 @@ -CoreAudioAAC="Cofificator AAC CoreAudio" +CoreAudioAAC="Codificator AAC CoreAudio" Bitrate="Rată de biți" AllowHEAAC="Permite HE-AAC" OutputSamplerate="Rată de eșantionare a ieșirii" diff --git a/plugins/coreaudio-encoder/data/locale/sr-CS.ini b/plugins/coreaudio-encoder/data/locale/sr-CS.ini index cf7f107..8faa28d 100644 --- a/plugins/coreaudio-encoder/data/locale/sr-CS.ini +++ b/plugins/coreaudio-encoder/data/locale/sr-CS.ini @@ -1,6 +1,6 @@ -CoreAudioAAC="CoreAudio AAC nekoder" +CoreAudioAAC="CoreAudio AAC enkoder" Bitrate="Protok" AllowHEAAC="Dozvoli HE-AAC" -OutputSamplerate="Izlazni sample-rate" -UseInputSampleRate="Koristi ulazni (OBS) sample-rate (mogu biti prikazani nepodržani bitrate-ovi)" +OutputSamplerate="Brzina semplovanja na izlazu" +UseInputSampleRate="Koristi brzinu semplovanja sa ulaza (OBS) (mogu biti zabeleženi protoci koji nisu podržani)" diff --git a/plugins/coreaudio-encoder/data/locale/sr-SP.ini b/plugins/coreaudio-encoder/data/locale/sr-SP.ini index 4617ee6..70a7734 100644 --- a/plugins/coreaudio-encoder/data/locale/sr-SP.ini +++ b/plugins/coreaudio-encoder/data/locale/sr-SP.ini @@ -1,6 +1,6 @@ CoreAudioAAC="CoreAudio AAC енкодер" Bitrate="Проток" AllowHEAAC="Дозволи HE-AAC" -OutputSamplerate="Излазни sample-rate" -UseInputSampleRate="Користи улазни sample-rate (OBS) (могу бити приказани неподржани bitrate-ови)" +OutputSamplerate="Брзина семпловања на излазу" +UseInputSampleRate="Користи брзину семпловања са улаза (OBS) (могу бити забележени протоци који нису подржани)" diff --git a/plugins/coreaudio-encoder/data/locale/ur-PK.ini b/plugins/coreaudio-encoder/data/locale/ur-PK.ini new file mode 100644 index 0000000..dd43963 --- /dev/null +++ b/plugins/coreaudio-encoder/data/locale/ur-PK.ini @@ -0,0 +1,2 @@ +Bitrate="بٹ ریٹ" + diff --git a/plugins/coreaudio-encoder/encoder.cpp b/plugins/coreaudio-encoder/encoder.cpp index 972376d..0affe6e 100644 --- a/plugins/coreaudio-encoder/encoder.cpp +++ b/plugins/coreaudio-encoder/encoder.cpp @@ -10,6 +10,7 @@ #ifndef _WIN32 #include +#include #endif #define CA_LOG(level, format, ...) \ @@ -257,17 +258,8 @@ static DStr osstatus_to_dstr(OSStatus code) kCFErrorDomainOSStatus, code, NULL)}; cf_ptr str{CFErrorCopyDescription(err.get())}; - CFIndex length = CFStringGetLength(str.get()); - CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, - kCFStringEncodingUTF8); - - dstr_ensure_capacity(result, max_size); - - if (result->array && CFStringGetCString(str.get(), result->array, - max_size, kCFStringEncodingUTF8)) { - dstr_resize(result, strlen(result->array)); + if (cfstr_copy_dstr(str.get(), kCFStringEncodingUTF8, result)) return result; - } #endif const char *code_str = code_to_str(code); @@ -1374,6 +1366,10 @@ static obs_properties_t *aac_properties(void *data) OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("coreaudio-encoder", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Apple CoreAudio based encoder"; +} bool obs_module_load(void) { diff --git a/plugins/decklink/DecklinkBase.cpp b/plugins/decklink/DecklinkBase.cpp new file mode 100644 index 0000000..e916a24 --- /dev/null +++ b/plugins/decklink/DecklinkBase.cpp @@ -0,0 +1,20 @@ +#include "DecklinkBase.h" + +DecklinkBase::DecklinkBase(DeckLinkDeviceDiscovery *discovery_) + : discovery(discovery_) +{ +} + +DeckLinkDevice *DecklinkBase::GetDevice() const +{ + return instance ? instance->GetDevice() : nullptr; +} + +bool DecklinkBase::Activate(DeckLinkDevice*, long long) +{ + return false; +} + +void DecklinkBase::Deactivate() +{ +} diff --git a/plugins/decklink/DecklinkBase.h b/plugins/decklink/DecklinkBase.h new file mode 100644 index 0000000..a337092 --- /dev/null +++ b/plugins/decklink/DecklinkBase.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +#include + +#include "platform.hpp" + +#include "decklink-device-discovery.hpp" +#include "decklink-device-instance.hpp" +#include "decklink-device-mode.hpp" + +class DecklinkBase { + +protected: + DecklinkBase(DeckLinkDeviceDiscovery *discovery_); + ComPtr instance; + DeckLinkDeviceDiscovery *discovery; + std::recursive_mutex deviceMutex; + volatile long activateRefs = 0; + BMDPixelFormat pixelFormat = bmdFormat8BitYUV; + video_colorspace colorSpace = VIDEO_CS_DEFAULT; + video_range_type colorRange = VIDEO_RANGE_DEFAULT; + speaker_layout channelFormat = SPEAKERS_STEREO; + +public: + virtual bool Activate(DeckLinkDevice *device, long long modeId); + virtual void Deactivate(); + + DeckLinkDevice *GetDevice() const; +}; diff --git a/plugins/decklink/decklink.cpp b/plugins/decklink/DecklinkInput.cpp similarity index 57% rename from plugins/decklink/decklink.cpp rename to plugins/decklink/DecklinkInput.cpp index ea0ec96..0f74aa6 100644 --- a/plugins/decklink/decklink.cpp +++ b/plugins/decklink/DecklinkInput.cpp @@ -1,30 +1,23 @@ -#include "decklink.hpp" -#include "decklink-device-discovery.hpp" -#include "decklink-device-instance.hpp" -#include "decklink-device-mode.hpp" +#include "DecklinkInput.hpp" #include -DeckLink::DeckLink(obs_source_t *source, DeckLinkDeviceDiscovery *discovery_) : - discovery(discovery_), source(source) +DeckLinkInput::DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery_) + : DecklinkBase(discovery_), + source(source) { - discovery->AddCallback(DeckLink::DevicesChanged, this); + discovery->AddCallback(DeckLinkInput::DevicesChanged, this); } -DeckLink::~DeckLink(void) +DeckLinkInput::~DeckLinkInput(void) { - discovery->RemoveCallback(DeckLink::DevicesChanged, this); + discovery->RemoveCallback(DeckLinkInput::DevicesChanged, this); Deactivate(); } -DeckLinkDevice *DeckLink::GetDevice() const +void DeckLinkInput::DevicesChanged(void *param, DeckLinkDevice *device, bool added) { - return instance ? instance->GetDevice() : nullptr; -} - -void DeckLink::DevicesChanged(void *param, DeckLinkDevice *device, bool added) -{ - DeckLink *decklink = reinterpret_cast(param); + DeckLinkInput *decklink = reinterpret_cast(param); std::lock_guard lock(decklink->deviceMutex); obs_source_update_properties(decklink->source); @@ -33,16 +26,20 @@ void DeckLink::DevicesChanged(void *param, DeckLinkDevice *device, bool added) const char *hash; long long mode; obs_data_t *settings; + BMDVideoConnection videoConnection; + BMDAudioConnection audioConnection; settings = obs_source_get_settings(decklink->source); hash = obs_data_get_string(settings, "device_hash"); + videoConnection = (BMDVideoConnection) obs_data_get_int(settings, "video_connection"); + audioConnection = (BMDAudioConnection) obs_data_get_int(settings, "audio_connection"); mode = obs_data_get_int(settings, "mode_id"); obs_data_release(settings); if (device->GetHash().compare(hash) == 0) { if (!decklink->activateRefs) return; - if (decklink->Activate(device, mode)) + if (decklink->Activate(device, mode, videoConnection, audioConnection)) os_atomic_dec_long(&decklink->activateRefs); } @@ -54,7 +51,9 @@ void DeckLink::DevicesChanged(void *param, DeckLinkDevice *device, bool added) } } -bool DeckLink::Activate(DeckLinkDevice *device, long long modeId) +bool DeckLinkInput::Activate(DeckLinkDevice *device, long long modeId, + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection) { std::lock_guard lock(deviceMutex); DeckLinkDevice *curDevice = GetDevice(); @@ -65,49 +64,66 @@ bool DeckLink::Activate(DeckLinkDevice *device, long long modeId) if (!isActive) return false; if (instance->GetActiveModeId() == modeId && + instance->GetVideoConnection() == bmdVideoConnection && + instance->GetAudioConnection() == bmdAudioConnection && instance->GetActivePixelFormat() == pixelFormat && instance->GetActiveColorSpace() == colorSpace && instance->GetActiveColorRange() == colorRange && - instance->GetActiveChannelFormat() == channelFormat) + instance->GetActiveChannelFormat() == channelFormat && + instance->GetActiveSwapState() == swap) return false; } if (isActive) instance->StopCapture(); + isCapturing = false; if (!same) instance.Set(new DeckLinkDeviceInstance(this, device)); if (instance == nullptr) return false; - DeckLinkDeviceMode *mode = GetDevice()->FindMode(modeId); + if (GetDevice() == nullptr) { + LOG(LOG_ERROR, "Tried to activate an input with nullptr device."); + return false; + } + + DeckLinkDeviceMode *mode = GetDevice()->FindInputMode(modeId); if (mode == nullptr) { instance = nullptr; return false; } - if (!instance->StartCapture(mode)) { + if (!instance->StartCapture(mode, bmdVideoConnection, bmdAudioConnection)) { instance = nullptr; return false; } os_atomic_inc_long(&activateRefs); SaveSettings(); + id = modeId; + isCapturing = true; return true; } -void DeckLink::Deactivate(void) +void DeckLinkInput::Deactivate(void) { std::lock_guard lock(deviceMutex); if (instance) instance->StopCapture(); + isCapturing = false; instance = nullptr; os_atomic_dec_long(&activateRefs); } -void DeckLink::SaveSettings() +bool DeckLinkInput::Capturing(void) +{ + return isCapturing; +} + +void DeckLinkInput::SaveSettings() { if (!instance) return; @@ -127,7 +143,7 @@ void DeckLink::SaveSettings() obs_data_release(settings); } -obs_source_t *DeckLink::GetSource(void) const +obs_source_t *DeckLinkInput::GetSource(void) const { return source; } diff --git a/plugins/decklink/decklink.hpp b/plugins/decklink/DecklinkInput.hpp similarity index 51% rename from plugins/decklink/decklink.hpp rename to plugins/decklink/DecklinkInput.hpp index 23f8b59..c90dd7e 100644 --- a/plugins/decklink/decklink.hpp +++ b/plugins/decklink/DecklinkInput.hpp @@ -1,40 +1,19 @@ #pragma once -#include "platform.hpp" +#include "DecklinkBase.h" -#include - -#include -#include -#include - -class DeckLinkDeviceDiscovery; -class DeckLinkDeviceInstance; -class DeckLinkDevice; -class DeckLinkDeviceMode; - -class DeckLink { +class DeckLinkInput : public DecklinkBase { protected: - ComPtr instance; - DeckLinkDeviceDiscovery *discovery; bool isCapturing = false; obs_source_t *source; - volatile long activateRefs = 0; - std::recursive_mutex deviceMutex; - BMDPixelFormat pixelFormat = bmdFormat8BitYUV; - video_colorspace colorSpace = VIDEO_CS_DEFAULT; - video_range_type colorRange = VIDEO_RANGE_DEFAULT; - speaker_layout channelFormat = SPEAKERS_STEREO; void SaveSettings(); static void DevicesChanged(void *param, DeckLinkDevice *device, bool added); public: - DeckLink(obs_source_t *source, DeckLinkDeviceDiscovery *discovery); - virtual ~DeckLink(void); - - DeckLinkDevice *GetDevice() const; + DeckLinkInput(obs_source_t *source, DeckLinkDeviceDiscovery *discovery); + virtual ~DeckLinkInput(void); long long GetActiveModeId(void) const; obs_source_t *GetSource(void) const; @@ -60,8 +39,17 @@ public: channelFormat = format; } - bool Activate(DeckLinkDevice *device, long long modeId); + bool Activate(DeckLinkDevice *device, long long modeId, + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection); void Deactivate(); + bool Capturing(); bool buffering = false; + bool dwns = false; + std::string hash; + long long id; + bool swap = false; + BMDVideoConnection videoConnection; + BMDAudioConnection audioConnection; }; diff --git a/plugins/decklink/DecklinkOutput.cpp b/plugins/decklink/DecklinkOutput.cpp new file mode 100644 index 0000000..40eaf33 --- /dev/null +++ b/plugins/decklink/DecklinkOutput.cpp @@ -0,0 +1,110 @@ +#include "DecklinkOutput.hpp" + +#include + +DeckLinkOutput::DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery_) + : DecklinkBase(discovery_), + output(output) +{ + discovery->AddCallback(DeckLinkOutput::DevicesChanged, this); +} + +DeckLinkOutput::~DeckLinkOutput(void) +{ + discovery->RemoveCallback(DeckLinkOutput::DevicesChanged, this); + Deactivate(); +} + +void DeckLinkOutput::DevicesChanged(void *param, DeckLinkDevice *device, bool) +{ + auto *decklink = reinterpret_cast(param); + std::lock_guard lock(decklink->deviceMutex); + + blog(LOG_DEBUG, "%s", device->GetHash().c_str()); +} + +bool DeckLinkOutput::Activate(DeckLinkDevice *device, long long modeId) +{ + std::lock_guard lock(deviceMutex); + DeckLinkDevice *curDevice = GetDevice(); + const bool same = device == curDevice; + const bool isActive = instance != nullptr; + + if (same) { + if (!isActive) + return false; + + if (instance->GetActiveModeId() == modeId && + instance->GetActivePixelFormat() == pixelFormat && + instance->GetActiveColorSpace() == colorSpace && + instance->GetActiveColorRange() == colorRange && + instance->GetActiveChannelFormat() == channelFormat) + return false; + } + + if (isActive) + instance->StopOutput(); + + if (!same) + instance.Set(new DeckLinkDeviceInstance(this, device)); + + if (instance == nullptr) + return false; + + DeckLinkDeviceMode *mode = GetDevice()->FindOutputMode(modeId); + if (mode == nullptr) { + instance = nullptr; + return false; + } + + + if (!instance->StartOutput(mode)) { + instance = nullptr; + return false; + } + + os_atomic_inc_long(&activateRefs); + return true; +} + +void DeckLinkOutput::Deactivate(void) +{ + std::lock_guard lock(deviceMutex); + if (instance) + instance->StopOutput(); + + instance = nullptr; + + os_atomic_dec_long(&activateRefs); +} + +obs_output_t *DeckLinkOutput::GetOutput(void) const +{ + return output; +} + +void DeckLinkOutput::DisplayVideoFrame(video_data *frame) +{ + instance->DisplayVideoFrame(frame); +} + +void DeckLinkOutput::WriteAudio(audio_data *frames) +{ + instance->WriteAudio(frames); +} + +void DeckLinkOutput::SetSize(int width, int height) +{ + this->width = width; + this->height = height; +} + +int DeckLinkOutput::GetWidth() +{ + return width; +} + +int DeckLinkOutput::GetHeight() +{ + return height; +} diff --git a/plugins/decklink/DecklinkOutput.hpp b/plugins/decklink/DecklinkOutput.hpp new file mode 100644 index 0000000..0a4fe85 --- /dev/null +++ b/plugins/decklink/DecklinkOutput.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include "DecklinkBase.h" + +#include "../../libobs/media-io/video-scaler.h" + +class DeckLinkOutput : public DecklinkBase { +protected: + obs_output_t *output; + int width; + int height; + + static void DevicesChanged(void *param, DeckLinkDevice *device, bool added); + +public: + const char *deviceHash; + long long modeID; + uint64_t start_timestamp; + uint32_t audio_samplerate; + size_t audio_planes; + size_t audio_size; + int keyerMode; + + DeckLinkOutput(obs_output_t *output, DeckLinkDeviceDiscovery *discovery); + virtual ~DeckLinkOutput(void); + obs_output_t *GetOutput(void) const; + bool Activate(DeckLinkDevice *device, long long modeId) override; + void Deactivate() override; + void DisplayVideoFrame(video_data *pData); + void WriteAudio(audio_data *frames); + void SetSize(int width, int height); + int GetWidth(); + int GetHeight(); +}; diff --git a/plugins/decklink/audio-repack.c b/plugins/decklink/audio-repack.c index 02d0879..ec92f76 100644 --- a/plugins/decklink/audio-repack.c +++ b/plugins/decklink/audio-repack.c @@ -21,38 +21,16 @@ int check_buffer(struct audio_repack *repack, } /* - * Swap channel 3 & 4, 5 & 7, 6 & 8 and squash arrays + * Squash arrays. + * For instance: * 2.1: * * | FL | FR | LFE | emp | emp | emp |emp |emp | * | | | * | FL | FR | LFE | - * 4.0 (quad): - * - * | FL | FR | BR | BL | emp | emp |emp |emp | - * | | x | - * | FL | FR | BL | BC | - * - * 4.1: - * - * | FL | FR |LFE | FC | BC | emp |emp |emp | - * | | x | | - * | FL | FR | FC |LFE | BC | - * - * 5.1: - * - * | FL | FR |LFE | FC |(emp|emp)|(BL|BR)| - * | | x x - * | FL | FR | FC |LFE | BL | BR | - * - * 7.1: - * - * | FL | FR |LFE | FC |( SL | SR )|(BL |BR )| - * | | x X - * | FL | FR | FC |LFE |( BL | BR )|(SL |SR )| - */ +*/ -int repack_squash_swap(struct audio_repack *repack, +int repack_squash(struct audio_repack *repack, const uint8_t *bsrc, uint32_t frame_count) { if (check_buffer(repack, frame_count) < 0) @@ -62,28 +40,39 @@ int repack_squash_swap(struct audio_repack *repack, const __m128i *src = (__m128i *)bsrc; const __m128i *esrc = src + frame_count; uint16_t *dst = (uint16_t *)repack->packet_buffer; - /* 2.1 audio does not require re-ordering but still needs squashing - * in order to avoid sampling issues. + + /* Audio needs squashing in order to avoid resampling issues. + * The condition checks for 7.1 audio for which no squash is needed. */ - if (squash == 5) { + if (squash > 0) { while (src != esrc) { __m128i target = _mm_load_si128(src++); _mm_storeu_si128((__m128i *)dst, target); dst += 8 - squash; } - } else { - while (src != esrc) { - __m128i target = _mm_load_si128(src++); - __m128i buf = _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); - __m128i buf2 = _mm_shufflehi_epi16(buf, _MM_SHUFFLE(1, 0, 3, 2)); - _mm_storeu_si128((__m128i *)dst, buf2); - dst += 8 - squash; - } } return 0; } +int repack_squash_swap(struct audio_repack *repack, + const uint8_t *bsrc, uint32_t frame_count) +{ + if (check_buffer(repack, frame_count) < 0) + return -1; + int squash = repack->extra_dst_size; + const __m128i *src = (__m128i *)bsrc; + const __m128i *esrc = src + frame_count; + uint16_t *dst = (uint16_t *)repack->packet_buffer; + while (src != esrc) { + __m128i target = _mm_load_si128(src++); + __m128i buf = _mm_shufflelo_epi16(target, _MM_SHUFFLE(2, 3, 1, 0)); + _mm_storeu_si128((__m128i *)dst, buf); + dst += 8 - squash; + } + return 0; +} + int audio_repack_init(struct audio_repack *repack, audio_repack_mode_t repack_mode, uint8_t sample_bit) { @@ -91,44 +80,15 @@ int audio_repack_init(struct audio_repack *repack, if (sample_bit != 16) return -1; - - switch (repack_mode) { - case repack_mode_8to3ch_swap23: - repack->base_src_size = 8 * (16 / 8); - repack->base_dst_size = 3 * (16 / 8); - repack->extra_dst_size = 5; + int _audio_repack_ch[8] = { 3, 4, 5, 6, 5, 6, 8, 8 }; + repack->base_src_size = 8 * (16 / 8); + repack->base_dst_size = _audio_repack_ch[repack_mode] * (16 / 8); + repack->extra_dst_size = 8 - _audio_repack_ch[repack_mode]; + repack->repack_func = &repack_squash; + if (repack_mode == repack_mode_8to5ch_swap || + repack_mode == repack_mode_8to6ch_swap || + repack_mode == repack_mode_8ch_swap) repack->repack_func = &repack_squash_swap; - break; - case repack_mode_8to4ch_swap23: - repack->base_src_size = 8 * (16 / 8); - repack->base_dst_size = 4 * (16 / 8); - repack->extra_dst_size = 4; - repack->repack_func = &repack_squash_swap; - break; - - case repack_mode_8to5ch_swap23: - repack->base_src_size = 8 * (16 / 8); - repack->base_dst_size = 5 * (16 / 8); - repack->extra_dst_size = 3; - repack->repack_func = &repack_squash_swap; - break; - - case repack_mode_8to6ch_swap23: - repack->base_src_size = 8 * (16 / 8); - repack->base_dst_size = 6 * (16 / 8); - repack->extra_dst_size = 2; - repack->repack_func = &repack_squash_swap; - break; - - case repack_mode_8ch_swap23_swap46_swap57: - repack->base_src_size = 8 * (16 / 8); - repack->base_dst_size = 8 * (16 / 8); - repack->extra_dst_size = 0; - repack->repack_func = &repack_squash_swap; - break; - - default: return -1; - } return 0; } diff --git a/plugins/decklink/audio-repack.h b/plugins/decklink/audio-repack.h index e063e13..448cd99 100644 --- a/plugins/decklink/audio-repack.h +++ b/plugins/decklink/audio-repack.h @@ -26,11 +26,14 @@ struct audio_repack { }; enum _audio_repack_mode { - repack_mode_8to3ch_swap23, - repack_mode_8to4ch_swap23, - repack_mode_8to5ch_swap23, - repack_mode_8to6ch_swap23, - repack_mode_8ch_swap23_swap46_swap57, + repack_mode_8to3ch=0, + repack_mode_8to4ch, + repack_mode_8to5ch, + repack_mode_8to6ch, + repack_mode_8to5ch_swap, + repack_mode_8to6ch_swap, + repack_mode_8ch_swap, + repack_mode_8ch, }; typedef enum _audio_repack_mode audio_repack_mode_t; diff --git a/plugins/decklink/const.h b/plugins/decklink/const.h new file mode 100644 index 0000000..4f67a77 --- /dev/null +++ b/plugins/decklink/const.h @@ -0,0 +1,41 @@ +#define DEVICE_HASH "device_hash" +#define DEVICE_NAME "device_name" +#define VIDEO_CONNECTION "video_connection" +#define AUDIO_CONNECTION "audio_connection" +#define MODE_ID "mode_id" +#define MODE_NAME "mode_name" +#define CHANNEL_FORMAT "channel_format" +#define PIXEL_FORMAT "pixel_format" +#define COLOR_SPACE "color_space" +#define COLOR_RANGE "color_range" +#define BUFFERING "buffering" +#define DEACTIVATE_WNS "deactivate_when_not_showing" +#define AUTO_START "auto_start" +#define KEYER "keyer" +#define SWAP "swap" + +#define TEXT_DEVICE obs_module_text("Device") +#define TEXT_VIDEO_CONNECTION obs_module_text("VideoConnection") +#define TEXT_AUDIO_CONNECTION obs_module_text("AudioConnection") +#define TEXT_MODE obs_module_text("Mode") +#define TEXT_PIXEL_FORMAT obs_module_text("PixelFormat") +#define TEXT_COLOR_SPACE obs_module_text("ColorSpace") +#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default") +#define TEXT_COLOR_RANGE obs_module_text("ColorRange") +#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default") +#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial") +#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full") +#define TEXT_CHANNEL_FORMAT obs_module_text("ChannelFormat") +#define TEXT_CHANNEL_FORMAT_NONE obs_module_text("ChannelFormat.None") +#define TEXT_CHANNEL_FORMAT_2_0CH obs_module_text("ChannelFormat.2_0ch") +#define TEXT_CHANNEL_FORMAT_2_1CH obs_module_text("ChannelFormat.2_1ch") +#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch") +#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch") +#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch") +#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch") +#define TEXT_BUFFERING obs_module_text("Buffering") +#define TEXT_DWNS obs_module_text("DeactivateWhenNotShowing") +#define TEXT_AUTO_START obs_module_text("AutoStart") +#define TEXT_ENABLE_KEYER obs_module_text("Keyer") +#define TEXT_SWAP obs_module_text("SwapFC-LFE") +#define TEXT_SWAP_TOOLTIP obs_module_text("SwapFC-LFE.Tooltip") diff --git a/plugins/decklink/data/locale/ar-SA.ini b/plugins/decklink/data/locale/ar-SA.ini index fdaf139..f26cc16 100644 --- a/plugins/decklink/data/locale/ar-SA.ini +++ b/plugins/decklink/data/locale/ar-SA.ini @@ -3,4 +3,18 @@ Device="الجهاز" Mode="الوضع" Buffering="استخدام التخزين المؤقت" PixelFormat="صيغة البكسل" +ColorSpace.Default="الافتراضي" +ColorRange.Default="الافتراضي" +ColorRange.Partial="جزئي" +ColorRange.Full="كامل" +ChannelFormat="قناة" +ChannelFormat.None="بلا" +ChannelFormat.2_0ch="2ch" +ChannelFormat.2_1ch="2.1ch" +ChannelFormat.4_0ch="4ch" +ChannelFormat.4_1ch="4.1ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="التعطيل عندما لا يكون ظاهراً" +AutoStart="البدء تلقائياً مع التشغيل" diff --git a/plugins/decklink/data/locale/bn-BD.ini b/plugins/decklink/data/locale/bn-BD.ini index f13caa4..657e1ea 100644 --- a/plugins/decklink/data/locale/bn-BD.ini +++ b/plugins/decklink/data/locale/bn-BD.ini @@ -1,4 +1,7 @@ BlackmagicDevice="Blackmagic যন্ত্র" Device="ডিভাইস" PixelFormat="পিক্সেল বিন্যাস" +ColorRange.Partial="আংশিক" +ColorRange.Full="পূর্ণ" +ChannelFormat="চ্যানেল" diff --git a/plugins/decklink/data/locale/ca-ES.ini b/plugins/decklink/data/locale/ca-ES.ini index c6df023..bacbb37 100644 --- a/plugins/decklink/data/locale/ca-ES.ini +++ b/plugins/decklink/data/locale/ca-ES.ini @@ -3,9 +3,9 @@ Device="Dispositiu" Mode="Mode" Buffering="Usa memòria intermèdia" PixelFormat="Format de píxel" -ColorSpace="Espai de color YUV" +ColorSpace="Espai de color" ColorSpace.Default="Per defecte" -ColorRange="Gamma de color YUV" +ColorRange="Gamma de colors" ColorRange.Default="Per defecte" ColorRange.Partial="Parcial" ColorRange.Full="Complet" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4" ChannelFormat.4_1ch="4.1" ChannelFormat.5_1ch="Canals 5.1" ChannelFormat.7_1ch="Canals 7.1" +DeactivateWhenNotShowing="Desactiva quan no es mostra" +AutoStart="Executa automàticament a l'inici" +SwapFC-LFE="Commuta FC i LFE" +SwapFC-LFE.Tooltip="Commuta el centre del canal frontal i el subwoofer" +VideoConnection="Connexió de vídeo" +AudioConnection="Connexió d'àudio" diff --git a/plugins/decklink/data/locale/cs-CZ.ini b/plugins/decklink/data/locale/cs-CZ.ini index 081819c..4d1661b 100644 --- a/plugins/decklink/data/locale/cs-CZ.ini +++ b/plugins/decklink/data/locale/cs-CZ.ini @@ -3,9 +3,9 @@ Device="Zařízení" Mode="Mód" Buffering="Použít vyrovnávací paměť" PixelFormat="Formát pixelů" -ColorSpace="Prostor barev YUV" +ColorSpace="Barevný prostor" ColorSpace.Default="Výchozí" -ColorRange="Rozsah barev YUV" +ColorRange="Rozsah barev" ColorRange.Default="Výchozí" ColorRange.Partial="Částečný" ColorRange.Full="Plný" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Deaktivovat při skrytém" +AutoStart="Spustit při startu" +SwapFC-LFE="Prohodit FC a LFE" +SwapFC-LFE.Tooltip="Prohodí přední prostřední kanál a LFE kanál (Subwoofer)" +VideoConnection="Obrazové spojení" +AudioConnection="Zvukové spojení" diff --git a/plugins/decklink/data/locale/da-DK.ini b/plugins/decklink/data/locale/da-DK.ini index 8ccdb60..5a8a0ae 100644 --- a/plugins/decklink/data/locale/da-DK.ini +++ b/plugins/decklink/data/locale/da-DK.ini @@ -1,20 +1,26 @@ BlackmagicDevice="Blackmagic-enhed" Device="Enhed" Mode="Tilstand" -Buffering="Brug buffering" +Buffering="Benyt buffering" PixelFormat="Pixelformat" -ColorSpace="YUV farverum" +ColorSpace="Farverum" ColorSpace.Default="Standard" -ColorRange="YUV-farveområde" +ColorRange="Farveområde" ColorRange.Default="Standard" ColorRange.Partial="Delvis" ColorRange.Full="Fuld" ChannelFormat="Kanal" ChannelFormat.None="Intet" -ChannelFormat.2_0ch="2kan" -ChannelFormat.2_1ch="2.1 kasnals" +ChannelFormat.2_0ch="2 kanals" +ChannelFormat.2_1ch="2.1 kanals" ChannelFormat.4_0ch="4 kanals" ChannelFormat.4_1ch="4.1 kanals" ChannelFormat.5_1ch="5.1 kanals" ChannelFormat.7_1ch="7.1 kanals" +DeactivateWhenNotShowing="Deaktivér, hvis ikke synlig" +AutoStart="Autostart ved opstart" +SwapFC-LFE="Ombyt FC og LFE" +SwapFC-LFE.Tooltip="Byt Front Center-kanal og LFE-kanal" +VideoConnection="Videoforbindelse" +AudioConnection="Lydforbindelse" diff --git a/plugins/decklink/data/locale/de-DE.ini b/plugins/decklink/data/locale/de-DE.ini index 5694853..3bdbd6e 100644 --- a/plugins/decklink/data/locale/de-DE.ini +++ b/plugins/decklink/data/locale/de-DE.ini @@ -1,11 +1,11 @@ -BlackmagicDevice="Blackmagic Gerät" +BlackmagicDevice="Blackmagic-Gerät" Device="Gerät" Mode="Modus" -Buffering="Buffering benutzen" +Buffering="Puffern benutzen" PixelFormat="Pixelformat" -ColorSpace="YUV-Farbmatrix" +ColorSpace="Farbraum" ColorSpace.Default="Standard" -ColorRange="YUV-Farbbereich" +ColorRange="Farbbereich" ColorRange.Default="Standard" ColorRange.Partial="Begrenzt" ColorRange.Full="Voll" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 Kanal" ChannelFormat.4_1ch="4.1 Kanal" ChannelFormat.5_1ch="5.1 Kanal" ChannelFormat.7_1ch="7.1 Kanal" +DeactivateWhenNotShowing="Deaktivieren, wenn die Quelle nicht angezeigt wird" +AutoStart="Automatisch beim Öffnen starten" +SwapFC-LFE="FC und LFE tauschen" +SwapFC-LFE.Tooltip="Vorderen Front-Center-Kanal und LFE-Kanal tauschen" +VideoConnection="Videoverbindung" +AudioConnection="Audioverbindung" diff --git a/plugins/decklink/data/locale/el-GR.ini b/plugins/decklink/data/locale/el-GR.ini index 26fa84c..b4f167a 100644 --- a/plugins/decklink/data/locale/el-GR.ini +++ b/plugins/decklink/data/locale/el-GR.ini @@ -3,9 +3,7 @@ Device="Συσκευή" Mode="Λειτουργία" Buffering="Χρήση ενδιάμεσης μνήμης" PixelFormat="Μορφή pixel" -ColorSpace="Χώρος Χρωμάτων YUV" ColorSpace.Default="Προεπιλογή" -ColorRange="Έκταση Χρωμάτων YUV" ColorRange.Default="Προεπιλογή" ColorRange.Partial="Μερική" ColorRange.Full="Πλήρης" @@ -17,4 +15,6 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Απενεργοποίηση όταν δεν εμφανίζεται" +AutoStart="Αυτόματη εκκίνηση" diff --git a/plugins/decklink/data/locale/en-US.ini b/plugins/decklink/data/locale/en-US.ini index a694a06..a73f79d 100644 --- a/plugins/decklink/data/locale/en-US.ini +++ b/plugins/decklink/data/locale/en-US.ini @@ -3,9 +3,9 @@ Device="Device" Mode="Mode" Buffering="Use Buffering" PixelFormat="Pixel Format" -ColorSpace="YUV Color Space" +ColorSpace="Color Space" ColorSpace.Default="Default" -ColorRange="YUV Color Range" +ColorRange="Color Range" ColorRange.Default="Default" ColorRange.Partial="Partial" ColorRange.Full="Full" @@ -17,3 +17,9 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Deactivate when not showing" +AutoStart="Auto start on launch" +SwapFC-LFE="Swap FC and LFE" +SwapFC-LFE.Tooltip="Swap Front Center Channel and LFE Channel" +VideoConnection="Video Connection" +AudioConnection="Audio Connection" diff --git a/plugins/decklink/data/locale/es-ES.ini b/plugins/decklink/data/locale/es-ES.ini index a4d8415..f1b7abf 100644 --- a/plugins/decklink/data/locale/es-ES.ini +++ b/plugins/decklink/data/locale/es-ES.ini @@ -3,9 +3,9 @@ Device="Dispositivo" Mode="Modo" Buffering="Utilizar el almacenamiento en búfer" PixelFormat="Formato de píxel" -ColorSpace="Espacio de color YUV" +ColorSpace="Espacio de color" ColorSpace.Default="Predeterminado" -ColorRange="Rango de color YUV" +ColorRange="Rango de color" ColorRange.Default="Predeterminado" ColorRange.Partial="Parcial" ColorRange.Full="Completo" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 canales" ChannelFormat.4_1ch="4.1 canales" ChannelFormat.5_1ch="5.1 canales" ChannelFormat.7_1ch="7.1 canales" +DeactivateWhenNotShowing="Desactivar cuando no se muestre" +AutoStart="Comenzar al iniciar" +SwapFC-LFE="Intercambiar FC y LFE" +SwapFC-LFE.Tooltip="Intercambiar Canal Central Frontal y Canal LFE" +VideoConnection="Conexión de vídeo" +AudioConnection="Conexión de audio" diff --git a/plugins/decklink/data/locale/eu-ES.ini b/plugins/decklink/data/locale/eu-ES.ini index eb5aee2..a64ec00 100644 --- a/plugins/decklink/data/locale/eu-ES.ini +++ b/plugins/decklink/data/locale/eu-ES.ini @@ -3,18 +3,24 @@ Device="Gailua" Mode="Modua" Buffering="Erabili Bufferreratzea" PixelFormat="Pixel formatua" -ColorSpace="YUV kolore espazioa" +ColorSpace="Kolore-espazioa" ColorSpace.Default="Lehenetsia" -ColorRange="YUV kolore tartea" +ColorRange="Kolore tartea" ColorRange.Default="Lehenetsia" ColorRange.Partial="Partziala" ColorRange.Full="Osoa" ChannelFormat="Kanala" ChannelFormat.None="Ezer ez" -ChannelFormat.2_0ch="2k" +ChannelFormat.2_0ch="2 kanala" ChannelFormat.2_1ch="2.1 kanala" -ChannelFormat.4_0ch="4kanala" -ChannelFormat.4_1ch="4.1kanala" +ChannelFormat.4_0ch="4 kanala" +ChannelFormat.4_1ch="4.1 kanala" ChannelFormat.5_1ch="5.1 kanala" ChannelFormat.7_1ch="7.1 kanala" +DeactivateWhenNotShowing="Desaktibatu ikusten ez denean" +AutoStart="Hasi automatikoki abiatzean" +SwapFC-LFE="Aldatu FC <-> LFE" +SwapFC-LFE.Tooltip="Aldatu Aurreko Kanal Zentrala eta LFE kanala (subwooferra)" +VideoConnection="Bideo-konexioa" +AudioConnection="Audio-konexioa" diff --git a/plugins/decklink/data/locale/fa-IR.ini b/plugins/decklink/data/locale/fa-IR.ini new file mode 100644 index 0000000..89b7ab6 --- /dev/null +++ b/plugins/decklink/data/locale/fa-IR.ini @@ -0,0 +1,22 @@ +BlackmagicDevice="Blackmagic دستگاه" +Device="دستگاه" +Mode="نوع" +Buffering="استفاده از بافرینگ" +PixelFormat="فرمت پیکسل" +ColorSpace.Default="پیش فرض" +ColorRange.Default="پیش فرض" +ColorRange.Partial="جزئی" +ColorRange.Full="کامل" +ChannelFormat="کانال" +ChannelFormat.None="هیچ‌کدام" +ChannelFormat.2_0ch="2ch" +ChannelFormat.2_1ch="2.1ch" +ChannelFormat.4_0ch="4ch" +ChannelFormat.4_1ch="4.1ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="غیر فعال کردن زمانی که نمایش داده نشود" +AutoStart="شروع خودکار در راه اندازی" +VideoConnection="اتصال صوتی" +AudioConnection="اتصال صوتی" + diff --git a/plugins/decklink/data/locale/fi-FI.ini b/plugins/decklink/data/locale/fi-FI.ini index 7439eb2..007cb01 100644 --- a/plugins/decklink/data/locale/fi-FI.ini +++ b/plugins/decklink/data/locale/fi-FI.ini @@ -3,9 +3,9 @@ Device="Laite" Mode="Tila" Buffering="Käytä puskurointia" PixelFormat="Pikselimuoto" -ColorSpace="YUV väriavaruus" +ColorSpace="Väriavaruus" ColorSpace.Default="Oletusarvo" -ColorRange="YUV värialue" +ColorRange="Värialue" ColorRange.Default="Oletusarvo" ColorRange.Partial="Osittainen" ColorRange.Full="Täysi" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Poista käytöstä piilotettaessa" +AutoStart="Aloita automaattisesti käynnistyksessä" +SwapFC-LFE="Vaihda FC ja LFE" +SwapFC-LFE.Tooltip="Vaihda etummainen keskikanava ja LFE-kanava" +VideoConnection="Kuvayhteys" +AudioConnection="Ääniyhteys" diff --git a/plugins/decklink/data/locale/fil-PH.ini b/plugins/decklink/data/locale/fil-PH.ini index 9f0477c..e7c0399 100644 --- a/plugins/decklink/data/locale/fil-PH.ini +++ b/plugins/decklink/data/locale/fil-PH.ini @@ -3,9 +3,7 @@ Device="Kagamitan" Mode="Mode" Buffering="Gamitin ang Buffering" PixelFormat="Format ng Pixel" -ColorSpace="YUV Kulay Space" ColorSpace.Default="Pangunahin" -ColorRange="Saklaw ng Kulay ng YUV" ColorRange.Default="Pangunahin" ColorRange.Partial="Bahagyang" ColorRange.Full="Buong" diff --git a/plugins/decklink/data/locale/fr-FR.ini b/plugins/decklink/data/locale/fr-FR.ini index 9248d58..d958ff7 100644 --- a/plugins/decklink/data/locale/fr-FR.ini +++ b/plugins/decklink/data/locale/fr-FR.ini @@ -7,7 +7,7 @@ ColorSpace="Espace de couleurs YUV" ColorSpace.Default="Défaut" ColorRange="Gamme de couleurs YUV" ColorRange.Default="Défaut" -ColorRange.Partial="Partiel" +ColorRange.Partial="Partielle" ColorRange.Full="Complète" ChannelFormat="Canaux audio" ChannelFormat.None="Aucun" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 canaux" ChannelFormat.4_1ch="4.1 canaux" ChannelFormat.5_1ch="5.1 canaux" ChannelFormat.7_1ch="7.1 canaux" +DeactivateWhenNotShowing="Désactiver si non-affiché" +AutoStart="Démarrer automatiquement au lancement" +SwapFC-LFE="Permuter Canal FC (Centre Avant) et Caisson de Basses" +SwapFC-LFE.Tooltip="Permuter le canal Centre Avant (FC) et le Caisson de Basses (LFE)" +VideoConnection="Connexion vidéo" +AudioConnection="Connexion audio" diff --git a/plugins/decklink/data/locale/gd-GB.ini b/plugins/decklink/data/locale/gd-GB.ini index ecb1814..691e33f 100644 --- a/plugins/decklink/data/locale/gd-GB.ini +++ b/plugins/decklink/data/locale/gd-GB.ini @@ -1,9 +1,7 @@ Device="Uidheam" Mode="Modh" Buffering="Cleachd bufaireadh" -ColorSpace="Spàs dhathan YUV" ColorSpace.Default="Bun-roghainn" -ColorRange="Rainse dhathan YUV" ColorRange.Default="Bun-roghainn" ColorRange.Partial="Leth-phàirteach" ColorRange.Full="Làn" diff --git a/plugins/decklink/data/locale/hu-HU.ini b/plugins/decklink/data/locale/hu-HU.ini index 7ed2de1..3a5b236 100644 --- a/plugins/decklink/data/locale/hu-HU.ini +++ b/plugins/decklink/data/locale/hu-HU.ini @@ -3,9 +3,9 @@ Device="Eszköz" Mode="Mód" Buffering="Pufferelés használata" PixelFormat="Képpont formátum" -ColorSpace="YUV színtér" +ColorSpace="Színtér" ColorSpace.Default="Alapértelmezett" -ColorRange="YUV színtartomány" +ColorRange="Színtartomány" ColorRange.Default="Alapértelmezett" ColorRange.Partial="Részleges" ColorRange.Full="Teljes" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4cs" ChannelFormat.4_1ch="4.1cs" ChannelFormat.5_1ch="5.1cs" ChannelFormat.7_1ch="7.1cs" +DeactivateWhenNotShowing="Kikapcsolás, ha nem jelenik meg" +AutoStart="Automatikus start induláskor" +SwapFC-LFE="FC és LFE Megfordítása" +SwapFC-LFE.Tooltip="Elülső középső csatorna és az LFE csatorna megcserélése" +VideoConnection="Videó kapcsolat" +AudioConnection="Audio kapcsolat" diff --git a/plugins/decklink/data/locale/it-IT.ini b/plugins/decklink/data/locale/it-IT.ini index adac817..6572718 100644 --- a/plugins/decklink/data/locale/it-IT.ini +++ b/plugins/decklink/data/locale/it-IT.ini @@ -1,11 +1,11 @@ BlackmagicDevice="Dispositivo Blackmagic" Device="Dispositivo" Mode="Modalità" -Buffering="Usa buffer" +Buffering="Utilizza il buffering" PixelFormat="Formato pixel" -ColorSpace="Spazio colore YUV" +ColorSpace="Spazio colore" ColorSpace.Default="Predefinito" -ColorRange="Gamma di colore YUV" +ColorRange="Gamma di colori" ColorRange.Default="Predefinito" ColorRange.Partial="Parziale" ColorRange.Full="Intero" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 canali" ChannelFormat.4_1ch="4.1 canali" ChannelFormat.5_1ch="5.1 canali" ChannelFormat.7_1ch="7.1 canali" +DeactivateWhenNotShowing="Disattiva quando non visibile" +AutoStart="Avvia assieme a OBS" +SwapFC-LFE="Scambia FC e LFE" +SwapFC-LFE.Tooltip="Scambia il canale centrale davanti con quello LFE" +VideoConnection="Connessione video" +AudioConnection="Connessione audio" diff --git a/plugins/decklink/data/locale/ja-JP.ini b/plugins/decklink/data/locale/ja-JP.ini index a519119..896ff32 100644 --- a/plugins/decklink/data/locale/ja-JP.ini +++ b/plugins/decklink/data/locale/ja-JP.ini @@ -3,9 +3,9 @@ Device="デバイス" Mode="モード" Buffering="バッファリングを使用する" PixelFormat="ピクセルフォーマット" -ColorSpace="YUV 色空間" +ColorSpace="色空間" ColorSpace.Default="既定" -ColorRange="YUV 色範囲" +ColorRange="色範囲" ColorRange.Default="既定" ColorRange.Partial="一部" ColorRange.Full="全部" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="表示中でない場合非アクティブ化する" +AutoStart="起動時に自動的に開始" +SwapFC-LFE="FC と LFE を入れ替え" +SwapFC-LFE.Tooltip="フロントセンターチャンネルとサブウーファーチャンネルを入れ替える" +VideoConnection="映像接続" +AudioConnection="音声接続" diff --git a/plugins/decklink/data/locale/ka-GE.ini b/plugins/decklink/data/locale/ka-GE.ini index a655ee4..79f7ed0 100644 --- a/plugins/decklink/data/locale/ka-GE.ini +++ b/plugins/decklink/data/locale/ka-GE.ini @@ -1,20 +1,26 @@ -BlackmagicDevice="Blackmagic მოწყობილობა" +BlackmagicDevice="Blackmagic-მოწყობილობა" Device="მოწყობილობა" Mode="რეჟიმი" Buffering="ბუფერიზაციის გამოყენება" PixelFormat="პიქსელის ფორმატი" -ColorSpace="YUV ფერთა სისტემა" +ColorSpace="ფერთა სივრცე" ColorSpace.Default="ნაგულისხმევი" -ColorRange="YUV ფერთა გამა" +ColorRange="ფერთა გამა" ColorRange.Default="ნაგულისხმევი" ColorRange.Partial="ნაწილობრივი" ColorRange.Full="სრული" ChannelFormat="არხი" ChannelFormat.None="არცერთი" -ChannelFormat.2_0ch="2 არხიანი" -ChannelFormat.2_1ch="2.1 არხიანი" -ChannelFormat.4_0ch="4 არხიანი" -ChannelFormat.4_1ch="4.1 არხიანი" -ChannelFormat.5_1ch="5.1 არხიანი" -ChannelFormat.7_1ch="7.1 არხიანი" +ChannelFormat.2_0ch="2-არხიანი" +ChannelFormat.2_1ch="2.1-არხიანი" +ChannelFormat.4_0ch="4-არხიანი" +ChannelFormat.4_1ch="4.1-არხიანი" +ChannelFormat.5_1ch="5.1-არხიანი" +ChannelFormat.7_1ch="7.1-არხიანი" +DeactivateWhenNotShowing="გაუქმება, როცა არ ჩანს" +AutoStart="ავტომატური ჩართვა გაშვებისას" +SwapFC-LFE="შენაცვლდეს FC და LFE" +SwapFC-LFE.Tooltip="წინა ცენტრის არხისა და დაბალი სიხშირის არხის შენაცვლება" +VideoConnection="ვიდეოკავშირი" +AudioConnection="ხმოვანი კავშირი" diff --git a/plugins/decklink/data/locale/ko-KR.ini b/plugins/decklink/data/locale/ko-KR.ini index e4450d8..e7b9dc6 100644 --- a/plugins/decklink/data/locale/ko-KR.ini +++ b/plugins/decklink/data/locale/ko-KR.ini @@ -3,9 +3,9 @@ Device="장치" Mode="방식" Buffering="버퍼링 사용" PixelFormat="픽셀 형식" -ColorSpace="YUV 색 공간" +ColorSpace="색 공간" ColorSpace.Default="기본값" -ColorRange="YUV 색상 범위" +ColorRange="색상 범위" ColorRange.Default="기본값" ColorRange.Partial="부분" ColorRange.Full="전체" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4채널" ChannelFormat.4_1ch="4.1채널" ChannelFormat.5_1ch="5.1 채널" ChannelFormat.7_1ch="7.1 채널" +DeactivateWhenNotShowing="보이지 않을 경우 비활성화" +AutoStart="OBS Studio 실행 시 자동 시작" +SwapFC-LFE="FC 와 LFE 교환" +SwapFC-LFE.Tooltip="전면 중앙 채널과 저주파 채널 교환" +VideoConnection="비디오 연결" +AudioConnection="오디오 연결" diff --git a/plugins/decklink/data/locale/mn-MN.ini b/plugins/decklink/data/locale/mn-MN.ini new file mode 100644 index 0000000..2bdc181 --- /dev/null +++ b/plugins/decklink/data/locale/mn-MN.ini @@ -0,0 +1,2 @@ +DeactivateWhenNotShowing="Харуулаагүй байга үед идэвхгүй болгох" + diff --git a/plugins/decklink/data/locale/nb-NO.ini b/plugins/decklink/data/locale/nb-NO.ini index d93b304..682d9c9 100644 --- a/plugins/decklink/data/locale/nb-NO.ini +++ b/plugins/decklink/data/locale/nb-NO.ini @@ -3,9 +3,9 @@ Device="Enhet" Mode="Modus" Buffering="Bruk bufring" PixelFormat="Pikselformat" -ColorSpace="YUV fargerom" +ColorSpace="Fargerom" ColorSpace.Default="Standard" -ColorRange="YUV fargerom" +ColorRange="Fargespekter" ColorRange.Default="Standard" ColorRange.Partial="Delvis" ColorRange.Full="Hel" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Deaktiver når denne ikke vises" +AutoStart="Automatisk start ved oppstart" +SwapFC-LFE="Bytt FC og LFE" +SwapFC-LFE.Tooltip="Bytt front-kanal og LFE-kanal" +VideoConnection="Videotilkobling" +AudioConnection="Lydtilkobling" diff --git a/plugins/decklink/data/locale/nl-NL.ini b/plugins/decklink/data/locale/nl-NL.ini index e610e7c..a2be026 100644 --- a/plugins/decklink/data/locale/nl-NL.ini +++ b/plugins/decklink/data/locale/nl-NL.ini @@ -3,9 +3,9 @@ Device="Apparaat" Mode="Modus" Buffering="Buffering Gebruiken" PixelFormat="Pixelindeling" -ColorSpace="YUV-Kleurruimte" +ColorSpace="Kleurruimte" ColorSpace.Default="Standaard" -ColorRange="YUV Kleurbereik" +ColorRange="Kleurbereik" ColorRange.Default="Standaard" ColorRange.Partial="Gedeeltelijk" ColorRange.Full="Volledig" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Deactiveer wanneer niet zichtbaar" +AutoStart="Autostart bij lancering" +SwapFC-LFE="Wissel FC en LFE" +SwapFC-LFE.Tooltip="Verwissel midden voor kanaal en lage tonenkanaal" +VideoConnection="Videoverbinding" +AudioConnection="Audio-verbinding" diff --git a/plugins/decklink/data/locale/pl-PL.ini b/plugins/decklink/data/locale/pl-PL.ini index 92a226a..f2addfc 100644 --- a/plugins/decklink/data/locale/pl-PL.ini +++ b/plugins/decklink/data/locale/pl-PL.ini @@ -3,9 +3,9 @@ Device="Urządzenie" Mode="Tryb" Buffering="Użyj buforowania" PixelFormat="Format pikseli" -ColorSpace="Przestrzeń kolorów YUV" +ColorSpace="Przestrzeń kolorów" ColorSpace.Default="Domyślne" -ColorRange="Zakres kolorów YUV" +ColorRange="Zakres kolorów" ColorRange.Default="Domyślne" ColorRange.Partial="Częściowy" ColorRange.Full="Pełny" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4.0" ChannelFormat.4_1ch="4.1" ChannelFormat.5_1ch="5.1" ChannelFormat.7_1ch="7.1" +DeactivateWhenNotShowing="Wyłącz, gdy nie jest pokazywane" +AutoStart="Uruchamiaj automatycznie przy starcie" +SwapFC-LFE="Zamień FC i LFE" +SwapFC-LFE.Tooltip="Zamień centralny kanał z subwooferem" +VideoConnection="Połączenie wideo" +AudioConnection="Połączenie audio" diff --git a/plugins/decklink/data/locale/pt-BR.ini b/plugins/decklink/data/locale/pt-BR.ini index cabb030..298273f 100644 --- a/plugins/decklink/data/locale/pt-BR.ini +++ b/plugins/decklink/data/locale/pt-BR.ini @@ -3,9 +3,9 @@ Device="Dispositivo" Mode="Modo" Buffering="Utilizar Buffering" PixelFormat="Formato de Pixel" -ColorSpace="Espaço de cor YUV" +ColorSpace="Espaço de cor" ColorSpace.Default="Padrão" -ColorRange="Intervalo de Cores YUV" +ColorRange="Faixa de cores" ColorRange.Default="Padrão" ColorRange.Partial="Parcial" ColorRange.Full="Completo" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4.0" ChannelFormat.4_1ch="4.1" ChannelFormat.5_1ch="5.1" ChannelFormat.7_1ch="7.1" +DeactivateWhenNotShowing="Desativar quando não estiver visível" +AutoStart="Iniciar ao abrir o OBS" +SwapFC-LFE="Trocar C e SUB" +SwapFC-LFE.Tooltip="Trocar canal Central com o Subwoofer" +VideoConnection="Conexão de Vídeo" +AudioConnection="Conexão de Áudio" diff --git a/plugins/decklink/data/locale/pt-PT.ini b/plugins/decklink/data/locale/pt-PT.ini index cc47aa0..e23f4d7 100644 --- a/plugins/decklink/data/locale/pt-PT.ini +++ b/plugins/decklink/data/locale/pt-PT.ini @@ -3,7 +3,18 @@ Device="Dispositivo" Mode="Modo" Buffering="Utilizar Buffering" PixelFormat="Formato de pixel" +ColorSpace.Default="Predefinido" +ColorRange.Default="Predefinido" ColorRange.Partial="Parcial" +ColorRange.Full="Completo" ChannelFormat="Canal" ChannelFormat.None="Nenhum" +ChannelFormat.2_0ch="2ch" +ChannelFormat.2_1ch="2.1ch" +ChannelFormat.4_0ch="4ch" +ChannelFormat.4_1ch="4.1ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Desativar quando não visível" +AutoStart="Iniciar automaticamente ao arrancar" diff --git a/plugins/decklink/data/locale/ro-RO.ini b/plugins/decklink/data/locale/ro-RO.ini index e3a29fa..24515cf 100644 --- a/plugins/decklink/data/locale/ro-RO.ini +++ b/plugins/decklink/data/locale/ro-RO.ini @@ -1,6 +1,8 @@ BlackmagicDevice="Dispozitiv Blackmagic" Device="Dispozitiv" Mode="Mod" -Buffering="Folosește buffering" +Buffering="Folosește zona tampon" PixelFormat="Formatul pixelilor" +ColorSpace.Default="Implicit" +ColorRange.Default="Implicit" diff --git a/plugins/decklink/data/locale/ru-RU.ini b/plugins/decklink/data/locale/ru-RU.ini index 0dce592..fccde7c 100644 --- a/plugins/decklink/data/locale/ru-RU.ini +++ b/plugins/decklink/data/locale/ru-RU.ini @@ -3,9 +3,9 @@ Device="Устройство" Mode="Режим" Buffering="Использовать буферизацию" PixelFormat="Формат пикселей" -ColorSpace="Цветовое пространство YUV" +ColorSpace="Цветовое пространство" ColorSpace.Default="По умолчанию" -ColorRange="Цветовой диапазон YUV" +ColorRange="Цветовой диапазон" ColorRange.Default="По умолчанию" ColorRange.Partial="Частичный" ColorRange.Full="Полный" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4-канальный" ChannelFormat.4_1ch="4.1-канальный" ChannelFormat.5_1ch="5.1-канальный" ChannelFormat.7_1ch="7.1-канальный" +DeactivateWhenNotShowing="Выключать, когда не показывается" +AutoStart="Авто-старт при запуске" +SwapFC-LFE="Обменять ПЦ и LFE" +SwapFC-LFE.Tooltip="Обменять передний центральный канал и LFE канал" +VideoConnection="Видео соединение" +AudioConnection="Аудио соединение" diff --git a/plugins/decklink/data/locale/sk-SK.ini b/plugins/decklink/data/locale/sk-SK.ini index 439f7dd..be2e463 100644 --- a/plugins/decklink/data/locale/sk-SK.ini +++ b/plugins/decklink/data/locale/sk-SK.ini @@ -3,15 +3,24 @@ Device="Zariadenie" Mode="Mód" Buffering="Použiť vyrovnávaciu pamäť" PixelFormat="Formát pixelov" -ColorSpace="Farebný priestor YUV" +ColorSpace="Farebný priestor" ColorSpace.Default="Predvolený" -ColorRange="Rozsah farieb YUV" +ColorRange="Farebný rozsah" ColorRange.Default="Predvolený" ColorRange.Partial="Čiastočný" ColorRange.Full="Plný" ChannelFormat="Kanál" ChannelFormat.None="Nič" ChannelFormat.2_0ch="2ch" +ChannelFormat.2_1ch="2.1ch" ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" +ChannelFormat.5_1ch="5.1ch" +ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Deaktivovať, keď je skrytý" +AutoStart="Automaticky spustiť pri štarte" +SwapFC-LFE="Vymeniť FC a LFE" +SwapFC-LFE.Tooltip="Vymeniť kanál Front Center a kanál LFE" +VideoConnection="Video pripojenie" +AudioConnection="Audio pripojenie" diff --git a/plugins/decklink/data/locale/sr-CS.ini b/plugins/decklink/data/locale/sr-CS.ini index 54d4274..64b6ff4 100644 --- a/plugins/decklink/data/locale/sr-CS.ini +++ b/plugins/decklink/data/locale/sr-CS.ini @@ -3,4 +3,18 @@ Device="Uređaj" Mode="Režim" Buffering="Koristi baferovanje" PixelFormat="Piksel format" +ColorSpace.Default="Podrazumevan" +ColorRange.Default="Podrazumevan" +ColorRange.Partial="Delimičan" +ColorRange.Full="Potpun" +ChannelFormat="Kanal" +ChannelFormat.None="Nijedan" +ChannelFormat.2_0ch="2k" +ChannelFormat.2_1ch="2.1k" +ChannelFormat.4_0ch="4k" +ChannelFormat.4_1ch="4.1k" +ChannelFormat.5_1ch="5.1k" +ChannelFormat.7_1ch="7.1k" +DeactivateWhenNotShowing="U slučaju da se ne prikazuje - deaktiviraj" +AutoStart="Automatski uključi pri pokretanju programa" diff --git a/plugins/decklink/data/locale/sr-SP.ini b/plugins/decklink/data/locale/sr-SP.ini index 50bd35b..0bf4dcc 100644 --- a/plugins/decklink/data/locale/sr-SP.ini +++ b/plugins/decklink/data/locale/sr-SP.ini @@ -3,4 +3,18 @@ Device="Уређај" Mode="Режим" Buffering="Користи баферовање" PixelFormat="Пиксел формат" +ColorSpace.Default="Подразумеван" +ColorRange.Default="Подразумеван" +ColorRange.Partial="Делимичан" +ColorRange.Full="Потпун" +ChannelFormat="Канал" +ChannelFormat.None="Ниједан" +ChannelFormat.2_0ch="2к" +ChannelFormat.2_1ch="2.1к" +ChannelFormat.4_0ch="4к" +ChannelFormat.4_1ch="4.1к" +ChannelFormat.5_1ch="5.1к" +ChannelFormat.7_1ch="7.1к" +DeactivateWhenNotShowing="У случају да се не приказује - деактивирај" +AutoStart="Аутоматски укључи при покретању програма" diff --git a/plugins/decklink/data/locale/sv-SE.ini b/plugins/decklink/data/locale/sv-SE.ini index 12f6e39..494e677 100644 --- a/plugins/decklink/data/locale/sv-SE.ini +++ b/plugins/decklink/data/locale/sv-SE.ini @@ -3,9 +3,9 @@ Device="Enhet" Mode="Läge" Buffering="Använd buffert" PixelFormat="Bildpunktsformat" -ColorSpace="YUV-färgrymd" +ColorSpace="Färgrymd" ColorSpace.Default="Standard" -ColorRange="YUV-färgområde" +ColorRange="Färgintervall" ColorRange.Default="Standard" ColorRange.Partial="Partiell" ColorRange.Full="Full" @@ -17,4 +17,10 @@ ChannelFormat.4_0ch="4 kanaler" ChannelFormat.4_1ch="4.1 kanaler" ChannelFormat.5_1ch="5.1 kanaler" ChannelFormat.7_1ch="7.1 kanaler" +DeactivateWhenNotShowing="Inaktivera när den inte visas" +AutoStart="Autostarta vid uppstart" +SwapFC-LFE="Byt FC och LFE" +SwapFC-LFE.Tooltip="Byt Front Center-kanal och LFE-kanal" +VideoConnection="Videoanslutning" +AudioConnection="Ljudanslutning" diff --git a/plugins/decklink/data/locale/tl-PH.ini b/plugins/decklink/data/locale/tl-PH.ini index 6eccea9..6cb8bc9 100644 --- a/plugins/decklink/data/locale/tl-PH.ini +++ b/plugins/decklink/data/locale/tl-PH.ini @@ -3,9 +3,7 @@ Device="Aparato" Mode="I-mode" Buffering="Paggamit ng Buffering" PixelFormat="Ang Format ng Pixel" -ColorSpace="Pagitan sa kulay na YUV" ColorSpace.Default="I-default" -ColorRange="Ang Saklaw ng Kulay na YUV" ColorRange.Default="I-default" ColorRange.Partial="Bahagya" ColorRange.Full="Puno" diff --git a/plugins/decklink/data/locale/tr-TR.ini b/plugins/decklink/data/locale/tr-TR.ini index 1626abf..1c6d8b7 100644 --- a/plugins/decklink/data/locale/tr-TR.ini +++ b/plugins/decklink/data/locale/tr-TR.ini @@ -3,9 +3,9 @@ Device="Aygıt" Mode="Mod" Buffering="Arabelleğe Almayı Kullan" PixelFormat="Piksel Biçimi" -ColorSpace="YUV Renk Alanı" +ColorSpace="Renk Uzayı" ColorSpace.Default="Varsayılan" -ColorRange="YUV Renk Aralığı" +ColorRange="Renk Aralığı" ColorRange.Default="Varsayılan" ColorRange.Partial="Kısmi" ColorRange.Full="Tam" @@ -17,4 +17,8 @@ ChannelFormat.4_0ch="4ch" ChannelFormat.4_1ch="4.1ch" ChannelFormat.5_1ch="5.1ch" ChannelFormat.7_1ch="7.1ch" +DeactivateWhenNotShowing="Gösterilmediğinde devre dışı bırak" +AutoStart="Açılışta otomatik olarak başlat" +VideoConnection="Video Bağlantısı" +AudioConnection="Ses Bağlantısı" diff --git a/plugins/decklink/data/locale/uk-UA.ini b/plugins/decklink/data/locale/uk-UA.ini index 9a12869..6e735b6 100644 --- a/plugins/decklink/data/locale/uk-UA.ini +++ b/plugins/decklink/data/locale/uk-UA.ini @@ -3,9 +3,7 @@ Device="Пристрій" Mode="Режим" Buffering="Увімкнути буферизацію" PixelFormat="Формат пікселів" -ColorSpace="Колірний простір YUV" ColorSpace.Default="За замовчуванням" -ColorRange="Колірний діапазон YUV" ColorRange.Default="За замовчуванням" ColorRange.Partial="Частковий" ColorRange.Full="Повний" @@ -17,4 +15,10 @@ ChannelFormat.4_0ch="4-канальний" ChannelFormat.4_1ch="4.1-канальний" ChannelFormat.5_1ch="5.1-канальний" ChannelFormat.7_1ch="7.1-канальний" +DeactivateWhenNotShowing="Деактивувати, коли не виводиться" +AutoStart="Запускати автоматично" +SwapFC-LFE="Поміняти місцями FC та LFE" +SwapFC-LFE.Tooltip="Міняє місцями Front Center та LFE канали" +VideoConnection="Відео вхід" +AudioConnection="Аудіо вхід" diff --git a/plugins/decklink/data/locale/zh-CN.ini b/plugins/decklink/data/locale/zh-CN.ini index e8b179d..7b42f9a 100644 --- a/plugins/decklink/data/locale/zh-CN.ini +++ b/plugins/decklink/data/locale/zh-CN.ini @@ -2,19 +2,25 @@ BlackmagicDevice="Blackmagic设备" Device="设备" Mode="模式" Buffering="使用缓冲" -PixelFormat="像素格式" -ColorSpace="YUV 颜色空间" +PixelFormat="视频格式" +ColorSpace="色彩空间" ColorSpace.Default="默认" -ColorRange="YUV 颜色范围" +ColorRange="色彩范围" ColorRange.Default="默认" ColorRange.Partial="局部" ColorRange.Full="全部" ChannelFormat="频道" ChannelFormat.None="无" -ChannelFormat.2_0ch="2ch" -ChannelFormat.2_1ch="2.1ch" -ChannelFormat.4_0ch="4ch" -ChannelFormat.4_1ch="4.1ch" -ChannelFormat.5_1ch="5.1ch" -ChannelFormat.7_1ch="7.1ch" +ChannelFormat.2_0ch="双声道" +ChannelFormat.2_1ch="2.1声道" +ChannelFormat.4_0ch="4声道" +ChannelFormat.4_1ch="4.1声道" +ChannelFormat.5_1ch="5.1声道" +ChannelFormat.7_1ch="7.1声道" +DeactivateWhenNotShowing="当不显示时禁用" +AutoStart="启动时自动启动" +SwapFC-LFE="交换 FC 和 LFE" +SwapFC-LFE.Tooltip="切换前中(FC)声道与低频效果(LFE)声道" +VideoConnection="视频连接" +AudioConnection="声音连接" diff --git a/plugins/decklink/data/locale/zh-TW.ini b/plugins/decklink/data/locale/zh-TW.ini index ebbfaaa..ab75c32 100644 --- a/plugins/decklink/data/locale/zh-TW.ini +++ b/plugins/decklink/data/locale/zh-TW.ini @@ -3,18 +3,24 @@ Device="裝置" Mode="模式" Buffering="使用緩衝" PixelFormat="像素格式" -ColorSpace="YUV 色彩空間" +ColorSpace="色彩空間" ColorSpace.Default="預設" -ColorRange="YUV 色彩範圍" +ColorRange="顏色範圍" ColorRange.Default="預設" ColorRange.Partial="部分" ColorRange.Full="完整" ChannelFormat="聲道" ChannelFormat.None="無" -ChannelFormat.2_0ch="雙聲道" +ChannelFormat.2_0ch="雙聲道(2ch)" ChannelFormat.2_1ch="2.1聲道" ChannelFormat.4_0ch="4聲道" ChannelFormat.4_1ch="4.1聲道" ChannelFormat.5_1ch="5.1聲道" ChannelFormat.7_1ch="7.1聲道" +DeactivateWhenNotShowing="不顯示時停用" +AutoStart="啟動時自動開啟" +SwapFC-LFE="切換 FC 和 LFE" +SwapFC-LFE.Tooltip="切換 Front Center (FC) 頻道和 LFE 頻道" +VideoConnection="影像連接" +AudioConnection="聲音連接" diff --git a/plugins/decklink/decklink-device-discovery.hpp b/plugins/decklink/decklink-device-discovery.hpp index 3bb6e3c..9f2842c 100644 --- a/plugins/decklink/decklink-device-discovery.hpp +++ b/plugins/decklink/decklink-device-discovery.hpp @@ -1,10 +1,11 @@ #pragma once +#include +#include "platform.hpp" + #include #include -#include "decklink.hpp" - class DeckLinkDevice; typedef void (*DeviceChangeCallback)(void *param, DeckLinkDevice *device, diff --git a/plugins/decklink/decklink-device-instance.cpp b/plugins/decklink/decklink-device-instance.cpp index 5dc674e..e2e13d1 100644 --- a/plugins/decklink/decklink-device-instance.cpp +++ b/plugins/decklink/decklink-device-instance.cpp @@ -1,19 +1,14 @@ #include "decklink-device-instance.hpp" #include "audio-repack.hpp" +#include "DecklinkInput.hpp" +#include "DecklinkOutput.hpp" + #include #include #include - -#define LOG(level, message, ...) blog(level, "%s: " message, \ - obs_source_get_name(this->decklink->GetSource()), ##__VA_ARGS__) - -#ifdef _WIN32 -#define IS_WIN 1 -#else -#define IS_WIN 0 -#endif +#include static inline enum video_format ConvertPixelFormat(BMDPixelFormat format) { @@ -43,26 +38,26 @@ static inline int ConvertChannelFormat(speaker_layout format) } } -static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format) +static inline audio_repack_mode_t ConvertRepackFormat(speaker_layout format, bool swap) { switch (format) { case SPEAKERS_2POINT1: - return repack_mode_8to3ch_swap23; + return repack_mode_8to3ch; case SPEAKERS_4POINT0: - return repack_mode_8to4ch_swap23; + return repack_mode_8to4ch; case SPEAKERS_4POINT1: - return repack_mode_8to5ch_swap23; + return swap? repack_mode_8to5ch_swap:repack_mode_8to5ch; case SPEAKERS_5POINT1: - return repack_mode_8to6ch_swap23; + return swap ? repack_mode_8to6ch_swap : repack_mode_8to6ch; case SPEAKERS_7POINT1: - return repack_mode_8ch_swap23_swap46_swap57; + return swap ? repack_mode_8ch_swap: repack_mode_8ch; default: assert(false && "No repack requested"); return (audio_repack_mode_t)-1; } } -DeckLinkDeviceInstance::DeckLinkDeviceInstance(DeckLink *decklink_, +DeckLinkDeviceInstance::DeckLinkDeviceInstance(DecklinkBase *decklink_, DeckLinkDevice *device_) : currentFrame(), currentPacket(), decklink(decklink_), device(device_) { @@ -92,7 +87,7 @@ void DeckLinkDeviceInstance::HandleAudioPacket( currentPacket.frames = frameCount; currentPacket.timestamp = timestamp; - if (decklink && !decklink->buffering) { + if (decklink && !static_cast(decklink)->buffering) { currentPacket.timestamp = os_gettime_ns(); currentPacket.timestamp -= (uint64_t)frameCount * 1000000000ULL / @@ -100,13 +95,12 @@ void DeckLinkDeviceInstance::HandleAudioPacket( } int maxdevicechannel = device->GetMaxChannel(); - bool isWin = IS_WIN; if (channelFormat != SPEAKERS_UNKNOWN && channelFormat != SPEAKERS_MONO && channelFormat != SPEAKERS_STEREO && - maxdevicechannel >= 8 && - isWin) { + (channelFormat != SPEAKERS_7POINT1 || static_cast(decklink)->swap) + && maxdevicechannel >= 8) { if (audioRepacker->repack((uint8_t *)bytes, frameCount) < 0) { LOG(LOG_ERROR, "Failed to convert audio packet data"); @@ -120,7 +114,7 @@ void DeckLinkDeviceInstance::HandleAudioPacket( nextAudioTS = timestamp + ((uint64_t)frameCount * 1000000000ULL / 48000ULL) + 1; - obs_source_output_audio(decklink->GetSource(), ¤tPacket); + obs_source_output_audio(static_cast(decklink)->GetSource(), ¤tPacket); } void DeckLinkDeviceInstance::HandleVideoFrame( @@ -141,7 +135,7 @@ void DeckLinkDeviceInstance::HandleVideoFrame( currentFrame.height = (uint32_t)videoFrame->GetHeight(); currentFrame.timestamp = timestamp; - obs_source_output_video(decklink->GetSource(), ¤tFrame); + obs_source_output_video2(static_cast(decklink)->GetSource(), ¤tFrame); } void DeckLinkDeviceInstance::FinalizeStream() @@ -169,7 +163,7 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) currentFrame.format = ConvertPixelFormat(pixelFormat); - colorSpace = decklink->GetColorSpace(); + colorSpace = static_cast(decklink)->GetColorSpace(); if (colorSpace == VIDEO_CS_DEFAULT) { const BMDDisplayModeFlags flags = mode_->GetDisplayModeFlags(); if (flags & bmdDisplayModeColorspaceRec709) @@ -182,8 +176,8 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) activeColorSpace = colorSpace; } - colorRange = decklink->GetColorRange(); - currentFrame.full_range = colorRange == VIDEO_RANGE_FULL; + colorRange = static_cast(decklink)->GetColorRange(); + currentFrame.range = colorRange; video_format_get_parameters(activeColorSpace, colorRange, currentFrame.color_matrix, currentFrame.color_range_min, @@ -197,7 +191,9 @@ void DeckLinkDeviceInstance::SetupVideoFormat(DeckLinkDeviceMode *mode_) #endif } -bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) +bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_, + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection) { if (mode != nullptr) return false; @@ -209,6 +205,40 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) if (!device->GetInput(&input)) return false; + + IDeckLinkConfiguration *deckLinkConfiguration = NULL; + HRESULT result = input->QueryInterface(IID_IDeckLinkConfiguration, + (void**)&deckLinkConfiguration); + if (result != S_OK) + { + LOG(LOG_ERROR, + "Could not obtain the IDeckLinkConfiguration interface: %08x\n", + result); + } else { + if (bmdVideoConnection > 0) { + result = deckLinkConfiguration->SetInt( + bmdDeckLinkConfigVideoInputConnection, bmdVideoConnection); + if (result != S_OK) { + LOG(LOG_ERROR, + "Couldn't set input video port to %d\n\n", + bmdVideoConnection); + } + } + + if (bmdAudioConnection > 0) { + result = deckLinkConfiguration->SetInt( + bmdDeckLinkConfigAudioInputConnection, bmdAudioConnection); + if (result != S_OK) { + LOG(LOG_ERROR, + "Couldn't set input audio port to %d\n\n", + bmdVideoConnection); + } + } + } + + videoConnection = bmdVideoConnection; + audioConnection = bmdAudioConnection; + BMDVideoInputFlags flags; bool isauto = mode_->GetName() == "Auto"; @@ -218,7 +248,7 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) flags = bmdVideoInputEnableFormatDetection; } else { displayMode = mode_->GetDisplayMode(); - pixelFormat = decklink->GetPixelFormat(); + pixelFormat = static_cast(decklink)->GetPixelFormat(); flags = bmdVideoInputFlagDefault; } @@ -231,11 +261,11 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) SetupVideoFormat(mode_); - channelFormat = decklink->GetChannelFormat(); + channelFormat = static_cast(decklink)->GetChannelFormat(); currentPacket.speakers = channelFormat; + swap = static_cast(decklink)->swap; int maxdevicechannel = device->GetMaxChannel(); - bool isWin = IS_WIN; if (channelFormat != SPEAKERS_UNKNOWN) { const int channel = ConvertChannelFormat(channelFormat); @@ -248,11 +278,11 @@ bool DeckLinkDeviceInstance::StartCapture(DeckLinkDeviceMode *mode_) if (channelFormat != SPEAKERS_UNKNOWN && channelFormat != SPEAKERS_MONO && channelFormat != SPEAKERS_STEREO && - maxdevicechannel >= 8 && - isWin) { + (channelFormat != SPEAKERS_7POINT1 || swap) + && maxdevicechannel >= 8) { const audio_repack_mode_t repack_mode = ConvertRepackFormat - (channelFormat); + (channelFormat, swap); audioRepacker = new AudioRepacker(repack_mode); } } @@ -288,6 +318,128 @@ bool DeckLinkDeviceInstance::StopCapture(void) return true; } +bool DeckLinkDeviceInstance::StartOutput(DeckLinkDeviceMode *mode_) +{ + if (mode != nullptr) + return false; + if (mode_ == nullptr) + return false; + + LOG(LOG_INFO, "Starting output..."); + + if (!device->GetOutput(&output)) + return false; + + const HRESULT videoResult = output->EnableVideoOutput( + mode_->GetDisplayMode(), + bmdVideoOutputFlagDefault); + if (videoResult != S_OK) { + LOG(LOG_ERROR, "Failed to enable video output"); + return false; + } + + const HRESULT audioResult = output->EnableAudioOutput( + bmdAudioSampleRate48kHz, + bmdAudioSampleType16bitInteger, + 2, + bmdAudioOutputStreamTimestamped); + if (audioResult != S_OK) { + LOG(LOG_ERROR, "Failed to enable audio output"); + return false; + } + + mode = mode_; + + int keyerMode = device->GetKeyerMode(); + + IDeckLinkKeyer *deckLinkKeyer = nullptr; + if (device->GetKeyer(&deckLinkKeyer)) { + if (keyerMode) { + deckLinkKeyer->Enable(keyerMode == 1); + deckLinkKeyer->SetLevel(255); + } else { + deckLinkKeyer->Disable(); + } + } + + auto decklinkOutput = dynamic_cast(decklink); + if (decklinkOutput == nullptr) + return false; + + int rowBytes = decklinkOutput->GetWidth() * 2; + if (decklinkOutput->keyerMode != 0) { + rowBytes = decklinkOutput->GetWidth() * 4; + } + + BMDPixelFormat pixelFormat = bmdFormat8BitYUV; + if (keyerMode != 0) { + pixelFormat = bmdFormat8BitBGRA; + } + + HRESULT result; + result = output->CreateVideoFrame(decklinkOutput->GetWidth(), + decklinkOutput->GetHeight(), + rowBytes, + pixelFormat, + bmdFrameFlagDefault, + &decklinkOutputFrame); + if (result != S_OK) { + blog(LOG_ERROR ,"failed to make frame 0x%X", result); + return false; + } + + return true; +} + +bool DeckLinkDeviceInstance::StopOutput() +{ + if (mode == nullptr || output == nullptr) + return false; + + LOG(LOG_INFO, "Stopping output of '%s'...", + GetDevice()->GetDisplayName().c_str()); + + output->DisableVideoOutput(); + output->DisableAudioOutput(); + + if (decklinkOutputFrame != nullptr) { + decklinkOutputFrame->Release(); + decklinkOutputFrame = nullptr; + } + + return true; +} + +void DeckLinkDeviceInstance::DisplayVideoFrame(video_data *frame) +{ + auto decklinkOutput = dynamic_cast(decklink); + if (decklinkOutput == nullptr) + return; + + uint8_t *destData; + decklinkOutputFrame->GetBytes((void**)&destData); + + uint8_t *outData = frame->data[0]; + + int rowBytes = decklinkOutput->GetWidth() * 2; + if (device->GetKeyerMode()) { + rowBytes = decklinkOutput->GetWidth() * 4; + } + + std::copy(outData, outData + (decklinkOutput->GetHeight() * + rowBytes), destData); + + output->DisplayVideoFrameSync(decklinkOutputFrame); +} + +void DeckLinkDeviceInstance::WriteAudio(audio_data *frames) +{ + uint32_t sampleFramesWritten; + output->WriteAudioSamplesSync(frames->data[0], + frames->frames, + &sampleFramesWritten); +} + #define TIME_BASE 1000000000 HRESULT STDMETHODCALLTYPE DeckLinkDeviceInstance::VideoInputFrameArrived( diff --git a/plugins/decklink/decklink-device-instance.hpp b/plugins/decklink/decklink-device-instance.hpp index ffbed07..bee60e2 100644 --- a/plugins/decklink/decklink-device-instance.hpp +++ b/plugins/decklink/decklink-device-instance.hpp @@ -1,28 +1,39 @@ #pragma once +#define LOG(level, message, ...) blog(level, "%s: " message, "decklink", ##__VA_ARGS__) + +#include #include "decklink-device.hpp" +#include "../../libobs/media-io/video-scaler.h" class AudioRepacker; +class DecklinkBase; class DeckLinkDeviceInstance : public IDeckLinkInputCallback { protected: - struct obs_source_frame currentFrame; + struct obs_source_frame2 currentFrame; struct obs_source_audio currentPacket; - DeckLink *decklink = nullptr; + DecklinkBase *decklink = nullptr; DeckLinkDevice *device = nullptr; DeckLinkDeviceMode *mode = nullptr; + BMDVideoConnection videoConnection; + BMDAudioConnection audioConnection; BMDDisplayMode displayMode = bmdModeNTSC; BMDPixelFormat pixelFormat = bmdFormat8BitYUV; video_colorspace colorSpace = VIDEO_CS_DEFAULT; video_colorspace activeColorSpace = VIDEO_CS_DEFAULT; video_range_type colorRange = VIDEO_RANGE_DEFAULT; ComPtr input; + ComPtr output; volatile long refCount = 1; int64_t audioOffset = 0; uint64_t nextAudioTS = 0; uint64_t lastVideoTS = 0; AudioRepacker *audioRepacker = nullptr; speaker_layout channelFormat = SPEAKERS_STEREO; + bool swap; + + IDeckLinkMutableVideoFrame *decklinkOutputFrame = nullptr; void FinalizeStream(); void SetupVideoFormat(DeckLinkDeviceMode *mode_); @@ -33,7 +44,7 @@ protected: const uint64_t timestamp); public: - DeckLinkDeviceInstance(DeckLink *decklink, DeckLinkDevice *device); + DeckLinkDeviceInstance(DecklinkBase *decklink, DeckLinkDevice *device); virtual ~DeckLinkDeviceInstance(); inline DeckLinkDevice *GetDevice() const {return device;} @@ -46,12 +57,20 @@ public: inline video_colorspace GetActiveColorSpace() const {return colorSpace;} inline video_range_type GetActiveColorRange() const {return colorRange;} inline speaker_layout GetActiveChannelFormat() const {return channelFormat;} + inline bool GetActiveSwapState() const {return swap;} + inline BMDVideoConnection GetVideoConnection() const {return videoConnection;} + inline BMDAudioConnection GetAudioConnection() const {return audioConnection;} inline DeckLinkDeviceMode *GetMode() const {return mode;} - bool StartCapture(DeckLinkDeviceMode *mode); + bool StartCapture(DeckLinkDeviceMode *mode, + BMDVideoConnection bmdVideoConnection, + BMDAudioConnection bmdAudioConnection); bool StopCapture(void); + bool StartOutput(DeckLinkDeviceMode *mode_); + bool StopOutput(void); + HRESULT STDMETHODCALLTYPE VideoInputFrameArrived( IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioPacket); @@ -63,4 +82,7 @@ public: ULONG STDMETHODCALLTYPE AddRef(void); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv); ULONG STDMETHODCALLTYPE Release(void); + + void DisplayVideoFrame(video_data *frame); + void WriteAudio(audio_data *frames); }; diff --git a/plugins/decklink/decklink-device-mode.cpp b/plugins/decklink/decklink-device-mode.cpp index 48d6eac..67a052b 100644 --- a/plugins/decklink/decklink-device-mode.cpp +++ b/plugins/decklink/decklink-device-mode.cpp @@ -32,6 +32,22 @@ BMDDisplayMode DeckLinkDeviceMode::GetDisplayMode(void) const return bmdModeUnknown; } +int DeckLinkDeviceMode::GetWidth() +{ + if (mode != nullptr) + return mode->GetWidth(); + + return 0; +} + +int DeckLinkDeviceMode::GetHeight() +{ + if (mode != nullptr) + return mode->GetHeight(); + + return 0; +} + BMDDisplayModeFlags DeckLinkDeviceMode::GetDisplayModeFlags(void) const { if (mode != nullptr) diff --git a/plugins/decklink/decklink-device-mode.hpp b/plugins/decklink/decklink-device-mode.hpp index 8ff642d..ae00153 100644 --- a/plugins/decklink/decklink-device-mode.hpp +++ b/plugins/decklink/decklink-device-mode.hpp @@ -23,4 +23,7 @@ public: const std::string& GetName(void) const; void SetMode(IDeckLinkDisplayMode *mode); + + int GetWidth(); + int GetHeight(); }; diff --git a/plugins/decklink/decklink-device.cpp b/plugins/decklink/decklink-device.cpp index d173053..c2166cd 100644 --- a/plugins/decklink/decklink-device.cpp +++ b/plugins/decklink/decklink-device.cpp @@ -1,4 +1,4 @@ -#include +#include #include "decklink-device.hpp" @@ -10,7 +10,10 @@ DeckLinkDevice::DeckLinkDevice(IDeckLink *device_) : device(device_) DeckLinkDevice::~DeckLinkDevice(void) { - for (DeckLinkDeviceMode *mode : modes) + for (DeckLinkDeviceMode *mode : inputModes) + delete mode; + + for (DeckLinkDeviceMode *mode : outputModes) delete mode; } @@ -37,37 +40,85 @@ bool DeckLinkDevice::Init() decklink_bool_t detectable = false; if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &detectable) == S_OK && !!detectable) { - DeckLinkDeviceMode *mode = - new DeckLinkDeviceMode("Auto", MODE_ID_AUTO); - modes.push_back(mode); - modeIdMap[MODE_ID_AUTO] = mode; + DeckLinkDeviceMode *mode = new DeckLinkDeviceMode( + "Auto", + MODE_ID_AUTO); + inputModes.push_back(mode); + inputModeIdMap[MODE_ID_AUTO] = mode; } } + // Find input modes ComPtr input; - if (device->QueryInterface(IID_IDeckLinkInput, (void**)&input) != S_OK) - return false; + if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) { + IDeckLinkDisplayModeIterator *modeIterator; + if (input->GetDisplayModeIterator(&modeIterator) == S_OK) { + IDeckLinkDisplayMode *displayMode; + long long modeId = 1; - IDeckLinkDisplayModeIterator *modeIterator; - if (input->GetDisplayModeIterator(&modeIterator) == S_OK) { - IDeckLinkDisplayMode *displayMode; - long long modeId = 1; + while (modeIterator->Next(&displayMode) == S_OK) { + if (displayMode == nullptr) + continue; - while (modeIterator->Next(&displayMode) == S_OK) { - if (displayMode == nullptr) - continue; + DeckLinkDeviceMode *mode = + new DeckLinkDeviceMode(displayMode, modeId); + inputModes.push_back(mode); + inputModeIdMap[modeId] = mode; + displayMode->Release(); + ++modeId; + } - DeckLinkDeviceMode *mode = - new DeckLinkDeviceMode(displayMode, modeId); - modes.push_back(mode); - modeIdMap[modeId] = mode; - displayMode->Release(); - ++modeId; + modeIterator->Release(); } - - modeIterator->Release(); } + // Get supported video connections + attributes->GetInt(BMDDeckLinkVideoInputConnections, + &supportedVideoInputConnections); + attributes->GetInt(BMDDeckLinkVideoOutputConnections, + &supportedVideoOutputConnections); + + // Get supported audio connections + attributes->GetInt(BMDDeckLinkAudioInputConnections, + &supportedAudioInputConnections); + attributes->GetInt(BMDDeckLinkAudioOutputConnections, + &supportedAudioOutputConnections); + + // find output modes + ComPtr output; + if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) { + + IDeckLinkDisplayModeIterator *modeIterator; + if (output->GetDisplayModeIterator(&modeIterator) == S_OK) { + IDeckLinkDisplayMode *displayMode; + long long modeId = 1; + + while (modeIterator->Next(&displayMode) == S_OK) { + if (displayMode == nullptr) + continue; + + DeckLinkDeviceMode *mode = + new DeckLinkDeviceMode(displayMode, modeId); + outputModes.push_back(mode); + outputModeIdMap[modeId] = mode; + displayMode->Release(); + ++modeId; + } + + modeIterator->Release(); + } + } + + // get keyer support + attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, + &supportsExternalKeyer); + attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, + &supportsInternalKeyer); + + // Sub Device Counts + attributes->GetInt(BMDDeckLinkSubDeviceIndex, &subDeviceIndex); + attributes->GetInt(BMDDeckLinkNumberOfSubDevices, &numSubDevices); + decklink_string_t decklinkModelName; decklink_string_t decklinkDisplayName; @@ -115,9 +166,43 @@ bool DeckLinkDevice::GetInput(IDeckLinkInput **input) return true; } -DeckLinkDeviceMode *DeckLinkDevice::FindMode(long long id) +bool DeckLinkDevice::GetOutput(IDeckLinkOutput **output) { - return modeIdMap[id]; + if (device->QueryInterface(IID_IDeckLinkOutput, (void**)output) != S_OK) + return false; + + return true; +} + +bool DeckLinkDevice::GetKeyer(IDeckLinkKeyer **deckLinkKeyer) +{ + if (device->QueryInterface(IID_IDeckLinkKeyer, (void**)deckLinkKeyer) != S_OK) + { + fprintf(stderr, "Could not obtain the IDeckLinkKeyer interface\n"); + return false; + } + + return true; +} + +void DeckLinkDevice::SetKeyerMode(int newKeyerMode) +{ + keyerMode = newKeyerMode; +} + +int DeckLinkDevice::GetKeyerMode(void) +{ + return keyerMode; +} + +DeckLinkDeviceMode *DeckLinkDevice::FindInputMode(long long id) +{ + return inputModeIdMap[id]; +} + +DeckLinkDeviceMode *DeckLinkDevice::FindOutputMode(long long id) +{ + return outputModeIdMap[id]; } const std::string& DeckLinkDevice::GetDisplayName(void) @@ -130,9 +215,45 @@ const std::string& DeckLinkDevice::GetHash(void) const return hash; } -const std::vector& DeckLinkDevice::GetModes(void) const +const std::vector& DeckLinkDevice::GetInputModes(void) const { - return modes; + return inputModes; +} + +const std::vector& DeckLinkDevice::GetOutputModes(void) const +{ + return outputModes; +} + +int64_t DeckLinkDevice::GetVideoInputConnections() +{ + return supportedVideoInputConnections; +} + +int64_t DeckLinkDevice::GetAudioInputConnections() +{ + return supportedAudioInputConnections; +} + + +bool DeckLinkDevice::GetSupportsExternalKeyer(void) const +{ + return supportsExternalKeyer; +} + +bool DeckLinkDevice::GetSupportsInternalKeyer(void) const +{ + return supportsInternalKeyer; +} + +int64_t DeckLinkDevice::GetSubDeviceCount() +{ + return numSubDevices; +} + +int64_t DeckLinkDevice::GetSubDeviceIndex() +{ + return subDeviceIndex; } const std::string& DeckLinkDevice::GetName(void) const diff --git a/plugins/decklink/decklink-device.hpp b/plugins/decklink/decklink-device.hpp index 9825ad8..a882a6c 100644 --- a/plugins/decklink/decklink-device.hpp +++ b/plugins/decklink/decklink-device.hpp @@ -1,20 +1,33 @@ -#pragma once +#pragma once -#include "decklink.hpp" #include "decklink-device-mode.hpp" #include #include #include +#include + + class DeckLinkDevice { ComPtr device; - std::map modeIdMap; - std::vector modes; + std::map inputModeIdMap; + std::vector inputModes; + std::map outputModeIdMap; + std::vector outputModes; std::string name; std::string displayName; std::string hash; - int32_t maxChannel; + int32_t maxChannel = 0; + decklink_bool_t supportsExternalKeyer = false; + decklink_bool_t supportsInternalKeyer = false; + int64_t subDeviceIndex = 0; + int64_t numSubDevices = 0; + int64_t supportedVideoInputConnections = -1; + int64_t supportedVideoOutputConnections = -1; + int64_t supportedAudioInputConnections = -1; + int64_t supportedAudioOutputConnections = -1; + int keyerMode = 0; volatile long refCount = 1; public: @@ -26,14 +39,26 @@ public: bool Init(); - DeckLinkDeviceMode *FindMode(long long id); + DeckLinkDeviceMode *FindInputMode(long long id); + DeckLinkDeviceMode *FindOutputMode(long long id); const std::string& GetDisplayName(void); const std::string& GetHash(void) const; - const std::vector& GetModes(void) const; + const std::vector& GetInputModes(void) const; + const std::vector& GetOutputModes(void) const; + int64_t GetVideoInputConnections(); + int64_t GetAudioInputConnections(); + bool GetSupportsExternalKeyer(void) const; + bool GetSupportsInternalKeyer(void) const; + int64_t GetSubDeviceCount(); + int64_t GetSubDeviceIndex(); + int GetKeyerMode(void); + void SetKeyerMode(int newKeyerMode); const std::string& GetName(void) const; int32_t GetMaxChannel(void) const; bool GetInput(IDeckLinkInput **input); + bool GetOutput(IDeckLinkOutput **output); + bool GetKeyer(IDeckLinkKeyer **keyer); inline bool IsDevice(IDeckLink *device_) { diff --git a/plugins/decklink/decklink-devices.cpp b/plugins/decklink/decklink-devices.cpp new file mode 100644 index 0000000..28607ef --- /dev/null +++ b/plugins/decklink/decklink-devices.cpp @@ -0,0 +1,17 @@ +#include "decklink-devices.hpp" + +DeckLinkDeviceDiscovery *deviceEnum = nullptr; + +void fill_out_devices(obs_property_t *list) +{ + deviceEnum->Lock(); + + const std::vector &devices = deviceEnum->GetDevices(); + for (DeckLinkDevice *device : devices) { + obs_property_list_add_string(list, + device->GetDisplayName().c_str(), + device->GetHash().c_str()); + } + + deviceEnum->Unlock(); +} diff --git a/plugins/decklink/decklink-devices.hpp b/plugins/decklink/decklink-devices.hpp new file mode 100644 index 0000000..fa1d24c --- /dev/null +++ b/plugins/decklink/decklink-devices.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include "decklink-device.hpp" +#include "decklink-device-discovery.hpp" + +extern DeckLinkDeviceDiscovery *deviceEnum; + +void fill_out_devices(obs_property_t *list); diff --git a/plugins/decklink/decklink-output.cpp b/plugins/decklink/decklink-output.cpp new file mode 100644 index 0000000..a5cf2f4 --- /dev/null +++ b/plugins/decklink/decklink-output.cpp @@ -0,0 +1,262 @@ +#include +#include + +#include "const.h" + +#include "DecklinkOutput.hpp" +#include "decklink-device.hpp" +#include "decklink-device-discovery.hpp" +#include "decklink-devices.hpp" + +#include "../../libobs/media-io/video-scaler.h" + +static void decklink_output_destroy(void *data) +{ + auto *decklink = (DeckLinkOutput *)data; + delete decklink; +} + +static void *decklink_output_create(obs_data_t *settings, obs_output_t *output) +{ + auto *decklinkOutput = new DeckLinkOutput(output, deviceEnum); + + decklinkOutput->deviceHash = obs_data_get_string(settings, DEVICE_HASH); + decklinkOutput->modeID = obs_data_get_int(settings, MODE_ID); + decklinkOutput->keyerMode = obs_data_get_int(settings, KEYER); + + return decklinkOutput; +} + +static void decklink_output_update(void *data, obs_data_t *settings) +{ + auto *decklink = (DeckLinkOutput *)data; + + decklink->deviceHash = obs_data_get_string(settings, DEVICE_HASH); + decklink->modeID = obs_data_get_int(settings, MODE_ID); + decklink->keyerMode = obs_data_get_int(settings, KEYER); +} + +static bool decklink_output_start(void *data) +{ + auto *decklink = (DeckLinkOutput *)data; + struct obs_audio_info aoi; + + if (!obs_get_audio_info(&aoi)) { + blog(LOG_WARNING, "No active audio"); + return false; + } + + decklink->audio_samplerate = aoi.samples_per_sec; + decklink->audio_planes = 2; + decklink->audio_size = get_audio_size(AUDIO_FORMAT_16BIT, aoi.speakers, 1); + + decklink->start_timestamp = 0; + + ComPtr device; + + device.Set(deviceEnum->FindByHash(decklink->deviceHash)); + + DeckLinkDeviceMode *mode = device->FindOutputMode(decklink->modeID); + + decklink->SetSize(mode->GetWidth(), mode->GetHeight()); + + struct video_scale_info to = {}; + + if (decklink->keyerMode != 0) { + to.format = VIDEO_FORMAT_BGRA; + } else { + to.format = VIDEO_FORMAT_UYVY; + } + to.width = mode->GetWidth(); + to.height = mode->GetHeight(); + + obs_output_set_video_conversion(decklink->GetOutput(), &to); + + device->SetKeyerMode(decklink->keyerMode); + decklink->Activate(device, decklink->modeID); + + struct audio_convert_info conversion = {}; + conversion.format = AUDIO_FORMAT_16BIT; + conversion.speakers = SPEAKERS_STEREO; + conversion.samples_per_sec = 48000; // Only format the decklink supports + + obs_output_set_audio_conversion(decklink->GetOutput(), &conversion); + + if (!obs_output_begin_data_capture(decklink->GetOutput(), 0)) + return false; + + return true; +} + +static void decklink_output_stop(void *data, uint64_t) +{ + auto *decklink = (DeckLinkOutput *)data; + + obs_output_end_data_capture(decklink->GetOutput()); + + ComPtr device; + + device.Set(deviceEnum->FindByHash(decklink->deviceHash)); + + decklink->Deactivate(); +} + +static void decklink_output_raw_video(void *data, struct video_data *frame) +{ + auto *decklink = (DeckLinkOutput *)data; + + if (!decklink->start_timestamp) + decklink->start_timestamp = frame->timestamp; + + decklink->DisplayVideoFrame(frame); +} + +static bool prepare_audio(DeckLinkOutput *decklink, + const struct audio_data *frame, + struct audio_data *output) +{ + *output = *frame; + + if (frame->timestamp < decklink->start_timestamp) { + uint64_t duration = (uint64_t)frame->frames * 1000000000 / + (uint64_t)decklink->audio_samplerate; + uint64_t end_ts = frame->timestamp + duration; + uint64_t cutoff; + + if (end_ts <= decklink->start_timestamp) + return false; + + cutoff = decklink->start_timestamp - frame->timestamp; + output->timestamp += cutoff; + + cutoff *= (uint64_t)decklink->audio_samplerate / 1000000000; + + for (size_t i = 0; i < decklink->audio_planes; i++) + output->data[i] += decklink->audio_size * + (uint32_t)cutoff; + + output->frames -= (uint32_t)cutoff; + } + + return true; +} + +static void decklink_output_raw_audio(void *data, struct audio_data *frames) +{ + auto *decklink = (DeckLinkOutput *)data; + struct audio_data in; + + if (!decklink->start_timestamp) + return; + + if (!prepare_audio(decklink, frames, &in)) + return; + + decklink->WriteAudio(&in); +} + +static bool decklink_output_device_changed(obs_properties_t *props, + obs_property_t *list, obs_data_t *settings) +{ + const char *name = obs_data_get_string(settings, DEVICE_NAME); + const char *hash = obs_data_get_string(settings, DEVICE_HASH); + const char *mode = obs_data_get_string(settings, MODE_NAME); + long long modeId = obs_data_get_int(settings, MODE_ID); + + size_t itemCount = obs_property_list_item_count(list); + bool itemFound = false; + + for (size_t i = 0; i < itemCount; i++) { + const char *curHash = obs_property_list_item_string(list, i); + if (strcmp(hash, curHash) == 0) { + itemFound = true; + break; + } + } + + if (!itemFound) { + obs_property_list_insert_string(list, 0, name, hash); + obs_property_list_item_disable(list, 0, true); + } + + obs_property_t *modeList = obs_properties_get(props, MODE_ID); + obs_property_t *keyerList = obs_properties_get(props, KEYER); + + obs_property_list_clear(modeList); + obs_property_list_clear(keyerList); + + ComPtr device; + device.Set(deviceEnum->FindByHash(hash)); + + if (!device) { + obs_property_list_add_int(modeList, mode, modeId); + obs_property_list_item_disable(modeList, 0, true); + obs_property_list_item_disable(keyerList, 0, true); + } else { + const std::vector &modes = + device->GetOutputModes(); + + for (DeckLinkDeviceMode *mode : modes) { + obs_property_list_add_int(modeList, + mode->GetName().c_str(), + mode->GetId()); + } + + obs_property_list_add_int(keyerList, "Disabled", 0); + + if (device->GetSupportsExternalKeyer()) { + obs_property_list_add_int(keyerList, "External", 1); + } + + if (device->GetSupportsInternalKeyer()) { + obs_property_list_add_int(keyerList, "Internal", 2); + } + } + + return true; +} + +static obs_properties_t *decklink_output_properties(void *unused) +{ + UNUSED_PARAMETER(unused); + obs_properties_t *props = obs_properties_create(); + + obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, + TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_set_modified_callback(list, decklink_output_device_changed); + + fill_out_devices(list); + + obs_properties_add_list(props, + MODE_ID, TEXT_MODE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + + obs_properties_add_bool(props, AUTO_START, TEXT_AUTO_START); + + obs_properties_add_list(props, KEYER, TEXT_ENABLE_KEYER, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + + return props; +} + +static const char *decklink_output_get_name(void*) +{ + return obs_module_text("BlackmagicDevice"); +} + +struct obs_output_info create_decklink_output_info() +{ + struct obs_output_info decklink_output_info = {}; + + decklink_output_info.id = "decklink_output"; + decklink_output_info.flags = OBS_OUTPUT_AV; + decklink_output_info.get_name = decklink_output_get_name; + decklink_output_info.create = decklink_output_create; + decklink_output_info.destroy = decklink_output_destroy; + decklink_output_info.start = decklink_output_start; + decklink_output_info.stop = decklink_output_stop; + decklink_output_info.get_properties = decklink_output_properties; + decklink_output_info.raw_video = decklink_output_raw_video; + decklink_output_info.raw_audio = decklink_output_raw_audio; + decklink_output_info.update = decklink_output_update; + + return decklink_output_info; +} diff --git a/plugins/decklink/decklink-source.cpp b/plugins/decklink/decklink-source.cpp new file mode 100644 index 0000000..f781898 --- /dev/null +++ b/plugins/decklink/decklink-source.cpp @@ -0,0 +1,318 @@ +#include + +#include "const.h" +#include "util.hpp" + +#include "DecklinkInput.hpp" +#include "decklink-device.hpp" +#include "decklink-device-discovery.hpp" +#include "decklink-devices.hpp" + +static void decklink_enable_buffering(DeckLinkInput *decklink, bool enabled) +{ + obs_source_t *source = decklink->GetSource(); + obs_source_set_async_unbuffered(source, !enabled); + decklink->buffering = enabled; +} + +static void decklink_deactivate_when_not_showing(DeckLinkInput *decklink, bool dwns) +{ + decklink->dwns = dwns; +} + +static void *decklink_create(obs_data_t *settings, obs_source_t *source) +{ + DeckLinkInput *decklink = new DeckLinkInput(source, deviceEnum); + + obs_source_set_async_decoupled(source, true); + decklink_enable_buffering(decklink, + obs_data_get_bool(settings, BUFFERING)); + + obs_source_update(source, settings); + return decklink; +} + +static void decklink_destroy(void *data) +{ + DeckLinkInput *decklink = (DeckLinkInput *)data; + delete decklink; +} + +static void decklink_update(void *data, obs_data_t *settings) +{ + DeckLinkInput *decklink = (DeckLinkInput *)data; + const char *hash = obs_data_get_string(settings, DEVICE_HASH); + long long id = obs_data_get_int(settings, MODE_ID); + BMDVideoConnection videoConnection = (BMDVideoConnection) obs_data_get_int(settings, + VIDEO_CONNECTION); + BMDAudioConnection audioConnection = (BMDAudioConnection) obs_data_get_int(settings, + AUDIO_CONNECTION); + BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings, + PIXEL_FORMAT); + video_colorspace colorSpace = (video_colorspace)obs_data_get_int(settings, + COLOR_SPACE); + video_range_type colorRange = (video_range_type)obs_data_get_int(settings, + COLOR_RANGE); + int chFmtInt = (int)obs_data_get_int(settings, CHANNEL_FORMAT); + + if (chFmtInt == 7) + chFmtInt = SPEAKERS_5POINT1; + else if (chFmtInt < SPEAKERS_UNKNOWN || chFmtInt > SPEAKERS_7POINT1) + chFmtInt = 2; + + speaker_layout channelFormat = (speaker_layout)chFmtInt; + + decklink_enable_buffering(decklink, + obs_data_get_bool(settings, BUFFERING)); + + decklink_deactivate_when_not_showing(decklink, + obs_data_get_bool(settings, DEACTIVATE_WNS)); + + ComPtr device; + device.Set(deviceEnum->FindByHash(hash)); + + decklink->SetPixelFormat(pixelFormat); + decklink->SetColorSpace(colorSpace); + decklink->SetColorRange(colorRange); + decklink->SetChannelFormat(channelFormat); + decklink->hash = std::string(hash); + decklink->swap = obs_data_get_bool(settings, SWAP); + decklink->Activate(device, id, videoConnection, audioConnection); +} + +static void decklink_show(void *data) +{ + DeckLinkInput *decklink = (DeckLinkInput *)data; + obs_source_t *source = decklink->GetSource(); + bool showing = obs_source_showing(source); + if (decklink->dwns && showing && !decklink->Capturing()) { + ComPtr device; + device.Set(deviceEnum->FindByHash(decklink->hash.c_str())); + decklink->Activate(device, decklink->id, decklink->videoConnection, + decklink->audioConnection); + } +} +static void decklink_hide(void *data) +{ + DeckLinkInput *decklink = (DeckLinkInput *)data; + obs_source_t *source = decklink->GetSource(); + bool showing = obs_source_showing(source); + if (decklink->dwns && showing) + decklink->Deactivate(); +} + +static void decklink_get_defaults(obs_data_t *settings) +{ + obs_data_set_default_bool(settings, BUFFERING, false); + obs_data_set_default_int(settings, PIXEL_FORMAT, bmdFormat8BitYUV); + obs_data_set_default_int(settings, COLOR_SPACE, VIDEO_CS_DEFAULT); + obs_data_set_default_int(settings, COLOR_RANGE, VIDEO_RANGE_DEFAULT); + obs_data_set_default_int(settings, CHANNEL_FORMAT, SPEAKERS_STEREO); + obs_data_set_default_bool(settings, SWAP, false); +} + +static const char *decklink_get_name(void*) +{ + return obs_module_text("BlackmagicDevice"); +} + +static bool decklink_device_changed(obs_properties_t *props, + obs_property_t *list, obs_data_t *settings) +{ + const char *name = obs_data_get_string(settings, DEVICE_NAME); + const char *hash = obs_data_get_string(settings, DEVICE_HASH); + const char *mode = obs_data_get_string(settings, MODE_NAME); + long long modeId = obs_data_get_int(settings, MODE_ID); + + size_t itemCount = obs_property_list_item_count(list); + bool itemFound = false; + + for (size_t i = 0; i < itemCount; i++) { + const char *curHash = obs_property_list_item_string(list, i); + if (strcmp(hash, curHash) == 0) { + itemFound = true; + break; + } + } + + if (!itemFound) { + obs_property_list_insert_string(list, 0, name, hash); + obs_property_list_item_disable(list, 0, true); + } + + obs_property_t *videoConnectionList = obs_properties_get(props, + VIDEO_CONNECTION); + obs_property_t *audioConnectionList = obs_properties_get(props, + AUDIO_CONNECTION); + obs_property_t *modeList = obs_properties_get(props, MODE_ID); + obs_property_t *channelList = obs_properties_get(props, CHANNEL_FORMAT); + + obs_property_list_clear(videoConnectionList); + obs_property_list_clear(audioConnectionList); + + obs_property_list_clear(modeList); + + obs_property_list_clear(channelList); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_NONE, + SPEAKERS_UNKNOWN); + obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_0CH, + SPEAKERS_STEREO); + + ComPtr device; + device.Set(deviceEnum->FindByHash(hash)); + + if (!device) { + obs_property_list_item_disable(videoConnectionList, 0, true); + obs_property_list_item_disable(audioConnectionList, 0, true); + obs_property_list_add_int(modeList, mode, modeId); + obs_property_list_item_disable(modeList, 0, true); + } else { + const BMDVideoConnection BMDVideoConnections[] = { + bmdVideoConnectionSDI, bmdVideoConnectionHDMI, + bmdVideoConnectionOpticalSDI, bmdVideoConnectionComponent, + bmdVideoConnectionComposite, bmdVideoConnectionSVideo + }; + + for (BMDVideoConnection conn : BMDVideoConnections) { + if ((device->GetVideoInputConnections() & conn) == conn) { + obs_property_list_add_int(videoConnectionList, + bmd_video_connection_to_name(conn), conn); + } + } + + const BMDAudioConnection BMDAudioConnections[] = { + bmdAudioConnectionEmbedded, bmdAudioConnectionAESEBU, + bmdAudioConnectionAnalog, bmdAudioConnectionAnalogXLR, + bmdAudioConnectionAnalogRCA, bmdAudioConnectionMicrophone, + bmdAudioConnectionHeadphones + }; + + for (BMDAudioConnection conn : BMDAudioConnections) { + if ((device->GetAudioInputConnections() & conn) == conn) { + obs_property_list_add_int(audioConnectionList, + bmd_audio_connection_to_name(conn), conn); + } + } + + const std::vector &modes = + device->GetInputModes(); + + for (DeckLinkDeviceMode *mode : modes) { + obs_property_list_add_int(modeList, + mode->GetName().c_str(), + mode->GetId()); + } + + if (device->GetMaxChannel() >= 8) { + obs_property_list_add_int(channelList, + TEXT_CHANNEL_FORMAT_2_1CH, SPEAKERS_2POINT1); + obs_property_list_add_int(channelList, + TEXT_CHANNEL_FORMAT_4_0CH, SPEAKERS_4POINT0); + obs_property_list_add_int(channelList, + TEXT_CHANNEL_FORMAT_4_1CH, SPEAKERS_4POINT1); + obs_property_list_add_int(channelList, + TEXT_CHANNEL_FORMAT_5_1CH, SPEAKERS_5POINT1); + obs_property_list_add_int(channelList, + TEXT_CHANNEL_FORMAT_7_1CH, SPEAKERS_7POINT1); + } + } + + return true; +} + +static bool mode_id_changed(obs_properties_t *props, + obs_property_t *list, obs_data_t *settings) +{ + long long id = obs_data_get_int(settings, MODE_ID); + + list = obs_properties_get(props, PIXEL_FORMAT); + obs_property_set_visible(list, id != MODE_ID_AUTO); + + return true; +} + +static obs_properties_t *decklink_get_properties(void *data) +{ + obs_properties_t *props = obs_properties_create(); + + obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, + TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + obs_property_set_modified_callback(list, decklink_device_changed); + + fill_out_devices(list); + + obs_properties_add_list(props, VIDEO_CONNECTION, TEXT_VIDEO_CONNECTION, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_properties_add_list(props, AUDIO_CONNECTION, TEXT_AUDIO_CONNECTION, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + + list = obs_properties_add_list(props, MODE_ID, TEXT_MODE, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_set_modified_callback(list, mode_id_changed); + + list = obs_properties_add_list(props, PIXEL_FORMAT, + TEXT_PIXEL_FORMAT, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + + obs_property_list_add_int(list, "8-bit YUV", bmdFormat8BitYUV); + obs_property_list_add_int(list, "8-bit BGRA", bmdFormat8BitBGRA); + + list = obs_properties_add_list(props, COLOR_SPACE, TEXT_COLOR_SPACE, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT, VIDEO_CS_DEFAULT); + obs_property_list_add_int(list, "BT.601", VIDEO_CS_601); + obs_property_list_add_int(list, "BT.709", VIDEO_CS_709); + + list = obs_properties_add_list(props, COLOR_RANGE, TEXT_COLOR_RANGE, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT, VIDEO_RANGE_DEFAULT); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL, VIDEO_RANGE_PARTIAL); + obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL, VIDEO_RANGE_FULL); + + list = obs_properties_add_list(props, CHANNEL_FORMAT, + TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE, + SPEAKERS_UNKNOWN); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH, + SPEAKERS_STEREO); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_1CH, + SPEAKERS_2POINT1); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_0CH, + SPEAKERS_4POINT0); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_1CH, + SPEAKERS_4POINT1); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_5_1CH, + SPEAKERS_5POINT1); + obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_7_1CH, + SPEAKERS_7POINT1); + + obs_property_t *swap = obs_properties_add_bool(props, SWAP, TEXT_SWAP); + obs_property_set_long_description(swap, TEXT_SWAP_TOOLTIP); + + obs_properties_add_bool(props, BUFFERING, TEXT_BUFFERING); + + obs_properties_add_bool(props, DEACTIVATE_WNS, TEXT_DWNS); + + UNUSED_PARAMETER(data); + return props; +} + + +struct obs_source_info create_decklink_source_info() +{ + struct obs_source_info decklink_source_info = {}; + decklink_source_info.id = "decklink-input"; + decklink_source_info.type = OBS_SOURCE_TYPE_INPUT; + decklink_source_info.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE; + decklink_source_info.create = decklink_create; + decklink_source_info.destroy = decklink_destroy; + decklink_source_info.get_defaults = decklink_get_defaults; + decklink_source_info.get_name = decklink_get_name; + decklink_source_info.get_properties = decklink_get_properties; + decklink_source_info.update = decklink_update; + decklink_source_info.show = decklink_show; + decklink_source_info.hide = decklink_hide; + + return decklink_source_info; +} diff --git a/plugins/decklink/linux/CMakeLists.txt b/plugins/decklink/linux/CMakeLists.txt index 1ed5ae4..4f006ec 100644 --- a/plugins/decklink/linux/CMakeLists.txt +++ b/plugins/decklink/linux/CMakeLists.txt @@ -21,33 +21,47 @@ set(linux-decklink-sdk_SOURCES ) set(linux-decklink_HEADERS + ../decklink-devices.hpp + ../const.h + ../DecklinkOutput.hpp ../platform.hpp - ../decklink.hpp + ../DecklinkInput.hpp + ../DecklinkBase.h ../decklink-device-instance.hpp ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp ../audio-repack.h ../audio-repack.hpp + ../util.hpp ) set(linux-decklink_SOURCES ../plugin-main.cpp - ../decklink.cpp + ../decklink-devices.cpp + ../decklink-source.cpp + ../decklink-output.cpp + ../DecklinkOutput.cpp + ../DecklinkInput.cpp + ../DecklinkBase.cpp ../decklink-device-instance.cpp ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp ../audio-repack.c - platform.cpp) + platform.cpp + ../util.cpp + ) add_library(linux-decklink MODULE ${linux-decklink_SOURCES} ${linux-decklink_HEADERS} ${linux-decklink-sdk_HEADERS} - ${linux-decklink-sdk_SOURCES}) + ${linux-decklink-sdk_SOURCES} + ) target_link_libraries(linux-decklink - libobs) + libobs + ) install_obs_plugin_with_data(linux-decklink ../data) diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h index 2eed7b7..e113fc3 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + /* DeckLink API */ #include @@ -64,12 +68,16 @@ BMD_CONST REFIID IID_IDeckLinkIterator = /* 50FB36CD- BMD_CONST REFIID IID_IDeckLinkAPIInformation = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ {0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4}; BMD_CONST REFIID IID_IDeckLinkOutput = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64}; BMD_CONST REFIID IID_IDeckLinkInput = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95}; +BMD_CONST REFIID IID_IDeckLinkHDMIInputEDID = /* ABBBACBC-45BC-4665-9D92-ACE6E5A97902 */ {0xAB,0xBB,0xAC,0xBC,0x45,0xBC,0x46,0x65,0x9D,0x92,0xAC,0xE6,0xE5,0xA9,0x79,0x02}; BMD_CONST REFIID IID_IDeckLinkEncoderInput = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85}; BMD_CONST REFIID IID_IDeckLinkVideoFrame = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ {0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17}; BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ {0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90}; BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ {0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7}; BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F}; BMD_CONST REFIID IID_IDeckLinkVideoInputFrame = /* 05CFE374-537C-4094-9A57-680525118F44 */ {0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44}; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacket = /* CC5BBF7E-029C-4D3B-9158-6000EF5E3670 */ {0xCC,0x5B,0xBF,0x7E,0x02,0x9C,0x4D,0x3B,0x91,0x58,0x60,0x00,0xEF,0x5E,0x36,0x70}; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacketIterator = /* 3FC8994B-88FB-4C17-968F-9AAB69D964A7 */ {0x3F,0xC8,0x99,0x4B,0x88,0xFB,0x4C,0x17,0x96,0x8F,0x9A,0xAB,0x69,0xD9,0x64,0xA7}; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillaryPackets = /* 6C186C0F-459E-41D8-AEE2-4812D81AEE68 */ {0x6C,0x18,0x6C,0x0F,0x45,0x9E,0x41,0xD8,0xAE,0xE2,0x48,0x12,0xD8,0x1A,0xEE,0x68}; BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ {0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04}; BMD_CONST REFIID IID_IDeckLinkEncoderPacket = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ {0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20}; BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ {0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0}; @@ -113,9 +121,11 @@ enum _BMDFrameFlags { bmdFrameFlagDefault = 0, bmdFrameFlagFlipVertical = 1 << 0, bmdFrameContainsHDRMetadata = 1 << 1, + bmdFrameContainsCintelMetadata = 1 << 2, /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + bmdFrameCapturedAsPsF = 1 << 30, bmdFrameHasNoInputSource = 1 << 31 }; @@ -159,10 +169,10 @@ enum _BMDDeckLinkCapturePassthroughMode { typedef uint32_t BMDOutputFrameCompletionResult; enum _BMDOutputFrameCompletionResult { - bmdOutputFrameCompleted, - bmdOutputFrameDisplayedLate, - bmdOutputFrameDropped, - bmdOutputFrameFlushed + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed }; /* Enum BMDReferenceStatus - GenLock input status */ @@ -199,9 +209,9 @@ enum _BMDAudioSampleType { typedef uint32_t BMDAudioOutputStreamType; enum _BMDAudioOutputStreamType { - bmdAudioOutputStreamContinuous, - bmdAudioOutputStreamContinuousDontResample, - bmdAudioOutputStreamTimestamped + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped }; /* Enum BMDDisplayModeSupport - Output mode supported flags */ @@ -209,8 +219,17 @@ enum _BMDAudioOutputStreamType { typedef uint32_t BMDDisplayModeSupport; enum _BMDDisplayModeSupport { bmdDisplayModeNotSupported = 0, - bmdDisplayModeSupported, - bmdDisplayModeSupportedWithConversion + bmdDisplayModeSupported, + bmdDisplayModeSupportedWithConversion +}; + +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef uint32_t BMDAncillaryPacketFormat; +enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = /* 'ui08' */ 0x75693038, + bmdAncillaryPacketFormatUInt16 = /* 'ui16' */ 0x75693136, + bmdAncillaryPacketFormatYCbCr10 = /* 'v210' */ 0x76323130 }; /* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ @@ -332,11 +351,68 @@ enum _BMDDeviceInterface { bmdDeviceInterfaceThunderbolt = /* 'thun' */ 0x7468756E }; +/* Enum BMDColorspace - Colorspace */ + +typedef uint32_t BMDColorspace; +enum _BMDColorspace { + bmdColorspaceRec601 = /* 'r601' */ 0x72363031, + bmdColorspaceRec709 = /* 'r709' */ 0x72373039, + bmdColorspaceRec2020 = /* '2020' */ 0x32303230 +}; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef uint32_t BMDDynamicRange; +enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, + bmdDynamicRangeHDRStaticPQ = 1 << 29, // SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // ITU-R BT.2100-0 +}; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef uint32_t BMDDeckLinkHDMIInputEDIDID; +enum _BMDDeckLinkHDMIInputEDIDID { + bmdDeckLinkHDMIInputEDIDDynamicRange = /* 'HIDy' */ 0x48494479 // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +}; + /* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ typedef uint32_t BMDDeckLinkFrameMetadataID; enum _BMDDeckLinkFrameMetadataID { + bmdDeckLinkFrameMetadataColorspace = /* 'cspc' */ 0x63737063, // Colorspace of video frame (see BMDColorspace) bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = /* 'eotf' */ 0x656F7466, // EOTF in range 0-7 as per CEA 861.3 + bmdDeckLinkFrameMetadataCintelFilmType = /* 'cfty' */ 0x63667479, // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge = /* 'cfga' */ 0x63666761, // Current film gauge + bmdDeckLinkFrameMetadataCintelOffsetDetectedHorizontal = /* 'odfh' */ 0x6F646668, // Horizontal offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelOffsetDetectedVertical = /* 'odfv' */ 0x6F646676, // Vertical offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelKeykodeLow = /* 'ckkl' */ 0x636B6B6C, // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh = /* 'ckkh' */ 0x636B6B68, // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size = /* 'ct1s' */ 0x63743173, // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size = /* 'ct2s' */ 0x63743273, // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size = /* 'ct3s' */ 0x63743373, // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size = /* 'ct4s' */ 0x63743473, // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth = /* 'IWPx' */ 0x49575078, // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight = /* 'IHPx' */ 0x49485078, // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed = /* 'mrir' */ 0x6D726972, // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed = /* 'mgir' */ 0x6D676972, // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed = /* 'mbir' */ 0x6D626972, // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen = /* 'mrig' */ 0x6D726967, // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen = /* 'mgig' */ 0x6D676967, // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen = /* 'mbig' */ 0x6D626967, // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue = /* 'mrib' */ 0x6D726962, // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue = /* 'mgib' */ 0x6D676962, // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue = /* 'mbib' */ 0x6D626962, // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed = /* 'mlrr' */ 0x6D6C7272, // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed = /* 'mlgr' */ 0x6D6C6772, // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed = /* 'mlbr' */ 0x6D6C6272, // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen = /* 'mlrg' */ 0x6D6C7267, // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen = /* 'mlgg' */ 0x6D6C6767, // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen = /* 'mlbg' */ 0x6D6C6267, // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue = /* 'mlrb' */ 0x6D6C7262, // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue = /* 'mlgb' */ 0x6D6C6762, // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue = /* 'mlbb' */ 0x6D6C6262, // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate = /* 'cffr' */ 0x63666672, // Film frame rate bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = /* 'hdrx' */ 0x68647278, // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = /* 'hdry' */ 0x68647279, // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = /* 'hdgx' */ 0x68646778, // Green display primaries in range 0.0 - 1.0 @@ -348,7 +424,15 @@ enum _BMDDeckLinkFrameMetadataID { bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = /* 'hdml' */ 0x68646D6C, // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = /* 'hmil' */ 0x686D696C, // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = /* 'mcll' */ 0x6D636C6C, // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 - bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C, // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal = /* 'otah' */ 0x6F746168, // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical = /* 'otav' */ 0x6F746176, // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed = /* 'LfRd' */ 0x4C665264, // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen = /* 'LfGr' */ 0x4C664772, // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue = /* 'LfBl' */ 0x4C66426C, // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed = /* 'GnRd' */ 0x476E5264, // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen = /* 'GnGr' */ 0x476E4772, // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue = /* 'GnBl' */ 0x476E426C // Blue lift parameter to apply after log and gain }; /* Enum BMDDuplexMode - Duplex for configurable ports */ @@ -386,22 +470,24 @@ enum _BMDDeckLinkAttributeID { BMDDeckLinkHasLTCTimecodeInput = /* 'hltc' */ 0x686C7463, BMDDeckLinkSupportsDuplexModeConfiguration = /* 'dupx' */ 0x64757078, BMDDeckLinkSupportsHDRMetadata = /* 'hdrm' */ 0x6864726D, + BMDDeckLinkSupportsColorspaceMetadata = /* 'cmet' */ 0x636D6574, /* Integers */ BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, - BMDDeckLinkMaximumAnalogAudioChannels = /* 'aach' */ 0x61616368, + BMDDeckLinkMaximumAnalogAudioInputChannels = /* 'iach' */ 0x69616368, + BMDDeckLinkMaximumAnalogAudioOutputChannels = /* 'aach' */ 0x61616368, BMDDeckLinkNumberOfSubDevices = /* 'nsbd' */ 0x6E736264, BMDDeckLinkSubDeviceIndex = /* 'subi' */ 0x73756269, BMDDeckLinkPersistentID = /* 'peid' */ 0x70656964, BMDDeckLinkDeviceGroupID = /* 'dgid' */ 0x64676964, BMDDeckLinkTopologicalID = /* 'toid' */ 0x746F6964, - BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, - BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, - BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, - BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, + BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, // Returns a BMDAudioConnection bit field BMDDeckLinkVideoIOSupport = /* 'vios' */ 0x76696F73, // Returns a BMDVideoIOSupport bit field - BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, + BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, // Returns a BMDDeckControlConnection bit field BMDDeckLinkDeviceInterface = /* 'dbus' */ 0x64627573, // Returns a BMDDeviceInterface BMDDeckLinkAudioInputRCAChannelCount = /* 'airc' */ 0x61697263, BMDDeckLinkAudioInputXLRChannelCount = /* 'aixc' */ 0x61697863, @@ -455,11 +541,14 @@ enum _BMDDeckLinkStatusID { bmdDeckLinkStatusReferenceSignalFlags = /* 'reff' */ 0x72656666, bmdDeckLinkStatusDuplexMode = /* 'dupx' */ 0x64757078, bmdDeckLinkStatusBusy = /* 'busy' */ 0x62757379, + bmdDeckLinkStatusInterchangeablePanelType = /* 'icpt' */ 0x69637074, + bmdDeckLinkStatusDeviceTemperature = /* 'dtmp' */ 0x64746D70, /* Flags */ bmdDeckLinkStatusVideoInputSignalLocked = /* 'visl' */ 0x7669736C, - bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C + bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C, + bmdDeckLinkStatusReceivedEDID = /* 'edid' */ 0x65646964 }; /* Enum BMDDeckLinkVideoStatusFlags - */ @@ -480,6 +569,14 @@ enum _BMDDuplexStatus { bmdDuplexStatusInactive = /* 'inac' */ 0x696E6163 }; +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef uint32_t BMDPanelType; +enum _BMDPanelType { + bmdPanelNotDetected = /* 'npnl' */ 0x6E706E6C, + bmdPanelTeranexMiniSmartPanel = /* 'tmsm' */ 0x746D736D +}; + /* Enum BMDDeviceBusyState - Current device busy state */ typedef uint32_t BMDDeviceBusyState; @@ -529,12 +626,16 @@ class IDeckLinkIterator; class IDeckLinkAPIInformation; class IDeckLinkOutput; class IDeckLinkInput; +class IDeckLinkHDMIInputEDID; class IDeckLinkEncoderInput; class IDeckLinkVideoFrame; class IDeckLinkMutableVideoFrame; class IDeckLinkVideoFrame3DExtensions; class IDeckLinkVideoFrameMetadataExtensions; class IDeckLinkVideoInputFrame; +class IDeckLinkAncillaryPacket; +class IDeckLinkAncillaryPacketIterator; +class IDeckLinkVideoFrameAncillaryPackets; class IDeckLinkVideoFrameAncillary; class IDeckLinkEncoderPacket; class IDeckLinkEncoderVideoPacket; @@ -554,7 +655,7 @@ class IDeckLinkDiscovery; /* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ -class IDeckLinkVideoOutputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkVideoOutputCallback : public IUnknown { public: virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; @@ -566,7 +667,7 @@ protected: /* Interface IDeckLinkInputCallback - Frame arrival callback. */ -class IDeckLinkInputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkInputCallback : public IUnknown { public: virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -578,7 +679,7 @@ protected: /* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */ -class IDeckLinkEncoderInputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderInputCallback : public IUnknown { public: virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -591,7 +692,7 @@ protected: /* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ -class IDeckLinkMemoryAllocator : public IUnknown +class BMD_PUBLIC IDeckLinkMemoryAllocator : public IUnknown { public: virtual HRESULT AllocateBuffer (/* in */ uint32_t bufferSize, /* out */ void **allocatedBuffer) = 0; @@ -603,7 +704,7 @@ public: /* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ -class IDeckLinkAudioOutputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkAudioOutputCallback : public IUnknown { public: virtual HRESULT RenderAudioSamples (/* in */ bool preroll) = 0; @@ -611,7 +712,7 @@ public: /* Interface IDeckLinkIterator - enumerates installed DeckLink hardware */ -class IDeckLinkIterator : public IUnknown +class BMD_PUBLIC IDeckLinkIterator : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLink **deckLinkInstance) = 0; @@ -619,7 +720,7 @@ public: /* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ -class IDeckLinkAPIInformation : public IUnknown +class BMD_PUBLIC IDeckLinkAPIInformation : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ bool *value) = 0; @@ -633,7 +734,7 @@ protected: /* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkOutput : public IUnknown +class BMD_PUBLIC IDeckLinkOutput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -648,7 +749,7 @@ public: virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; - virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; @@ -690,7 +791,7 @@ protected: /* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkInput : public IUnknown +class BMD_PUBLIC IDeckLinkInput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -727,9 +828,22 @@ protected: virtual ~IDeckLinkInput () {} // call Release method to drop reference count }; +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +class BMD_PUBLIC IDeckLinkHDMIInputEDID : public IUnknown +{ +public: + virtual HRESULT SetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT WriteToEDID (void) = 0; + +protected: + virtual ~IDeckLinkHDMIInputEDID () {} // call Release method to drop reference count +}; + /* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkEncoderInput : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderInput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -766,7 +880,7 @@ protected: /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ -class IDeckLinkVideoFrame : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame : public IUnknown { public: virtual long GetWidth (void) = 0; @@ -777,7 +891,7 @@ public: virtual HRESULT GetBytes (/* out */ void **buffer) = 0; virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) = 0; - virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred protected: virtual ~IDeckLinkVideoFrame () {} // call Release method to drop reference count @@ -785,7 +899,7 @@ protected: /* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ -class IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame +class BMD_PUBLIC IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame { public: virtual HRESULT SetFlags (/* in */ BMDFrameFlags newFlags) = 0; @@ -801,7 +915,7 @@ protected: /* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */ -class IDeckLinkVideoFrame3DExtensions : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame3DExtensions : public IUnknown { public: virtual BMDVideo3DPackingFormat Get3DPackingFormat (void) = 0; @@ -813,7 +927,7 @@ protected: /* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */ -class IDeckLinkVideoFrameMetadataExtensions : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions : public IUnknown { public: virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t *value) = 0; @@ -827,7 +941,7 @@ protected: /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ -class IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame +class BMD_PUBLIC IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame { public: virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, /* in */ BMDTimeScale timeScale) = 0; @@ -837,13 +951,56 @@ protected: virtual ~IDeckLinkVideoInputFrame () {} // call Release method to drop reference count }; -/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ -class IDeckLinkVideoFrameAncillary : public IUnknown +class BMD_PUBLIC IDeckLinkAncillaryPacket : public IUnknown { public: - virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void **buffer) = 0; + virtual HRESULT GetBytes (/* in */ BMDAncillaryPacketFormat format /* For output, only one format need be offered */, /* out */ const void **data /* Optional */, /* out */ uint32_t *size /* Optional */) = 0; + virtual uint8_t GetDID (void) = 0; + virtual uint8_t GetSDID (void) = 0; + virtual uint32_t GetLineNumber (void) = 0; // On output, zero is auto + virtual uint8_t GetDataStreamIndex (void) = 0; // Usually zero. Can only be 1 if non-SD and the first data stream is completely full + +protected: + virtual ~IDeckLinkAncillaryPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +class BMD_PUBLIC IDeckLinkAncillaryPacketIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkAncillaryPacket **packet) = 0; + +protected: + virtual ~IDeckLinkAncillaryPacketIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets : public IUnknown +{ +public: + + virtual HRESULT GetPacketIterator (/* out */ IDeckLinkAncillaryPacketIterator **iterator) = 0; + virtual HRESULT GetFirstPacketByID (/* in */ uint8_t DID, /* in */ uint8_t SDID, /* out */ IDeckLinkAncillaryPacket **packet) = 0; + virtual HRESULT AttachPacket (/* in */ IDeckLinkAncillaryPacket *packet) = 0; // Implement IDeckLinkAncillaryPacket to output your own + virtual HRESULT DetachPacket (/* in */ IDeckLinkAncillaryPacket *packet) = 0; + virtual HRESULT DetachAllPackets (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillaryPackets () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillary : public IUnknown +{ +public: + + virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void **buffer) = 0; // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes virtual BMDPixelFormat GetPixelFormat (void) = 0; virtual BMDDisplayMode GetDisplayMode (void) = 0; @@ -853,7 +1010,7 @@ protected: /* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */ -class IDeckLinkEncoderPacket : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderPacket : public IUnknown { public: virtual HRESULT GetBytes (/* out */ void **buffer) = 0; @@ -867,7 +1024,7 @@ protected: /* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */ -class IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket +class BMD_PUBLIC IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket { public: virtual BMDPixelFormat GetPixelFormat (void) = 0; @@ -881,7 +1038,7 @@ protected: /* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */ -class IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket +class BMD_PUBLIC IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket { public: virtual BMDAudioFormat GetAudioFormat (void) = 0; @@ -892,7 +1049,7 @@ protected: /* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object */ -class IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket +class BMD_PUBLIC IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket { public: virtual HRESULT GetUnitType (/* out */ uint8_t *unitType) = 0; @@ -905,7 +1062,7 @@ protected: /* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ -class IDeckLinkAudioInputPacket : public IUnknown +class BMD_PUBLIC IDeckLinkAudioInputPacket : public IUnknown { public: virtual long GetSampleFrameCount (void) = 0; @@ -918,7 +1075,7 @@ protected: /* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ -class IDeckLinkScreenPreviewCallback : public IUnknown +class BMD_PUBLIC IDeckLinkScreenPreviewCallback : public IUnknown { public: virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame *theFrame) = 0; @@ -929,7 +1086,7 @@ protected: /* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ -class IDeckLinkGLScreenPreviewHelper : public IUnknown +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper : public IUnknown { public: @@ -946,7 +1103,7 @@ protected: /* Interface IDeckLinkNotificationCallback - DeckLink Notification Callback Interface */ -class IDeckLinkNotificationCallback : public IUnknown +class BMD_PUBLIC IDeckLinkNotificationCallback : public IUnknown { public: virtual HRESULT Notify (/* in */ BMDNotifications topic, /* in */ uint64_t param1, /* in */ uint64_t param2) = 0; @@ -954,7 +1111,7 @@ public: /* Interface IDeckLinkNotification - DeckLink Notification interface */ -class IDeckLinkNotification : public IUnknown +class BMD_PUBLIC IDeckLinkNotification : public IUnknown { public: virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; @@ -963,7 +1120,7 @@ public: /* Interface IDeckLinkAttributes - DeckLink Attribute interface */ -class IDeckLinkAttributes : public IUnknown +class BMD_PUBLIC IDeckLinkAttributes : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool *value) = 0; @@ -977,7 +1134,7 @@ protected: /* Interface IDeckLinkStatus - DeckLink Status interface */ -class IDeckLinkStatus : public IUnknown +class BMD_PUBLIC IDeckLinkStatus : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool *value) = 0; @@ -992,7 +1149,7 @@ protected: /* Interface IDeckLinkKeyer - DeckLink Keyer interface */ -class IDeckLinkKeyer : public IUnknown +class BMD_PUBLIC IDeckLinkKeyer : public IUnknown { public: virtual HRESULT Enable (/* in */ bool isExternal) = 0; @@ -1007,7 +1164,7 @@ protected: /* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ -class IDeckLinkVideoConversion : public IUnknown +class BMD_PUBLIC IDeckLinkVideoConversion : public IUnknown { public: virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame* srcFrame, /* in */ IDeckLinkVideoFrame* dstFrame) = 0; @@ -1018,7 +1175,7 @@ protected: /* Interface IDeckLinkDeviceNotificationCallback - DeckLink device arrival/removal notification callbacks */ -class IDeckLinkDeviceNotificationCallback : public IUnknown +class BMD_PUBLIC IDeckLinkDeviceNotificationCallback : public IUnknown { public: virtual HRESULT DeckLinkDeviceArrived (/* in */ IDeckLink* deckLinkDevice) = 0; @@ -1030,7 +1187,7 @@ protected: /* Interface IDeckLinkDiscovery - DeckLink device discovery */ -class IDeckLinkDiscovery : public IUnknown +class BMD_PUBLIC IDeckLinkDiscovery : public IUnknown { public: virtual HRESULT InstallDeviceNotifications (/* in */ IDeckLinkDeviceNotificationCallback* deviceNotificationCallback) = 0; @@ -1044,11 +1201,12 @@ protected: extern "C" { - IDeckLinkIterator* CreateDeckLinkIteratorInstance (void); - IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void); - IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void); - IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void); - IDeckLinkVideoConversion* CreateVideoConversionInstance (void); + IDeckLinkIterator* BMD_PUBLIC CreateDeckLinkIteratorInstance (void); + IDeckLinkDiscovery* BMD_PUBLIC CreateDeckLinkDiscoveryInstance (void); + IDeckLinkAPIInformation* BMD_PUBLIC CreateDeckLinkAPIInformationInstance (void); + IDeckLinkGLScreenPreviewHelper* BMD_PUBLIC CreateOpenGLScreenPreviewHelper (void); + IDeckLinkVideoConversion* BMD_PUBLIC CreateVideoConversionInstance (void); + IDeckLinkVideoFrameAncillaryPackets* BMD_PUBLIC CreateVideoFrameAncillaryPacketsInstance (void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame } diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h index dedf15e..430f871 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,12 +37,16 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations // Interface ID Declarations -BMD_CONST REFIID IID_IDeckLinkConfiguration = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; +BMD_CONST REFIID IID_IDeckLinkConfiguration = /* EF90380B-4AE5-4346-9077-E288E149F129 */ {0xEF,0x90,0x38,0x0B,0x4A,0xE5,0x43,0x46,0x90,0x77,0xE2,0x88,0xE1,0x49,0xF1,0x29}; BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration = /* 138050E5-C60A-4552-BF3F-0F358049327E */ {0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E}; /* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ @@ -54,10 +58,6 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigSwapSerialRxTx = /* 'ssrt' */ 0x73737274, - /* Video Input/Output Flags */ - - bmdDeckLinkConfigUse1080pNotPsF = /* 'fpro' */ 0x6670726F, - /* Video Input/Output Integers */ bmdDeckLinkConfigHDMI3DPackingFormat = /* '3dpf' */ 0x33647066, @@ -78,6 +78,12 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigLowLatencyVideoOutput = /* 'llvo' */ 0x6C6C766F, bmdDeckLinkConfigDownConversionOnAllAnalogOutput = /* 'caao' */ 0x6361616F, bmdDeckLinkConfigSMPTELevelAOutput = /* 'smta' */ 0x736D7461, + bmdDeckLinkConfigRec2020Output = /* 'rec2' */ 0x72656332, // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = /* 'SDQS' */ 0x53445153, + + /* Video Output Flags */ + + bmdDeckLinkConfigOutput1080pAsPsF = /* 'pfpr' */ 0x70667072, /* Video Output Integers */ @@ -106,6 +112,10 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigUseDedicatedLTCInput = /* 'dltc' */ 0x646C7463, // Use timecode from LTC input instead of SDI stream bmdDeckLinkConfigSDIInput3DPayloadOverride = /* '3dds' */ 0x33646473, + /* Video Input Flags */ + + bmdDeckLinkConfigCapture1080pAsPsF = /* 'cfpr' */ 0x63667072, + /* Video Input Integers */ bmdDeckLinkConfigVideoInputConnection = /* 'vicn' */ 0x7669636E, @@ -206,7 +216,7 @@ class IDeckLinkEncoderConfiguration; /* Interface IDeckLinkConfiguration - DeckLink Configuration interface */ -class IDeckLinkConfiguration : public IUnknown +class BMD_PUBLIC IDeckLinkConfiguration : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; @@ -225,7 +235,7 @@ protected: /* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ -class IDeckLinkEncoderConfiguration : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderConfiguration : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h index 30bd5ae..457f041 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -40,7 +40,7 @@ class IDeckLinkConfiguration_v10_2; /* Interface IDeckLinkConfiguration_v10_2 - DeckLink Configuration interface */ -class IDeckLinkConfiguration_v10_2 : public IUnknown +class BMD_PUBLIC IDeckLinkConfiguration_v10_2 : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h index 750387f..c4d340f 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_4.h @@ -42,7 +42,7 @@ class IDeckLinkConfiguration_v10_4; /* Interface IDeckLinkConfiguration_v10_4 - DeckLink Configuration interface */ -class IDeckLinkConfiguration_v10_4 : public IUnknown +class BMD_PUBLIC IDeckLinkConfiguration_v10_4 : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h index da36e50..684b83b 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -40,7 +40,7 @@ class IDeckLinkEncoderConfiguration_v10_5; /* Interface IDeckLinkEncoderConfiguration_v10_5 - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ -class IDeckLinkEncoderConfiguration_v10_5 : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderConfiguration_v10_5 : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h new file mode 100644 index 0000000..f507637 --- /dev/null +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h @@ -0,0 +1,62 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_9_H +#define BMD_DECKLINKAPICONFIGURATION_v10_9_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_9 = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +class BMD_PUBLIC IDeckLinkConfiguration_v10_9 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ const char *value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ const char **value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_9 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_9_H) */ diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h index 8dc069c..e0522a2 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDeckControl.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -149,7 +153,7 @@ class IDeckLinkDeckControl; /* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */ -class IDeckLinkDeckControlStatusCallback : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback : public IUnknown { public: virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; @@ -163,7 +167,7 @@ protected: /* Interface IDeckLinkDeckControl - Deck Control main interface */ -class IDeckLinkDeckControl : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControl : public IUnknown { public: virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h index d9253ff..d6619ca 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDiscovery.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -50,7 +54,7 @@ class IDeckLink; /* Interface IDeckLink - represents a DeckLink device */ -class IDeckLink : public IUnknown +class BMD_PUBLIC IDeckLink : public IUnknown { public: virtual HRESULT GetModelName (/* out */ const char **modelName) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch.cpp index f639286..880cf34 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch.cpp +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -39,6 +39,7 @@ typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; @@ -50,21 +51,22 @@ static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; -void InitDeckLinkAPI (void) +static void InitDeckLinkAPI (void) { void *libraryHandle; - + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { fprintf(stderr, "%s\n", dlerror()); return; } - + gLoadedDeckLinkAPI = true; - - gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0002"); + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0003"); if (!gCreateIteratorFunc) fprintf(stderr, "%s\n", dlerror()); gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); @@ -73,15 +75,18 @@ void InitDeckLinkAPI (void) gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); if (!gCreateVideoConversionFunc) fprintf(stderr, "%s\n", dlerror()); - gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0001"); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0002"); if (!gCreateDeckLinkDiscoveryFunc) fprintf(stderr, "%s\n", dlerror()); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)dlsym(libraryHandle, "CreateVideoFrameAncillaryPacketsInstance_0001"); + if (!gCreateVideoFrameAncillaryPacketsFunc) + fprintf(stderr, "%s\n", dlerror()); } -void InitDeckLinkPreviewAPI (void) +static void InitDeckLinkPreviewAPI (void) { void *libraryHandle; - + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { @@ -102,7 +107,7 @@ bool IsDeckLinkAPIPresent (void) IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateIteratorFunc == NULL) return NULL; return gCreateIteratorFunc(); @@ -111,7 +116,7 @@ IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateAPIInformationFunc == NULL) return NULL; return gCreateAPIInformationFunc(); @@ -121,7 +126,7 @@ IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; return gCreateOpenGLPreviewFunc(); @@ -130,7 +135,7 @@ IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) IDeckLinkVideoConversion* CreateVideoConversionInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateVideoConversionFunc == NULL) return NULL; return gCreateVideoConversionFunc(); @@ -139,8 +144,17 @@ IDeckLinkVideoConversion* CreateVideoConversionInstance (void) IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateDeckLinkDiscoveryFunc == NULL) return NULL; return gCreateDeckLinkDiscoveryFunc(); } + +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + return gCreateVideoFrameAncillaryPacketsFunc(); +} diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp new file mode 100644 index 0000000..3172ba5 --- /dev/null +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp @@ -0,0 +1,146 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +**/ + +#include +#include +#include + +#include "DeckLinkAPI.h" + +#define kDeckLinkAPI_Name "libDeckLinkAPI.so" +#define KDeckLinkPreviewAPI_Name "libDeckLinkPreviewAPI.so" + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static pthread_once_t gPreviewOnceControl = PTHREAD_ONCE_INIT; + +static bool gLoadedDeckLinkAPI = false; + +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; + +static void InitDeckLinkAPI(void) +{ + void *libraryHandle; + + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW | RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + + gLoadedDeckLinkAPI = true; + + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0002"); + if (!gCreateIteratorFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)dlsym(libraryHandle, "CreateDeckLinkAPIInformationInstance_0001"); + if (!gCreateAPIInformationFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)dlsym(libraryHandle, "CreateVideoConversionInstance_0001"); + if (!gCreateVideoConversionFunc) + fprintf(stderr, "%s\n", dlerror()); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)dlsym(libraryHandle, "CreateDeckLinkDiscoveryInstance_0001"); + if (!gCreateDeckLinkDiscoveryFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +static void InitDeckLinkPreviewAPI(void) +{ + void *libraryHandle; + + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW | RTLD_GLOBAL); + if (!libraryHandle) + { + fprintf(stderr, "%s\n", dlerror()); + return; + } + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)dlsym(libraryHandle, "CreateOpenGLScreenPreviewHelper_0001"); + if (!gCreateOpenGLPreviewFunc) + fprintf(stderr, "%s\n", dlerror()); +} + +bool IsDeckLinkAPIPresent(void) +{ + // If the DeckLink API dynamic library was successfully loaded, return this knowledge to the caller + return gLoadedDeckLinkAPI; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + return gCreateDeckLinkDiscoveryFunc(); +} diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp index 4963060..3726624 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -45,17 +45,17 @@ static CreateIteratorFunc_v7_6 gCreateIteratorFunc = NULL; static CreateOpenGLScreenPreviewHelperFunc_v7_6 gCreateOpenGLPreviewFunc = NULL; static CreateVideoConversionInstanceFunc_v7_6 gCreateVideoConversionFunc = NULL; -void InitDeckLinkAPI_v7_6 (void) +static void InitDeckLinkAPI_v7_6 (void) { void *libraryHandle; - + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { fprintf(stderr, "%s\n", dlerror()); return; } - + gCreateIteratorFunc = (CreateIteratorFunc_v7_6)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance"); if (!gCreateIteratorFunc) fprintf(stderr, "%s\n", dlerror()); @@ -64,10 +64,10 @@ void InitDeckLinkAPI_v7_6 (void) fprintf(stderr, "%s\n", dlerror()); } -void InitDeckLinkPreviewAPI_v7_6 (void) +static void InitDeckLinkPreviewAPI_v7_6 (void) { void *libraryHandle; - + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { @@ -82,7 +82,7 @@ void InitDeckLinkPreviewAPI_v7_6 (void) IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateIteratorFunc == NULL) return NULL; return gCreateIteratorFunc(); @@ -92,7 +92,7 @@ IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI_v7_6); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; return gCreateOpenGLPreviewFunc(); @@ -101,7 +101,7 @@ IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateVideoConversionFunc == NULL) return NULL; return gCreateVideoConversionFunc(); diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp index 770f143..1a924f7 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -49,19 +49,19 @@ static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; -void InitDeckLinkAPI (void) +static void InitDeckLinkAPI (void) { void *libraryHandle; - + libraryHandle = dlopen(kDeckLinkAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { fprintf(stderr, "%s\n", dlerror()); return; } - + gLoadedDeckLinkAPI = true; - + gCreateIteratorFunc = (CreateIteratorFunc)dlsym(libraryHandle, "CreateDeckLinkIteratorInstance_0001"); if (!gCreateIteratorFunc) fprintf(stderr, "%s\n", dlerror()); @@ -73,10 +73,10 @@ void InitDeckLinkAPI (void) fprintf(stderr, "%s\n", dlerror()); } -void InitDeckLinkPreviewAPI (void) +static void InitDeckLinkPreviewAPI (void) { void *libraryHandle; - + libraryHandle = dlopen(KDeckLinkPreviewAPI_Name, RTLD_NOW|RTLD_GLOBAL); if (!libraryHandle) { @@ -97,7 +97,7 @@ bool IsDeckLinkAPIPresent (void) IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateIteratorFunc == NULL) return NULL; return gCreateIteratorFunc(); @@ -106,7 +106,7 @@ IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance (void) IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateAPIInformationFunc == NULL) return NULL; return gCreateAPIInformationFunc(); @@ -116,7 +116,7 @@ IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); pthread_once(&gPreviewOnceControl, InitDeckLinkPreviewAPI); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; return gCreateOpenGLPreviewFunc(); @@ -125,7 +125,7 @@ IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) IDeckLinkVideoConversion* CreateVideoConversionInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateVideoConversionFunc == NULL) return NULL; return gCreateVideoConversionFunc(); diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h index 6c52051..543aaa1 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIModes.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -65,12 +69,12 @@ enum _BMDDisplayMode { bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, - bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, - bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, - bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. /* HD 720 Modes */ @@ -78,19 +82,24 @@ enum _BMDDisplayMode { bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, bmdModeHD720p60 = /* 'hp60' */ 0x68703630, - /* 2k Modes */ + /* 2K Modes */ bmdMode2k2398 = /* '2k23' */ 0x326B3233, bmdMode2k24 = /* '2k24' */ 0x326B3234, bmdMode2k25 = /* '2k25' */ 0x326B3235, - /* DCI Modes (output only) */ + /* 2K DCI Modes */ bmdMode2kDCI2398 = /* '2d23' */ 0x32643233, bmdMode2kDCI24 = /* '2d24' */ 0x32643234, bmdMode2kDCI25 = /* '2d25' */ 0x32643235, + bmdMode2kDCI2997 = /* '2d29' */ 0x32643239, + bmdMode2kDCI30 = /* '2d30' */ 0x32643330, + bmdMode2kDCI50 = /* '2d50' */ 0x32643530, + bmdMode2kDCI5994 = /* '2d59' */ 0x32643539, + bmdMode2kDCI60 = /* '2d60' */ 0x32643630, - /* 4k Modes */ + /* 4K UHD Modes */ bmdMode4K2160p2398 = /* '4k23' */ 0x346B3233, bmdMode4K2160p24 = /* '4k24' */ 0x346B3234, @@ -101,11 +110,43 @@ enum _BMDDisplayMode { bmdMode4K2160p5994 = /* '4k59' */ 0x346B3539, bmdMode4K2160p60 = /* '4k60' */ 0x346B3630, - /* DCI Modes (output only) */ + /* 4K DCI Modes */ bmdMode4kDCI2398 = /* '4d23' */ 0x34643233, bmdMode4kDCI24 = /* '4d24' */ 0x34643234, bmdMode4kDCI25 = /* '4d25' */ 0x34643235, + bmdMode4kDCI2997 = /* '4d29' */ 0x34643239, + bmdMode4kDCI30 = /* '4d30' */ 0x34643330, + bmdMode4kDCI50 = /* '4d50' */ 0x34643530, + bmdMode4kDCI5994 = /* '4d59' */ 0x34643539, + bmdMode4kDCI60 = /* '4d60' */ 0x34643630, + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = /* '8k23' */ 0x386B3233, + bmdMode8K4320p24 = /* '8k24' */ 0x386B3234, + bmdMode8K4320p25 = /* '8k25' */ 0x386B3235, + bmdMode8K4320p2997 = /* '8k29' */ 0x386B3239, + bmdMode8K4320p30 = /* '8k30' */ 0x386B3330, + bmdMode8K4320p50 = /* '8k50' */ 0x386B3530, + bmdMode8K4320p5994 = /* '8k59' */ 0x386B3539, + bmdMode8K4320p60 = /* '8k60' */ 0x386B3630, + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = /* '8d23' */ 0x38643233, + bmdMode8kDCI24 = /* '8d24' */ 0x38643234, + bmdMode8kDCI25 = /* '8d25' */ 0x38643235, + bmdMode8kDCI2997 = /* '8d29' */ 0x38643239, + bmdMode8kDCI30 = /* '8d30' */ 0x38643330, + bmdMode8kDCI50 = /* '8d50' */ 0x38643530, + bmdMode8kDCI5994 = /* '8d59' */ 0x38643539, + bmdMode8kDCI60 = /* '8d60' */ 0x38643630, + + /* RAW Modes for Cintel (input only) */ + + bmdModeCintelRAW = /* 'rwci' */ 0x72776369, // Frame size up to 4096x3072, variable frame rate + bmdModeCintelCompressedRAW = /* 'rwcc' */ 0x72776363, // Frame size up to 4096x3072, variable frame rate /* Special Modes */ @@ -140,7 +181,12 @@ enum _BMDPixelFormat { /* AVID DNxHR */ - bmdFormatDNxHR = /* 'AVdh' */ 0x41566468 + bmdFormatDNxHR = /* 'AVdh' */ 0x41566468, + + /* Cintel formats */ + + bmdFormat12BitRAWGRBG = /* 'r12p' */ 0x72313270, // 12-bit RAW data for bayer pattern GRBG + bmdFormat12BitRAWJPEG = /* 'r16p' */ 0x72313670 // 12-bit RAW data arranged in tiles and JPEG compressed }; /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ @@ -149,7 +195,8 @@ typedef uint32_t BMDDisplayModeFlags; enum _BMDDisplayModeFlags { bmdDisplayModeSupports3D = 1 << 0, bmdDisplayModeColorspaceRec601 = 1 << 1, - bmdDisplayModeColorspaceRec709 = 1 << 2 + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 }; // Forward Declarations @@ -159,7 +206,7 @@ class IDeckLinkDisplayMode; /* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ -class IDeckLinkDisplayModeIterator : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayModeIterator : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLinkDisplayMode **deckLinkDisplayMode) = 0; @@ -170,7 +217,7 @@ protected: /* Interface IDeckLinkDisplayMode - represents a display mode */ -class IDeckLinkDisplayMode : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayMode : public IUnknown { public: virtual HRESULT GetName (/* out */ const char **name) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h index 979a9aa..5591262 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPITypes.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations typedef int64_t BMDTimeValue; @@ -54,7 +58,8 @@ typedef uint32_t BMDTimecodeFlags; enum _BMDTimecodeFlags { bmdTimecodeFlagDefault = 0, bmdTimecodeIsDropFrame = 1 << 0, - bmdTimecodeFieldMark = 1 << 1 + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2 }; /* Enum BMDVideoConnection - Video connection types */ @@ -96,7 +101,7 @@ class IDeckLinkTimecode; /* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ -class IDeckLinkTimecode : public IUnknown +class BMD_PUBLIC IDeckLinkTimecode : public IUnknown { public: virtual BMDTimecodeBCD GetBCD (void) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h index dfd1799..f9db7ff 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPIVersion.h @@ -7,14 +7,14 @@ * ** execute, and transmit the Software, and to prepare derivative works of the * ** Software, and to permit third-parties to whom the Software is furnished to * ** do so, all subject to the following: - * ** + * ** * ** The copyright notices in the Software and this entire statement, including * ** the above license grant, this restriction and the following disclaimer, * ** must be included in all copies of the Software, in whole or in part, and * ** all derivative works of the Software, unless such copies or derivative * ** works are solely in the form of machine-executable object code generated by * ** a source language processor. - * ** + * ** * ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -30,8 +30,8 @@ #ifndef __DeckLink_API_Version_h__ #define __DeckLink_API_Version_h__ -#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a080000 -#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.8" +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a0b0400 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.11.4" #endif // __DeckLink_API_Version_h__ diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h index a465133..ad2ff32 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,7 +37,7 @@ typedef uint32_t BMDDeckLinkConfigurationID_v10_2; enum _BMDDeckLinkConfigurationID_v10_2 { /* Video output flags */ - + bmdDeckLinkConfig3GBpsVideoOutput_v10_2 = '3gbs', }; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_9.h new file mode 100644 index 0000000..aec8c7c --- /dev/null +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v10_9.h @@ -0,0 +1,45 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_9_H +#define BMD_DECKLINKAPI_v10_9_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_9; +enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = 'fpro', +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_9_H) */ diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h index 1602d6a..b0c637c 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_1.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -66,14 +66,14 @@ class IDeckLinkVideoFrame_v7_1; class IDeckLinkVideoInputFrame_v7_1; class IDeckLinkAudioInputPacket_v7_1; -class IDeckLinkDisplayModeIterator_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayModeIterator_v7_1 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE Next (IDeckLinkDisplayMode_v7_1* *deckLinkDisplayMode) = 0; }; -class IDeckLinkDisplayMode_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayMode_v7_1 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE GetName (const char **name) = 0; @@ -83,56 +83,56 @@ public: virtual HRESULT STDMETHODCALLTYPE GetFrameRate (BMDTimeValue *frameDuration, BMDTimeScale *timeScale) = 0; }; -class IDeckLinkVideoOutputCallback_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkVideoOutputCallback_v7_1 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE ScheduledFrameCompleted (IDeckLinkVideoFrame_v7_1* completedFrame, BMDOutputFrameCompletionResult result) = 0; }; -class IDeckLinkInputCallback_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkInputCallback_v7_1 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived (IDeckLinkVideoInputFrame_v7_1* videoFrame, IDeckLinkAudioInputPacket_v7_1* audioPacket) = 0; }; // IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink. -class IDeckLinkOutput_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkOutput_v7_1 : public IUnknown { public: // Display mode predicates virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0; - - + + // Video output virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput (BMDDisplayMode displayMode) = 0; virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput () = 0; - + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0; virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; - + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0; virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0; - - + + // Audio output virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput () = 0; - + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll () = 0; virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll () = 0; virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples () = 0; - + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0; - - + + // Output control virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; @@ -140,23 +140,23 @@ public: }; // IDeckLinkInput_v7_1. Created by QueryInterface from IDeckLink. -class IDeckLinkInput_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkInput_v7_1 : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; - + // Video input virtual HRESULT STDMETHODCALLTYPE EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; virtual HRESULT STDMETHODCALLTYPE DisableVideoInput () = 0; - + // Audio input virtual HRESULT STDMETHODCALLTYPE EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; virtual HRESULT STDMETHODCALLTYPE DisableAudioInput () = 0; virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0; virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; + - // Input control virtual HRESULT STDMETHODCALLTYPE StartStreams () = 0; virtual HRESULT STDMETHODCALLTYPE StopStreams () = 0; virtual HRESULT STDMETHODCALLTYPE PauseStreams () = 0; @@ -164,7 +164,7 @@ public: }; // IDeckLinkVideoFrame_v7_1. Created by IDeckLinkOutput::CreateVideoFrame. -class IDeckLinkVideoFrame_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame_v7_1 : public IUnknown { public: virtual long STDMETHODCALLTYPE GetWidth () = 0; @@ -176,19 +176,19 @@ public: }; // IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkInput_v7_1 frame arrival callback. -class IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1 +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_1 : public IDeckLinkVideoFrame_v7_1 { public: virtual HRESULT STDMETHODCALLTYPE GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; }; // IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput_v7_1 callback. -class IDeckLinkAudioInputPacket_v7_1 : public IUnknown +class BMD_PUBLIC IDeckLinkAudioInputPacket_v7_1 : public IUnknown { public: virtual long STDMETHODCALLTYPE GetSampleCount () = 0; virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; - + virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0; }; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h index c8b3da8..bb3192e 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_3.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -53,7 +53,7 @@ class IDeckLinkVideoInputFrame_v7_3; /* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkOutput_v7_3 : public IUnknown +class BMD_PUBLIC IDeckLinkOutput_v7_3 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0; @@ -107,7 +107,7 @@ protected: /* Interface IDeckLinkInputCallback - Frame arrival callback. */ -class IDeckLinkInputCallback_v7_3 : public IUnknown +class BMD_PUBLIC IDeckLinkInputCallback_v7_3 : public IUnknown { public: virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -122,7 +122,7 @@ protected: /* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkInput_v7_3 : public IUnknown +class BMD_PUBLIC IDeckLinkInput_v7_3 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0; @@ -158,7 +158,7 @@ protected: /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ -class IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6 +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_3 : public IDeckLinkVideoFrame_v7_6 { public: virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h index 8bc9329..d981206 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_6.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -83,7 +83,7 @@ class IDeckLinkVideoConversion_v7_6; /* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ -class IDeckLinkVideoOutputCallback_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkVideoOutputCallback_v7_6 : public IUnknown { public: virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame_v7_6 *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; @@ -96,7 +96,7 @@ protected: /* Interface IDeckLinkInputCallback - Frame arrival callback. */ -class IDeckLinkInputCallback_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkInputCallback_v7_6 : public IUnknown { public: virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode_v7_6 *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -109,7 +109,7 @@ protected: /* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ -class IDeckLinkDisplayModeIterator_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayModeIterator_v7_6 : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLinkDisplayMode_v7_6 **deckLinkDisplayMode) = 0; @@ -121,7 +121,7 @@ protected: /* Interface IDeckLinkDisplayMode - represents a display mode */ -class IDeckLinkDisplayMode_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayMode_v7_6 : public IUnknown { public: virtual HRESULT GetName (/* out */ const char **name) = 0; @@ -138,7 +138,7 @@ protected: /* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkOutput_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkOutput_v7_6 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0; @@ -194,7 +194,7 @@ protected: /* Interface IDeckLinkInput_v7_6 - Created by QueryInterface from IDeckLink. */ -class IDeckLinkInput_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkInput_v7_6 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* out */ BMDDisplayModeSupport *result) = 0; @@ -233,7 +233,7 @@ protected: /* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ -class IDeckLinkTimecode_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkTimecode_v7_6 : public IUnknown { public: virtual BMDTimecodeBCD GetBCD (void) = 0; @@ -248,7 +248,7 @@ protected: /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ -class IDeckLinkVideoFrame_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame_v7_6 : public IUnknown { public: virtual long GetWidth (void) = 0; @@ -268,7 +268,7 @@ protected: /* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ -class IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +class BMD_PUBLIC IDeckLinkMutableVideoFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 { public: virtual HRESULT SetFlags (BMDFrameFlags newFlags) = 0; @@ -284,7 +284,7 @@ protected: /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ -class IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 +class BMD_PUBLIC IDeckLinkVideoInputFrame_v7_6 : public IDeckLinkVideoFrame_v7_6 { public: virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, BMDTimeScale timeScale) = 0; @@ -297,7 +297,7 @@ protected: /* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ -class IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkScreenPreviewCallback_v7_6 : public IUnknown { public: virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame_v7_6 *theFrame) = 0; @@ -309,7 +309,7 @@ protected: /* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ -class IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper_v7_6 : public IUnknown { public: @@ -326,7 +326,7 @@ protected: /* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ -class IDeckLinkVideoConversion_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkVideoConversion_v7_6 : public IUnknown { public: virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame_v7_6* srcFrame, /* in */ IDeckLinkVideoFrame_v7_6* dstFrame) = 0; @@ -337,54 +337,54 @@ protected: /* Interface IDeckLinkConfiguration - Created by QueryInterface from IDeckLink. */ -class IDeckLinkConfiguration_v7_6 : public IUnknown +class BMD_PUBLIC IDeckLinkConfiguration_v7_6 : public IUnknown { public: virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0; virtual HRESULT WriteConfigurationToPreferences (void) = 0; - + /* Video Output Configuration */ - + virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0; virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0; - + virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; - + virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0; virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0; - + virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0; virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0; - + virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0; virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0; - + virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0; virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0; - + /* Video Input Configuration */ - + virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0; virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0; - + virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; - + virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0; virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0; - + virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0; virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0; - + virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0; virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0; - + virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0; virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0; - + /* Audio Input Configuration */ - + virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0; virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0; }; @@ -393,9 +393,9 @@ public: extern "C" { - IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void); - IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void); - IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void); + IDeckLinkIterator* BMD_PUBLIC CreateDeckLinkIteratorInstance_v7_6 (void); + IDeckLinkGLScreenPreviewHelper_v7_6* BMD_PUBLIC CreateOpenGLScreenPreviewHelper_v7_6 (void); + IDeckLinkVideoConversion_v7_6* BMD_PUBLIC CreateVideoConversionInstance_v7_6 (void); }; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h index 406ce0a..c8e3faa 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v7_9.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -42,7 +42,7 @@ class IDeckLinkDeckControl_v7_9; /* Interface IDeckLinkDeckControl_v7_9 - Deck Control main interface */ -class IDeckLinkDeckControl_v7_9 : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControl_v7_9 : public IUnknown { public: virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; @@ -77,7 +77,7 @@ public: virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback *callback) = 0; - + protected: virtual ~IDeckLinkDeckControl_v7_9 () {}; // call Release method to drop reference count }; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h index 832664c..6cace7e 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_0.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -39,7 +39,7 @@ /* Interface IDeckLink_v8_0 - represents a DeckLink device */ -class IDeckLink_v8_0 : public IUnknown +class BMD_PUBLIC IDeckLink_v8_0 : public IUnknown { public: virtual HRESULT GetModelName (/* out */ const char **modelName) = 0; @@ -47,14 +47,14 @@ public: /* Interface IDeckLinkIterator_v8_0 - enumerates installed DeckLink hardware */ -class IDeckLinkIterator_v8_0 : public IUnknown +class BMD_PUBLIC IDeckLinkIterator_v8_0 : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLink_v8_0 **deckLinkInstance) = 0; }; extern "C" { - IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance_v8_0 (void); + IDeckLinkIterator_v8_0* BMD_PUBLIC CreateDeckLinkIteratorInstance_v8_0 (void); }; #endif // defined __cplusplus diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h index 7f68919..c7362aa 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v8_1.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: - ** + ** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. - ** + ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -52,21 +52,21 @@ enum _BMDDeckControlVTRControlState_v8_1 { /* Interface IDeckLinkDeckControlStatusCallback_v8_1 - Deck control state change callback. */ -class IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback_v8_1 : public IUnknown { public: virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0; virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; - + protected: virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count }; /* Interface IDeckLinkDeckControl_v8_1 - Deck Control main interface */ -class IDeckLinkDeckControl_v8_1 : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControl_v8_1 : public IUnknown { public: virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; @@ -102,7 +102,7 @@ public: virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0; - + protected: virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count }; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h index 236d182..dd5f83f 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -40,7 +40,7 @@ /* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkInput_v9_2 : public IUnknown +class BMD_PUBLIC IDeckLinkInput_v9_2 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h index 98d115d..9a51bf2 100644 --- a/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h +++ b/plugins/decklink/linux/decklink-sdk/DeckLinkAPI_v9_9.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -40,7 +40,7 @@ /* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkOutput_v9_9 : public IUnknown +class BMD_PUBLIC IDeckLinkOutput_v9_9 : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; diff --git a/plugins/decklink/linux/decklink-sdk/LinuxCOM.h b/plugins/decklink/linux/decklink-sdk/LinuxCOM.h index 3041ea7..663602b 100644 --- a/plugins/decklink/linux/decklink-sdk/LinuxCOM.h +++ b/plugins/decklink/linux/decklink-sdk/LinuxCOM.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -29,7 +29,7 @@ #define __LINUX_COM_H_ struct REFIID -{ +{ unsigned char byte0; unsigned char byte1; unsigned char byte2; @@ -85,14 +85,19 @@ typedef void *LPVOID; #define IID_IUnknown (REFIID){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} #define IUnknownUUID IID_IUnknown +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + #ifdef __cplusplus -class IUnknown +class BMD_PUBLIC IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) = 0; - virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; - virtual ULONG STDMETHODCALLTYPE Release(void) = 0; + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) = 0; + virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0; + virtual ULONG STDMETHODCALLTYPE Release(void) = 0; }; #endif -#endif +#endif + diff --git a/plugins/decklink/mac/CMakeLists.txt b/plugins/decklink/mac/CMakeLists.txt index d016470..04a2a1a 100644 --- a/plugins/decklink/mac/CMakeLists.txt +++ b/plugins/decklink/mac/CMakeLists.txt @@ -5,9 +5,9 @@ if(DISABLE_DECKLINK) return() endif() -find_library(COREFOUNDATION CoreFoundation) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}") -include_directories(${COREFOUNDATION}) +find_library(COREFOUNDATION CoreFoundation) set(mac-decklink-sdk_HEADERS decklink-sdk/DeckLinkAPI.h @@ -17,39 +17,59 @@ set(mac-decklink-sdk_HEADERS decklink-sdk/DeckLinkAPIModes.h decklink-sdk/DeckLinkAPIStreaming.h decklink-sdk/DeckLinkAPITypes.h - decklink-sdk/DeckLinkAPIVersion.h - ) + decklink-sdk/DeckLinkAPIVersion.h) set(mac-decklink-sdk_SOURCES decklink-sdk/DeckLinkAPIDispatch.cpp ) set(mac-decklink_HEADERS + ../decklink-devices.hpp + ../const.h + ../DecklinkOutput.hpp ../platform.hpp - ../decklink.hpp + ../DecklinkInput.hpp + ../DecklinkBase.h ../decklink-device-instance.hpp ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp ../audio-repack.h ../audio-repack.hpp + ../util.hpp ) set(mac-decklink_SOURCES ../plugin-main.cpp - ../decklink.cpp + ../decklink-devices.cpp + ../decklink-output.cpp + ../decklink-source.cpp + ../DecklinkOutput.cpp + ../DecklinkInput.cpp + ../DecklinkBase.cpp ../decklink-device-instance.cpp ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp ../audio-repack.c - platform.cpp) + platform.cpp + ../util.cpp + ) + +list(APPEND decklink_HEADERS ${decklink_UI_HEADERS}) + +include_directories( + ${COREFOUNDATION} + "${CMAKE_SOURCE_DIR}/UI/obs-frontend-api") + +list(APPEND mac-decklink_HEADERS ${decklink_UI_HEADERS}) add_library(mac-decklink MODULE ${mac-decklink_SOURCES} ${mac-decklink_HEADERS} ${mac-decklink-sdk_HEADERS} - ${mac-decklink-sdk_SOURCES}) + ${mac-decklink-sdk_SOURCES} + ) target_link_libraries(mac-decklink libobs diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h index 3b0fc11..368a72b 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + /* DeckLink API */ #include @@ -67,12 +71,16 @@ BMD_CONST REFIID IID_IDeckLinkIterator = /* 50FB36CD- BMD_CONST REFIID IID_IDeckLinkAPIInformation = /* 7BEA3C68-730D-4322-AF34-8A7152B532A4 */ {0x7B,0xEA,0x3C,0x68,0x73,0x0D,0x43,0x22,0xAF,0x34,0x8A,0x71,0x52,0xB5,0x32,0xA4}; BMD_CONST REFIID IID_IDeckLinkOutput = /* CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564 */ {0xCC,0x5C,0x8A,0x6E,0x3F,0x2F,0x4B,0x3A,0x87,0xEA,0xFD,0x78,0xAF,0x30,0x05,0x64}; BMD_CONST REFIID IID_IDeckLinkInput = /* AF22762B-DFAC-4846-AA79-FA8883560995 */ {0xAF,0x22,0x76,0x2B,0xDF,0xAC,0x48,0x46,0xAA,0x79,0xFA,0x88,0x83,0x56,0x09,0x95}; +BMD_CONST REFIID IID_IDeckLinkHDMIInputEDID = /* ABBBACBC-45BC-4665-9D92-ACE6E5A97902 */ {0xAB,0xBB,0xAC,0xBC,0x45,0xBC,0x46,0x65,0x9D,0x92,0xAC,0xE6,0xE5,0xA9,0x79,0x02}; BMD_CONST REFIID IID_IDeckLinkEncoderInput = /* 270587DA-6B7D-42E7-A1F0-6D853F581185 */ {0x27,0x05,0x87,0xDA,0x6B,0x7D,0x42,0xE7,0xA1,0xF0,0x6D,0x85,0x3F,0x58,0x11,0x85}; BMD_CONST REFIID IID_IDeckLinkVideoFrame = /* 3F716FE0-F023-4111-BE5D-EF4414C05B17 */ {0x3F,0x71,0x6F,0xE0,0xF0,0x23,0x41,0x11,0xBE,0x5D,0xEF,0x44,0x14,0xC0,0x5B,0x17}; BMD_CONST REFIID IID_IDeckLinkMutableVideoFrame = /* 69E2639F-40DA-4E19-B6F2-20ACE815C390 */ {0x69,0xE2,0x63,0x9F,0x40,0xDA,0x4E,0x19,0xB6,0xF2,0x20,0xAC,0xE8,0x15,0xC3,0x90}; BMD_CONST REFIID IID_IDeckLinkVideoFrame3DExtensions = /* DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7 */ {0xDA,0x0F,0x7E,0x4A,0xED,0xC7,0x48,0xA8,0x9C,0xDD,0x2D,0xB5,0x1C,0x72,0x9C,0xD7}; BMD_CONST REFIID IID_IDeckLinkVideoFrameMetadataExtensions = /* D5973DC9-6432-46D0-8F0B-2496F8A1238F */ {0xD5,0x97,0x3D,0xC9,0x64,0x32,0x46,0xD0,0x8F,0x0B,0x24,0x96,0xF8,0xA1,0x23,0x8F}; BMD_CONST REFIID IID_IDeckLinkVideoInputFrame = /* 05CFE374-537C-4094-9A57-680525118F44 */ {0x05,0xCF,0xE3,0x74,0x53,0x7C,0x40,0x94,0x9A,0x57,0x68,0x05,0x25,0x11,0x8F,0x44}; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacket = /* CC5BBF7E-029C-4D3B-9158-6000EF5E3670 */ {0xCC,0x5B,0xBF,0x7E,0x02,0x9C,0x4D,0x3B,0x91,0x58,0x60,0x00,0xEF,0x5E,0x36,0x70}; +BMD_CONST REFIID IID_IDeckLinkAncillaryPacketIterator = /* 3FC8994B-88FB-4C17-968F-9AAB69D964A7 */ {0x3F,0xC8,0x99,0x4B,0x88,0xFB,0x4C,0x17,0x96,0x8F,0x9A,0xAB,0x69,0xD9,0x64,0xA7}; +BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillaryPackets = /* 6C186C0F-459E-41D8-AEE2-4812D81AEE68 */ {0x6C,0x18,0x6C,0x0F,0x45,0x9E,0x41,0xD8,0xAE,0xE2,0x48,0x12,0xD8,0x1A,0xEE,0x68}; BMD_CONST REFIID IID_IDeckLinkVideoFrameAncillary = /* 732E723C-D1A4-4E29-9E8E-4A88797A0004 */ {0x73,0x2E,0x72,0x3C,0xD1,0xA4,0x4E,0x29,0x9E,0x8E,0x4A,0x88,0x79,0x7A,0x00,0x04}; BMD_CONST REFIID IID_IDeckLinkEncoderPacket = /* B693F36C-316E-4AF1-B6C2-F389A4BCA620 */ {0xB6,0x93,0xF3,0x6C,0x31,0x6E,0x4A,0xF1,0xB6,0xC2,0xF3,0x89,0xA4,0xBC,0xA6,0x20}; BMD_CONST REFIID IID_IDeckLinkEncoderVideoPacket = /* 4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0 */ {0x4E,0x7F,0xD9,0x44,0xE8,0xC7,0x4E,0xAC,0xB8,0xC0,0x7B,0x77,0xF8,0x0F,0x5A,0xE0}; @@ -117,9 +125,11 @@ enum _BMDFrameFlags { bmdFrameFlagDefault = 0, bmdFrameFlagFlipVertical = 1 << 0, bmdFrameContainsHDRMetadata = 1 << 1, + bmdFrameContainsCintelMetadata = 1 << 2, /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + bmdFrameCapturedAsPsF = 1 << 30, bmdFrameHasNoInputSource = 1 << 31 }; @@ -163,10 +173,10 @@ enum _BMDDeckLinkCapturePassthroughMode { typedef uint32_t BMDOutputFrameCompletionResult; enum _BMDOutputFrameCompletionResult { - bmdOutputFrameCompleted, - bmdOutputFrameDisplayedLate, - bmdOutputFrameDropped, - bmdOutputFrameFlushed + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed }; /* Enum BMDReferenceStatus - GenLock input status */ @@ -203,9 +213,9 @@ enum _BMDAudioSampleType { typedef uint32_t BMDAudioOutputStreamType; enum _BMDAudioOutputStreamType { - bmdAudioOutputStreamContinuous, - bmdAudioOutputStreamContinuousDontResample, - bmdAudioOutputStreamTimestamped + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped }; /* Enum BMDDisplayModeSupport - Output mode supported flags */ @@ -213,8 +223,17 @@ enum _BMDAudioOutputStreamType { typedef uint32_t BMDDisplayModeSupport; enum _BMDDisplayModeSupport { bmdDisplayModeNotSupported = 0, - bmdDisplayModeSupported, - bmdDisplayModeSupportedWithConversion + bmdDisplayModeSupported, + bmdDisplayModeSupportedWithConversion +}; + +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef uint32_t BMDAncillaryPacketFormat; +enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = 'ui08', + bmdAncillaryPacketFormatUInt16 = 'ui16', + bmdAncillaryPacketFormatYCbCr10 = 'v210' }; /* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ @@ -336,11 +355,68 @@ enum _BMDDeviceInterface { bmdDeviceInterfaceThunderbolt = 'thun' }; +/* Enum BMDColorspace - Colorspace */ + +typedef uint32_t BMDColorspace; +enum _BMDColorspace { + bmdColorspaceRec601 = 'r601', + bmdColorspaceRec709 = 'r709', + bmdColorspaceRec2020 = '2020' +}; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef uint32_t BMDDynamicRange; +enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, + bmdDynamicRangeHDRStaticPQ = 1 << 29, // SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // ITU-R BT.2100-0 +}; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef uint32_t BMDDeckLinkHDMIInputEDIDID; +enum _BMDDeckLinkHDMIInputEDIDID { + bmdDeckLinkHDMIInputEDIDDynamicRange = 'HIDy' // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +}; + /* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ typedef uint32_t BMDDeckLinkFrameMetadataID; enum _BMDDeckLinkFrameMetadataID { + bmdDeckLinkFrameMetadataColorspace = 'cspc', // Colorspace of video frame (see BMDColorspace) bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = 'eotf', // EOTF in range 0-7 as per CEA 861.3 + bmdDeckLinkFrameMetadataCintelFilmType = 'cfty', // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge = 'cfga', // Current film gauge + bmdDeckLinkFrameMetadataCintelOffsetDetectedHorizontal = 'odfh', // Horizontal offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelOffsetDetectedVertical = 'odfv', // Vertical offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelKeykodeLow = 'ckkl', // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh = 'ckkh', // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size = 'ct1s', // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size = 'ct2s', // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size = 'ct3s', // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size = 'ct4s', // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth = 'IWPx', // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight = 'IHPx', // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed = 'mrir', // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed = 'mgir', // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed = 'mbir', // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen = 'mrig', // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen = 'mgig', // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen = 'mbig', // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue = 'mrib', // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue = 'mgib', // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue = 'mbib', // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed = 'mlrr', // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed = 'mlgr', // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed = 'mlbr', // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen = 'mlrg', // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen = 'mlgg', // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen = 'mlbg', // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue = 'mlrb', // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue = 'mlgb', // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue = 'mlbb', // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate = 'cffr', // Film frame rate bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = 'hdrx', // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = 'hdry', // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = 'hdgx', // Green display primaries in range 0.0 - 1.0 @@ -352,7 +428,15 @@ enum _BMDDeckLinkFrameMetadataID { bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = 'hdml', // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = 'hmil', // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = 'mcll', // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 - bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = 'fall' // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = 'fall', // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal = 'otah', // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical = 'otav', // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed = 'LfRd', // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen = 'LfGr', // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue = 'LfBl', // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed = 'GnRd', // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen = 'GnGr', // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue = 'GnBl' // Blue lift parameter to apply after log and gain }; /* Enum BMDDuplexMode - Duplex for configurable ports */ @@ -390,22 +474,24 @@ enum _BMDDeckLinkAttributeID { BMDDeckLinkHasLTCTimecodeInput = 'hltc', BMDDeckLinkSupportsDuplexModeConfiguration = 'dupx', BMDDeckLinkSupportsHDRMetadata = 'hdrm', + BMDDeckLinkSupportsColorspaceMetadata = 'cmet', /* Integers */ BMDDeckLinkMaximumAudioChannels = 'mach', - BMDDeckLinkMaximumAnalogAudioChannels = 'aach', + BMDDeckLinkMaximumAnalogAudioInputChannels = 'iach', + BMDDeckLinkMaximumAnalogAudioOutputChannels = 'aach', BMDDeckLinkNumberOfSubDevices = 'nsbd', BMDDeckLinkSubDeviceIndex = 'subi', BMDDeckLinkPersistentID = 'peid', BMDDeckLinkDeviceGroupID = 'dgid', BMDDeckLinkTopologicalID = 'toid', - BMDDeckLinkVideoOutputConnections = 'vocn', - BMDDeckLinkVideoInputConnections = 'vicn', - BMDDeckLinkAudioOutputConnections = 'aocn', - BMDDeckLinkAudioInputConnections = 'aicn', + BMDDeckLinkVideoOutputConnections = 'vocn', // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = 'vicn', // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = 'aocn', // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = 'aicn', // Returns a BMDAudioConnection bit field BMDDeckLinkVideoIOSupport = 'vios', // Returns a BMDVideoIOSupport bit field - BMDDeckLinkDeckControlConnections = 'dccn', + BMDDeckLinkDeckControlConnections = 'dccn', // Returns a BMDDeckControlConnection bit field BMDDeckLinkDeviceInterface = 'dbus', // Returns a BMDDeviceInterface BMDDeckLinkAudioInputRCAChannelCount = 'airc', BMDDeckLinkAudioInputXLRChannelCount = 'aixc', @@ -459,11 +545,14 @@ enum _BMDDeckLinkStatusID { bmdDeckLinkStatusReferenceSignalFlags = 'reff', bmdDeckLinkStatusDuplexMode = 'dupx', bmdDeckLinkStatusBusy = 'busy', + bmdDeckLinkStatusInterchangeablePanelType = 'icpt', + bmdDeckLinkStatusDeviceTemperature = 'dtmp', /* Flags */ bmdDeckLinkStatusVideoInputSignalLocked = 'visl', - bmdDeckLinkStatusReferenceSignalLocked = 'refl' + bmdDeckLinkStatusReferenceSignalLocked = 'refl', + bmdDeckLinkStatusReceivedEDID = 'edid' }; /* Enum BMDDeckLinkVideoStatusFlags - */ @@ -484,6 +573,14 @@ enum _BMDDuplexStatus { bmdDuplexStatusInactive = 'inac' }; +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef uint32_t BMDPanelType; +enum _BMDPanelType { + bmdPanelNotDetected = 'npnl', + bmdPanelTeranexMiniSmartPanel = 'tmsm' +}; + /* Enum BMDDeviceBusyState - Current device busy state */ typedef uint32_t BMDDeviceBusyState; @@ -533,12 +630,16 @@ class IDeckLinkIterator; class IDeckLinkAPIInformation; class IDeckLinkOutput; class IDeckLinkInput; +class IDeckLinkHDMIInputEDID; class IDeckLinkEncoderInput; class IDeckLinkVideoFrame; class IDeckLinkMutableVideoFrame; class IDeckLinkVideoFrame3DExtensions; class IDeckLinkVideoFrameMetadataExtensions; class IDeckLinkVideoInputFrame; +class IDeckLinkAncillaryPacket; +class IDeckLinkAncillaryPacketIterator; +class IDeckLinkVideoFrameAncillaryPackets; class IDeckLinkVideoFrameAncillary; class IDeckLinkEncoderPacket; class IDeckLinkEncoderVideoPacket; @@ -559,7 +660,7 @@ class IDeckLinkDiscovery; /* Interface IDeckLinkVideoOutputCallback - Frame completion callback. */ -class IDeckLinkVideoOutputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkVideoOutputCallback : public IUnknown { public: virtual HRESULT ScheduledFrameCompleted (/* in */ IDeckLinkVideoFrame *completedFrame, /* in */ BMDOutputFrameCompletionResult result) = 0; @@ -571,7 +672,7 @@ protected: /* Interface IDeckLinkInputCallback - Frame arrival callback. */ -class IDeckLinkInputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkInputCallback : public IUnknown { public: virtual HRESULT VideoInputFormatChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -583,7 +684,7 @@ protected: /* Interface IDeckLinkEncoderInputCallback - Frame arrival callback. */ -class IDeckLinkEncoderInputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderInputCallback : public IUnknown { public: virtual HRESULT VideoInputSignalChanged (/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newDisplayMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags) = 0; @@ -596,7 +697,7 @@ protected: /* Interface IDeckLinkMemoryAllocator - Memory allocator for video frames. */ -class IDeckLinkMemoryAllocator : public IUnknown +class BMD_PUBLIC IDeckLinkMemoryAllocator : public IUnknown { public: virtual HRESULT AllocateBuffer (/* in */ uint32_t bufferSize, /* out */ void **allocatedBuffer) = 0; @@ -608,7 +709,7 @@ public: /* Interface IDeckLinkAudioOutputCallback - Optional callback to allow audio samples to be pulled as required. */ -class IDeckLinkAudioOutputCallback : public IUnknown +class BMD_PUBLIC IDeckLinkAudioOutputCallback : public IUnknown { public: virtual HRESULT RenderAudioSamples (/* in */ bool preroll) = 0; @@ -616,7 +717,7 @@ public: /* Interface IDeckLinkIterator - enumerates installed DeckLink hardware */ -class IDeckLinkIterator : public IUnknown +class BMD_PUBLIC IDeckLinkIterator : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLink **deckLinkInstance) = 0; @@ -624,7 +725,7 @@ public: /* Interface IDeckLinkAPIInformation - DeckLinkAPI attribute interface */ -class IDeckLinkAPIInformation : public IUnknown +class BMD_PUBLIC IDeckLinkAPIInformation : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkAPIInformationID cfgID, /* out */ bool *value) = 0; @@ -638,7 +739,7 @@ protected: /* Interface IDeckLinkOutput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkOutput : public IUnknown +class BMD_PUBLIC IDeckLinkOutput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -653,7 +754,7 @@ public: virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; - virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; + virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; @@ -695,7 +796,7 @@ protected: /* Interface IDeckLinkInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkInput : public IUnknown +class BMD_PUBLIC IDeckLinkInput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -732,9 +833,22 @@ protected: virtual ~IDeckLinkInput () {} // call Release method to drop reference count }; +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +class BMD_PUBLIC IDeckLinkHDMIInputEDID : public IUnknown +{ +public: + virtual HRESULT SetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkHDMIInputEDIDID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT WriteToEDID (void) = 0; + +protected: + virtual ~IDeckLinkHDMIInputEDID () {} // call Release method to drop reference count +}; + /* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ -class IDeckLinkEncoderInput : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderInput : public IUnknown { public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoInputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; @@ -771,7 +885,7 @@ protected: /* Interface IDeckLinkVideoFrame - Interface to encapsulate a video frame; can be caller-implemented. */ -class IDeckLinkVideoFrame : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame : public IUnknown { public: virtual long GetWidth (void) = 0; @@ -782,7 +896,7 @@ public: virtual HRESULT GetBytes (/* out */ void **buffer) = 0; virtual HRESULT GetTimecode (/* in */ BMDTimecodeFormat format, /* out */ IDeckLinkTimecode **timecode) = 0; - virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; + virtual HRESULT GetAncillaryData (/* out */ IDeckLinkVideoFrameAncillary **ancillary) = 0; // Use of IDeckLinkVideoFrameAncillaryPackets is preferred protected: virtual ~IDeckLinkVideoFrame () {} // call Release method to drop reference count @@ -790,7 +904,7 @@ protected: /* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ -class IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame +class BMD_PUBLIC IDeckLinkMutableVideoFrame : public IDeckLinkVideoFrame { public: virtual HRESULT SetFlags (/* in */ BMDFrameFlags newFlags) = 0; @@ -806,7 +920,7 @@ protected: /* Interface IDeckLinkVideoFrame3DExtensions - Optional interface implemented on IDeckLinkVideoFrame to support 3D frames */ -class IDeckLinkVideoFrame3DExtensions : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrame3DExtensions : public IUnknown { public: virtual BMDVideo3DPackingFormat Get3DPackingFormat (void) = 0; @@ -818,7 +932,7 @@ protected: /* Interface IDeckLinkVideoFrameMetadataExtensions - Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information */ -class IDeckLinkVideoFrameMetadataExtensions : public IUnknown +class BMD_PUBLIC IDeckLinkVideoFrameMetadataExtensions : public IUnknown { public: virtual HRESULT GetInt (/* in */ BMDDeckLinkFrameMetadataID metadataID, /* out */ int64_t *value) = 0; @@ -832,7 +946,7 @@ protected: /* Interface IDeckLinkVideoInputFrame - Provided by the IDeckLinkVideoInput frame arrival callback. */ -class IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame +class BMD_PUBLIC IDeckLinkVideoInputFrame : public IDeckLinkVideoFrame { public: virtual HRESULT GetStreamTime (/* out */ BMDTimeValue *frameTime, /* out */ BMDTimeValue *frameDuration, /* in */ BMDTimeScale timeScale) = 0; @@ -842,13 +956,56 @@ protected: virtual ~IDeckLinkVideoInputFrame () {} // call Release method to drop reference count }; -/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ -class IDeckLinkVideoFrameAncillary : public IUnknown +class BMD_PUBLIC IDeckLinkAncillaryPacket : public IUnknown { public: - virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void **buffer) = 0; + virtual HRESULT GetBytes (/* in */ BMDAncillaryPacketFormat format /* For output, only one format need be offered */, /* out */ const void **data /* Optional */, /* out */ uint32_t *size /* Optional */) = 0; + virtual uint8_t GetDID (void) = 0; + virtual uint8_t GetSDID (void) = 0; + virtual uint32_t GetLineNumber (void) = 0; // On output, zero is auto + virtual uint8_t GetDataStreamIndex (void) = 0; // Usually zero. Can only be 1 if non-SD and the first data stream is completely full + +protected: + virtual ~IDeckLinkAncillaryPacket () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +class BMD_PUBLIC IDeckLinkAncillaryPacketIterator : public IUnknown +{ +public: + virtual HRESULT Next (/* out */ IDeckLinkAncillaryPacket **packet) = 0; + +protected: + virtual ~IDeckLinkAncillaryPacketIterator () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillaryPackets : public IUnknown +{ +public: + + virtual HRESULT GetPacketIterator (/* out */ IDeckLinkAncillaryPacketIterator **iterator) = 0; + virtual HRESULT GetFirstPacketByID (/* in */ uint8_t DID, /* in */ uint8_t SDID, /* out */ IDeckLinkAncillaryPacket **packet) = 0; + virtual HRESULT AttachPacket (/* in */ IDeckLinkAncillaryPacket *packet) = 0; // Implement IDeckLinkAncillaryPacket to output your own + virtual HRESULT DetachPacket (/* in */ IDeckLinkAncillaryPacket *packet) = 0; + virtual HRESULT DetachAllPackets (void) = 0; + +protected: + virtual ~IDeckLinkVideoFrameAncillaryPackets () {} // call Release method to drop reference count +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +class BMD_PUBLIC IDeckLinkVideoFrameAncillary : public IUnknown +{ +public: + + virtual HRESULT GetBufferForVerticalBlankingLine (/* in */ uint32_t lineNumber, /* out */ void **buffer) = 0; // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes virtual BMDPixelFormat GetPixelFormat (void) = 0; virtual BMDDisplayMode GetDisplayMode (void) = 0; @@ -858,7 +1015,7 @@ protected: /* Interface IDeckLinkEncoderPacket - Interface to encapsulate an encoded packet. */ -class IDeckLinkEncoderPacket : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderPacket : public IUnknown { public: virtual HRESULT GetBytes (/* out */ void **buffer) = 0; @@ -872,7 +1029,7 @@ protected: /* Interface IDeckLinkEncoderVideoPacket - Provided by the IDeckLinkEncoderInput video packet arrival callback. */ -class IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket +class BMD_PUBLIC IDeckLinkEncoderVideoPacket : public IDeckLinkEncoderPacket { public: virtual BMDPixelFormat GetPixelFormat (void) = 0; @@ -886,7 +1043,7 @@ protected: /* Interface IDeckLinkEncoderAudioPacket - Provided by the IDeckLinkEncoderInput audio packet arrival callback. */ -class IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket +class BMD_PUBLIC IDeckLinkEncoderAudioPacket : public IDeckLinkEncoderPacket { public: virtual BMDAudioFormat GetAudioFormat (void) = 0; @@ -897,7 +1054,7 @@ protected: /* Interface IDeckLinkH265NALPacket - Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object */ -class IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket +class BMD_PUBLIC IDeckLinkH265NALPacket : public IDeckLinkEncoderVideoPacket { public: virtual HRESULT GetUnitType (/* out */ uint8_t *unitType) = 0; @@ -910,7 +1067,7 @@ protected: /* Interface IDeckLinkAudioInputPacket - Provided by the IDeckLinkInput callback. */ -class IDeckLinkAudioInputPacket : public IUnknown +class BMD_PUBLIC IDeckLinkAudioInputPacket : public IUnknown { public: virtual long GetSampleFrameCount (void) = 0; @@ -923,7 +1080,7 @@ protected: /* Interface IDeckLinkScreenPreviewCallback - Screen preview callback */ -class IDeckLinkScreenPreviewCallback : public IUnknown +class BMD_PUBLIC IDeckLinkScreenPreviewCallback : public IUnknown { public: virtual HRESULT DrawFrame (/* in */ IDeckLinkVideoFrame *theFrame) = 0; @@ -934,7 +1091,7 @@ protected: /* Interface IDeckLinkCocoaScreenPreviewCallback - Screen preview callback for Cocoa-based applications */ -class IDeckLinkCocoaScreenPreviewCallback : public IDeckLinkScreenPreviewCallback +class BMD_PUBLIC IDeckLinkCocoaScreenPreviewCallback : public IDeckLinkScreenPreviewCallback { public: @@ -944,7 +1101,7 @@ protected: /* Interface IDeckLinkGLScreenPreviewHelper - Created with CoCreateInstance(). */ -class IDeckLinkGLScreenPreviewHelper : public IUnknown +class BMD_PUBLIC IDeckLinkGLScreenPreviewHelper : public IUnknown { public: @@ -961,7 +1118,7 @@ protected: /* Interface IDeckLinkNotificationCallback - DeckLink Notification Callback Interface */ -class IDeckLinkNotificationCallback : public IUnknown +class BMD_PUBLIC IDeckLinkNotificationCallback : public IUnknown { public: virtual HRESULT Notify (/* in */ BMDNotifications topic, /* in */ uint64_t param1, /* in */ uint64_t param2) = 0; @@ -969,7 +1126,7 @@ public: /* Interface IDeckLinkNotification - DeckLink Notification interface */ -class IDeckLinkNotification : public IUnknown +class BMD_PUBLIC IDeckLinkNotification : public IUnknown { public: virtual HRESULT Subscribe (/* in */ BMDNotifications topic, /* in */ IDeckLinkNotificationCallback *theCallback) = 0; @@ -978,7 +1135,7 @@ public: /* Interface IDeckLinkAttributes - DeckLink Attribute interface */ -class IDeckLinkAttributes : public IUnknown +class BMD_PUBLIC IDeckLinkAttributes : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkAttributeID cfgID, /* out */ bool *value) = 0; @@ -992,7 +1149,7 @@ protected: /* Interface IDeckLinkStatus - DeckLink Status interface */ -class IDeckLinkStatus : public IUnknown +class BMD_PUBLIC IDeckLinkStatus : public IUnknown { public: virtual HRESULT GetFlag (/* in */ BMDDeckLinkStatusID statusID, /* out */ bool *value) = 0; @@ -1007,7 +1164,7 @@ protected: /* Interface IDeckLinkKeyer - DeckLink Keyer interface */ -class IDeckLinkKeyer : public IUnknown +class BMD_PUBLIC IDeckLinkKeyer : public IUnknown { public: virtual HRESULT Enable (/* in */ bool isExternal) = 0; @@ -1022,7 +1179,7 @@ protected: /* Interface IDeckLinkVideoConversion - Created with CoCreateInstance(). */ -class IDeckLinkVideoConversion : public IUnknown +class BMD_PUBLIC IDeckLinkVideoConversion : public IUnknown { public: virtual HRESULT ConvertFrame (/* in */ IDeckLinkVideoFrame* srcFrame, /* in */ IDeckLinkVideoFrame* dstFrame) = 0; @@ -1033,7 +1190,7 @@ protected: /* Interface IDeckLinkDeviceNotificationCallback - DeckLink device arrival/removal notification callbacks */ -class IDeckLinkDeviceNotificationCallback : public IUnknown +class BMD_PUBLIC IDeckLinkDeviceNotificationCallback : public IUnknown { public: virtual HRESULT DeckLinkDeviceArrived (/* in */ IDeckLink* deckLinkDevice) = 0; @@ -1045,7 +1202,7 @@ protected: /* Interface IDeckLinkDiscovery - DeckLink device discovery */ -class IDeckLinkDiscovery : public IUnknown +class BMD_PUBLIC IDeckLinkDiscovery : public IUnknown { public: virtual HRESULT InstallDeviceNotifications (/* in */ IDeckLinkDeviceNotificationCallback* deviceNotificationCallback) = 0; @@ -1059,12 +1216,13 @@ protected: extern "C" { - IDeckLinkIterator* CreateDeckLinkIteratorInstance (void); - IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void); - IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void); - IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void); - IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* /* (NSView*) */ parentView); - IDeckLinkVideoConversion* CreateVideoConversionInstance (void); + IDeckLinkIterator* BMD_PUBLIC CreateDeckLinkIteratorInstance (void); + IDeckLinkDiscovery* BMD_PUBLIC CreateDeckLinkDiscoveryInstance (void); + IDeckLinkAPIInformation* BMD_PUBLIC CreateDeckLinkAPIInformationInstance (void); + IDeckLinkGLScreenPreviewHelper* BMD_PUBLIC CreateOpenGLScreenPreviewHelper (void); + IDeckLinkCocoaScreenPreviewCallback* BMD_PUBLIC CreateCocoaScreenPreview (void* /* (NSView*) */ parentView); + IDeckLinkVideoConversion* BMD_PUBLIC CreateVideoConversionInstance (void); + IDeckLinkVideoFrameAncillaryPackets* BMD_PUBLIC CreateVideoFrameAncillaryPacketsInstance (void); // For use when creating a custom IDeckLinkVideoFrame without wrapping IDeckLinkOutput::CreateVideoFrame } diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h index 31b652b..a76d33a 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,12 +37,16 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations // Interface ID Declarations -BMD_CONST REFIID IID_IDeckLinkConfiguration = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; +BMD_CONST REFIID IID_IDeckLinkConfiguration = /* EF90380B-4AE5-4346-9077-E288E149F129 */ {0xEF,0x90,0x38,0x0B,0x4A,0xE5,0x43,0x46,0x90,0x77,0xE2,0x88,0xE1,0x49,0xF1,0x29}; BMD_CONST REFIID IID_IDeckLinkEncoderConfiguration = /* 138050E5-C60A-4552-BF3F-0F358049327E */ {0x13,0x80,0x50,0xE5,0xC6,0x0A,0x45,0x52,0xBF,0x3F,0x0F,0x35,0x80,0x49,0x32,0x7E}; /* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ @@ -54,10 +58,6 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigSwapSerialRxTx = 'ssrt', - /* Video Input/Output Flags */ - - bmdDeckLinkConfigUse1080pNotPsF = 'fpro', - /* Video Input/Output Integers */ bmdDeckLinkConfigHDMI3DPackingFormat = '3dpf', @@ -78,6 +78,12 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigLowLatencyVideoOutput = 'llvo', bmdDeckLinkConfigDownConversionOnAllAnalogOutput = 'caao', bmdDeckLinkConfigSMPTELevelAOutput = 'smta', + bmdDeckLinkConfigRec2020Output = 'rec2', // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = 'SDQS', + + /* Video Output Flags */ + + bmdDeckLinkConfigOutput1080pAsPsF = 'pfpr', /* Video Output Integers */ @@ -106,6 +112,10 @@ enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigUseDedicatedLTCInput = 'dltc', // Use timecode from LTC input instead of SDI stream bmdDeckLinkConfigSDIInput3DPayloadOverride = '3dds', + /* Video Input Flags */ + + bmdDeckLinkConfigCapture1080pAsPsF = 'cfpr', + /* Video Input Integers */ bmdDeckLinkConfigVideoInputConnection = 'vicn', @@ -206,7 +216,7 @@ class IDeckLinkEncoderConfiguration; /* Interface IDeckLinkConfiguration - DeckLink Configuration interface */ -class IDeckLinkConfiguration : public IUnknown +class BMD_PUBLIC IDeckLinkConfiguration : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; @@ -225,7 +235,7 @@ protected: /* Interface IDeckLinkEncoderConfiguration - DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput */ -class IDeckLinkEncoderConfiguration : public IUnknown +class BMD_PUBLIC IDeckLinkEncoderConfiguration : public IUnknown { public: virtual HRESULT SetFlag (/* in */ BMDDeckLinkEncoderConfigurationID cfgID, /* in */ bool value) = 0; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h index ca7f815..2c989a0 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h index 29695cf..0808367 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_5.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h new file mode 100644 index 0000000..e49a3ee --- /dev/null +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIConfiguration_v10_9.h @@ -0,0 +1,62 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPICONFIGURATION_v10_9_H +#define BMD_DECKLINKAPICONFIGURATION_v10_9_H + +#include "DeckLinkAPIConfiguration.h" + +// Interface ID Declarations + +BMD_CONST REFIID IID_IDeckLinkConfiguration_v10_9 = /* CB71734A-FE37-4E8D-8E13-802133A1C3F2 */ {0xCB,0x71,0x73,0x4A,0xFE,0x37,0x4E,0x8D,0x8E,0x13,0x80,0x21,0x33,0xA1,0xC3,0xF2}; + +// +// Forward Declarations + +class IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +class IDeckLinkConfiguration_v10_9 : public IUnknown +{ +public: + virtual HRESULT SetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ bool value) = 0; + virtual HRESULT GetFlag (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ bool *value) = 0; + virtual HRESULT SetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ int64_t value) = 0; + virtual HRESULT GetInt (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ int64_t *value) = 0; + virtual HRESULT SetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ double value) = 0; + virtual HRESULT GetFloat (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ double *value) = 0; + virtual HRESULT SetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* in */ CFStringRef value) = 0; + virtual HRESULT GetString (/* in */ BMDDeckLinkConfigurationID cfgID, /* out */ CFStringRef *value) = 0; + virtual HRESULT WriteConfigurationToPreferences (void) = 0; + +protected: + virtual ~IDeckLinkConfiguration_v10_9 () {} // call Release method to drop reference count +}; + + +#endif /* defined(BMD_DECKLINKAPICONFIGURATION_v10_9_H) */ diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h index 6237ab7..b1b7797 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDeckControl.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -149,7 +153,7 @@ class IDeckLinkDeckControl; /* Interface IDeckLinkDeckControlStatusCallback - Deck control state change callback. */ -class IDeckLinkDeckControlStatusCallback : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControlStatusCallback : public IUnknown { public: virtual HRESULT TimecodeUpdate (/* in */ BMDTimecodeBCD currentTimecode) = 0; @@ -163,7 +167,7 @@ protected: /* Interface IDeckLinkDeckControl - Deck Control main interface */ -class IDeckLinkDeckControl : public IUnknown +class BMD_PUBLIC IDeckLinkDeckControl : public IUnknown { public: virtual HRESULT Open (/* in */ BMDTimeScale timeScale, /* in */ BMDTimeValue timeValue, /* in */ bool timecodeIsDropFrame, /* out */ BMDDeckControlError *error) = 0; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h index 3715a03..c8331ad 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDiscovery.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -50,7 +54,7 @@ class IDeckLink; /* Interface IDeckLink - represents a DeckLink device */ -class IDeckLink : public IUnknown +class BMD_PUBLIC IDeckLink : public IUnknown { public: virtual HRESULT GetModelName (/* out */ CFStringRef *modelName) = 0; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch.cpp index 92e41b2..7bb93ce 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch.cpp +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -42,6 +42,7 @@ typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(v typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); +typedef IDeckLinkVideoFrameAncillaryPackets* (*CreateVideoFrameAncillaryPacketsInstanceFunc)(void); static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; static CFBundleRef gDeckLinkAPIBundleRef = NULL; @@ -51,9 +52,10 @@ static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc= NULL; +static CreateVideoFrameAncillaryPacketsInstanceFunc gCreateVideoFrameAncillaryPacketsFunc = NULL; -void InitDeckLinkAPI (void) +static void InitDeckLinkAPI (void) { CFURLRef bundleURL; @@ -63,12 +65,13 @@ void InitDeckLinkAPI (void) gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); if (gDeckLinkAPIBundleRef != NULL) { - gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0002")); + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0003")); gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); - gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0001")); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0002")); + gCreateVideoFrameAncillaryPacketsFunc = (CreateVideoFrameAncillaryPacketsInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoFrameAncillaryPacketsInstance_0001")); } CFRelease(bundleURL); } @@ -79,70 +82,80 @@ bool IsDeckLinkAPIPresent (void) // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller if (gDeckLinkAPIBundleRef != NULL) return true; - + return false; } IDeckLinkIterator* CreateDeckLinkIteratorInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateIteratorFunc == NULL) return NULL; - + return gCreateIteratorFunc(); } IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateAPIInformationFunc == NULL) return NULL; - + return gCreateAPIInformationFunc(); } IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; - + return gCreateOpenGLPreviewFunc(); } IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateCocoaPreviewFunc == NULL) return NULL; - + return gCreateCocoaPreviewFunc(parentView); } IDeckLinkVideoConversion* CreateVideoConversionInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateVideoConversionFunc == NULL) return NULL; - + return gCreateVideoConversionFunc(); } IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateDeckLinkDiscoveryFunc == NULL) return NULL; - + return gCreateDeckLinkDiscoveryFunc(); } +IDeckLinkVideoFrameAncillaryPackets* CreateVideoFrameAncillaryPacketsInstance (void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoFrameAncillaryPacketsFunc == NULL) + return NULL; + + return gCreateVideoFrameAncillaryPacketsFunc(); +} + #define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" @@ -154,7 +167,7 @@ static CFBundleRef gBMDStreamingAPIBundleRef = NULL; static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; static CreateNALParserFunc gCreateNALParserFunc = NULL; -void InitBMDStreamingAPI(void) +static void InitBMDStreamingAPI(void) { CFURLRef bundleURL; @@ -164,7 +177,7 @@ void InitBMDStreamingAPI(void) gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); if (gBMDStreamingAPIBundleRef != NULL) { - gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0001")); + gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0002")); gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); } diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp new file mode 100644 index 0000000..c412a10 --- /dev/null +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v10_8.cpp @@ -0,0 +1,193 @@ +/* -LICENSE-START- +** Copyright (c) 2009 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ +/* DeckLinkAPIDispatch.cpp */ + +#include "DeckLinkAPI.h" +#include + +#if BLACKMAGIC_DECKLINK_API_MAGIC != 1 +#error The DeckLink API version of DeckLinkAPIDispatch.cpp is not the same version as DeckLinkAPI.h +#endif + +#define kDeckLinkAPI_BundlePath "/Library/Frameworks/DeckLinkAPI.framework" + + +typedef IDeckLinkIterator* (*CreateIteratorFunc)(void); +typedef IDeckLinkAPIInformation* (*CreateAPIInformationFunc)(void); +typedef IDeckLinkGLScreenPreviewHelper* (*CreateOpenGLScreenPreviewHelperFunc)(void); +typedef IDeckLinkCocoaScreenPreviewCallback* (*CreateCocoaScreenPreviewFunc)(void*); +typedef IDeckLinkVideoConversion* (*CreateVideoConversionInstanceFunc)(void); +typedef IDeckLinkDiscovery* (*CreateDeckLinkDiscoveryInstanceFunc)(void); + +static pthread_once_t gDeckLinkOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gDeckLinkAPIBundleRef = NULL; +static CreateIteratorFunc gCreateIteratorFunc = NULL; +static CreateAPIInformationFunc gCreateAPIInformationFunc = NULL; +static CreateOpenGLScreenPreviewHelperFunc gCreateOpenGLPreviewFunc = NULL; +static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; +static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; +static CreateDeckLinkDiscoveryInstanceFunc gCreateDeckLinkDiscoveryFunc = NULL; + + +static void InitDeckLinkAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kDeckLinkAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gDeckLinkAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gDeckLinkAPIBundleRef != NULL) + { + gCreateIteratorFunc = (CreateIteratorFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkIteratorInstance_0002")); + gCreateAPIInformationFunc = (CreateAPIInformationFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkAPIInformationInstance_0001")); + gCreateOpenGLPreviewFunc = (CreateOpenGLScreenPreviewHelperFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateOpenGLScreenPreviewHelper_0001")); + gCreateCocoaPreviewFunc = (CreateCocoaScreenPreviewFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateCocoaScreenPreview_0001")); + gCreateVideoConversionFunc = (CreateVideoConversionInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateVideoConversionInstance_0001")); + gCreateDeckLinkDiscoveryFunc = (CreateDeckLinkDiscoveryInstanceFunc)CFBundleGetFunctionPointerForName(gDeckLinkAPIBundleRef, CFSTR("CreateDeckLinkDiscoveryInstance_0001")); + } + CFRelease(bundleURL); + } +} + +bool IsDeckLinkAPIPresent(void) +{ + // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller + if (gDeckLinkAPIBundleRef != NULL) + return true; + + return false; +} + +IDeckLinkIterator* CreateDeckLinkIteratorInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateIteratorFunc == NULL) + return NULL; + + return gCreateIteratorFunc(); +} + +IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateAPIInformationFunc == NULL) + return NULL; + + return gCreateAPIInformationFunc(); +} + +IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateOpenGLPreviewFunc == NULL) + return NULL; + + return gCreateOpenGLPreviewFunc(); +} + +IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview(void* parentView) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateCocoaPreviewFunc == NULL) + return NULL; + + return gCreateCocoaPreviewFunc(parentView); +} + +IDeckLinkVideoConversion* CreateVideoConversionInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateVideoConversionFunc == NULL) + return NULL; + + return gCreateVideoConversionFunc(); +} + +IDeckLinkDiscovery* CreateDeckLinkDiscoveryInstance(void) +{ + pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); + + if (gCreateDeckLinkDiscoveryFunc == NULL) + return NULL; + + return gCreateDeckLinkDiscoveryFunc(); +} + + +#define kBMDStreamingAPI_BundlePath "/Library/Application Support/Blackmagic Design/Streaming/BMDStreamingAPI.bundle" + +typedef IBMDStreamingDiscovery* (*CreateDiscoveryFunc)(void); +typedef IBMDStreamingH264NALParser* (*CreateNALParserFunc)(void); + +static pthread_once_t gBMDStreamingOnceControl = PTHREAD_ONCE_INIT; +static CFBundleRef gBMDStreamingAPIBundleRef = NULL; +static CreateDiscoveryFunc gCreateDiscoveryFunc = NULL; +static CreateNALParserFunc gCreateNALParserFunc = NULL; + +static void InitBMDStreamingAPI(void) +{ + CFURLRef bundleURL; + + bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR(kBMDStreamingAPI_BundlePath), kCFURLPOSIXPathStyle, true); + if (bundleURL != NULL) + { + gBMDStreamingAPIBundleRef = CFBundleCreate(kCFAllocatorDefault, bundleURL); + if (gBMDStreamingAPIBundleRef != NULL) + { + gCreateDiscoveryFunc = (CreateDiscoveryFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingDiscoveryInstance_0001")); + gCreateNALParserFunc = (CreateNALParserFunc)CFBundleGetFunctionPointerForName(gBMDStreamingAPIBundleRef, CFSTR("CreateBMDStreamingH264NALParser_0001")); + } + + CFRelease(bundleURL); + } +} + +IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateDiscoveryFunc == NULL) + return NULL; + + return gCreateDiscoveryFunc(); +} + +IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser() +{ + pthread_once(&gBMDStreamingOnceControl, InitBMDStreamingAPI); + + if (gCreateNALParserFunc == NULL) + return NULL; + + return gCreateNALParserFunc(); +} diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp index 8b0c0cc..ba918b0 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v7_6.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -44,7 +44,7 @@ static CreateCocoaScreenPreviewFunc_v7_6 gCreateCocoaPreviewFunc = NULL; static CreateVideoConversionInstanceFunc_v7_6 gCreateVideoConversionFunc = NULL; -void InitDeckLinkAPI_v7_6 (void) +static void InitDeckLinkAPI_v7_6 (void) { CFURLRef bundleURL; @@ -66,40 +66,40 @@ void InitDeckLinkAPI_v7_6 (void) IDeckLinkIterator* CreateDeckLinkIteratorInstance_v7_6 (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateIteratorFunc == NULL) return NULL; - + return gCreateIteratorFunc(); } IDeckLinkGLScreenPreviewHelper_v7_6* CreateOpenGLScreenPreviewHelper_v7_6 (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; - + return gCreateOpenGLPreviewFunc(); } IDeckLinkCocoaScreenPreviewCallback_v7_6* CreateCocoaScreenPreview_v7_6 (void* parentView) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateCocoaPreviewFunc == NULL) return NULL; - + return gCreateCocoaPreviewFunc(parentView); } IDeckLinkVideoConversion_v7_6* CreateVideoConversionInstance_v7_6 (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI_v7_6); - + if (gCreateVideoConversionFunc == NULL) return NULL; - + return gCreateVideoConversionFunc(); } diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp index 898d739..3791bf4 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIDispatch_v8_0.cpp @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -50,7 +50,7 @@ static CreateCocoaScreenPreviewFunc gCreateCocoaPreviewFunc = NULL; static CreateVideoConversionInstanceFunc gCreateVideoConversionFunc = NULL; -void InitDeckLinkAPI (void) +static void InitDeckLinkAPI (void) { CFURLRef bundleURL; @@ -75,57 +75,57 @@ bool IsDeckLinkAPIPresent (void) // If the DeckLink API bundle was successfully loaded, return this knowledge to the caller if (gDeckLinkAPIBundleRef != NULL) return true; - + return false; } IDeckLinkIterator_v8_0* CreateDeckLinkIteratorInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateIteratorFunc == NULL) return NULL; - + return gCreateIteratorFunc(); } IDeckLinkAPIInformation* CreateDeckLinkAPIInformationInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateAPIInformationFunc == NULL) return NULL; - + return gCreateAPIInformationFunc(); } IDeckLinkGLScreenPreviewHelper* CreateOpenGLScreenPreviewHelper (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateOpenGLPreviewFunc == NULL) return NULL; - + return gCreateOpenGLPreviewFunc(); } IDeckLinkCocoaScreenPreviewCallback* CreateCocoaScreenPreview (void* parentView) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateCocoaPreviewFunc == NULL) return NULL; - + return gCreateCocoaPreviewFunc(parentView); } IDeckLinkVideoConversion* CreateVideoConversionInstance (void) { pthread_once(&gDeckLinkOnceControl, InitDeckLinkAPI); - + if (gCreateVideoConversionFunc == NULL) return NULL; - + return gCreateVideoConversionFunc(); } diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h index 3bc3429..9a242e0 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIModes.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -65,12 +69,12 @@ enum _BMDDisplayMode { bmdModeHD1080p25 = 'Hp25', bmdModeHD1080p2997 = 'Hp29', bmdModeHD1080p30 = 'Hp30', - bmdModeHD1080i50 = 'Hi50', - bmdModeHD1080i5994 = 'Hi59', - bmdModeHD1080i6000 = 'Hi60', // N.B. This _really_ is 60.00 Hz. bmdModeHD1080p50 = 'Hp50', bmdModeHD1080p5994 = 'Hp59', bmdModeHD1080p6000 = 'Hp60', // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080i50 = 'Hi50', + bmdModeHD1080i5994 = 'Hi59', + bmdModeHD1080i6000 = 'Hi60', // N.B. This _really_ is 60.00 Hz. /* HD 720 Modes */ @@ -78,19 +82,24 @@ enum _BMDDisplayMode { bmdModeHD720p5994 = 'hp59', bmdModeHD720p60 = 'hp60', - /* 2k Modes */ + /* 2K Modes */ bmdMode2k2398 = '2k23', bmdMode2k24 = '2k24', bmdMode2k25 = '2k25', - /* DCI Modes (output only) */ + /* 2K DCI Modes */ bmdMode2kDCI2398 = '2d23', bmdMode2kDCI24 = '2d24', bmdMode2kDCI25 = '2d25', + bmdMode2kDCI2997 = '2d29', + bmdMode2kDCI30 = '2d30', + bmdMode2kDCI50 = '2d50', + bmdMode2kDCI5994 = '2d59', + bmdMode2kDCI60 = '2d60', - /* 4k Modes */ + /* 4K UHD Modes */ bmdMode4K2160p2398 = '4k23', bmdMode4K2160p24 = '4k24', @@ -101,11 +110,43 @@ enum _BMDDisplayMode { bmdMode4K2160p5994 = '4k59', bmdMode4K2160p60 = '4k60', - /* DCI Modes (output only) */ + /* 4K DCI Modes */ bmdMode4kDCI2398 = '4d23', bmdMode4kDCI24 = '4d24', bmdMode4kDCI25 = '4d25', + bmdMode4kDCI2997 = '4d29', + bmdMode4kDCI30 = '4d30', + bmdMode4kDCI50 = '4d50', + bmdMode4kDCI5994 = '4d59', + bmdMode4kDCI60 = '4d60', + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = '8k23', + bmdMode8K4320p24 = '8k24', + bmdMode8K4320p25 = '8k25', + bmdMode8K4320p2997 = '8k29', + bmdMode8K4320p30 = '8k30', + bmdMode8K4320p50 = '8k50', + bmdMode8K4320p5994 = '8k59', + bmdMode8K4320p60 = '8k60', + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = '8d23', + bmdMode8kDCI24 = '8d24', + bmdMode8kDCI25 = '8d25', + bmdMode8kDCI2997 = '8d29', + bmdMode8kDCI30 = '8d30', + bmdMode8kDCI50 = '8d50', + bmdMode8kDCI5994 = '8d59', + bmdMode8kDCI60 = '8d60', + + /* RAW Modes for Cintel (input only) */ + + bmdModeCintelRAW = 'rwci', // Frame size up to 4096x3072, variable frame rate + bmdModeCintelCompressedRAW = 'rwcc', // Frame size up to 4096x3072, variable frame rate /* Special Modes */ @@ -140,7 +181,12 @@ enum _BMDPixelFormat { /* AVID DNxHR */ - bmdFormatDNxHR = 'AVdh' + bmdFormatDNxHR = 'AVdh', + + /* Cintel formats */ + + bmdFormat12BitRAWGRBG = 'r12p', // 12-bit RAW data for bayer pattern GRBG + bmdFormat12BitRAWJPEG = 'r16p' // 12-bit RAW data arranged in tiles and JPEG compressed }; /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ @@ -149,7 +195,8 @@ typedef uint32_t BMDDisplayModeFlags; enum _BMDDisplayModeFlags { bmdDisplayModeSupports3D = 1 << 0, bmdDisplayModeColorspaceRec601 = 1 << 1, - bmdDisplayModeColorspaceRec709 = 1 << 2 + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 }; // Forward Declarations @@ -159,7 +206,7 @@ class IDeckLinkDisplayMode; /* Interface IDeckLinkDisplayModeIterator - enumerates over supported input/output display modes. */ -class IDeckLinkDisplayModeIterator : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayModeIterator : public IUnknown { public: virtual HRESULT Next (/* out */ IDeckLinkDisplayMode **deckLinkDisplayMode) = 0; @@ -170,7 +217,7 @@ protected: /* Interface IDeckLinkDisplayMode - represents a display mode */ -class IDeckLinkDisplayMode : public IUnknown +class BMD_PUBLIC IDeckLinkDisplayMode : public IUnknown { public: virtual HRESULT GetName (/* out */ CFStringRef *name) = 0; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h index 6bb5168..c2d357c 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIStreaming.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations @@ -92,8 +96,8 @@ enum _BMDStreamingEncodingFrameRate { typedef uint32_t BMDStreamingEncodingSupport; enum _BMDStreamingEncodingSupport { bmdStreamingEncodingModeNotSupported = 0, - bmdStreamingEncodingModeSupported, - bmdStreamingEncodingModeSupportedWithChanges + bmdStreamingEncodingModeSupported, + bmdStreamingEncodingModeSupportedWithChanges }; /* Enum BMDStreamingVideoCodec - Video codecs */ @@ -188,7 +192,7 @@ class IBMDStreamingH264NALParser; /* Interface IBMDStreamingDeviceNotificationCallback - Device notification callbacks. */ -class IBMDStreamingDeviceNotificationCallback : public IUnknown +class BMD_PUBLIC IBMDStreamingDeviceNotificationCallback : public IUnknown { public: virtual HRESULT StreamingDeviceArrived (/* in */ IDeckLink* device) = 0; @@ -201,7 +205,7 @@ protected: /* Interface IBMDStreamingH264InputCallback - H264 input callbacks. */ -class IBMDStreamingH264InputCallback : public IUnknown +class BMD_PUBLIC IBMDStreamingH264InputCallback : public IUnknown { public: virtual HRESULT H264NALPacketArrived (/* in */ IBMDStreamingH264NALPacket* nalPacket) = 0; @@ -217,7 +221,7 @@ protected: /* Interface IBMDStreamingDiscovery - Installs device notifications */ -class IBMDStreamingDiscovery : public IUnknown +class BMD_PUBLIC IBMDStreamingDiscovery : public IUnknown { public: virtual HRESULT InstallDeviceNotifications (/* in */ IBMDStreamingDeviceNotificationCallback* theCallback) = 0; @@ -229,7 +233,7 @@ protected: /* Interface IBMDStreamingVideoEncodingMode - Represents an encoded video mode. */ -class IBMDStreamingVideoEncodingMode : public IUnknown +class BMD_PUBLIC IBMDStreamingVideoEncodingMode : public IUnknown { public: virtual HRESULT GetName (/* out */ CFStringRef *name) = 0; @@ -252,7 +256,7 @@ protected: /* Interface IBMDStreamingMutableVideoEncodingMode - Represents a mutable encoded video mode. */ -class IBMDStreamingMutableVideoEncodingMode : public IBMDStreamingVideoEncodingMode +class BMD_PUBLIC IBMDStreamingMutableVideoEncodingMode : public IBMDStreamingVideoEncodingMode { public: virtual HRESULT SetSourceRect (/* in */ uint32_t posX, /* in */ uint32_t posY, /* in */ uint32_t width, /* in */ uint32_t height) = 0; @@ -268,7 +272,7 @@ protected: /* Interface IBMDStreamingVideoEncodingModePresetIterator - Enumerates encoding mode presets */ -class IBMDStreamingVideoEncodingModePresetIterator : public IUnknown +class BMD_PUBLIC IBMDStreamingVideoEncodingModePresetIterator : public IUnknown { public: virtual HRESULT Next (/* out */ IBMDStreamingVideoEncodingMode** videoEncodingMode) = 0; @@ -279,7 +283,7 @@ protected: /* Interface IBMDStreamingDeviceInput - Created by QueryInterface from IDeckLink */ -class IBMDStreamingDeviceInput : public IUnknown +class BMD_PUBLIC IBMDStreamingDeviceInput : public IUnknown { public: @@ -309,7 +313,7 @@ protected: /* Interface IBMDStreamingH264NALPacket - Represent an H.264 NAL packet */ -class IBMDStreamingH264NALPacket : public IUnknown +class BMD_PUBLIC IBMDStreamingH264NALPacket : public IUnknown { public: virtual long GetPayloadSize (void) = 0; @@ -324,7 +328,7 @@ protected: /* Interface IBMDStreamingAudioPacket - Represents a chunk of audio data */ -class IBMDStreamingAudioPacket : public IUnknown +class BMD_PUBLIC IBMDStreamingAudioPacket : public IUnknown { public: virtual BMDStreamingAudioCodec GetCodec (void) = 0; @@ -339,7 +343,7 @@ protected: /* Interface IBMDStreamingMPEG2TSPacket - Represent an MPEG2 Transport Stream packet */ -class IBMDStreamingMPEG2TSPacket : public IUnknown +class BMD_PUBLIC IBMDStreamingMPEG2TSPacket : public IUnknown { public: virtual long GetPayloadSize (void) = 0; @@ -351,7 +355,7 @@ protected: /* Interface IBMDStreamingH264NALParser - For basic NAL parsing */ -class IBMDStreamingH264NALParser : public IUnknown +class BMD_PUBLIC IBMDStreamingH264NALParser : public IUnknown { public: virtual HRESULT IsNALSequenceParameterSet (/* in */ IBMDStreamingH264NALPacket* nal) = 0; @@ -366,8 +370,8 @@ protected: extern "C" { - IBMDStreamingDiscovery* CreateBMDStreamingDiscoveryInstance (void); - IBMDStreamingH264NALParser* CreateBMDStreamingH264NALParser (void); + IBMDStreamingDiscovery* BMD_PUBLIC CreateBMDStreamingDiscoveryInstance (void); + IBMDStreamingH264NALParser* BMD_PUBLIC CreateBMDStreamingH264NALParser (void); } diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h index 04da49f..1564c6e 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPITypes.h @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,6 +37,10 @@ #endif #endif +#ifndef BMD_PUBLIC + #define BMD_PUBLIC +#endif + // Type Declarations typedef int64_t BMDTimeValue; @@ -54,7 +58,8 @@ typedef uint32_t BMDTimecodeFlags; enum _BMDTimecodeFlags { bmdTimecodeFlagDefault = 0, bmdTimecodeIsDropFrame = 1 << 0, - bmdTimecodeFieldMark = 1 << 1 + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2 }; /* Enum BMDVideoConnection - Video connection types */ @@ -96,7 +101,7 @@ class IDeckLinkTimecode; /* Interface IDeckLinkTimecode - Used for video frame timecode representation. */ -class IDeckLinkTimecode : public IUnknown +class BMD_PUBLIC IDeckLinkTimecode : public IUnknown { public: virtual BMDTimecodeBCD GetBCD (void) = 0; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h index 55b24b1..f9db7ff 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPIVersion.h @@ -7,14 +7,14 @@ * ** execute, and transmit the Software, and to prepare derivative works of the * ** Software, and to permit third-parties to whom the Software is furnished to * ** do so, all subject to the following: - * ** + * ** * ** The copyright notices in the Software and this entire statement, including * ** the above license grant, this restriction and the following disclaimer, * ** must be included in all copies of the Software, in whole or in part, and * ** all derivative works of the Software, unless such copies or derivative * ** works are solely in the form of machine-executable object code generated by * ** a source language processor. - * ** + * ** * ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -30,7 +30,8 @@ #ifndef __DeckLink_API_Version_h__ #define __DeckLink_API_Version_h__ -#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a080000 -#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.8" +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a0b0400 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.11.4" #endif // __DeckLink_API_Version_h__ + diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h index 29ff820..e5c95e4 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -37,7 +37,7 @@ typedef uint32_t BMDDeckLinkConfigurationID_v10_2; enum _BMDDeckLinkConfigurationID_v10_2 { /* Video output flags */ - + bmdDeckLinkConfig3GBpsVideoOutput_v10_2 = '3gbs', }; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_9.h new file mode 100644 index 0000000..aec8c7c --- /dev/null +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v10_9.h @@ -0,0 +1,45 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + +#ifndef BMD_DECKLINKAPI_v10_9_H +#define BMD_DECKLINKAPI_v10_9_H + +#include "DeckLinkAPI.h" + +// Type Declarations + +/* Enum BMDDeckLinkAttributeID - DeckLink Attribute ID */ + +typedef uint32_t BMDDeckLinkConfigurationID_v10_9; +enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = 'fpro', +}; + +#endif /* defined(BMD_DECKLINKAPI_v10_9_H) */ diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h index 50e0d11..68d0beb 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_1.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -102,37 +102,37 @@ public: // Display mode predicates virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1* *iterator) = 0; - - + + // Video output virtual HRESULT STDMETHODCALLTYPE EnableVideoOutput (BMDDisplayMode displayMode) = 0; virtual HRESULT STDMETHODCALLTYPE DisableVideoOutput () = 0; - + virtual HRESULT STDMETHODCALLTYPE SetVideoOutputFrameMemoryAllocator (IDeckLinkMemoryAllocator* theAllocator) = 0; virtual HRESULT STDMETHODCALLTYPE CreateVideoFrame (int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; virtual HRESULT STDMETHODCALLTYPE CreateVideoFrameFromBuffer (void* buffer, int32_t width, int32_t height, int32_t rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1* *outFrame) = 0; - + virtual HRESULT STDMETHODCALLTYPE DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame) = 0; virtual HRESULT STDMETHODCALLTYPE ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale) = 0; virtual HRESULT STDMETHODCALLTYPE SetScheduledFrameCompletionCallback (IDeckLinkVideoOutputCallback_v7_1* theCallback) = 0; - - + + // Audio output virtual HRESULT STDMETHODCALLTYPE EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; virtual HRESULT STDMETHODCALLTYPE DisableAudioOutput () = 0; - + virtual HRESULT STDMETHODCALLTYPE WriteAudioSamplesSync (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT STDMETHODCALLTYPE BeginAudioPreroll () = 0; virtual HRESULT STDMETHODCALLTYPE EndAudioPreroll () = 0; virtual HRESULT STDMETHODCALLTYPE ScheduleAudioSamples (void* buffer, uint32_t sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; virtual HRESULT STDMETHODCALLTYPE FlushBufferedAudioSamples () = 0; - + virtual HRESULT STDMETHODCALLTYPE SetAudioCallback (IDeckLinkAudioOutputCallback* theCallback) = 0; - - + + // Output control virtual HRESULT STDMETHODCALLTYPE StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed) = 0; virtual HRESULT STDMETHODCALLTYPE StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale) = 0; @@ -145,17 +145,17 @@ class IDeckLinkInput_v7_1 : public IUnknown public: virtual HRESULT STDMETHODCALLTYPE DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDDisplayModeSupport *result) = 0; virtual HRESULT STDMETHODCALLTYPE GetDisplayModeIterator (IDeckLinkDisplayModeIterator_v7_1 **iterator) = 0; - + // Video input virtual HRESULT STDMETHODCALLTYPE EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags) = 0; virtual HRESULT STDMETHODCALLTYPE DisableVideoInput () = 0; - + // Audio input virtual HRESULT STDMETHODCALLTYPE EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, uint32_t channelCount) = 0; virtual HRESULT STDMETHODCALLTYPE DisableAudioInput () = 0; virtual HRESULT STDMETHODCALLTYPE ReadAudioSamples (void* buffer, uint32_t sampleFrameCount, uint32_t *sampleFramesRead, BMDTimeValue *audioPacketTime, BMDTimeScale timeScale) = 0; virtual HRESULT STDMETHODCALLTYPE GetBufferedAudioSampleFrameCount (uint32_t *bufferedSampleCount) = 0; - + // Input control virtual HRESULT STDMETHODCALLTYPE StartStreams () = 0; virtual HRESULT STDMETHODCALLTYPE StopStreams () = 0; @@ -188,7 +188,7 @@ class IDeckLinkAudioInputPacket_v7_1 : public IUnknown public: virtual long STDMETHODCALLTYPE GetSampleCount () = 0; virtual HRESULT STDMETHODCALLTYPE GetBytes (void* *buffer) = 0; - + virtual HRESULT STDMETHODCALLTYPE GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale) = 0; }; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h index c8b3da8..430a905 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_3.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h index 93d7c04..a90d497 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_6.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -356,49 +356,49 @@ class IDeckLinkConfiguration_v7_6 : public IUnknown public: virtual HRESULT GetConfigurationValidator (/* out */ IDeckLinkConfiguration_v7_6 **configObject) = 0; virtual HRESULT WriteConfigurationToPreferences (void) = 0; - + /* Video Output Configuration */ - + virtual HRESULT SetVideoOutputFormat (/* in */ BMDVideoConnection_v7_6 videoOutputConnection) = 0; virtual HRESULT IsVideoOutputActive (/* in */ BMDVideoConnection_v7_6 videoOutputConnection, /* out */ bool *active) = 0; - + virtual HRESULT SetAnalogVideoOutputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; virtual HRESULT GetAnalogVideoOutputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; - + virtual HRESULT EnableFieldFlickerRemovalWhenPaused (/* in */ bool enable) = 0; virtual HRESULT IsEnabledFieldFlickerRemovalWhenPaused (/* out */ bool *enabled) = 0; - + virtual HRESULT Set444And3GBpsVideoOutput (/* in */ bool enable444VideoOutput, /* in */ bool enable3GbsOutput) = 0; virtual HRESULT Get444And3GBpsVideoOutput (/* out */ bool *is444VideoOutputEnabled, /* out */ bool *threeGbsOutputEnabled) = 0; - + virtual HRESULT SetVideoOutputConversionMode (/* in */ BMDVideoOutputConversionMode conversionMode) = 0; virtual HRESULT GetVideoOutputConversionMode (/* out */ BMDVideoOutputConversionMode *conversionMode) = 0; - + virtual HRESULT Set_HD1080p24_to_HD1080i5994_Conversion (/* in */ bool enable) = 0; virtual HRESULT Get_HD1080p24_to_HD1080i5994_Conversion (/* out */ bool *enabled) = 0; - + /* Video Input Configuration */ - + virtual HRESULT SetVideoInputFormat (/* in */ BMDVideoConnection_v7_6 videoInputFormat) = 0; virtual HRESULT GetVideoInputFormat (/* out */ BMDVideoConnection_v7_6 *videoInputFormat) = 0; - + virtual HRESULT SetAnalogVideoInputFlags (/* in */ BMDAnalogVideoFlags analogVideoFlags) = 0; virtual HRESULT GetAnalogVideoInputFlags (/* out */ BMDAnalogVideoFlags *analogVideoFlags) = 0; - + virtual HRESULT SetVideoInputConversionMode (/* in */ BMDVideoInputConversionMode conversionMode) = 0; virtual HRESULT GetVideoInputConversionMode (/* out */ BMDVideoInputConversionMode *conversionMode) = 0; - + virtual HRESULT SetBlackVideoOutputDuringCapture (/* in */ bool blackOutInCapture) = 0; virtual HRESULT GetBlackVideoOutputDuringCapture (/* out */ bool *blackOutInCapture) = 0; - + virtual HRESULT Set32PulldownSequenceInitialTimecodeFrame (/* in */ uint32_t aFrameTimecode) = 0; virtual HRESULT Get32PulldownSequenceInitialTimecodeFrame (/* out */ uint32_t *aFrameTimecode) = 0; - + virtual HRESULT SetVancSourceLineMapping (/* in */ uint32_t activeLine1VANCsource, /* in */ uint32_t activeLine2VANCsource, /* in */ uint32_t activeLine3VANCsource) = 0; virtual HRESULT GetVancSourceLineMapping (/* out */ uint32_t *activeLine1VANCsource, /* out */ uint32_t *activeLine2VANCsource, /* out */ uint32_t *activeLine3VANCsource) = 0; - + /* Audio Input Configuration */ - + virtual HRESULT SetAudioInputFormat (/* in */ BMDAudioConnection audioInputFormat) = 0; virtual HRESULT GetAudioInputFormat (/* out */ BMDAudioConnection *audioInputFormat) = 0; }; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h index 327a382..c882f61 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v7_9.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h index b4e8f21..ea06183 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_0.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h index e1444cd..0eea695 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v8_1.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: - ** + ** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. - ** + ** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -59,7 +59,7 @@ public: virtual HRESULT VTRControlStateChanged (/* in */ BMDDeckControlVTRControlState_v8_1 newState, /* in */ BMDDeckControlError error) = 0; virtual HRESULT DeckControlEventReceived (/* in */ BMDDeckControlEvent event, /* in */ BMDDeckControlError error) = 0; virtual HRESULT DeckControlStatusChanged (/* in */ BMDDeckControlStatusFlags flags, /* in */ uint32_t mask) = 0; - + protected: virtual ~IDeckLinkDeckControlStatusCallback_v8_1 () {}; // call Release method to drop reference count }; @@ -102,7 +102,7 @@ public: virtual HRESULT CrashRecordStart (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT CrashRecordStop (/* out */ BMDDeckControlError *error) = 0; virtual HRESULT SetCallback (/* in */ IDeckLinkDeckControlStatusCallback_v8_1 *callback) = 0; - + protected: virtual ~IDeckLinkDeckControl_v8_1 () {}; // call Release method to drop reference count }; diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h index 236d182..ab2aa03 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_2.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h index 3fa3a50..966c8ad 100644 --- a/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h +++ b/plugins/decklink/mac/decklink-sdk/DeckLinkAPI_v9_9.h @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -47,51 +47,51 @@ class IDeckLinkOutput_v9_9 : public IUnknown public: virtual HRESULT DoesSupportVideoMode (/* in */ BMDDisplayMode displayMode, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDVideoOutputFlags flags, /* out */ BMDDisplayModeSupport *result, /* out */ IDeckLinkDisplayMode **resultDisplayMode) = 0; virtual HRESULT GetDisplayModeIterator (/* out */ IDeckLinkDisplayModeIterator **iterator) = 0; - + virtual HRESULT SetScreenPreviewCallback (/* in */ IDeckLinkScreenPreviewCallback *previewCallback) = 0; - + /* Video Output */ - + virtual HRESULT EnableVideoOutput (/* in */ BMDDisplayMode displayMode, /* in */ BMDVideoOutputFlags flags) = 0; virtual HRESULT DisableVideoOutput (void) = 0; - + virtual HRESULT SetVideoOutputFrameMemoryAllocator (/* in */ IDeckLinkMemoryAllocator *theAllocator) = 0; virtual HRESULT CreateVideoFrame (/* in */ int32_t width, /* in */ int32_t height, /* in */ int32_t rowBytes, /* in */ BMDPixelFormat pixelFormat, /* in */ BMDFrameFlags flags, /* out */ IDeckLinkMutableVideoFrame **outFrame) = 0; virtual HRESULT CreateAncillaryData (/* in */ BMDPixelFormat pixelFormat, /* out */ IDeckLinkVideoFrameAncillary **outBuffer) = 0; - + virtual HRESULT DisplayVideoFrameSync (/* in */ IDeckLinkVideoFrame *theFrame) = 0; virtual HRESULT ScheduleVideoFrame (/* in */ IDeckLinkVideoFrame *theFrame, /* in */ BMDTimeValue displayTime, /* in */ BMDTimeValue displayDuration, /* in */ BMDTimeScale timeScale) = 0; virtual HRESULT SetScheduledFrameCompletionCallback (/* in */ IDeckLinkVideoOutputCallback *theCallback) = 0; virtual HRESULT GetBufferedVideoFrameCount (/* out */ uint32_t *bufferedFrameCount) = 0; - + /* Audio Output */ - + virtual HRESULT EnableAudioOutput (/* in */ BMDAudioSampleRate sampleRate, /* in */ BMDAudioSampleType sampleType, /* in */ uint32_t channelCount, /* in */ BMDAudioOutputStreamType streamType) = 0; virtual HRESULT DisableAudioOutput (void) = 0; - + virtual HRESULT WriteAudioSamplesSync (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* out */ uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT BeginAudioPreroll (void) = 0; virtual HRESULT EndAudioPreroll (void) = 0; virtual HRESULT ScheduleAudioSamples (/* in */ void *buffer, /* in */ uint32_t sampleFrameCount, /* in */ BMDTimeValue streamTime, /* in */ BMDTimeScale timeScale, /* out */ uint32_t *sampleFramesWritten) = 0; - + virtual HRESULT GetBufferedAudioSampleFrameCount (/* out */ uint32_t *bufferedSampleFrameCount) = 0; virtual HRESULT FlushBufferedAudioSamples (void) = 0; - + virtual HRESULT SetAudioCallback (/* in */ IDeckLinkAudioOutputCallback *theCallback) = 0; - + /* Output Control */ - + virtual HRESULT StartScheduledPlayback (/* in */ BMDTimeValue playbackStartTime, /* in */ BMDTimeScale timeScale, /* in */ double playbackSpeed) = 0; virtual HRESULT StopScheduledPlayback (/* in */ BMDTimeValue stopPlaybackAtTime, /* out */ BMDTimeValue *actualStopTime, /* in */ BMDTimeScale timeScale) = 0; virtual HRESULT IsScheduledPlaybackRunning (/* out */ bool *active) = 0; virtual HRESULT GetScheduledStreamTime (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *streamTime, /* out */ double *playbackSpeed) = 0; virtual HRESULT GetReferenceStatus (/* out */ BMDReferenceStatus *referenceStatus) = 0; - + /* Hardware Timing */ - + virtual HRESULT GetHardwareReferenceClock (/* in */ BMDTimeScale desiredTimeScale, /* out */ BMDTimeValue *hardwareTime, /* out */ BMDTimeValue *timeInFrame, /* out */ BMDTimeValue *ticksPerFrame) = 0; - + protected: virtual ~IDeckLinkOutput_v9_9 () {}; // call Release method to drop reference count }; diff --git a/plugins/decklink/mac/platform.cpp b/plugins/decklink/mac/platform.cpp index 02e8a59..21ca4ec 100644 --- a/plugins/decklink/mac/platform.cpp +++ b/plugins/decklink/mac/platform.cpp @@ -1,22 +1,17 @@ #include "../platform.hpp" +#include bool DeckLinkStringToStdString(decklink_string_t input, std::string& output) { const CFStringRef string = static_cast(input); - const CFIndex length = CFStringGetLength(string); - const CFIndex maxLength = CFStringGetMaximumSizeForEncoding(length, - kCFStringEncodingASCII) + 1; - char * const buffer = new char[maxLength]; + char *buffer = cfstr_copy_cstr(string, kCFStringEncodingASCII); - const bool result = CFStringGetCString(string, buffer, maxLength, - kCFStringEncodingASCII); - - if (result) + if (buffer) output = std::string(buffer); - delete[] buffer; + bfree(buffer); CFRelease(string); - return result; + return (buffer != NULL); } diff --git a/plugins/decklink/plugin-main.cpp b/plugins/decklink/plugin-main.cpp index 78c9b25..023de7b 100644 --- a/plugins/decklink/plugin-main.cpp +++ b/plugins/decklink/plugin-main.cpp @@ -1,287 +1,18 @@ -#include "decklink.hpp" -#include "decklink-device.hpp" -#include "decklink-device-discovery.hpp" - #include +#include "decklink-devices.hpp" OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("decklink", "en-US") - -#define DEVICE_HASH "device_hash" -#define DEVICE_NAME "device_name" -#define MODE_ID "mode_id" -#define MODE_NAME "mode_name" -#define CHANNEL_FORMAT "channel_format" -#define PIXEL_FORMAT "pixel_format" -#define COLOR_SPACE "color_space" -#define COLOR_RANGE "color_range" -#define BUFFERING "buffering" - -#define TEXT_DEVICE obs_module_text("Device") -#define TEXT_MODE obs_module_text("Mode") -#define TEXT_PIXEL_FORMAT obs_module_text("PixelFormat") -#define TEXT_COLOR_SPACE obs_module_text("ColorSpace") -#define TEXT_COLOR_SPACE_DEFAULT obs_module_text("ColorSpace.Default") -#define TEXT_COLOR_RANGE obs_module_text("ColorRange") -#define TEXT_COLOR_RANGE_DEFAULT obs_module_text("ColorRange.Default") -#define TEXT_COLOR_RANGE_PARTIAL obs_module_text("ColorRange.Partial") -#define TEXT_COLOR_RANGE_FULL obs_module_text("ColorRange.Full") -#define TEXT_CHANNEL_FORMAT obs_module_text("ChannelFormat") -#define TEXT_CHANNEL_FORMAT_NONE obs_module_text("ChannelFormat.None") -#define TEXT_CHANNEL_FORMAT_2_0CH obs_module_text("ChannelFormat.2_0ch") -#define TEXT_CHANNEL_FORMAT_2_1CH obs_module_text("ChannelFormat.2_1ch") -#define TEXT_CHANNEL_FORMAT_4_0CH obs_module_text("ChannelFormat.4_0ch") -#define TEXT_CHANNEL_FORMAT_4_1CH obs_module_text("ChannelFormat.4_1ch") -#define TEXT_CHANNEL_FORMAT_5_1CH obs_module_text("ChannelFormat.5_1ch") -#define TEXT_CHANNEL_FORMAT_7_1CH obs_module_text("ChannelFormat.7_1ch") -#define TEXT_BUFFERING obs_module_text("Buffering") - -static DeckLinkDeviceDiscovery *deviceEnum = nullptr; - -static void decklink_enable_buffering(DeckLink *decklink, bool enabled) +MODULE_EXPORT const char *obs_module_description(void) { - obs_source_t *source = decklink->GetSource(); - obs_source_set_async_unbuffered(source, !enabled); - decklink->buffering = enabled; + return "Blackmagic DeckLink source"; } -static void *decklink_create(obs_data_t *settings, obs_source_t *source) -{ - DeckLink *decklink = new DeckLink(source, deviceEnum); +extern struct obs_source_info create_decklink_source_info(); +struct obs_source_info decklink_source_info; - obs_source_set_async_decoupled(source, true); - decklink_enable_buffering(decklink, - obs_data_get_bool(settings, BUFFERING)); - - obs_source_update(source, settings); - return decklink; -} - -static void decklink_destroy(void *data) -{ - DeckLink *decklink = (DeckLink *)data; - delete decklink; -} - -static void decklink_update(void *data, obs_data_t *settings) -{ - DeckLink *decklink = (DeckLink *)data; - const char *hash = obs_data_get_string(settings, DEVICE_HASH); - long long id = obs_data_get_int(settings, MODE_ID); - BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings, - PIXEL_FORMAT); - video_colorspace colorSpace = (video_colorspace)obs_data_get_int(settings, - COLOR_SPACE); - video_range_type colorRange = (video_range_type)obs_data_get_int(settings, - COLOR_RANGE); - int chFmtInt = (int)obs_data_get_int(settings, CHANNEL_FORMAT); - - if (chFmtInt == 7) { - chFmtInt = SPEAKERS_5POINT1; - } else if (chFmtInt < SPEAKERS_UNKNOWN || chFmtInt > SPEAKERS_7POINT1) { - chFmtInt = 2; - } - - speaker_layout channelFormat = (speaker_layout)chFmtInt; - - decklink_enable_buffering(decklink, - obs_data_get_bool(settings, BUFFERING)); - - ComPtr device; - device.Set(deviceEnum->FindByHash(hash)); - - decklink->SetPixelFormat(pixelFormat); - decklink->SetColorSpace(colorSpace); - decklink->SetColorRange(colorRange); - decklink->SetChannelFormat(channelFormat); - decklink->Activate(device, id); -} - -static void decklink_get_defaults(obs_data_t *settings) -{ - obs_data_set_default_bool(settings, BUFFERING, false); - obs_data_set_default_int(settings, PIXEL_FORMAT, bmdFormat8BitYUV); - obs_data_set_default_int(settings, COLOR_SPACE, VIDEO_CS_DEFAULT); - obs_data_set_default_int(settings, COLOR_RANGE, VIDEO_RANGE_DEFAULT); - obs_data_set_default_int(settings, CHANNEL_FORMAT, SPEAKERS_STEREO); -} - -static const char *decklink_get_name(void*) -{ - return obs_module_text("BlackmagicDevice"); -} - -static bool decklink_device_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) -{ - const char *name = obs_data_get_string(settings, DEVICE_NAME); - const char *hash = obs_data_get_string(settings, DEVICE_HASH); - const char *mode = obs_data_get_string(settings, MODE_NAME); - long long modeId = obs_data_get_int(settings, MODE_ID); - - size_t itemCount = obs_property_list_item_count(list); - bool itemFound = false; - - for (size_t i = 0; i < itemCount; i++) { - const char *curHash = obs_property_list_item_string(list, i); - if (strcmp(hash, curHash) == 0) { - itemFound = true; - break; - } - } - - if (!itemFound) { - obs_property_list_insert_string(list, 0, name, hash); - obs_property_list_item_disable(list, 0, true); - } - - obs_property_t *modeList = obs_properties_get(props, MODE_ID); - obs_property_t *channelList = obs_properties_get(props, CHANNEL_FORMAT); - - obs_property_list_clear(modeList); - - obs_property_list_clear(channelList); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_NONE, - SPEAKERS_UNKNOWN); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_0CH, - SPEAKERS_STEREO); - - ComPtr device; - device.Set(deviceEnum->FindByHash(hash)); - - if (!device) { - obs_property_list_add_int(modeList, mode, modeId); - obs_property_list_item_disable(modeList, 0, true); - } else { - const std::vector &modes = - device->GetModes(); - - for (DeckLinkDeviceMode *mode : modes) { - obs_property_list_add_int(modeList, - mode->GetName().c_str(), - mode->GetId()); - } - - if (device->GetMaxChannel() >= 8) { - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_2_1CH, - SPEAKERS_2POINT1); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_4_0CH, - SPEAKERS_4POINT0); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_4_1CH, - SPEAKERS_4POINT1); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_5_1CH, - SPEAKERS_5POINT1); - obs_property_list_add_int(channelList, TEXT_CHANNEL_FORMAT_7_1CH, - SPEAKERS_7POINT1); - } - } - - return true; -} - -static void fill_out_devices(obs_property_t *list) -{ - deviceEnum->Lock(); - - const std::vector &devices = deviceEnum->GetDevices(); - for (DeckLinkDevice *device : devices) { - obs_property_list_add_string(list, - device->GetDisplayName().c_str(), - device->GetHash().c_str()); - } - - deviceEnum->Unlock(); -} - -static bool color_format_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings); - -static bool mode_id_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) -{ - long long id = obs_data_get_int(settings, MODE_ID); - - list = obs_properties_get(props, PIXEL_FORMAT); - obs_property_set_visible(list, id != MODE_ID_AUTO); - - return color_format_changed(props, nullptr, settings); -} - -static bool color_format_changed(obs_properties_t *props, - obs_property_t *list, obs_data_t *settings) -{ - long long id = obs_data_get_int(settings, MODE_ID); - BMDPixelFormat pixelFormat = (BMDPixelFormat)obs_data_get_int(settings, - PIXEL_FORMAT); - - list = obs_properties_get(props, COLOR_SPACE); - obs_property_set_visible(list, - id != MODE_ID_AUTO && pixelFormat == bmdFormat8BitYUV); - - list = obs_properties_get(props, COLOR_RANGE); - obs_property_set_visible(list, - id == MODE_ID_AUTO || pixelFormat == bmdFormat8BitYUV); - - return true; -} - -static obs_properties_t *decklink_get_properties(void *data) -{ - obs_properties_t *props = obs_properties_create(); - - obs_property_t *list = obs_properties_add_list(props, DEVICE_HASH, - TEXT_DEVICE, OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); - obs_property_set_modified_callback(list, decklink_device_changed); - - fill_out_devices(list); - - list = obs_properties_add_list(props, MODE_ID, TEXT_MODE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_set_modified_callback(list, mode_id_changed); - - list = obs_properties_add_list(props, PIXEL_FORMAT, - TEXT_PIXEL_FORMAT, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); - obs_property_set_modified_callback(list, color_format_changed); - - obs_property_list_add_int(list, "8-bit YUV", bmdFormat8BitYUV); - obs_property_list_add_int(list, "8-bit BGRA", bmdFormat8BitBGRA); - - list = obs_properties_add_list(props, COLOR_SPACE, TEXT_COLOR_SPACE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, TEXT_COLOR_SPACE_DEFAULT, VIDEO_CS_DEFAULT); - obs_property_list_add_int(list, "BT.601", VIDEO_CS_601); - obs_property_list_add_int(list, "BT.709", VIDEO_CS_709); - - list = obs_properties_add_list(props, COLOR_RANGE, TEXT_COLOR_RANGE, - OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_DEFAULT, VIDEO_RANGE_DEFAULT); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_PARTIAL, VIDEO_RANGE_PARTIAL); - obs_property_list_add_int(list, TEXT_COLOR_RANGE_FULL, VIDEO_RANGE_FULL); - - list = obs_properties_add_list(props, CHANNEL_FORMAT, - TEXT_CHANNEL_FORMAT, OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_INT); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_NONE, - SPEAKERS_UNKNOWN); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_0CH, - SPEAKERS_STEREO); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_2_1CH, - SPEAKERS_2POINT1); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_0CH, - SPEAKERS_4POINT0); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_4_1CH, - SPEAKERS_4POINT1); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_5_1CH, - SPEAKERS_5POINT1); - obs_property_list_add_int(list, TEXT_CHANNEL_FORMAT_7_1CH, - SPEAKERS_7POINT1); - - obs_properties_add_bool(props, BUFFERING, TEXT_BUFFERING); - - UNUSED_PARAMETER(data); - return props; -} +extern struct obs_output_info create_decklink_output_info(); +struct obs_output_info decklink_output_info; bool obs_module_load(void) { @@ -289,19 +20,11 @@ bool obs_module_load(void) if (!deviceEnum->Init()) return true; - struct obs_source_info info = {}; - info.id = "decklink-input"; - info.type = OBS_SOURCE_TYPE_INPUT; - info.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO | - OBS_SOURCE_DO_NOT_DUPLICATE; - info.create = decklink_create; - info.destroy = decklink_destroy; - info.get_defaults = decklink_get_defaults; - info.get_name = decklink_get_name; - info.get_properties = decklink_get_properties; - info.update = decklink_update; + decklink_source_info = create_decklink_source_info(); + obs_register_source(&decklink_source_info); - obs_register_source(&info); + decklink_output_info = create_decklink_output_info(); + obs_register_output(&decklink_output_info); return true; } diff --git a/plugins/decklink/util.cpp b/plugins/decklink/util.cpp new file mode 100644 index 0000000..c3055e8 --- /dev/null +++ b/plugins/decklink/util.cpp @@ -0,0 +1,43 @@ +#include "util.hpp" + +const char *bmd_video_connection_to_name(BMDVideoConnection connection) +{ + switch (connection) { + case bmdVideoConnectionSDI: + return "SDI"; + case bmdVideoConnectionHDMI: + return "HDMI"; + case bmdVideoConnectionOpticalSDI: + return "Optical SDI"; + case bmdVideoConnectionComponent: + return "Component"; + case bmdVideoConnectionComposite: + return "Composite"; + case bmdVideoConnectionSVideo: + return "S-Video"; + default: + return "Unknown"; + } +} + +const char *bmd_audio_connection_to_name(BMDAudioConnection connection) +{ + switch (connection) { + case bmdAudioConnectionEmbedded: + return "Embedded"; + case bmdAudioConnectionAESEBU: + return "AES/EBU"; + case bmdAudioConnectionAnalog: + return "Analog"; + case bmdAudioConnectionAnalogXLR: + return "Analog XLR"; + case bmdAudioConnectionAnalogRCA: + return "Analog RCA"; + case bmdAudioConnectionMicrophone: + return "Microphone"; + case bmdAudioConnectionHeadphones: + return "Headphones"; + default: + return "Unknown"; + } +} \ No newline at end of file diff --git a/plugins/decklink/util.hpp b/plugins/decklink/util.hpp new file mode 100644 index 0000000..f264a0b --- /dev/null +++ b/plugins/decklink/util.hpp @@ -0,0 +1,7 @@ +#pragma once + +#include "decklink-device.hpp" + +const char *bmd_video_connection_to_name(BMDVideoConnection connection); + +const char *bmd_audio_connection_to_name(BMDAudioConnection connection); \ No newline at end of file diff --git a/plugins/decklink/win/CMakeLists.txt b/plugins/decklink/win/CMakeLists.txt index af94645..005dbb8 100644 --- a/plugins/decklink/win/CMakeLists.txt +++ b/plugins/decklink/win/CMakeLists.txt @@ -16,37 +16,52 @@ set(win-decklink-sdk_HEADERS ) set(win-decklink_HEADERS + ../decklink-devices.hpp + ../DecklinkOutput.hpp + ../const.h ../platform.hpp - ../decklink.hpp + ../DecklinkInput.hpp + ../DecklinkBase.h ../decklink-device-instance.hpp ../decklink-device-discovery.hpp ../decklink-device.hpp ../decklink-device-mode.hpp ../audio-repack.h ../audio-repack.hpp + ../util.hpp ) set(win-decklink_SOURCES ../plugin-main.cpp - ../decklink.cpp + ../decklink-devices.cpp + ../DecklinkOutput.cpp + ../decklink-source.cpp + ../decklink-output.cpp + ../DecklinkInput.cpp + ../DecklinkBase.cpp ../decklink-device-instance.cpp ../decklink-device-discovery.cpp ../decklink-device.cpp ../decklink-device-mode.cpp ../audio-repack.c - platform.cpp) + platform.cpp + ../util.cpp + ) add_idl_files(win-decklink-sdk_GENERATED_FILES - ${win-decklink-sdk_IDLS}) + ${win-decklink-sdk_IDLS} + ) include_directories( - ${CMAKE_CURRENT_BINARY_DIR}) + ${CMAKE_CURRENT_BINARY_DIR} +) add_library(win-decklink MODULE ${win-decklink_SOURCES} ${win-decklink_HEADERS} ${win-decklink-sdk_HEADERS} - ${win-decklink-sdk_GENERATED_FILES}) + ${win-decklink-sdk_GENERATED_FILES} + ) target_link_libraries(win-decklink libobs) diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl index 786d68d..07ee9fe 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -95,9 +95,11 @@ typedef [v1_enum] enum _BMDPacketType { bmdFrameFlagDefault = 0, bmdFrameFlagFlipVertical = 1 << 0, bmdFrameContainsHDRMetadata = 1 << 1, + bmdFrameContainsCintelMetadata = 1 << 2, /* Flags that are applicable only to instances of IDeckLinkVideoInputFrame */ + bmdFrameCapturedAsPsF = 1 << 30, bmdFrameHasNoInputSource = 1 << 31 }; @@ -136,10 +138,10 @@ typedef [v1_enum] enum _BMDPacketType { /* Enum BMDOutputFrameCompletionResult - Frame Completion Callback */ typedef [v1_enum] enum _BMDOutputFrameCompletionResult { - bmdOutputFrameCompleted, - bmdOutputFrameDisplayedLate, - bmdOutputFrameDropped, - bmdOutputFrameFlushed + bmdOutputFrameCompleted, + bmdOutputFrameDisplayedLate, + bmdOutputFrameDropped, + bmdOutputFrameFlushed } BMDOutputFrameCompletionResult; /* Enum BMDReferenceStatus - GenLock input status */ @@ -171,19 +173,27 @@ typedef [v1_enum] enum _BMDAudioSampleType { /* Enum BMDAudioOutputStreamType - Audio output stream type */ typedef [v1_enum] enum _BMDAudioOutputStreamType { - bmdAudioOutputStreamContinuous, - bmdAudioOutputStreamContinuousDontResample, - bmdAudioOutputStreamTimestamped + bmdAudioOutputStreamContinuous, + bmdAudioOutputStreamContinuousDontResample, + bmdAudioOutputStreamTimestamped } BMDAudioOutputStreamType; /* Enum BMDDisplayModeSupport - Output mode supported flags */ typedef [v1_enum] enum _BMDDisplayModeSupport { bmdDisplayModeNotSupported = 0, - bmdDisplayModeSupported, - bmdDisplayModeSupportedWithConversion + bmdDisplayModeSupported, + bmdDisplayModeSupportedWithConversion } BMDDisplayModeSupport; +/* Enum BMDAncillaryPacketFormat - Ancillary packet format */ + +typedef [v1_enum] enum _BMDAncillaryPacketFormat { + bmdAncillaryPacketFormatUInt8 = /* 'ui08' */ 0x75693038, + bmdAncillaryPacketFormatUInt16 = /* 'ui16' */ 0x75693136, + bmdAncillaryPacketFormatYCbCr10 = /* 'v210' */ 0x76323130 +} BMDAncillaryPacketFormat; + /* Enum BMDTimecodeFormat - Timecode formats for frame metadata */ typedef [v1_enum] enum _BMDTimecodeFormat { @@ -292,10 +302,64 @@ typedef [v1_enum] enum _BMDDeviceInterface { bmdDeviceInterfaceThunderbolt = /* 'thun' */ 0x7468756E } BMDDeviceInterface; +/* Enum BMDColorspace - Colorspace */ + +typedef [v1_enum] enum _BMDColorspace { + bmdColorspaceRec601 = /* 'r601' */ 0x72363031, + bmdColorspaceRec709 = /* 'r709' */ 0x72373039, + bmdColorspaceRec2020 = /* '2020' */ 0x32303230 +} BMDColorspace; + +/* Enum BMDDynamicRange - SDR or HDR */ + +typedef [v1_enum] enum _BMDDynamicRange { + bmdDynamicRangeSDR = 0, + bmdDynamicRangeHDRStaticPQ = 1 << 29, // SMPTE ST 2084 + bmdDynamicRangeHDRStaticHLG = 1 << 30 // ITU-R BT.2100-0 +} BMDDynamicRange; + +/* Enum BMDDeckLinkHDMIInputEDIDID - DeckLink HDMI Input EDID ID */ + +typedef [v1_enum] enum _BMDDeckLinkHDMIInputEDIDID { + bmdDeckLinkHDMIInputEDIDDynamicRange = /* 'HIDy' */ 0x48494479 // Parameter is of type BMDDynamicRange. Default is (bmdDynamicRangeSDR|bmdDynamicRangeHDRStaticPQ) +} BMDDeckLinkHDMIInputEDIDID; + /* Enum BMDDeckLinkFrameMetadataID - DeckLink Frame Metadata ID */ typedef [v1_enum] enum _BMDDeckLinkFrameMetadataID { + bmdDeckLinkFrameMetadataColorspace = /* 'cspc' */ 0x63737063, // Colorspace of video frame (see BMDColorspace) bmdDeckLinkFrameMetadataHDRElectroOpticalTransferFunc = /* 'eotf' */ 0x656F7466, // EOTF in range 0-7 as per CEA 861.3 + bmdDeckLinkFrameMetadataCintelFilmType = /* 'cfty' */ 0x63667479, // Current film type + bmdDeckLinkFrameMetadataCintelFilmGauge = /* 'cfga' */ 0x63666761, // Current film gauge + bmdDeckLinkFrameMetadataCintelOffsetDetectedHorizontal = /* 'odfh' */ 0x6F646668, // Horizontal offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelOffsetDetectedVertical = /* 'odfv' */ 0x6F646676, // Vertical offset (pixels) detected in image + bmdDeckLinkFrameMetadataCintelKeykodeLow = /* 'ckkl' */ 0x636B6B6C, // Raw keykode value - low 64 bits + bmdDeckLinkFrameMetadataCintelKeykodeHigh = /* 'ckkh' */ 0x636B6B68, // Raw keykode value - high 64 bits + bmdDeckLinkFrameMetadataCintelTile1Size = /* 'ct1s' */ 0x63743173, // Size in bytes of compressed raw tile 1 + bmdDeckLinkFrameMetadataCintelTile2Size = /* 'ct2s' */ 0x63743273, // Size in bytes of compressed raw tile 2 + bmdDeckLinkFrameMetadataCintelTile3Size = /* 'ct3s' */ 0x63743373, // Size in bytes of compressed raw tile 3 + bmdDeckLinkFrameMetadataCintelTile4Size = /* 'ct4s' */ 0x63743473, // Size in bytes of compressed raw tile 4 + bmdDeckLinkFrameMetadataCintelImageWidth = /* 'IWPx' */ 0x49575078, // Width in pixels of image + bmdDeckLinkFrameMetadataCintelImageHeight = /* 'IHPx' */ 0x49485078, // Height in pixels of image + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInRed = /* 'mrir' */ 0x6D726972, // Red in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInRed = /* 'mgir' */ 0x6D676972, // Green in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInRed = /* 'mbir' */ 0x6D626972, // Blue in red linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInGreen = /* 'mrig' */ 0x6D726967, // Red in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInGreen = /* 'mgig' */ 0x6D676967, // Green in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInGreen = /* 'mbig' */ 0x6D626967, // Blue in green linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingRedInBlue = /* 'mrib' */ 0x6D726962, // Red in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingGreenInBlue = /* 'mgib' */ 0x6D676962, // Green in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLinearMaskingBlueInBlue = /* 'mbib' */ 0x6D626962, // Blue in blue linear masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInRed = /* 'mlrr' */ 0x6D6C7272, // Red in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInRed = /* 'mlgr' */ 0x6D6C6772, // Green in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInRed = /* 'mlbr' */ 0x6D6C6272, // Blue in red log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInGreen = /* 'mlrg' */ 0x6D6C7267, // Red in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInGreen = /* 'mlgg' */ 0x6D6C6767, // Green in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInGreen = /* 'mlbg' */ 0x6D6C6267, // Blue in green log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingRedInBlue = /* 'mlrb' */ 0x6D6C7262, // Red in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingGreenInBlue = /* 'mlgb' */ 0x6D6C6762, // Green in blue log masking parameter + bmdDeckLinkFrameMetadataCintelLogMaskingBlueInBlue = /* 'mlbb' */ 0x6D6C6262, // Blue in blue log masking parameter + bmdDeckLinkFrameMetadataCintelFilmFrameRate = /* 'cffr' */ 0x63666672, // Film frame rate bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedX = /* 'hdrx' */ 0x68647278, // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesRedY = /* 'hdry' */ 0x68647279, // Red display primaries in range 0.0 - 1.0 bmdDeckLinkFrameMetadataHDRDisplayPrimariesGreenX = /* 'hdgx' */ 0x68646778, // Green display primaries in range 0.0 - 1.0 @@ -307,7 +371,15 @@ typedef [v1_enum] enum _BMDDeckLinkFrameMetadataID { bmdDeckLinkFrameMetadataHDRMaxDisplayMasteringLuminance = /* 'hdml' */ 0x68646D6C, // Max display mastering luminance in range 1 cd/m2 - 65535 cd/m2 bmdDeckLinkFrameMetadataHDRMinDisplayMasteringLuminance = /* 'hmil' */ 0x686D696C, // Min display mastering luminance in range 0.0001 cd/m2 - 6.5535 cd/m2 bmdDeckLinkFrameMetadataHDRMaximumContentLightLevel = /* 'mcll' */ 0x6D636C6C, // Maximum Content Light Level in range 1 cd/m2 - 65535 cd/m2 - bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataHDRMaximumFrameAverageLightLevel = /* 'fall' */ 0x66616C6C, // Maximum Frame Average Light Level in range 1 cd/m2 - 65535 cd/m2 + bmdDeckLinkFrameMetadataCintelOffsetToApplyHorizontal = /* 'otah' */ 0x6F746168, // Horizontal offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelOffsetToApplyVertical = /* 'otav' */ 0x6F746176, // Vertical offset (pixels) to be applied to image + bmdDeckLinkFrameMetadataCintelGainRed = /* 'LfRd' */ 0x4C665264, // Red gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainGreen = /* 'LfGr' */ 0x4C664772, // Green gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelGainBlue = /* 'LfBl' */ 0x4C66426C, // Blue gain parameter to apply after log + bmdDeckLinkFrameMetadataCintelLiftRed = /* 'GnRd' */ 0x476E5264, // Red lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftGreen = /* 'GnGr' */ 0x476E4772, // Green lift parameter to apply after log and gain + bmdDeckLinkFrameMetadataCintelLiftBlue = /* 'GnBl' */ 0x476E426C // Blue lift parameter to apply after log and gain } BMDDeckLinkFrameMetadataID; /* Enum BMDDuplexMode - Duplex for configurable ports */ @@ -343,22 +415,24 @@ typedef [v1_enum] enum _BMDDeckLinkAttributeID { BMDDeckLinkHasLTCTimecodeInput = /* 'hltc' */ 0x686C7463, BMDDeckLinkSupportsDuplexModeConfiguration = /* 'dupx' */ 0x64757078, BMDDeckLinkSupportsHDRMetadata = /* 'hdrm' */ 0x6864726D, + BMDDeckLinkSupportsColorspaceMetadata = /* 'cmet' */ 0x636D6574, /* Integers */ BMDDeckLinkMaximumAudioChannels = /* 'mach' */ 0x6D616368, - BMDDeckLinkMaximumAnalogAudioChannels = /* 'aach' */ 0x61616368, + BMDDeckLinkMaximumAnalogAudioInputChannels = /* 'iach' */ 0x69616368, + BMDDeckLinkMaximumAnalogAudioOutputChannels = /* 'aach' */ 0x61616368, BMDDeckLinkNumberOfSubDevices = /* 'nsbd' */ 0x6E736264, BMDDeckLinkSubDeviceIndex = /* 'subi' */ 0x73756269, BMDDeckLinkPersistentID = /* 'peid' */ 0x70656964, BMDDeckLinkDeviceGroupID = /* 'dgid' */ 0x64676964, BMDDeckLinkTopologicalID = /* 'toid' */ 0x746F6964, - BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, - BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, - BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, - BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, + BMDDeckLinkVideoOutputConnections = /* 'vocn' */ 0x766F636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkVideoInputConnections = /* 'vicn' */ 0x7669636E, // Returns a BMDVideoConnection bit field + BMDDeckLinkAudioOutputConnections = /* 'aocn' */ 0x616F636E, // Returns a BMDAudioConnection bit field + BMDDeckLinkAudioInputConnections = /* 'aicn' */ 0x6169636E, // Returns a BMDAudioConnection bit field BMDDeckLinkVideoIOSupport = /* 'vios' */ 0x76696F73, // Returns a BMDVideoIOSupport bit field - BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, + BMDDeckLinkDeckControlConnections = /* 'dccn' */ 0x6463636E, // Returns a BMDDeckControlConnection bit field BMDDeckLinkDeviceInterface = /* 'dbus' */ 0x64627573, // Returns a BMDDeviceInterface BMDDeckLinkAudioInputRCAChannelCount = /* 'airc' */ 0x61697263, BMDDeckLinkAudioInputXLRChannelCount = /* 'aixc' */ 0x61697863, @@ -410,11 +484,14 @@ typedef [v1_enum] enum _BMDDeckLinkStatusID { bmdDeckLinkStatusReferenceSignalFlags = /* 'reff' */ 0x72656666, bmdDeckLinkStatusDuplexMode = /* 'dupx' */ 0x64757078, bmdDeckLinkStatusBusy = /* 'busy' */ 0x62757379, + bmdDeckLinkStatusInterchangeablePanelType = /* 'icpt' */ 0x69637074, + bmdDeckLinkStatusDeviceTemperature = /* 'dtmp' */ 0x64746D70, /* Flags */ bmdDeckLinkStatusVideoInputSignalLocked = /* 'visl' */ 0x7669736C, - bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C + bmdDeckLinkStatusReferenceSignalLocked = /* 'refl' */ 0x7265666C, + bmdDeckLinkStatusReceivedEDID = /* 'edid' */ 0x65646964 } BMDDeckLinkStatusID; /* Enum BMDDeckLinkVideoStatusFlags - */ @@ -433,6 +510,13 @@ typedef [v1_enum] enum _BMDDuplexStatus { bmdDuplexStatusInactive = /* 'inac' */ 0x696E6163 } BMDDuplexStatus; +/* Enum BMDPanelType - The type of interchangeable panel */ + +typedef [v1_enum] enum _BMDPanelType { + bmdPanelNotDetected = /* 'npnl' */ 0x6E706E6C, + bmdPanelTeranexMiniSmartPanel = /* 'tmsm' */ 0x746D736D +} BMDPanelType; + /* Enum BMDDeviceBusyState - Current device busy state */ [v1_enum] enum _BMDDeviceBusyState { @@ -476,12 +560,16 @@ interface IDeckLinkIterator; interface IDeckLinkAPIInformation; interface IDeckLinkOutput; interface IDeckLinkInput; +interface IDeckLinkHDMIInputEDID; interface IDeckLinkEncoderInput; interface IDeckLinkVideoFrame; interface IDeckLinkMutableVideoFrame; interface IDeckLinkVideoFrame3DExtensions; interface IDeckLinkVideoFrameMetadataExtensions; interface IDeckLinkVideoInputFrame; +interface IDeckLinkAncillaryPacket; +interface IDeckLinkAncillaryPacketIterator; +interface IDeckLinkVideoFrameAncillaryPackets; interface IDeckLinkVideoFrameAncillary; interface IDeckLinkEncoderPacket; interface IDeckLinkEncoderVideoPacket; @@ -542,7 +630,7 @@ interface IDeckLinkDiscovery; [ object, uuid(B36EB6E7-9D29-4AA8-92EF-843B87A289E8), - local, + local, helpstring("Memory allocator for video frames.") ] interface IDeckLinkMemoryAllocator : IUnknown { @@ -558,7 +646,7 @@ interface IDeckLinkDiscovery; [ object, uuid(403C681B-7F46-4A12-B993-2BB127084EE6), - local, + local, helpstring("Optional callback to allow audio samples to be pulled as required.") ] interface IDeckLinkAudioOutputCallback : IUnknown { @@ -595,7 +683,7 @@ interface IDeckLinkDiscovery; [ object, uuid(CC5C8A6E-3F2F-4B3A-87EA-FD78AF300564), - local, + local, helpstring("Created by QueryInterface from IDeckLink.") ] interface IDeckLinkOutput : IUnknown { @@ -611,7 +699,7 @@ interface IDeckLinkDiscovery; HRESULT SetVideoOutputFrameMemoryAllocator([in] IDeckLinkMemoryAllocator *theAllocator); HRESULT CreateVideoFrame([in] int width, [in] int height, [in] int rowBytes, [in] BMDPixelFormat pixelFormat, [in] BMDFrameFlags flags, [out] IDeckLinkMutableVideoFrame **outFrame); - HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); + HRESULT CreateAncillaryData([in] BMDPixelFormat pixelFormat, [out] IDeckLinkVideoFrameAncillary **outBuffer); // Use of IDeckLinkVideoFrameAncillaryPackets is preferred HRESULT DisplayVideoFrameSync([in] IDeckLinkVideoFrame *theFrame); HRESULT ScheduleVideoFrame([in] IDeckLinkVideoFrame *theFrame, [in] BMDTimeValue displayTime, [in] BMDTimeValue displayDuration, [in] BMDTimeScale timeScale); @@ -687,6 +775,19 @@ interface IDeckLinkDiscovery; HRESULT GetHardwareReferenceClock([in] BMDTimeScale desiredTimeScale, [out] BMDTimeValue *hardwareTime, [out] BMDTimeValue *timeInFrame, [out] BMDTimeValue *ticksPerFrame); }; +/* Interface IDeckLinkHDMIInputEDID - Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default */ + +[ + object, + uuid(ABBBACBC-45BC-4665-9D92-ACE6E5A97902), + helpstring("Created by QueryInterface from IDeckLink. Releasing all references will restore EDID to default") +] interface IDeckLinkHDMIInputEDID : IUnknown +{ + HRESULT SetInt([in] BMDDeckLinkHDMIInputEDIDID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkHDMIInputEDIDID cfgID, [out] LONGLONG *value); + HRESULT WriteToEDID(void); +}; + /* Interface IDeckLinkEncoderInput - Created by QueryInterface from IDeckLink. */ [ @@ -729,7 +830,7 @@ interface IDeckLinkDiscovery; [ object, uuid(3F716FE0-F023-4111-BE5D-EF4414C05B17), - local, + local, helpstring("Interface to encapsulate a video frame; can be caller-implemented.") ] interface IDeckLinkVideoFrame : IUnknown { @@ -741,7 +842,7 @@ interface IDeckLinkDiscovery; HRESULT GetBytes([out] void **buffer); HRESULT GetTimecode([in] BMDTimecodeFormat format, [out] IDeckLinkTimecode **timecode); - HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary); + HRESULT GetAncillaryData([out] IDeckLinkVideoFrameAncillary **ancillary); // Use of IDeckLinkVideoFrameAncillaryPackets is preferred }; /* Interface IDeckLinkMutableVideoFrame - Created by IDeckLinkOutput::CreateVideoFrame. */ @@ -749,7 +850,7 @@ interface IDeckLinkDiscovery; [ object, uuid(69E2639F-40DA-4E19-B6F2-20ACE815C390), - local, + local, helpstring("Created by IDeckLinkOutput::CreateVideoFrame.") ] interface IDeckLinkMutableVideoFrame : IDeckLinkVideoFrame { @@ -766,7 +867,7 @@ interface IDeckLinkDiscovery; [ object, uuid(DA0F7E4A-EDC7-48A8-9CDD-2DB51C729CD7), - local, + local, helpstring("Optional interface implemented on IDeckLinkVideoFrame to support 3D frames") ] interface IDeckLinkVideoFrame3DExtensions : IUnknown { @@ -779,7 +880,7 @@ interface IDeckLinkDiscovery; [ object, uuid(D5973DC9-6432-46D0-8F0B-2496F8A1238F), - local, + local, helpstring("Optional interface implemented on IDeckLinkVideoFrame to support frame metadata such as HDMI HDR information") ] interface IDeckLinkVideoFrameMetadataExtensions : IUnknown { @@ -794,7 +895,7 @@ interface IDeckLinkDiscovery; [ object, uuid(05CFE374-537C-4094-9A57-680525118F44), - local, + local, helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") ] interface IDeckLinkVideoInputFrame : IDeckLinkVideoFrame { @@ -802,17 +903,61 @@ interface IDeckLinkDiscovery; HRESULT GetHardwareReferenceTimestamp([in] BMDTimeScale timeScale, [out] BMDTimeValue *frameTime, [out] BMDTimeValue *frameDuration); }; -/* Interface IDeckLinkVideoFrameAncillary - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ +/* Interface IDeckLinkAncillaryPacket - On output, user needs to implement this interface */ + +[ + object, + uuid(CC5BBF7E-029C-4D3B-9158-6000EF5E3670), + helpstring("On output, user needs to implement this interface") +] interface IDeckLinkAncillaryPacket : IUnknown +{ + + HRESULT GetBytes([in] BMDAncillaryPacketFormat format /* For output, only one format need be offered */, [out] const void **data /* Optional */, [out] unsigned int *size /* Optional */); + unsigned char GetDID(void); + unsigned char GetSDID(void); + unsigned int GetLineNumber(void); // On output, zero is auto + unsigned char GetDataStreamIndex(void); // Usually zero. Can only be 1 if non-SD and the first data stream is completely full +}; + +/* Interface IDeckLinkAncillaryPacketIterator - Enumerates ancillary packets */ + +[ + object, + uuid(3FC8994B-88FB-4C17-968F-9AAB69D964A7), + helpstring("Enumerates ancillary packets") +] interface IDeckLinkAncillaryPacketIterator : IUnknown +{ + HRESULT Next([out] IDeckLinkAncillaryPacket **packet); +}; + +/* Interface IDeckLinkVideoFrameAncillaryPackets - Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ + +[ + object, + uuid(6C186C0F-459E-41D8-AEE2-4812D81AEE68), + local, + helpstring("Obtained through QueryInterface() on an IDeckLinkVideoFrame object.") +] interface IDeckLinkVideoFrameAncillaryPackets : IUnknown +{ + + HRESULT GetPacketIterator([out] IDeckLinkAncillaryPacketIterator **iterator); + HRESULT GetFirstPacketByID([in] unsigned char DID, [in] unsigned char SDID, [out] IDeckLinkAncillaryPacket **packet); + HRESULT AttachPacket([in] IDeckLinkAncillaryPacket *packet); // Implement IDeckLinkAncillaryPacket to output your own + HRESULT DetachPacket([in] IDeckLinkAncillaryPacket *packet); + HRESULT DetachAllPackets(void); +}; + +/* Interface IDeckLinkVideoFrameAncillary - Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface() on an IDeckLinkVideoFrame object. */ [ object, uuid(732E723C-D1A4-4E29-9E8E-4A88797A0004), - local, - helpstring("Obtained through QueryInterface() on an IDeckLinkVideoFrame object.") + local, + helpstring("Use of IDeckLinkVideoFrameAncillaryPackets is preferred. Obtained through QueryInterface() on an IDeckLinkVideoFrame object.") ] interface IDeckLinkVideoFrameAncillary : IUnknown { - HRESULT GetBufferForVerticalBlankingLine([in] unsigned int lineNumber, [out] void **buffer); + HRESULT GetBufferForVerticalBlankingLine([in] unsigned int lineNumber, [out] void **buffer); // Pixels/rowbytes is same as display mode, except for above HD where it's 1920 pixels for UHD modes and 2048 pixels for DCI modes BMDPixelFormat GetPixelFormat(void); BMDDisplayMode GetDisplayMode(void); }; @@ -822,7 +967,7 @@ interface IDeckLinkDiscovery; [ object, uuid(B693F36C-316E-4AF1-B6C2-F389A4BCA620), - local, + local, helpstring("Interface to encapsulate an encoded packet.") ] interface IDeckLinkEncoderPacket : IUnknown { @@ -837,7 +982,7 @@ interface IDeckLinkDiscovery; [ object, uuid(4E7FD944-E8C7-4EAC-B8C0-7B77F80F5AE0), - local, + local, helpstring("Provided by the IDeckLinkEncoderInput video packet arrival callback.") ] interface IDeckLinkEncoderVideoPacket : IDeckLinkEncoderPacket { @@ -852,7 +997,7 @@ interface IDeckLinkDiscovery; [ object, uuid(49E8EDC8-693B-4E14-8EF6-12C658F5A07A), - local, + local, helpstring("Provided by the IDeckLinkEncoderInput audio packet arrival callback.") ] interface IDeckLinkEncoderAudioPacket : IDeckLinkEncoderPacket { @@ -864,7 +1009,7 @@ interface IDeckLinkDiscovery; [ object, uuid(639C8E0B-68D5-4BDE-A6D4-95F3AEAFF2E7), - local, + local, helpstring("Obtained through QueryInterface() on an IDeckLinkEncoderVideoPacket object") ] interface IDeckLinkH265NALPacket : IDeckLinkEncoderVideoPacket { @@ -878,7 +1023,7 @@ interface IDeckLinkDiscovery; [ object, uuid(E43D5870-2894-11DE-8C30-0800200C9A66), - local, + local, helpstring("Provided by the IDeckLinkInput callback.") ] interface IDeckLinkAudioInputPacket : IUnknown { @@ -892,7 +1037,7 @@ interface IDeckLinkDiscovery; [ object, uuid(B1D3F49A-85FE-4C5D-95C8-0B5D5DCCD438), - local, + local, helpstring("Screen preview callback") ] interface IDeckLinkScreenPreviewCallback : IUnknown { @@ -904,7 +1049,7 @@ interface IDeckLinkDiscovery; [ object, uuid(504E2209-CAC7-4C1A-9FB4-C5BB6274D22F), - local, + local, helpstring("Created with CoCreateInstance().") ] interface IDeckLinkGLScreenPreviewHelper : IUnknown { @@ -922,7 +1067,7 @@ interface IDeckLinkDiscovery; [ object, uuid(2094B522-D1A1-40C0-9AC7-1C012218EF02), - local, + local, helpstring("Created with CoCreateInstance().") ] interface IDeckLinkDX9ScreenPreviewHelper : IUnknown { @@ -937,7 +1082,7 @@ interface IDeckLinkDiscovery; [ object, uuid(b002a1ec-070d-4288-8289-bd5d36e5ff0d), - local, + local, helpstring("DeckLink Notification Callback Interface") ] interface IDeckLinkNotificationCallback : IUnknown { @@ -949,7 +1094,7 @@ interface IDeckLinkDiscovery; [ object, uuid(0a1fb207-e215-441b-9b19-6fa1575946c5), - local, + local, helpstring("DeckLink Notification interface") ] interface IDeckLinkNotification : IUnknown { @@ -962,7 +1107,7 @@ interface IDeckLinkDiscovery; [ object, uuid(ABC11843-D966-44CB-96E2-A1CB5D3135C4), - local, + local, helpstring("DeckLink Attribute interface") ] interface IDeckLinkAttributes : IUnknown { @@ -977,7 +1122,7 @@ interface IDeckLinkDiscovery; [ object, uuid(5F558200-4028-49BC-BEAC-DB3FA4A96E46), - local, + local, helpstring("DeckLink Status interface") ] interface IDeckLinkStatus : IUnknown { @@ -993,7 +1138,7 @@ interface IDeckLinkDiscovery; [ object, uuid(89AFCAF5-65F8-421E-98F7-96FE5F5BFBA3), - local, + local, helpstring("DeckLink Keyer interface") ] interface IDeckLinkKeyer : IUnknown { @@ -1009,7 +1154,7 @@ interface IDeckLinkDiscovery; [ object, uuid(3BBCB8A2-DA2C-42D9-B5D8-88083644E99A), - local, + local, helpstring("Created with CoCreateInstance().") ] interface IDeckLinkVideoConversion : IUnknown { @@ -1045,7 +1190,7 @@ interface IDeckLinkDiscovery; importlib("stdole2.tlb"); [ - uuid(1F2E109A-8F4F-49E4-9203-135595CB6FA5), + uuid(87D2693F-8D4A-45C7-B43F-10ACBA25E68F), helpstring("CDeckLinkIterator Class") ] coclass CDeckLinkIterator { @@ -1085,15 +1230,26 @@ importlib("stdole2.tlb"); }; [ - uuid(1073A05C-D885-47E9-B3C6-129B3F9F648B), + uuid(652615D4-26CD-4514-B161-2FD5072ED008), helpstring("CDeckLinkDiscovery Class") ] coclass CDeckLinkDiscovery { [default] interface IDeckLinkDiscovery; }; +[ + uuid(F891AD29-D0C2-46E9-A926-4E2D0DD8CFAD), + helpstring("CDeckLinkVideoFrameAncillaryPackets Class") +] coclass CDeckLinkVideoFrameAncillaryPackets +{ + [default] interface IDeckLinkVideoFrameAncillaryPackets; +}; + // import deprecated interfaces +#include "DeckLinkAPI_v10_9.idl" +#include "DeckLinkAPIStreaming_v10_8.idl" +#include "DeckLinkAPI_v10_8.idl" #include "DeckLinkAPI_v10_6.idl" #include "DeckLinkAPI_v10_5.idl" #include "DeckLinkAPI_v10_4.idl" diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl index 4e271e4..42a5234 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIConfiguration.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -50,10 +50,6 @@ typedef [v1_enum] enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigSwapSerialRxTx = /* 'ssrt' */ 0x73737274, - /* Video Input/Output Flags */ - - bmdDeckLinkConfigUse1080pNotPsF = /* 'fpro' */ 0x6670726F, - /* Video Input/Output Integers */ bmdDeckLinkConfigHDMI3DPackingFormat = /* '3dpf' */ 0x33647066, @@ -74,6 +70,12 @@ typedef [v1_enum] enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigLowLatencyVideoOutput = /* 'llvo' */ 0x6C6C766F, bmdDeckLinkConfigDownConversionOnAllAnalogOutput = /* 'caao' */ 0x6361616F, bmdDeckLinkConfigSMPTELevelAOutput = /* 'smta' */ 0x736D7461, + bmdDeckLinkConfigRec2020Output = /* 'rec2' */ 0x72656332, // Ensure output is Rec.2020 colorspace + bmdDeckLinkConfigQuadLinkSDIVideoOutputSquareDivisionSplit = /* 'SDQS' */ 0x53445153, + + /* Video Output Flags */ + + bmdDeckLinkConfigOutput1080pAsPsF = /* 'pfpr' */ 0x70667072, /* Video Output Integers */ @@ -102,6 +104,10 @@ typedef [v1_enum] enum _BMDDeckLinkConfigurationID { bmdDeckLinkConfigUseDedicatedLTCInput = /* 'dltc' */ 0x646C7463, // Use timecode from LTC input instead of SDI stream bmdDeckLinkConfigSDIInput3DPayloadOverride = /* '3dds' */ 0x33646473, + /* Video Input Flags */ + + bmdDeckLinkConfigCapture1080pAsPsF = /* 'cfpr' */ 0x63667072, + /* Video Input Integers */ bmdDeckLinkConfigVideoInputConnection = /* 'vicn' */ 0x7669636E, @@ -203,8 +209,8 @@ interface IDeckLinkEncoderConfiguration; [ object, - uuid(CB71734A-FE37-4E8D-8E13-802133A1C3F2), - local, + uuid(EF90380B-4AE5-4346-9077-E288E149F129), + local, helpstring("DeckLink Configuration interface") ] interface IDeckLinkConfiguration : IUnknown { @@ -224,7 +230,7 @@ interface IDeckLinkEncoderConfiguration; [ object, uuid(138050E5-C60A-4552-BF3F-0F358049327E), - local, + local, helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput") ] interface IDeckLinkEncoderConfiguration : IUnknown { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl index cba3f2e..ef85d82 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDeckControl.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl index 8b9db8e..66f65bc 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIDiscovery.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl index e4f4c35..4e9eb26 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIModes.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -63,12 +63,12 @@ typedef [v1_enum] enum _BMDDisplayMode { bmdModeHD1080p25 = /* 'Hp25' */ 0x48703235, bmdModeHD1080p2997 = /* 'Hp29' */ 0x48703239, bmdModeHD1080p30 = /* 'Hp30' */ 0x48703330, - bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, - bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, - bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. bmdModeHD1080p50 = /* 'Hp50' */ 0x48703530, bmdModeHD1080p5994 = /* 'Hp59' */ 0x48703539, bmdModeHD1080p6000 = /* 'Hp60' */ 0x48703630, // N.B. This _really_ is 60.00 Hz. + bmdModeHD1080i50 = /* 'Hi50' */ 0x48693530, + bmdModeHD1080i5994 = /* 'Hi59' */ 0x48693539, + bmdModeHD1080i6000 = /* 'Hi60' */ 0x48693630, // N.B. This _really_ is 60.00 Hz. /* HD 720 Modes */ @@ -76,19 +76,24 @@ typedef [v1_enum] enum _BMDDisplayMode { bmdModeHD720p5994 = /* 'hp59' */ 0x68703539, bmdModeHD720p60 = /* 'hp60' */ 0x68703630, - /* 2k Modes */ + /* 2K Modes */ bmdMode2k2398 = /* '2k23' */ 0x326B3233, bmdMode2k24 = /* '2k24' */ 0x326B3234, bmdMode2k25 = /* '2k25' */ 0x326B3235, - /* DCI Modes (output only) */ + /* 2K DCI Modes */ bmdMode2kDCI2398 = /* '2d23' */ 0x32643233, bmdMode2kDCI24 = /* '2d24' */ 0x32643234, bmdMode2kDCI25 = /* '2d25' */ 0x32643235, + bmdMode2kDCI2997 = /* '2d29' */ 0x32643239, + bmdMode2kDCI30 = /* '2d30' */ 0x32643330, + bmdMode2kDCI50 = /* '2d50' */ 0x32643530, + bmdMode2kDCI5994 = /* '2d59' */ 0x32643539, + bmdMode2kDCI60 = /* '2d60' */ 0x32643630, - /* 4k Modes */ + /* 4K UHD Modes */ bmdMode4K2160p2398 = /* '4k23' */ 0x346B3233, bmdMode4K2160p24 = /* '4k24' */ 0x346B3234, @@ -99,11 +104,43 @@ typedef [v1_enum] enum _BMDDisplayMode { bmdMode4K2160p5994 = /* '4k59' */ 0x346B3539, bmdMode4K2160p60 = /* '4k60' */ 0x346B3630, - /* DCI Modes (output only) */ + /* 4K DCI Modes */ bmdMode4kDCI2398 = /* '4d23' */ 0x34643233, bmdMode4kDCI24 = /* '4d24' */ 0x34643234, bmdMode4kDCI25 = /* '4d25' */ 0x34643235, + bmdMode4kDCI2997 = /* '4d29' */ 0x34643239, + bmdMode4kDCI30 = /* '4d30' */ 0x34643330, + bmdMode4kDCI50 = /* '4d50' */ 0x34643530, + bmdMode4kDCI5994 = /* '4d59' */ 0x34643539, + bmdMode4kDCI60 = /* '4d60' */ 0x34643630, + + /* 8K UHD Modes */ + + bmdMode8K4320p2398 = /* '8k23' */ 0x386B3233, + bmdMode8K4320p24 = /* '8k24' */ 0x386B3234, + bmdMode8K4320p25 = /* '8k25' */ 0x386B3235, + bmdMode8K4320p2997 = /* '8k29' */ 0x386B3239, + bmdMode8K4320p30 = /* '8k30' */ 0x386B3330, + bmdMode8K4320p50 = /* '8k50' */ 0x386B3530, + bmdMode8K4320p5994 = /* '8k59' */ 0x386B3539, + bmdMode8K4320p60 = /* '8k60' */ 0x386B3630, + + /* 8K DCI Modes */ + + bmdMode8kDCI2398 = /* '8d23' */ 0x38643233, + bmdMode8kDCI24 = /* '8d24' */ 0x38643234, + bmdMode8kDCI25 = /* '8d25' */ 0x38643235, + bmdMode8kDCI2997 = /* '8d29' */ 0x38643239, + bmdMode8kDCI30 = /* '8d30' */ 0x38643330, + bmdMode8kDCI50 = /* '8d50' */ 0x38643530, + bmdMode8kDCI5994 = /* '8d59' */ 0x38643539, + bmdMode8kDCI60 = /* '8d60' */ 0x38643630, + + /* RAW Modes for Cintel (input only) */ + + bmdModeCintelRAW = /* 'rwci' */ 0x72776369, // Frame size up to 4096x3072, variable frame rate + bmdModeCintelCompressedRAW = /* 'rwcc' */ 0x72776363, // Frame size up to 4096x3072, variable frame rate /* Special Modes */ @@ -136,7 +173,12 @@ typedef [v1_enum] enum _BMDPixelFormat { /* AVID DNxHR */ - bmdFormatDNxHR = /* 'AVdh' */ 0x41566468 + bmdFormatDNxHR = /* 'AVdh' */ 0x41566468, + + /* Cintel formats */ + + bmdFormat12BitRAWGRBG = /* 'r12p' */ 0x72313270, // 12-bit RAW data for bayer pattern GRBG + bmdFormat12BitRAWJPEG = /* 'r16p' */ 0x72313670 // 12-bit RAW data arranged in tiles and JPEG compressed } BMDPixelFormat; /* Enum BMDDisplayModeFlags - Flags to describe the characteristics of an IDeckLinkDisplayMode. */ @@ -144,7 +186,8 @@ typedef [v1_enum] enum _BMDPixelFormat { [v1_enum] enum _BMDDisplayModeFlags { bmdDisplayModeSupports3D = 1 << 0, bmdDisplayModeColorspaceRec601 = 1 << 1, - bmdDisplayModeColorspaceRec709 = 1 << 2 + bmdDisplayModeColorspaceRec709 = 1 << 2, + bmdDisplayModeColorspaceRec2020 = 1 << 3 }; // Forward Declarations diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl index b609e5d..56855fc 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -77,8 +77,8 @@ typedef [v1_enum] enum _BMDStreamingEncodingFrameRate { typedef [v1_enum] enum _BMDStreamingEncodingSupport { bmdStreamingEncodingModeNotSupported = 0, - bmdStreamingEncodingModeSupported, - bmdStreamingEncodingModeSupportedWithChanges + bmdStreamingEncodingModeSupported, + bmdStreamingEncodingModeSupportedWithChanges } BMDStreamingEncodingSupport; /* Enum BMDStreamingVideoCodec - Video codecs */ @@ -346,7 +346,7 @@ interface IBMDStreamingH264NALParser; importlib("stdole2.tlb"); [ - uuid(0CAA31F6-8A26-40B0-86A4-BF58DCCA710C), + uuid(23A4EDF5-A0E5-432C-94EF-3BABB5F81C82), helpstring("CBMDStreamingDiscovery Class") ] coclass CBMDStreamingDiscovery { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming_v10_8.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming_v10_8.idl new file mode 100644 index 0000000..7d8aa5a --- /dev/null +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIStreaming_v10_8.idl @@ -0,0 +1,40 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ + + + +/* Coclasses */ + +importlib("stdole2.tlb"); + +[ + uuid(0CAA31F6-8A26-40B0-86A4-BF58DCCA710C), + helpstring("CBMDStreamingDiscovery Class") +] coclass CBMDStreamingDiscovery_v10_8 +{ + [default] interface IBMDStreamingDiscovery; +}; diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl index 35915b4..aeb52ab 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPITypes.idl @@ -1,5 +1,5 @@ /* -LICENSE-START- -** Copyright (c) 2016 Blackmagic Design +** Copyright (c) 2018 Blackmagic Design ** ** Permission is hereby granted, free of charge, to any person or organization ** obtaining a copy of the software and accompanying documentation covered by @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -53,7 +53,8 @@ cpp_quote("#endif") [v1_enum] enum _BMDTimecodeFlags { bmdTimecodeFlagDefault = 0, bmdTimecodeIsDropFrame = 1 << 0, - bmdTimecodeFieldMark = 1 << 1 + bmdTimecodeFieldMark = 1 << 1, + bmdTimecodeColorFrame = 1 << 2 }; /* Enum BMDVideoConnection - Video connection types */ diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h b/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h index dfd1799..f9db7ff 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPIVersion.h @@ -7,14 +7,14 @@ * ** execute, and transmit the Software, and to prepare derivative works of the * ** Software, and to permit third-parties to whom the Software is furnished to * ** do so, all subject to the following: - * ** + * ** * ** The copyright notices in the Software and this entire statement, including * ** the above license grant, this restriction and the following disclaimer, * ** must be included in all copies of the Software, in whole or in part, and * ** all derivative works of the Software, unless such copies or derivative * ** works are solely in the form of machine-executable object code generated by * ** a source language processor. - * ** + * ** * ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -30,8 +30,8 @@ #ifndef __DeckLink_API_Version_h__ #define __DeckLink_API_Version_h__ -#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a080000 -#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.8" +#define BLACKMAGIC_DECKLINK_API_VERSION 0x0a0b0400 +#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "10.11.4" #endif // __DeckLink_API_Version_h__ diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl index 12b6250..02a58a2 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_2.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -57,7 +57,7 @@ interface IDeckLinkConfiguration_v10_2; [ object, uuid(C679A35B-610C-4D09-B748-1D0478100FC0), - local, + local, helpstring("DeckLink Configuration interface") ] interface IDeckLinkConfiguration_v10_2 : IUnknown { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl index 7348e49..1e89d39 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_5.idl @@ -45,7 +45,7 @@ interface IDeckLinkEncoderConfiguration_v10_5; [ object, uuid(67455668-0848-45DF-8D8E-350A77C9A028), - local, + local, helpstring("DeckLink Encoder Configuration interface. Obtained from IDeckLinkEncoderInput") ] interface IDeckLinkEncoderConfiguration_v10_5 : IUnknown { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_8.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_8.idl new file mode 100644 index 0000000..c23b993 --- /dev/null +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_8.idl @@ -0,0 +1,46 @@ +/* -LICENSE-START- +** Copyright (c) 2016 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_8.idl */ + + +importlib("stdole2.tlb"); + +[ + uuid(1F2E109A-8F4F-49E4-9203-135595CB6FA5), + helpstring("CDeckLinkIterator_v10_8 Class") +] coclass CDeckLinkIterator_v10_8 +{ + [default] interface IDeckLinkIterator; +}; + +[ + uuid(1073A05C-D885-47E9-B3C6-129B3F9F648B), + helpstring("CDeckLinkDiscovery_v10_8 Class") +] coclass CDeckLinkDiscovery_v10_8 +{ + [default] interface IDeckLinkDiscovery; +}; diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_9.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_9.idl new file mode 100644 index 0000000..5506387 --- /dev/null +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v10_9.idl @@ -0,0 +1,61 @@ +/* -LICENSE-START- +** Copyright (c) 2017 Blackmagic Design +** +** Permission is hereby granted, free of charge, to any person or organization +** obtaining a copy of the software and accompanying documentation covered by +** this license (the "Software") to use, reproduce, display, distribute, +** execute, and transmit the Software, and to prepare derivative works of the +** Software, and to permit third-parties to whom the Software is furnished to +** do so, all subject to the following: +** +** The copyright notices in the Software and this entire statement, including +** the above license grant, this restriction and the following disclaimer, +** must be included in all copies of the Software, in whole or in part, and +** all derivative works of the Software, unless such copies or derivative +** works are solely in the form of machine-executable object code generated by +** a source language processor. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +** DEALINGS IN THE SOFTWARE. +** -LICENSE-END- +*/ +/* DeckLinkAPI_v10_9.idl */ + +/* Enum BMDDeckLinkConfigurationID - DeckLink Configuration ID */ + +typedef [v1_enum] enum _BMDDeckLinkConfigurationID_v10_9 { + + /* Video output flags */ + + bmdDeckLinkConfig1080pNotPsF_v10_9 = /* 'fpro' */ 0x6670726F, + +} BMDDeckLinkConfigurationID_v10_9; + +// Forward Declarations + +interface IDeckLinkConfiguration_v10_9; + +/* Interface IDeckLinkConfiguration_v10_9 - DeckLink Configuration interface */ + +[ + object, + uuid(CB71734A-FE37-4E8D-8E13-802133A1C3F2), + local, + helpstring("DeckLink Configuration interface") +] interface IDeckLinkConfiguration_v10_9 : IUnknown +{ + HRESULT SetFlag([in] BMDDeckLinkConfigurationID cfgID, [in] BOOL value); + HRESULT GetFlag([in] BMDDeckLinkConfigurationID cfgID, [out] BOOL *value); + HRESULT SetInt([in] BMDDeckLinkConfigurationID cfgID, [in] LONGLONG value); + HRESULT GetInt([in] BMDDeckLinkConfigurationID cfgID, [out] LONGLONG *value); + HRESULT SetFloat([in] BMDDeckLinkConfigurationID cfgID, [in] double value); + HRESULT GetFloat([in] BMDDeckLinkConfigurationID cfgID, [out] double *value); + HRESULT SetString([in] BMDDeckLinkConfigurationID cfgID, [in] BSTR value); + HRESULT GetString([in] BMDDeckLinkConfigurationID cfgID, [out] BSTR *value); + HRESULT WriteConfigurationToPreferences(void); +}; diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl index e21b5a8..0fcc88e 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_1.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -31,7 +31,7 @@ interface IDeckLinkVideoFrame_v7_1; interface IDeckLinkVideoInputFrame_v7_1; interface IDeckLinkAudioInputPacket_v7_1; - + [object, uuid(B28131B6-59AC-4857-B5AC-CD75D5883E2F), helpstring("IDeckLinkDisplayModeIterator_v7_1 enumerates over supported input/output display modes.")] interface IDeckLinkDisplayModeIterator_v7_1 : IUnknown @@ -50,21 +50,21 @@ long GetHeight (); HRESULT GetFrameRate ([out] BMDTimeValue *frameDuration, [out] BMDTimeScale *timeScale); }; - + [object, uuid(EBD01AFA-E4B0-49C6-A01D-EDB9D1B55FD9), helpstring("IDeckLinkVideoOutputCallback. Frame completion callback.")] interface IDeckLinkVideoOutputCallback_v7_1 : IUnknown { HRESULT ScheduledFrameCompleted ([in] IDeckLinkVideoFrame_v7_1* completedFrame, [in] BMDOutputFrameCompletionResult result); }; - + [object, uuid(7F94F328-5ED4-4E9F-9729-76A86BDC99CC), helpstring("IDeckLinkInputCallback_v7_1. Frame arrival callback.")] interface IDeckLinkInputCallback_v7_1 : IUnknown { HRESULT VideoInputFrameArrived ([in] IDeckLinkVideoInputFrame_v7_1* videoFrame, [in] IDeckLinkAudioInputPacket_v7_1* audioPacket); }; - + [object, uuid(AE5B3E9B-4E1E-4535-B6E8-480FF52F6CE5), local, helpstring("IDeckLinkOutput_v7_1. Created by QueryInterface from IDeckLink.")] @@ -72,11 +72,11 @@ { HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result); HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); - + // Video output HRESULT EnableVideoOutput (BMDDisplayMode displayMode); HRESULT DisableVideoOutput (); - + HRESULT SetVideoOutputFrameMemoryAllocator ([in] IDeckLinkMemoryAllocator* theAllocator); HRESULT CreateVideoFrame (int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); HRESULT CreateVideoFrameFromBuffer (void* buffer, int width, int height, int rowBytes, BMDPixelFormat pixelFormat, BMDFrameFlags flags, IDeckLinkVideoFrame_v7_1** outFrame); @@ -84,22 +84,22 @@ HRESULT DisplayVideoFrameSync (IDeckLinkVideoFrame_v7_1* theFrame); HRESULT ScheduleVideoFrame (IDeckLinkVideoFrame_v7_1* theFrame, BMDTimeValue displayTime, BMDTimeValue displayDuration, BMDTimeScale timeScale); HRESULT SetScheduledFrameCompletionCallback ([in] IDeckLinkVideoOutputCallback_v7_1* theCallback); - + // Audio output HRESULT EnableAudioOutput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); HRESULT DisableAudioOutput (); - + HRESULT WriteAudioSamplesSync (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesWritten); - + HRESULT BeginAudioPreroll (); HRESULT EndAudioPreroll (); HRESULT ScheduleAudioSamples (void* buffer, unsigned int sampleFrameCount, BMDTimeValue streamTime, BMDTimeScale timeScale, [out] unsigned int *sampleFramesWritten); - + HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount); HRESULT FlushBufferedAudioSamples (); - + HRESULT SetAudioCallback ( [in] IDeckLinkAudioOutputCallback* theCallback); - + // Output control HRESULT StartScheduledPlayback (BMDTimeValue playbackStartTime, BMDTimeScale timeScale, double playbackSpeed); HRESULT StopScheduledPlayback (BMDTimeValue stopPlaybackAtTime, BMDTimeValue *actualStopTime, BMDTimeScale timeScale); @@ -112,24 +112,24 @@ { HRESULT DoesSupportVideoMode (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, [out] BMDDisplayModeSupport *result); HRESULT GetDisplayModeIterator ([out] IDeckLinkDisplayModeIterator_v7_1 **iterator); - + // Video input HRESULT EnableVideoInput (BMDDisplayMode displayMode, BMDPixelFormat pixelFormat, BMDVideoInputFlags flags); HRESULT DisableVideoInput (); - + // Audio input HRESULT EnableAudioInput (BMDAudioSampleRate sampleRate, BMDAudioSampleType sampleType, unsigned int channelCount); HRESULT DisableAudioInput (); HRESULT ReadAudioSamples (void* buffer, unsigned int sampleFrameCount, [out] unsigned int *sampleFramesRead, [out] BMDTimeValue *audioPacketTime, BMDTimeScale timeScale); HRESULT GetBufferedAudioSampleFrameCount ( [out] unsigned int *bufferedSampleCount); - + // Input control HRESULT StartStreams (); HRESULT StopStreams (); HRESULT PauseStreams (); HRESULT SetCallback ([in] IDeckLinkInputCallback_v7_1* theCallback); }; - + [object, uuid(333F3A10-8C2D-43CF-B79D-46560FEEA1CE), local, helpstring("IDeckLinkVideoFrame_v7_1. Created by IDeckLinkVideoOutput::CreateVideoFrame.")] interface IDeckLinkVideoFrame_v7_1 : IUnknown @@ -141,14 +141,14 @@ BMDFrameFlags GetFlags (); HRESULT GetBytes (void* *buffer); }; - + [object, uuid(C8B41D95-8848-40EE-9B37-6E3417FB114B), local, helpstring("IDeckLinkVideoInputFrame_v7_1. Provided by the IDeckLinkVideoInput frame arrival callback.")] interface IDeckLinkVideoInputFrame_v7_1 : IDeckLinkVideoFrame_v7_1 { HRESULT GetFrameTime (BMDTimeValue *frameTime, BMDTimeValue *frameDuration, BMDTimeScale timeScale); }; - + [object, uuid(C86DE4F6-A29F-42E3-AB3A-1363E29F0788), local, helpstring("IDeckLinkAudioInputPacket_v7_1. Provided by the IDeckLinkInput callback.")] interface IDeckLinkAudioInputPacket_v7_1 : IUnknown @@ -157,4 +157,4 @@ HRESULT GetBytes (void* *buffer); HRESULT GetAudioPacketTime (BMDTimeValue *packetTime, BMDTimeScale timeScale); }; - + diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl index 9dfa497..3f3e00b 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_3.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -55,7 +55,7 @@ interface IDeckLinkVideoInputFrame_v7_3; [ object, uuid(271C65E3-C323-4344-A30F-D908BCB20AA3), - local, + local, helpstring("Created by QueryInterface from IDeckLink.") ] interface IDeckLinkOutput_v7_3 : IUnknown { @@ -146,7 +146,7 @@ interface IDeckLinkVideoInputFrame_v7_3; [ object, uuid(CF317790-2894-11DE-8C30-0800200C9A66), - local, + local, helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") ] interface IDeckLinkVideoInputFrame_v7_3 : IDeckLinkVideoFrame_v7_6 { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl index 8ed7b73..c9b9b18 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_6.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -114,7 +114,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(29228142-EB8C-4141-A621-F74026450955), - local, + local, helpstring("Created by QueryInterface from IDeckLink.") ] interface IDeckLinkOutput_v7_6 : IUnknown { @@ -225,7 +225,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(A8D8238E-6B18-4196-99E1-5AF717B83D32), - local, + local, helpstring("Interface to encapsulate a video frame; can be caller-implemented.") ] interface IDeckLinkVideoFrame_v7_6 : IUnknown { @@ -246,7 +246,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(46FCEE00-B4E6-43D0-91C0-023A7FCEB34F), - local, + local, helpstring("Created by IDeckLinkOutput::CreateVideoFrame.") ] interface IDeckLinkMutableVideoFrame_v7_6 : IDeckLinkVideoFrame_v7_6 { @@ -263,7 +263,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(9A74FA41-AE9F-47AC-8CF4-01F42DD59965), - local, + local, helpstring("Provided by the IDeckLinkVideoInput frame arrival callback.") ] interface IDeckLinkVideoInputFrame_v7_6 : IDeckLinkVideoFrame_v7_6 { @@ -277,7 +277,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(373F499D-4B4D-4518-AD22-6354E5A5825E), - local, + local, helpstring("Screen preview callback") ] interface IDeckLinkScreenPreviewCallback_v7_6 : IUnknown { @@ -290,7 +290,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(BA575CD9-A15E-497B-B2C2-F9AFE7BE4EBA), - local, + local, helpstring("Created with CoCreateInstance().") ] interface IDeckLinkGLScreenPreviewHelper_v7_6 : IUnknown { @@ -308,7 +308,7 @@ interface IDeckLinkConfiguration_v7_6; [ object, uuid(3EB504C9-F97D-40FE-A158-D407D48CB53B), - local, + local, helpstring("Created with CoCreateInstance().") ] interface IDeckLinkVideoConversion_v7_6 : IUnknown { diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl index 722984a..b222899 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v7_9.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl index a2da181..079f60b 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_0.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl index 59b9a21..5d163ae 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v8_1.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl index e918e04..6c6179a 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_2.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT diff --git a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl index a5e1439..c908e42 100644 --- a/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl +++ b/plugins/decklink/win/decklink-sdk/DeckLinkAPI_v9_9.idl @@ -7,14 +7,14 @@ ** execute, and transmit the Software, and to prepare derivative works of the ** Software, and to permit third-parties to whom the Software is furnished to ** do so, all subject to the following: -** +** ** The copyright notices in the Software and this entire statement, including ** the above license grant, this restriction and the following disclaimer, ** must be included in all copies of the Software, in whole or in part, and ** all derivative works of the Software, unless such copies or derivative ** works are solely in the form of machine-executable object code generated by ** a source language processor. -** +** ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT @@ -33,7 +33,7 @@ [ object, uuid(A3EF0963-0862-44ED-92A9-EE89ABF431C7), - local, + local, helpstring("Created by QueryInterface from IDeckLink.") ] interface IDeckLinkOutput_v9_9 : IUnknown { diff --git a/plugins/image-source/color-source.c b/plugins/image-source/color-source.c index 14f3b01..7cfa159 100644 --- a/plugins/image-source/color-source.c +++ b/plugins/image-source/color-source.c @@ -99,9 +99,12 @@ static uint32_t color_source_getheight(void *data) static void color_source_defaults(obs_data_t *settings) { + struct obs_video_info ovi; + obs_get_video_info(&ovi); + obs_data_set_default_int(settings, "color", 0xFFFFFFFF); - obs_data_set_default_int(settings, "width", 400); - obs_data_set_default_int(settings, "height", 400); + obs_data_set_default_int(settings, "width", ovi.base_width); + obs_data_set_default_int(settings, "height", ovi.base_height); } struct obs_source_info color_source_info = { diff --git a/plugins/image-source/data/locale/ar-SA.ini b/plugins/image-source/data/locale/ar-SA.ini index cac5ca7..2414988 100644 --- a/plugins/image-source/data/locale/ar-SA.ini +++ b/plugins/image-source/data/locale/ar-SA.ini @@ -3,4 +3,7 @@ File="ملف الصورة" UnloadWhenNotShowing="إلغاء تحميل الصورة إذا لم تظهر" +ColorSource.Color="اللون" +ColorSource.Width="العرض" +ColorSource.Height="الإرتفاع" diff --git a/plugins/image-source/data/locale/bg-BG.ini b/plugins/image-source/data/locale/bg-BG.ini index 44df8ff..b061182 100644 --- a/plugins/image-source/data/locale/bg-BG.ini +++ b/plugins/image-source/data/locale/bg-BG.ini @@ -1,5 +1,23 @@ ImageInput="Изображение" File="Файл с изображение" +SlideShow.TransitionSpeed="Бързина на прехода (милисекунди)" +SlideShow.SlideTime="Време между слайдовете (милисекунди)" +SlideShow.Files="Файлове с изображения" +SlideShow.CustomSize.Auto="Автоматично" +SlideShow.Randomize="Произволно изпълнение" +SlideShow.Loop="Повтаряне" +SlideShow.Transition="Преход" +SlideShow.Transition.Cut="Изрязване" +SlideShow.Transition.Fade="Затъмняване" +SlideShow.PlaybackBehavior.AlwaysPlay="Винаги да се пуска, дори когато не се вижда" +SlideShow.SlideMode.Auto="Автоматично" +SlideShow.PlayPause="Пускане/пауза" +SlideShow.Restart="Рестартиране" +SlideShow.Stop="Спиране" +ColorSource="Източник за цвят" +ColorSource.Color="Цвят" +ColorSource.Width="Широчина" +ColorSource.Height="Височина" diff --git a/plugins/image-source/data/locale/da-DK.ini b/plugins/image-source/data/locale/da-DK.ini index 3623fab..8466ef2 100644 --- a/plugins/image-source/data/locale/da-DK.ini +++ b/plugins/image-source/data/locale/da-DK.ini @@ -2,27 +2,27 @@ ImageInput="Billede" File="Billedfil" UnloadWhenNotShowing="Fjern billede fra hukommelsen når det ikke vises" -SlideShow="Billede diasshow" -SlideShow.TransitionSpeed="Overgangshastighed (millisekunder)" -SlideShow.SlideTime="Tid mellem dias (millisekunder)" +SlideShow="Billedediasshow" +SlideShow.TransitionSpeed="Overgangshastighed (ms)" +SlideShow.SlideTime="Tid mellem dias (ms)" SlideShow.Files="Billedfiler" SlideShow.CustomSize="Afgrænsningsstørrelse/Formatforhold" SlideShow.CustomSize.Auto="Automatisk" SlideShow.Randomize="Tilfældig afspilning" -SlideShow.Loop="Gentagelse" +SlideShow.Loop="Løkke" SlideShow.Transition="Overgang" SlideShow.Transition.Cut="Klip" -SlideShow.Transition.Fade="Overgang" +SlideShow.Transition.Fade="Toning" SlideShow.Transition.Swipe="Stryg" SlideShow.Transition.Slide="Glide" SlideShow.PlaybackBehavior="Synlighedsadfærd" SlideShow.PlaybackBehavior.StopRestart="Stop når ikke synlig, genstart når synlig" SlideShow.PlaybackBehavior.PauseUnpause="Sæt på pause når ikke synlig, genoptag når synlig" -SlideShow.PlaybackBehavior.AlwaysPlay="Afspil altid også når usynlig" -SlideShow.SlideMode="Diasshowtilstand" +SlideShow.PlaybackBehavior.AlwaysPlay="Afspil altid, også når usynlig" +SlideShow.SlideMode="Diastilstand" SlideShow.SlideMode.Auto="Automatisk" -SlideShow.SlideMode.Manual="Manuel (styr diasshow via genvejstaster)" -SlideShow.PlayPause="Afspil/pause" +SlideShow.SlideMode.Manual="Manuelt (styr diasshow via genvejstaster)" +SlideShow.PlayPause="Afspil/Pause" SlideShow.Restart="Genstart" SlideShow.Stop="Stop" SlideShow.NextSlide="Næste dias" diff --git a/plugins/image-source/data/locale/de-DE.ini b/plugins/image-source/data/locale/de-DE.ini index 0914f65..435b868 100644 --- a/plugins/image-source/data/locale/de-DE.ini +++ b/plugins/image-source/data/locale/de-DE.ini @@ -1,12 +1,12 @@ ImageInput="Bild" File="Bilddatei" -UnloadWhenNotShowing="Entlade Bild, wenn es nicht angezeigt wird" +UnloadWhenNotShowing="Bild entladen, wenn es nicht angezeigt wird" SlideShow="Diashow" SlideShow.TransitionSpeed="Übergangsgeschwindigkeit (Millisekunden)" SlideShow.SlideTime="Zeit zwischen Bildern (Millisekunden)" SlideShow.Files="Bilddateien" -SlideShow.CustomSize="Rahmen Größe/Seitenverhältnis" +SlideShow.CustomSize="Rahmengröße/Seitenverhältnis" SlideShow.CustomSize.Auto="Automatisch" SlideShow.Randomize="Zufällige Wiedergabe" SlideShow.Loop="Endlosschleife" @@ -16,14 +16,14 @@ SlideShow.Transition.Fade="Überblenden" SlideShow.Transition.Swipe="Swipe" SlideShow.Transition.Slide="Slide" SlideShow.PlaybackBehavior="Sichtbarkeitsverhalten" -SlideShow.PlaybackBehavior.StopRestart="Anhalten wenn nicht sichtbar, neu starten wenn sichtbar" -SlideShow.PlaybackBehavior.PauseUnpause="Pausieren wenn nicht sichtbar, fortsetzen wenn sichtbar" +SlideShow.PlaybackBehavior.StopRestart="Anhalten, wenn nicht sichtbar, neustarten, wenn sichtbar" +SlideShow.PlaybackBehavior.PauseUnpause="Pausieren, wenn nicht sichtbar, fortsetzen, wenn sichtbar" SlideShow.PlaybackBehavior.AlwaysPlay="Immer abspielen, auch wenn nicht sichtbar" SlideShow.SlideMode="Diashowmodus" SlideShow.SlideMode.Auto="Automatisch" SlideShow.SlideMode.Manual="Manuell (Hotkeys verwenden, um Diashow zu steuern)" -SlideShow.PlayPause="Abspielen/Pausieren" -SlideShow.Restart="Neu starten" +SlideShow.PlayPause="Abspielen/pausieren" +SlideShow.Restart="Neustarten" SlideShow.Stop="Stop" SlideShow.NextSlide="Nächstes Bild" SlideShow.PreviousSlide="Vorheriges Bild" diff --git a/plugins/image-source/data/locale/fa-IR.ini b/plugins/image-source/data/locale/fa-IR.ini new file mode 100644 index 0000000..ae1e29a --- /dev/null +++ b/plugins/image-source/data/locale/fa-IR.ini @@ -0,0 +1,33 @@ +ImageInput="تصویر" +File="پوشه تصویر" +UnloadWhenNotShowing="لغو بارگیری عکس زمانی که نشان داده نشد" + +SlideShow="نمایش اسلایدی تصویر" +SlideShow.TransitionSpeed="سرعت انتقال (میلی ثانیه)" +SlideShow.SlideTime="زمان بین اسلاید (میلی ثانیه)" +SlideShow.Files="پوشه تصاویر" +SlideShow.CustomSize.Auto="خودکار" +SlideShow.Randomize="پخش تصادفی" +SlideShow.Loop="چرخه" +SlideShow.Transition="انتقال" +SlideShow.Transition.Cut="برش" +SlideShow.Transition.Fade="محو شدن" +SlideShow.Transition.Swipe="کشیدن" +SlideShow.Transition.Slide="اسلاید" +SlideShow.PlaybackBehavior="کنش های دیداری" +SlideShow.PlaybackBehavior.StopRestart="توقف زمانی که قابل مشاهده نیست، راه اندازی مجدد زمانی که قابل مشاهده است" +SlideShow.PlaybackBehavior.PauseUnpause="توقف زمانی که قابل مشاهده نیست، راه اندازی مجدد زمانی که قابل مشاهده است" +SlideShow.SlideMode="حالت اسلاید" +SlideShow.SlideMode.Auto="خودکار" +SlideShow.PlayPause="پخش/توقف" +SlideShow.Restart="راه اندازی مجدد" +SlideShow.Stop="توقف" +SlideShow.NextSlide="اسلاید بعدی" +SlideShow.PreviousSlide="اسلاید قبلی" +SlideShow.HideWhenDone="پنهان کردن هنگامی که نمایش پرده ای انجام می شود" + +ColorSource="رنگ منبع" +ColorSource.Color="رنگ" +ColorSource.Width="عرض" +ColorSource.Height="ارتفاع" + diff --git a/plugins/image-source/data/locale/fr-FR.ini b/plugins/image-source/data/locale/fr-FR.ini index edb8113..936d9b8 100644 --- a/plugins/image-source/data/locale/fr-FR.ini +++ b/plugins/image-source/data/locale/fr-FR.ini @@ -4,9 +4,9 @@ UnloadWhenNotShowing="Décharger l'image quand elle n'est pas affichée" SlideShow="Diaporama" SlideShow.TransitionSpeed="Vitesse de transition (millisecondes)" -SlideShow.SlideTime="Temps entre chaque diapositive (millisecondes)" +SlideShow.SlideTime="Temps entre chaque diapositive (en millisecondes)" SlideShow.Files="Fichiers image" -SlideShow.CustomSize="Taille Limite/Ratio d'aspect" +SlideShow.CustomSize="Taille du Cadre/Rapport d'aspect" SlideShow.CustomSize.Auto="Automatique" SlideShow.Randomize="Lecture aléatoire" SlideShow.Loop="Boucle" @@ -18,11 +18,11 @@ SlideShow.Transition.Slide="Glissement" SlideShow.PlaybackBehavior="Comportement de Visibilité" SlideShow.PlaybackBehavior.StopRestart="Arrêter si non visible, redémarrer si visible" SlideShow.PlaybackBehavior.PauseUnpause="Suspendre si non visible, reprendre si visible" -SlideShow.PlaybackBehavior.AlwaysPlay="Toujours jouer même lorsqu'elle n'est pas visible" +SlideShow.PlaybackBehavior.AlwaysPlay="Toujours jouer même si non visible" SlideShow.SlideMode="Mode Diapo" SlideShow.SlideMode.Auto="Automatique" SlideShow.SlideMode.Manual="Manuel (utiliser les raccourcis clavier pour contrôler le diapo)" -SlideShow.PlayPause="Lire/Pause" +SlideShow.PlayPause="Lecture/Pause" SlideShow.Restart="Relancer" SlideShow.Stop="Arrêter" SlideShow.NextSlide="Diapo suivante" diff --git a/plugins/image-source/data/locale/it-IT.ini b/plugins/image-source/data/locale/it-IT.ini index 5b1f5ef..aae5605 100644 --- a/plugins/image-source/data/locale/it-IT.ini +++ b/plugins/image-source/data/locale/it-IT.ini @@ -1,35 +1,35 @@ ImageInput="Immagine" -File="File Immagine" -UnloadWhenNotShowing="Non caricare immagine se non si vede" +File="File immagine" +UnloadWhenNotShowing="Disattiva l'immagine quando non è visibile" -SlideShow="Presentazione immagini" -SlideShow.TransitionSpeed="Velocità di transizione (millisecondi)" -SlideShow.SlideTime="Tempo tra le diapositive (millisecondi)" -SlideShow.Files="Files Immagini" +SlideShow="Presentazione di immagini" +SlideShow.TransitionSpeed="Velocità di transizione (in millisecondi)" +SlideShow.SlideTime="Tempo tra le diapositive (in millisecondi)" +SlideShow.Files="File di immagini" SlideShow.CustomSize="Dimensioni/proporzioni" -SlideShow.CustomSize.Auto="Automatico" -SlideShow.Randomize="Randomizzare la riproduzione" -SlideShow.Loop="Loop" +SlideShow.CustomSize.Auto="Automatiche" +SlideShow.Randomize="Riproduzione casuale" +SlideShow.Loop="Ripetizione" SlideShow.Transition="Transizione" SlideShow.Transition.Cut="Taglio" SlideShow.Transition.Fade="Dissolvenza" SlideShow.Transition.Swipe="Scorri" SlideShow.Transition.Slide="Scivola" SlideShow.PlaybackBehavior="Comportamento visibilità" -SlideShow.PlaybackBehavior.StopRestart="Interrompi quando non visibile, riavvia quando visibile" +SlideShow.PlaybackBehavior.StopRestart="Interrompi quando non visibile, ricomincia quando visibile" SlideShow.PlaybackBehavior.PauseUnpause="Pausa quando non visibile, riprendi quando visibile" SlideShow.PlaybackBehavior.AlwaysPlay="Continua sempre anche quando non visibile" -SlideShow.SlideMode="Modalità Slide" -SlideShow.SlideMode.Auto="Automatico" -SlideShow.SlideMode.Manual="Manuale (usa i tasti di scelta rapida per controllare la presentazione)" -SlideShow.PlayPause="Play/Pausa" -SlideShow.Restart="Riavvia" -SlideShow.Stop="Stop" -SlideShow.NextSlide="Prossima Slide" -SlideShow.PreviousSlide="Slide Precedente" +SlideShow.SlideMode="Modalità diapositiva" +SlideShow.SlideMode.Auto="Automatica" +SlideShow.SlideMode.Manual="Manuale (usa le scorciatoie per controllare la presentazione)" +SlideShow.PlayPause="Riproduci/pausa" +SlideShow.Restart="Ricomincia" +SlideShow.Stop="Interrompi" +SlideShow.NextSlide="Diapositiva successiva" +SlideShow.PreviousSlide="Diapositiva precedente" SlideShow.HideWhenDone="Nascondi quando la presentazione è terminata" -ColorSource="Origine del colore" +ColorSource="Fonte di colore" ColorSource.Color="Colore" ColorSource.Width="Larghezza" ColorSource.Height="Altezza" diff --git a/plugins/image-source/data/locale/mn-MN.ini b/plugins/image-source/data/locale/mn-MN.ini new file mode 100644 index 0000000..272950e --- /dev/null +++ b/plugins/image-source/data/locale/mn-MN.ini @@ -0,0 +1,22 @@ +ImageInput="Зураг" + +SlideShow.CustomSize.Auto="Aвтомат" +SlideShow.Randomize="Тоглуулагчыг түүвэрээр ажилууллах" +SlideShow.Loop="Давталт" +SlideShow.Transition="Шилжилт" +SlideShow.Transition.Cut="Шууд" +SlideShow.Transition.Fade="Алга болно" +SlideShow.Transition.Swipe="Хажуунаас" +SlideShow.Transition.Slide="Гулгаж" +SlideShow.PlaybackBehavior="Харагдах байдал" +SlideShow.PlaybackBehavior.StopRestart="Ил харагдахгүй бол зогсоох, харагдах үед дахин эхлүүлнэ" +SlideShow.PlaybackBehavior.PauseUnpause="Ил харагдахгүй бол пауз авах, харагдах үед паузаа болих" +SlideShow.PlaybackBehavior.AlwaysPlay="Ил харагдахгүй бол үргэлжлүүлэн тоглуулах" +SlideShow.SlideMode.Auto="Aвтомат" +SlideShow.PlayPause="Тоглуулах/Түр зогсоох" +SlideShow.Stop="Зогсоох" + +ColorSource.Color="Өнгө" +ColorSource.Width="Өргөн" +ColorSource.Height="Өндөр" + diff --git a/plugins/image-source/data/locale/pt-PT.ini b/plugins/image-source/data/locale/pt-PT.ini index 01eec59..46de88f 100644 --- a/plugins/image-source/data/locale/pt-PT.ini +++ b/plugins/image-source/data/locale/pt-PT.ini @@ -6,11 +6,20 @@ SlideShow="Imagens em Deslize" SlideShow.TransitionSpeed="Velocidade de transição (milissegundos)" SlideShow.SlideTime="Tempo entre Deslizes (milissegundos)" SlideShow.Files="Arquivos de Imagem" +SlideShow.CustomSize.Auto="Automático" SlideShow.Randomize="Reprodução aleatória" +SlideShow.Loop="Loop" SlideShow.Transition="Transição" SlideShow.Transition.Cut="Cortar" SlideShow.Transition.Fade="Desvanecer" SlideShow.Transition.Swipe="Deslizar" SlideShow.Transition.Slide="Deslize" +SlideShow.PlaybackBehavior.AlwaysPlay="Reproduzir sempre, mesmo quando não está visível" +SlideShow.SlideMode.Auto="Automático" +SlideShow.PlayPause="Play/Pausa" +SlideShow.Stop="Stop" +ColorSource.Color="Cor" +ColorSource.Width="Largura" +ColorSource.Height="Altura" diff --git a/plugins/image-source/data/locale/ro-RO.ini b/plugins/image-source/data/locale/ro-RO.ini index 12e7f38..9619905 100644 --- a/plugins/image-source/data/locale/ro-RO.ini +++ b/plugins/image-source/data/locale/ro-RO.ini @@ -2,19 +2,25 @@ ImageInput="Imagine" File="Fișier imagine" UnloadWhenNotShowing="Eliberează din memorie imaginea când nu este afișată" -SlideShow="Slide Show de imagini" -SlideShow.TransitionSpeed="Viteza de tranziție (milisecunde)" +SlideShow="Diaporamă" +SlideShow.TransitionSpeed="Viteză de tranziție (milisecunde)" SlideShow.SlideTime="Timpul dintre diapozitive (milisecunde)" -SlideShow.Files="Fișiere Imagine" +SlideShow.Files="Fișiere imagine" SlideShow.CustomSize.Auto="Automat" SlideShow.Loop="Buclă" SlideShow.Transition="Tranziție" SlideShow.Transition.Cut="Decupare" -SlideShow.Transition.Slide="Diapozitiv" +SlideShow.Transition.Fade="Estompare" +SlideShow.Transition.Swipe="Glisare" +SlideShow.Transition.Slide="Culisare" SlideShow.SlideMode.Auto="Automat" -SlideShow.NextSlide="Următorul diapozitiv" -SlideShow.PreviousSlide="Diapozitiv anterior" +SlideShow.PlayPause="Redă/Pune pe pauză" +SlideShow.Restart="Repornește" +SlideShow.Stop="Oprește" +SlideShow.NextSlide="Diapozitivul următor" +SlideShow.PreviousSlide="Diapozitivul anterior" +ColorSource="Sursă de culoare" ColorSource.Color="Culoare" ColorSource.Width="Lățime" ColorSource.Height="Înălțime" diff --git a/plugins/image-source/data/locale/ru-RU.ini b/plugins/image-source/data/locale/ru-RU.ini index b74e4ee..3f626a5 100644 --- a/plugins/image-source/data/locale/ru-RU.ini +++ b/plugins/image-source/data/locale/ru-RU.ini @@ -11,7 +11,7 @@ SlideShow.CustomSize.Auto="Автоматически" SlideShow.Randomize="Случайное воспроизведение" SlideShow.Loop="Повтор" SlideShow.Transition="Переход" -SlideShow.Transition.Cut="Обрезка" +SlideShow.Transition.Cut="Обрезать" SlideShow.Transition.Fade="Затухание" SlideShow.Transition.Swipe="Перемещение" SlideShow.Transition.Slide="Сдвиг" diff --git a/plugins/image-source/data/locale/sr-CS.ini b/plugins/image-source/data/locale/sr-CS.ini index 579ba01..64ad4f4 100644 --- a/plugins/image-source/data/locale/sr-CS.ini +++ b/plugins/image-source/data/locale/sr-CS.ini @@ -6,11 +6,31 @@ SlideShow="Prikazivanje slajdova" SlideShow.TransitionSpeed="Brzina prelaza (milisekunde)" SlideShow.SlideTime="Vreme između slajdova (milisekunde)" SlideShow.Files="Datoteke slika" +SlideShow.CustomSize="Veličina/proporcija" +SlideShow.CustomSize.Auto="Automatska" SlideShow.Randomize="Nasumična reprodukcija" +SlideShow.Loop="Ponavljaj" SlideShow.Transition="Prelaz" SlideShow.Transition.Cut="Isecanje" SlideShow.Transition.Fade="Zatamnjenje" SlideShow.Transition.Swipe="Prevlačenje" SlideShow.Transition.Slide="Klizanje" +SlideShow.PlaybackBehavior="Funkcionisanje u zavisnosti od vidljivosti" +SlideShow.PlaybackBehavior.StopRestart="Zaustavi kada nije vidljiv, počni ispočetka kada je vidljiv" +SlideShow.PlaybackBehavior.PauseUnpause="Pauziraj kada nije vidljiv, nastavi kada postane vidljiv" +SlideShow.PlaybackBehavior.AlwaysPlay="Uvek emituj, čak i kada nije vidljiv" +SlideShow.SlideMode="Slajd režim" +SlideShow.SlideMode.Auto="Automatski" +SlideShow.SlideMode.Manual="Ručni (Koristite prečice na tastaturi da kontrolišete prezentaciju)" +SlideShow.PlayPause="Pusti/Pauziraj" +SlideShow.Restart="Počni ispočetka" +SlideShow.Stop="Zaustavi" +SlideShow.NextSlide="Sledeći slajd" +SlideShow.PreviousSlide="Prethodni slajd" +SlideShow.HideWhenDone="Sakrij kada se prezentacija završi" +ColorSource="Izvor boje" +ColorSource.Color="Boja" +ColorSource.Width="Širina" +ColorSource.Height="Visina" diff --git a/plugins/image-source/data/locale/sr-SP.ini b/plugins/image-source/data/locale/sr-SP.ini index 1101941..8e4d21a 100644 --- a/plugins/image-source/data/locale/sr-SP.ini +++ b/plugins/image-source/data/locale/sr-SP.ini @@ -6,11 +6,31 @@ SlideShow="Приказивање слајдова" SlideShow.TransitionSpeed="Брзина прелаза (милисекунде)" SlideShow.SlideTime="Време између слајдова (милисекунде)" SlideShow.Files="Датотеке слика" +SlideShow.CustomSize="Величина/пропорција" +SlideShow.CustomSize.Auto="Аутоматска" SlideShow.Randomize="Насумична репродукција" +SlideShow.Loop="Понављај" SlideShow.Transition="Прелаз" SlideShow.Transition.Cut="Исецање" SlideShow.Transition.Fade="Затамњење" SlideShow.Transition.Swipe="Превлачење" SlideShow.Transition.Slide="Клизање" +SlideShow.PlaybackBehavior="Функционисање у зависности од видљивости" +SlideShow.PlaybackBehavior.StopRestart="Заустави када није видљив, почни испочетка када је видљив" +SlideShow.PlaybackBehavior.PauseUnpause="Паузирај када није видљив, настави када постане видљив" +SlideShow.PlaybackBehavior.AlwaysPlay="Увек емитуј, чак и када није видљив" +SlideShow.SlideMode="Слајд режим" +SlideShow.SlideMode.Auto="Аутоматски" +SlideShow.SlideMode.Manual="Ручни (користите пречице на тастатури да контролишете презентацију)" +SlideShow.PlayPause="Пусти/Паузирај" +SlideShow.Restart="Почни испочетка" +SlideShow.Stop="Заустави" +SlideShow.NextSlide="Следећи слајд" +SlideShow.PreviousSlide="Претходни слајд" +SlideShow.HideWhenDone="Сакриј када се презентација заврши" +ColorSource="Извор боје" +ColorSource.Color="Боја" +ColorSource.Width="Ширина" +ColorSource.Height="Висина" diff --git a/plugins/image-source/data/locale/zh-CN.ini b/plugins/image-source/data/locale/zh-CN.ini index 1942e61..2ea81e6 100644 --- a/plugins/image-source/data/locale/zh-CN.ini +++ b/plugins/image-source/data/locale/zh-CN.ini @@ -3,17 +3,17 @@ File="图像文件" UnloadWhenNotShowing="当不显示时卸载图像" SlideShow="图像幻灯片放映" -SlideShow.TransitionSpeed="过渡速度(毫秒)" +SlideShow.TransitionSpeed="转场速度(毫秒)" SlideShow.SlideTime="幻灯片之间时间(毫秒)" SlideShow.Files="图像文件" -SlideShow.CustomSize="边框大小/高宽比" +SlideShow.CustomSize="边框大小/宽高比" SlideShow.CustomSize.Auto="自动" SlideShow.Randomize="随机播放" SlideShow.Loop="循环" -SlideShow.Transition="转换" +SlideShow.Transition="转换特效" SlideShow.Transition.Cut="剪切" SlideShow.Transition.Fade="淡出" -SlideShow.Transition.Swipe="滑动" +SlideShow.Transition.Swipe="滑出" SlideShow.Transition.Slide="幻灯片" SlideShow.PlaybackBehavior="可见性的行为" SlideShow.PlaybackBehavior.StopRestart="不可见时停止, 可见时重新开始" @@ -27,7 +27,7 @@ SlideShow.Restart="重新开始" SlideShow.Stop="停止" SlideShow.NextSlide="下一张幻灯片" SlideShow.PreviousSlide="上一张幻灯片" -SlideShow.HideWhenDone="幻灯片完成时隐藏" +SlideShow.HideWhenDone="幻灯片放映完成后隐藏" ColorSource="色源" ColorSource.Color="色彩" diff --git a/plugins/image-source/image-source.c b/plugins/image-source/image-source.c index b464325..1c3fa34 100644 --- a/plugins/image-source/image-source.c +++ b/plugins/image-source/image-source.c @@ -25,7 +25,7 @@ struct image_source { uint64_t last_time; bool active; - gs_image_file_t image; + gs_image_file2_t if2; }; @@ -48,20 +48,20 @@ static void image_source_load(struct image_source *context) char *file = context->file; obs_enter_graphics(); - gs_image_file_free(&context->image); + gs_image_file2_free(&context->if2); obs_leave_graphics(); if (file && *file) { debug("loading texture '%s'", file); context->file_timestamp = get_modified_timestamp(file); - gs_image_file_init(&context->image, file); + gs_image_file2_init(&context->if2, file); context->update_time_elapsed = 0; obs_enter_graphics(); - gs_image_file_init_texture(&context->image); + gs_image_file2_init_texture(&context->if2); obs_leave_graphics(); - if (!context->image.loaded) + if (!context->if2.image.loaded) warn("failed to load texture '%s'", file); } } @@ -69,7 +69,7 @@ static void image_source_load(struct image_source *context) static void image_source_unload(struct image_source *context) { obs_enter_graphics(); - gs_image_file_free(&context->image); + gs_image_file2_free(&context->if2); obs_leave_graphics(); } @@ -135,26 +135,26 @@ static void image_source_destroy(void *data) static uint32_t image_source_getwidth(void *data) { struct image_source *context = data; - return context->image.cx; + return context->if2.image.cx; } static uint32_t image_source_getheight(void *data) { struct image_source *context = data; - return context->image.cy; + return context->if2.image.cy; } static void image_source_render(void *data, gs_effect_t *effect) { struct image_source *context = data; - if (!context->image.texture) + if (!context->if2.image.texture) return; gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), - context->image.texture); - gs_draw_sprite(context->image.texture, 0, - context->image.cx, context->image.cy); + context->if2.image.texture); + gs_draw_sprite(context->if2.image.texture, 0, + context->if2.image.cx, context->if2.image.cy); } static void image_source_tick(void *data, float seconds) @@ -175,20 +175,20 @@ static void image_source_tick(void *data, float seconds) if (obs_source_active(context->source)) { if (!context->active) { - if (context->image.is_animated_gif) + if (context->if2.image.is_animated_gif) context->last_time = frame_time; context->active = true; } } else { if (context->active) { - if (context->image.is_animated_gif) { - context->image.cur_frame = 0; - context->image.cur_loop = 0; - context->image.cur_time = 0; + if (context->if2.image.is_animated_gif) { + context->if2.image.cur_frame = 0; + context->if2.image.cur_loop = 0; + context->if2.image.cur_time = 0; obs_enter_graphics(); - gs_image_file_update_texture(&context->image); + gs_image_file2_update_texture(&context->if2); obs_leave_graphics(); } @@ -198,13 +198,13 @@ static void image_source_tick(void *data, float seconds) return; } - if (context->last_time && context->image.is_animated_gif) { + if (context->last_time && context->if2.image.is_animated_gif) { uint64_t elapsed = frame_time - context->last_time; - bool updated = gs_image_file_tick(&context->image, elapsed); + bool updated = gs_image_file2_tick(&context->if2, elapsed); if (updated) { obs_enter_graphics(); - gs_image_file_update_texture(&context->image); + gs_image_file2_update_texture(&context->if2); obs_leave_graphics(); } } @@ -214,12 +214,14 @@ static void image_source_tick(void *data, float seconds) static const char *image_filter = - "All formats (*.bmp *.tga *.png *.jpeg *.jpg *.gif);;" + "All formats (*.bmp *.tga *.png *.jpeg *.jpg *.gif *.psd);;" "BMP Files (*.bmp);;" "Targa Files (*.tga);;" "PNG Files (*.png);;" "JPEG Files (*.jpeg *.jpg);;" - "GIF Files (*.gif)"; + "GIF Files (*.gif);;" + "PSD Files (*.psd);;" + "All Files (*.*)"; static obs_properties_t *image_source_properties(void *data) { @@ -248,6 +250,12 @@ static obs_properties_t *image_source_properties(void *data) return props; } +uint64_t image_source_get_memory_usage(void *data) +{ + struct image_source *s = data; + return s->if2.mem_usage; +} + static struct obs_source_info image_source_info = { .id = "image_source", .type = OBS_SOURCE_TYPE_INPUT, @@ -268,6 +276,10 @@ static struct obs_source_info image_source_info = { OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("image-source", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Image/color/slideshow sources"; +} extern struct obs_source_info slideshow_info; extern struct obs_source_info color_source_info; diff --git a/plugins/image-source/obs-slideshow.c b/plugins/image-source/obs-slideshow.c index e8316e9..4dc1038 100644 --- a/plugins/image-source/obs-slideshow.c +++ b/plugins/image-source/obs-slideshow.c @@ -57,6 +57,11 @@ /* ------------------------------------------------------------------------- */ +extern uint64_t image_source_get_memory_usage(void *data); + +#define BYTES_TO_MBYTES (1024 * 1024) +#define MAX_MEM_USAGE (250 * BYTES_TO_MBYTES) + struct image_file_data { char *path; obs_source_t *source; @@ -91,6 +96,7 @@ struct slideshow { uint32_t cx; uint32_t cy; + uint64_t mem_usage; pthread_mutex_t mutex; DARRAY(struct image_file_data) files; @@ -203,6 +209,9 @@ static void add_file(struct slideshow *ss, struct darray *array, if (new_cx > *cx) *cx = new_cx; if (new_cy > *cy) *cy = new_cy; + + void *source_data = obs_obj_get_data(new_source); + ss->mem_usage += image_source_get_memory_usage(source_data); } *array = new_files.da; @@ -308,6 +317,8 @@ static void ss_update(void *data, obs_data_t *settings) /* ------------------------------------- */ /* create new list of sources */ + ss->mem_usage = 0; + for (size_t i = 0; i < count; i++) { obs_data_t *item = obs_data_array_item(array, i); const char *path = obs_data_get_string(item, "value"); @@ -335,6 +346,9 @@ static void ss_update(void *data, obs_data_t *settings) dstr_cat(&dir_path, ent->d_name); add_file(ss, &new_files.da, dir_path.array, &cx, &cy); + + if (ss->mem_usage >= MAX_MEM_USAGE) + break; } dstr_free(&dir_path); @@ -344,6 +358,9 @@ static void ss_update(void *data, obs_data_t *settings) } obs_data_release(item); + + if (ss->mem_usage >= MAX_MEM_USAGE) + break; } /* ------------------------------------- */ @@ -358,10 +375,15 @@ static void ss_update(void *data, obs_data_t *settings) ss->transition = new_tr; } - if (new_duration < 50) - new_duration = 50; - if (new_speed > (new_duration - 50)) - new_speed = new_duration - 50; + if (strcmp(tr_name, "cut_transition") != 0) { + if (new_duration < 100) + new_duration = 100; + + new_duration += new_speed; + } else { + if (new_duration < 50) + new_duration = 50; + } ss->tr_speed = new_speed; ss->tr_name = tr_name; @@ -475,7 +497,7 @@ static void ss_next_slide(void *data) { struct slideshow *ss = data; - if (!ss->files.num) + if (!ss->files.num || obs_transition_get_time(ss->transition) < 1.0f) return; if (++ss->cur_item >= ss->files.num) @@ -488,7 +510,7 @@ static void ss_previous_slide(void *data) { struct slideshow *ss = data; - if (!ss->files.num) + if (!ss->files.num || obs_transition_get_time(ss->transition) < 1.0f) return; if (ss->cur_item == 0) diff --git a/plugins/linux-alsa/data/locale/da-DK.ini b/plugins/linux-alsa/data/locale/da-DK.ini index 40fe514..0e2e8c4 100644 --- a/plugins/linux-alsa/data/locale/da-DK.ini +++ b/plugins/linux-alsa/data/locale/da-DK.ini @@ -1,3 +1,3 @@ -AlsaInput="Lyd-optagelsesenhed (ALSA)" +AlsaInput="Lydoptagelsesenhed (ALSA)" Device="Enhed" diff --git a/plugins/linux-alsa/data/locale/eu-ES.ini b/plugins/linux-alsa/data/locale/eu-ES.ini index 9c5f61c..8321130 100644 --- a/plugins/linux-alsa/data/locale/eu-ES.ini +++ b/plugins/linux-alsa/data/locale/eu-ES.ini @@ -1,3 +1,3 @@ -AlsaInput="Audio kapturako gailua (ALSA)" +AlsaInput="Audioa kapturatzeko gailua (ALSA)" Device="Gailua" diff --git a/plugins/linux-alsa/data/locale/fa-IR.ini b/plugins/linux-alsa/data/locale/fa-IR.ini new file mode 100644 index 0000000..944ac80 --- /dev/null +++ b/plugins/linux-alsa/data/locale/fa-IR.ini @@ -0,0 +1,3 @@ +AlsaInput="دستگاه ضبط صدا (ALSA)" +Device="دستگاه" + diff --git a/plugins/linux-alsa/linux-alsa.c b/plugins/linux-alsa/linux-alsa.c index b0cad0c..73635b1 100644 --- a/plugins/linux-alsa/linux-alsa.c +++ b/plugins/linux-alsa/linux-alsa.c @@ -18,6 +18,10 @@ along with this program. If not, see . OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("linux-alsa", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Linux ALSA audio input capture"; +} extern struct obs_source_info alsa_input_capture; diff --git a/plugins/linux-capture/CMakeLists.txt b/plugins/linux-capture/CMakeLists.txt index d4f1649..7080346 100644 --- a/plugins/linux-capture/CMakeLists.txt +++ b/plugins/linux-capture/CMakeLists.txt @@ -6,7 +6,7 @@ if(NOT X11_Xcomposite_FOUND) return() endif() -find_package(XCB COMPONENTS XCB SHM XFIXES XINERAMA REQUIRED) +find_package(XCB COMPONENTS XCB RANDR SHM XFIXES XINERAMA REQUIRED) find_package(X11_XCB REQUIRED) include_directories(SYSTEM diff --git a/plugins/linux-capture/data/locale/da-DK.ini b/plugins/linux-capture/data/locale/da-DK.ini index b1b3df3..303ab88 100644 --- a/plugins/linux-capture/data/locale/da-DK.ini +++ b/plugins/linux-capture/data/locale/da-DK.ini @@ -11,6 +11,6 @@ CropRight="Beskær højre (pixels)" CropBottom="Beskær bund (pixels)" SwapRedBlue="Ombyt rød og blå" LockX="Lås X server under optagelse" -IncludeXBorder="Inkluder X-kant" +IncludeXBorder="Inkludér X-kant" ExcludeAlpha="Benyt alpha-fri teksturformat (Mesa løsning)" diff --git a/plugins/linux-capture/data/locale/de-DE.ini b/plugins/linux-capture/data/locale/de-DE.ini index e879a93..e72024c 100644 --- a/plugins/linux-capture/data/locale/de-DE.ini +++ b/plugins/linux-capture/data/locale/de-DE.ini @@ -2,7 +2,7 @@ X11SharedMemoryScreenInput="Bildschirmaufnahme (XSHM)" Screen="Bildschirm" CaptureCursor="Mauszeiger aufnehmen" AdvancedSettings="Erweiterte Einstellungen" -XServer="X Server" +XServer="X-Server" XCCapture="Fensteraufnahme (Xcomposite)" Window="Fenster" CropTop="Oben abschneiden (Pixel)" @@ -10,7 +10,7 @@ CropLeft="Links abschneiden (Pixel)" CropRight="Rechts abschneiden (Pixel)" CropBottom="Unten abschneiden (Pixel)" SwapRedBlue="Rot und Blau tauschen" -LockX="X Server sperren während der Aufnahme" -IncludeXBorder="X Rahmen anzeigen" -ExcludeAlpha="Verwenden von alphalosem Texturformat (Mesa Problemumgehung)" +LockX="X-Server während der Aufnahme sperren" +IncludeXBorder="X-Rahmen anzeigen" +ExcludeAlpha="Alphaloses Texturformat verwenden (Mesa-Problemumgehung)" diff --git a/plugins/linux-capture/data/locale/fa-IR.ini b/plugins/linux-capture/data/locale/fa-IR.ini new file mode 100644 index 0000000..d6ed785 --- /dev/null +++ b/plugins/linux-capture/data/locale/fa-IR.ini @@ -0,0 +1,15 @@ +X11SharedMemoryScreenInput="صفحه نمایش ضبط (XSHM)" +Screen="صفحه نمایش" +CaptureCursor="گرفتن مکان نما" +AdvancedSettings="تنظیمات پیشرفته" +XServer="سرویس دهنده" +XCCapture="ضبط پنجره (Xcomposite)" +Window="ویندوز" +CropTop="برش بالا (پیکسل)" +CropLeft="برش چپ (پیکسل)" +CropRight="برش راست (پیکسل)" +CropBottom="برش پایین (پیکسل)" +LockX="سرور اکس قفل هنگام گرفتن" +IncludeXBorder="شامل X مرز" +ExcludeAlpha="استفاده از فرمت های بافت آلفا کمتر (مسا حلی)" + diff --git a/plugins/linux-capture/data/locale/fr-FR.ini b/plugins/linux-capture/data/locale/fr-FR.ini index 9258fa3..910dd26 100644 --- a/plugins/linux-capture/data/locale/fr-FR.ini +++ b/plugins/linux-capture/data/locale/fr-FR.ini @@ -11,6 +11,6 @@ CropRight="Rogner à droite (pixels)" CropBottom="Rogner en bas (pixels)" SwapRedBlue="Intervertir le rouge et le bleu" LockX="Verrouiller le serveur X lors de la capture" -IncludeXBorder="Inclure la bordure de X" -ExcludeAlpha="Utiliser un format de texture sans alpha (contournement pour Mesa)" +IncludeXBorder="Inclure la bordure de la fenêtre X" +ExcludeAlpha="Utiliser un format de texture sans alpha (palliatif pour Mesa)" diff --git a/plugins/linux-capture/data/locale/it-IT.ini b/plugins/linux-capture/data/locale/it-IT.ini index a2f3307..b1f1f40 100644 --- a/plugins/linux-capture/data/locale/it-IT.ini +++ b/plugins/linux-capture/data/locale/it-IT.ini @@ -1,16 +1,16 @@ -X11SharedMemoryScreenInput="Cattura schermo (XSHM)" +X11SharedMemoryScreenInput="Cattura dello schermo (XSHM)" Screen="Schermo" CaptureCursor="Cattura il cursore" -AdvancedSettings="Configurazioni Avanzate" +AdvancedSettings="Impostazioni avanzate" XServer="X Server" -XCCapture="Cattura la finestra (xcomposite)" +XCCapture="Cattura la finestra (Xcomposite)" Window="Finestra" -CropTop="Crop Superiore (pixels)" -CropLeft="Crop Sinistro (pixels)" -CropRight="Crop Destro (pixels)" -CropBottom="Crop Inferiore (pixels)" -SwapRedBlue="Inverti rosso e blu" -LockX="Blocca l' X Server durante l'acquisizione" -IncludeXBorder="Includi X bordi" -ExcludeAlpha="Usa formato texture alfa-less (soluzione di Mesa)" +CropTop="Ritaglia dall'alto (in pixel)" +CropLeft="Ritaglia da sinistra (in pixel)" +CropRight="Ritaglia da destra (in pixel)" +CropBottom="Ritaglia dal basso (in pixel)" +SwapRedBlue="Inverti i colori rosso e blu" +LockX="Blocca X Server durante la cattura" +IncludeXBorder="Includi i bordi della finestra X" +ExcludeAlpha="Utilizza il formato alfa-less per le texture (soluzione di Mesa)" diff --git a/plugins/linux-capture/data/locale/ro-RO.ini b/plugins/linux-capture/data/locale/ro-RO.ini index 0ae7367..57a4520 100644 --- a/plugins/linux-capture/data/locale/ro-RO.ini +++ b/plugins/linux-capture/data/locale/ro-RO.ini @@ -12,5 +12,5 @@ CropBottom="Trunchiază partea inferioară (pixeli)" SwapRedBlue="Schimbă roșu cu albastru" LockX="Blochează serverul X atunci când se capturează" IncludeXBorder="Include marginea cu X" -ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare Mesa)" +ExcludeAlpha="Folosește formatul de texturi fără alpha (soluție de evitare pentru Mesa)" diff --git a/plugins/linux-capture/data/locale/sr-CS.ini b/plugins/linux-capture/data/locale/sr-CS.ini index 912e937..362aa7f 100644 --- a/plugins/linux-capture/data/locale/sr-CS.ini +++ b/plugins/linux-capture/data/locale/sr-CS.ini @@ -1,6 +1,6 @@ -X11SharedMemoryScreenInput="Ekranski ulaz (XSHM)" -Screen="Ekran" -CaptureCursor="Snimaj kursor" +X11SharedMemoryScreenInput="Snimak ekrana (XSHM)" +Screen="Екран" +CaptureCursor="Снимај курсор" AdvancedSettings="Napredna podešavanja" XServer="X server" XCCapture="Улаз са прозора (Xcomposite)" diff --git a/plugins/linux-capture/data/locale/sr-SP.ini b/plugins/linux-capture/data/locale/sr-SP.ini index 1823224..9920ed1 100644 --- a/plugins/linux-capture/data/locale/sr-SP.ini +++ b/plugins/linux-capture/data/locale/sr-SP.ini @@ -1,6 +1,6 @@ -X11SharedMemoryScreenInput="Екрански улаз (XSHM)" -Screen="Екран" -CaptureCursor="Снимај курсор" +X11SharedMemoryScreenInput="Снимак екрана (XSHM)" +Screen="Ekran" +CaptureCursor="Snimaj kursor" AdvancedSettings="Напредна подешавања" XServer="X сервер" XCCapture="Ulaz sa prozora (Xcomposite)" diff --git a/plugins/linux-capture/data/locale/sv-SE.ini b/plugins/linux-capture/data/locale/sv-SE.ini index 688168a..5fe29d2 100644 --- a/plugins/linux-capture/data/locale/sv-SE.ini +++ b/plugins/linux-capture/data/locale/sv-SE.ini @@ -1,7 +1,7 @@ X11SharedMemoryScreenInput="Bildskärmskälla (XSHM)" Screen="Skärm" CaptureCursor="Visa muspekare" -AdvancedSettings="Avancerade Inställningar" +AdvancedSettings="Avancerade inställningar" XServer="X-servern" XCCapture="Fönsterkälla (Xcomposite)" Window="Fönster" diff --git a/plugins/linux-capture/linux-capture.c b/plugins/linux-capture/linux-capture.c index ad95463..ce49ee7 100644 --- a/plugins/linux-capture/linux-capture.c +++ b/plugins/linux-capture/linux-capture.c @@ -18,6 +18,10 @@ along with this program. If not, see . OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("linux-xshm", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "xcomposite/xshm based window/screen capture for X11"; +} extern struct obs_source_info xshm_input; diff --git a/plugins/linux-capture/xcompcap-main.cpp b/plugins/linux-capture/xcompcap-main.cpp index ba7986f..bbfe2eb 100644 --- a/plugins/linux-capture/xcompcap-main.cpp +++ b/plugins/linux-capture/xcompcap-main.cpp @@ -148,6 +148,7 @@ struct XCompcapMain_private bool lockX; bool include_border; bool exclude_alpha; + bool draw_opaque; double window_check_time = 0.0; @@ -251,6 +252,9 @@ static void xcc_cleanup(XCompcapMain_private *p) XDisplayLock xlock; if (p->gltex) { + GLuint gltex = *(GLuint*)gs_texture_get_obj(p->gltex); + glBindTexture(GL_TEXTURE_2D, gltex); + glXReleaseTexImageEXT(xdisp, p->glxpixmap, GLX_FRONT_LEFT_EXT); gs_texture_destroy(p->gltex); p->gltex = 0; } @@ -301,6 +305,7 @@ void XCompcapMain::updateSettings(obs_data_t *settings) p->show_cursor = obs_data_get_bool(settings, "show_cursor"); p->include_border = obs_data_get_bool(settings, "include_border"); p->exclude_alpha = obs_data_get_bool(settings, "exclude_alpha"); + p->draw_opaque = false; } else { p->win = prevWin; } @@ -347,6 +352,90 @@ void XCompcapMain::updateSettings(obs_data_t *settings) cf = GS_BGRX; } + bool has_alpha = true; + + const int attrs[] = + { + GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, + GLX_ALPHA_SIZE, 8, + GLX_DOUBLEBUFFER, GL_FALSE, + None + }; + + int nelem = 0; + GLXFBConfig *configs = glXGetFBConfigs(xdisp, + XCompcap::getRootWindowScreen(attr.root), + &nelem); + + if (nelem <= 0) { + blog(LOG_ERROR, "no fb configs available"); + p->win = 0; + p->height = 0; + p->width = 0; + return; + } + + GLXFBConfig config; + for (int i = 0; i < nelem; i++) { + config = configs[i]; + XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config); + if (!visual) + continue; + + if (attr.visual->visualid != visual->visualid) { + XFree(visual); + continue; + } + XFree(visual); + + int value; + glXGetFBConfigAttrib(xdisp, config, GLX_ALPHA_SIZE, &value); + if (value != 8) + has_alpha = false; + + break; + } + + XFree(configs); + configs = glXChooseFBConfig(xdisp, + XCompcap::getRootWindowScreen(attr.root), + attrs, &nelem); + + if (nelem <= 0) { + blog(LOG_ERROR, "no matching fb config found"); + p->win = 0; + p->height = 0; + p->width = 0; + return; + } + bool found = false; + for (int i = 0; i < nelem; i++) { + config = configs[i]; + XVisualInfo *visual = glXGetVisualFromFBConfig(xdisp, config); + if (!visual) + continue; + + if (attr.depth != visual->depth) { + XFree(visual); + continue; + } + XFree(visual); + found = true; + break; + } + if (!found) + config = configs[0]; + + if (cf == GS_BGRX || !has_alpha) { + p->draw_opaque = true; + } + + int inverted; + glXGetFBConfigAttrib(xdisp, config, GLX_Y_INVERTED_EXT, &inverted); + p->inverted = inverted != 0; + p->border = attr.border_width; if (p->include_border) { @@ -395,32 +484,6 @@ void XCompcapMain::updateSettings(obs_data_t *settings) glBindTexture(GL_TEXTURE_2D, 0); } - const int attrs[] = - { - GLX_BIND_TO_TEXTURE_RGBA_EXT, GL_TRUE, - GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, - GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, - GLX_ALPHA_SIZE, 8, - GLX_DOUBLEBUFFER, GL_FALSE, - None - }; - - int nelem = 0; - GLXFBConfig* configs = glXChooseFBConfig(xdisp, - XCompcap::getRootWindowScreen(attr.root), - attrs, &nelem); - - if (nelem <= 0) { - blog(LOG_ERROR, "no matching fb config found"); - p->win = 0; - p->height = 0; - p->width = 0; - return; - } - - glXGetFBConfigAttrib(xdisp, configs[0], GLX_Y_INVERTED_EXT, &nelem); - p->inverted = nelem != 0; - xlock.resetError(); p->pixmap = XCompositeNameWindowPixmap(xdisp, p->win); @@ -433,14 +496,23 @@ void XCompcapMain::updateSettings(obs_data_t *settings) return; } - const int attribs[] = + const int attribs_alpha[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; - p->glxpixmap = glXCreatePixmap(xdisp, configs[0], p->pixmap, attribs); + const int attribs_no_alpha[] = + { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, + None + }; + + const int *attribs = cf == GS_RGBA ? attribs_alpha : attribs_no_alpha; + + p->glxpixmap = glXCreatePixmap(xdisp, config, p->pixmap, attribs); if (xlock.gotError()) { blog(LOG_ERROR, "glXCreatePixmap failed: %s", @@ -466,10 +538,14 @@ void XCompcapMain::updateSettings(obs_data_t *settings) if (!p->windowName.empty()) { blog(LOG_INFO, "[window-capture: '%s'] update settings:\n" "\ttitle: %s\n" - "\tclass: %s", + "\tclass: %s\n" + "\tHas alpha: %s\n" + "\tFound proper GLXFBConfig: %s\n", obs_source_get_name(p->source), XCompcap::getWindowName(p->win).c_str(), - XCompcap::getWindowClass(p->win).c_str()); + XCompcap::getWindowClass(p->win).c_str(), + has_alpha ? "yes" : "no", + found ? "yes" : "no"); blog(LOG_DEBUG, "\n" "\tid: %s", std::to_string((long long)p->win).c_str()); @@ -563,7 +639,10 @@ void XCompcapMain::render(gs_effect_t *effect) PLock lock(&p->lock, true); - effect = obs_get_base_effect(OBS_EFFECT_OPAQUE); + if (p->draw_opaque) + effect = obs_get_base_effect(OBS_EFFECT_OPAQUE); + else + effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); if (!lock.isLocked() || !p->tex) return; diff --git a/plugins/linux-capture/xhelpers.c b/plugins/linux-capture/xhelpers.c index 1eeda7c..724f4f3 100644 --- a/plugins/linux-capture/xhelpers.c +++ b/plugins/linux-capture/xhelpers.c @@ -17,6 +17,7 @@ along with this program. If not, see . #include #include +#include #include #include @@ -95,6 +96,78 @@ fail: return -1; } +bool randr_is_active(xcb_connection_t *xcb) +{ + if (!xcb || !xcb_get_extension_data(xcb, &xcb_randr_id)->present) + return false; + + return true; +} + +int randr_screen_count(xcb_connection_t *xcb) +{ + if (!xcb) + return 0; + + xcb_screen_t *screen; + screen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; + + xcb_randr_get_screen_resources_cookie_t res_c; + xcb_randr_get_screen_resources_reply_t* res_r; + + res_c = xcb_randr_get_screen_resources(xcb, screen->root); + res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0); + if (!res_r) + return 0; + + return xcb_randr_get_screen_resources_crtcs_length(res_r); +} + +int randr_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *x, int_fast32_t *y, + int_fast32_t *w, int_fast32_t *h, + xcb_screen_t **rscreen) +{ + xcb_screen_t *xscreen; + xscreen = xcb_setup_roots_iterator(xcb_get_setup(xcb)).data; + + xcb_randr_get_screen_resources_cookie_t res_c; + xcb_randr_get_screen_resources_reply_t* res_r; + + res_c = xcb_randr_get_screen_resources(xcb, xscreen->root); + res_r = xcb_randr_get_screen_resources_reply(xcb, res_c, 0); + if (!res_r) + goto fail; + + int screens = xcb_randr_get_screen_resources_crtcs_length(res_r); + if (screen < 0 || screen >= screens) + goto fail; + + xcb_randr_crtc_t *crtc = xcb_randr_get_screen_resources_crtcs(res_r); + + xcb_randr_get_crtc_info_cookie_t crtc_c; + xcb_randr_get_crtc_info_reply_t *crtc_r; + + crtc_c = xcb_randr_get_crtc_info(xcb, *(crtc + screen), 0); + crtc_r = xcb_randr_get_crtc_info_reply(xcb, crtc_c, 0); + if (!crtc_r) + goto fail; + + *x = crtc_r->x; + *y = crtc_r->y; + *w = crtc_r->width; + *h = crtc_r->height; + + if (rscreen) + *rscreen = xscreen; + + return 0; + +fail: + *x = *y = *w = *h = 0; + return -1; +} + int x11_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, int_fast32_t *w, int_fast32_t *h) { diff --git a/plugins/linux-capture/xhelpers.h b/plugins/linux-capture/xhelpers.h index 066684f..95aff5c 100644 --- a/plugins/linux-capture/xhelpers.h +++ b/plugins/linux-capture/xhelpers.h @@ -64,6 +64,39 @@ int xinerama_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, int_fast32_t *x, int_fast32_t *y, int_fast32_t *w, int_fast32_t *h); +/** + * Check for Randr extension + * + * @return true if randr is available which means it's active. + */ +bool randr_is_active(xcb_connection_t *xcb); + +/** + * Get the number of Randr screens + * + * @return number of screens + */ +int randr_screen_count(xcb_connection_t *xcb); + +/** + * Get screen geometry for a Rand crtc (screen) + * + * @note On error the passed coordinates/sizes will be set to 0. + * + * @param xcb xcb connection + * @param screen screen number to get geometry for + * @param x x-coordinate of the screen + * @param y y-coordinate of the screen + * @param w width of the screen + * @param h height of the screen + * + * @return < 0 on error + */ +int randr_screen_geo(xcb_connection_t *xcb, int_fast32_t screen, + int_fast32_t *x, int_fast32_t *y, + int_fast32_t *w, int_fast32_t *h, + xcb_screen_t **rscreen); + /** * Get screen geometry for a X11 screen * diff --git a/plugins/linux-capture/xshm-input.c b/plugins/linux-capture/xshm-input.c index b5fa3a3..f00c0eb 100644 --- a/plugins/linux-capture/xshm-input.c +++ b/plugins/linux-capture/xshm-input.c @@ -18,6 +18,7 @@ along with this program. If not, see . #include #include #include +#include #include #include #include @@ -50,6 +51,7 @@ struct xshm_data { bool show_cursor; bool use_xinerama; + bool use_randr; bool advanced; }; @@ -83,6 +85,9 @@ static bool xshm_check_extensions(xcb_connection_t *xcb) if (!xcb_get_extension_data(xcb, &xcb_xinerama_id)->present) blog(LOG_INFO, "Missing Xinerama extension !"); + if (!xcb_get_extension_data(xcb, &xcb_randr_id)->present) + blog(LOG_INFO, "Missing Randr extension !"); + return ok; } @@ -96,7 +101,15 @@ static int_fast32_t xshm_update_geometry(struct xshm_data *data) int_fast32_t old_width = data->width; int_fast32_t old_height = data->height; - if (data->use_xinerama) { + if (data->use_randr) { + if (randr_screen_geo(data->xcb, data->screen_id, + &data->x_org, &data->y_org, + &data->width, &data->height, + &data->xcb_screen) < 0) { + return -1; + } + } + else if (data->use_xinerama) { if (xinerama_screen_geo(data->xcb, data->screen_id, &data->x_org, &data->y_org, &data->width, &data->height) < 0) { @@ -189,6 +202,7 @@ static void xshm_capture_start(struct xshm_data *data) if (!xshm_check_extensions(data->xcb)) goto fail; + data->use_randr = randr_is_active(data->xcb) ? true : false; data->use_xinerama = xinerama_is_active(data->xcb) ? true : false; if (xshm_update_geometry(data) < 0) { @@ -287,16 +301,21 @@ static bool xshm_server_changed(obs_properties_t *props, struct dstr screen_info; dstr_init(&screen_info); + bool randr = randr_is_active(xcb); bool xinerama = xinerama_is_active(xcb); - int_fast32_t count = (xinerama) ? - xinerama_screen_count(xcb) : - xcb_setup_roots_length(xcb_get_setup(xcb)); + int_fast32_t count = (randr) ? + randr_screen_count(xcb) : + (xinerama) ? + xinerama_screen_count(xcb) : + xcb_setup_roots_length(xcb_get_setup(xcb)); for (int_fast32_t i = 0; i < count; ++i) { int_fast32_t x, y, w, h; x = y = w = h = 0; - if (xinerama) + if (randr) + randr_screen_geo(xcb, i, &x, &y, &w, &h, NULL); + else if (xinerama) xinerama_screen_geo(xcb, i, &x, &y, &w, &h); else x11_screen_geo(xcb, i, &w, &h); diff --git a/plugins/linux-jack/data/locale/da-DK.ini b/plugins/linux-jack/data/locale/da-DK.ini index 0ac0563..ca3411b 100644 --- a/plugins/linux-jack/data/locale/da-DK.ini +++ b/plugins/linux-jack/data/locale/da-DK.ini @@ -1,4 +1,4 @@ -StartJACKServer="Start JACK server" -Channels="Antal af kanaler" -JACKInput="JACK input klient" +StartJACKServer="Start JACK Server" +Channels="Antal kanaler" +JACKInput="JACK Input Client" diff --git a/plugins/linux-jack/data/locale/de-DE.ini b/plugins/linux-jack/data/locale/de-DE.ini index 38c656d..2c222bb 100644 --- a/plugins/linux-jack/data/locale/de-DE.ini +++ b/plugins/linux-jack/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -StartJACKServer="JACK Server starten" +StartJACKServer="JACK-Server starten" Channels="Anzahl der Kanäle" -JACKInput="JACK-Eingang-Client" +JACKInput="JACK-Eingabe-Client" diff --git a/plugins/linux-jack/data/locale/fa-IR.ini b/plugins/linux-jack/data/locale/fa-IR.ini new file mode 100644 index 0000000..88f791d --- /dev/null +++ b/plugins/linux-jack/data/locale/fa-IR.ini @@ -0,0 +1,3 @@ +StartJACKServer="شروع JACK سرور" +Channels="تعداد کانال" + diff --git a/plugins/linux-jack/data/locale/it-IT.ini b/plugins/linux-jack/data/locale/it-IT.ini index 6f73b82..3edd86a 100644 --- a/plugins/linux-jack/data/locale/it-IT.ini +++ b/plugins/linux-jack/data/locale/it-IT.ini @@ -1,4 +1,4 @@ -StartJACKServer="Avvia il Server JACK" +StartJACKServer="Avvia il server JACK" Channels="Numero dei canali" -JACKInput="Ingresso JACK Client" +JACKInput="Ingresso del client JACK" diff --git a/plugins/linux-jack/data/locale/ur-PK.ini b/plugins/linux-jack/data/locale/ur-PK.ini new file mode 100644 index 0000000..3f12b3c --- /dev/null +++ b/plugins/linux-jack/data/locale/ur-PK.ini @@ -0,0 +1,4 @@ +StartJACKServer="جیک کا آغاز" +Channels="چینلز کی تعداد" +JACKInput="وصول کار جیک ان پٹ" + diff --git a/plugins/linux-jack/jack-wrapper.c b/plugins/linux-jack/jack-wrapper.c index 63309cc..98fa132 100644 --- a/plugins/linux-jack/jack-wrapper.c +++ b/plugins/linux-jack/jack-wrapper.c @@ -103,7 +103,7 @@ int_fast32_t jack_init(struct jack_data* data) sizeof(jack_port_t*) * data->channels); for (unsigned int i = 0; i < data->channels; ++i) { char port_name[10] = {'\0'}; - snprintf(port_name, sizeof(port_name), "in_%d", i+1); + snprintf(port_name, sizeof(port_name), "in_%u", i+1); data->jack_ports[i] = jack_port_register(data->jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); diff --git a/plugins/linux-jack/linux-jack.c b/plugins/linux-jack/linux-jack.c index 349a205..be6721d 100644 --- a/plugins/linux-jack/linux-jack.c +++ b/plugins/linux-jack/linux-jack.c @@ -18,6 +18,10 @@ along with this program. If not, see . OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("linux-jack", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "JACK Audio Connection Kit output capture"; +} extern struct obs_source_info jack_output_capture; diff --git a/plugins/linux-pulseaudio/data/locale/da-DK.ini b/plugins/linux-pulseaudio/data/locale/da-DK.ini index ba09e5a..ac28123 100644 --- a/plugins/linux-pulseaudio/data/locale/da-DK.ini +++ b/plugins/linux-pulseaudio/data/locale/da-DK.ini @@ -1,4 +1,4 @@ -PulseInput="Indfang lyd ind (PulseAudio)" -PulseOutput="Indfang lyd Ud (PulseAudio)" +PulseInput="Lydinputoptagelse (PulseAudio)" +PulseOutput="Lydoutputoptagelse (PulseAudio)" Device="Enhed" diff --git a/plugins/linux-pulseaudio/data/locale/de-DE.ini b/plugins/linux-pulseaudio/data/locale/de-DE.ini index 8f28f83..e05d55d 100644 --- a/plugins/linux-pulseaudio/data/locale/de-DE.ini +++ b/plugins/linux-pulseaudio/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -PulseInput="Audio Eingabe Aufnahme (PulseAudio)" -PulseOutput="Audio Ausgabe Aufnahme (PulseAudio)" +PulseInput="Audioeingabeaufnahme (PulseAudio)" +PulseOutput="Audioausgabeaufnahme (PulseAudio)" Device="Gerät" diff --git a/plugins/linux-pulseaudio/data/locale/fa-IR.ini b/plugins/linux-pulseaudio/data/locale/fa-IR.ini new file mode 100644 index 0000000..72535e1 --- /dev/null +++ b/plugins/linux-pulseaudio/data/locale/fa-IR.ini @@ -0,0 +1,4 @@ +PulseInput="ضبط صوت داخلی (PulseAudio)" +PulseOutput="ضبط صوت خروجی (PulseAudio)" +Device="دستگاه" + diff --git a/plugins/linux-pulseaudio/data/locale/fr-FR.ini b/plugins/linux-pulseaudio/data/locale/fr-FR.ini index 152b52a..125f38b 100644 --- a/plugins/linux-pulseaudio/data/locale/fr-FR.ini +++ b/plugins/linux-pulseaudio/data/locale/fr-FR.ini @@ -1,4 +1,4 @@ -PulseInput="Capture de l'audio entrant (PulseAudio)" -PulseOutput="Capture de l'audio sortant (PulseAudio)" +PulseInput="Capture Audio (Entrée PulseAudio)" +PulseOutput="Capture Audio (Sorties PulseAudio)" Device="Périphérique" diff --git a/plugins/linux-pulseaudio/data/locale/it-IT.ini b/plugins/linux-pulseaudio/data/locale/it-IT.ini index 672ed38..e10bac9 100644 --- a/plugins/linux-pulseaudio/data/locale/it-IT.ini +++ b/plugins/linux-pulseaudio/data/locale/it-IT.ini @@ -1,4 +1,4 @@ -PulseInput="Input di acquisizione audio (PulseAudio)" -PulseOutput="Output acquisizione audio (PulseAudio)" +PulseInput="Ingresso di acquisizione audio (PulseAudio)" +PulseOutput="Uscita di acquisizione audio (PulseAudio)" Device="Dispositivo" diff --git a/plugins/linux-pulseaudio/data/locale/ka-GE.ini b/plugins/linux-pulseaudio/data/locale/ka-GE.ini index 78a0453..e36f439 100644 --- a/plugins/linux-pulseaudio/data/locale/ka-GE.ini +++ b/plugins/linux-pulseaudio/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ PulseInput="შემავალი ხმოვანი სიგნალის ჩაწერა (PulseAudio)" -PulseOutput="გამომავალი ხმოვანი სიგნალის ჩაწერა (PulseAudio)" +PulseOutput="გამოტანილი ხმის ჩაწერა (PulseAudio)" Device="მოწყობილობა" diff --git a/plugins/linux-pulseaudio/linux-pulseaudio.c b/plugins/linux-pulseaudio/linux-pulseaudio.c index acfd10e..78f066e 100644 --- a/plugins/linux-pulseaudio/linux-pulseaudio.c +++ b/plugins/linux-pulseaudio/linux-pulseaudio.c @@ -18,6 +18,10 @@ along with this program. If not, see . OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("linux-pulseaudio", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Linux PulseAudio input/output capture"; +} extern struct obs_source_info pulse_input_capture; extern struct obs_source_info pulse_output_capture; diff --git a/plugins/linux-v4l2/data/locale/ar-SA.ini b/plugins/linux-v4l2/data/locale/ar-SA.ini index 988037c..034bfe3 100644 --- a/plugins/linux-v4l2/data/locale/ar-SA.ini +++ b/plugins/linux-v4l2/data/locale/ar-SA.ini @@ -5,4 +5,7 @@ VideoStandard="معيار الفيديو" DVTiming="توقيت DV" Resolution="الأبعاد" FrameRate="الإطار" +ColorRange="نطاق اللون" +ColorRange.Partial="جزئي" +ColorRange.Full="كامل" diff --git a/plugins/linux-v4l2/data/locale/ca-ES.ini b/plugins/linux-v4l2/data/locale/ca-ES.ini index ed9f9d2..4a01274 100644 --- a/plugins/linux-v4l2/data/locale/ca-ES.ini +++ b/plugins/linux-v4l2/data/locale/ca-ES.ini @@ -8,4 +8,7 @@ Resolution="Resolució" FrameRate="Fotogrames per segon" LeaveUnchanged="No ho canviïs" UseBuffering="Usa memòria intermèdia" +ColorRange="Gamma de colors" +ColorRange.Partial="Parcial" +ColorRange.Full="Complet" diff --git a/plugins/linux-v4l2/data/locale/cs-CZ.ini b/plugins/linux-v4l2/data/locale/cs-CZ.ini index ad33b44..56488ab 100644 --- a/plugins/linux-v4l2/data/locale/cs-CZ.ini +++ b/plugins/linux-v4l2/data/locale/cs-CZ.ini @@ -8,4 +8,7 @@ Resolution="Rozlišení" FrameRate="Snímkovací frekvence" LeaveUnchanged="Ponechat nezměněné" UseBuffering="Použít vyrovnávací paměť" +ColorRange="Rozsah barev" +ColorRange.Partial="Částečný" +ColorRange.Full="Plný" diff --git a/plugins/linux-v4l2/data/locale/da-DK.ini b/plugins/linux-v4l2/data/locale/da-DK.ini index d3c94e4..75755b6 100644 --- a/plugins/linux-v4l2/data/locale/da-DK.ini +++ b/plugins/linux-v4l2/data/locale/da-DK.ini @@ -1,11 +1,14 @@ -V4L2Input="Video optagelses enhed (V4L2)" +V4L2Input="Videooptageenhed (V4L2)" Device="Enhed" Input="Input" -VideoFormat="Video format" -VideoStandard="Video standard" -DVTiming="DV timing" +VideoFormat="Videoformat" +VideoStandard="Videostandard" +DVTiming="DV-timing" Resolution="Opløsning" -FrameRate="Framerate" -LeaveUnchanged="Efterlad uændret" -UseBuffering="Brug buffering" +FrameRate="Billedhastighed" +LeaveUnchanged="Behold uændret" +UseBuffering="Benyt buffering" +ColorRange="Farveområde" +ColorRange.Partial="Delvist" +ColorRange.Full="Fuldt" diff --git a/plugins/linux-v4l2/data/locale/de-DE.ini b/plugins/linux-v4l2/data/locale/de-DE.ini index 03d3d56..f2f6fc2 100644 --- a/plugins/linux-v4l2/data/locale/de-DE.ini +++ b/plugins/linux-v4l2/data/locale/de-DE.ini @@ -7,5 +7,8 @@ DVTiming="DV-Timing" Resolution="Auflösung" FrameRate="Bildrate" LeaveUnchanged="Unverändert lassen" -UseBuffering="Buffering benutzen" +UseBuffering="Puffern benutzen" +ColorRange="Farbbereich" +ColorRange.Partial="Begrenzt" +ColorRange.Full="Voll" diff --git a/plugins/linux-v4l2/data/locale/en-US.ini b/plugins/linux-v4l2/data/locale/en-US.ini index bdb93b0..7a001c2 100644 --- a/plugins/linux-v4l2/data/locale/en-US.ini +++ b/plugins/linux-v4l2/data/locale/en-US.ini @@ -8,3 +8,6 @@ Resolution="Resolution" FrameRate="Frame Rate" LeaveUnchanged="Leave Unchanged" UseBuffering="Use Buffering" +ColorRange="Color Range" +ColorRange.Partial="Partial" +ColorRange.Full="Full" diff --git a/plugins/linux-v4l2/data/locale/es-ES.ini b/plugins/linux-v4l2/data/locale/es-ES.ini index e7e0e7e..38dbadc 100644 --- a/plugins/linux-v4l2/data/locale/es-ES.ini +++ b/plugins/linux-v4l2/data/locale/es-ES.ini @@ -8,4 +8,7 @@ Resolution="Resolución" FrameRate="Frecuencia de imágenes" LeaveUnchanged="Dejar sin cambios" UseBuffering="Utilizar el almacenamiento en búfer" +ColorRange="Gama de Colores" +ColorRange.Partial="Parcial" +ColorRange.Full="Completo" diff --git a/plugins/linux-v4l2/data/locale/eu-ES.ini b/plugins/linux-v4l2/data/locale/eu-ES.ini index 3769275..e3f7bd0 100644 --- a/plugins/linux-v4l2/data/locale/eu-ES.ini +++ b/plugins/linux-v4l2/data/locale/eu-ES.ini @@ -8,4 +8,7 @@ Resolution="Bereizmena" FrameRate="Fotograma emaria" LeaveUnchanged="Utzi aldatu gabe" UseBuffering="Erabili bufferreratzea" +ColorRange="Kolore tartea" +ColorRange.Partial="Partziala" +ColorRange.Full="Osoa" diff --git a/plugins/linux-v4l2/data/locale/fa-IR.ini b/plugins/linux-v4l2/data/locale/fa-IR.ini new file mode 100644 index 0000000..639ebc8 --- /dev/null +++ b/plugins/linux-v4l2/data/locale/fa-IR.ini @@ -0,0 +1,14 @@ +V4L2Input="دستگاه ضبط ویدئویی (V4L2)" +Device="دستگاه" +Input="ورودی" +VideoFormat="فرمت های تصویری" +VideoStandard="استاندارد های تصویری" +DVTiming="زمان بندی دی وی" +Resolution="اندازه تصویر" +FrameRate="نرخ فریم" +LeaveUnchanged="ترک بدون تغییر" +UseBuffering="استفاده از بافرینگ" +ColorRange="طیف رنگ" +ColorRange.Partial="جزئی" +ColorRange.Full="کامل" + diff --git a/plugins/linux-v4l2/data/locale/fi-FI.ini b/plugins/linux-v4l2/data/locale/fi-FI.ini index 28279a9..14795ed 100644 --- a/plugins/linux-v4l2/data/locale/fi-FI.ini +++ b/plugins/linux-v4l2/data/locale/fi-FI.ini @@ -8,4 +8,7 @@ Resolution="Tarkkuus" FrameRate="Kuvanopeus" LeaveUnchanged="Jätä ennalleen" UseBuffering="Käytä puskurointia" +ColorRange="Värialue" +ColorRange.Partial="Osittainen" +ColorRange.Full="Täysi" diff --git a/plugins/linux-v4l2/data/locale/fr-FR.ini b/plugins/linux-v4l2/data/locale/fr-FR.ini index 52d4e6f..367e885 100644 --- a/plugins/linux-v4l2/data/locale/fr-FR.ini +++ b/plugins/linux-v4l2/data/locale/fr-FR.ini @@ -5,7 +5,10 @@ VideoFormat="Format vidéo" VideoStandard="Standard vidéo" DVTiming="Timing DV" Resolution="Résolution" -FrameRate="Fréquence d'image" +FrameRate="Images par seconde" LeaveUnchanged="Annuler les modifications" -UseBuffering="Utiliser la mise en mémoire tampon" +UseBuffering="Utiliser le tampon mémoire" +ColorRange="Gamme de couleurs" +ColorRange.Partial="Partielle" +ColorRange.Full="Complète" diff --git a/plugins/linux-v4l2/data/locale/hu-HU.ini b/plugins/linux-v4l2/data/locale/hu-HU.ini index 1f2db15..85b6e79 100644 --- a/plugins/linux-v4l2/data/locale/hu-HU.ini +++ b/plugins/linux-v4l2/data/locale/hu-HU.ini @@ -8,4 +8,7 @@ Resolution="Felbontás" FrameRate="Képkockasebesség" LeaveUnchanged="Változatlanul hagyni" UseBuffering="Pufferelés használata" +ColorRange="Színtartomány" +ColorRange.Partial="Részleges" +ColorRange.Full="Teljes" diff --git a/plugins/linux-v4l2/data/locale/it-IT.ini b/plugins/linux-v4l2/data/locale/it-IT.ini index a8723b7..eac5c7a 100644 --- a/plugins/linux-v4l2/data/locale/it-IT.ini +++ b/plugins/linux-v4l2/data/locale/it-IT.ini @@ -1,11 +1,14 @@ V4L2Input="Dispositivo di acquisizione video (V4L2)" Device="Dispositivo" -Input="Input" -VideoFormat="Formato Video" -VideoStandard="Video Standard" -DVTiming="DV Timing" +Input="Ingresso" +VideoFormat="Formato video" +VideoStandard="Standard video" +DVTiming="Timing DV" Resolution="Risoluzione" -FrameRate="Frame Rate" +FrameRate="Velocità dei fotogrammi" LeaveUnchanged="Lascia invariato" -UseBuffering="Usa Buffer" +UseBuffering="Utilizza il buffering" +ColorRange="Gamma di colori" +ColorRange.Partial="Parziale" +ColorRange.Full="Intero" diff --git a/plugins/linux-v4l2/data/locale/ja-JP.ini b/plugins/linux-v4l2/data/locale/ja-JP.ini index 847fd2c..215675f 100644 --- a/plugins/linux-v4l2/data/locale/ja-JP.ini +++ b/plugins/linux-v4l2/data/locale/ja-JP.ini @@ -8,4 +8,7 @@ Resolution="解像度" FrameRate="フレームレート" LeaveUnchanged="変更せずに戻る" UseBuffering="バッファリングを使用する" +ColorRange="色範囲" +ColorRange.Partial="一部" +ColorRange.Full="全部" diff --git a/plugins/linux-v4l2/data/locale/ka-GE.ini b/plugins/linux-v4l2/data/locale/ka-GE.ini index 4ede749..1b2e750 100644 --- a/plugins/linux-v4l2/data/locale/ka-GE.ini +++ b/plugins/linux-v4l2/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -V4L2Input="ვიდეოს ჩამწერი მოწყობილობა (V4L2)" +V4L2Input="ვიდეოს გადამღები მოწყობილობა (V4L2)" Device="მოწყობილობა" Input="შემავალი" VideoFormat="ვიდეოს ფორმატი" @@ -8,4 +8,7 @@ Resolution="გარჩევადობა" FrameRate="კადრის სიხშირე" LeaveUnchanged="უცვლელად დატოვება" UseBuffering="ბუფერიზაციის გამოყენება" +ColorRange="ფერთა გამა" +ColorRange.Partial="ნაწილობრივი" +ColorRange.Full="სრული" diff --git a/plugins/linux-v4l2/data/locale/ko-KR.ini b/plugins/linux-v4l2/data/locale/ko-KR.ini index 7554923..0e55a4d 100644 --- a/plugins/linux-v4l2/data/locale/ko-KR.ini +++ b/plugins/linux-v4l2/data/locale/ko-KR.ini @@ -8,4 +8,7 @@ Resolution="해상도" FrameRate="프레임 레이트" LeaveUnchanged="저장하지 않고 두기" UseBuffering="버퍼링 사용" +ColorRange="색상 범위" +ColorRange.Partial="부분" +ColorRange.Full="전체" diff --git a/plugins/linux-v4l2/data/locale/nb-NO.ini b/plugins/linux-v4l2/data/locale/nb-NO.ini index a0c2d89..2945c8c 100644 --- a/plugins/linux-v4l2/data/locale/nb-NO.ini +++ b/plugins/linux-v4l2/data/locale/nb-NO.ini @@ -8,4 +8,7 @@ Resolution="Oppløsning" FrameRate="Bildefrekvens" LeaveUnchanged="La stå uendret" UseBuffering="Bruk bufring" +ColorRange="Fargespekter" +ColorRange.Partial="Delvis" +ColorRange.Full="Full" diff --git a/plugins/linux-v4l2/data/locale/nl-NL.ini b/plugins/linux-v4l2/data/locale/nl-NL.ini index 4a5ab42..356e52c 100644 --- a/plugins/linux-v4l2/data/locale/nl-NL.ini +++ b/plugins/linux-v4l2/data/locale/nl-NL.ini @@ -8,4 +8,7 @@ Resolution="Resolutie" FrameRate="Frame Rate" LeaveUnchanged="Ongewijzigd Laten" UseBuffering="Buffering Gebruiken" +ColorRange="Kleurbereik" +ColorRange.Partial="Gedeeltelijk" +ColorRange.Full="Volledig" diff --git a/plugins/linux-v4l2/data/locale/pl-PL.ini b/plugins/linux-v4l2/data/locale/pl-PL.ini index ba1200b..34986ff 100644 --- a/plugins/linux-v4l2/data/locale/pl-PL.ini +++ b/plugins/linux-v4l2/data/locale/pl-PL.ini @@ -8,4 +8,7 @@ Resolution="Rozdzielczość" FrameRate="Klatki na sekundę" LeaveUnchanged="Pozostaw bez zmian" UseBuffering="Użyj buforowania" +ColorRange="Zakres kolorów" +ColorRange.Partial="Częściowy" +ColorRange.Full="Pełny" diff --git a/plugins/linux-v4l2/data/locale/pt-BR.ini b/plugins/linux-v4l2/data/locale/pt-BR.ini index 9909414..34fe477 100644 --- a/plugins/linux-v4l2/data/locale/pt-BR.ini +++ b/plugins/linux-v4l2/data/locale/pt-BR.ini @@ -8,4 +8,7 @@ Resolution="Resolução" FrameRate="Taxa de quadros" LeaveUnchanged="Deixar inalterado" UseBuffering="Utilizar Buffering" +ColorRange="Intervalo de Cor" +ColorRange.Partial="Parcial" +ColorRange.Full="Completo" diff --git a/plugins/linux-v4l2/data/locale/ro-RO.ini b/plugins/linux-v4l2/data/locale/ro-RO.ini index 77481d0..78fba1f 100644 --- a/plugins/linux-v4l2/data/locale/ro-RO.ini +++ b/plugins/linux-v4l2/data/locale/ro-RO.ini @@ -7,5 +7,5 @@ DVTiming="Sincronizare DV" Resolution="Rezoluție" FrameRate="Frecvență de cadre" LeaveUnchanged="Lasă neschimbat" -UseBuffering="Folosește buffering" +UseBuffering="Folosește zona tampon" diff --git a/plugins/linux-v4l2/data/locale/ru-RU.ini b/plugins/linux-v4l2/data/locale/ru-RU.ini index f63553c..3daf760 100644 --- a/plugins/linux-v4l2/data/locale/ru-RU.ini +++ b/plugins/linux-v4l2/data/locale/ru-RU.ini @@ -8,4 +8,7 @@ Resolution="Разрешение" FrameRate="Частота кадров" LeaveUnchanged="Оставить без изменений" UseBuffering="Использовать буферизацию" +ColorRange="Цветовой диапазон" +ColorRange.Partial="Частичный" +ColorRange.Full="Полный" diff --git a/plugins/linux-v4l2/data/locale/sk-SK.ini b/plugins/linux-v4l2/data/locale/sk-SK.ini index 02f9011..efd1878 100644 --- a/plugins/linux-v4l2/data/locale/sk-SK.ini +++ b/plugins/linux-v4l2/data/locale/sk-SK.ini @@ -8,4 +8,7 @@ Resolution="Rozlíšenie" FrameRate="Frekvencia snímok" LeaveUnchanged="Ponechať bez zmeny" UseBuffering="Použiť vyrovnávaciu pamäť" +ColorRange="Farebný rozsah" +ColorRange.Partial="Čiastočný" +ColorRange.Full="Plný" diff --git a/plugins/linux-v4l2/data/locale/sr-CS.ini b/plugins/linux-v4l2/data/locale/sr-CS.ini index 917d57f..c8cdf5e 100644 --- a/plugins/linux-v4l2/data/locale/sr-CS.ini +++ b/plugins/linux-v4l2/data/locale/sr-CS.ini @@ -1,4 +1,4 @@ -V4L2Input="Ulazni video uređaj (V4L2)" +V4L2Input="Uređaj za snimanje videa (V4L2)" Device="Uređaj" Input="Ulaz" VideoFormat="Video format" diff --git a/plugins/linux-v4l2/data/locale/sr-SP.ini b/plugins/linux-v4l2/data/locale/sr-SP.ini index c631713..de0a8be 100644 --- a/plugins/linux-v4l2/data/locale/sr-SP.ini +++ b/plugins/linux-v4l2/data/locale/sr-SP.ini @@ -1,4 +1,4 @@ -V4L2Input="Улазни видео уређај (V4L2)" +V4L2Input="Уређај за снимање видеа (V4L2)" Device="Уређај" Input="Улаз" VideoFormat="Видео формат" diff --git a/plugins/linux-v4l2/data/locale/sv-SE.ini b/plugins/linux-v4l2/data/locale/sv-SE.ini index 25b0486..4d96e71 100644 --- a/plugins/linux-v4l2/data/locale/sv-SE.ini +++ b/plugins/linux-v4l2/data/locale/sv-SE.ini @@ -8,4 +8,7 @@ Resolution="Upplösning" FrameRate="Bildhastighet" LeaveUnchanged="Lämna oförändrat" UseBuffering="Använd buffer" +ColorRange="Färgintervall" +ColorRange.Partial="Delvis" +ColorRange.Full="Full" diff --git a/plugins/linux-v4l2/data/locale/tr-TR.ini b/plugins/linux-v4l2/data/locale/tr-TR.ini index 544d6a1..ad36b52 100644 --- a/plugins/linux-v4l2/data/locale/tr-TR.ini +++ b/plugins/linux-v4l2/data/locale/tr-TR.ini @@ -8,4 +8,7 @@ Resolution="Çözünürlük" FrameRate="Kare Hızı" LeaveUnchanged="Değişmeden Bırak" UseBuffering="Arabelleğe Almayı Kullan" +ColorRange="Renk Aralığı" +ColorRange.Partial="Kısmi" +ColorRange.Full="Tam" diff --git a/plugins/linux-v4l2/data/locale/uk-UA.ini b/plugins/linux-v4l2/data/locale/uk-UA.ini index 3305e16..2e4614e 100644 --- a/plugins/linux-v4l2/data/locale/uk-UA.ini +++ b/plugins/linux-v4l2/data/locale/uk-UA.ini @@ -8,4 +8,7 @@ Resolution="Роздільна здатність" FrameRate="Частота кадрів" LeaveUnchanged="Залишити без змін" UseBuffering="Увімкнути буферизацію" +ColorRange="Колірний діапазон" +ColorRange.Partial="Частковий" +ColorRange.Full="Повний" diff --git a/plugins/linux-v4l2/data/locale/zh-CN.ini b/plugins/linux-v4l2/data/locale/zh-CN.ini index 6955936..68c0c1f 100644 --- a/plugins/linux-v4l2/data/locale/zh-CN.ini +++ b/plugins/linux-v4l2/data/locale/zh-CN.ini @@ -8,4 +8,7 @@ Resolution="分辨率" FrameRate="帧率" LeaveUnchanged="保持不变" UseBuffering="使用缓冲" +ColorRange="颜色范围" +ColorRange.Partial="部分" +ColorRange.Full="全部" diff --git a/plugins/linux-v4l2/data/locale/zh-TW.ini b/plugins/linux-v4l2/data/locale/zh-TW.ini index 66a8387..5a00fd5 100644 --- a/plugins/linux-v4l2/data/locale/zh-TW.ini +++ b/plugins/linux-v4l2/data/locale/zh-TW.ini @@ -8,4 +8,7 @@ Resolution="解析度" FrameRate="影格率" LeaveUnchanged="不改變並離開" UseBuffering="使用緩衝" +ColorRange="顏色範圍" +ColorRange.Partial="部分" +ColorRange.Full="完整" diff --git a/plugins/linux-v4l2/linux-v4l2.c b/plugins/linux-v4l2/linux-v4l2.c index 287e10c..b57deaa 100644 --- a/plugins/linux-v4l2/linux-v4l2.c +++ b/plugins/linux-v4l2/linux-v4l2.c @@ -18,6 +18,10 @@ along with this program. If not, see . OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("linux-v4l2", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Video4Linux2(V4L2) sources"; +} extern struct obs_source_info v4l2_input; diff --git a/plugins/linux-v4l2/v4l2-input.c b/plugins/linux-v4l2/v4l2-input.c index 46726ee..d3803c1 100644 --- a/plugins/linux-v4l2/v4l2-input.c +++ b/plugins/linux-v4l2/v4l2-input.c @@ -75,6 +75,7 @@ struct v4l2_data { int dv_timing; int resolution; int framerate; + int color_range; /* internal data */ obs_source_t *source; @@ -112,7 +113,7 @@ static void v4l2_prep_obs_frame(struct v4l2_data *data, frame->width = data->width; frame->height = data->height; frame->format = v4l2_to_obs_video_format(data->pixfmt); - video_format_get_parameters(VIDEO_CS_DEFAULT, VIDEO_RANGE_PARTIAL, + video_format_get_parameters(VIDEO_CS_DEFAULT, data->color_range, frame->color_matrix, frame->color_range_min, frame->color_range_max); @@ -231,6 +232,7 @@ static void v4l2_defaults(obs_data_t *settings) obs_data_set_default_int(settings, "dv_timing", -1); obs_data_set_default_int(settings, "resolution", -1); obs_data_set_default_int(settings, "framerate", -1); + obs_data_set_default_int(settings, "color_range", VIDEO_RANGE_PARTIAL); obs_data_set_default_bool(settings, "buffering", true); } @@ -329,7 +331,11 @@ static void v4l2_device_list(obs_property_t *prop, obs_data_t *settings) continue; } - obs_property_list_add_string(prop, (char *) video_cap.card, + /* make sure device names are unique */ + char unique_device_name[68]; + sprintf(unique_device_name, "%s (%s)", video_cap.card, + video_cap.bus_info); + obs_property_list_add_string(prop, unique_device_name, device.array); blog(LOG_INFO, "Found device '%s' at %s", video_cap.card, device.array); @@ -759,6 +765,12 @@ static obs_properties_t *v4l2_properties(void *vptr) "framerate", obs_module_text("FrameRate"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_t *color_range_list = obs_properties_add_list(props, + "color_range", obs_module_text("ColorRange"), + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(color_range_list, obs_module_text("ColorRange.Partial"), VIDEO_RANGE_PARTIAL); + obs_property_list_add_int(color_range_list, obs_module_text("ColorRange.Full"), VIDEO_RANGE_FULL); + obs_properties_add_bool(props, "buffering", obs_module_text("UseBuffering")); @@ -940,6 +952,7 @@ static void v4l2_update(void *vptr, obs_data_t *settings) data->dv_timing = obs_data_get_int(settings, "dv_timing"); data->resolution = obs_data_get_int(settings, "resolution"); data->framerate = obs_data_get_int(settings, "framerate"); + data->color_range = obs_data_get_int(settings, "color_range"); v4l2_update_source_flags(data, settings); diff --git a/plugins/mac-avcapture/av-capture.mm b/plugins/mac-avcapture/av-capture.mm index 2e2a591..446ba91 100644 --- a/plugins/mac-avcapture/av-capture.mm +++ b/plugins/mac-avcapture/av-capture.mm @@ -2175,6 +2175,10 @@ static void av_capture_update(void *data, obs_data_t *settings) OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("mac-avcapture", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "MacOS AVFoundation Capture source"; +} bool obs_module_load(void) { diff --git a/plugins/mac-avcapture/data/locale/ar-SA.ini b/plugins/mac-avcapture/data/locale/ar-SA.ini index 4fecc55..065a680 100644 --- a/plugins/mac-avcapture/data/locale/ar-SA.ini +++ b/plugins/mac-avcapture/data/locale/ar-SA.ini @@ -4,4 +4,11 @@ UsePreset="استعمال عارض ضوئي" Preset="العارض الضوئي" Buffering="استخدام التخزين المؤقت Buffering" FrameRate="معدل الإطار" +InputFormat="تنسيق الإدخال" +ColorSpace="مساحة الألوان" +VideoRange="مدى ألوان الفيديو" +VideoRange.Partial="جزئي" +VideoRange.Full="كامل" +Auto="تلقائي" +Unknown="غير معروف ($1)" diff --git a/plugins/mac-avcapture/data/locale/bg-BG.ini b/plugins/mac-avcapture/data/locale/bg-BG.ini index f9bc23a..9b17bcf 100644 --- a/plugins/mac-avcapture/data/locale/bg-BG.ini +++ b/plugins/mac-avcapture/data/locale/bg-BG.ini @@ -1,4 +1,14 @@ AVCapture="Устройство за записване на видео" Device="Устройство" +UsePreset="Използвай шаблона" +Preset="Шаблон" Buffering="Използвай буфериране" +FrameRate="Кадри в секунда" +InputFormat="Формат за входа" +ColorSpace="Цветово пространство" +VideoRange="Диапазон на видео" +VideoRange.Partial="Частичен" +VideoRange.Full="Пълен" +Auto="Автоматично" +Unknown="Неизвестно ($1)" diff --git a/plugins/mac-avcapture/data/locale/da-DK.ini b/plugins/mac-avcapture/data/locale/da-DK.ini index 921fb01..b43e4c2 100644 --- a/plugins/mac-avcapture/data/locale/da-DK.ini +++ b/plugins/mac-avcapture/data/locale/da-DK.ini @@ -1,14 +1,14 @@ -AVCapture="Video optagelsesenhed" +AVCapture="Videooptageenhed" Device="Enhed" -UsePreset="Brug forudindstilling" -Preset="Forudindstilling" +UsePreset="Benyt forvalg" +Preset="Forvalg" Buffering="Brug buffering" -FrameRate="Billedfrekvens" -InputFormat="Input format" +FrameRate="Billedhastighed" +InputFormat="Inputformat" ColorSpace="Farverum" -VideoRange="Videoudstrækning" +VideoRange="Videoområde" VideoRange.Partial="Delvis" VideoRange.Full="Fuld" Auto="Auto" -Unknown="Ukendt($1)" +Unknown="Ukendt ($1)" diff --git a/plugins/mac-avcapture/data/locale/de-DE.ini b/plugins/mac-avcapture/data/locale/de-DE.ini index e2a9570..c4bd593 100644 --- a/plugins/mac-avcapture/data/locale/de-DE.ini +++ b/plugins/mac-avcapture/data/locale/de-DE.ini @@ -2,11 +2,11 @@ AVCapture="Videoaufnahmegerät" Device="Gerät" UsePreset="Benutze Voreinstellung" Preset="Voreinstellung" -Buffering="Buffering benutzen" +Buffering="Puffern benutzen" FrameRate="Bildrate" InputFormat="Eingabeformat" ColorSpace="Farbraum" -VideoRange="Video-Bereich" +VideoRange="Videobereich" VideoRange.Partial="Teilweise" VideoRange.Full="Voll" Auto="Auto" diff --git a/plugins/mac-avcapture/data/locale/eu-ES.ini b/plugins/mac-avcapture/data/locale/eu-ES.ini index 6b9ff97..84144f3 100644 --- a/plugins/mac-avcapture/data/locale/eu-ES.ini +++ b/plugins/mac-avcapture/data/locale/eu-ES.ini @@ -1,6 +1,6 @@ AVCapture="Bideoa kapturatzeko gailua" Device="Gailua" -UsePreset="Erabili aurrezarpena" +UsePreset="Erabili aurre-ezarpena" Preset="Aurre-ezarpena" Buffering="Erabili bufferreratzea" FrameRate="Fotograma emaria" diff --git a/plugins/mac-avcapture/data/locale/fa-IR.ini b/plugins/mac-avcapture/data/locale/fa-IR.ini new file mode 100644 index 0000000..ab6b22b --- /dev/null +++ b/plugins/mac-avcapture/data/locale/fa-IR.ini @@ -0,0 +1,14 @@ +AVCapture="دستگاه ضبط ویدئویی" +Device="دستگاه" +UsePreset="استفاده از پیشفرض" +Preset="پیش فرض" +Buffering="استفاده از بافرینگ" +FrameRate="نرخ فریم" +InputFormat="فرمت های ورودی" +ColorSpace="فضای رنگی" +VideoRange="محدوده ویدئو" +VideoRange.Partial="جزئی" +VideoRange.Full="کامل" +Auto="خودکار" +Unknown="ناشناخته ($1)" + diff --git a/plugins/mac-avcapture/data/locale/fr-FR.ini b/plugins/mac-avcapture/data/locale/fr-FR.ini index 895e90b..c9d56bf 100644 --- a/plugins/mac-avcapture/data/locale/fr-FR.ini +++ b/plugins/mac-avcapture/data/locale/fr-FR.ini @@ -1,12 +1,12 @@ AVCapture="Périphérique de capture vidéo" Device="Périphérique" -UsePreset="Utiliser les réglages par défaut" -Preset="Réglages par défaut" -Buffering="Utiliser la mise en mémoire tampon" -FrameRate="Fréquence d'image" +UsePreset="Utiliser un pré-réglage" +Preset="Pré-réglage" +Buffering="Utiliser le tampon mémoire" +FrameRate="Débit d'images (nombre d'images par seconde)" InputFormat="Format d'entrée" ColorSpace="Espace colorimétrique" -VideoRange="Gamme vidéo" +VideoRange="Gamme de couleurs" VideoRange.Partial="Partielle" VideoRange.Full="Complète" Auto="Auto" diff --git a/plugins/mac-avcapture/data/locale/it-IT.ini b/plugins/mac-avcapture/data/locale/it-IT.ini index 42d5dc7..c318843 100644 --- a/plugins/mac-avcapture/data/locale/it-IT.ini +++ b/plugins/mac-avcapture/data/locale/it-IT.ini @@ -1,14 +1,14 @@ AVCapture="Dispositivo di cattura video" Device="Dispositivo" -UsePreset="Usa il pre impostato" -Preset="Preimpostato" -Buffering="Usa Buffer" -FrameRate="Frame rate" -InputFormat="Formato di input" +UsePreset="Utilizza il preset" +Preset="Preset" +Buffering="Utilizza il buffering" +FrameRate="Velocità dei fotogrammi" +InputFormat="Formato di ingresso" ColorSpace="Spazio colore" -VideoRange="Gamma video" +VideoRange="Gamma di colori" VideoRange.Partial="Parziale" -VideoRange.Full="Intero" -Auto="Autom." +VideoRange.Full="Intera" +Auto="Automatica" Unknown="Sconosciuto ($1)" diff --git a/plugins/mac-avcapture/data/locale/ka-GE.ini b/plugins/mac-avcapture/data/locale/ka-GE.ini index d00fdbd..8aa910f 100644 --- a/plugins/mac-avcapture/data/locale/ka-GE.ini +++ b/plugins/mac-avcapture/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -AVCapture="ვიდეოს ჩამწერი მოწყობილობა" +AVCapture="ვიდეოს გადამღები მოწყობილობა" Device="მოწყობილობა" UsePreset="მზა პარამეტრებით სარგებლობა" Preset="მზა პარამეტრები" diff --git a/plugins/mac-avcapture/data/locale/ro-RO.ini b/plugins/mac-avcapture/data/locale/ro-RO.ini index a997f67..b246f32 100644 --- a/plugins/mac-avcapture/data/locale/ro-RO.ini +++ b/plugins/mac-avcapture/data/locale/ro-RO.ini @@ -2,7 +2,7 @@ AVCapture="Dispozitiv de captură video" Device="Dispozitiv" UsePreset="Folosește presetare" Preset="Presetare" -Buffering="Folosește buffering" +Buffering="Folosește zona tampon" FrameRate="Frecvență de cadre" InputFormat="Format de intrare" ColorSpace="Spațiu de culori" diff --git a/plugins/mac-avcapture/data/locale/sr-CS.ini b/plugins/mac-avcapture/data/locale/sr-CS.ini index 0c3ae05..86ea6d5 100644 --- a/plugins/mac-avcapture/data/locale/sr-CS.ini +++ b/plugins/mac-avcapture/data/locale/sr-CS.ini @@ -1,7 +1,7 @@ -AVCapture="Ulazni video uređaj" +AVCapture="Uređaj za snimanje videa" Device="Uređaj" -UsePreset="Koristi šablon" -Preset="Šablon" +UsePreset="Koristi predefinisana podešavanja" +Preset="Predefinisana podešavanja" Buffering="Koristi baferovanje" FrameRate="Frame rate" InputFormat="Format ulaza" diff --git a/plugins/mac-avcapture/data/locale/sr-SP.ini b/plugins/mac-avcapture/data/locale/sr-SP.ini index 5c6cda8..f5dfbda 100644 --- a/plugins/mac-avcapture/data/locale/sr-SP.ini +++ b/plugins/mac-avcapture/data/locale/sr-SP.ini @@ -1,7 +1,7 @@ -AVCapture="Улазни видео уређај" +AVCapture="Уређај за снимање видеа" Device="Уређај" -UsePreset="Користи шаблон" -Preset="Шаблон" +UsePreset="Користи предефинисана подешавања" +Preset="Предефинисана подешавања" Buffering="Користи баферовање" FrameRate="Frame rate" InputFormat="Формат улаза" diff --git a/plugins/mac-avcapture/data/locale/uk-UA.ini b/plugins/mac-avcapture/data/locale/uk-UA.ini index cf84450..5177afd 100644 --- a/plugins/mac-avcapture/data/locale/uk-UA.ini +++ b/plugins/mac-avcapture/data/locale/uk-UA.ini @@ -1,7 +1,7 @@ AVCapture="Відео пристрій" Device="Пристрій" UsePreset="Використовувати шаблон" -Preset="Пресет" +Preset="Шаблон" Buffering="Увімкнути буферизацію" FrameRate="Частота кадрів" InputFormat="Вхідний формат" diff --git a/plugins/mac-avcapture/data/locale/vi-VN.ini b/plugins/mac-avcapture/data/locale/vi-VN.ini index 48089de..a52a172 100644 --- a/plugins/mac-avcapture/data/locale/vi-VN.ini +++ b/plugins/mac-avcapture/data/locale/vi-VN.ini @@ -1,4 +1,5 @@ Device="Thiết bị" +UsePreset="Dùng mẫu có sẵn" Auto="Tự động" Unknown="Không xác định ($1)" diff --git a/plugins/mac-capture/CMakeLists.txt b/plugins/mac-capture/CMakeLists.txt index 6e7b2eb..50e34f6 100644 --- a/plugins/mac-capture/CMakeLists.txt +++ b/plugins/mac-capture/CMakeLists.txt @@ -14,7 +14,6 @@ include_directories(${COREAUDIO} set(mac-capture_HEADERS audio-device-enum.h - mac-helpers.h window-utils.h) set(mac-capture_SOURCES diff --git a/plugins/mac-capture/audio-device-enum.c b/plugins/mac-capture/audio-device-enum.c index bf7de8d..5a1d7b7 100644 --- a/plugins/mac-capture/audio-device-enum.c +++ b/plugins/mac-capture/audio-device-enum.c @@ -1,7 +1,8 @@ #include #include -#include "mac-helpers.h" +#include + #include "audio-device-enum.h" /* ugh, because mac has no means of capturing output, we have to basically @@ -114,9 +115,9 @@ static bool coreaudio_enum_add_device(void *param, CFStringRef cf_name, memset(&item, 0, sizeof(item)); - if (!cf_to_dstr(cf_name, &item.name)) + if (!cfstr_copy_dstr(cf_name, kCFStringEncodingUTF8, &item.name)) goto fail; - if (!cf_to_dstr(cf_uid, &item.value)) + if (!cfstr_copy_dstr(cf_uid, kCFStringEncodingUTF8, &item.value)) goto fail; if (data->input || !device_is_input(item.value.array)) diff --git a/plugins/mac-capture/data/locale/da-DK.ini b/plugins/mac-capture/data/locale/da-DK.ini index b784969..6b3c602 100644 --- a/plugins/mac-capture/data/locale/da-DK.ini +++ b/plugins/mac-capture/data/locale/da-DK.ini @@ -1,11 +1,11 @@ -CoreAudio.InputCapture="Indfang lyd ind" -CoreAudio.OutputCapture="Indfang lyd ud" +CoreAudio.InputCapture="Lydinputoptagelse" +CoreAudio.OutputCapture="Lydoutputoptagelse" CoreAudio.Device="Enhed" CoreAudio.Device.Default="Standard" -DisplayCapture="Skærm optag" +DisplayCapture="Skærmoptagelse" DisplayCapture.Display="Skærm" -DisplayCapture.ShowCursor="Vis markøren" -WindowCapture="Vindue indfang" +DisplayCapture.ShowCursor="Vis markør" +WindowCapture="Vinduesoptagelse" WindowCapture.ShowShadow="Vis vinduesskygge" WindowUtils.Window="Vindue" WindowUtils.ShowEmptyNames="Vis vinduer med tomme navne" diff --git a/plugins/mac-capture/data/locale/de-DE.ini b/plugins/mac-capture/data/locale/de-DE.ini index 90bc1dd..43cbbf5 100644 --- a/plugins/mac-capture/data/locale/de-DE.ini +++ b/plugins/mac-capture/data/locale/de-DE.ini @@ -1,14 +1,14 @@ -CoreAudio.InputCapture="Audio Eingabe Aufnahme" -CoreAudio.OutputCapture="Audio Ausgabe Aufnahme" +CoreAudio.InputCapture="Audioeingabeaufnahme" +CoreAudio.OutputCapture="Audioausgabeaufnahme" CoreAudio.Device="Gerät" CoreAudio.Device.Default="Standard" -DisplayCapture="Monitoraufnahme" -DisplayCapture.Display="Monitor" +DisplayCapture="Bildschirmaufnahme" +DisplayCapture.Display="Bildschirm" DisplayCapture.ShowCursor="Mauszeiger anzeigen" WindowCapture="Fensteraufnahme" -WindowCapture.ShowShadow="Zeige Fensterschatten" +WindowCapture.ShowShadow="Fensterschatten anzeigen" WindowUtils.Window="Fenster" -WindowUtils.ShowEmptyNames="Zeige Fenster mit leeren Namen" +WindowUtils.ShowEmptyNames="Fenster mit leeren Namen anzeigen" CropMode="Zuschneiden" CropMode.None="Keine" CropMode.Manual="Manuell" diff --git a/plugins/mac-capture/data/locale/fa-IR.ini b/plugins/mac-capture/data/locale/fa-IR.ini new file mode 100644 index 0000000..429a9ef --- /dev/null +++ b/plugins/mac-capture/data/locale/fa-IR.ini @@ -0,0 +1,21 @@ +CoreAudio.InputCapture="گرفتن صدای ورودی" +CoreAudio.OutputCapture="گرفتن صدای خروجی" +CoreAudio.Device="دستگاه" +CoreAudio.Device.Default="پیش فرض" +DisplayCapture="کپچر نمایش" +DisplayCapture.Display="نمایش" +DisplayCapture.ShowCursor="نمایش مکان نما" +WindowCapture="ویندوز کپچر" +WindowCapture.ShowShadow="نمایش سایه ویندوز" +WindowUtils.Window="ویندوز" +WindowUtils.ShowEmptyNames="نمایش پنجره با نام های خالی" +CropMode="بریدن" +CropMode.None="هیچ‌کدام" +CropMode.Manual="دستی" +CropMode.ToWindow="به پنجره" +CropMode.ToWindowAndManual="به پنجره و دستي" +Crop.origin.x="برش چپ" +Crop.origin.y="برش بالا" +Crop.size.width="برش راست" +Crop.size.height="برش پایین" + diff --git a/plugins/mac-capture/data/locale/fr-FR.ini b/plugins/mac-capture/data/locale/fr-FR.ini index 659dbc5..54f94b9 100644 --- a/plugins/mac-capture/data/locale/fr-FR.ini +++ b/plugins/mac-capture/data/locale/fr-FR.ini @@ -1,14 +1,14 @@ -CoreAudio.InputCapture="Capture de l'audio entrant" -CoreAudio.OutputCapture="Capture de l'audio sortant" +CoreAudio.InputCapture="Capture d'une Entrée Audio" +CoreAudio.OutputCapture="Capture Audio (Sorties)" CoreAudio.Device="Périphérique" -CoreAudio.Device.Default="Par défaut" -DisplayCapture="Afficher la capture" -DisplayCapture.Display="Affichage" +CoreAudio.Device.Default="Défaut" +DisplayCapture="Capture d'écran" +DisplayCapture.Display="Écran" DisplayCapture.ShowCursor="Afficher le curseur" -WindowCapture="Capture de la fenêtre" +WindowCapture="Capture de Fenêtre" WindowCapture.ShowShadow="Afficher l'ombre de la fenêtre" WindowUtils.Window="Fenêtre" -WindowUtils.ShowEmptyNames="Afficher les fenêtres avec des noms vides" +WindowUtils.ShowEmptyNames="Afficher les fenêtres sans noms" CropMode="Rogner" CropMode.None="Aucune" CropMode.Manual="Manuel" diff --git a/plugins/mac-capture/data/locale/it-IT.ini b/plugins/mac-capture/data/locale/it-IT.ini index 4e43f23..acf4c71 100644 --- a/plugins/mac-capture/data/locale/it-IT.ini +++ b/plugins/mac-capture/data/locale/it-IT.ini @@ -2,18 +2,18 @@ CoreAudio.InputCapture="Cattura l'audio in ingresso" CoreAudio.OutputCapture="Cattura l'audio in uscita" CoreAudio.Device="Dispositivo" CoreAudio.Device.Default="Predefinito" -DisplayCapture="Cattura schermo" -DisplayCapture.Display="Display" +DisplayCapture="Cattura lo schermo" +DisplayCapture.Display="Schermo" DisplayCapture.ShowCursor="Mostra il cursore" -WindowCapture="Cattura finestra" -WindowCapture.ShowShadow="Visualizza ombra finestra" +WindowCapture="Cattura la finestra" +WindowCapture.ShowShadow="Mostra l'ombra della finestra" WindowUtils.Window="Finestra" -WindowUtils.ShowEmptyNames="Visualizza finestre con senza nomi" +WindowUtils.ShowEmptyNames="Mostra le finestre con nomi vuoti" CropMode="Ritaglia" -CropMode.None="Nessuno" -CropMode.Manual="Manuale" +CropMode.None="Niente" +CropMode.Manual="Manualmente" CropMode.ToWindow="Alla finestra" -CropMode.ToWindowAndManual="Alla finestra manualmente" +CropMode.ToWindowAndManual="Alla finestra e manualmente" Crop.origin.x="Ritaglia a sinistra" Crop.origin.y="Ritaglia dall'alto" Crop.size.width="Ritaglia a destra" diff --git a/plugins/mac-capture/data/locale/ka-GE.ini b/plugins/mac-capture/data/locale/ka-GE.ini index 0f8b3eb..69d81de 100644 --- a/plugins/mac-capture/data/locale/ka-GE.ini +++ b/plugins/mac-capture/data/locale/ka-GE.ini @@ -1,5 +1,5 @@ CoreAudio.InputCapture="შემავალი ხმოვანი სიგნალის ჩაწერა" -CoreAudio.OutputCapture="გამომავალი ხმოვანი სიგნალის ჩაწერა" +CoreAudio.OutputCapture="გამოტანილი ხმის ჩაწერა" CoreAudio.Device="მოწყობილობა" CoreAudio.Device.Default="ნაგულისხმევი" DisplayCapture="ეკრანის გადაღება" diff --git a/plugins/mac-capture/data/locale/nl-NL.ini b/plugins/mac-capture/data/locale/nl-NL.ini index 1be3b06..56210fd 100644 --- a/plugins/mac-capture/data/locale/nl-NL.ini +++ b/plugins/mac-capture/data/locale/nl-NL.ini @@ -2,7 +2,7 @@ CoreAudio.InputCapture="Audioinvoer Opname" CoreAudio.OutputCapture="Audiouitvoer Opname" CoreAudio.Device="Apparaat" CoreAudio.Device.Default="Standaardinstellingen" -DisplayCapture="Beeldschermcapture" +DisplayCapture="Beeldschermopname" DisplayCapture.Display="Beeldscherm" DisplayCapture.ShowCursor="Cursor Weergeven" WindowCapture="Venstercapture" diff --git a/plugins/mac-capture/data/locale/ro-RO.ini b/plugins/mac-capture/data/locale/ro-RO.ini index 3f07ce8..9215d51 100644 --- a/plugins/mac-capture/data/locale/ro-RO.ini +++ b/plugins/mac-capture/data/locale/ro-RO.ini @@ -6,9 +6,9 @@ DisplayCapture="Captură de display" DisplayCapture.Display="Display" DisplayCapture.ShowCursor="Arată cursorul" WindowCapture="Captură de fereastră" -WindowCapture.ShowShadow="Arată umbra ferestrei" +WindowCapture.ShowShadow="Afișează umbra ferestrei" WindowUtils.Window="Fereastră" -WindowUtils.ShowEmptyNames="Arată ferestrele cu numele goale" +WindowUtils.ShowEmptyNames="Afișează ferestrele cu nume goale" CropMode="Trunchiază" CropMode.None="Niciunul" CropMode.Manual="Manual" diff --git a/plugins/mac-capture/data/locale/sr-CS.ini b/plugins/mac-capture/data/locale/sr-CS.ini index a3504e5..8b235e3 100644 --- a/plugins/mac-capture/data/locale/sr-CS.ini +++ b/plugins/mac-capture/data/locale/sr-CS.ini @@ -1,11 +1,11 @@ -CoreAudio.InputCapture="Ulaz zvuka" -CoreAudio.OutputCapture="Izlaz zvuka" +CoreAudio.InputCapture="Snimanje zvuka na ulazu" +CoreAudio.OutputCapture="Snimanje zvuka na izlazu" CoreAudio.Device="Uređaj" CoreAudio.Device.Default="Podrazumevano" -DisplayCapture="Prikaži ulaz" -DisplayCapture.Display="Ekran" +DisplayCapture="Prikaži snimak" +DisplayCapture.Display="Prikaži" DisplayCapture.ShowCursor="Prikaži kursor" -WindowCapture="Snimanje sa prozora" +WindowCapture="Snimanje prozora" WindowCapture.ShowShadow="Prikaži senku na prozoru" WindowUtils.Window="Prozor" WindowUtils.ShowEmptyNames="Prikaži i prozore bez imena" diff --git a/plugins/mac-capture/data/locale/sr-SP.ini b/plugins/mac-capture/data/locale/sr-SP.ini index 123ac46..2234d8a 100644 --- a/plugins/mac-capture/data/locale/sr-SP.ini +++ b/plugins/mac-capture/data/locale/sr-SP.ini @@ -1,11 +1,11 @@ -CoreAudio.InputCapture="Улаз звука" -CoreAudio.OutputCapture="Излаз звука" +CoreAudio.InputCapture="Снимање звука на улазу" +CoreAudio.OutputCapture="Снимање звука на излазу" CoreAudio.Device="Уређај" CoreAudio.Device.Default="Подразумевано" -DisplayCapture="Прикажи улаз" -DisplayCapture.Display="Екран" +DisplayCapture="Прикажи снимак" +DisplayCapture.Display="Прикажи" DisplayCapture.ShowCursor="Прикажи курсор" -WindowCapture="Снимање са прозора" +WindowCapture="Снимање прозора" WindowCapture.ShowShadow="Прикажи сенку на прозору" WindowUtils.Window="Прозор" WindowUtils.ShowEmptyNames="Прикажи и прозоре без имена" diff --git a/plugins/mac-capture/mac-audio.c b/plugins/mac-capture/mac-audio.c index 47b480d..7d94c64 100644 --- a/plugins/mac-capture/mac-audio.c +++ b/plugins/mac-capture/mac-audio.c @@ -7,8 +7,8 @@ #include #include #include +#include -#include "mac-helpers.h" #include "audio-device-enum.h" #define PROPERTY_DEFAULT_DEVICE kAudioHardwarePropertyDefaultInputDevice @@ -496,7 +496,7 @@ static bool coreaudio_get_device_name(struct coreaudio_data *ca) { CFStringRef cf_name = NULL; UInt32 size = sizeof(CFStringRef); - char name[1024]; + char *name = NULL; const AudioObjectPropertyAddress addr = { kAudioDevicePropertyDeviceNameCFString, @@ -512,14 +512,15 @@ static bool coreaudio_get_device_name(struct coreaudio_data *ca) return false; } - if (!cf_to_cstr(cf_name, name, 1024)) { + name = cfstr_copy_cstr(cf_name, kCFStringEncodingUTF8); + if (!name) { blog(LOG_WARNING, "[coreaudio_get_device_name] failed to " "convert name to cstr for some reason"); return false; } bfree(ca->device_name); - ca->device_name = bstrdup(name); + ca->device_name = name; if (cf_name) CFRelease(cf_name); diff --git a/plugins/mac-capture/mac-helpers.h b/plugins/mac-capture/mac-helpers.h deleted file mode 100644 index e77b450..0000000 --- a/plugins/mac-capture/mac-helpers.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include - -static inline bool mac_success(OSStatus stat, const char *action) -{ - if (stat != noErr) { - blog(LOG_WARNING, "%s failed: %d", action, (int)stat); - return false; - } - - return true; -} - -static inline bool cf_to_cstr(CFStringRef ref, char *buf, size_t size) -{ - if (!ref) return false; - return (bool)CFStringGetCString(ref, buf, size, kCFStringEncodingUTF8); -} - -static inline bool cf_to_dstr(CFStringRef ref, struct dstr *str) -{ - size_t size; - if (!ref) return false; - - size = (size_t)CFStringGetLength(ref); - if (!size) - return false; - - dstr_resize(str, size); - - return (bool)CFStringGetCString(ref, str->array, size+1, - kCFStringEncodingUTF8); -} diff --git a/plugins/mac-capture/plugin-main.c b/plugins/mac-capture/plugin-main.c index 4f6698d..2efa3a0 100644 --- a/plugins/mac-capture/plugin-main.c +++ b/plugins/mac-capture/plugin-main.c @@ -2,6 +2,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("mac-capture", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "macOS audio input/output and window/display capture"; +} extern struct obs_source_info coreaudio_input_capture_info; extern struct obs_source_info coreaudio_output_capture_info; diff --git a/plugins/mac-syphon/data/locale/ar-SA.ini b/plugins/mac-syphon/data/locale/ar-SA.ini index 55a9c1f..4c8f1ed 100644 --- a/plugins/mac-syphon/data/locale/ar-SA.ini +++ b/plugins/mac-syphon/data/locale/ar-SA.ini @@ -1,4 +1,3 @@ -Syphon="التقاط لعبة (Syphon)" Source="مصدر" LaunchSyphonInject="بدء تشغيل حقن SyphonInject" Inject="حقن" diff --git a/plugins/mac-syphon/data/locale/bn-BD.ini b/plugins/mac-syphon/data/locale/bn-BD.ini index 33bec3d..37765a2 100644 --- a/plugins/mac-syphon/data/locale/bn-BD.ini +++ b/plugins/mac-syphon/data/locale/bn-BD.ini @@ -1,4 +1,3 @@ -Syphon="খেলার অধিগ্রহণ (Syphon)" Source="উৎস" Application="অ্যাপ্লিকেশন" SyphonLicense="Syphon লাইসেন্স" diff --git a/plugins/mac-syphon/data/locale/ca-ES.ini b/plugins/mac-syphon/data/locale/ca-ES.ini index c54badb..5935542 100644 --- a/plugins/mac-syphon/data/locale/ca-ES.ini +++ b/plugins/mac-syphon/data/locale/ca-ES.ini @@ -1,4 +1,4 @@ -Syphon="Captura de videojoc (Syphon)" +Syphon="Client Syphon" Source="Origen" LaunchSyphonInject="Executa SyphonInject" Inject="Injecta" diff --git a/plugins/mac-syphon/data/locale/cs-CZ.ini b/plugins/mac-syphon/data/locale/cs-CZ.ini index 3e48974..ee4d195 100644 --- a/plugins/mac-syphon/data/locale/cs-CZ.ini +++ b/plugins/mac-syphon/data/locale/cs-CZ.ini @@ -1,4 +1,4 @@ -Syphon="Záznam hry (Syphon)" +Syphon="Klient Syphon" Source="Zdroj" LaunchSyphonInject="Spustit SyphonInject" Inject="Injektovat" diff --git a/plugins/mac-syphon/data/locale/da-DK.ini b/plugins/mac-syphon/data/locale/da-DK.ini index 5ed2c5f..681e6f8 100644 --- a/plugins/mac-syphon/data/locale/da-DK.ini +++ b/plugins/mac-syphon/data/locale/da-DK.ini @@ -1,9 +1,9 @@ -Syphon="Indfang spil (Syphon)" +Syphon="Syphon-klient" Source="Kilde" LaunchSyphonInject="Kør SyphonInject" -Inject="Indsæt" +Inject="Injicér" Application="Program" -SyphonLicense="Syphon licens" +SyphonLicense="Syphon-licens" Crop="Beskær" Crop.origin.x="Beskær venstre" Crop.origin.y="Beskær top" diff --git a/plugins/mac-syphon/data/locale/de-DE.ini b/plugins/mac-syphon/data/locale/de-DE.ini index 60201ff..eb3e43c 100644 --- a/plugins/mac-syphon/data/locale/de-DE.ini +++ b/plugins/mac-syphon/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -Syphon="Spielaufnahme (Syphon)" +Syphon="Syphon-Client" Source="Quelle" LaunchSyphonInject="SyphonInject starten" Inject="Injizieren" @@ -9,5 +9,5 @@ Crop.origin.x="Links abschneiden" Crop.origin.y="Oben abschneiden" Crop.size.width="Rechts abschneiden" Crop.size.height="Unten abschneiden" -AllowTransparency="Erlaube Transparenz" +AllowTransparency="Transparenz erlauben" diff --git a/plugins/mac-syphon/data/locale/el-GR.ini b/plugins/mac-syphon/data/locale/el-GR.ini index 60a5bd7..799625a 100644 --- a/plugins/mac-syphon/data/locale/el-GR.ini +++ b/plugins/mac-syphon/data/locale/el-GR.ini @@ -1,4 +1,3 @@ -Syphon="Σύλληψη Παιχνιδιού (Syphon)" Source="Πηγή" LaunchSyphonInject="Έναρξη SyphonInject" Inject="Εισήγαγε" diff --git a/plugins/mac-syphon/data/locale/en-US.ini b/plugins/mac-syphon/data/locale/en-US.ini index 607eb5d..86550be 100644 --- a/plugins/mac-syphon/data/locale/en-US.ini +++ b/plugins/mac-syphon/data/locale/en-US.ini @@ -1,4 +1,4 @@ -Syphon="Game Capture (Syphon)" +Syphon="Syphon Client" Source="Source" LaunchSyphonInject="Launch SyphonInject" Inject="Inject" diff --git a/plugins/mac-syphon/data/locale/es-ES.ini b/plugins/mac-syphon/data/locale/es-ES.ini index 1402989..7e9aebb 100644 --- a/plugins/mac-syphon/data/locale/es-ES.ini +++ b/plugins/mac-syphon/data/locale/es-ES.ini @@ -1,4 +1,4 @@ -Syphon="Captura de juego (Syphon)" +Syphon="Syphon Client" Source="Fuente" LaunchSyphonInject="Lanzar SyphonInject" Inject="Inyectar" diff --git a/plugins/mac-syphon/data/locale/et-EE.ini b/plugins/mac-syphon/data/locale/et-EE.ini index 456813f..2718251 100644 --- a/plugins/mac-syphon/data/locale/et-EE.ini +++ b/plugins/mac-syphon/data/locale/et-EE.ini @@ -1,4 +1,3 @@ -Syphon="Mängu hõive (Syphon)" Source="Allikas" LaunchSyphonInject="Käivita SyphonInject" Inject="Sisesta" diff --git a/plugins/mac-syphon/data/locale/eu-ES.ini b/plugins/mac-syphon/data/locale/eu-ES.ini index 1a4c5f5..ce7fe8d 100644 --- a/plugins/mac-syphon/data/locale/eu-ES.ini +++ b/plugins/mac-syphon/data/locale/eu-ES.ini @@ -1,4 +1,4 @@ -Syphon="Jokoen kaptura (Syphon)" +Syphon="Syphon bezeroa" Source="Iturburua" LaunchSyphonInject="Abiarazi SyphonInject" Inject="Injektatu" diff --git a/plugins/mac-syphon/data/locale/fa-IR.ini b/plugins/mac-syphon/data/locale/fa-IR.ini new file mode 100644 index 0000000..fe38fac --- /dev/null +++ b/plugins/mac-syphon/data/locale/fa-IR.ini @@ -0,0 +1,12 @@ +Source="منبع" +LaunchSyphonInject="راه اندازی SyphonInject" +Inject="تزریق" +Application="برنامه" +SyphonLicense="مجوز syphon" +Crop="بریدن" +Crop.origin.x="برش چپ" +Crop.origin.y="برش بالا" +Crop.size.width="برش راست" +Crop.size.height="برش پایین" +AllowTransparency="اجازه شفافیت" + diff --git a/plugins/mac-syphon/data/locale/fi-FI.ini b/plugins/mac-syphon/data/locale/fi-FI.ini index 586fafc..9f43f87 100644 --- a/plugins/mac-syphon/data/locale/fi-FI.ini +++ b/plugins/mac-syphon/data/locale/fi-FI.ini @@ -1,4 +1,4 @@ -Syphon="Kaappaa peli (Syphon)" +Syphon="Syphon Client" Source="Lähde" LaunchSyphonInject="Käynnistä SyphonInject" Inject="Inject" diff --git a/plugins/mac-syphon/data/locale/fil-PH.ini b/plugins/mac-syphon/data/locale/fil-PH.ini index 18c8632..b416c8b 100644 --- a/plugins/mac-syphon/data/locale/fil-PH.ini +++ b/plugins/mac-syphon/data/locale/fil-PH.ini @@ -1,4 +1,3 @@ -Syphon="Pagkuha ng Laro (Siphon)" Source="Pinagkukunan" LaunchSyphonInject="Simulan ang SayponIngekt" Inject="Turukan" diff --git a/plugins/mac-syphon/data/locale/fr-FR.ini b/plugins/mac-syphon/data/locale/fr-FR.ini index 9e482a4..de78996 100644 --- a/plugins/mac-syphon/data/locale/fr-FR.ini +++ b/plugins/mac-syphon/data/locale/fr-FR.ini @@ -1,6 +1,6 @@ -Syphon="Capture de jeu (Syphon)" +Syphon="Client Syphon" Source="Source" -LaunchSyphonInject="Lancer SyphonInject" +LaunchSyphonInject="Démarrer SyphonInject" Inject="Injecter" Application="Application" SyphonLicense="Licence de Syphon" diff --git a/plugins/mac-syphon/data/locale/gl-ES.ini b/plugins/mac-syphon/data/locale/gl-ES.ini index a40f703..27b87bb 100644 --- a/plugins/mac-syphon/data/locale/gl-ES.ini +++ b/plugins/mac-syphon/data/locale/gl-ES.ini @@ -1,4 +1,3 @@ -Syphon="Captura de xogo (Syphon)" Source="Fonte" LaunchSyphonInject="Lanzar SyphonInject" Inject="Inxectar" diff --git a/plugins/mac-syphon/data/locale/hr-HR.ini b/plugins/mac-syphon/data/locale/hr-HR.ini index 34f6f38..1c84dab 100644 --- a/plugins/mac-syphon/data/locale/hr-HR.ini +++ b/plugins/mac-syphon/data/locale/hr-HR.ini @@ -1,4 +1,3 @@ -Syphon="Snimanje igre (Syphon)" Source="Izvor" LaunchSyphonInject="Pokreni SyphonInject" Inject="Ubrizgaj" diff --git a/plugins/mac-syphon/data/locale/hu-HU.ini b/plugins/mac-syphon/data/locale/hu-HU.ini index b920289..bb2250e 100644 --- a/plugins/mac-syphon/data/locale/hu-HU.ini +++ b/plugins/mac-syphon/data/locale/hu-HU.ini @@ -1,4 +1,4 @@ -Syphon="Játék felvétel (Syphon)" +Syphon="Syphon Kliens" Source="Forrás" LaunchSyphonInject="SyphonInject indítása" Inject="Fecskendezés" diff --git a/plugins/mac-syphon/data/locale/it-IT.ini b/plugins/mac-syphon/data/locale/it-IT.ini index 2204ca5..3c94b02 100644 --- a/plugins/mac-syphon/data/locale/it-IT.ini +++ b/plugins/mac-syphon/data/locale/it-IT.ini @@ -1,6 +1,6 @@ -Syphon="Cattura Gioco (Syphon)" -Source="Sorgente" -LaunchSyphonInject="Lancia SyphonInject" +Syphon="Client Syphon" +Source="Fonte" +LaunchSyphonInject="Avvia SyphonInject" Inject="Inserisci" Application="Applicazione" SyphonLicense="Licenza Syphon" @@ -9,5 +9,5 @@ Crop.origin.x="Ritaglia a sinistra" Crop.origin.y="Ritaglia dall'alto" Crop.size.width="Ritaglia a destra" Crop.size.height="Ritaglia dal basso" -AllowTransparency="Permetti trasparenza" +AllowTransparency="Permetti la trasparenza" diff --git a/plugins/mac-syphon/data/locale/ja-JP.ini b/plugins/mac-syphon/data/locale/ja-JP.ini index 47013a2..a62e8a3 100644 --- a/plugins/mac-syphon/data/locale/ja-JP.ini +++ b/plugins/mac-syphon/data/locale/ja-JP.ini @@ -1,4 +1,4 @@ -Syphon="ゲームキャプチャ (サイフォン)" +Syphon="サイフォンクライアント" Source="ソース" LaunchSyphonInject="サイフォンインジェクトを起動する" Inject="インジェクト" diff --git a/plugins/mac-syphon/data/locale/ka-GE.ini b/plugins/mac-syphon/data/locale/ka-GE.ini index f359593..1733ede 100644 --- a/plugins/mac-syphon/data/locale/ka-GE.ini +++ b/plugins/mac-syphon/data/locale/ka-GE.ini @@ -1,4 +1,4 @@ -Syphon="თამაშის გადაღება (Syphon)" +Syphon="Syphon-პროგრამა" Source="წყარო" LaunchSyphonInject="SyphonInject გაშვება" Inject="ჩადგმა" diff --git a/plugins/mac-syphon/data/locale/ko-KR.ini b/plugins/mac-syphon/data/locale/ko-KR.ini index ce4cce2..fb9fad8 100644 --- a/plugins/mac-syphon/data/locale/ko-KR.ini +++ b/plugins/mac-syphon/data/locale/ko-KR.ini @@ -1,4 +1,4 @@ -Syphon="게임 캡쳐 (Syphon)" +Syphon="Syphon 클라이언트" Source="소스" LaunchSyphonInject="SyphonInject 실행" Inject="삽입" diff --git a/plugins/mac-syphon/data/locale/nb-NO.ini b/plugins/mac-syphon/data/locale/nb-NO.ini index ef04687..2e530bf 100644 --- a/plugins/mac-syphon/data/locale/nb-NO.ini +++ b/plugins/mac-syphon/data/locale/nb-NO.ini @@ -1,4 +1,4 @@ -Syphon="Spillopptak (Syphon)" +Syphon="Syphon-klient" Source="Kilde" LaunchSyphonInject="Start SyphonInject" Inject="Injiser" diff --git a/plugins/mac-syphon/data/locale/nl-NL.ini b/plugins/mac-syphon/data/locale/nl-NL.ini index 8a89106..f9ac3b4 100644 --- a/plugins/mac-syphon/data/locale/nl-NL.ini +++ b/plugins/mac-syphon/data/locale/nl-NL.ini @@ -1,4 +1,4 @@ -Syphon="Gamecapture (Syphon)" +Syphon="Syphon cliënt" Source="Bron" LaunchSyphonInject="Start SyphonInject" Inject="Injecteren" diff --git a/plugins/mac-syphon/data/locale/pl-PL.ini b/plugins/mac-syphon/data/locale/pl-PL.ini index 988a710..58a8679 100644 --- a/plugins/mac-syphon/data/locale/pl-PL.ini +++ b/plugins/mac-syphon/data/locale/pl-PL.ini @@ -1,4 +1,4 @@ -Syphon="Przechwytywanie gry (Syphon)" +Syphon="Klient Syphon" Source="Źródło" LaunchSyphonInject="Uruchom SyphonInject" Inject="Załaduj" diff --git a/plugins/mac-syphon/data/locale/pt-BR.ini b/plugins/mac-syphon/data/locale/pt-BR.ini index def7cfa..54b7bbd 100644 --- a/plugins/mac-syphon/data/locale/pt-BR.ini +++ b/plugins/mac-syphon/data/locale/pt-BR.ini @@ -1,4 +1,4 @@ -Syphon="Captura de jogo (Syphon)" +Syphon="Cliente do Syphon" Source="Fonte" LaunchSyphonInject="Iniciar SyphonInject" Inject="Injetar" diff --git a/plugins/mac-syphon/data/locale/pt-PT.ini b/plugins/mac-syphon/data/locale/pt-PT.ini index 059c56c..bc77e3a 100644 --- a/plugins/mac-syphon/data/locale/pt-PT.ini +++ b/plugins/mac-syphon/data/locale/pt-PT.ini @@ -1,4 +1,3 @@ -Syphon="Captura de jogo (Syphon)" Source="Fonte" LaunchSyphonInject="Iniciar SyphonInject" Inject="Injetar" diff --git a/plugins/mac-syphon/data/locale/ro-RO.ini b/plugins/mac-syphon/data/locale/ro-RO.ini index 9cc2423..496b786 100644 --- a/plugins/mac-syphon/data/locale/ro-RO.ini +++ b/plugins/mac-syphon/data/locale/ro-RO.ini @@ -1,4 +1,3 @@ -Syphon="Captură de joc (Syphon)" Source="Sursă" LaunchSyphonInject="Lansează SyphonInject" Inject="Injectează" diff --git a/plugins/mac-syphon/data/locale/ru-RU.ini b/plugins/mac-syphon/data/locale/ru-RU.ini index 4ca0df3..0357836 100644 --- a/plugins/mac-syphon/data/locale/ru-RU.ini +++ b/plugins/mac-syphon/data/locale/ru-RU.ini @@ -1,4 +1,4 @@ -Syphon="Захват игры (Syphon)" +Syphon="Клиент Syphon" Source="Источник" LaunchSyphonInject="Запуск SyphonInject" Inject="Ввести" diff --git a/plugins/mac-syphon/data/locale/sk-SK.ini b/plugins/mac-syphon/data/locale/sk-SK.ini index c57f1b4..94fc06b 100644 --- a/plugins/mac-syphon/data/locale/sk-SK.ini +++ b/plugins/mac-syphon/data/locale/sk-SK.ini @@ -1,4 +1,4 @@ -Syphon="Zachytávanie hry (Syphon)" +Syphon="Syphon klient" Source="Zdroj" LaunchSyphonInject="Zapnúť SyphonInject" Inject="Zaviesť" @@ -9,5 +9,5 @@ Crop.origin.x="Orezanie vľavo" Crop.origin.y="Orezanie hore" Crop.size.width="Orezanie vpravo" Crop.size.height="Orezanie dole" -AllowTransparency="Povoliť transparentnosť" +AllowTransparency="Povoliť priehľadnosť" diff --git a/plugins/mac-syphon/data/locale/sl-SI.ini b/plugins/mac-syphon/data/locale/sl-SI.ini index bbab943..c56cc7c 100644 --- a/plugins/mac-syphon/data/locale/sl-SI.ini +++ b/plugins/mac-syphon/data/locale/sl-SI.ini @@ -1,4 +1,3 @@ -Syphon="Zajemanje igre (Syphon)" Source="Vir" LaunchSyphonInject="Zaženi SyphonInject" Inject="Vstavi" diff --git a/plugins/mac-syphon/data/locale/sr-CS.ini b/plugins/mac-syphon/data/locale/sr-CS.ini index 34f6f38..c59480f 100644 --- a/plugins/mac-syphon/data/locale/sr-CS.ini +++ b/plugins/mac-syphon/data/locale/sr-CS.ini @@ -1,4 +1,4 @@ -Syphon="Snimanje igre (Syphon)" +Syphon="Syphon klijent" Source="Izvor" LaunchSyphonInject="Pokreni SyphonInject" Inject="Ubrizgaj" diff --git a/plugins/mac-syphon/data/locale/sr-SP.ini b/plugins/mac-syphon/data/locale/sr-SP.ini index 90e5c1b..66454ae 100644 --- a/plugins/mac-syphon/data/locale/sr-SP.ini +++ b/plugins/mac-syphon/data/locale/sr-SP.ini @@ -1,4 +1,4 @@ -Syphon="Снимање игре (Syphon)" +Syphon="Syphon клијент" Source="Извор" LaunchSyphonInject="Покрени SyphonInject" Inject="Убризгај" diff --git a/plugins/mac-syphon/data/locale/sv-SE.ini b/plugins/mac-syphon/data/locale/sv-SE.ini index 7f37426..1145c82 100644 --- a/plugins/mac-syphon/data/locale/sv-SE.ini +++ b/plugins/mac-syphon/data/locale/sv-SE.ini @@ -1,4 +1,4 @@ -Syphon="Spelinspelning (Syphon)" +Syphon="Syphon-klient" Source="Källa" LaunchSyphonInject="Starta SyphonInject" Inject="Injicera" diff --git a/plugins/mac-syphon/data/locale/tr-TR.ini b/plugins/mac-syphon/data/locale/tr-TR.ini index c68d2f3..6800b97 100644 --- a/plugins/mac-syphon/data/locale/tr-TR.ini +++ b/plugins/mac-syphon/data/locale/tr-TR.ini @@ -1,4 +1,4 @@ -Syphon="Oyun Yakalama (Syphon)" +Syphon="Syphon İstemcisi" Source="Kaynak" LaunchSyphonInject="SyphonInject'i Başlat" Inject="Araya gir" diff --git a/plugins/mac-syphon/data/locale/uk-UA.ini b/plugins/mac-syphon/data/locale/uk-UA.ini index bcf0248..2517736 100644 --- a/plugins/mac-syphon/data/locale/uk-UA.ini +++ b/plugins/mac-syphon/data/locale/uk-UA.ini @@ -1,4 +1,4 @@ -Syphon="Захват гри (Syphon)" +Syphon="Syphon клієнт" Source="Джерело" LaunchSyphonInject="Запустити SyphonInject" Inject="Ввести" diff --git a/plugins/mac-syphon/data/locale/vi-VN.ini b/plugins/mac-syphon/data/locale/vi-VN.ini index d272325..e1e1b09 100644 --- a/plugins/mac-syphon/data/locale/vi-VN.ini +++ b/plugins/mac-syphon/data/locale/vi-VN.ini @@ -1,3 +1,9 @@ Source="Nguồn" Application="Ứng dụng" +Crop="Cắt" +Crop.origin.x="Cắt trái" +Crop.origin.y="Cắt trên" +Crop.size.width="Cắt phải" +Crop.size.height="Cắt dưới" +AllowTransparency="Cho phép trong suốt" diff --git a/plugins/mac-syphon/data/locale/zh-CN.ini b/plugins/mac-syphon/data/locale/zh-CN.ini index eb1e104..87cec6f 100644 --- a/plugins/mac-syphon/data/locale/zh-CN.ini +++ b/plugins/mac-syphon/data/locale/zh-CN.ini @@ -1,4 +1,4 @@ -Syphon="游戏捕获(Syphon)" +Syphon="Syphon客户端" Source="来源" LaunchSyphonInject="启动 SyphonInject" Inject="注入" diff --git a/plugins/mac-syphon/data/locale/zh-TW.ini b/plugins/mac-syphon/data/locale/zh-TW.ini index 34028b2..7ece6e0 100644 --- a/plugins/mac-syphon/data/locale/zh-TW.ini +++ b/plugins/mac-syphon/data/locale/zh-TW.ini @@ -1,4 +1,4 @@ -Syphon="遊戲擷取 (Syphon)" +Syphon="Syphon用戶端" Source="來源" LaunchSyphonInject="啟動 SyphonInject" Inject="注入" diff --git a/plugins/mac-syphon/plugin-main.c b/plugins/mac-syphon/plugin-main.c index 011e711..e319d56 100644 --- a/plugins/mac-syphon/plugin-main.c +++ b/plugins/mac-syphon/plugin-main.c @@ -2,6 +2,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("syphon", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Syphon frame sharing"; +} extern struct obs_source_info syphon_info; diff --git a/plugins/mac-vth264/data/locale/da-DK.ini b/plugins/mac-vth264/data/locale/da-DK.ini index fbedef8..f30c85b 100644 --- a/plugins/mac-vth264/data/locale/da-DK.ini +++ b/plugins/mac-vth264/data/locale/da-DK.ini @@ -5,7 +5,7 @@ Bitrate="Bit-hastighed" UseMaxBitrate="Begræns bit-hastighed" MaxBitrate="Maks. bit-hastighed" MaxBitrateWindow="Maks. bit-hastighedsvindue (sekunder)" -KeyframeIntervalSec="Keyframe interval (sekunder, 0= auto)" +KeyframeIntervalSec="Keyframe-interval (sekunder, 0= auto)" Profile="Profil" None="(ingen)" DefaultEncoder="(Standard Encoder)" diff --git a/plugins/mac-vth264/data/locale/de-DE.ini b/plugins/mac-vth264/data/locale/de-DE.ini index b095bd3..fc0eda5 100644 --- a/plugins/mac-vth264/data/locale/de-DE.ini +++ b/plugins/mac-vth264/data/locale/de-DE.ini @@ -1,14 +1,14 @@ -VTH264EncHW="Apple VT H264 Hardware Codierer" -VTH264EncSW="Apple VT H264 Software Codierer" -VTEncoder="VideoToolbox Codierer" +VTH264EncHW="Apple-VT-H264-Hardware-Kodierer" +VTH264EncSW="Apple-VT-H264-Software-Kodierer" +VTEncoder="VideoToolbox-Kodierer" Bitrate="Bitrate" UseMaxBitrate="Limitiere Bitrate" -MaxBitrate="Maximale Bitrate" -MaxBitrateWindow="Maximales Bitrate Fenster (Sekunden)" -KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" +MaxBitrate="Max. Bitrate" +MaxBitrateWindow="Maximales Bitratenfenster (Sekunden)" +KeyframeIntervalSec="Keyframeintervall (Sekunden, 0 = auto)" Profile="Profil" None="(Nichts)" -DefaultEncoder="(Standard-Codierer)" +DefaultEncoder="(Standardkodierer)" UseBFrames="B-Frames verwenden" diff --git a/plugins/mac-vth264/data/locale/fa-IR.ini b/plugins/mac-vth264/data/locale/fa-IR.ini new file mode 100644 index 0000000..150397c --- /dev/null +++ b/plugins/mac-vth264/data/locale/fa-IR.ini @@ -0,0 +1,14 @@ +VTH264EncHW="تخمین سخت افزار اپل VT H264" +VTH264EncSW="رمزگذار نرم افزار اپل VT H264" +VTEncoder="تخمین VideoToolbox" +Bitrate="نرخ بیت" +UseMaxBitrate="بیت محدود" +MaxBitrate="حداکثر میزان نرخ بیت" +MaxBitrateWindow="پنجره حداکثر میزان نرخ بیت (ثانیه)" +KeyframeIntervalSec="فاصله Keyframe (ثانیه 0 = خودکار)" +Profile="پروفایل" +None="(هیچ‌کدام)" +DefaultEncoder="(رمزگذاری پیشفرض)" +UseBFrames="استفاده از فریم های B" + + diff --git a/plugins/mac-vth264/data/locale/fr-FR.ini b/plugins/mac-vth264/data/locale/fr-FR.ini index 21bc564..d0ce648 100644 --- a/plugins/mac-vth264/data/locale/fr-FR.ini +++ b/plugins/mac-vth264/data/locale/fr-FR.ini @@ -1,10 +1,10 @@ VTH264EncHW="Encodeur matériel Apple VT H264" VTH264EncSW="Encodeur logiciel Apple VT H264" VTEncoder="Encodeur VideoToolbox" -Bitrate="Bitrate" -UseMaxBitrate="Limiter le bitrate" -MaxBitrate="Bitrate maximal" -MaxBitrateWindow="Fenêtre de bitrate maximal (en secondes)" +Bitrate="Débit" +UseMaxBitrate="Limiter le débit" +MaxBitrate="Débit maximal" +MaxBitrateWindow="Fenêtre de débit maximal (en secondes)" KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" Profile="Profil" None="(Aucun)" diff --git a/plugins/mac-vth264/data/locale/it-IT.ini b/plugins/mac-vth264/data/locale/it-IT.ini index 6e9331f..25bbb60 100644 --- a/plugins/mac-vth264/data/locale/it-IT.ini +++ b/plugins/mac-vth264/data/locale/it-IT.ini @@ -1,14 +1,14 @@ -VTH264EncHW="Apple VT H264 Hardware Encoder" -VTH264EncSW="Apple VT H264 Software Encoder" -VTEncoder="VideoToolbox Encoder" -Bitrate="Bitrate" -UseMaxBitrate="Limite bitrate" -MaxBitrate="Bitrate massimo" -MaxBitrateWindow="Bitrate massimo finestra (secondi)" -KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)" +VTH264EncHW="Codifica hardware Apple VT H264" +VTH264EncSW="Codifica software Apple VT H264" +VTEncoder="Codifica VideoToolbox" +Bitrate="Velocità in bit" +UseMaxBitrate="Limite della velocità in bit" +MaxBitrate="Velocità in bit massima" +MaxBitrateWindow="Velocità in bit massima per la finestra (in secondi)" +KeyframeIntervalSec="Intervallo dei fotogrammi chiave (in secondi, 0=automatico)" Profile="Profilo" -None="(Nessuno)" -DefaultEncoder="(Encoder Predefinito)" -UseBFrames="Usa B-Frames" +None="(nessuno)" +DefaultEncoder="(codifica predefinita)" +UseBFrames="Utilizza i B-Frame" diff --git a/plugins/mac-vth264/data/locale/zh-CN.ini b/plugins/mac-vth264/data/locale/zh-CN.ini index 0811aca..389dcaf 100644 --- a/plugins/mac-vth264/data/locale/zh-CN.ini +++ b/plugins/mac-vth264/data/locale/zh-CN.ini @@ -6,7 +6,7 @@ UseMaxBitrate="限制比特率" MaxBitrate="最大比特率" MaxBitrateWindow="最大比特率窗口 (秒)" KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" -Profile="档案" +Profile="配置文件" None="(无)" DefaultEncoder="(默认编码器)" UseBFrames="使用 B 帧" diff --git a/plugins/mac-vth264/encoder.c b/plugins/mac-vth264/encoder.c index 71e5e89..83137dd 100644 --- a/plugins/mac-vth264/encoder.c +++ b/plugins/mac-vth264/encoder.c @@ -6,6 +6,8 @@ #include #include +#include + #include #define VT_LOG(level, format, ...) \ @@ -74,23 +76,20 @@ struct vt_h264_encoder static void log_osstatus(int log_level, struct vt_h264_encoder *enc, const char *context, OSStatus code) { + char *c_str = NULL; CFErrorRef err = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, code, NULL); CFStringRef str = CFErrorCopyDescription(err); - CFIndex length = CFStringGetLength(str); - CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, - kCFStringEncodingUTF8); - - char *c_str = malloc(max_size); - if (CFStringGetCString(str, c_str, max_size, kCFStringEncodingUTF8)) { + c_str = cfstr_copy_cstr(str, kCFStringEncodingUTF8); + if (c_str) { if (enc) VT_BLOG(log_level, "Error in %s: %s", context, c_str); else VT_LOG(log_level, "Error in %s: %s", context, c_str); } - free(c_str); + bfree(c_str); CFRelease(str); CFRelease(err); } @@ -875,14 +874,18 @@ static obs_properties_t *vt_h264_properties(void *unused) obs_properties_t *props = obs_properties_create(); obs_property_t *p; - obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 1); + p = obs_properties_add_int(props, "bitrate", + TEXT_BITRATE, 50, 10000000, 50); + obs_property_int_set_suffix(p, " Kbps"); p = obs_properties_add_bool(props, "limit_bitrate", TEXT_USE_MAX_BITRATE); obs_property_set_modified_callback(p, limit_bitrate_modified); - obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50, - 10000000, 1); + p = obs_properties_add_int(props, "max_bitrate", TEXT_MAX_BITRATE, 50, + 10000000, 50); + obs_property_int_set_suffix(p, " Kbps"); + obs_properties_add_float(props, "max_bitrate_window", TEXT_MAX_BITRATE_WINDOW, 0.10f, 10.0f, 0.25f); diff --git a/plugins/obs-ffmpeg/CMakeLists.txt b/plugins/obs-ffmpeg/CMakeLists.txt index 4c04ab1..34d08b0 100644 --- a/plugins/obs-ffmpeg/CMakeLists.txt +++ b/plugins/obs-ffmpeg/CMakeLists.txt @@ -13,6 +13,7 @@ set(obs-ffmpeg_HEADERS obs-ffmpeg-formats.h obs-ffmpeg-compat.h closest-pixel-format.h) + set(obs-ffmpeg_SOURCES obs-ffmpeg.c obs-ffmpeg-audio-encoders.c @@ -21,6 +22,21 @@ set(obs-ffmpeg_SOURCES obs-ffmpeg-mux.c obs-ffmpeg-source.c) +if(UNIX AND NOT APPLE) + list(APPEND obs-ffmpeg_SOURCES + obs-ffmpeg-vaapi.c) + LIST(APPEND obs-ffmpeg_PLATFORM_DEPS + ${LIBVA_LBRARIES}) +endif() + +if(WIN32) + list(APPEND obs-ffmpeg_SOURCES + jim-nvenc.c + jim-nvenc-helpers.c) + list(APPEND obs-ffmpeg_HEADERS + jim-nvenc.h) +endif() + add_library(obs-ffmpeg MODULE ${obs-ffmpeg_HEADERS} ${obs-ffmpeg_SOURCES}) diff --git a/plugins/obs-ffmpeg/data/locale/ar-SA.ini b/plugins/obs-ffmpeg/data/locale/ar-SA.ini index ec69c93..59e22e4 100644 --- a/plugins/obs-ffmpeg/data/locale/ar-SA.ini +++ b/plugins/obs-ffmpeg/data/locale/ar-SA.ini @@ -4,15 +4,11 @@ Bitrate="معدل النقل" Preset="الإعداد المسبق" -NVENC.Preset.default="الإفتراضي" -NVENC.Preset.hq="جودة عالية" -NVENC.Preset.hp="أداء عالي" -NVENC.Preset.bd="بلوراي Bluray" -NVENC.Level="المستوى" FFmpegSource="مصدر وسائط" LocalFile="ملف محلي" Looping="تكرار حلقي" +ClearOnMediaEnd="عدم إظهار شيء عند انتهاء التشغيل" Advanced="متقدم" ColorRange="نطاق ألوان YUV" ColorRange.Auto="تلقائي" diff --git a/plugins/obs-ffmpeg/data/locale/bg-BG.ini b/plugins/obs-ffmpeg/data/locale/bg-BG.ini index f4957f4..e772f17 100644 --- a/plugins/obs-ffmpeg/data/locale/bg-BG.ini +++ b/plugins/obs-ffmpeg/data/locale/bg-BG.ini @@ -1,8 +1,38 @@ FFmpegOutput="FFmpeg изход" +FFmpegAAC="Основен кодек FFmpeg AAC" +FFmpegOpus="Кодек FFmpeg Opus" Bitrate="Битрейт" - - - +MaxBitrate="Максимален битрейт" +Preset="Шаблон" +RateControl="Управление на битрейт" +KeyframeIntervalSec="Интервал на ключови кадри (секунди, 0=автоматично)" +Lossless="Без загуба на качество" + + +NVENC.Preset.default="Производителност" +NVENC.Preset.hq="Качество" +NVENC.Preset.hp="Максимална производителност" +NVENC.Preset.mq="Максимално качество" +NVENC.Preset.ll="Ниска латентност" +NVENC.Preset.llhq="Ниска латенност, високо качество" +NVENC.Preset.llhp="Ниска латентност, висока производителност" +NVENC.LookAhead="Предопределяне" +NVENC.CQLevel="Ниво CQ" + +FFmpegSource="Източник на медия" +LocalFile="Локален файл" +Looping="Преповтаряне" +Input="Вход" +InputFormat="Формат за вход" +BufferingMB="Мрежова буферизация (MB)" +HardwareDecode="Използване на хардуерно декодиране, ако е налично" +Advanced="Разширено" +RestartWhenActivated="Възобновява възпроизвеждането когато източникът е активен" +CloseFileWhenInactive="Затваряне на файла при неактивност" +ColorRange.Auto="Автоматично" +ColorRange.Partial="Частично" +ColorRange.Full="Пълно" +SpeedPercentage="Скорост (процент)" diff --git a/plugins/obs-ffmpeg/data/locale/bn-BD.ini b/plugins/obs-ffmpeg/data/locale/bn-BD.ini index 5fc90b2..4c4a17c 100644 --- a/plugins/obs-ffmpeg/data/locale/bn-BD.ini +++ b/plugins/obs-ffmpeg/data/locale/bn-BD.ini @@ -3,14 +3,9 @@ FFmpegAAC="পূর্ব-নির্ধারিত FFmpeg AAC এনকো Preset="পূর্ব-নির্ধারিত" RateControl="হার নিয়ন্ত্রণ" -BFrames="বি-ফ্রেম" NVENC.Use2Pass="দুই পাসে এনকোডিং ব্যবহার করো" -NVENC.Preset.default="পূর্ব-নির্ধারিত" NVENC.Preset.ll="লো-সুপ্ত" -NVENC.Preset.llhq="উচ্চ মান নিম্ন-সুপ্ত" -NVENC.Preset.llhp="লো-সুপ্ত উচ্চ কার্যক্ষমতা" -NVENC.Level="শ্রেনী" FFmpegSource="মিডিয়া উৎস" diff --git a/plugins/obs-ffmpeg/data/locale/ca-ES.ini b/plugins/obs-ffmpeg/data/locale/ca-ES.ini index 427a74c..c701ea6 100644 --- a/plugins/obs-ffmpeg/data/locale/ca-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/ca-ES.ini @@ -1,23 +1,28 @@ FFmpegOutput="Sortida FFmpeg" -FFmpegAAC="Codificador FFmpeg AAC predeterminat" +FFmpegAAC="Codificador FFmpeg AAC per defecte" FFmpegOpus="Codificador Opus FFmpeg" Bitrate="Taxa de bits" +MaxBitrate="Taxa de bits màxima" Preset="Valors predefinits" RateControl="Control de freqüència" KeyframeIntervalSec="Interval de fotograma clau (en segons, 0 = automàtic)" Lossless="Sense pèrdues" -BFrames="B-frames" +BFrames="Fotogrames-B màxims" NVENC.Use2Pass="Utilitza codificació en dues passades" -NVENC.Preset.default="Per defecte" -NVENC.Preset.hq="Alta Qualitat" -NVENC.Preset.hp="Alt rendiment" -NVENC.Preset.bd="BluRay" +NVENC.Preset.default="Rendiment" +NVENC.Preset.hq="Qualitat" +NVENC.Preset.hp="Rendiment màxim" +NVENC.Preset.mq="Qualitat màxima" NVENC.Preset.ll="Latencia baixa" -NVENC.Preset.llhq="Latència baixa Alta Qualitat" -NVENC.Preset.llhp="Latència baixa alt rendiment" -NVENC.Level="Nivell" +NVENC.Preset.llhq="Qualitat de latència baixa" +NVENC.Preset.llhp="Rendiment de latència baixa" +NVENC.LookAhead="Previsió" +NVENC.LookAhead.ToolTip="Habilita els Fotogrames-B dinàmics.\n\nEn inhabilitar-ho, el codificador utilitzarà sempre el nombre de Fotogrames-B indicat a l'opció «Fotogrames-B màxims».\n\nEn habilitar-ho, augmentarà la qualitat visual només utilitzant els Fotogrames-B necessaris,\nfins el màxim permès per l'ús de la GPU." +NVENC.PsychoVisualTuning="Ajust psico visual" +NVENC.PsychoVisualTuning.ToolTip="Permet la configuració del codificador que optimitza l'ús de la taxa de bits per millorar la qualitat visual percebuda,\nespecialment en situacions amb gran moviment, a costa d'una major utilització de la GPU." +NVENC.CQLevel="Nivell de quantificació constant" FFmpegSource="Font multimèdia" LocalFile="Fitxer local" @@ -26,7 +31,7 @@ Input="Entrada" InputFormat="Format d'entrada" BufferingMB="Memòria intermèdia de xarxa (MB)" HardwareDecode="Usa la descodificació per maquinari si és disponible" -ClearOnMediaEnd="Amaga l'origen en acabar la reproducció" +ClearOnMediaEnd="No mostris res quan acabi la reproducció" Advanced="Avançat" RestartWhenActivated="Reinicia la reproducció quan la font estigui activa" CloseFileWhenInactive="Tanca el fitxer quan estigui inactiu" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Desa la repetició" HelperProcessFailed="No s'ha pogut iniciar el procés d'assistència de gravació. Comproveu que els arxius d'OBS no han estat bloquejats o eliminats per qualsevol programa de seguretat de tercers." UnableToWritePath="No s'ha pogut escriure a %1. Assegureu-vos que utilitzeu una ruta de gravació a la qual el vostre compte d'usuari tingui permisos per escriure i que hi hagi prou espai al disc." +WarnWindowsDefender="Si la protecció contra Ransomware del Windows 10 està activada, també pot causar aquest error. Proveu inhabilitant la protecció contra amenaces del Windows a la configuració de seguretat/virus i protecció." diff --git a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini index 5f688a3..2df3cac 100644 --- a/plugins/obs-ffmpeg/data/locale/cs-CZ.ini +++ b/plugins/obs-ffmpeg/data/locale/cs-CZ.ini @@ -2,22 +2,27 @@ FFmpegOutput="Výstup FFmpegu" FFmpegAAC="Výchozí FFmpeg AAC enkodér" FFmpegOpus="FFmpeg Opus enkodér" Bitrate="Bitrate" +MaxBitrate="Maximální bitrate" Preset="Předvolba" RateControl="Řízení toku" KeyframeIntervalSec="Interval klíč. snímků (vteřiny, 0=auto)" Lossless="Lossless" -BFrames="B-frames" +BFrames="Maximum B-snímků" NVENC.Use2Pass="Použít dvoustupňové enkódování" -NVENC.Preset.default="Výchozí" -NVENC.Preset.hq="Vysoká kvalita" -NVENC.Preset.hp="Vysoký výkon" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Výkon" +NVENC.Preset.hq="Kvalita" +NVENC.Preset.hp="Maximální výkon" +NVENC.Preset.mq="Maximální kvalita" NVENC.Preset.ll="Nízká odezva" NVENC.Preset.llhq="Nízká odezva, vysoká kvalita" NVENC.Preset.llhp="Nízká odezva, vysoký výkon" -NVENC.Level="Úrověň" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Zapne dynamické B-snímky.\n\nPokud vypnuto, enkodér vždy použije číslo uvedené v nastavení 'Maximum B-snímků'.\n\nPokud zapnuto, zvýší se vizuální kvalita použitím tolika B-smínků, jak je potřeba, až do maxima,\nale za cenu zvýšení využití GPU." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Povolí nastavení enkodéru, které optimalizuje využití bitratu pro zvýšení vnímané vizuální kvality,\npředevším v situacích s velkým množstvím pohybu, ale za cenu zvýšení využití GPU." +NVENC.CQLevel="CQ úroveň" FFmpegSource="Médium" LocalFile="Místní soubor" @@ -26,7 +31,7 @@ Input="Vstup" InputFormat="Formát vstupu" BufferingMB="Vyrovnávací paměť pro síť (MB)" HardwareDecode="Použít hardwarové dekódování, pokud je k dispozici" -ClearOnMediaEnd="Skrýt zdroj po skončení přehrávání" +ClearOnMediaEnd="Po skončení přehrávání nezobrazovat nic" Advanced="Pokročilé" RestartWhenActivated="Restartovat přehrávání poté, co je zdroj aktivován" CloseFileWhenInactive="Zavřít soubor při neaktivitě" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Uložit záznam" HelperProcessFailed="Nelze spustit pomocný proces nahrávání. Zkontrolujte prosím, zda nejsou soubory OBS blokovány či odstraněny některý z antivirových programů třetích stran." UnableToWritePath="Nelze zapsat do %1. Zkontrolujte prosím, zda používáte úložiště, do kterého může váš uživatelský účet zapisovat a je zde dostatek volného místa." +WarnWindowsDefender="Pokud je zapnuta ochrana proti ransomwaru (Windows 10), může to také způsobit tuto chybu. Zkuste vypnout funkci kontrolovaných složek v nastavení Zabezpečení Windows / Ochrana proti virům." diff --git a/plugins/obs-ffmpeg/data/locale/da-DK.ini b/plugins/obs-ffmpeg/data/locale/da-DK.ini index 25277c1..8b3aad3 100644 --- a/plugins/obs-ffmpeg/data/locale/da-DK.ini +++ b/plugins/obs-ffmpeg/data/locale/da-DK.ini @@ -1,43 +1,48 @@ -FFmpegOutput="FFmpeg output" +FFmpegOutput="FFmpeg-output" FFmpegAAC="FFmpeg Standard AAC Encoder" FFmpegOpus="FFmpeg Opus-encoder" Bitrate="Bitrate" +MaxBitrate="Maks. bithastighed" Preset="Forudindstillet" RateControl="Tempokontrol" KeyframeIntervalSec="Keyframe-interval (sekunder, 0= auto)" Lossless="Tabsfri" -BFrames="B-rammer" +BFrames="Maks. B-billeder" NVENC.Use2Pass="Benyt to-trins kodning" -NVENC.Preset.default="Standard" -NVENC.Preset.hq="Høj kvalitet" -NVENC.Preset.hp="Høj ydeevne" -NVENC.Preset.bd="BluRay" -NVENC.Preset.ll="Lav latens" -NVENC.Preset.llhq="Lav-latens høj kvalitet" -NVENC.Preset.llhp="Lav latens høj ydeevne" -NVENC.Level="Niveau" +NVENC.Preset.default="Ydeevne" +NVENC.Preset.hq="Kvalitet" +NVENC.Preset.hp="Maks. ydeevne" +NVENC.Preset.mq="Maks. kvalitet" +NVENC.Preset.ll="Lavlatens" +NVENC.Preset.llhq="Lavlatenskvalitet" +NVENC.Preset.llhp="Lavlatensydeevne" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Aktiverer dynamiske B-frames.\n\nHvis deaktiveret, benytter encoderen altid antallet af B-frames angivet i indstillingen 'Maks. B-frames'.\n\nHvis aktiveret, forøges den visuelle kvalitet ved kun at benytte det nødvendige antal B-frames op til maksimum\npå bekostning af forøget GPU-forbrug." +NVENC.PsychoVisualTuning="Psychovisuel tuning" +NVENC.PsychoVisualTuning.ToolTip="Aktiverer encoderindstillinger, som optimerer brugen af bithastighed for øget opfattet visuel kvalitet,\nisær i situationer med megen bevægelse, på bekostning af forøget GPU-forbrug." +NVENC.CQLevel="CQ-niveau" FFmpegSource="Mediekilde" LocalFile="Lokal fil" Looping="Gentagelse" Input="Input" -InputFormat="Input format" +InputFormat="Inputformat" BufferingMB="Netværksbuffering (MB)" -HardwareDecode="Brug hardwareafkodning når tilgængelige" -ClearOnMediaEnd="Skjul kilde når afspilning slutter" +HardwareDecode="Benyt hardwareafkodning, når tilgængelig" +ClearOnMediaEnd="Vis intet, når afspilning afsluttes" Advanced="Avanceret" -RestartWhenActivated="Genstart afspilning når kilde bliver aktiv" -CloseFileWhenInactive="Luk fil når inaktiv" -CloseFileWhenInactive.ToolTip="Lukker filen, når kilden ikke vises i streamen ellerr\noptagelsen. Dette muliggør at filen kan ændres, når kilden er ikke aktiv, \nmen der kan være noget opstartsforsinkelse, når kilden genaktiveres." +RestartWhenActivated="Genstart afspilning, når kilde bliver aktiv" +CloseFileWhenInactive="Luk fil, når inaktiv" +CloseFileWhenInactive.ToolTip="Lukker filen, når kilden ikke vises i streamen ellerr\noptagelsen. Dette muliggør at filen kan ændres, når kilden er ikke aktiv,\nmen nogen opstartsforsinkelse kan forekomme, når kilden genaktiveres." ColorRange="YUV-farveområde" ColorRange.Auto="Auto" ColorRange.Partial="Delvis" ColorRange.Full="Fuld" RestartMedia="Genstart Media" SpeedPercentage="Hastighed (procent)" -Seekable="Seekable" +Seekable="Søgbar" MediaFileFilter.AllMediaFiles="Alle mediefiler" MediaFileFilter.VideoFiles="Videofiler" @@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="Alle filer" ReplayBuffer="Genafspilningsbuffer" ReplayBuffer.Save="Gem Genafspilning" -HelperProcessFailed="Kan ikke starte optagelseshjælperprocessen. Tjek at OBS-filer ikke blokeres eller er fjernet af noget 3. parts antivirus-/sikkerhedssoftware." -UnableToWritePath="Kan ikke skrive til %1. Tjek at du benytter en optagelsessti, som din brugerkonto har skriverettighed til, og at der er tilstrækkelig ledig diskplads." +HelperProcessFailed="Kan ikke starte optagelseshjælperprocessen. Tjek, at OBS-filer ikke blokeres eller er fjernet af 3. parts antivirus-/sikkerhedssoftware." +UnableToWritePath="Kan ikke skrive til %1. Tjek, at du benytter en optagelsessti, som din brugerkonto har skriverettighed til, og at der er tilstrækkelig ledig diskplads." +WarnWindowsDefender="Er Windows 10 Ransomware-beskyttelse aktiveret, kan dette også medføre denne fejl. Prøv at deaktivere kontrolleret mappeadgang i Windows-indstillingen Sikkerhed/Virus- og Trusselsbeskyttelse." diff --git a/plugins/obs-ffmpeg/data/locale/de-DE.ini b/plugins/obs-ffmpeg/data/locale/de-DE.ini index 2025bfb..ad95bdc 100644 --- a/plugins/obs-ffmpeg/data/locale/de-DE.ini +++ b/plugins/obs-ffmpeg/data/locale/de-DE.ini @@ -1,23 +1,28 @@ -FFmpegOutput="FFmpeg Ausgabe" -FFmpegAAC="FFmpeg Standard AAC Codierer" -FFmpegOpus="FFmpeg Opus Codierer" +FFmpegOutput="FFmpeg-Ausgabe" +FFmpegAAC="FFmpeg-Standard-AAC-Kodierer" +FFmpegOpus="FFmpeg-Opus-Kodierer" Bitrate="Bitrate" +MaxBitrate="Max. Bitrate" Preset="Voreinstellung" RateControl="Qualitäts Regulierungsmethode" -KeyframeIntervalSec="Keyframeintervall (Sekunden, 0=auto)" +KeyframeIntervalSec="Keyframeintervall in Sek. (0 = auto)" Lossless="Verlustfrei" -BFrames="B-frames" +BFrames="Max. B-Frames" -NVENC.Use2Pass="Benutze Two-Pass Codierung" -NVENC.Preset.default="Standard" -NVENC.Preset.hq="Hohe Qualität" -NVENC.Preset.hp="Hohe Leistung" -NVENC.Preset.bd="Bluray" +NVENC.Use2Pass="Two-Pass-Kodierung verwenden" +NVENC.Preset.default="Leistung" +NVENC.Preset.hq="Qualität" +NVENC.Preset.hp="Max. Leistung" +NVENC.Preset.mq="Max. Qualität" NVENC.Preset.ll="Niedrige Latenz" -NVENC.Preset.llhq="Niedrige Latenz, Hohe Qualität" -NVENC.Preset.llhp="Niedrige Latenz, Hohe Leistung" -NVENC.Level="Level" +NVENC.Preset.llhq="Niedrige Latenz + Qualität" +NVENC.Preset.llhp="Niedrige Latenz + Leistung" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Aktiviert dynamische B-Frames.\n\nWenn deaktiviert, wird der Kodierer immer die Anzahl der B-Frames verwenden, die in der „Max B-Frames“-Einstellung angegeben sind.\n\nWenn aktiviert, wird er die visuelle Qualität erhöhen, indem nur so viele B-Frames verwendet werden wie benötigt, bis zum Maximum,\nzu den Kosten einer erhöhten GPU-Nutzung." +NVENC.PsychoVisualTuning="Psycho-visuelle Optimierung" +NVENC.PsychoVisualTuning.ToolTip="Aktiviert Kodierereinstellungen, die die Verwendung der Bitrate für eine erhöhte wahrgenommene visuelle Qualität optimieren,\ninsbesondere in Situationen mit hoher Bewegung, zu Kosten einer erhöhten GPU-Nutzung." +NVENC.CQLevel="CQ-Level" FFmpegSource="Medienquelle" LocalFile="Lokale Datei" @@ -25,17 +30,17 @@ Looping="Endlosschleife" Input="Eingabe" InputFormat="Eingabeformat" BufferingMB="Netzwerkpufferung (MB)" -HardwareDecode="Verwende Hardwaredecodierung, falls verfügbar" -ClearOnMediaEnd="Quelle verbergen, wenn Wiedergabe endet" +HardwareDecode="Hardwaredekodierung verwenden, falls verfügbar" +ClearOnMediaEnd="Nichts anzeigen, wenn Wiedergabe endet" Advanced="Erweitert" RestartWhenActivated="Wiedergabe erneut starten, wenn Quelle aktiviert wird" CloseFileWhenInactive="Datei schließen, wenn inaktiv" -CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\n Dies ermöglicht, dass die Datei geändert wird, wenn die Quelle nicht aktiv ist,\n aber es gibt wahrscheinlich etwas Starverzögerung, wenn die Quelle reaktiviert wird." +CloseFileWhenInactive.ToolTip="Schließt die Datei, wenn die Quelle im Stream oder der Aufnahme nicht angezeigt wird.\nDies ermöglicht, dass die Datei geändert werden kann, wenn die Quelle nicht aktiv ist,\n aber es gibt wahrscheinlich etwas Startverzögerung, wenn die Quelle reaktiviert wird." ColorRange="YUV-Farbmatrix" ColorRange.Auto="Automatisch" ColorRange.Partial="Teilweise" ColorRange.Full="Voll" -RestartMedia="Medium neu starten" +RestartMedia="Medium neustarten" SpeedPercentage="Geschwindigkeit (Prozent)" Seekable="Durch­such­bar" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Replay speichern" HelperProcessFailed="Der Aufnahmehelferprozeß kann nicht gestartet werden. Überprüfen Sie, ob OBS-Dateien nicht von einer Drittanbieter Antiviren- / Sicherheitssoftware blockiert oder entfernt wurden." UnableToWritePath="Kann nicht zu %1 schreiben. Vergewissern Sie sich, dass Sie einen Aufnahmepfad verwenden, für das Ihr Benutzerkonto Schreibrechte hat und dass genügend Speicherplatz zur Verfügung steht." +WarnWindowsDefender="Wenn Windows-10-Ransomware-Schutz aktiviert ist, kann dies auch den Fehler auslösen. Versuchen Sie, den überwachten Ordnerzugriff in Windows-Sicherheit → Viren- & Bedrohungsschutz auszuschalten." diff --git a/plugins/obs-ffmpeg/data/locale/el-GR.ini b/plugins/obs-ffmpeg/data/locale/el-GR.ini index 77562dc..818f3c8 100644 --- a/plugins/obs-ffmpeg/data/locale/el-GR.ini +++ b/plugins/obs-ffmpeg/data/locale/el-GR.ini @@ -7,17 +7,9 @@ RateControl="Έλεγχος ρυθμού" KeyframeIntervalSec="Συχνότητα Καρέ-Κλειδιού (δευτερόλεπτα, 0=αυτόματο)" Lossless="Χωρίς απώλειες" -BFrames="Β-πλαίσια" NVENC.Use2Pass="Χρήση κωδικοποίησης δύο περασμάτων" -NVENC.Preset.default="Προεπιλογή" -NVENC.Preset.hq="Υψηλή Ποιότητα" -NVENC.Preset.hp="Υψηλές Επιδόσεις" -NVENC.Preset.bd="BluRay" NVENC.Preset.ll="Χαμηλή Καθυστέρηση" -NVENC.Preset.llhq="Χαμηλή Καθυστέρηση Υψηλή Ποιότητα" -NVENC.Preset.llhp="Χαμηλή Καθυστέρηση Υψηλές Επιδόσεις" -NVENC.Level="Επίπεδο" FFmpegSource="Πηγή Πολυμέσων" LocalFile="Τοπικό αρχείο" @@ -26,7 +18,6 @@ Input="Είσοδος" InputFormat="Μορφή Εισόδου" BufferingMB="Μέγεθος προσωρινης αποθήκευσης Δικτύου (MB)" HardwareDecode="Χρήση αποκωδικοποίησης υλικού όταν είναι διαθέσιμη" -ClearOnMediaEnd="Απόκρυψη πηγής όταν τελειώνει η αναπαραγωγή" Advanced="Σύνθετες επιλογές" RestartWhenActivated="Επανεκκίνηση της αναπαραγωγής όταν η πηγή γίνεται ξανά ενεργή" CloseFileWhenInactive="Κλείσιμο του αρχείου όταν η πηγή είναι ανενεργή" diff --git a/plugins/obs-ffmpeg/data/locale/en-US.ini b/plugins/obs-ffmpeg/data/locale/en-US.ini index 486aff1..7d762ac 100644 --- a/plugins/obs-ffmpeg/data/locale/en-US.ini +++ b/plugins/obs-ffmpeg/data/locale/en-US.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg Output" FFmpegAAC="FFmpeg Default AAC Encoder" FFmpegOpus="FFmpeg Opus Encoder" Bitrate="Bitrate" +MaxBitrate="Max Bitrate" Preset="Preset" RateControl="Rate Control" KeyframeIntervalSec="Keyframe Interval (seconds, 0=auto)" Lossless="Lossless" -BFrames="B-frames" +BFrames="Max B-frames" NVENC.Use2Pass="Use Two-Pass Encoding" -NVENC.Preset.default="Default" -NVENC.Preset.hq="High Quality" -NVENC.Preset.hp="High Performance" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Performance" +NVENC.Preset.hq="Quality" +NVENC.Preset.hp="Max Performance" +NVENC.Preset.mq="Max Quality" NVENC.Preset.ll="Low-Latency" -NVENC.Preset.llhq="Low-Latency High Quality" -NVENC.Preset.llhp="Low-Latency High Performance" -NVENC.Level="Level" +NVENC.Preset.llhq="Low-Latency Quality" +NVENC.Preset.llhp="Low-Latency Performance" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Enables dynamic B-frames.\n\nIf disabled, the encoder will always use the number of B-frames specified in the 'Max B-frames' setting.\n\nIf enabled, it will increase visual quality by only using however many B-frames are necessary, up to the maximum,\nat the cost of increased GPU utilization." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Enables encoder settings that optimize the use of bitrate for increased perceived visual quality,\nespecially in situations with high motion, at the cost of increased GPU utilization." +NVENC.CQLevel="CQ Level" FFmpegSource="Media Source" LocalFile="Local File" @@ -26,11 +31,11 @@ Input="Input" InputFormat="Input Format" BufferingMB="Network Buffering (MB)" HardwareDecode="Use hardware decoding when available" -ClearOnMediaEnd="Hide source when playback ends" +ClearOnMediaEnd="Show nothing when playback ends" Advanced="Advanced" RestartWhenActivated="Restart playback when source becomes active" CloseFileWhenInactive="Close file when inactive" -CloseFileWhenInactive.ToolTip="Closes the file when the source is not being displayed on the stream or\nrecording. This allows the file to be changed when the source isn't active,\nbut there may be some startup delay when the source reactivates." +CloseFileWhenInactive.ToolTip="Closes the file when the source is not being displayed on the stream or\nrecording. This allows the file to be changed when the source isn't active,\nbut there may be some startup delay when the source reactivates." ColorRange="YUV Color Range" ColorRange.Auto="Auto" ColorRange.Partial="Partial" @@ -49,3 +54,4 @@ ReplayBuffer.Save="Save Replay" HelperProcessFailed="Unable to start the recording helper process. Check that OBS files have not been blocked or removed by any 3rd party antivirus / security software." UnableToWritePath="Unable to write to %1. Make sure you're using a recording path which your user account is allowed to write to and that there is sufficient disk space." +WarnWindowsDefender="If Windows 10 Ransomware Protection is enabled it can also cause this error. Try turning off controlled folder access in Windows Security / Virus & threat protection settings." diff --git a/plugins/obs-ffmpeg/data/locale/es-ES.ini b/plugins/obs-ffmpeg/data/locale/es-ES.ini index 9dcb1cf..f218ee1 100644 --- a/plugins/obs-ffmpeg/data/locale/es-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/es-ES.ini @@ -2,22 +2,27 @@ FFmpegOutput="Salida de FFmpeg" FFmpegAAC="Codificador AAC FFmpeg predeterminado" FFmpegOpus="Codificador Opus de FFmpeg" Bitrate="Tasa de bits" +MaxBitrate="Tasa de bits máxima" Preset="Preajuste" RateControl="Control de la frecuencia" KeyframeIntervalSec="Intervalo de keyframes (segundos, 0=auto)" Lossless="Sin pérdidas" -BFrames="B-Frames" +BFrames="Máximos B-frames" NVENC.Use2Pass="Usar codificación en dos pasadas" -NVENC.Preset.default="Por defecto" -NVENC.Preset.hq="Alta Calidad" -NVENC.Preset.hp="Alto rendimiento" -NVENC.Preset.bd="BluRay" +NVENC.Preset.default="Rendimiento" +NVENC.Preset.hq="Calidad" +NVENC.Preset.hp="Rendimiento Máximo" +NVENC.Preset.mq="Máxima Calidad" NVENC.Preset.ll="Baja latencia" -NVENC.Preset.llhq="Baja latencia alta calidad" -NVENC.Preset.llhp="Baja latencia alto rendimiento" -NVENC.Level="Nivel" +NVENC.Preset.llhq="Calidad de baja Latencia" +NVENC.Preset.llhp="Rendimiento de baja Latencia" +NVENC.LookAhead="\"Look-Ahead\"" +NVENC.LookAhead.ToolTip="Habilita B-frames dinámicos.\n\nSi se deshabilita, el codificador siempre usará el número de B-frames especificado en el ajuste 'B-frames máximos'.\n\nSi se habilita, incrementará la calidad visual haciendo uso solo de la cantidad de B-frames necesaria, hasta el máximo,\na costa de incrementar el uso de la GPU." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Activa ajustes del codificador que optimizan el uso del bitrate para aumentar la calidad visual percibida,\nespecialmente en situaciones con alto movimiento, a costa de una mayor utilización de la GPU." +NVENC.CQLevel="Nivel de CQ" FFmpegSource="Fuente multimedia" LocalFile="Archivo local" @@ -26,7 +31,7 @@ Input="Entrada" InputFormat="Formato de entrada" BufferingMB="Almacenamiento búfer de Red (MB)" HardwareDecode="Utilizar la decodificación por hardware cuando esté disponible" -ClearOnMediaEnd="Ocultar la fuente cuando finaliza la reproducción" +ClearOnMediaEnd="No mostrar nada al terminar la reproducción" Advanced="Avanzado" RestartWhenActivated="Reiniciar la reproducción cuando la fuente esté activa" CloseFileWhenInactive="Cerrar archivo cuando esté inactivo" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Guardar repetición" HelperProcessFailed="No se pudo iniciar el proceso ayudante de grabación. Compruebe que los archivos de OBS no han sido bloqueados o eliminados por cualquier programa de seguridad externo." UnableToWritePath="No se pudo escribir a %1. Asegúrese de que utiliza una ruta de grabación que su cuenta de usuario tenga permisos para escribir y que haya suficiente espacio en disco." +WarnWindowsDefender="Si la protección del Ransomware de Windows 10 está activada, también puede causar este error. Intenta desactivar el acceso controlado a la carpeta en la configuración de protección de virus y virus de Windows." diff --git a/plugins/obs-ffmpeg/data/locale/et-EE.ini b/plugins/obs-ffmpeg/data/locale/et-EE.ini index 9fbb92d..bd6ea1d 100644 --- a/plugins/obs-ffmpeg/data/locale/et-EE.ini +++ b/plugins/obs-ffmpeg/data/locale/et-EE.ini @@ -7,21 +7,13 @@ Lossless="Kadudeta" NVENC.Use2Pass="Kasuta Two-Pass kodeeringut" -NVENC.Preset.default="Vaikimisi" -NVENC.Preset.hq="Kõrge kvaliteet" -NVENC.Preset.hp="Suur jõudlus" -NVENC.Preset.bd="Bluray" NVENC.Preset.ll="Madal-viivitus" -NVENC.Preset.llhq="Madal-viivitus Kõrge kvaliteediga" -NVENC.Preset.llhp="Madal-viivitus suure jõudlusega" -NVENC.Level="Tase" FFmpegSource="Meedia allikas" LocalFile="Kohalik fail" Looping="Korda" Input="Sisend" InputFormat="Sisestus formaat" -ClearOnMediaEnd="Peida allikas kui taasesitus lõppeb" RestartWhenActivated="Taaskäivita taasesitus, kui allikas muutub aktiivseks" ColorRange="YUV värviruumi vahemik" ColorRange.Auto="Automaatne" diff --git a/plugins/obs-ffmpeg/data/locale/eu-ES.ini b/plugins/obs-ffmpeg/data/locale/eu-ES.ini index 13d38a1..3c54c22 100644 --- a/plugins/obs-ffmpeg/data/locale/eu-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/eu-ES.ini @@ -1,23 +1,28 @@ FFmpegOutput="FFmpeg irteera" FFmpegAAC="FFmpeg lehenetsitako AAC Kodetzailea" FFmpegOpus="FFmpeg Opus kodetzailea" -Bitrate="Bit-tasa" -Preset="Aurrezarpena" +Bitrate="Bit-emaria" +MaxBitrate="Bit-emari maximoa" +Preset="Aurre-ezarpena" RateControl="Tasaren kontrola" KeyframeIntervalSec="Gako-fotogramen tartea (segundoak, 0=auto)" Lossless="Galerarik gabe" -BFrames="B-fotogramak" +BFrames="B-fotogramen maximoa" -NVENC.Use2Pass="Erabili bi urratseko kodeketa" -NVENC.Preset.default="Lehenetsia" -NVENC.Preset.hq="Kalitate handia" -NVENC.Preset.hp="Eraginkortasun handia" -NVENC.Preset.bd="Bluray" +NVENC.Use2Pass="Erabili bi pasaldiko kodeketa" +NVENC.Preset.default="Errendimendua" +NVENC.Preset.hq="Kalitatea" +NVENC.Preset.hp="Errendimendu maximoa" +NVENC.Preset.mq="Kalitate maximoa" NVENC.Preset.ll="Latentzia txikia" -NVENC.Preset.llhq="Latentzia txikia kalitate handia" -NVENC.Preset.llhp="Latentzia txikia eraginkortasun handia" -NVENC.Level="Maila" +NVENC.Preset.llhq="Latentzia txikiko kalitatea" +NVENC.Preset.llhp="Latentzia txikiko errendimendua" +NVENC.LookAhead="Aurrera begira" +NVENC.LookAhead.ToolTip="Gaitu B-fotograma dinamikoak.\n\nGalerazita badaude, kodetzaileak beti erabiliko du 'Max B-fotogramak' ezarpenetan zehazten den B-fotogramen kopurua.\n\nGaituta badaude, ikusmen kalitatea hobetuko du beharrezkoak diren B-fotogramen kopurua erabiliz, maximora iritsi arte\nordainez GPUren erabilera handituko bada ere." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Aukera ematen du kodetzailea konfiguratzeko optimizatzeko bit-ratioaren erabilera antzemandako ikusmen kalitatea hobetzeko,\nbatez ere mugimendu handiko egoeretan, ordainean GPUren erabilera handituz." +NVENC.CQLevel="CQ maila" FFmpegSource="Multimedia iturburua" LocalFile="Tokiko fitxategia" @@ -26,7 +31,7 @@ Input="Sarrera" InputFormat="Sarrera formatua" BufferingMB="Sareko bufferreratzea (MB)" HardwareDecode="Erabili hardware deskodeketa eskuragarri dagoenean" -ClearOnMediaEnd="Ezkutatu iturburua erreprodukzioa amaitzean" +ClearOnMediaEnd="Erreprodukzioa bukatzean ez erakutsi ezer" Advanced="Aurreratua" RestartWhenActivated="Berrabiarazi erreprodukzioa iturburua aktiboa dagoenean" CloseFileWhenInactive="Itxi fitxategia inaktibo dagoenean" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Gorde erreprodukzioa" HelperProcessFailed="Ezin izan da grabaziorako laguntza prozesua hasi. Begiratu hirugarren beten antibirusa edo seguritate-softwareak ez duela OBS fitxategiak blokeatzen edo ezabatzen." UnableToWritePath="Ezin izan da idatzi %1-ean. Egiaztatu grabazio-tokian idazteko baimena duzula eta diskoan leku libre nahikoa dagoela." +WarnWindowsDefender="Windows 10 Ransomware Protection aktibatuta egoteak errore hori ere sor dezake. Gehitu OBS Windows segurtasuna/ birus eta mehatxuen babeserako ezarpenen kontrolpeko karpeten sarbide-zerrendara." diff --git a/plugins/obs-ffmpeg/data/locale/fa-IR.ini b/plugins/obs-ffmpeg/data/locale/fa-IR.ini new file mode 100644 index 0000000..ea127f2 --- /dev/null +++ b/plugins/obs-ffmpeg/data/locale/fa-IR.ini @@ -0,0 +1,43 @@ +FFmpegOutput="خروجی FFmpeg" +FFmpegAAC="پیش فرض FFmpeg تخمین AAC" +FFmpegOpus="اپوس FFmpeg تخمین" +Bitrate="نرخ بیت" +MaxBitrate="حداکثر میزان نرخ بیت" +Preset="پیش فرض" +RateControl="کنترل نرخ" +KeyframeIntervalSec="فاصله Keyframe (ثانیه 0 = خودکار)" +Lossless="بدون تلف" + +BFrames="حد اکثر فریم های B" + +NVENC.Use2Pass="استفاده از کدگذاری 2 گذر" +NVENC.Preset.default="اجرا (کارایی)" +NVENC.Preset.hq="کیفیت" +NVENC.Preset.hp="حد اکثر اجرا (کارایی)" +NVENC.Preset.mq="حداکثر کیفیت" +NVENC.Preset.ll="زمان تاخیر کم" +NVENC.Preset.llhq="کیفیت پایین و زمان تاخیر" +NVENC.Preset.llhp="زمان تاخیر کم عملکرد" +NVENC.LookAhead="پیش رو نگاه" + +LocalFile="فایل محلی" +Looping="چرخه" +Input="ورودی" +InputFormat="فرمت های ورودی" +BufferingMB="شبکه بافری (مگابایت)" +ColorRange.Auto="خودکار" +ColorRange.Partial="جزئی" +ColorRange.Full="کامل" +RestartMedia="راه اندازی مجدد رسانه ها" +SpeedPercentage="سرعت (درصد)" +Seekable="جستجوگر" + +MediaFileFilter.AllMediaFiles="تمامی فایل های رسانه" +MediaFileFilter.VideoFiles="فایل‌های ویدئویی" +MediaFileFilter.AudioFiles="فایل‌های صوتی" +MediaFileFilter.AllFiles="همه‌ی فایل ها" + +ReplayBuffer="پخش مجدد بافر" +ReplayBuffer.Save="ذخیره پخش مجدد" + + diff --git a/plugins/obs-ffmpeg/data/locale/fi-FI.ini b/plugins/obs-ffmpeg/data/locale/fi-FI.ini index 1f24578..e36e7a6 100644 --- a/plugins/obs-ffmpeg/data/locale/fi-FI.ini +++ b/plugins/obs-ffmpeg/data/locale/fi-FI.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-ulostulo" FFmpegAAC="FFmpeg oletus AAC-enkooderi" FFmpegOpus="FFmpeg Opus -enkooderi" Bitrate="Bitrate" +MaxBitrate="Maksimi bitrate" Preset="Esiasetus" RateControl="Rate Control -tila" KeyframeIntervalSec="Keyframe-väli (sekunteina, 0=automaattinen)" Lossless="Häviötön" -BFrames="B-kehykset" +BFrames="Maksimi B-kehykset" NVENC.Use2Pass="Käytä Two-Pass enkoodausta" -NVENC.Preset.default="Oletusarvo" -NVENC.Preset.hq="Korkea laatu" -NVENC.Preset.hp="Korkea suorituskyky" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Suorituskyky" +NVENC.Preset.hq="Laatu" +NVENC.Preset.hp="Korkein suorituskyky" +NVENC.Preset.mq="Korkein laatu" NVENC.Preset.ll="Alhainen latenssi" NVENC.Preset.llhq="Alhainen latenssi, korkea laatu" NVENC.Preset.llhp="Alhainen latenssi, korkea suorituskyky" -NVENC.Level="Taso" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Käytä dynaamisia B-kehyksiä.\n\nPois päältä pidettäessä enkooderi käyttää aina B-kehysten lukumäärää joka on asetettu 'Maksimi B-kehykset' -kohdassa.\n\nKäytössä ollessaan se parantaa visuaalista laatua käyttäen vain tarvittavan määrän B-kehyksiä maksimiin asti,\nGPU:n käytön kustannuksella." +NVENC.PsychoVisualTuning="Psykovisuaalinen viritys" +NVENC.PsychoVisualTuning.ToolTip="Ottaa käyttöön enkooderin asetuksen GPU:n kustannuksella joka optimoi bitraten käytön\nkorkeampaan visuaaliseen laatuun varsinkin tilanteissa joissa liike on nopeaa." +NVENC.CQLevel="CQ-taso" FFmpegSource="Lisää media" LocalFile="Paikallinen tiedosto" @@ -26,7 +31,7 @@ Input="Sisääntulo" InputFormat="Sisääntulon muoto" BufferingMB="Verkon puskurointi (MB)" HardwareDecode="Käytä laitteistotason purkua, kun mahdollista" -ClearOnMediaEnd="Piilota lähde kun toisto päättyy" +ClearOnMediaEnd="Älä näytä mitään kun toisto päättyy" Advanced="Lisäasetukset" RestartWhenActivated="Aloita toisto uudelleen kun lähde aktivoituu" CloseFileWhenInactive="Sulje tiedosto, kun toimeton" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Tallenna uusinta" HelperProcessFailed="Nauhoitusavustaja-prosessin käynnistäminen ei onnistunut. Tarkista, että OBS-tiedostoja ei ole estetty tai poistettu virustutkan tai muun turvallisuusohjelman johdosta." UnableToWritePath="Ei voida kirjoittaa %1. Tarkista, että käytät oikeaa tiedostopolkua johon käyttäjätililläsi on kirjoitusoikeus. Tarkista myös, että levyllä on tarpeeksi tilaa." +WarnWindowsDefender="Tämä virhe saattaa aiheutua myös jos Windowsin Hyökkäysten esto on käytössä. Yritä kytkeä valvottujen kansioiden seuranta pois päältä Windowsin suojaus / Virusten ja uhkien torjunta -asetuksissa." diff --git a/plugins/obs-ffmpeg/data/locale/fil-PH.ini b/plugins/obs-ffmpeg/data/locale/fil-PH.ini index 7da7422..53a58a0 100644 --- a/plugins/obs-ffmpeg/data/locale/fil-PH.ini +++ b/plugins/obs-ffmpeg/data/locale/fil-PH.ini @@ -7,17 +7,9 @@ RateControl="Kontrolin ang Antas" KeyframeIntervalSec="Ang pagitan ng Keyframe (segundos, 0=auto)" Lossless="Lossless" -BFrames="B-frames" NVENC.Use2Pass="Gamitin ang Two-Pass Encoding" -NVENC.Preset.default="I-Default" -NVENC.Preset.hq="Itaas ang Kalidad" -NVENC.Preset.hp="Itaas ang Pagganap" -NVENC.Preset.bd="Bluray" NVENC.Preset.ll="Mababa na Latency" -NVENC.Preset.llhq="Mababa na Latency Mataas na kalidad" -NVENC.Preset.llhp="Mababa na Latency Mataas na pagganap" -NVENC.Level="Lebel" FFmpegSource="Pagkunan ng Media" LocalFile="Ang File na lokal" @@ -26,7 +18,6 @@ Input="Ang Input" InputFormat="Ang Format ng Input" BufferingMB="Nag buffering ang Network (MB)" HardwareDecode="Gamitin ang hardware decoding kapag magagamit" -ClearOnMediaEnd="Itago ang pinagmulan kung tapos ang playback" Advanced="I-Advanced" RestartWhenActivated="Simulan mulang ang playback kapag aktibo ang pinagmulan" CloseFileWhenInactive="Isarado ang file pag di aktibo" diff --git a/plugins/obs-ffmpeg/data/locale/fr-FR.ini b/plugins/obs-ffmpeg/data/locale/fr-FR.ini index 9b15413..4d9881f 100644 --- a/plugins/obs-ffmpeg/data/locale/fr-FR.ini +++ b/plugins/obs-ffmpeg/data/locale/fr-FR.ini @@ -2,22 +2,27 @@ FFmpegOutput="Sortie FFmpeg" FFmpegAAC="Encodeur AAC FFmpeg par défaut" FFmpegOpus="Encodeur FFmpeg Opus" Bitrate="Débit" -Preset="Préréglage" +MaxBitrate="Débit maximal" +Preset="Pré-réglage" RateControl="Contrôle du débit" KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" Lossless="Sans perte" -BFrames="B-frames" +BFrames="Nombre maximal de B-frames" NVENC.Use2Pass="Utiliser l'encodage double passe" -NVENC.Preset.default="Défaut" -NVENC.Preset.hq="Haute qualité" -NVENC.Preset.hp="Haute performance" -NVENC.Preset.bd="Blu-ray" -NVENC.Preset.ll="Faible latence" -NVENC.Preset.llhq="Faible latence haute qualité" -NVENC.Preset.llhp="Faible latence haute performance" -NVENC.Level="Niveau" +NVENC.Preset.default="Performances" +NVENC.Preset.hq="Qualité" +NVENC.Preset.hp="Performances maximales" +NVENC.Preset.mq="Qualité maximale" +NVENC.Preset.ll="Faible Latence" +NVENC.Preset.llhq="Qualité avec Faible Latence" +NVENC.Preset.llhp="Performance avec Faible Latence" +NVENC.LookAhead="Prédiction (Look-ahead)" +NVENC.LookAhead.ToolTip="Active les B-frames dynamiques.\n\nSi désactivé, l'encodeur utilisera toujours le nombre de B-frames dans le paramètre \"Nombre maximal de B-frames\".\n\nSi activé, il augmentera la qualité visuelle en n'utilisant que le nombre de B-frames nécessaire, inférieur au maximum,\nau prix d'une utilisation accrue de la carte graphique." +NVENC.PsychoVisualTuning="Améliorations psycho-visuelles" +NVENC.PsychoVisualTuning.ToolTip="Active des paramètres de l'encodeur qui optimisent l'utilisation du débit afin d'avoir une meilleure qualité visuelle perçue,\nen particulier lors de scènes comportant beaucoup de mouvement, au prix d'une utilisation accrue de la carte graphique." +NVENC.CQLevel="Niveau CQ" FFmpegSource="Source média" LocalFile="Fichier local" @@ -26,17 +31,17 @@ Input="Entrée" InputFormat="Format d'entrée" BufferingMB="Mémoire tampon réseau (Mo)" HardwareDecode="Utiliser le décodage matériel si possible" -ClearOnMediaEnd="Cacher la source lorsque la lecture est finie" +ClearOnMediaEnd="Ne rien afficher lorsque la lecture se termine" Advanced="Options avancées" RestartWhenActivated="Reprendre la lecture quand la source est active" CloseFileWhenInactive="Fermer fichier lorsqu’il est inactif" -CloseFileWhenInactive.ToolTip="Ferme le fichier lorsque la source ne s'affiche pas sur le flux ou \nl'enregistrement. Cela permet de modifier le fichier lorsque la source n'est pas active, \nmais il peut y avoir un délai de démarrage lorsque la source se réactive." +CloseFileWhenInactive.ToolTip="Ferme le fichier lorsque la source ne s'affiche pas sur le stream ou \nl'enregistrement. Cela permet de modifier le fichier lorsque la source n'est pas active, \nmais il peut y avoir un délai de démarrage lorsque la source se réactive." ColorRange="Gamme de couleurs YUV" ColorRange.Auto="Auto" ColorRange.Partial="Partielle" ColorRange.Full="Complète" -RestartMedia="Redémarrez Media" -SpeedPercentage="Vitesse (pourcent)" +RestartMedia="Reprendre depuis le début" +SpeedPercentage="Vitesse (pourcentage)" Seekable="Navigable" MediaFileFilter.AllMediaFiles="Tous les fichiers multimédias" @@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="Tous les fichiers" ReplayBuffer="Tampon de relecture" ReplayBuffer.Save="Sauvegarder la relecture" -HelperProcessFailed="Impossible de démarrer le processus d’assistance pour l’enregistrement. Vérifiez que les fichiers de OBS ne sont pas bloqués/supprimés par n’importe quel antivirus/logiciel de sécurité." -UnableToWritePath="Impossible d’écrire dans %1. Assurez-vous que vous utilisez un chemin d’enregistrement dont votre compte d’utilisateur est autorisé à écrire et qu’il y a suffisamment d’espace disque." +HelperProcessFailed="Impossible de démarrer le processus compagnon pour l’enregistrement. Vérifiez que les fichiers d'OBS ne sont pas bloqués/supprimés par un quelconque antivirus/logiciel de sécurité." +UnableToWritePath="Impossible d’écrire dans %1. Assurez-vous que vous utilisez un chemin d’enregistrement où votre compte d’utilisateur est autorisé à écrire et qu’il y a suffisamment d’espace disque." +WarnWindowsDefender="Si la Protection contre les ransomware de Windows 10 est activée, cela peut causer cette erreur. Essayez de désactiver le Dispositif d'accès contrôlé aux dossiers dans \"Sécurité Windows\" / \"Protection contre les virus et menaces\"." diff --git a/plugins/obs-ffmpeg/data/locale/gd-GB.ini b/plugins/obs-ffmpeg/data/locale/gd-GB.ini index 8c48562..3d519e0 100644 --- a/plugins/obs-ffmpeg/data/locale/gd-GB.ini +++ b/plugins/obs-ffmpeg/data/locale/gd-GB.ini @@ -2,22 +2,23 @@ FFmpegOutput="Às-chur FFmpeg" FFmpegAAC="Inneal-còdachaidh AAC tùsail airson FFmpeg" FFmpegOpus="Inneal-còdachaidh Opus airson FFmpeg" Bitrate="Reat bhiotaichean" +MaxBitrate="Reat bhiotaichean as motha" Preset="Ro-sheata" RateControl="Smachd air an reat" KeyframeIntervalSec="Eadaramh nam frèamaichean-iuchrach (diog, fèin-obrachail)" Lossless="Gun chall càileachd" -BFrames="Frèamaichean-B" +BFrames="Frèamaichean-B as motha" NVENC.Use2Pass="Cleachd còdachadh dà phas" -NVENC.Preset.default="Bun-roghainn" -NVENC.Preset.hq="Càileachd àrd" -NVENC.Preset.hp="Dèanadas àrd" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Dèanadas" +NVENC.Preset.hq="Càileachd" +NVENC.Preset.hp="Dèanadas as àirde" +NVENC.Preset.mq="Càileachd as àirde" NVENC.Preset.ll="Foillidheachd ìosal" -NVENC.Preset.llhq="Foillidheachd ìosal ⁊ càileachd àrd" -NVENC.Preset.llhp="Foillidheachd ìosal ⁊ dèanadas àrd" -NVENC.Level="Leibheil" +NVENC.Preset.llhq="Càileachd foillidheachd ìosail" +NVENC.Preset.llhp="Dèanadas foillidheachd ìosail" +NVENC.LookAhead="Coimhead roimhe" FFmpegSource="Tùs a’ mheadhain" LocalFile="Faidhle ionadail" @@ -26,7 +27,6 @@ Input="Ion-chur" InputFormat="Fòrmat an ion-chuir" BufferingMB="Bufair an lìonraidh (MB)" HardwareDecode="Cleachd dì-chòdachadh bathair-chruaidh ma bhios e ri fhaighinn" -ClearOnMediaEnd="Falaich an tùs nuair a bhios a’ chluiche deiseil" Advanced="Adhartach" RestartWhenActivated="Ath-thòisich a’ chluiche nuair a thig gnìomh on tùs" CloseFileWhenInactive="Dùin am faidhle mur eil gnìomh ann" diff --git a/plugins/obs-ffmpeg/data/locale/gl-ES.ini b/plugins/obs-ffmpeg/data/locale/gl-ES.ini index 1cde94a..196a04f 100644 --- a/plugins/obs-ffmpeg/data/locale/gl-ES.ini +++ b/plugins/obs-ffmpeg/data/locale/gl-ES.ini @@ -3,7 +3,6 @@ FFmpegAAC="Codificador AAC FFmpeg predefinido" Bitrate="Velocidade de bits" -NVENC.Level="Nivel" FFmpegSource="Fonte multimedia" LocalFile="Ficheiro local" @@ -11,7 +10,6 @@ Looping="Bucle" Input="Entrada" InputFormat="Formato de entrada" HardwareDecode="Utilizar a descodificación por hárdware cando estiver dispoñible" -ClearOnMediaEnd="Agochar a fonte cando a reprodución remata" Advanced="Avanzado" diff --git a/plugins/obs-ffmpeg/data/locale/he-IL.ini b/plugins/obs-ffmpeg/data/locale/he-IL.ini index 3d1c0db..dd7cfa2 100644 --- a/plugins/obs-ffmpeg/data/locale/he-IL.ini +++ b/plugins/obs-ffmpeg/data/locale/he-IL.ini @@ -8,14 +8,7 @@ Lossless="ללא אובדן נתונים" NVENC.Use2Pass="השתמש בקידוד שני מעברים" -NVENC.Preset.default="ברירת מחדל" -NVENC.Preset.hq="איכות גבוהה" -NVENC.Preset.hp="ביצועים גבוהים" -NVENC.Preset.bd="בלוריי" NVENC.Preset.ll="השהיה נמוכה" -NVENC.Preset.llhq="השהיה נמוכה איכות גבוהה" -NVENC.Preset.llhp="השהיה נמוכה ביצועים גבוהים" -NVENC.Level="רמה" FFmpegSource="מקור מדיה" LocalFile="קובץ מקומי" @@ -23,7 +16,6 @@ Looping="לולאה" Input="קלט" InputFormat="תבנית קלט" HardwareDecode="השתמש בפענוח חומרה כאשר היא זמין" -ClearOnMediaEnd="הסתר את מקור כאשר ההשמעה מסתיימת" Advanced="מתקדם" RestartWhenActivated="הפעל מחדש השמעה כאשר מקור הופך לפעיל" ColorRange="טווח צבעים YUV" diff --git a/plugins/obs-ffmpeg/data/locale/hr-HR.ini b/plugins/obs-ffmpeg/data/locale/hr-HR.ini index 839bc97..ee3d6fb 100644 --- a/plugins/obs-ffmpeg/data/locale/hr-HR.ini +++ b/plugins/obs-ffmpeg/data/locale/hr-HR.ini @@ -8,14 +8,7 @@ Lossless="Bez gubitka" NVENC.Use2Pass="Koristi enkoding duplog prolaza" -NVENC.Preset.default="Podrazumevani" -NVENC.Preset.hq="Visoki kvalitet" -NVENC.Preset.hp="Visoke performanse" -NVENC.Preset.bd="Bluray" NVENC.Preset.ll="Nisko kašnjenje" -NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja" -NVENC.Preset.llhp="Visoke performanse niskog kašnjenja" -NVENC.Level="Nivo" FFmpegSource="Medija izvor" LocalFile="Lokalna datoteka" @@ -23,7 +16,6 @@ Looping="Ponavljanje" Input="Ulaz" InputFormat="Format ulaza" HardwareDecode="Koristi hardversko enkodiranje kada je dostupno" -ClearOnMediaEnd="Sakrij izvor kada se reprodukcija završi" Advanced="Napredno" RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan" ColorRange="YUV opseg boja" diff --git a/plugins/obs-ffmpeg/data/locale/hu-HU.ini b/plugins/obs-ffmpeg/data/locale/hu-HU.ini index d1339a7..9f3c3b2 100644 --- a/plugins/obs-ffmpeg/data/locale/hu-HU.ini +++ b/plugins/obs-ffmpeg/data/locale/hu-HU.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg kimenet" FFmpegAAC="FFmpeg alapértelmezett AAC kódoló" FFmpegOpus="FFmpeg Opus kódoló" Bitrate="Bitsebesség" +MaxBitrate="Max bitsebesség" Preset="Készlet" RateControl="Sebesség Vezérlés" KeyframeIntervalSec="Kulcsképkocka időköze (másodperc, 0=auto)" Lossless="Veszteségmentes" -BFrames="B képkocka" +BFrames="Max B-kockák" NVENC.Use2Pass="Kétmenetes kódolás" -NVENC.Preset.default="Alapértelmezett" -NVENC.Preset.hq="Kiváló minőség" -NVENC.Preset.hp="Nagy teljesítmény" -NVENC.Preset.bd="BluRay" +NVENC.Preset.default="Teljesítménycentrikus" +NVENC.Preset.hq="Minőségcentrikus" +NVENC.Preset.hp="Maximális teljesítmény" +NVENC.Preset.mq="Maximális minőség" NVENC.Preset.ll="Alacsony-késleltetés" -NVENC.Preset.llhq="Alacsony-késleltetés kiváló minőséggel" -NVENC.Preset.llhp="Alacsony-késleltetés nagy teljesítménnyel" -NVENC.Level="Szint" +NVENC.Preset.llhq="Alacsony késleltetés minőséggel" +NVENC.Preset.llhp="Alacsony késleltetés nagyobb teljesítménnyel" +NVENC.LookAhead="Előretekintés" +NVENC.LookAhead.ToolTip="Lehetővé teszi a dinamikus B-kockákat.\n\nHa le van tiltva, a kódoló mindig a \"Max B-kockák\" beállításnál megadott értéket használja.\n\nHa engedélyezve van, az növeli vizuális minőséget és annyi B-kockát használ a kódoló, amennyire szükség van, akár a maximumot is,\nmegnövekedett GPU kihasználtság árán." +NVENC.PsychoVisualTuning="Psichovizuális Tuning" +NVENC.PsychoVisualTuning.ToolTip="Lehetővé teszi a kódoló beállításait bitráta optimalizáláshoz az érzékelhető vizuális minőség megnöveléséhez,\nkülönösen olyan helyzetekben ahol sok a mozgás, megnövekedett GPU kihasználtság árán." +NVENC.CQLevel="CQ szint" FFmpegSource="Médiaforrás" LocalFile="Helyi fájl" @@ -26,11 +31,11 @@ Input="Bemenet" InputFormat="Bemeneti formátum" BufferingMB="Hálózati pufferelés (MB)" HardwareDecode="Hardveres dekódolás használata, ha rendelkezésre áll" -ClearOnMediaEnd="Forrás elrejtése a lejátszás végeztével" +ClearOnMediaEnd="Semmit se mutasson, a lejátszás végeztével" Advanced="Haladó" RestartWhenActivated="Lejátszás újraindítása, ha a forrás aktivizálódik" CloseFileWhenInactive="Fájl bezárása ha tétlen" -CloseFileWhenInactive.ToolTip="Bezárja a fájlt, ha a forrás nem aktív streamen vagy\nfelvételen. Ez lehetővé teszi, hogy a fájlt meg kell változtatni, ha a forrás nem aktív, a \nviszont felléphet némi indítási késés, ha a forrás reaktiválódik." +CloseFileWhenInactive.ToolTip="Bezárja a fájlt, ha a forrás nem aktív streamen vagy\nfelvételen. Ez lehetővé teszi, hogy a fájlt meg kell változtatni, ha a forrás nem aktív, a \nviszont felléphet némi indítási késés, ha a forrás reaktiválódik." ColorRange="YUV színtartomány" ColorRange.Auto="Auto" ColorRange.Partial="Részleges" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Visszajátszás mentése" HelperProcessFailed="Nem lehet indítani a felvétel segítő folyamatot. Ellenőrizze, hogy az OBS fájlok nincsenek e blokkolva vagy eltávolítva bármilyen harmadik féltől származó antivírus / biztonsági szoftver által." UnableToWritePath="Nem lehet megírni a %1. Győződjön meg róla, hogy a felhasználói fiókjának megvannak a szükséges engedélyei az íráshoz vagy rendelkezésre áll az elegendő lemezterület." +WarnWindowsDefender="Amennyiben a Windows 10 Ransomware Védelem aktiválva van, úgy az is képes ezt a hibát generálni. Adja hozzá a kontrollált könyvtárlistához a Windows Biztonság / Vírus és fenyegetésvédelem beállítások között." diff --git a/plugins/obs-ffmpeg/data/locale/it-IT.ini b/plugins/obs-ffmpeg/data/locale/it-IT.ini index 2d69185..f0a14fd 100644 --- a/plugins/obs-ffmpeg/data/locale/it-IT.ini +++ b/plugins/obs-ffmpeg/data/locale/it-IT.ini @@ -1,52 +1,58 @@ FFmpegOutput="Uscita FFmpeg" -FFmpegAAC="Codificatore FFmpeg predefinito AAC" -FFmpegOpus="FFmpeg Opus Encoder" -Bitrate="Bitrate" +FFmpegAAC="Codifica FFmpeg predefinita per AAC" +FFmpegOpus="Codifica FFmpeg Opus" +Bitrate="Velocità in bit" +MaxBitrate="Velocità in bit massima" Preset="Preset" -RateControl="Controllo frequenza" -KeyframeIntervalSec="Intervallo Keyframe (secondi, 0=automatico)" +RateControl="Tipo di controllo della frequenza" +KeyframeIntervalSec="Intervallo dei fotogrammi chiave (in secondi, 0=automatico)" Lossless="Lossless" -BFrames="B-frames" +BFrames="B-frame massimi" -NVENC.Use2Pass="Usa codifica in due passaggi" -NVENC.Preset.default="Predefinito" -NVENC.Preset.hq="Alta Qualità" -NVENC.Preset.hp="Alte Prestazioni" -NVENC.Preset.bd="Bluray" +NVENC.Use2Pass="Utilizza la codifica in due passaggi" +NVENC.Preset.default="Prestazioni" +NVENC.Preset.hq="Qualità" +NVENC.Preset.hp="Massime prestazioni" +NVENC.Preset.mq="Massima qualità" NVENC.Preset.ll="Bassa latenza" -NVENC.Preset.llhq="Bassa latenza Alta Qualità" -NVENC.Preset.llhp="Bassa latenza ad Alte Prestazioni" -NVENC.Level="Livello" +NVENC.Preset.llhq="Bassa latenza e qualità" +NVENC.Preset.llhp="Bassa latenza e prestazioni" +NVENC.LookAhead="Previsione (look-ahead)" +NVENC.LookAhead.ToolTip="Attiva i B-frame dinamici.\n\nSe disattivato, la codifica utilizzerà sempre il numero di B-frame specificato nell'impostazione «B-frame massimi».\n\nSe attivato, aumenterà la qualità visiva utilizzando comunque solo i B-frame necessari,\nfino al massimo, al costo di un maggiore utilizzo della GPU." +NVENC.PsychoVisualTuning="Ottimizzazione visiva di Psycho" +NVENC.PsychoVisualTuning.ToolTip="Attiva le impostazioni di codifica che ottimizzano l'utilizzo della velocità in bit per ottenere una maggiore qualità visiva,\nsoprattutto in situazioni con molti movimenti, al costo di un maggiore utilizzo della GPU." +NVENC.CQLevel="Livello di quantificazione costante" -FFmpegSource="Origine multimediale" +FFmpegSource="Fonte multimediale" LocalFile="File locale" Looping="Ripeti" Input="Input" -InputFormat="Formato di input" -BufferingMB="Rete Buffering (MB)" +InputFormat="Formato dell'input" +BufferingMB="Buffering della rete (in MB)" HardwareDecode="Utilizza la decodifica hardware quando disponibile" -ClearOnMediaEnd="Nascondi la fonte quando termina la riproduzione" +ClearOnMediaEnd="Non mostrare nulla quando la riproduzione finisce" Advanced="Avanzate" -RestartWhenActivated="Riattiva playback quando la fonte torna attiva" -CloseFileWhenInactive="Chiudi file quando inattivo" -CloseFileWhenInactive.ToolTip="Chiude il file quando l'origine non viene visualizzato sullo stream o\nrecording il flusso. In questo modo permette di modificare il file quando la fonte non è attiva, \nma ci può essere qualche ritardo di avvio quando si riattiva l'origine." +RestartWhenActivated="Riavvia la riproduzione quando la fonte torna attiva" +CloseFileWhenInactive="Chiudi il file quando la fonte diventa inattiva" +CloseFileWhenInactive.ToolTip="Chiude il file quando la fonte non viene più visualizzata nell'inquadratura.\nQuesto permette di modificare il file quando la fonte non è attiva,\nma potrebbe esserci un po' di ritardo all'avvio quando si riattiva la fonte." ColorRange="Gamma di colore YUV" -ColorRange.Auto="Autom." +ColorRange.Auto="Automatico" ColorRange.Partial="Parziale" ColorRange.Full="Intero" -RestartMedia="Riavvia Media" -SpeedPercentage="Velocità (percentuale)" +RestartMedia="Riavvia media dall'inizio" +SpeedPercentage="Velocità (in percentuale)" Seekable="Ricercabile" -MediaFileFilter.AllMediaFiles="Tutti i file media" +MediaFileFilter.AllMediaFiles="Tutti i file multimediali" MediaFileFilter.VideoFiles="File video" MediaFileFilter.AudioFiles="File audio" MediaFileFilter.AllFiles="Tutti i file" -ReplayBuffer="Buffer di Replay" -ReplayBuffer.Save="Salva Replay" +ReplayBuffer="Buffer di replay" +ReplayBuffer.Save="Salva il replay" -HelperProcessFailed="Impossibile avviare il processo di supporto di registrazione. Verifica che i file di OBS non siano stati bloccati o rimossi da software di sicurezza od antivirus di terze parti." -UnableToWritePath="Impossibile scrivere su %1. Assicurati che il tuo account possa accedere al percorso di registrazione, e che ci sia spazio sufficiente su disco." +HelperProcessFailed="Impossibile avviare il processo di assistenza alla registrazione. Controlla che i file di OBS non siano stati bloccati o rimossi da software di sicurezza di terze parti o antivirus." +UnableToWritePath="Impossibile scrivere su %1. Assicurati che il tuo account utente possa accedere al percorso di registrazione, e che ci sia spazio sufficiente sul disco." +WarnWindowsDefender="Se la protezione ransomware di Windows 10 è attivata, può causare questo errore. Prova a disattivare l'accesso alle cartelle controllato, lo puoi trovare in Sicurezza di Windows → Protezione da virus e minacce → Gestisci protezione ransomware." diff --git a/plugins/obs-ffmpeg/data/locale/ja-JP.ini b/plugins/obs-ffmpeg/data/locale/ja-JP.ini index c291993..e790cb3 100644 --- a/plugins/obs-ffmpeg/data/locale/ja-JP.ini +++ b/plugins/obs-ffmpeg/data/locale/ja-JP.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg の出力" FFmpegAAC="FFmpeg 既定のAAC エンコーダ" FFmpegOpus="FFmpeg Opus エンコーダ" Bitrate="ビットレート" +MaxBitrate="最大ビットレート" Preset="プリセット" RateControl="レート制御" KeyframeIntervalSec="キーフレーム間隔 (秒, 0=自動)" Lossless="無損失" -BFrames="B-フレーム" +BFrames="最大 B フレーム" NVENC.Use2Pass="2パスエンコードを使用" -NVENC.Preset.default="既定" -NVENC.Preset.hq="高品質" -NVENC.Preset.hp="高性能" -NVENC.Preset.bd="ブルーレイ" -NVENC.Preset.ll="低遅延" -NVENC.Preset.llhq="低遅延高品質" -NVENC.Preset.llhp="低遅延高性能" -NVENC.Level="レベル" +NVENC.Preset.default="Performance" +NVENC.Preset.hq="Quality" +NVENC.Preset.hp="Max Performance" +NVENC.Preset.mq="Max Quality" +NVENC.Preset.ll="Low-Latency" +NVENC.Preset.llhq="Low-Latency Quality" +NVENC.Preset.llhp="Low-Latency Performance" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="動的Bフレームを有効にします。 \n\n無効にすると、エンコーダは常に’最大Bフレーム数’設定で指定されたBフレーム数を使用します。 \n\n有効にした場合、GPU使用率の増加を犠牲にして、\n\n最大数まで、必要な分だけ多くのBフレームを使用することで視覚的品質を向上させます。" +NVENC.PsychoVisualTuning="心理視覚チューニング" +NVENC.PsychoVisualTuning.ToolTip="GPU使用率の増加を犠牲にして、特に動きの激しい状況で、\n視覚品質の向上のためにビットレートの使用を最適化するエンコーダ設定を有効にします。" +NVENC.CQLevel="CQ レベル" FFmpegSource="メディアソース" LocalFile="ローカルファイル" @@ -26,7 +31,7 @@ Input="入力" InputFormat="入力フォーマット" BufferingMB="ネットワークバッファリング (MB)" HardwareDecode="可能な場合ハードウェアデコードを使用" -ClearOnMediaEnd="再生終了時にソースを非表示にする" +ClearOnMediaEnd="再生終了時に何も表示しない" Advanced="高度な設定" RestartWhenActivated="ソースがアクティブになったときに再生を再開する" CloseFileWhenInactive="アクティブでないときにファイルを閉じる" @@ -44,9 +49,10 @@ MediaFileFilter.VideoFiles="ビデオファイル" MediaFileFilter.AudioFiles="オーディオファイル" MediaFileFilter.AllFiles="すべてのファイル" -ReplayBuffer="リプレイバッファー" +ReplayBuffer="リプレイバッファ" ReplayBuffer.Save="リプレイ保存" HelperProcessFailed="録画の補助プロセスを開始できません。 OBSのファイルがサードパーティ製のアンチウイルス/セキュリティソフトウェアによってブロックまたは削除されていないことを確認してください。" UnableToWritePath="%1 に書き込めません。 あなたのユーザーアカウントが書き込みを許可されている録画のパスを使用していることと十分なディスク容量があることを確認してください。" +WarnWindowsDefender="Windows 10 ランサムウェア保護が有効になっていると、このエラーが発生する可能性があります。Windowsのセキュリティ/ウイルス対策と脅威対策の設定で、フォルダへのアクセス制御を無効にしてみてください。" diff --git a/plugins/obs-ffmpeg/data/locale/ka-GE.ini b/plugins/obs-ffmpeg/data/locale/ka-GE.ini index f1d9220..cd244e0 100644 --- a/plugins/obs-ffmpeg/data/locale/ka-GE.ini +++ b/plugins/obs-ffmpeg/data/locale/ka-GE.ini @@ -1,23 +1,28 @@ -FFmpegOutput="FFmpeg გამომავალი სიგნალი" +FFmpegOutput="FFmpeg-გამოტანა" FFmpegAAC="FFmpeg ნაგულისხმევი AAC დამშიფრავი" FFmpegOpus="FFmpeg Opus დამშიფრავი" Bitrate="ბიტური სიხშირე" +MaxBitrate="უმაღლესი დასაშვები ბიტური სიხშირე" Preset="მზა პარამეტრები" RateControl="სიხშირის მართვა" KeyframeIntervalSec="საკვანძო კადრებს შორის შუალედი (წამი, 0=თვითშერჩევა)" Lossless="უდანაკარგო" -BFrames="B-კადრები" +BFrames="B-კადრების დასაშვები რაოდენობა" NVENC.Use2Pass="ორმაგი დაშიფვრის გამოყენება" -NVENC.Preset.default="ნაგულისხმევი" -NVENC.Preset.hq="მაღალი ხარისხი" -NVENC.Preset.hp="მაღალი წარმადობა" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="წარმადობა" +NVENC.Preset.hq="ხარისხი" +NVENC.Preset.hp="უმაღლესი წარმადობა" +NVENC.Preset.mq="უმაღლესი ხარისხი" NVENC.Preset.ll="მცირე დაყოვნება" -NVENC.Preset.llhq="მცირე დაყოვნება, მაღალი ხარისხი" -NVENC.Preset.llhp="მცირე დაყოვნება, მაღალი წარმადობა" -NVENC.Level="საფეხური" +NVENC.Preset.llhq="მცირე დაყოვნება მაღალი ხარისხით" +NVENC.Preset.llhp="მცირე დაყოვნება მაღალი წარმადობით" +NVENC.LookAhead="თვითგანსაზღვრა" +NVENC.LookAhead.ToolTip="ჩაირთვება ცვალებადი რაოდენობის B-კადრები.\n\nგამორთვის შემთხვევაში, დამშიფრავი ყოველთვის „B-კადრების დასაშვები რაოდენობის“ ველში მითითებულს გამოიყენებს.\n\nჩართვის შედეგად, გაიზრდება გამოსახულების ხარისხი საჭირო რაოდენობის B-კადრების დამატებით, უმაღლეს დასაშვებ რაოდენობამდე,\nგრაფიკული პროცესორის გაზრდილი დატვირთვის ხარჯზე." +NVENC.PsychoVisualTuning="ფსიქოვიზუალური გამართვა" +NVENC.PsychoVisualTuning.ToolTip="საშუალებას აძლევს დამშიფრავს, საუკეთესოდ შეარჩიოს ბიტური სიხშირე გამოსახულების ხარისხის უკეთ აღქმისთვის,\nგანსაკუთრებით მოძრავ სცენებში, გრაფიკული პროცესორის გაზრდილი დატვირთვის ხარჯზე." +NVENC.CQLevel="CQ-დონე (მუდმივ ნაწილაკებად დაყოფა)" FFmpegSource="მასალის წყარო" LocalFile="ადგილობრივი ფაილი" @@ -26,11 +31,11 @@ Input="შეტანა" InputFormat="შეტანის ფორმატი" BufferingMB="ქსელის ბუფერიზაცია (მბაიტი)" HardwareDecode="აპარატურული დაშიფვრის გამოყენება, ხელმისაწვდომობის შემთხვევაში" -ClearOnMediaEnd="წყაროს დამალვა, გაშვების დამთავრებისას" +ClearOnMediaEnd="აღარაფერი გამოჩნდეს, ჩვენების დასრულების შემდგომ" Advanced="გაფართოებული" RestartWhenActivated="ხელახლა გაშვება წყაროს ამოქმედებისას" CloseFileWhenInactive="ფაილის დახურვა უმოქმედობისას" -CloseFileWhenInactive.ToolTip="ფაილი დაიხურება, თუ წყარო არ იქნება ეთერში ან\nჩაწერაზე გაშვებული. ეს საშუალებას იძლევა შეიცვალოს ფაილი, როცა წყარო არაა მოქმედი,\nთუმცა ხელახლა ამოქმედებისას, შესაძლოა გარკვეული დროით დაყოვნებას ჰქონდეს ადგილი." +CloseFileWhenInactive.ToolTip="ფაილი დაიხურება, თუ წყარო არ იქნება ეთერში ან\nჩაწერაზე გაშვებული. ეს საშუალებას იძლევა შეიცვალოს ფაილი, როცა წყარო არაა მოქმედი,\nთუმცა ხელახლა ამოქმედებისას, შესაძლოა გარკვეული დროით დაყოვნებას ჰქონდეს ადგილი." ColorRange="YUV ფერთა გამა" ColorRange.Auto="ავტომატური" ColorRange.Partial="ნაწილობრივი" @@ -49,4 +54,5 @@ ReplayBuffer.Save="გადახვევის შენახვა" HelperProcessFailed="ჩაწერის პროცესის გაშვება ვერ ხერხდება. გადაამოწმეთ, ხომ არ არის OBS ფაილები შეზღუდული ან წაშლილი ანტივირუსის / უსაფრთხოების სხვა პროგრამების მიერ." UnableToWritePath="%1-ში ჩაწერა ვერ ხერხდება. დარწმუნდით, რომ ჩაწერისთვის ისეთი მისამართი გაქვთ მითითებული, სადაც ჩაწერის ნებართვაც გააჩნია თქვენს ანგარიშს და ამასთან, არის საკმარისი ადგილი დისკზე." +WarnWindowsDefender="თუ ჩართულია Windows 10-ის დაცვა ფაილების მიმტაცებელი პროგრამებისგან (Ransomware), ამ შეცდომას ეგეც შეიძლება იწვევდეს. სცადეთ საქაღალდეებთან წვდომის შეზღუდვის მოხსნა, Windows-ის უსაფრთხოების ან ანტივირუსის პარამეტრებიდან." diff --git a/plugins/obs-ffmpeg/data/locale/ko-KR.ini b/plugins/obs-ffmpeg/data/locale/ko-KR.ini index 535fdb8..292f8b3 100644 --- a/plugins/obs-ffmpeg/data/locale/ko-KR.ini +++ b/plugins/obs-ffmpeg/data/locale/ko-KR.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 출력" FFmpegAAC="FFmpeg 기본 AAC 인코더" FFmpegOpus="FFmpeg Opus 인코더" Bitrate="비트레이트" +MaxBitrate="최대 비트레이트" Preset="사전 설정" RateControl="데이터율 제어" KeyframeIntervalSec="키프레임 간격 (초 단위, 0=자동)" Lossless="무손실" -BFrames="B-화면" +BFrames="최대 B-프레임" NVENC.Use2Pass="2 패스 인코딩 사용" -NVENC.Preset.default="기본" -NVENC.Preset.hq="우수한 품질" -NVENC.Preset.hp="우수한 성능" -NVENC.Preset.bd="블루레이" +NVENC.Preset.default="성능 우선" +NVENC.Preset.hq="품질 우선" +NVENC.Preset.hp="최대 성능" +NVENC.Preset.mq="최대 품질" NVENC.Preset.ll="낮은 지연 시간" -NVENC.Preset.llhq="낮은 지연 시간 우수한 품질" -NVENC.Preset.llhp="낮은 지연 시간 우수한 성능" -NVENC.Level="수준" +NVENC.Preset.llhq="낮은 지연 시간 및 품질" +NVENC.Preset.llhp="낮은 지연 시간 및 성능" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="동적 B-프레임을 활성화합니다.\n\n이 설정을 사용하지 않으면 인코더는 항상 지정한 수 만큼만 B-프레임을 사용합니다.\n\n이 설정을 켜면 B-프레임을 품질을 올리는데 필요한 만큼 사용하지만,\nGPU사용률이 증가합니다." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="비트레이트 사용을 최적화하여 영상 품질을 높일 수 있습니다.\n특히 영상 내 빠른 동작을 처리할 때 도움이 됩니다. 다만 GPU 사용률이 증가합니다." +NVENC.CQLevel="CQ 수준" FFmpegSource="미디어 소스" LocalFile="로컬 파일" @@ -26,7 +31,7 @@ Input="입력" InputFormat="입력 형식" BufferingMB="네트워크 버퍼링 (MB)" HardwareDecode="가능한 경우 하드웨어 디코딩 사용" -ClearOnMediaEnd="재생이 끝나면 소스를 숨기기" +ClearOnMediaEnd="재생이 끝나면 아무 것도 표시하지 않기" Advanced="고급" RestartWhenActivated="소스가 활성화될 때 재생을 다시 시작" CloseFileWhenInactive="비활성화 상태일 때 파일 닫기" @@ -49,4 +54,5 @@ ReplayBuffer.Save="리플레이 저장" HelperProcessFailed="녹화 도우미를 시작할 수 없습니다. 백신이나 보안 소프트웨어가 OBS 파일을 차단 혹은 제거하지 않았는지 확인하십시오." UnableToWritePath="%1에 기록할 수 없습니다. 사용자 계정이 녹화 계정에 접근할 수 있는지 혹은 저장 공간이 충분한지 확인하십시오." +WarnWindowsDefender="윈도우 10에서 제공하는 랜섬웨어 보호 기능이 켜져 있으면 이 오류가 일어날 수 있습니다. 윈도우 설정에서 '보호된 폴더' 기능을 검색하여 꺼주세요." diff --git a/plugins/obs-ffmpeg/data/locale/nb-NO.ini b/plugins/obs-ffmpeg/data/locale/nb-NO.ini index 7439c6e..30849de 100644 --- a/plugins/obs-ffmpeg/data/locale/nb-NO.ini +++ b/plugins/obs-ffmpeg/data/locale/nb-NO.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg utdata" FFmpegAAC="Standard FFmpeg AAC-koder" FFmpegOpus="FFmpeg Opus enkoder" Bitrate="Bitrate" +MaxBitrate="Maks bitrate" Preset="Forhåndsinnstilling" RateControl="Hastighetskontroll" KeyframeIntervalSec="Nøkkelbildeintervall (sekunder, 0 = automatisk)" Lossless="Tapsfri" -BFrames="B-bilder" +BFrames="Maksimalt antall B-frames" NVENC.Use2Pass="Bruk tostegskoding" -NVENC.Preset.default="Standard" -NVENC.Preset.hq="Høy kvalitet" -NVENC.Preset.hp="Høy ytelse" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Ytelse" +NVENC.Preset.hq="Kvalitet" +NVENC.Preset.hp="Best ytelse" +NVENC.Preset.mq="Best kvalitet" NVENC.Preset.ll="Lav latens" -NVENC.Preset.llhq="Lav latens, høy kvalitet" -NVENC.Preset.llhp="Lav latens, høy ytelse" -NVENC.Level="Nivå" +NVENC.Preset.llhq="Lav latens og kvalitet" +NVENC.Preset.llhp="Lav latens og ytelse" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Aktiverer dynamiske B-frames. \n\nHvis deaktivert, vil koderen alltid bruke nummeret spesifisert i \"Maks B-frames\" instillingen. \n\nHvis aktivert, vil bildekvaliteten forbedres ved å bare bruke antallet nødvendige B-frames, opp til maksimum antallet,\npå bekostning av økt GPU-forbruk." +NVENC.PsychoVisualTuning="Psykovisuell justering" +NVENC.PsychoVisualTuning.ToolTip="Aktiverer kodingsinstillinger som optimerer bruken av bitrate for forbedret oppfattet bildekvalitet,\nspesielt i situasjonen med mye bevegelse, på bekostning av økt GPU-forbruk." +NVENC.CQLevel="QC-nivå" FFmpegSource="Mediekilde" LocalFile="Lokal fil" @@ -26,7 +31,7 @@ Input="Inngang" InputFormat="Inngangsformat" BufferingMB="Nettverksbuffer (Mb)" HardwareDecode="Bruk maskinvaredekoding når tilgjengelig" -ClearOnMediaEnd="Skjul kilde når avspilling ender" +ClearOnMediaEnd="Vis ingenting når avspillingen slutter" Advanced="Avansert" RestartWhenActivated="Start avspilling omigjen når kilde blir aktiv" CloseFileWhenInactive="Lukk fil når inaktiv" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Lagre replay" HelperProcessFailed="Kan ikke starte prosess for opptakshjelper. Sjekk at OBS ikke har noen blokkerte filer, eller at tredjeparts antivirus/sikkerhetsprogramvare har slettet noen filer." UnableToWritePath="Kan ikke skrive til %1. Kontroller at du bruker en filbane som kontoen din har rettigheter til å skrive på, og at du har nok diskplass tilgjengelig." +WarnWindowsDefender="Hvis Windows 10 Ransomvare-beskyttelse er aktivert, kan dette medføre denne feilen. Forsøk å deaktivere kontrollert mappetilgang i Windows-instillingen Sikkerhet > Virus- og Trusselbeskyttelse." diff --git a/plugins/obs-ffmpeg/data/locale/nl-NL.ini b/plugins/obs-ffmpeg/data/locale/nl-NL.ini index 62c9163..7f996d7 100644 --- a/plugins/obs-ffmpeg/data/locale/nl-NL.ini +++ b/plugins/obs-ffmpeg/data/locale/nl-NL.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-uitvoer" FFmpegAAC="FFmpeg Standaard AAC Encoder" FFmpegOpus="FFmpeg Opus Encoder" Bitrate="Bitrate" +MaxBitrate="Maximale bitrate" Preset="Preset" RateControl="Rate Control" KeyframeIntervalSec="Tijd tussen keyframes (seconden, 0=auto)" Lossless="Lossless" -BFrames="B-frames" +BFrames="Max B-frames" NVENC.Use2Pass="Gebruik two-pass encoding" -NVENC.Preset.default="Standaard" -NVENC.Preset.hq="Hoge kwaliteit" -NVENC.Preset.hp="Hoge prestaties" -NVENC.Preset.bd="Blu-ray" +NVENC.Preset.default="Prestaties" +NVENC.Preset.hq="Kwaliteit" +NVENC.Preset.hp="Hoogste Prestaties" +NVENC.Preset.mq="Hoogste Kwaliteit" NVENC.Preset.ll="Lage Latency" -NVENC.Preset.llhq="Lage latency, hoge kwaliteit" -NVENC.Preset.llhp="Lage latency, hoge prestaties" -NVENC.Level="Niveau" +NVENC.Preset.llhq="Lage Latency Kwaliteit" +NVENC.Preset.llhp="Lage Latency Prestaties" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Maakt dynamische B-frames mogelijk.\n\nIndien uitgeschakeld, zal de encoder altijd het aantal B-frames gebruiken dat is opgegeven in de instelling 'Max B-frames'.\n\nIndien ingeschakeld, zal het de visuele kwaliteit verhogen door alleen het aantal B-frames te gebruiken dat nodig is, tot het maximum,\nten koste van een verhoogd GPU-gebruik." +NVENC.PsychoVisualTuning="Psycho Visuele Stemming" +NVENC.PsychoVisualTuning.ToolTip="Maakt encoderinstellingen mogelijk die het gebruik van de bitsnelheid optimaliseren voor een hogere waargenomen visuele kwaliteit,\nvooral in situaties met veel beweging, ten koste van een hoger GPU-gebruik." +NVENC.CQLevel="CQ effen" FFmpegSource="Mediabron" LocalFile="Lokaal bestand" @@ -26,7 +31,7 @@ Input="Invoer" InputFormat="Invoerformaat" BufferingMB="Netwerk Buffering (MB)" HardwareDecode="Gebruik hardware-decoding wanneer mogelijk" -ClearOnMediaEnd="Verberg de bron na het afspelen" +ClearOnMediaEnd="Toon niets wanneer het afspelen eindigt" Advanced="Geavanceerd" RestartWhenActivated="Opnieuw starten met afspelen zodra de bron actief wordt" CloseFileWhenInactive="Sluit bestand wanneer niet actief" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Replay Opslaan" HelperProcessFailed="Kan het opnamehulp-proces niet starten. Controleer of er geen OBS bestanden geblokkeerd of verwijderd zijn door antivirus of beveiligingssoftware." UnableToWritePath="Kan niet naar %1 schrijven. Controller of je een opnamepad gebruikt waar je gebruikersaccount naartoe kan schrijven, en dat er voldoende schijfruimte beschikbaar is." +WarnWindowsDefender="Als Windows 10 Ransomware Protection is ingeschakeld, kan dit ook deze fout veroorzaken. Probeer gecontroleerde toegang tot mappen uit te schakelen in de instellingen van Windows Security / Virus & Threat Protection." diff --git a/plugins/obs-ffmpeg/data/locale/pl-PL.ini b/plugins/obs-ffmpeg/data/locale/pl-PL.ini index 09f1f5d..2be79c9 100644 --- a/plugins/obs-ffmpeg/data/locale/pl-PL.ini +++ b/plugins/obs-ffmpeg/data/locale/pl-PL.ini @@ -1,23 +1,28 @@ FFmpegOutput="Wyjście FFmpeg" FFmpegAAC="Domyślny enkoder AAC w FFmpeg" FFmpegOpus="Enkoder FFmpeg Opus" -Bitrate="Przepływność bitowa" +Bitrate="Przepływność (bitrate)" +MaxBitrate="Maksymalna przepływność (bitrate)" Preset="Profil ustawień" RateControl="Typ przepływności" KeyframeIntervalSec="Odstęp między klatkami kluczowymi (sekundy, 0=automatyczny)" Lossless="Bezstratny" -BFrames="B-ramki" +BFrames="Maksymalna liczba klatek B-frame" NVENC.Use2Pass="Użyj enkodowania dwuprzebiegowego" -NVENC.Preset.default="Domyślny" -NVENC.Preset.hq="Wysoka jakość" -NVENC.Preset.hp="Wysoka wydajność" -NVENC.Preset.bd="Blu-ray" +NVENC.Preset.default="Wydajność" +NVENC.Preset.hq="Jakość" +NVENC.Preset.hp="Najlepsza wydajność" +NVENC.Preset.mq="Najlepsza jakość" NVENC.Preset.ll="Niskie opóźnienie" -NVENC.Preset.llhq="Niskie opóźnienie - wysoka jakość" -NVENC.Preset.llhp="Niskie opóźnienie - wysoka wydajność" -NVENC.Level="Poziom" +NVENC.Preset.llhq="Niskie opóźnienie - jakość" +NVENC.Preset.llhp="Niskie opóźnienie - wydajność" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Umożliwia dynamiczne klatki B.\n\nJeśli jest wyłączony, koder będzie zawsze używać liczbę klatek B określonego w ustawieniach 'Maksymalnych klatkach B'.\n\nJeśli włączony, zwiększy jakość obrazu przy użyciu jakkolwiek wiele klatek B które są konieczne, do maksymum\nkosztem zwiększenia wykorzystania procesora graficznego." +NVENC.PsychoVisualTuning="Psycho Visual Tuning" +NVENC.PsychoVisualTuning.ToolTip="Umożliwia ustawienia kodera, które optymalizują użycie bitratów dla zwiększonej jakość wizualnej,\n, zwłaszcza w sytuacjach z wysokim ruchem, kosztem zwiększonego wykorzystania procesora graficznego." +NVENC.CQLevel="Poziom CQ" FFmpegSource="Źródło danych" LocalFile="Plik lokalny" @@ -26,7 +31,7 @@ Input="Wejście" InputFormat="Format wejściowy" BufferingMB="Bufor sieciowy (MB)" HardwareDecode="Użyj sprzętowego dekodowania gdy to możliwe" -ClearOnMediaEnd="Ukryj źródło po zakończeniu odtwarzania" +ClearOnMediaEnd="Po zakończeniu odtwarzania nie pokazuj nic" Advanced="Zaawansowane" RestartWhenActivated="Zrestartuj odtwarzanie, gdy źródła będą aktywne" CloseFileWhenInactive="Zamknij plik, gdy niekatywne" @@ -44,9 +49,10 @@ MediaFileFilter.VideoFiles="Pliki video" MediaFileFilter.AudioFiles="Pliki audio" MediaFileFilter.AllFiles="Wszystkie pliki" -ReplayBuffer="Bufor replay" -ReplayBuffer.Save="Zapisz replay" +ReplayBuffer="Nagrywanie powtórek" +ReplayBuffer.Save="Zapisz nagraną powtórkę" HelperProcessFailed="Nie można uruchomić procesu nagrywania. Sprawdź, czy pliki OBS nie są blokowane lub usunięte przez oprogramowanie zewnętrzne, np. antywirusowe lub chroniące system." UnableToWritePath="Nie można zapisać do %1. Sprawdź poprawność ścieżki zapisu, prawa dostępu do niej oraz wolne miejsce na dysku." +WarnWindowsDefender="Błąd ten może być spowodowany również włączoną ochroną Windows 10 przed ransomware. Prosimy spróbować wyłączyć \"Kontrolowany dostęp do folderu\" w sekcji Ochrona przed wirusami i zagrożeniami." diff --git a/plugins/obs-ffmpeg/data/locale/pt-BR.ini b/plugins/obs-ffmpeg/data/locale/pt-BR.ini index 2004e1a..85fa70e 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-BR.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-BR.ini @@ -2,22 +2,27 @@ FFmpegOutput="Saída do FFmpeg" FFmpegAAC="Codificador AAC Padrão do FFmpeg" FFmpegOpus="Codificador FFmpeg Optus" Bitrate="Taxa de Bits" +MaxBitrate="Taxa de Bits Máxima" Preset="Predefinição" RateControl="Controle da Taxa de Bits" KeyframeIntervalSec="Intervalo de Keyframe (segundos, 0=auto)" Lossless="Sem perdas" -BFrames="B-frames" +BFrames="B-Frames Máximo" NVENC.Use2Pass="Utilizar a codificação em dois passos" -NVENC.Preset.default="Padrão" -NVENC.Preset.hq="Alta Qualidade" -NVENC.Preset.hp="Alta Performance" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Desempenho" +NVENC.Preset.hq="Qualidade" +NVENC.Preset.hp="Alto Desempenho" +NVENC.Preset.mq="Qualidade Máxima" NVENC.Preset.ll="Baixa Latência" -NVENC.Preset.llhq="Baixa Latência e Alta Qualidade" -NVENC.Preset.llhp="Baixa latência e Alta Performance" -NVENC.Level="Nível" +NVENC.Preset.llhq="Qualidade com Baixa Latência" +NVENC.Preset.llhp="Desempenho com Baixa Latência" +NVENC.LookAhead="Olhar quadros futuros" +NVENC.LookAhead.ToolTip="Habilita B-Frames dinâmicos.\n\nSe desabilitado, o codificador sempre usará o número de B-Frames especificados na configuração de 'B-Frames Máximo'.\n\nSe habilitado, aumentará a qualidade visual usando apenas B-Frames necessários, até o máximo,\nao custo de uma maior utilização da GPU." +NVENC.PsychoVisualTuning="Ajuste Psico-Visual" +NVENC.PsychoVisualTuning.ToolTip="Permite configurações do codificador que otimizam o uso da taxa de bits para uma melhoria\n perceptível na qualidade - especialmente em situações com muitos movimentos - com o custo de mais utilização da GPU." +NVENC.CQLevel="Nível de CQ" FFmpegSource="Fonte de mídia" LocalFile="Arquivo Local" @@ -26,11 +31,11 @@ Input="Entrada" InputFormat="Formato de entrada" BufferingMB="Buffer de Rede (MB)" HardwareDecode="Utilizar descodificação de hardware quando disponível" -ClearOnMediaEnd="Ocultar fonte quando a reprodução terminar" +ClearOnMediaEnd="Não mostrar nada quando terminar a reprodução" Advanced="Avançado" RestartWhenActivated="Reiniciar reprodução quando a fonte se tornar ativa" CloseFileWhenInactive="Fechar arquivo quando inativo" -CloseFileWhenInactive.ToolTip="Fechar o arquivo quando a fonte não estiver sendo exibida na transmissão\n ou gravação. Isto permite alterar o arquivo quando a fonte não está ativa,\nmas pode ter algum atraso de inicialização quando a fonte for reativada." +CloseFileWhenInactive.ToolTip="Fechar o arquivo quando a fonte não estiver sendo exibida na transmissão\n ou gravação. Isto permite alterar o arquivo quando a fonte não está ativa,\nmas pode ter algum atraso de inicialização quando a fonte for reativada." ColorRange="Intervalo de Cores YUV" ColorRange.Auto="Auto" ColorRange.Partial="Parcial" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Salvar Replay" HelperProcessFailed="Não foi possível iniciar o processo auxiliar de gravação. Verifique se os arquivos do OBS não foram bloqueados ou removidos por qualquer outro software (Ex: antivírus)." UnableToWritePath="Não foi possível escrever em %1. Certifique-se de que você está usando um caminho de gravação que sua conta de usuário possui permissão para gravar e que há espaço suficiente no disco." +WarnWindowsDefender="Este erro pode acontecer também por causa da Proteção contra Ransomware do Windows 10. Experimente desligar o acesso controlado a pastas em: Configurações do Windows Defender > Proteção contra vírus e ameaças." diff --git a/plugins/obs-ffmpeg/data/locale/pt-PT.ini b/plugins/obs-ffmpeg/data/locale/pt-PT.ini index 54a5ba0..d8e2cee 100644 --- a/plugins/obs-ffmpeg/data/locale/pt-PT.ini +++ b/plugins/obs-ffmpeg/data/locale/pt-PT.ini @@ -1,20 +1,21 @@ FFmpegOutput="Saída de FFmpeg" FFmpegAAC="Codificador AAC padrão do FFmpeg" +FFmpegOpus="FFmpeg Opus Encoder" Bitrate="Bitrate" +MaxBitrate="Bitrate Máximo" Preset="Predefinição" RateControl="Controle de Taxa" KeyframeIntervalSec="Intervalo do keyframe (segundos, 0=automático)" Lossless="Sem perdas" +BFrames="B-frames Máximas" -NVENC.Preset.default="Predefinido" -NVENC.Preset.hq="Alta Qualidade" -NVENC.Preset.hp="Alto Desempenho" -NVENC.Preset.bd="Bluray" +NVENC.Use2Pass="Usar codificação a dois passos" +NVENC.Preset.default="Desempenho" +NVENC.Preset.hq="Qualidade" +NVENC.Preset.hp="Máximo Desempenho" +NVENC.Preset.mq="Qualidade Máxima" NVENC.Preset.ll="Baixa latência" -NVENC.Preset.llhq="Baixa latência Alta Qualidade" -NVENC.Preset.llhp="Baixa latência Alto Desempenho" -NVENC.Level="Nível" FFmpegSource="Fonte de multimédia" LocalFile="Ficheiro local" @@ -22,13 +23,14 @@ Looping="Repetir" Input="Entrada" InputFormat="Formato de entrada" HardwareDecode="Utilizar descodificação de hardware quando disponível" -ClearOnMediaEnd="Ocultar fonte quando a reprodução terminar" Advanced="Avançado" RestartWhenActivated="Reiniciar reprodução quando a fonte se torna ativo" +CloseFileWhenInactive="Fechar ficheiro quando inativo" ColorRange="Gama de cor YUV" ColorRange.Auto="Auto" ColorRange.Partial="Parcial" ColorRange.Full="Completo" +SpeedPercentage="Velocidade (percentagem)" MediaFileFilter.AllMediaFiles="Todos os Arquivos de Media" MediaFileFilter.VideoFiles="Arquivos de Vídeo" diff --git a/plugins/obs-ffmpeg/data/locale/ro-RO.ini b/plugins/obs-ffmpeg/data/locale/ro-RO.ini index 6ac99f2..535519b 100644 --- a/plugins/obs-ffmpeg/data/locale/ro-RO.ini +++ b/plugins/obs-ffmpeg/data/locale/ro-RO.ini @@ -2,19 +2,25 @@ FFmpegOutput="Ieșire FFmpeg" FFmpegAAC="Codificator AAC implicit FFmpeg" Bitrate="Rată de biți" Preset="Presetare" +RateControl="Controlul ratei" +KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)" -NVENC.Preset.default="Implicită" -NVENC.Preset.bd="Bluray" -NVENC.Level="Nivel" +NVENC.Preset.default="Performanță" +NVENC.Preset.hq="Calitate" +NVENC.Preset.hp="Performanță maximă" +NVENC.Preset.mq="Calitate maximă" +NVENC.Preset.ll="Latență redusă" +NVENC.Preset.llhq="Calitate cu latență redusă" +NVENC.Preset.llhp="Performanță cu latență redusă" FFmpegSource="Sursă media" LocalFile="Fișier local" Looping="Buclă" Input="Intrare" InputFormat="Format de intrare" +BufferingMB="Zonă tampon pentru rețea (MB)" HardwareDecode="Folosește decodarea hardware când este disponibilă" -ClearOnMediaEnd="Ascunde sursa atunci când se termină redarea" Advanced="Avansat" RestartWhenActivated="Repornește redarea când sursa devine activă" ColorRange="Gamă de culori YUV" diff --git a/plugins/obs-ffmpeg/data/locale/ru-RU.ini b/plugins/obs-ffmpeg/data/locale/ru-RU.ini index c0aeeef..c68c87a 100644 --- a/plugins/obs-ffmpeg/data/locale/ru-RU.ini +++ b/plugins/obs-ffmpeg/data/locale/ru-RU.ini @@ -2,22 +2,27 @@ FFmpegOutput="Вывод FFmpeg" FFmpegAAC="Стандартный AAC-кодер FFmpeg" FFmpegOpus="Кодировщик FFmpeg Opus" Bitrate="Битрейт" +MaxBitrate="Макс. битрейт" Preset="Пресет" RateControl="Управление битрейтом" KeyframeIntervalSec="Интервал ключевых кадров (сек, 0=авто)" Lossless="Без потерь" -BFrames="B-Кадры" +BFrames="Макс. кол-во B-кадров" NVENC.Use2Pass="Использовать двухпроходное кодирование" -NVENC.Preset.default="По умолчанию" -NVENC.Preset.hq="Высокое качество" -NVENC.Preset.hp="Высокая производительность" -NVENC.Preset.bd="Blu-ray" +NVENC.Preset.default="Производительность" +NVENC.Preset.hq="Качество" +NVENC.Preset.hp="Макс. производительность" +NVENC.Preset.mq="Макс. качество" NVENC.Preset.ll="Малая задержка" NVENC.Preset.llhq="Малая задержка, высокое качество" NVENC.Preset.llhp="Малая задержка, высокая производительность" -NVENC.Level="Уровень" +NVENC.LookAhead="Предугадывание" +NVENC.LookAhead.ToolTip="Включает динамические B-кадры.\n\nЕсли отключено, кодировщик всегда будет использовать количество B-кадров, указанное в параметре 'Макс. кол-во B-кадров'.\n\nЕсли включено, то это увеличит визуальное качество изображения путем использования любого количества B-кадров, вплоть до максимума,\nза счет увеличения использования GPU." +NVENC.PsychoVisualTuning="Психовизуальная корректировка" +NVENC.PsychoVisualTuning.ToolTip="Включает настройки кодировщика, которые оптимизируют использование битрейта для повышенного восприятия визуального качества,\nособенно в ситуациях с высоким движением, за счет увеличения использования GPU." +NVENC.CQLevel="Уровень QC" FFmpegSource="Источник медиа" LocalFile="Локальный файл" @@ -26,7 +31,7 @@ Input="Ввод" InputFormat="Формат ввода" BufferingMB="Сетевая буферизация (МБ)" HardwareDecode="Использовать аппаратное декодирование при наличии" -ClearOnMediaEnd="Скрывать источник, когда воспроизведение заканчивается" +ClearOnMediaEnd="Ничего не показывать, когда воспроизведение заканчивается" Advanced="Дополнительно" RestartWhenActivated="Перезапустить воспроизведение, когда источник становится активным" CloseFileWhenInactive="Закрыть файл при отсутствии активности" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Сохранить повтор" HelperProcessFailed="Невозможно запустить вспомогательный процесс для записи. Проверьте, не были ли заблокированы или удалены файлы OBS сторонним антивирусом / защитным ПО." UnableToWritePath="Невозможно записать в %1. Убедитесь, что для вашей учетной записи разрешена запись по этому пути, и что на диске достаточно свободного пространства." +WarnWindowsDefender="Если включена Защита от программ-шантажистов Windows 10, это так же может вызывать эту ошибку. Попробуйте выключить контролируемый доступ к папкам в параметрах Безопасности Windows / Защита от вирусов и угроз." diff --git a/plugins/obs-ffmpeg/data/locale/sk-SK.ini b/plugins/obs-ffmpeg/data/locale/sk-SK.ini index 67fbe86..451fd83 100644 --- a/plugins/obs-ffmpeg/data/locale/sk-SK.ini +++ b/plugins/obs-ffmpeg/data/locale/sk-SK.ini @@ -3,13 +3,13 @@ FFmpegAAC="Predvolený FFmpeg AAC enkodér" FFmpegOpus="FFmpeg Opus enkodér" Bitrate="Bitrate" Preset="Predvoľba" +RateControl="Riadenie toku" +KeyframeIntervalSec="Interval kľúčových snímok (sekúnd, 0 = automaticky)" +Lossless="Bezstratová" -NVENC.Preset.default="Predvolená" -NVENC.Preset.hq="Vysoká kvalita" -NVENC.Preset.hp="Vysoký výkon" -NVENC.Preset.bd="BluRay" -NVENC.Level="Úroveň" +NVENC.Use2Pass="Použiť dvojfázové enkódovanie" +NVENC.Preset.ll="Nízka odozva" FFmpegSource="Zdroj médií" LocalFile="Lokálny súbor" @@ -19,15 +19,25 @@ InputFormat="Vstupný formát" BufferingMB="Sieťové zapisovanie do medzipamäte (MB)" HardwareDecode="Použiť hardvérové dekódovanie podľa dostupnosti" Advanced="Rozšírené" +RestartWhenActivated="Obnoviť prehrávanie pri aktivovaní zdroja" +CloseFileWhenInactive="Zatvoriť súbor pri neaktivite" +CloseFileWhenInactive.ToolTip="Zatvorí súbor, ak zdroj nie je práve zobrazovaný vo vysielaní\nalebo nahrávaní. Toto umožní zmeny súboru pri neaktivite zdroja,\nale môže spôsobiť oneskorenie pri opätovnom použití zdroja." ColorRange="Rozsah farieb YUV" ColorRange.Auto="Automaticky" ColorRange.Partial="Čiastočný" ColorRange.Full="Plný" +RestartMedia="Reštartuj mediálny zdroj" +SpeedPercentage="Rýchlosť (v percentách)" +Seekable="Posúvateľný" MediaFileFilter.AllMediaFiles="Všetky mediálne súbory" MediaFileFilter.VideoFiles="Video súbory" MediaFileFilter.AudioFiles="Zvukové súbory" MediaFileFilter.AllFiles="Všetky súbory" +ReplayBuffer="Medzipamäť znovuprehratia" +ReplayBuffer.Save="Uložiť záznam" +HelperProcessFailed="Nepodarilo sa spustiť pomocný proces nahrávania. Skontrolujte, či neboli súbory OBS zablokované alebo odstránené zabezpečovacím softvérom/antivírusom tretej strany." +UnableToWritePath="Nedá sa zapisovať do %1. Uistite sa, že v ceste nahrávania má váš používateľský účet právo na zápis a že máte dostatok miesta na disku." diff --git a/plugins/obs-ffmpeg/data/locale/sl-SI.ini b/plugins/obs-ffmpeg/data/locale/sl-SI.ini index 3d54ab6..2a40a24 100644 --- a/plugins/obs-ffmpeg/data/locale/sl-SI.ini +++ b/plugins/obs-ffmpeg/data/locale/sl-SI.ini @@ -10,7 +10,6 @@ Looping="Ponavljaj" Input="Vhod" InputFormat="Format vnosa" HardwareDecode="Uporabi strojno pospeševanje, ko je na voljo" -ClearOnMediaEnd="Skri vir, ko se predvajanje konča" Advanced="Napredno" diff --git a/plugins/obs-ffmpeg/data/locale/sr-CS.ini b/plugins/obs-ffmpeg/data/locale/sr-CS.ini index 839bc97..d2830ac 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-CS.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-CS.ini @@ -1,40 +1,57 @@ FFmpegOutput="FFmpeg izlaz" FFmpegAAC="FFmpeg podrazumevani AAC enkoder" +FFmpegOpus="FFmpeg Opus enkoder" Bitrate="Protok" +MaxBitrate="Maksimalni protok" Preset="Šablon" RateControl="Kontrola protoka" KeyframeIntervalSec="Interval ključnih frejmova (sekunde, 0=automatski)" Lossless="Bez gubitka" +BFrames="Maksimalni B-frejmovi" NVENC.Use2Pass="Koristi enkoding duplog prolaza" -NVENC.Preset.default="Podrazumevani" -NVENC.Preset.hq="Visoki kvalitet" -NVENC.Preset.hp="Visoke performanse" -NVENC.Preset.bd="Bluray" -NVENC.Preset.ll="Nisko kašnjenje" -NVENC.Preset.llhq="Visoki kvalitet niskog kašnjenja" -NVENC.Preset.llhp="Visoke performanse niskog kašnjenja" -NVENC.Level="Nivo" +NVENC.Preset.default="Performanse" +NVENC.Preset.hq="Kvalitet" +NVENC.Preset.hp="Maksimalne performanse" +NVENC.Preset.mq="Maksimalni kvalitet" +NVENC.Preset.ll="Malo kašnjenje" +NVENC.Preset.llhq="Kvalitet malog kašnjenja" +NVENC.Preset.llhp="Performanse malog kašnjenja" +NVENC.LookAhead="Gledanje unapred" +NVENC.LookAhead.ToolTip="Uključuje dinamičke B-frejmove.\n\n Ako je isključeno, enkoder će uvek koristiti broj B-frejmova naveden u 'Maksimalni B-frejmovi' delu.\n\nUkoliko je uključeno, povećaće vizuelni kvalitet korišćenjem onoliko B-frejmova koliko je potrebno, do maksimalnog broja,\npo cenu povećane upotrebe GPU-a." +NVENC.PsychoVisualTuning="Psiho vizuelna podešavanja" +NVENC.PsychoVisualTuning.ToolTip="Uključuje podešavanja enkodera koja optimizuju korišćenje protoka za povećani vizuelni kvalitet,\nposebno u situacijama sa ubrzanim pokretima, po cenu povećane upotrebe GPU-a." +NVENC.CQLevel="CQ Nivo" FFmpegSource="Medija izvor" LocalFile="Lokalna datoteka" Looping="Ponavljanje" Input="Ulaz" InputFormat="Format ulaza" +BufferingMB="Baferovanje mreže (MB)" HardwareDecode="Koristi hardversko enkodiranje kada je dostupno" -ClearOnMediaEnd="Sakrij izvor kada se reprodukcija završi" Advanced="Napredno" RestartWhenActivated="Ponovi reprodukciju kada izvor postane aktivan" +CloseFileWhenInactive="Zatvori fajl kada je neaktivan" +CloseFileWhenInactive.ToolTip="Zatvorite fajl kada izvor nije prikazan tokom strimovanja ili\nna snimku. Ovo omogućava fajlu da bude izmenjen kada izvor nije aktivan,\nali je moguće da se javi određeno kašnjenje kada se izvor ponovo aktivira." ColorRange="YUV opseg boja" ColorRange.Auto="Automatski" ColorRange.Partial="Delimični" ColorRange.Full="Potpuni" +RestartMedia="Restartuj medij" +SpeedPercentage="Brzina (procenat)" +Seekable="Pretraživanje" MediaFileFilter.AllMediaFiles="Sve medija datoteke" MediaFileFilter.VideoFiles="Video datoteke" MediaFileFilter.AudioFiles="Zvučne datoteke" MediaFileFilter.AllFiles="Sve datoteke" +ReplayBuffer="Bafer za ponovno reprodukovanje" +ReplayBuffer.Save="Sačuvaj ponovno reprodukovanje" +HelperProcessFailed="Nemoguće je pokrenuti pomoć za snimanje. Proverite da li su OBS fajlovi blokirani ili premešteni od strane nekog antivirus softvera/softvera za zaštitu." +UnableToWritePath="Nemoguće je pisati na %1. Proverite da li koristite putanju kojoj vaš nalog ima pravo da pristupi i da li imate dovoljno prostora na disku." +WarnWindowsDefender="Ova greška takođe može da nastane ako je Windows 10 Ransomware Protection uključen. Pokušajte da isključite kontrolisani pristup folderu u podešavanjima za Windows Sigurnost/Zaštitu od virusa." diff --git a/plugins/obs-ffmpeg/data/locale/sr-SP.ini b/plugins/obs-ffmpeg/data/locale/sr-SP.ini index ecfb53a..abf1911 100644 --- a/plugins/obs-ffmpeg/data/locale/sr-SP.ini +++ b/plugins/obs-ffmpeg/data/locale/sr-SP.ini @@ -1,40 +1,57 @@ FFmpegOutput="FFmpeg излаз" FFmpegAAC="FFmpeg подразумевани AAC енкодер" +FFmpegOpus="FFmpeg Opus енкодер" Bitrate="Проток" +MaxBitrate="Максимални проток" Preset="Шаблон" RateControl="Контрола протока" KeyframeIntervalSec="Интервал кључних фрејмова (секунде, 0=аутоматски)" Lossless="Без губитка" +BFrames="Максимални Б-фрејм" NVENC.Use2Pass="Користи енкодинг дуплог пролаза" -NVENC.Preset.default="Подразумевани" -NVENC.Preset.hq="Високи квалитет" -NVENC.Preset.hp="Високе перформансе" -NVENC.Preset.bd="Bluray" -NVENC.Preset.ll="Ниско кашњење" -NVENC.Preset.llhq="Високи квалитет ниског кашњења" -NVENC.Preset.llhp="Високе перформансе ниског кашњења" -NVENC.Level="Ниво" +NVENC.Preset.default="Перформансе" +NVENC.Preset.hq="Квалитет" +NVENC.Preset.hp="Максималне перформансе" +NVENC.Preset.mq="Максимални квалитет" +NVENC.Preset.ll="Мало кашњење" +NVENC.Preset.llhq="Квалитет малог кашњења" +NVENC.Preset.llhp="Перформансе малог кашњења" +NVENC.LookAhead="Гледање унапред" +NVENC.LookAhead.ToolTip="Укључује динамичке Б-фрејмове..\n\n Ако је искључено, енкодер ће увек користити број Б-фрејмова наведен у 'Максимални Б-фрејмови' делу.\n\nУколико је укључено, повећаће визуелни квалитет коришћењем онолико Б-фрејмова колико је потребно, до максималног броја,\nпо цену повећане употребе GPU-a." +NVENC.PsychoVisualTuning="Психо визуелна подешавања" +NVENC.PsychoVisualTuning.ToolTip="Укључује подешавања енкодера која оптимизују коришћење протока за повећани визуелни квалитет,\nпосебно у ситуацијама са убрзаним покретима, по цену повећане употребе GPU-а." +NVENC.CQLevel="CQ Ниво" FFmpegSource="Медија извор" LocalFile="Локална датотека" Looping="Понављање" Input="Улаз" InputFormat="Формат улаза" +BufferingMB="Баферовање мреже (мегабајти)" HardwareDecode="Користи хардверско енкодирање када је доступно" -ClearOnMediaEnd="Сакриј извор када се репродукција заврши" Advanced="Напредно" RestartWhenActivated="Понови репродукцију када извор постане активан" +CloseFileWhenInactive="Затвори фајл када је неактиван" +CloseFileWhenInactive.ToolTip="Затворите фајл када извор није приказан током стримовања или\nна снимку. Ово омогућава фајлу да буде измењен када извор није активан, \nали је могуће да се јави одређено кашњење када се извор поново активира." ColorRange="YUV опсег боја" ColorRange.Auto="Аутоматски" ColorRange.Partial="Делимични" ColorRange.Full="Потпуни" +RestartMedia="Рестартуј медиј" +SpeedPercentage="Брзина (проценат)" +Seekable="Претраживање" MediaFileFilter.AllMediaFiles="Све медија датотеке" MediaFileFilter.VideoFiles="Видео датотеке" MediaFileFilter.AudioFiles="Звучне датотеке" MediaFileFilter.AllFiles="Све датотеке" +ReplayBuffer="Бафер за поновно репродуковање" +ReplayBuffer.Save="Сачувај поновно репродуковање" +HelperProcessFailed="Немогуће је покренути помоћ за снимање. Проверите да ли су OBS фајлови блокирани или премештени од стране неког антивирус софтвера/софтвера за заштиту." +UnableToWritePath="Немогуће је писати на %1. Проверите да ли користите путању којој ваш налог има право да приступи и да ли имате довољно простора на диску." +WarnWindowsDefender="Ова грешка такође може да настане ако је Windows 10 Ransomware Protection укључен. Покушајте да искључите контролисани приступ фолдеру у подешавањима за Windows Сигурност/Заштиту од вируса." diff --git a/plugins/obs-ffmpeg/data/locale/sv-SE.ini b/plugins/obs-ffmpeg/data/locale/sv-SE.ini index e098af9..9a33cb5 100644 --- a/plugins/obs-ffmpeg/data/locale/sv-SE.ini +++ b/plugins/obs-ffmpeg/data/locale/sv-SE.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg-utmatning" FFmpegAAC="AAC-kodare (FFmpeg standard)" FFmpegOpus="FFmpeg Opus-kodare" Bitrate="Bithastighet" +MaxBitrate="Max bithastighet" Preset="Förinställning" RateControl="Hastighetskontroll" KeyframeIntervalSec="Intervall för keyframes (sekunder, 0=automatisk)" Lossless="Förlustfri" -BFrames="B-bildrutor" +BFrames="Maximalt antal B-frames" NVENC.Use2Pass="Använd tvåpassavkodning" -NVENC.Preset.default="Standard" -NVENC.Preset.hq="Hög kvalitet" -NVENC.Preset.hp="Hög prestanda" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Prestanda" +NVENC.Preset.hq="Kvalitet" +NVENC.Preset.hp="Maximal prestanda" +NVENC.Preset.mq="Maximal kvalitet" NVENC.Preset.ll="Låg latens" -NVENC.Preset.llhq="Låg latens, hög kvalitet" -NVENC.Preset.llhp="Låg latens, hög prestanda" -NVENC.Level="Nivå" +NVENC.Preset.llhq="Kvalitet med låg latens" +NVENC.Preset.llhp="Prestanda med låg latens" +NVENC.LookAhead="Look-ahead" +NVENC.LookAhead.ToolTip="Aktiverar dynamiska B-frames.\n\nOm detta inaktiveras kommer kodaren alltid använda antalet B-frames som anges i inställningen \"Max B-frames\".\n\nOm detta aktiveras kommer det öka den visuella kvaliteten genom att endast använda så många B-frames som är nödvändigt, upp till det som är möjligt\npå bekostnad av ökad användning av grafikprocessorn." +NVENC.PsychoVisualTuning="Psykovisuell justering" +NVENC.PsychoVisualTuning.ToolTip="Aktiverar kodarinställningar som optimerar hur bithastigheten används för förbättrad visuell kvalitet,\nspeciellt i situationer med snabba rörelser på bekostnad av ökad användning av grafikprocessorn." +NVENC.CQLevel="CQ-nivå" FFmpegSource="Mediakälla" LocalFile="Lokal fil" @@ -26,7 +31,7 @@ Input="Infoga" InputFormat="Inmatningsformat" BufferingMB="Nätverksbuffring (MB)" HardwareDecode="Använda hårdvareavkodning när tillgängligt" -ClearOnMediaEnd="Dölja källa när uppspelningen slutar" +ClearOnMediaEnd="Visa ingenting när uppspelningen slutar" Advanced="Avancerat" RestartWhenActivated="Starta om uppspelning när källa blir aktiv" CloseFileWhenInactive="Stäng filen vid inaktivitet" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Spara repris" HelperProcessFailed="Kan inte spela in hjälpprocessen. Kontrollera att OBS-filer inte har blockerats eller tagits bort av antivirus-/säkerhetsprogram från tredjepart." UnableToWritePath="Kan inte skriva till %1. Se till att du använder en inspelningssökväg som ditt användarkonto har tillåtelse att skriva till och att det finns tillräckligt mycket diskutrymme." +WarnWindowsDefender="Om skyddet mot ransomware i Windows 10 är aktiverat kan det också orsaka detta fel. Försök att inaktivera kontrollerad mappåtkomst i Windows-säkerhet / Inställningar för skydd mot virus & hot." diff --git a/plugins/obs-ffmpeg/data/locale/tl-PH.ini b/plugins/obs-ffmpeg/data/locale/tl-PH.ini index b3b3189..a9417f9 100644 --- a/plugins/obs-ffmpeg/data/locale/tl-PH.ini +++ b/plugins/obs-ffmpeg/data/locale/tl-PH.ini @@ -7,17 +7,9 @@ RateControl="Kontrolin ang Rate" KeyframeIntervalSec="Ang Pagitan ng Keyframe (segundo, 0=awto)" Lossless="Walang Pagkawala" -BFrames="Ang mga B-frame" NVENC.Use2Pass="Gamitin ang Dalawang Pass ng Encoding" -NVENC.Preset.default="I-default" -NVENC.Preset.hq="Mataas na Kalidad" -NVENC.Preset.hp="Mataas na Pagganap" -NVENC.Preset.bd="Ang Bluray" NVENC.Preset.ll="Mababang Pagkawalang kilos" -NVENC.Preset.llhq="Mababang-Pagkawalang kilos na Mataas ang Kalidad" -NVENC.Preset.llhp="Mababang-Pagkawalang kilos na Mataan ang Pagganap" -NVENC.Level="Antas" FFmpegSource="Pinagmulan ng Media" LocalFile="Ang Lokal na File" @@ -26,7 +18,6 @@ Input="Pampasok" InputFormat="Pampasok na Format" BufferingMB="Ang Network Buffering (MB)" HardwareDecode="Gamitin ang hardware sa pag-decode kapag itong magagamit na" -ClearOnMediaEnd="Itago ang pinagmulan kapag ang playback ay natapos" Advanced="Nauuna" RestartWhenActivated="I-restart ang playback kapag ang pinagmulan ay naging aktibo na" CloseFileWhenInactive="Isarado ang file kapag hindi ito aktibo" diff --git a/plugins/obs-ffmpeg/data/locale/tr-TR.ini b/plugins/obs-ffmpeg/data/locale/tr-TR.ini index c4c3b77..1c7b908 100644 --- a/plugins/obs-ffmpeg/data/locale/tr-TR.ini +++ b/plugins/obs-ffmpeg/data/locale/tr-TR.ini @@ -2,22 +2,23 @@ FFmpegOutput="FFmpeg Çıkışı" FFmpegAAC="FFmpeg Varsayılan AAC Kodlayıcı" FFmpegOpus="FFmpeg Opus Kodlayıcı" Bitrate="Bit hızı" +MaxBitrate="Maksimum Bit Hızı" Preset="Ön Tanımlı" RateControl="Oran Kontrolü" KeyframeIntervalSec="Anahtar Kare Aralığı (saniye, 0=otomatik)" Lossless="Kayıpsız" -BFrames="B-Kareleri" +BFrames="Maksimum B-kareleri" NVENC.Use2Pass="İki Taramalı Kodlama Kullan" -NVENC.Preset.default="Varsayılan" -NVENC.Preset.hq="Yüksek Kalite" -NVENC.Preset.hp="Yüksek Performans" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Performans" +NVENC.Preset.hq="Kalite" +NVENC.Preset.hp="Maksimum Performans" +NVENC.Preset.mq="Maksimum Kalite" NVENC.Preset.ll="Düşük Gecikme" -NVENC.Preset.llhq="Düşük Gecikme Yüksek Kalite" -NVENC.Preset.llhp="Düşük Gecikme Yüksek Performans" -NVENC.Level="Seviye" +NVENC.Preset.llhq="Düşük Gecikme, Düşük Kalite" +NVENC.Preset.llhp="Düşük Gecikme, Düşük Performans" +NVENC.PsychoVisualTuning.ToolTip="Bit hızı kullanımını, arttırılmış algılanan görsel kalite için optimize eden ayarları etkinleştirir,\nÖzellikle yüksek haraketli durumlarda, arttırılmış GPU kullanımı pahasına." FFmpegSource="Ortam Kaynağı" LocalFile="Yerel Dosya" @@ -26,7 +27,6 @@ Input="Giriş" InputFormat="Giriş Biçimi" BufferingMB="Ağ Arabelleğe Alma (MB)" HardwareDecode="Kullanılabilir ise, donanım kod çözmeyi kullan" -ClearOnMediaEnd="Kayıttan yürütme bittiğinde kaynağı gizle" Advanced="Gelişmiş" RestartWhenActivated="Yeniden oynatmayı kaynak etkin olduğunda yeniden başlat" CloseFileWhenInactive="Etkin değilken dosyayı kapat" @@ -49,4 +49,5 @@ ReplayBuffer.Save="Yeniden Oynatmayı Kaydet" HelperProcessFailed="Kayıt yardımcısı işlemi başlatılamadı. OBS dosyalarının herhangi bir 3. taraf antivirüs / güvenlik yazılımı tarafından engellenmediğini veya kaldırılmadığını kontrol edin." UnableToWritePath="%1 yazılamadı. Kullanıcı hesabınızın yazmasına izin verilen bir kayıt konumu kullanıyor olduğunuzdan ve yeterli disk alanı olduğundan emin olun." +WarnWindowsDefender="Eğer Windows 10 Fidye Virüsü koruması etkinse bu hataya neden olabilir. Windows Güvenlik / Virüs & tehdit koruması ayarlarından kontrollü klasör erişimini kapatmayı dene." diff --git a/plugins/obs-ffmpeg/data/locale/uk-UA.ini b/plugins/obs-ffmpeg/data/locale/uk-UA.ini index 88c2d44..549cf29 100644 --- a/plugins/obs-ffmpeg/data/locale/uk-UA.ini +++ b/plugins/obs-ffmpeg/data/locale/uk-UA.ini @@ -2,22 +2,27 @@ FFmpegOutput="Вивід FFmpeg" FFmpegAAC="FFmpeg AAC енкодер за замовчанням" FFmpegOpus="FFmpeg Opus енкодер" Bitrate="Бітрейт" +MaxBitrate="Максимальний бітрейт" Preset="Шаблон" RateControl="Керування потоком" KeyframeIntervalSec="Інтервал ключових кадрів (секунд, 0 = авто)" Lossless="Без втрат" -BFrames="B-кадри" +BFrames="B-кадрів, максимально" NVENC.Use2Pass="Використовувати двопрохідне кодування" -NVENC.Preset.default="Стандартний" -NVENC.Preset.hq="Висока якість" -NVENC.Preset.hp="Висока продуктивність" -NVENC.Preset.bd="Blu-ray" +NVENC.Preset.default="Продуктивність" +NVENC.Preset.hq="Якість" +NVENC.Preset.hp="Максимальна продуктивність" +NVENC.Preset.mq="Максимальна якість" NVENC.Preset.ll="З низькою затримкою" -NVENC.Preset.llhq="З низькою затримкою, висока Якість" -NVENC.Preset.llhp="З низькою затримкою, висока Продуктивність" -NVENC.Level="Рівень" +NVENC.Preset.llhq="З низькою затримкою, Якість" +NVENC.Preset.llhp="З низькою затримкою, Продуктивність" +NVENC.LookAhead="Передбачення" +NVENC.LookAhead.ToolTip="Дозволяє використовувати динамічні B-кадри.\n\nЯкщо вимкнено, енкодер завжди буде використовувати кількість B-кадрів,\nвказаних у налаштуванні: B-кадрів, максимально.\n\nЯкщо увімкнено, це поліпшить якість завдяки використанню необхідної\nта достатньої кількості B-кадрів (не більше вказаного максимуму), однак це відбудеться\nза рахунок збільшення навантаження на графічний процессор." +NVENC.PsychoVisualTuning="Психо-візуальні спрощення" +NVENC.PsychoVisualTuning.ToolTip="Дозволяє енкодеру використовувати методи оптимізації з розподілення бітрейту\nдля підвищення візуального сприйняття якості, особливо в сценах з швидким рухом.\nВідбувається за рахунок збільшення навантаження на графічний процесор." +NVENC.CQLevel="CQ (постійне квантування), рівень" FFmpegSource="Мультимедіа" LocalFile="Локальний файл" @@ -49,4 +54,5 @@ ReplayBuffer.Save="Зберегти Повтор" HelperProcessFailed="Не вдалося розпочати допоміжний процес для запису. Перевірте, що OBS файли не було заблоковано чи видалено антивірусом або будь-яким іншим програмним забезпеченням з безпеки." UnableToWritePath="Не вдалося записати до %1. Переконайтеся, що ви використовуєте для запису шлях, до якого ваш обліковий запис має дозвіл на запис, і що там є достатньо вільного місця." +WarnWindowsDefender="Якщо Windows 10 Ransomware Protection (захист від програм-вимагачів) увімкнуто у системі - це також може бути причиною появи цієї помилки. Спробуйте вимкнути контроль за доступом до папок у Безпека Windows Захист від вірусів та загроз." diff --git a/plugins/obs-ffmpeg/data/locale/vi-VN.ini b/plugins/obs-ffmpeg/data/locale/vi-VN.ini index b558018..3132009 100644 --- a/plugins/obs-ffmpeg/data/locale/vi-VN.ini +++ b/plugins/obs-ffmpeg/data/locale/vi-VN.ini @@ -1,22 +1,21 @@ FFmpegOutput="FFmpeg đầu ra" FFmpegAAC="FFmpeg AAC Encoder mặc định" Bitrate="Bitrate" +MaxBitrate="'Tốc độ bit' tối đa" Preset="Mẫu thiết lập" RateControl="Cách kiểm soát bitrate" KeyframeIntervalSec="Thời gian đặt Keyframe (giây, 0=tự động)" Lossless="Lossless" -BFrames="B-Frames" NVENC.Use2Pass="Sử dụng 2-Pass Encoding" -NVENC.Preset.default="Mặc định" -NVENC.Preset.hq="Chất lượng cao" -NVENC.Preset.hp="Hiệu suất cao" -NVENC.Preset.bd="Bluray" +NVENC.Preset.default="Hiệu suất" +NVENC.Preset.hq="Chất lượng" +NVENC.Preset.hp="Hiệu suất tối đa" +NVENC.Preset.mq="Chất lượng tối đa" NVENC.Preset.ll="Độ trễ thấp" -NVENC.Preset.llhq="Độ trễ thấp chất lượng cao" -NVENC.Preset.llhp="Độ trễ thấp hiệu suất cao" -NVENC.Level="Cấp độ" +NVENC.Preset.llhq="Chất lượng \"độ trễ thấp\"" +NVENC.Preset.llhp="Hiệu suất \"độ trễ thấp\"" FFmpegSource="Nguồn media" LocalFile="Tập tin cục bộ" @@ -38,5 +37,6 @@ MediaFileFilter.AudioFiles="Tập tin âm thanh" MediaFileFilter.AllFiles="Tất cả tập tin" ReplayBuffer="Replay Buffer" +ReplayBuffer.Save="Lưu bản phát lại" diff --git a/plugins/obs-ffmpeg/data/locale/zh-CN.ini b/plugins/obs-ffmpeg/data/locale/zh-CN.ini index f630e62..5ef0fc1 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-CN.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-CN.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 输出" FFmpegAAC="FFmpeg 默认 AAC 编码器" FFmpegOpus="FFmpeg Opus 编码器" Bitrate="比特率" +MaxBitrate="最大比特率" Preset="预设" RateControl="速率控制" KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" Lossless="无损" -BFrames="B 帧" +BFrames="最大B帧" NVENC.Use2Pass="使用 Two-Pass 编码" -NVENC.Preset.default="默认" -NVENC.Preset.hq="高质量" -NVENC.Preset.hp="高性能" -NVENC.Preset.bd="蓝光" +NVENC.Preset.default="性能" +NVENC.Preset.hq="质量" +NVENC.Preset.hp="最大性能" +NVENC.Preset.mq="最高质量" NVENC.Preset.ll="低延迟" -NVENC.Preset.llhq="低延迟高质量" -NVENC.Preset.llhp="低延迟高性能" -NVENC.Level="等级" +NVENC.Preset.llhq="低延迟质量" +NVENC.Preset.llhp="低延迟性能" +NVENC.LookAhead="前向考虑" +NVENC.LookAhead.ToolTip="启用动态B帧。\n\n如果禁用,编码器将始终使用“最大B帧”设置中指定的B帧数。\n\n如果启用,它将通过仅使用足够多的B帧来提高视觉质量,直到最大,\n但以增加 GPU 使用率为代价。" +NVENC.PsychoVisualTuning="心理视觉调整" +NVENC.PsychoVisualTuning.ToolTip="启用编码器设置以优化比特率使用,以提高 GPU 使用率为代价,\n可在快速运动场景下提高人眼感知的视频质量。" +NVENC.CQLevel="CQ 级别" FFmpegSource="媒体源" LocalFile="本地文件" @@ -26,11 +31,11 @@ Input="输入" InputFormat="输入格式" BufferingMB="网络缓冲 (MB)" HardwareDecode="在可用时使用硬件解码" -ClearOnMediaEnd="当播放结束时隐藏源" +ClearOnMediaEnd="播放结束时不显示任何内容" Advanced="高级" RestartWhenActivated="当源变为活动状态时重新启动播放" CloseFileWhenInactive="非活跃状态时关闭文件" -CloseFileWhenInactive.ToolTip="当源没有显示在推流或者\n录像时关闭文件。这使得在源不活跃状态时可以更改文件,\n但是当当源重新激活时, 可能有一些启动延迟。" +CloseFileWhenInactive.ToolTip="当源没有被用以串流或录像时关闭文件。\n这允许在源未被使用时更改文件,\n但在重新启动源时可能会有些许的启动延迟。" ColorRange="YUV 颜色范围" ColorRange.Auto="自动" ColorRange.Partial="局部" @@ -47,6 +52,7 @@ MediaFileFilter.AllFiles="所有文件" ReplayBuffer="回放缓存" ReplayBuffer.Save="保存回放" -HelperProcessFailed="无法启动录音助手进程。检查 OBS 文件未被任何第三方防病毒 / 安全软件阻止或删除。" -UnableToWritePath="无法写入到 %1。请确保您使用的录制路径您的用户帐户允许写入,并有足够的磁盘空间。" +HelperProcessFailed="无法启动录制助手进程。检查 OBS 文件未被任何第三方防病毒 / 安全软件阻止或删除。" +UnableToWritePath="无法写入到 %1。请确保您使用的录像路径允许您的用户帐户写入,并且磁盘空间充足。" +WarnWindowsDefender="Windows 10 的勒索软件防护机制也可能导致该错误的发生。请尝试关闭 Windows 安全中心 - 勒索软件防护中的文件夹限制访问。" diff --git a/plugins/obs-ffmpeg/data/locale/zh-TW.ini b/plugins/obs-ffmpeg/data/locale/zh-TW.ini index 88ee839..f1683d8 100644 --- a/plugins/obs-ffmpeg/data/locale/zh-TW.ini +++ b/plugins/obs-ffmpeg/data/locale/zh-TW.ini @@ -2,22 +2,27 @@ FFmpegOutput="FFmpeg 輸出" FFmpegAAC="FFmpeg 預設 AAC 編碼器" FFmpegOpus="FFmpeg Opus 編碼器" Bitrate="位元率" +MaxBitrate="最大位元率" Preset="預置" RateControl="位元率控制" KeyframeIntervalSec="關鍵訊框間隔 (秒,0 = 自動)" Lossless="無損" -BFrames="B 訊框" +BFrames="最大 B 畫格數" NVENC.Use2Pass="使用 Two-Pass 編碼" -NVENC.Preset.default="預設" -NVENC.Preset.hq="高品質" -NVENC.Preset.hp="高性能" -NVENC.Preset.bd="藍光" +NVENC.Preset.default="效能" +NVENC.Preset.hq="畫質" +NVENC.Preset.hp="效能最高" +NVENC.Preset.mq="品質最高" NVENC.Preset.ll="低延遲" -NVENC.Preset.llhq="低延遲高品質" -NVENC.Preset.llhp="低延遲高性能" -NVENC.Level="级别" +NVENC.Preset.llhq="低延遲品質" +NVENC.Preset.llhp="低延遲效能" +NVENC.LookAhead="編碼緩衝預測" +NVENC.LookAhead.ToolTip="啟用動態B幀。 \n\n如果禁用,編碼器將始終使用“最大B幀”設置中指定的B幀數。 \n\n如果啟用,它將僅通過使用盡可能多的B幀來提高視覺品質,直到最大,\n但以增加 GPU 使用率為代價。" +NVENC.PsychoVisualTuning="心理視覺調整" +NVENC.PsychoVisualTuning.ToolTip="啟用優化比特率使用的編碼器設置,以提高感知的視覺品質,\n特別是在高運動的情況下,以提高 GPU 使用率為代價。" +NVENC.CQLevel="固定量化等級" FFmpegSource="媒體來源" LocalFile="本機檔案" @@ -26,7 +31,7 @@ Input="輸入" InputFormat="輸入格式" BufferingMB="網路緩衝 (MB)" HardwareDecode="盡可能使用硬體解碼" -ClearOnMediaEnd="當播放結束時隱藏來源" +ClearOnMediaEnd="播放結束時不顯示任何內容" Advanced="進階" RestartWhenActivated="當來源可使用時重新播放" CloseFileWhenInactive="非使用狀態時關閉檔案" @@ -49,4 +54,5 @@ ReplayBuffer.Save="儲存重播" HelperProcessFailed="無法啟動錄影協助程式。請確定 OBS 檔案沒有被防毒/安全軟體所阻擋或移除。" UnableToWritePath="無法寫入到 %1。請確定使用者帳戶可以寫入錄影檔路徑以及有足夠的磁碟空間。" +WarnWindowsDefender="如果啟用了 windows 10 勒索軟體保護, 也可能導致此錯誤。請嘗試將 obs 從 windows 安全/病毒和威脅防護設置中的受控資料夾訪問清單中移除。" diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt b/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt index 8c564d8..c464b8e 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt +++ b/plugins/obs-ffmpeg/ffmpeg-mux/CMakeLists.txt @@ -1,26 +1,20 @@ -project(ffmpeg-mux) +project(obs-ffmpeg-mux) find_package(FFmpeg REQUIRED COMPONENTS avcodec avutil avformat) include_directories(${FFMPEG_INCLUDE_DIRS}) -set(ffmpeg-mux_SOURCES +set(obs-ffmpeg-mux_SOURCES ffmpeg-mux.c) -set(ffmpeg-mux_HEADERS +set(obs-ffmpeg-mux_HEADERS ffmpeg-mux.h) -add_executable(ffmpeg-mux - ${ffmpeg-mux_SOURCES} - ${ffmpeg-mux_HEADERS}) +add_executable(obs-ffmpeg-mux + ${obs-ffmpeg-mux_SOURCES} + ${obs-ffmpeg-mux_HEADERS}) -target_link_libraries(ffmpeg-mux +target_link_libraries(obs-ffmpeg-mux ${FFMPEG_LIBRARIES}) -if(WIN32) - set_target_properties(ffmpeg-mux - PROPERTIES - OUTPUT_NAME "ffmpeg-mux${_output_suffix}") -endif() - -install_obs_datatarget(ffmpeg-mux "obs-plugins/obs-ffmpeg") +install_obs_core(obs-ffmpeg-mux) diff --git a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c index b3c5c88..728555d 100644 --- a/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/ffmpeg-mux/ffmpeg-mux.c @@ -268,7 +268,7 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream, AVCodec *codec; if (!desc) { - printf("Couldn't find encoder '%s'\n", name); + fprintf(stderr, "Couldn't find encoder '%s'\n", name); return false; } @@ -276,13 +276,13 @@ static bool new_stream(struct ffmpeg_mux *ffm, AVStream **stream, codec = avcodec_find_encoder(desc->id); if (!codec) { - printf("Couldn't create encoder"); + fprintf(stderr, "Couldn't create encoder"); return false; } *stream = avformat_new_stream(ffm->output, codec); if (!*stream) { - printf("Couldn't create stream for encoder '%s'\n", name); + fprintf(stderr, "Couldn't create stream for encoder '%s'\n", name); return false; } @@ -469,7 +469,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) ret = avio_open(&ffm->output->pb, ffm->params.file, AVIO_FLAG_WRITE); if (ret < 0) { - printf("Couldn't open '%s', %s", + fprintf(stderr, "Couldn't open '%s', %s", ffm->params.file, av_err2str(ret)); return FFM_ERROR; } @@ -482,7 +482,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) AVDictionary *dict = NULL; if ((ret = av_dict_parse_string(&dict, ffm->params.muxer_settings, "=", " ", 0))) { - printf("Failed to parse muxer settings: %s\n%s", + fprintf(stderr, "Failed to parse muxer settings: %s\n%s", av_err2str(ret), ffm->params.muxer_settings); av_dict_free(&dict); @@ -501,7 +501,7 @@ static inline int open_output_file(struct ffmpeg_mux *ffm) ret = avformat_write_header(ffm->output, &dict); if (ret < 0) { - printf("Error opening '%s': %s", + fprintf(stderr, "Error opening '%s': %s", ffm->params.file, av_err2str(ret)); av_dict_free(&dict); @@ -521,7 +521,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm) output_format = av_guess_format(NULL, ffm->params.file, NULL); if (output_format == NULL) { - printf("Couldn't find an appropriate muxer for '%s'\n", + fprintf(stderr, "Couldn't find an appropriate muxer for '%s'\n", ffm->params.file); return FFM_ERROR; } @@ -529,7 +529,7 @@ static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm) ret = avformat_alloc_output_context2(&ffm->output, output_format, NULL, NULL); if (ret < 0) { - printf("Couldn't initialize output context: %s\n", + fprintf(stderr, "Couldn't initialize output context: %s\n", av_err2str(ret)); return FFM_ERROR; } @@ -679,7 +679,7 @@ int main(int argc, char *argv[]) ret = ffmpeg_mux_init(&ffm, argc, argv); if (ret != FFM_SUCCESS) { - puts("Couldn't initialize muxer"); + fprintf(stderr, "Couldn't initialize muxer\n"); return ret; } diff --git a/plugins/obs-ffmpeg/jim-nvenc-helpers.c b/plugins/obs-ffmpeg/jim-nvenc-helpers.c new file mode 100644 index 0000000..68d20b3 --- /dev/null +++ b/plugins/obs-ffmpeg/jim-nvenc-helpers.c @@ -0,0 +1,149 @@ +#include "jim-nvenc.h" +#include +#include + +static void *nvenc_lib = NULL; +static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; +NV_ENCODE_API_FUNCTION_LIST nv = {NV_ENCODE_API_FUNCTION_LIST_VER}; +NV_CREATE_INSTANCE_FUNC nv_create_instance = NULL; + +#define error(format, ...) \ + blog(LOG_ERROR, "[jim-nvenc] " format, ##__VA_ARGS__) + +static inline bool nv_failed(NVENCSTATUS err, const char *func, const char *call) +{ + if (err == NV_ENC_SUCCESS) + return false; + + error("%s: %s failed: %d (%s)", func, call, (int)err, + nv_error_name(err)); + return true; +} + +#define NV_FAILED(x) nv_failed(x, __FUNCTION__, #x) + +bool load_nvenc_lib(void) +{ + if (sizeof(void*) == 8) { + nvenc_lib = os_dlopen("nvEncodeAPI64.dll"); + } else { + nvenc_lib = os_dlopen("nvEncodeAPI.dll"); + } + + return !!nvenc_lib; +} + +static void *load_nv_func(const char *func) +{ + void *func_ptr = os_dlsym(nvenc_lib, func); + if (!func_ptr) { + error("Could not load function: %s", func); + } + return func_ptr; +} + +typedef NVENCSTATUS (NVENCAPI *NV_MAX_VER_FUNC)(uint32_t*); + +const char *nv_error_name(NVENCSTATUS err) +{ +#define RETURN_CASE(x) \ + case x: return #x + + switch (err) { + RETURN_CASE(NV_ENC_SUCCESS); + RETURN_CASE(NV_ENC_ERR_NO_ENCODE_DEVICE); + RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_DEVICE); + RETURN_CASE(NV_ENC_ERR_INVALID_ENCODERDEVICE); + RETURN_CASE(NV_ENC_ERR_INVALID_DEVICE); + RETURN_CASE(NV_ENC_ERR_DEVICE_NOT_EXIST); + RETURN_CASE(NV_ENC_ERR_INVALID_PTR); + RETURN_CASE(NV_ENC_ERR_INVALID_EVENT); + RETURN_CASE(NV_ENC_ERR_INVALID_PARAM); + RETURN_CASE(NV_ENC_ERR_INVALID_CALL); + RETURN_CASE(NV_ENC_ERR_OUT_OF_MEMORY); + RETURN_CASE(NV_ENC_ERR_ENCODER_NOT_INITIALIZED); + RETURN_CASE(NV_ENC_ERR_UNSUPPORTED_PARAM); + RETURN_CASE(NV_ENC_ERR_LOCK_BUSY); + RETURN_CASE(NV_ENC_ERR_NOT_ENOUGH_BUFFER); + RETURN_CASE(NV_ENC_ERR_INVALID_VERSION); + RETURN_CASE(NV_ENC_ERR_MAP_FAILED); + RETURN_CASE(NV_ENC_ERR_NEED_MORE_INPUT); + RETURN_CASE(NV_ENC_ERR_ENCODER_BUSY); + RETURN_CASE(NV_ENC_ERR_EVENT_NOT_REGISTERD); + RETURN_CASE(NV_ENC_ERR_GENERIC); + RETURN_CASE(NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY); + RETURN_CASE(NV_ENC_ERR_UNIMPLEMENTED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_REGISTER_FAILED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_REGISTERED); + RETURN_CASE(NV_ENC_ERR_RESOURCE_NOT_MAPPED); + } +#undef RETURN_CASE + + return "Unknown Error"; +} + +static inline bool init_nvenc_internal(void) +{ + static bool initialized = false; + static bool success = false; + + if (initialized) + return success; + initialized = true; + + NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC) + load_nv_func("NvEncodeAPIGetMaxSupportedVersion"); + if (!nv_max_ver) { + return false; + } + + uint32_t ver = 0; + if (NV_FAILED(nv_max_ver(&ver))) { + return false; + } + + uint32_t cur_ver = + (NVENCAPI_MAJOR_VERSION << 4) | NVENCAPI_MINOR_VERSION; + if (cur_ver > ver) { + error("Current driver version does not support this NVENC " + "version, please upgrade your driver"); + return false; + } + + nv_create_instance = (NV_CREATE_INSTANCE_FUNC) + load_nv_func("NvEncodeAPICreateInstance"); + if (!nv_create_instance) { + return false; + } + + if (NV_FAILED(nv_create_instance(&nv))) { + return false; + } + + success = true; + return true; +} + +bool init_nvenc(void) +{ + bool success; + + pthread_mutex_lock(&init_mutex); + success = init_nvenc_internal(); + pthread_mutex_unlock(&init_mutex); + + return success; +} + +extern struct obs_encoder_info nvenc_info; + +void jim_nvenc_load(void) +{ + pthread_mutex_init(&init_mutex, NULL); + obs_register_encoder(&nvenc_info); +} + +void jim_nvenc_unload(void) +{ + pthread_mutex_destroy(&init_mutex); +} diff --git a/plugins/obs-ffmpeg/jim-nvenc.c b/plugins/obs-ffmpeg/jim-nvenc.c new file mode 100644 index 0000000..6eae7f9 --- /dev/null +++ b/plugins/obs-ffmpeg/jim-nvenc.c @@ -0,0 +1,945 @@ +#include "jim-nvenc.h" +#include +#include +#include +#include +#define INITGUID +#include +#include +#include + +/* ========================================================================= */ + +#define EXTRA_BUFFERS 5 + +#define do_log(level, format, ...) \ + blog(level, "[jim-nvenc: '%s'] " format, \ + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) + +#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__) +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) + +#define error_hr(msg) \ + error("%s: %s: 0x%08lX", __FUNCTION__, msg, (uint32_t)hr); + +struct nv_bitstream; +struct nv_texture; + +struct handle_tex { + uint32_t handle; + ID3D11Texture2D *tex; + IDXGIKeyedMutex *km; +}; + +/* ------------------------------------------------------------------------- */ +/* Main Implementation Structure */ + +struct nvenc_data { + obs_encoder_t *encoder; + + void *session; + NV_ENC_INITIALIZE_PARAMS params; + NV_ENC_CONFIG config; + size_t buf_count; + size_t output_delay; + size_t buffers_queued; + size_t next_bitstream; + size_t cur_bitstream; + bool encode_started; + bool first_packet; + bool can_change_bitrate; + bool bframes; + + DARRAY(struct nv_bitstream) bitstreams; + DARRAY(struct nv_texture) textures; + DARRAY(struct handle_tex) input_textures; + struct circlebuf dts_list; + + DARRAY(uint8_t) packet_data; + int64_t packet_pts; + bool packet_keyframe; + + ID3D11Device *device; + ID3D11DeviceContext *context; + + uint32_t cx; + uint32_t cy; + + uint8_t *header; + size_t header_size; + + uint8_t *sei; + size_t sei_size; +}; + +/* ------------------------------------------------------------------------- */ +/* Bitstream Buffer */ + +struct nv_bitstream { + void *ptr; + HANDLE event; +}; + +static inline bool nv_failed(struct nvenc_data *enc, NVENCSTATUS err, + const char *func, const char *call) +{ + if (err == NV_ENC_SUCCESS) + return false; + + error("%s: %s failed: %d (%s)", func, call, (int)err, + nv_error_name(err)); + return true; +} + +#define NV_FAILED(x) nv_failed(enc, x, __FUNCTION__, #x) + +static bool nv_bitstream_init(struct nvenc_data *enc, struct nv_bitstream *bs) +{ + NV_ENC_CREATE_BITSTREAM_BUFFER buf = {NV_ENC_CREATE_BITSTREAM_BUFFER_VER}; + NV_ENC_EVENT_PARAMS params = {NV_ENC_EVENT_PARAMS_VER}; + HANDLE event = NULL; + + if (NV_FAILED(nv.nvEncCreateBitstreamBuffer(enc->session, &buf))) { + return false; + } + + event = CreateEvent(NULL, true, true, NULL); + if (!event) { + error("%s: %s", __FUNCTION__, "Failed to create event"); + goto fail; + } + + params.completionEvent = event; + if (NV_FAILED(nv.nvEncRegisterAsyncEvent(enc->session, ¶ms))) { + goto fail; + } + + bs->ptr = buf.bitstreamBuffer; + bs->event = event; + return true; + +fail: + if (event) { + CloseHandle(event); + } + if (buf.bitstreamBuffer) { + nv.nvEncDestroyBitstreamBuffer(enc->session, + buf.bitstreamBuffer); + } + return false; +} + +static void nv_bitstream_free(struct nvenc_data *enc, struct nv_bitstream *bs) +{ + if (bs->ptr) { + nv.nvEncDestroyBitstreamBuffer(enc->session, bs->ptr); + + NV_ENC_EVENT_PARAMS params = {NV_ENC_EVENT_PARAMS_VER}; + params.completionEvent = bs->event; + nv.nvEncUnregisterAsyncEvent(enc->session, ¶ms); + CloseHandle(bs->event); + } +} + +/* ------------------------------------------------------------------------- */ +/* Texture Resource */ + +struct nv_texture { + void *res; + ID3D11Texture2D *tex; + void *mapped_res; +}; + +static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex) +{ + ID3D11Device *device = enc->device; + ID3D11Texture2D *tex; + HRESULT hr; + + D3D11_TEXTURE2D_DESC desc = {0}; + desc.Width = enc->cx; + desc.Height = enc->cy; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_NV12; + desc.SampleDesc.Count = 1; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + + hr = device->lpVtbl->CreateTexture2D(device, &desc, NULL, &tex); + if (FAILED(hr)) { + error_hr("Failed to create texture"); + return false; + } + + tex->lpVtbl->SetEvictionPriority(tex, DXGI_RESOURCE_PRIORITY_MAXIMUM); + + NV_ENC_REGISTER_RESOURCE res = {NV_ENC_REGISTER_RESOURCE_VER}; + res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX; + res.resourceToRegister = tex; + res.width = enc->cx; + res.height = enc->cy; + res.bufferFormat = NV_ENC_BUFFER_FORMAT_NV12; + + if (NV_FAILED(nv.nvEncRegisterResource(enc->session, &res))) { + tex->lpVtbl->Release(tex); + return false; + } + + nvtex->res = res.registeredResource; + nvtex->tex = tex; + return true; +} + +static void nv_texture_free(struct nvenc_data *enc, struct nv_texture *nvtex) +{ + if (nvtex->res) { + if (nvtex->mapped_res) { + nv.nvEncUnmapInputResource(enc->session, + nvtex->mapped_res); + } + nv.nvEncUnregisterResource(enc->session, nvtex->res); + nvtex->tex->lpVtbl->Release(nvtex->tex); + } +} + +/* ------------------------------------------------------------------------- */ +/* Implementation */ + +static const char *nvenc_get_name(void *type_data) +{ + UNUSED_PARAMETER(type_data); + return "NVIDIA NVENC H.264 (new)"; +} + +static inline int nv_get_cap(struct nvenc_data *enc, NV_ENC_CAPS cap) +{ + if (!enc->session) + return 0; + + NV_ENC_CAPS_PARAM param = {NV_ENC_CAPS_PARAM_VER}; + int v; + + param.capsToQuery = cap; + nv.nvEncGetEncodeCaps(enc->session, NV_ENC_CODEC_H264_GUID, ¶m, &v); + return v; +} + +static bool nvenc_update(void *data, obs_data_t *settings) +{ + struct nvenc_data *enc = data; + + /* Only support reconfiguration of CBR bitrate */ + if (enc->can_change_bitrate) { + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + + enc->config.rcParams.averageBitRate = bitrate * 1000; + enc->config.rcParams.maxBitRate = bitrate * 1000; + + NV_ENC_RECONFIGURE_PARAMS params = {0}; + params.version = NV_ENC_RECONFIGURE_PARAMS_VER; + params.reInitEncodeParams = enc->params; + + if (FAILED(nv.nvEncReconfigureEncoder(enc->session, ¶ms))) { + return false; + } + } + + return true; +} + +static HANDLE get_lib(struct nvenc_data *enc, const char *lib) +{ + HMODULE mod = GetModuleHandleA(lib); + if (mod) + return mod; + + mod = LoadLibraryA(lib); + if (!mod) + error("Failed to load %s", lib); + return mod; +} + +typedef HRESULT (WINAPI *CREATEDXGIFACTORY1PROC)(REFIID, void **); + +static bool init_d3d11(struct nvenc_data *enc, obs_data_t *settings) +{ + HMODULE dxgi = get_lib(enc, "DXGI.dll"); + HMODULE d3d11 = get_lib(enc, "D3D11.dll"); + CREATEDXGIFACTORY1PROC create_dxgi; + PFN_D3D11_CREATE_DEVICE create_device; + IDXGIFactory1 *factory; + IDXGIAdapter *adapter; + ID3D11Device *device; + ID3D11DeviceContext *context; + HRESULT hr; + + if (!dxgi || !d3d11) { + return false; + } + + create_dxgi = (CREATEDXGIFACTORY1PROC)GetProcAddress(dxgi, + "CreateDXGIFactory1"); + create_device = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11, + "D3D11CreateDevice"); + + if (!create_dxgi || !create_device) { + error("Failed to load D3D11/DXGI procedures"); + return false; + } + + hr = create_dxgi(&IID_IDXGIFactory1, &factory); + if (FAILED(hr)) { + error_hr("CreateDXGIFactory1 failed"); + return false; + } + + hr = factory->lpVtbl->EnumAdapters(factory, 0, &adapter); + factory->lpVtbl->Release(factory); + if (FAILED(hr)) { + error_hr("EnumAdapters failed"); + return false; + } + + hr = create_device(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, + NULL, 0, D3D11_SDK_VERSION, &device, NULL, &context); + adapter->lpVtbl->Release(adapter); + if (FAILED(hr)) { + error_hr("D3D11CreateDevice failed"); + return false; + } + + enc->device = device; + enc->context = context; + return true; +} + +static bool init_session(struct nvenc_data *enc) +{ + NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = + {NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER}; + params.device = enc->device; + params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX; + params.apiVersion = NVENCAPI_VERSION; + + if (NV_FAILED(nv.nvEncOpenEncodeSessionEx(¶ms, &enc->session))) { + return false; + } + return true; +} + +static bool init_encoder(struct nvenc_data *enc, obs_data_t *settings) +{ + const char *rc = obs_data_get_string(settings, "rate_control"); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + int max_bitrate = (int)obs_data_get_int(settings, "max_bitrate"); + int cqp = (int)obs_data_get_int(settings, "cqp"); + int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); + const char *preset = obs_data_get_string(settings, "preset"); + const char *profile = obs_data_get_string(settings, "profile"); + bool psycho_aq = obs_data_get_bool(settings, "psycho_aq"); + bool lookahead = obs_data_get_bool(settings, "lookahead"); + int bf = (int)obs_data_get_int(settings, "bf"); + bool vbr = astrcmpi(rc, "VBR") == 0; + NVENCSTATUS err; + + video_t *video = obs_encoder_video(enc->encoder); + const struct video_output_info *voi = video_output_get_info(video); + + enc->cx = voi->width; + enc->cy = voi->height; + + /* -------------------------- */ + /* get preset */ + + GUID nv_preset = NV_ENC_PRESET_DEFAULT_GUID; + bool twopass = false; + bool hp = false; + bool ll = false; + + if (astrcmpi(preset, "hq") == 0) { + nv_preset = NV_ENC_PRESET_HQ_GUID; + + } else if (astrcmpi(preset, "mq") == 0) { + nv_preset = NV_ENC_PRESET_HQ_GUID; + twopass = true; + + } else if (astrcmpi(preset, "hp") == 0) { + nv_preset = NV_ENC_PRESET_HP_GUID; + hp = true; + + } else if (astrcmpi(preset, "ll") == 0) { + nv_preset = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID; + ll = true; + + } else if (astrcmpi(preset, "llhq") == 0) { + nv_preset = NV_ENC_PRESET_LOW_LATENCY_HQ_GUID; + ll = true; + + } else if (astrcmpi(preset, "llhp") == 0) { + nv_preset = NV_ENC_PRESET_LOW_LATENCY_HP_GUID; + hp = true; + ll = true; + } + + if (astrcmpi(rc, "lossless") == 0) { + nv_preset = hp + ? NV_ENC_PRESET_LOSSLESS_HP_GUID + : NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID; + } + + /* -------------------------- */ + /* get preset default config */ + + NV_ENC_PRESET_CONFIG preset_config = + {NV_ENC_PRESET_CONFIG_VER, {NV_ENC_CONFIG_VER}}; + + err = nv.nvEncGetEncodePresetConfig(enc->session, + NV_ENC_CODEC_H264_GUID, nv_preset, &preset_config); + if (nv_failed(enc, err, __FUNCTION__, "nvEncGetEncodePresetConfig")) { + return false; + } + + /* -------------------------- */ + /* main configuration */ + + enc->config = preset_config.presetCfg; + + uint32_t gop_size = (keyint_sec) + ? keyint_sec * voi->fps_num / voi->fps_den + : 250; + + NV_ENC_INITIALIZE_PARAMS *params = &enc->params; + NV_ENC_CONFIG *config = &enc->config; + NV_ENC_CONFIG_H264 *h264_config = &config->encodeCodecConfig.h264Config; + NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui_params = + &h264_config->h264VUIParameters; + + memset(params, 0, sizeof(*params)); + params->version = NV_ENC_INITIALIZE_PARAMS_VER; + params->encodeGUID = NV_ENC_CODEC_H264_GUID; + params->presetGUID = nv_preset; + params->encodeWidth = voi->width; + params->encodeHeight = voi->height; + params->darWidth = voi->width; + params->darHeight = voi->height; + params->frameRateNum = voi->fps_num; + params->frameRateDen = voi->fps_den; + params->enableEncodeAsync = 1; + params->enablePTD = 1; + params->encodeConfig = &enc->config; + params->maxEncodeWidth = voi->width; + params->maxEncodeHeight = voi->height; + config->gopLength = gop_size; + config->frameIntervalP = 1 + bf; + h264_config->idrPeriod = gop_size; + vui_params->videoSignalTypePresentFlag = 1; + vui_params->videoFullRangeFlag = (voi->range == VIDEO_RANGE_FULL); + vui_params->colourDescriptionPresentFlag = 1; + vui_params->colourMatrix = (voi->colorspace == VIDEO_CS_709) ? 1 : 5; + vui_params->colourPrimaries = 1; + vui_params->transferCharacteristics = 1; + + enc->bframes = bf > 0; + + /* lookahead */ + if (lookahead && nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_LOOKAHEAD)) { + config->rcParams.lookaheadDepth = 8; + config->rcParams.enableLookahead = 1; + } + + /* psycho aq */ + if (nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_TEMPORAL_AQ)) { + config->rcParams.enableAQ = psycho_aq; + config->rcParams.enableTemporalAQ = psycho_aq; + } + + /* -------------------------- */ + /* rate control */ + + enc->can_change_bitrate = + nv_get_cap(enc, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE); + + config->rcParams.rateControlMode = twopass + ? NV_ENC_PARAMS_RC_VBR_HQ + : NV_ENC_PARAMS_RC_VBR; + + if (astrcmpi(rc, "cqp") == 0 || astrcmpi(rc, "lossless") == 0) { + if (astrcmpi(rc, "lossless") == 0) + cqp = 0; + + config->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP; + config->rcParams.constQP.qpInterP = cqp; + config->rcParams.constQP.qpInterB = cqp; + config->rcParams.constQP.qpIntra = cqp; + enc->can_change_bitrate = false; + + bitrate = 0; + max_bitrate = 0; + + } else if (astrcmpi(rc, "vbr") != 0) { /* CBR by default */ + h264_config->outputBufferingPeriodSEI = 1; + config->rcParams.rateControlMode = twopass + ? NV_ENC_PARAMS_RC_2_PASS_QUALITY + : NV_ENC_PARAMS_RC_CBR; + } + + h264_config->outputPictureTimingSEI = 1; + config->rcParams.averageBitRate = bitrate * 1000; + config->rcParams.maxBitRate = vbr ? max_bitrate * 1000 : bitrate * 1000; + + /* -------------------------- */ + /* profile */ + + if (astrcmpi(profile, "main") == 0) { + config->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID; + } else if (astrcmpi(profile, "baseline") == 0) { + config->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID; + } else { + config->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID; + } + + /* -------------------------- */ + /* initialize */ + + if (NV_FAILED(nv.nvEncInitializeEncoder(enc->session, params))) { + return false; + } + + enc->buf_count = config->frameIntervalP + + config->rcParams.lookaheadDepth + EXTRA_BUFFERS; + enc->output_delay = enc->buf_count - 1; + + info("settings:\n" + "\trate_control: %s\n" + "\tbitrate: %d\n" + "\tcqp: %d\n" + "\tkeyint: %d\n" + "\tpreset: %s\n" + "\tprofile: %s\n" + "\twidth: %d\n" + "\theight: %d\n" + "\t2-pass: %s\n" + "\tb-frames: %d\n" + "\tlookahead: %s\n" + "\tpsycho_aq: %s\n", + rc, bitrate, cqp, gop_size, + preset, profile, + enc->cx, enc->cy, + twopass ? "true" : "false", + bf, + lookahead ? "true" : "false", + psycho_aq ? "true" : "false"); + + return true; +} + +static bool init_bitstreams(struct nvenc_data *enc) +{ + da_reserve(enc->bitstreams, enc->buf_count); + for (size_t i = 0; i < enc->buf_count; i++) { + struct nv_bitstream bitstream; + if (!nv_bitstream_init(enc, &bitstream)) { + return false; + } + + da_push_back(enc->bitstreams, &bitstream); + } + + return true; +} + +static bool init_textures(struct nvenc_data *enc) +{ + da_reserve(enc->bitstreams, enc->buf_count); + for (size_t i = 0; i < enc->buf_count; i++) { + struct nv_texture texture; + if (!nv_texture_init(enc, &texture)) { + return false; + } + + da_push_back(enc->textures, &texture); + } + + return true; +} + +static void nvenc_destroy(void *data); + +static void *nvenc_create(obs_data_t *settings, obs_encoder_t *encoder) +{ + NV_ENCODE_API_FUNCTION_LIST init = {NV_ENCODE_API_FUNCTION_LIST_VER}; + struct nvenc_data *enc = bzalloc(sizeof(*enc)); + enc->encoder = encoder; + enc->first_packet = true; + + /* this encoder requires shared textures, this cannot be used on a + * gpu other than the one OBS is currently running on. */ + int gpu = (int)obs_data_get_int(settings, "gpu"); + if (gpu != 0) { + goto fail; + } + + if (!obs_nv12_tex_active()) { + goto fail; + } + if (!init_nvenc()) { + goto fail; + } + if (NV_FAILED(nv_create_instance(&init))) { + goto fail; + } + if (!init_d3d11(enc, settings)) { + goto fail; + } + if (!init_session(enc)) { + goto fail; + } + if (!init_encoder(enc, settings)) { + goto fail; + } + if (!init_bitstreams(enc)) { + goto fail; + } + if (!init_textures(enc)) { + goto fail; + } + + return enc; + +fail: + nvenc_destroy(enc); + return obs_encoder_create_rerouted(encoder, "ffmpeg_nvenc"); +} + +static bool get_encoded_packet(struct nvenc_data *enc, bool finalize); + +static void nvenc_destroy(void *data) +{ + struct nvenc_data *enc = data; + + if (enc->encode_started) { + size_t next_bitstream = enc->next_bitstream; + HANDLE next_event = enc->bitstreams.array[next_bitstream].event; + + NV_ENC_PIC_PARAMS params = {NV_ENC_PIC_PARAMS_VER}; + params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; + params.completionEvent = next_event; + nv.nvEncEncodePicture(enc->session, ¶ms); + get_encoded_packet(enc, true); + } + for (size_t i = 0; i < enc->textures.num; i++) { + nv_texture_free(enc, &enc->textures.array[i]); + } + for (size_t i = 0; i < enc->bitstreams.num; i++) { + nv_bitstream_free(enc, &enc->bitstreams.array[i]); + } + if (enc->session) { + nv.nvEncDestroyEncoder(enc->session); + } + for (size_t i = 0; i < enc->input_textures.num; i++) { + ID3D11Texture2D *tex = enc->input_textures.array[i].tex; + IDXGIKeyedMutex *km = enc->input_textures.array[i].km; + tex->lpVtbl->Release(tex); + km->lpVtbl->Release(km); + } + if (enc->context) { + enc->context->lpVtbl->Release(enc->context); + } + if (enc->device) { + enc->device->lpVtbl->Release(enc->device); + } + + bfree(enc->header); + bfree(enc->sei); + circlebuf_free(&enc->dts_list); + da_free(enc->textures); + da_free(enc->bitstreams); + da_free(enc->input_textures); + da_free(enc->packet_data); + bfree(enc); +} + +static ID3D11Texture2D *get_tex_from_handle(struct nvenc_data *enc, + uint32_t handle, IDXGIKeyedMutex **km_out) +{ + ID3D11Device *device = enc->device; + IDXGIKeyedMutex *km; + ID3D11Texture2D *input_tex; + HRESULT hr; + + for (size_t i = 0; i < enc->input_textures.num; i++) { + struct handle_tex *ht = &enc->input_textures.array[i]; + if (ht->handle == handle) { + *km_out = ht->km; + return ht->tex; + } + } + + hr = device->lpVtbl->OpenSharedResource(device, + (HANDLE)(uintptr_t)handle, + &IID_ID3D11Texture2D, &input_tex); + if (FAILED(hr)) { + error_hr("OpenSharedResource failed"); + return NULL; + } + + hr = input_tex->lpVtbl->QueryInterface(input_tex, &IID_IDXGIKeyedMutex, + &km); + if (FAILED(hr)) { + error_hr("QueryInterface(IDXGIKeyedMutex) failed"); + input_tex->lpVtbl->Release(input_tex); + return NULL; + } + + input_tex->lpVtbl->SetEvictionPriority(input_tex, + DXGI_RESOURCE_PRIORITY_MAXIMUM); + + *km_out = km; + + struct handle_tex new_ht = {handle, input_tex, km}; + da_push_back(enc->input_textures, &new_ht); + return input_tex; +} + +static bool get_encoded_packet(struct nvenc_data *enc, bool finalize) +{ + void *s = enc->session; + + da_resize(enc->packet_data, 0); + + if (!enc->buffers_queued) + return true; + if (!finalize && enc->buffers_queued < enc->output_delay) + return true; + + size_t count = finalize ? enc->buffers_queued : 1; + + for (size_t i = 0; i < count; i++) { + size_t cur_bs_idx = enc->cur_bitstream; + struct nv_bitstream *bs = &enc->bitstreams.array[cur_bs_idx]; + struct nv_texture *nvtex = &enc->textures.array[cur_bs_idx]; + + /* ---------------- */ + + NV_ENC_LOCK_BITSTREAM lock = {NV_ENC_LOCK_BITSTREAM_VER}; + lock.outputBitstream = bs->ptr; + lock.doNotWait = false; + + if (NV_FAILED(nv.nvEncLockBitstream(s, &lock))) { + return false; + } + + if (enc->first_packet) { + uint8_t *new_packet; + size_t size; + + enc->first_packet = false; + obs_extract_avc_headers( + lock.bitstreamBufferPtr, + lock.bitstreamSizeInBytes, + &new_packet, &size, + &enc->header, &enc->header_size, + &enc->sei, &enc->sei_size); + + da_copy_array(enc->packet_data, new_packet, size); + bfree(new_packet); + } else { + da_copy_array(enc->packet_data, + lock.bitstreamBufferPtr, + lock.bitstreamSizeInBytes); + } + + enc->packet_pts = (int64_t)lock.outputTimeStamp; + enc->packet_keyframe = lock.pictureType == NV_ENC_PIC_TYPE_IDR; + + if (NV_FAILED(nv.nvEncUnlockBitstream(s, bs->ptr))) { + return false; + } + + /* ---------------- */ + + if (nvtex->mapped_res) { + NVENCSTATUS err; + err = nv.nvEncUnmapInputResource(s, nvtex->mapped_res); + if (nv_failed(enc, err, __FUNCTION__, "unmap")) { + return false; + } + nvtex->mapped_res = NULL; + } + + /* ---------------- */ + + if (++enc->cur_bitstream == enc->buf_count) + enc->cur_bitstream = 0; + + enc->buffers_queued--; + } + + return true; +} + +static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts, + uint64_t lock_key, uint64_t *next_key, + struct encoder_packet *packet, bool *received_packet) +{ + struct nvenc_data *enc = data; + ID3D11Device *device = enc->device; + ID3D11DeviceContext *context = enc->context; + ID3D11Texture2D *input_tex; + ID3D11Texture2D *output_tex; + IDXGIKeyedMutex *km; + struct nv_texture *nvtex; + struct nv_bitstream *bs; + NVENCSTATUS err; + + if (handle == GS_INVALID_HANDLE) { + error("Encode failed: bad texture handle"); + *next_key = lock_key; + return false; + } + + bs = &enc->bitstreams.array[enc->next_bitstream]; + nvtex = &enc->textures.array[enc->next_bitstream]; + + input_tex = get_tex_from_handle(enc, handle, &km); + output_tex = nvtex->tex; + + if (!input_tex) { + *next_key = lock_key; + return false; + } + + circlebuf_push_back(&enc->dts_list, &pts, sizeof(pts)); + + /* ------------------------------------ */ + /* wait for output bitstream/tex */ + + WaitForSingleObject(bs->event, INFINITE); + + /* ------------------------------------ */ + /* copy to output tex */ + + km->lpVtbl->AcquireSync(km, lock_key, INFINITE); + + context->lpVtbl->CopyResource(context, + (ID3D11Resource *)output_tex, + (ID3D11Resource *)input_tex); + + km->lpVtbl->ReleaseSync(km, *next_key); + + /* ------------------------------------ */ + /* map output tex so nvenc can use it */ + + NV_ENC_MAP_INPUT_RESOURCE map = {NV_ENC_MAP_INPUT_RESOURCE_VER}; + map.registeredResource = nvtex->res; + if (NV_FAILED(nv.nvEncMapInputResource(enc->session, &map))) { + return false; + } + + nvtex->mapped_res = map.mappedResource; + + /* ------------------------------------ */ + /* do actual encode call */ + + NV_ENC_PIC_PARAMS params = {0}; + params.version = NV_ENC_PIC_PARAMS_VER; + params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME; + params.inputBuffer = nvtex->mapped_res; + params.bufferFmt = NV_ENC_BUFFER_FORMAT_NV12; + params.inputTimeStamp = (uint64_t)pts; + params.inputWidth = enc->cx; + params.inputHeight = enc->cy; + params.outputBitstream = bs->ptr; + params.completionEvent = bs->event; + + err = nv.nvEncEncodePicture(enc->session, ¶ms); + if (err != NV_ENC_SUCCESS && err != NV_ENC_ERR_NEED_MORE_INPUT) { + nv_failed(enc, err, __FUNCTION__, "nvEncEncodePicture"); + return false; + } + + enc->encode_started = true; + enc->buffers_queued++; + + if (++enc->next_bitstream == enc->buf_count) { + enc->next_bitstream = 0; + } + + /* ------------------------------------ */ + /* check for encoded packet and parse */ + + if (!get_encoded_packet(enc, false)) { + return false; + } + + /* ------------------------------------ */ + /* output encoded packet */ + + if (enc->packet_data.num) { + int64_t dts; + circlebuf_pop_front(&enc->dts_list, &dts, sizeof(dts)); + + /* subtract bframe delay from dts */ + if (enc->bframes) + dts -= packet->timebase_num; + + *received_packet = true; + packet->data = enc->packet_data.array; + packet->size = enc->packet_data.num; + packet->type = OBS_ENCODER_VIDEO; + packet->pts = enc->packet_pts; + packet->dts = dts; + packet->keyframe = enc->packet_keyframe; + } else { + *received_packet = false; + } + + return true; +} + +extern void nvenc_defaults(obs_data_t *settings); +extern obs_properties_t *nvenc_properties(void *unused); + +static bool nvenc_extra_data(void *data, uint8_t **header, size_t *size) +{ + struct nvenc_data *enc = data; + + if (!enc->header) { + return false; + } + + *header = enc->header; + *size = enc->header_size; + return true; +} + +static bool nvenc_sei_data(void *data, uint8_t **sei, size_t *size) +{ + struct nvenc_data *enc = data; + + if (!enc->sei) { + return false; + } + + *sei = enc->sei; + *size = enc->sei_size; + return true; +} + +struct obs_encoder_info nvenc_info = { + .id = "jim_nvenc", + .codec = "h264", + .type = OBS_ENCODER_VIDEO, + .caps = OBS_ENCODER_CAP_PASS_TEXTURE, + .get_name = nvenc_get_name, + .create = nvenc_create, + .destroy = nvenc_destroy, + .update = nvenc_update, + .encode_texture = nvenc_encode_tex, + .get_defaults = nvenc_defaults, + .get_properties = nvenc_properties, + .get_extra_data = nvenc_extra_data, + .get_sei_data = nvenc_sei_data, +}; diff --git a/plugins/obs-ffmpeg/jim-nvenc.h b/plugins/obs-ffmpeg/jim-nvenc.h new file mode 100644 index 0000000..c45ecdd --- /dev/null +++ b/plugins/obs-ffmpeg/jim-nvenc.h @@ -0,0 +1,14 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#include + +#include +#include "nvEncodeAPI.h" + +typedef NVENCSTATUS (NVENCAPI *NV_CREATE_INSTANCE_FUNC)(NV_ENCODE_API_FUNCTION_LIST*); + +extern const char *nv_error_name(NVENCSTATUS err); +extern NV_ENCODE_API_FUNCTION_LIST nv; +extern NV_CREATE_INSTANCE_FUNC nv_create_instance; +extern bool init_nvenc(void); diff --git a/plugins/obs-ffmpeg/nvEncodeAPI.h b/plugins/obs-ffmpeg/nvEncodeAPI.h index e662880..df13b2f 100644 --- a/plugins/obs-ffmpeg/nvEncodeAPI.h +++ b/plugins/obs-ffmpeg/nvEncodeAPI.h @@ -1,7 +1,7 @@ /* * This copyright notice applies to this header file only: * - * Copyright (c) 2010-2017 NVIDIA Corporation + * Copyright (c) 2010-2018 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -30,7 +30,7 @@ * NVIDIA GPUs - beginning with the Kepler generation - contain a hardware-based encoder * (referred to as NVENC) which provides fully-accelerated hardware-based video encoding. * NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC). - * \date 2011-2017 + * \date 2011-2018 * This file contains the interface constants, structure definitions and function prototypes. */ @@ -67,17 +67,13 @@ extern "C" { * @{ */ -#if defined(_WIN32) || defined(__CYGWIN__) -#define NVENCAPI __stdcall -#else -#define NVENCAPI -#endif - #ifdef _WIN32 +#define NVENCAPI __stdcall typedef RECT NVENC_RECT; #else +#define NVENCAPI // ========================================================================================= -#if !defined(GUID) && !defined(GUID_DEFINED) +#ifndef GUID /*! * \struct GUID * Abstracts the GUID structure for non-windows platforms. @@ -114,7 +110,7 @@ typedef void* NV_ENC_OUTPUT_PTR; /**< NVENCODE API output buffer*/ typedef void* NV_ENC_REGISTERED_PTR; /**< A Resource that has been registered with NVENCODE API*/ #define NVENCAPI_MAJOR_VERSION 8 -#define NVENCAPI_MINOR_VERSION 0 +#define NVENCAPI_MINOR_VERSION 1 #define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24)) @@ -262,6 +258,30 @@ typedef enum _NV_ENC_PARAMS_RC_MODE NV_ENC_PARAMS_RC_VBR_HQ = 0x20 /**< VBR, high quality (slower) */ } NV_ENC_PARAMS_RC_MODE; +/** + * Emphasis Levels + */ +typedef enum _NV_ENC_EMPHASIS_MAP_LEVEL +{ + NV_ENC_EMPHASIS_MAP_LEVEL_0 = 0x0, /**< Emphasis Map Level 0, for zero Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_1 = 0x1, /**< Emphasis Map Level 1, for very low Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_2 = 0x2, /**< Emphasis Map Level 2, for low Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_3 = 0x3, /**< Emphasis Map Level 3, for medium Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_4 = 0x4, /**< Emphasis Map Level 4, for high Delta QP value */ + NV_ENC_EMPHASIS_MAP_LEVEL_5 = 0x5 /**< Emphasis Map Level 5, for very high Delta QP value */ +} NV_ENC_EMPHASIS_MAP_LEVEL; + +/** + * QP MAP MODE + */ +typedef enum _NV_ENC_QP_MAP_MODE +{ + NV_ENC_QP_MAP_DISABLED = 0x0, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap have no effect. */ + NV_ENC_QP_MAP_EMPHASIS = 0x1, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as Empasis level. Currently this is only supported for H264 */ + NV_ENC_QP_MAP_DELTA = 0x2, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP delta map. */ + NV_ENC_QP_MAP = 0x3, /**< Currently This is not supported. Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP value. */ +} NV_ENC_QP_MAP_MODE; + #define NV_ENC_PARAMS_RC_VBR_MINQP (NV_ENC_PARAMS_RC_MODE)0x4 /**< Deprecated */ #define NV_ENC_PARAMS_RC_2_PASS_QUALITY NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ /**< Deprecated */ #define NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP NV_ENC_PARAMS_RC_CBR_HQ /**< Deprecated */ @@ -585,6 +605,15 @@ typedef enum _NV_ENC_MEMORY_HEAP NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED = 3 /**< Memory heap is in uncached system memory */ } NV_ENC_MEMORY_HEAP; +/** + * B-frame used as reference modes + */ +typedef enum _NV_ENC_BFRAME_REF_MODE +{ + NV_ENC_BFRAME_REF_MODE_DISABLED = 0x0, /**< B frame is not used for reference */ + NV_ENC_BFRAME_REF_MODE_EACH = 0x1, /**< Each B-frame will be used for reference. currently not supported */ + NV_ENC_BFRAME_REF_MODE_MIDDLE = 0x2, /**< Only(Number of B-frame)/2 th B-frame will be used for reference */ +} NV_ENC_BFRAME_REF_MODE; /** * H.264 entropy coding modes. @@ -955,7 +984,34 @@ typedef enum _NV_ENC_CAPS */ NV_ENC_CAPS_SUPPORT_WEIGHTED_PREDICTION, + /** + * On managed (vGPU) platforms (Windows only), this API, in conjunction with other GRID Management APIs, can be used + * to estimate the residual capacity of the hardware encoder on the GPU as a percentage of the total available encoder capacity. + * This API can be called at any time; i.e. during the encode session or before opening the encode session. + * If the available encoder capacity is returned as zero, applications may choose to switch to software encoding + * and continue to call this API (e.g. polling once per second) until capacity becomes available. + * + * On baremetal (non-virtualized GPU) and linux platforms, this API always returns 100. + */ + NV_ENC_CAPS_DYNAMIC_QUERY_ENCODER_CAPACITY, + + /** + * Indicates B as refererence support. + * \n 0 : B as reference is not supported. + * \n 1 : each B-Frame as reference is supported. + * \n 2 : only Middle B-frame as reference is supported. + */ + NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE, + + /** + * Indicates HW support for Emphasis Level Map based delta QP computation. + * \n 0 : Emphasis Level Map based delta QP not supported. + * \n 1 : Emphasis Level Map based delta QP is supported. + */ + NV_ENC_CAPS_SUPPORT_EMPHASIS_LEVEL_MAP, + + /** * Reserved - Not to be used by clients. */ NV_ENC_CAPS_EXPOSED_COUNT @@ -1100,7 +1156,7 @@ typedef struct _NV_ENC_QP uint32_t enableMaxQP :1; /**< [in]: Set this to 1 if maximum QP used for rate control. */ uint32_t enableInitialRCQP :1; /**< [in]: Set this to 1 if user suppplied initial QP is used for rate control. */ uint32_t enableAQ :1; /**< [in]: Set this to 1 to enable adaptive quantization (Spatial). */ - uint32_t enableExtQPDeltaMap :1; /**< [in]: Set this to 1 to enable additional QP modifier for each MB supplied by client though signed byte array pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap (Not Supported when AQ(Spatial/Temporal) is enabled) */ + uint32_t reservedBitField1 :1; /**< [in]: Reserved bitfields and must be set to 0. */ uint32_t enableLookahead :1; /**< [in]: Set this to 1 to enable lookahead with depth (if lookahead is enabled, input frames must remain available to the encoder until encode completion) */ uint32_t disableIadapt :1; /**< [in]: Set this to 1 to disable adaptive I-frame insertion at scene cuts (only has an effect when lookahead is enabled) */ uint32_t disableBadapt :1; /**< [in]: Set this to 1 to disable adaptive B-frame decision (only has an effect when lookahead is enabled) */ @@ -1118,7 +1174,25 @@ typedef struct _NV_ENC_QP uint8_t targetQuality; /**< [in]: Target CQ (Constant Quality) level for VBR mode (range 0-51 with 0-automatic) */ uint8_t targetQualityLSB; /**< [in]: Fractional part of target quality (as 8.8 fixed point format) */ uint16_t lookaheadDepth; /**< [in]: Maximum depth of lookahead with range 0-32 (only used if enableLookahead=1) */ - uint32_t reserved[9]; + uint32_t reserved1; + NV_ENC_QP_MAP_MODE qpMapMode; /**< [in]: This flag is used to interpret values in array pecified by NV_ENC_PIC_PARAMS::qpDeltaMap. + Set this to NV_ENC_QP_MAP_EMPHASIS to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as Emphasis level Map. + Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL. + Emphasis Level Map is used to specify regions to be encoded at varying levels of quality. + The hardware encoder adjusts the quantization within the image as per the provided emphasis map, + by adjusting the quantization parameter (QP) assigned to each macroblock. This adjustment is commonly called “Delta QP”. + The adjustment depends on the absolute QP decided by the rate control algorithm, and is applied after the rate control has decided each macroblock’s QP. + Since the Delta QP overrides rate control, enabling emphasis level map may violate bitrate and VBV buffersize constraints. + Emphasis level map is useful in situations when client has a priori knowledge of the image complexity (e.g. via use of NVFBC's Classification feature) and encoding those high-complexity areas at higher quality (lower QP) is important, even at the possible cost of violating bitrate/VBV buffersize constraints + This feature is not supported when AQ( Spatial/Temporal) is enabled. + This feature is only supported for H264 codec currently. + + Set this to NV_ENC_QP_MAP_DELTA to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as QPDelta. This specify QP modifier to be applied on top of the QP chosen by rate control + + Set this to NV_ENC_QP_MAP_DISABLED to ignore NV_ENC_PIC_PARAMS::qpDeltaMap values. In this case, qpDeltaMap should be set to NULL. + + Other values are reserved for future use.*/ + uint32_t reserved[7]; } NV_ENC_RC_PARAMS; /** macro for constructing the version field of ::_NV_ENC_RC_PARAMS */ @@ -1235,7 +1309,7 @@ typedef struct _NV_ENC_CONFIG_H264 is recommended to use a large DPB size so that the encoder can keep old reference frames which can be used if recent frames are invalidated. */ uint32_t sliceMode; /**< [in]: This parameter in conjunction with sliceModeData specifies the way in which the picture is divided into slices - sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3, numSlices in Picture + sliceMode = 0 MB based slices, sliceMode = 1 Byte based slices, sliceMode = 2 MB row based slices, sliceMode = 3 numSlices in Picture. When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting When sliceMode == 0 and sliceModeData == 0 whole picture will be coded with one slice */ uint32_t sliceModeData; /**< [in]: Specifies the parameter needed for sliceMode. For: @@ -1254,11 +1328,11 @@ typedef struct _NV_ENC_CONFIG_H264 uint32_t chromaFormatIDC; /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input. Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/ uint32_t maxTemporalLayers; /**< [in]: Specifies the max temporal layer used for hierarchical coding. */ - uint32_t reserved1[270]; /**< [in]: Reserved and must be set to 0 */ + NV_ENC_BFRAME_REF_MODE useBFramesAsRef; /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/ + uint32_t reserved1[269]; /**< [in]: Reserved and must be set to 0 */ void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ } NV_ENC_CONFIG_H264; - /** * \struct _NV_ENC_CONFIG_HEVC * HEVC encoder configuration parameters to be set during initialization. @@ -1312,7 +1386,7 @@ typedef struct _NV_ENC_CONFIG_HEVC Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may be deprecated in future releases. Set to 0 when using "LTR Per Picture" mode of LTR operation. */ - uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/ + uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/ void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */ } NV_ENC_CONFIG_HEVC; @@ -1382,7 +1456,7 @@ typedef struct _NV_ENC_CONFIG } NV_ENC_CONFIG; /** macro for constructing the version field of ::_NV_ENC_CONFIG */ -#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(6) | ( 1<<31 )) +#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 )) /** @@ -1436,7 +1510,21 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS typedef struct _NV_ENC_RECONFIGURE_PARAMS { uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_RECONFIGURE_PARAMS_VER. */ - NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters. */ + NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters. + If reInitEncodeParams.encodeConfig is NULL and + reInitEncodeParams.presetGUID is the same as the preset + GUID specified on the call to NvEncInitializeEncoder(), + EncodeAPI will continue to use the existing encode + configuration. + If reInitEncodeParams.encodeConfig is NULL and + reInitEncodeParams.presetGUID is different from the preset + GUID specified on the call to NvEncInitializeEncoder(), + EncodeAPI will try to use the default configuration for + the preset specified by reInitEncodeParams.presetGUID. + In this case, reconfiguration may fail if the new + configuration is incompatible with the existing + configuration (e.g. the new configuration results in + a change in the GOP structure). */ uint32_t resetEncoder :1; /**< [in]: This resets the rate control states and other internal encoder states. This should be used only with an IDR frame. If NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1, encoder will force the frame type to IDR */ uint32_t forceIDR :1; /**< [in]: Encode the current picture as an IDR picture. This flag is only valid when Picture type decision is taken by the Encoder @@ -1560,7 +1648,6 @@ typedef struct _NV_ENC_PIC_PARAMS_HEVC void* reserved3[61]; /**< [in]: Reserved and must be set to NULL. */ } NV_ENC_PIC_PARAMS_HEVC; - /** * Codec specific per-picture encoding parameters. */ @@ -1599,7 +1686,11 @@ typedef struct _NV_ENC_PIC_PARAMS + 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */ uint32_t reserved1[6]; /**< [in]: Reserved and must be set to 0 */ void* reserved2[2]; /**< [in]: Reserved and must be set to NULL */ - int8_t *qpDeltaMap; /**< [in]: Specifies the pointer to signed byte array containing QP delta value per MB in raster scan order in the current picture. This QP modifier is applied on top of the QP chosen by rate control. */ + int8_t *qpDeltaMap; /**< [in]: Specifies the pointer to signed byte array containing value per MB in raster scan order for the current picture, which will be Interperated depending on NV_ENC_RC_PARAMS::qpMapMode. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA , This specify QP modifier to be applied on top of the QP chosen by rate control. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, it specifies emphasis level map per MB. This level value along with QP chosen by rate control is used to compute the QP modifier, + which in turn is applied on top of QP chosen by rate control. + If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DISABLED value in qpDeltaMap will be ignored.*/ uint32_t qpDeltaMapSize; /**< [in]: Specifies the size in bytes of qpDeltaMap surface allocated by client and pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap. Surface (array) should be picWidthInMbs * picHeightInMbs */ uint32_t reservedBitFields; /**< [in]: Reserved bitfields and must be set to 0 */ uint16_t meHintRefPicDist[2]; /**< [in]: Specifies temporal distance for reference picture (NVENC_EXTERNAL_ME_HINT::refidx = 0) used during external ME with NV_ENC_INITALIZE_PARAMS::enablePTD = 1 . meHintRefPicDist[0] is for L0 hints and meHintRefPicDist[1] is for L1 hints. diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c index 9b65276..2683f8e 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-mux.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-mux.c @@ -26,6 +26,10 @@ #include #include "ffmpeg-mux/ffmpeg-mux.h" +#ifdef _WIN32 +#include "util/windows/win-version.h" +#endif + #include #define do_log(level, format, ...) \ @@ -109,13 +113,9 @@ static void *ffmpeg_mux_create(obs_data_t *settings, obs_output_t *output) } #ifdef _WIN32 -#ifdef _WIN64 -#define FFMPEG_MUX "ffmpeg-mux64.exe" +#define FFMPEG_MUX "obs-ffmpeg-mux.exe" #else -#define FFMPEG_MUX "ffmpeg-mux32.exe" -#endif -#else -#define FFMPEG_MUX "ffmpeg-mux" +#define FFMPEG_MUX "obs-ffmpeg-mux" #endif static inline bool capturing(struct ffmpeg_muxer *stream) @@ -237,7 +237,7 @@ static void build_command_line(struct ffmpeg_muxer *stream, struct dstr *cmd, num_tracks++; } - dstr_init_move_array(cmd, obs_module_file(FFMPEG_MUX)); + dstr_init_move_array(cmd, os_get_executable_path_ptr(FFMPEG_MUX)); dstr_insert_ch(cmd, 0, '\"'); dstr_cat(cmd, "\" \""); @@ -290,6 +290,16 @@ static bool ffmpeg_mux_start(void *data) struct dstr error_message; dstr_init_copy(&error_message, obs_module_text("UnableToWritePath")); +#ifdef _WIN32 + // special warning for Windows 10 users about Defender + struct win_version_info ver; + get_win_ver(&ver); + if (ver.major >= 10) { + dstr_cat(&error_message, "\n\n"); + dstr_cat(&error_message, + obs_module_text("WarnWindowsDefender")); + } +#endif dstr_replace(&error_message, "%1", path); obs_output_set_last_error(stream->output, error_message.array); @@ -321,7 +331,7 @@ static bool ffmpeg_mux_start(void *data) return true; } -static int deactivate(struct ffmpeg_muxer *stream) +static int deactivate(struct ffmpeg_muxer *stream, int code) { int ret = -1; @@ -335,8 +345,11 @@ static int deactivate(struct ffmpeg_muxer *stream) info("Output of file '%s' stopped", stream->path.array); } - if (stopping(stream)) + if (code) { + obs_output_signal_stop(stream->output, code); + } else if (stopping(stream)) { obs_output_end_data_capture(stream->output); + } os_atomic_set_bool(&stream->stopping, false); return ret; @@ -355,9 +368,23 @@ static void ffmpeg_mux_stop(void *data, uint64_t ts) static void signal_failure(struct ffmpeg_muxer *stream) { - int ret = deactivate(stream); + char error[1024]; + int ret; int code; + size_t len; + + len = os_process_pipe_read_err(stream->pipe, (uint8_t *)error, + sizeof(error) - 1); + + if (len > 0) { + error[len] = 0; + warn ("ffmpeg-mux: %s", error); + obs_output_set_last_error (stream->output, error); + } + + ret = deactivate(stream, 0); + switch (ret) { case FFM_UNSUPPORTED: code = OBS_OUTPUT_UNSUPPORTED; break; default: code = OBS_OUTPUT_ERROR; @@ -455,6 +482,12 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet) if (!active(stream)) return; + /* encoder failure */ + if (!packet) { + deactivate(stream, OBS_OUTPUT_ENCODE_ERROR); + return; + } + if (!stream->sent_headers) { if (!send_headers(stream)) return; @@ -464,7 +497,7 @@ static void ffmpeg_mux_data(void *data, struct encoder_packet *packet) if (stopping(stream)) { if (packet->sys_dts_usec >= stream->stop_ts) { - deactivate(stream); + deactivate(stream, 0); return; } } @@ -779,10 +812,13 @@ static void replay_buffer_save(struct ffmpeg_muxer *stream) replay_buffer_mux_thread, stream) == 0; } -static void deactivate_replay_buffer(struct ffmpeg_muxer *stream) +static void deactivate_replay_buffer(struct ffmpeg_muxer *stream, int code) { - if (stopping(stream)) + if (code) { + obs_output_signal_stop(stream->output, code); + } else if (stopping(stream)) { obs_output_end_data_capture(stream->output); + } os_atomic_set_bool(&stream->active, false); os_atomic_set_bool(&stream->sent_headers, false); @@ -798,9 +834,15 @@ static void replay_buffer_data(void *data, struct encoder_packet *packet) if (!active(stream)) return; + /* encoder failure */ + if (!packet) { + deactivate_replay_buffer(stream, OBS_OUTPUT_ENCODE_ERROR); + return; + } + if (stopping(stream)) { if (packet->sys_dts_usec >= stream->stop_ts) { - deactivate_replay_buffer(stream); + deactivate_replay_buffer(stream, 0); return; } } diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c index 16cd32e..469dce4 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c @@ -60,7 +60,7 @@ struct nvenc_encoder { static const char *nvenc_getname(void *unused) { UNUSED_PARAMETER(unused); - return "NVENC H.264"; + return "NVIDIA NVENC H.264"; } static inline bool valid_format(enum video_format format) @@ -134,8 +134,6 @@ static bool nvenc_update(void *data, obs_data_t *settings) int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); const char *preset = obs_data_get_string(settings, "preset"); const char *profile = obs_data_get_string(settings, "profile"); - const char *level = obs_data_get_string(settings, "level"); - bool twopass = obs_data_get_bool(settings, "2pass"); int gpu = (int)obs_data_get_int(settings, "gpu"); bool cbr_override = obs_data_get_bool(settings, "cbr"); int bf = (int)obs_data_get_int(settings, "bf"); @@ -158,6 +156,13 @@ static bool nvenc_update(void *data, obs_data_t *settings) info.colorspace = voi->colorspace; info.range = voi->range; + bool twopass = false; + + if (astrcmpi(preset, "mq") == 0) { + twopass = true; + preset = "hq"; + } + nvenc_video_info(enc, &info); av_opt_set_int(enc->context->priv_data, "cbr", false, 0); av_opt_set(enc->context->priv_data, "profile", profile, 0); @@ -185,7 +190,7 @@ static bool nvenc_update(void *data, obs_data_t *settings) } - av_opt_set(enc->context->priv_data, "level", level, 0); + av_opt_set(enc->context->priv_data, "level", "auto", 0); av_opt_set_int(enc->context->priv_data, "2pass", twopass, 0); av_opt_set_int(enc->context->priv_data, "gpu", gpu, 0); @@ -216,14 +221,13 @@ static bool nvenc_update(void *data, obs_data_t *settings) "\tkeyint: %d\n" "\tpreset: %s\n" "\tprofile: %s\n" - "\tlevel: %s\n" "\twidth: %d\n" "\theight: %d\n" "\t2-pass: %s\n" "\tb-frames: %d\n" "\tGPU: %d\n", rc, bitrate, cqp, enc->context->gop_size, - preset, profile, level, + preset, profile, enc->context->width, enc->context->height, twopass ? "true" : "false", enc->context->max_b_frames, @@ -390,16 +394,16 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame, return true; } -static void nvenc_defaults(obs_data_t *settings) +void nvenc_defaults(obs_data_t *settings) { obs_data_set_default_int(settings, "bitrate", 2500); + obs_data_set_default_int(settings, "max_bitrate", 5000); obs_data_set_default_int(settings, "keyint_sec", 0); - obs_data_set_default_int(settings, "cqp", 23); + obs_data_set_default_int(settings, "cqp", 20); obs_data_set_default_string(settings, "rate_control", "CBR"); - obs_data_set_default_string(settings, "preset", "default"); - obs_data_set_default_string(settings, "profile", "main"); - obs_data_set_default_string(settings, "level", "auto"); - obs_data_set_default_bool(settings, "2pass", true); + obs_data_set_default_string(settings, "preset", "hq"); + obs_data_set_default_string(settings, "profile", "high"); + obs_data_set_default_bool(settings, "psycho_aq", true); obs_data_set_default_int(settings, "gpu", 0); obs_data_set_default_int(settings, "bf", 2); } @@ -409,11 +413,14 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, { const char *rc = obs_data_get_string(settings, "rate_control"); bool cqp = astrcmpi(rc, "CQP") == 0; + bool vbr = astrcmpi(rc, "VBR") == 0; bool lossless = astrcmpi(rc, "lossless") == 0; size_t count; p = obs_properties_get(ppts, "bitrate"); obs_property_set_visible(p, !cqp && !lossless); + p = obs_properties_get(ppts, "max_bitrate"); + obs_property_set_visible(p, vbr); p = obs_properties_get(ppts, "cqp"); obs_property_set_visible(p, cqp); @@ -421,17 +428,15 @@ static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p, count = obs_property_list_item_count(p); for (size_t i = 0; i < count; i++) { - bool compatible = (i == 0 || i == 2); + bool compatible = (i == 0 || i == 3); obs_property_list_item_disable(p, i, lossless && !compatible); } return true; } -static obs_properties_t *nvenc_properties(void *unused) +obs_properties_t *nvenc_properties_internal(bool ffmpeg) { - UNUSED_PARAMETER(unused); - obs_properties_t *props = obs_properties_create(); obs_property_t *p; @@ -439,17 +444,22 @@ static obs_properties_t *nvenc_properties(void *unused) obs_module_text("RateControl"), OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, "CBR", "CBR"); - obs_property_list_add_string(p, "VBR", "VBR"); obs_property_list_add_string(p, "CQP", "CQP"); + obs_property_list_add_string(p, "VBR", "VBR"); obs_property_list_add_string(p, obs_module_text("Lossless"), "lossless"); obs_property_set_modified_callback(p, rate_control_modified); - obs_properties_add_int(props, "bitrate", + p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 50, 300000, 50); + obs_property_int_set_suffix(p, " Kbps"); + p = obs_properties_add_int(props, "max_bitrate", + obs_module_text("MaxBitrate"), 50, 300000, 50); + obs_property_int_set_suffix(p, " Kbps"); - obs_properties_add_int(props, "cqp", "CQP", 0, 50, 1); + obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"), + 1, 30, 1); obs_properties_add_int(props, "keyint_sec", obs_module_text("KeyframeIntervalSec"), 0, 10, 1); @@ -460,10 +470,10 @@ static obs_properties_t *nvenc_properties(void *unused) #define add_preset(val) \ obs_property_list_add_string(p, obs_module_text("NVENC.Preset." val), \ val) - add_preset("default"); + add_preset("mq"); add_preset("hq"); + add_preset("default"); add_preset("hp"); - add_preset("bd"); add_preset("ll"); add_preset("llhq"); add_preset("llhp"); @@ -477,38 +487,20 @@ static obs_properties_t *nvenc_properties(void *unused) add_profile("high"); add_profile("main"); add_profile("baseline"); - add_profile("high444p"); - - p = obs_properties_add_list(props, "level", - obs_module_text("NVENC.Level"), OBS_COMBO_TYPE_LIST, - OBS_COMBO_FORMAT_STRING); - add_profile("auto"); - add_profile("1" ); - add_profile("1.0" ); - add_profile("1b" ); - add_profile("1.0b"); - add_profile("1.1" ); - add_profile("1.2" ); - add_profile("1.3" ); - add_profile("2" ); - add_profile("2.0" ); - add_profile("2.1" ); - add_profile("2.2" ); - add_profile("3" ); - add_profile("3.0" ); - add_profile("3.1" ); - add_profile("3.2" ); - add_profile("4" ); - add_profile("4.0" ); - add_profile("4.1" ); - add_profile("4.2" ); - add_profile("5" ); - add_profile("5.0" ); - add_profile("5.1" ); #undef add_profile - obs_properties_add_bool(props, "2pass", - obs_module_text("NVENC.Use2Pass")); + if (!ffmpeg) { + p = obs_properties_add_bool(props, "lookahead", + obs_module_text("NVENC.LookAhead")); + obs_property_set_long_description(p, + obs_module_text("NVENC.LookAhead.ToolTip")); + + p = obs_properties_add_bool(props, "psycho_aq", + obs_module_text("NVENC.PsychoVisualTuning")); + obs_property_set_long_description(p, + obs_module_text("NVENC.PsychoVisualTuning.ToolTip")); + } + obs_properties_add_int(props, "gpu", obs_module_text("GPU"), 0, 8, 1); obs_properties_add_int(props, "bf", obs_module_text("BFrames"), @@ -517,6 +509,18 @@ static obs_properties_t *nvenc_properties(void *unused) return props; } +obs_properties_t *nvenc_properties(void *unused) +{ + UNUSED_PARAMETER(unused); + return nvenc_properties_internal(false); +} + +obs_properties_t *nvenc_properties_ffmpeg(void *unused) +{ + UNUSED_PARAMETER(unused); + return nvenc_properties_internal(true); +} + static bool nvenc_extra_data(void *data, uint8_t **extra_data, size_t *size) { struct nvenc_encoder *enc = data; @@ -544,7 +548,7 @@ struct obs_encoder_info nvenc_encoder_info = { .destroy = nvenc_destroy, .encode = nvenc_encode, .get_defaults = nvenc_defaults, - .get_properties = nvenc_properties, + .get_properties = nvenc_properties_ffmpeg, .get_extra_data = nvenc_extra_data, .get_sei_data = nvenc_sei_data, .get_video_info = nvenc_video_info diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c index 9acdef2..7f687ee 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -45,6 +45,8 @@ struct ffmpeg_cfg { int audio_encoder_id; const char *video_settings; const char *audio_settings; + int audio_mix_count; + int audio_tracks; enum AVPixelFormat format; enum AVColorRange color_range; enum AVColorSpace color_space; @@ -56,7 +58,7 @@ struct ffmpeg_cfg { struct ffmpeg_data { AVStream *video; - AVStream *audio; + AVStream **audio_streams; AVCodec *acodec; AVCodec *vcodec; AVFormatContext *output; @@ -68,18 +70,24 @@ struct ffmpeg_data { uint64_t start_timestamp; - int64_t total_samples; + int64_t total_samples[MAX_AUDIO_MIXES]; uint32_t audio_samplerate; enum audio_format audio_format; size_t audio_planes; size_t audio_size; - struct circlebuf excess_frames[MAX_AV_PLANES]; - uint8_t *samples[MAX_AV_PLANES]; - AVFrame *aframe; + int num_audio_streams; + + /* audio_tracks is a bitmask storing the indices of the mixes */ + int audio_tracks; + struct circlebuf excess_frames[MAX_AUDIO_MIXES][MAX_AV_PLANES]; + uint8_t *samples[MAX_AUDIO_MIXES][MAX_AV_PLANES]; + AVFrame *aframe[MAX_AUDIO_MIXES]; struct ffmpeg_cfg config; bool initialized; + + char *last_error; }; struct ffmpeg_output { @@ -108,6 +116,30 @@ struct ffmpeg_output { /* ------------------------------------------------------------------------- */ +static void ffmpeg_output_set_last_error(struct ffmpeg_data *data, + const char *error) +{ + if (data->last_error) + bfree(data->last_error); + + data->last_error = bstrdup(error); +} + +void ffmpeg_log_error(int log_level, struct ffmpeg_data *data, + const char *format, ...) +{ + va_list args; + char out[4096]; + + va_start(args, format); + vsnprintf(out, sizeof(out), format, args); + va_end(args); + + ffmpeg_output_set_last_error(data, out); + + blog(log_level, "%s", out); +} + static bool new_stream(struct ffmpeg_data *data, AVStream **stream, AVCodec **codec, enum AVCodecID id, const char *name) { @@ -116,14 +148,14 @@ static bool new_stream(struct ffmpeg_data *data, AVStream **stream, avcodec_find_encoder(id); if (!*codec) { - blog(LOG_WARNING, "Couldn't find encoder '%s'", + ffmpeg_log_error(LOG_WARNING, data, "Couldn't find encoder '%s'", avcodec_get_name(id)); return false; } *stream = avformat_new_stream(data->output, *codec); if (!*stream) { - blog(LOG_WARNING, "Couldn't create stream for encoder '%s'", + ffmpeg_log_error(LOG_WARNING, data, "Couldn't create stream for encoder '%s'", avcodec_get_name(id)); return false; } @@ -180,14 +212,14 @@ static bool open_video_codec(struct ffmpeg_data *data) ret = avcodec_open2(context, data->vcodec, NULL); if (ret < 0) { - blog(LOG_WARNING, "Failed to open video codec: %s", + ffmpeg_log_error(LOG_WARNING, data, "Failed to open video codec: %s", av_err2str(ret)); return false; } data->vframe = av_frame_alloc(); if (!data->vframe) { - blog(LOG_WARNING, "Failed to allocate video frame"); + ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate video frame"); return false; } @@ -199,7 +231,7 @@ static bool open_video_codec(struct ffmpeg_data *data) ret = av_frame_get_buffer(data->vframe, base_get_alignment()); if (ret < 0) { - blog(LOG_WARNING, "Failed to allocate vframe: %s", + ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate vframe: %s", av_err2str(ret)); return false; } @@ -217,7 +249,7 @@ static bool init_swscale(struct ffmpeg_data *data, AVCodecContext *context) SWS_BICUBIC, NULL, NULL, NULL); if (!data->swscale) { - blog(LOG_WARNING, "Could not initialize swscale"); + ffmpeg_log_error(LOG_WARNING, data, "Could not initialize swscale"); return false; } @@ -231,7 +263,7 @@ static bool create_video_stream(struct ffmpeg_data *data) struct obs_video_info ovi; if (!obs_get_video_info(&ovi)) { - blog(LOG_WARNING, "No active video"); + ffmpeg_log_error(LOG_WARNING, data, "No active video"); return false; } @@ -273,9 +305,9 @@ static bool create_video_stream(struct ffmpeg_data *data) return true; } -static bool open_audio_codec(struct ffmpeg_data *data) +static bool open_audio_codec(struct ffmpeg_data *data, int idx) { - AVCodecContext *context = data->audio->codec; + AVCodecContext *context = data->audio_streams[idx]->codec; char **opts = strlist_split(data->config.audio_settings, ' ', false); int ret; @@ -284,32 +316,32 @@ static bool open_audio_codec(struct ffmpeg_data *data) strlist_free(opts); } - data->aframe = av_frame_alloc(); - if (!data->aframe) { - blog(LOG_WARNING, "Failed to allocate audio frame"); + data->aframe[idx] = av_frame_alloc(); + if (!data->aframe[idx]) { + ffmpeg_log_error(LOG_WARNING, data, "Failed to allocate audio frame"); return false; } - data->aframe->format = context->sample_fmt; - data->aframe->channels = context->channels; - data->aframe->channel_layout = context->channel_layout; - data->aframe->sample_rate = context->sample_rate; + data->aframe[idx]->format = context->sample_fmt; + data->aframe[idx]->channels = context->channels; + data->aframe[idx]->channel_layout = context->channel_layout; + data->aframe[idx]->sample_rate = context->sample_rate; context->strict_std_compliance = -2; ret = avcodec_open2(context, data->acodec, NULL); if (ret < 0) { - blog(LOG_WARNING, "Failed to open audio codec: %s", + ffmpeg_log_error(LOG_WARNING, data, "Failed to open audio codec: %s", av_err2str(ret)); return false; } data->frame_size = context->frame_size ? context->frame_size : 1024; - ret = av_samples_alloc(data->samples, NULL, context->channels, + ret = av_samples_alloc(data->samples[idx], NULL, context->channels, data->frame_size, context->sample_fmt, 0); if (ret < 0) { - blog(LOG_WARNING, "Failed to create audio buffer: %s", + ffmpeg_log_error(LOG_WARNING, data, "Failed to create audio buffer: %s", av_err2str(ret)); return false; } @@ -317,27 +349,29 @@ static bool open_audio_codec(struct ffmpeg_data *data) return true; } -static bool create_audio_stream(struct ffmpeg_data *data) +static bool create_audio_stream(struct ffmpeg_data *data, int idx) { AVCodecContext *context; + AVStream *stream; struct obs_audio_info aoi; if (!obs_get_audio_info(&aoi)) { - blog(LOG_WARNING, "No active audio"); + ffmpeg_log_error(LOG_WARNING, data, "No active audio"); return false; } - if (!new_stream(data, &data->audio, &data->acodec, + if (!new_stream(data, &stream, &data->acodec, data->output->oformat->audio_codec, data->config.audio_encoder)) return false; - context = data->audio->codec; - context->bit_rate = data->config.audio_bitrate * 1000; - context->time_base = (AVRational){ 1, aoi.samples_per_sec }; - context->channels = get_audio_channels(aoi.speakers); - context->sample_rate = aoi.samples_per_sec; - context->channel_layout = + data->audio_streams[idx] = stream; + context = data->audio_streams[idx]->codec; + context->bit_rate = data->config.audio_bitrate * 1000; + context->time_base = (AVRational){ 1, aoi.samples_per_sec }; + context->channels = get_audio_channels(aoi.speakers); + context->sample_rate = aoi.samples_per_sec; + context->channel_layout = av_get_default_channel_layout(context->channels); //AVlib default channel layout for 5 channels is 5.0 ; fix for 4.1 @@ -347,7 +381,7 @@ static bool create_audio_stream(struct ffmpeg_data *data) context->sample_fmt = data->acodec->sample_fmts ? data->acodec->sample_fmts[0] : AV_SAMPLE_FMT_FLTP; - data->audio->time_base = context->time_base; + data->audio_streams[idx]->time_base = context->time_base; data->audio_samplerate = aoi.samples_per_sec; data->audio_format = convert_ffmpeg_sample_format(context->sample_fmt); @@ -357,7 +391,7 @@ static bool create_audio_stream(struct ffmpeg_data *data) if (data->output->oformat->flags & AVFMT_GLOBALHEADER) context->flags |= CODEC_FLAG_GLOBAL_H; - return open_audio_codec(data); + return open_audio_codec(data, idx); } static inline bool init_streams(struct ffmpeg_data *data) @@ -368,9 +402,14 @@ static inline bool init_streams(struct ffmpeg_data *data) if (!create_video_stream(data)) return false; - if (format->audio_codec != AV_CODEC_ID_NONE) - if (!create_audio_stream(data)) - return false; + if (format->audio_codec != AV_CODEC_ID_NONE && data->num_audio_streams) { + data->audio_streams = calloc(1, + data->num_audio_streams * sizeof(void*)); + for (int i = 0; i < data->num_audio_streams; i++) { + if (!create_audio_stream(data, i)) + return false; + } + } return true; } @@ -383,7 +422,7 @@ static inline bool open_output_file(struct ffmpeg_data *data) AVDictionary *dict = NULL; if ((ret = av_dict_parse_string(&dict, data->config.muxer_settings, "=", " ", 0))) { - blog(LOG_WARNING, "Failed to parse muxer settings: %s\n%s", + ffmpeg_log_error(LOG_WARNING, data, "Failed to parse muxer settings: %s\n%s", av_err2str(ret), data->config.muxer_settings); av_dict_free(&dict); @@ -406,8 +445,9 @@ static inline bool open_output_file(struct ffmpeg_data *data) ret = avio_open2(&data->output->pb, data->config.url, AVIO_FLAG_WRITE, NULL, &dict); if (ret < 0) { - blog(LOG_WARNING, "Couldn't open '%s', %s", - data->config.url, av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, data, + "Couldn't open '%s', %s", data->config.url, + av_err2str(ret)); av_dict_free(&dict); return false; } @@ -419,7 +459,7 @@ static inline bool open_output_file(struct ffmpeg_data *data) ret = avformat_write_header(data->output, &dict); if (ret < 0) { - blog(LOG_WARNING, "Error opening '%s': %s", + ffmpeg_log_error(LOG_WARNING, data, "Error opening '%s': %s", data->config.url, av_err2str(ret)); return false; } @@ -457,12 +497,17 @@ static void close_video(struct ffmpeg_data *data) static void close_audio(struct ffmpeg_data *data) { - for (size_t i = 0; i < MAX_AV_PLANES; i++) - circlebuf_free(&data->excess_frames[i]); + for (int idx = 0; idx < data->num_audio_streams; idx++) { + for (size_t i = 0; i < MAX_AV_PLANES; i++) + circlebuf_free(&data->excess_frames[idx][i]); - av_freep(&data->samples[0]); - avcodec_close(data->audio->codec); - av_frame_free(&data->aframe); + if (data->samples[idx][0]) + av_freep(&data->samples[idx][0]); + if (data->audio_streams[idx]) + avcodec_close(data->audio_streams[idx]->codec); + if (data->aframe[idx]) + av_frame_free(&data->aframe[idx]); + } } static void ffmpeg_data_free(struct ffmpeg_data *data) @@ -472,8 +517,11 @@ static void ffmpeg_data_free(struct ffmpeg_data *data) if (data->video) close_video(data); - if (data->audio) + if (data->audio_streams) { close_audio(data); + free(data->audio_streams); + data->audio_streams = NULL; + } if (data->output) { if ((data->output->oformat->flags & AVFMT_NOFILE) == 0) @@ -482,6 +530,9 @@ static void ffmpeg_data_free(struct ffmpeg_data *data) avformat_free_context(data->output); } + if (data->last_error) + bfree(data->last_error); + memset(data, 0, sizeof(struct ffmpeg_data)); } @@ -528,7 +579,8 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data, memset(data, 0, sizeof(struct ffmpeg_data)); data->config = *config; - + data->num_audio_streams = config->audio_mix_count; + data->audio_tracks = config->audio_tracks; if (!config->url || !*config->url) return false; @@ -543,19 +595,27 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data, is_rtmp ? NULL : data->config.format_mime_type); if (output_format == NULL) { - blog(LOG_WARNING, "Couldn't find matching output format with " - " parameters: name=%s, url=%s, mime=%s", - safe_str(is_rtmp ? - "flv" : data->config.format_name), - safe_str(data->config.url), - safe_str(is_rtmp ? - NULL : data->config.format_mime_type)); + ffmpeg_log_error(LOG_WARNING, data, + "Couldn't find matching output format with " + "parameters: name=%s, url=%s, mime=%s", + safe_str(is_rtmp ? + "flv" : data->config.format_name), + safe_str(data->config.url), + safe_str(is_rtmp ? + NULL : data->config.format_mime_type)); + goto fail; } avformat_alloc_output_context2(&data->output, output_format, NULL, NULL); + if (!data->output) { + ffmpeg_log_error(LOG_WARNING, data, + "Couldn't create avformat context"); + goto fail; + } + if (is_rtmp) { data->output->oformat->video_codec = AV_CODEC_ID_H264; data->output->oformat->audio_codec = AV_CODEC_ID_AAC; @@ -564,11 +624,6 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data, set_encoder_ids(data); } - if (!data->output) { - blog(LOG_WARNING, "Couldn't create avformat context"); - goto fail; - } - if (!init_streams(data)) goto fail; if (!open_output_file(data)) @@ -581,7 +636,6 @@ static bool ffmpeg_data_init(struct ffmpeg_data *data, fail: blog(LOG_WARNING, "ffmpeg_data_init failed"); - ffmpeg_data_free(data); return false; } @@ -736,6 +790,7 @@ static void receive_video(void *param, struct video_data *frame) if (ret < 0) { blog(LOG_WARNING, "receive_video: Error encoding " "video: %s", av_err2str(ret)); + //FIXME: stop the encode with an error return; } @@ -761,12 +816,13 @@ static void receive_video(void *param, struct video_data *frame) if (ret != 0) { blog(LOG_WARNING, "receive_video: Error writing video: %s", av_err2str(ret)); + //FIXME: stop the encode with an error } data->total_frames++; } -static void encode_audio(struct ffmpeg_output *output, +static void encode_audio(struct ffmpeg_output *output, int idx, struct AVCodecContext *context, size_t block_size) { struct ffmpeg_data *data = &output->ff_data; @@ -775,24 +831,25 @@ static void encode_audio(struct ffmpeg_output *output, int ret, got_packet; size_t total_size = data->frame_size * block_size * context->channels; - data->aframe->nb_samples = data->frame_size; - data->aframe->pts = av_rescale_q(data->total_samples, + data->aframe[idx]->nb_samples = data->frame_size; + data->aframe[idx]->pts = av_rescale_q(data->total_samples[idx], (AVRational){1, context->sample_rate}, context->time_base); - ret = avcodec_fill_audio_frame(data->aframe, context->channels, - context->sample_fmt, data->samples[0], + ret = avcodec_fill_audio_frame(data->aframe[idx], context->channels, + context->sample_fmt, data->samples[idx][0], (int)total_size, 1); if (ret < 0) { blog(LOG_WARNING, "encode_audio: avcodec_fill_audio_frame " "failed: %s", av_err2str(ret)); + //FIXME: stop the encode with an error return; } - data->total_samples += data->frame_size; + data->total_samples[idx] += data->frame_size; #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101) - ret = avcodec_send_frame(context, data->aframe); + ret = avcodec_send_frame(context, data->aframe[idx]); if (ret == 0) ret = avcodec_receive_packet(context, &packet); @@ -801,23 +858,26 @@ static void encode_audio(struct ffmpeg_output *output, if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) ret = 0; #else - ret = avcodec_encode_audio2(context, &packet, data->aframe, + ret = avcodec_encode_audio2(context, &packet, data->aframe[idx], &got_packet); #endif if (ret < 0) { blog(LOG_WARNING, "encode_audio: Error encoding audio: %s", av_err2str(ret)); + //FIXME: stop the encode with an error return; } if (!got_packet) return; - packet.pts = rescale_ts(packet.pts, context, data->audio->time_base); - packet.dts = rescale_ts(packet.dts, context, data->audio->time_base); + packet.pts = rescale_ts(packet.pts, context, + data->audio_streams[idx]->time_base); + packet.dts = rescale_ts(packet.dts, context, + data->audio_streams[idx]->time_base); packet.duration = (int)av_rescale_q(packet.duration, context->time_base, - data->audio->time_base); - packet.stream_index = data->audio->index; + data->audio_streams[idx]->time_base); + packet.stream_index = data->audio_streams[idx]->index; pthread_mutex_lock(&output->write_mutex); da_push_back(output->packets, &packet); @@ -853,18 +913,38 @@ static bool prepare_audio(struct ffmpeg_data *data, return true; } -static void receive_audio(void *param, struct audio_data *frame) +/* Given a bitmask for the selected tracks and the mix index, + * this returns the stream index which will be passed to the muxer. */ +static int get_track_order(int track_config, size_t mix_index) +{ + int position = 0; + for (size_t i = 0; i < mix_index; i++) { + if (track_config & 1 << i) + position++; + } + return position; +} + +static void receive_audio(void *param, size_t mix_idx, struct audio_data *frame) { struct ffmpeg_output *output = param; struct ffmpeg_data *data = &output->ff_data; size_t frame_size_bytes; struct audio_data in; + int track_order; // codec doesn't support audio or none configured - if (!data->audio) + if (!data->audio_streams) return; - AVCodecContext *context = data->audio->codec; + /* check that the track was selected */ + if ((data->audio_tracks & (1 << mix_idx)) == 0) + return; + + /* get track order (first selected, etc ...) */ + track_order = get_track_order(data->audio_tracks, mix_idx); + + AVCodecContext *context = data->audio_streams[track_order]->codec; if (!data->start_timestamp) return; @@ -877,15 +957,16 @@ static void receive_audio(void *param, struct audio_data *frame) frame_size_bytes = (size_t)data->frame_size * data->audio_size; for (size_t i = 0; i < data->audio_planes; i++) - circlebuf_push_back(&data->excess_frames[i], in.data[i], - in.frames * data->audio_size); + circlebuf_push_back(&data->excess_frames[track_order][i], + in.data[i], in.frames * data->audio_size); - while (data->excess_frames[0].size >= frame_size_bytes) { + while (data->excess_frames[track_order][0].size >= frame_size_bytes) { for (size_t i = 0; i < data->audio_planes; i++) - circlebuf_pop_front(&data->excess_frames[i], - data->samples[i], frame_size_bytes); + circlebuf_pop_front(&data->excess_frames[track_order][i], + data->samples[track_order][i], + frame_size_bytes); - encode_audio(output, context, data->audio_size); + encode_audio(output, track_order, context, data->audio_size); } } @@ -901,7 +982,7 @@ static uint64_t get_packet_sys_dts(struct ffmpeg_output *output, time_base = data->video->time_base; start_ts = output->video_start_ts; } else { - time_base = data->audio->time_base; + time_base = data->audio_streams[0]->time_base; start_ts = output->audio_start_ts; } @@ -944,8 +1025,9 @@ static int process_packet(struct ffmpeg_output *output) ret = av_interleaved_write_frame(output->ff_data.output, &packet); if (ret < 0) { av_free_packet(&packet); - blog(LOG_WARNING, "receive_audio: Error writing packet: %s", - av_err2str(ret)); + ffmpeg_log_error(LOG_WARNING, &output->ff_data, + "receive_audio: Error writing packet: %s", + av_err2str(ret)); return ret; } @@ -990,6 +1072,18 @@ static inline const char *get_string_or_null(obs_data_t *settings, return value; } +static int get_audio_mix_count(int audio_mix_mask) +{ + int mix_count = 0; + for (int i = 0; i < MAX_AUDIO_MIXES; i++) { + if ((audio_mix_mask & (1 << i)) != 0) { + mix_count++; + } + } + + return mix_count; +} + static bool try_connect(struct ffmpeg_output *output) { video_t *video = obs_output_video(output->output); @@ -1025,6 +1119,8 @@ static bool try_connect(struct ffmpeg_output *output) config.height = (int)obs_output_get_height(output->output); config.format = obs_to_ffmpeg_video_format( video_output_get_format(video)); + config.audio_tracks = (int)obs_output_get_mixers(output->output); + config.audio_mix_count = get_audio_mix_count(config.audio_tracks); if (format_is_yuv(voi->format)) { config.color_range = voi->range == VIDEO_RANGE_FULL ? @@ -1049,8 +1145,14 @@ static bool try_connect(struct ffmpeg_output *output) success = ffmpeg_data_init(&output->ff_data, &config); obs_data_release(settings); - if (!success) + if (!success) { + if (output->ff_data.last_error) { + obs_output_set_last_error(output->output, + output->ff_data.last_error); + } + ffmpeg_data_free(&output->ff_data); return false; + } struct audio_convert_info aci = { .format = output->ff_data.audio_format @@ -1063,8 +1165,9 @@ static bool try_connect(struct ffmpeg_output *output) ret = pthread_create(&output->write_thread, NULL, write_thread, output); if (ret != 0) { - blog(LOG_WARNING, "ffmpeg_output_start: failed to create write " - "thread."); + ffmpeg_log_error(LOG_WARNING, &output->ff_data, + "ffmpeg_output_start: failed to create write " + "thread."); ffmpeg_output_full_stop(output); return false; } @@ -1157,13 +1260,15 @@ static uint64_t ffmpeg_output_total_bytes(void *data) struct obs_output_info ffmpeg_output = { .id = "ffmpeg_output", - .flags = OBS_OUTPUT_AUDIO | OBS_OUTPUT_VIDEO, + .flags = OBS_OUTPUT_AUDIO | + OBS_OUTPUT_VIDEO | + OBS_OUTPUT_MULTI_TRACK, .get_name = ffmpeg_output_getname, .create = ffmpeg_output_create, .destroy = ffmpeg_output_destroy, .start = ffmpeg_output_start, .stop = ffmpeg_output_stop, .raw_video = receive_video, - .raw_audio = receive_audio, + .raw_audio2 = receive_audio, .get_total_bytes = ffmpeg_output_total_bytes, }; diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-source.c b/plugins/obs-ffmpeg/obs-ffmpeg-source.c index 730ad6d..b1fe369 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-source.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-source.c @@ -155,6 +155,10 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data) obs_properties_add_bool(props, "restart_on_activate", obs_module_text("RestartWhenActivated")); + obs_properties_add_int_slider(props, "buffering_mb", + obs_module_text("BufferingMB"), + 1, 16, 1); + obs_properties_add_text(props, "input", obs_module_text("Input"), OBS_TEXT_DEFAULT); diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c new file mode 100644 index 0000000..28b4d6f --- /dev/null +++ b/plugins/obs-ffmpeg/obs-ffmpeg-vaapi.c @@ -0,0 +1,539 @@ +/****************************************************************************** + Copyright (C) 2016 by Hugh Bailey + + 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, see . +******************************************************************************/ + +#include + +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 27, 100) + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "obs-ffmpeg-formats.h" + +#define do_log(level, format, ...) \ + blog(level, "[FFMPEG VAAPI encoder: '%s'] " format, \ + obs_encoder_get_name(enc->encoder), ##__VA_ARGS__) + +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) + +struct vaapi_encoder { + obs_encoder_t *encoder; + + AVBufferRef *vadevice_ref; + AVBufferRef *vaframes_ref; + + AVCodec * vaapi; + AVCodecContext *context; + + AVFrame *vframe; + + DARRAY(uint8_t) buffer; + + uint8_t *header; + size_t header_size; + + uint8_t *sei; + size_t sei_size; + + int height; + bool first_packet; + bool initialized; +}; + +static const char *vaapi_getname(void *unused) +{ + UNUSED_PARAMETER(unused); + return "FFMPEG VAAPI"; +} + +static inline bool valid_format(enum video_format format) +{ + return format == VIDEO_FORMAT_NV12; +} + +static void vaapi_video_info(void *data, struct video_scale_info *info) +{ + struct vaapi_encoder *enc = data; + enum video_format pref_format; + + pref_format = obs_encoder_get_preferred_video_format(enc->encoder); + + if (!valid_format(pref_format)) { + pref_format = valid_format(info->format) ? info->format + : VIDEO_FORMAT_NV12; + } + + info->format = pref_format; +} + +static bool vaapi_init_codec(struct vaapi_encoder *enc, const char *path) +{ + int ret; + + ret = av_hwdevice_ctx_create(&enc->vadevice_ref, AV_HWDEVICE_TYPE_VAAPI, + path, NULL, 0); + if (ret < 0) { + warn("Failed to create VAAPI device context: %s", + av_err2str(ret)); + return false; + } + + enc->vaframes_ref = av_hwframe_ctx_alloc(enc->vadevice_ref); + if (!enc->vaframes_ref) { + warn("Failed to alloc HW frames context"); + return false; + } + + AVHWFramesContext *frames_ctx = + (AVHWFramesContext *)enc->vaframes_ref->data; + frames_ctx->format = AV_PIX_FMT_VAAPI; + frames_ctx->sw_format = AV_PIX_FMT_NV12; + frames_ctx->width = enc->context->width; + frames_ctx->height = enc->context->height; + frames_ctx->initial_pool_size = 20; + + ret = av_hwframe_ctx_init(enc->vaframes_ref); + if (ret < 0) { + warn("Failed to init HW frames context: %s", av_err2str(ret)); + return false; + } + + /* 2. Create software frame and picture */ + enc->vframe = av_frame_alloc(); + if (!enc->vframe) { + warn("Failed to allocate video frame"); + return false; + } + + enc->vframe->format = enc->context->pix_fmt; + enc->vframe->width = enc->context->width; + enc->vframe->height = enc->context->height; + enc->vframe->colorspace = enc->context->colorspace; + enc->vframe->color_range = enc->context->color_range; + + ret = av_frame_get_buffer(enc->vframe, base_get_alignment()); + if (ret < 0) { + warn("Failed to allocate vframe: %s", av_err2str(ret)); + return false; + } + + /* 3. set up codec */ + enc->context->pix_fmt = AV_PIX_FMT_VAAPI; + enc->context->hw_frames_ctx = av_buffer_ref(enc->vaframes_ref); + + ret = avcodec_open2(enc->context, enc->vaapi, NULL); + if (ret < 0) { + warn("Failed to open VAAPI codec: %s", av_err2str(ret)); + return false; + } + + enc->initialized = true; + return true; +} + +static bool vaapi_update(void *data, obs_data_t *settings) +{ + struct vaapi_encoder *enc = data; + + const char *device = obs_data_get_string(settings, "vaapi_device"); + + int profile = (int)obs_data_get_int(settings, "profile"); + int bf = (int)obs_data_get_int(settings, "bf"); + + int level = (int)obs_data_get_int(settings, "level"); + int bitrate = (int)obs_data_get_int(settings, "bitrate"); + int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec"); + + int qp = (int)obs_data_get_int(settings, "qp"); + int quality = (int)obs_data_get_int(settings, "quality"); + + av_opt_set_int(enc->context->priv_data, "qp", qp, 0); + av_opt_set_int(enc->context->priv_data, "quality", quality, 0); + + video_t * video = obs_encoder_video(enc->encoder); + const struct video_output_info *voi = video_output_get_info(video); + struct video_scale_info info; + + info.format = voi->format; + info.colorspace = voi->colorspace; + info.range = voi->range; + + vaapi_video_info(enc, &info); + + enc->context->profile = profile; + enc->context->max_b_frames = bf; + enc->context->level = level; + enc->context->bit_rate = bitrate * 1000; + enc->context->rc_max_rate = bitrate * 1000; + + enc->context->width = obs_encoder_get_width(enc->encoder); + enc->context->height = obs_encoder_get_height(enc->encoder); + + enc->context->time_base = (AVRational){voi->fps_den, voi->fps_num}; + enc->context->pix_fmt = obs_to_ffmpeg_video_format(info.format); + enc->context->colorspace = info.colorspace == VIDEO_CS_709 + ? AVCOL_SPC_BT709 + : AVCOL_SPC_BT470BG; + enc->context->color_range = info.range == VIDEO_RANGE_FULL + ? AVCOL_RANGE_JPEG + : AVCOL_RANGE_MPEG; + + if (keyint_sec > 0) { + enc->context->gop_size = + keyint_sec * voi->fps_num / voi->fps_den; + } else { + enc->context->gop_size = 120; + } + + enc->height = enc->context->height; + + info("settings:\n" + "\tdevice: %s\n" + "\tqp: %d\n" + "\tquality: %d\n" + "\tprofile: %d\n" + "\tlevel: %d\n" + "\tbitrate: %d\n" + "\tkeyint: %d\n" + "\twidth: %d\n" + "\theight: %d\n" + "\tb-frames: %d\n", + device, qp, quality, profile, level, bitrate, + enc->context->gop_size, enc->context->width, + enc->context->height, enc->context->max_b_frames); + + return vaapi_init_codec(enc, device); +} + +static void vaapi_destroy(void *data) +{ + struct vaapi_encoder *enc = data; + + if (enc->initialized) { + AVPacket pkt = {0}; + int r_pkt = 1; + + while (r_pkt) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101) + if (avcodec_receive_packet(enc->context, &pkt) < 0) + break; +#else + if (avcodec_encode_video2(enc->context, &pkt, NULL, + &r_pkt) < 0) + break; +#endif + + if (r_pkt) + av_packet_unref(&pkt); + } + } + + avcodec_close(enc->context); + av_frame_unref(enc->vframe); + av_frame_free(&enc->vframe); + av_buffer_unref(&enc->vaframes_ref); + av_buffer_unref(&enc->vadevice_ref); + da_free(enc->buffer); + bfree(enc->header); + bfree(enc->sei); + + bfree(enc); +} + +static void *vaapi_create(obs_data_t *settings, obs_encoder_t *encoder) +{ + struct vaapi_encoder *enc; + avcodec_register_all(); + + enc = bzalloc(sizeof(*enc)); + enc->encoder = encoder; + + int vaapi_codec = (int)obs_data_get_int(settings, "vaapi_codec"); + + if (vaapi_codec == AV_CODEC_ID_H264) { + enc->vaapi = avcodec_find_encoder_by_name("h264_vaapi"); + } + + enc->first_packet = true; + + blog(LOG_INFO, "---------------------------------"); + + if (!enc->vaapi) { + warn("Couldn't find encoder"); + goto fail; + } + + enc->context = avcodec_alloc_context3(enc->vaapi); + if (!enc->context) { + warn("Failed to create codec context"); + goto fail; + } + + if (!vaapi_update(enc, settings)) + goto fail; + + return enc; + +fail: + vaapi_destroy(enc); + return NULL; +} + +static inline void copy_data(AVFrame *pic, const struct encoder_frame *frame, + int height, enum AVPixelFormat format) +{ + int h_chroma_shift, v_chroma_shift; + av_pix_fmt_get_chroma_sub_sample( + format, &h_chroma_shift, &v_chroma_shift); + for (int plane = 0; plane < MAX_AV_PLANES; plane++) { + if (!frame->data[plane]) + continue; + + int frame_rowsize = (int)frame->linesize[plane]; + int pic_rowsize = pic->linesize[plane]; + int bytes = frame_rowsize < pic_rowsize ? frame_rowsize + : pic_rowsize; + int plane_height = height >> (plane ? v_chroma_shift : 0); + + for (int y = 0; y < plane_height; y++) { + int pos_frame = y * frame_rowsize; + int pos_pic = y * pic_rowsize; + + memcpy(pic->data[plane] + pos_pic, + frame->data[plane] + pos_frame, bytes); + } + } +} + +static bool vaapi_encode(void *data, struct encoder_frame *frame, + struct encoder_packet *packet, bool *received_packet) +{ + struct vaapi_encoder *enc = data; + AVFrame * hwframe = NULL; + AVPacket av_pkt; + int got_packet; + int ret; + + hwframe = av_frame_alloc(); + if (!hwframe) { + warn("vaapi_encode: failed to allocate hw frame"); + return false; + } + + ret = av_hwframe_get_buffer(enc->vaframes_ref, hwframe, 0); + if (ret < 0) { + warn("vaapi_encode: failed to get buffer for hw frame: %s", + av_err2str(ret)); + goto fail; + } + + copy_data(enc->vframe, frame, enc->height, enc->context->pix_fmt); + + enc->vframe->pts = frame->pts; + hwframe->pts = frame->pts; + hwframe->width = enc->vframe->width; + hwframe->height = enc->vframe->height; + + ret = av_hwframe_transfer_data(hwframe, enc->vframe, 0); + if (ret < 0) { + warn("vaapi_encode: failed to upload hw frame: %s", + av_err2str(ret)); + goto fail; + } + + ret = av_frame_copy_props(hwframe, enc->vframe); + if (ret < 0) { + warn("vaapi_encode: failed to copy props to hw frame: %s", + av_err2str(ret)); + goto fail; + } + + av_init_packet(&av_pkt); + +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(57, 40, 101) + ret = avcodec_send_frame(enc->context, hwframe); + if (ret == 0) + ret = avcodec_receive_packet(enc->context, &av_pkt); + + got_packet = (ret == 0); + + if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) + ret = 0; +#else + ret = avcodec_encode_video2( + enc->context, &av_pkt, hwframe, &got_packet); +#endif + if (ret < 0) { + warn("vaapi_encode: Error encoding: %s", av_err2str(ret)); + goto fail; + } + + if (got_packet && av_pkt.size) { + if (enc->first_packet) { + uint8_t *new_packet; + size_t size; + + enc->first_packet = false; + obs_extract_avc_headers(av_pkt.data, av_pkt.size, + &new_packet, &size, &enc->header, + &enc->header_size, &enc->sei, + &enc->sei_size); + + da_copy_array(enc->buffer, new_packet, size); + bfree(new_packet); + } else { + da_copy_array(enc->buffer, av_pkt.data, av_pkt.size); + } + + packet->pts = av_pkt.pts; + packet->dts = av_pkt.dts; + packet->data = enc->buffer.array; + packet->size = enc->buffer.num; + packet->type = OBS_ENCODER_VIDEO; + packet->keyframe = obs_avc_keyframe(packet->data, packet->size); + *received_packet = true; + } else { + *received_packet = false; + } + + av_packet_unref(&av_pkt); + av_frame_free(&hwframe); + return true; + +fail: + av_frame_free(&hwframe); + return false; +} + +static void set_visible(obs_properties_t *ppts, const char *name, bool visible) +{ + obs_property_t *p = obs_properties_get(ppts, name); + obs_property_set_visible(p, visible); +} + +static void vaapi_defaults(obs_data_t *settings) +{ + obs_data_set_default_string( + settings, "vaapi_device", "/dev/dri/renderD128"); + obs_data_set_default_int(settings, "vaapi_codec", AV_CODEC_ID_H264); + obs_data_set_default_int(settings, "profile", + FF_PROFILE_H264_CONSTRAINED_BASELINE); + obs_data_set_default_int(settings, "level", 40); + obs_data_set_default_int(settings, "bitrate", 2500); + obs_data_set_default_int(settings, "keyint_sec", 0); + obs_data_set_default_int(settings, "bf", 0); + obs_data_set_default_int(settings, "qp", 20); + obs_data_set_default_int(settings, "quality", 0); + obs_data_set_default_int(settings, "rendermode", 0); +} + +static obs_properties_t *vaapi_properties(void *unused) +{ + UNUSED_PARAMETER(unused); + + obs_properties_t *props = obs_properties_create(); + obs_property_t * list; + + list = obs_properties_add_list(props, "vaapi_device", "VAAPI Device", + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING); + char path[32] = "/dev/dri/renderD1"; + for (int i = 28;; i++) { + sprintf(path, "/dev/dri/renderD1%d", i); + if (access(path, F_OK) == 0) { + char card[128] = "Card: "; + sprintf(card, "Card%d: %s", i - 28, path); + obs_property_list_add_string(list, card, path); + } else { + break; + } + } + + list = obs_properties_add_list(props, "vaapi_codec", "VAAPI Codec", + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + + obs_property_list_add_int(list, "H.264 (default)", AV_CODEC_ID_H264); + + list = obs_properties_add_list(props, "level", "Level", + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(list, "480p30 (3.0)", 30); + obs_property_list_add_int(list, "720p30/480p60 (3.1)", 31); + obs_property_list_add_int( + list, "Compatibility mode (4.0 default)", 40); + obs_property_list_add_int(list, "720p60/1080p30 (4.1)", 41); + obs_property_list_add_int(list, "1080p60 (4.2)", 42); + + obs_property_t *p; + p = obs_properties_add_int(props, "bitrate", obs_module_text("Bitrate"), 0, + 300000, 50); + obs_property_int_set_suffix(p, " Kbps"); + + obs_properties_add_int(props, "keyint_sec", + obs_module_text("Keyframe Interval (seconds)"), 0, 20, + 1); + + return props; +} + +static bool vaapi_extra_data(void *data, uint8_t **extra_data, size_t *size) +{ + struct vaapi_encoder *enc = data; + + *extra_data = enc->header; + *size = enc->header_size; + return true; +} + +static bool vaapi_sei_data(void *data, uint8_t **extra_data, size_t *size) +{ + struct vaapi_encoder *enc = data; + + *extra_data = enc->sei; + *size = enc->sei_size; + return true; +} + +struct obs_encoder_info vaapi_encoder_info = { + .id = "ffmpeg_vaapi", + .type = OBS_ENCODER_VIDEO, + .codec = "h264", + .get_name = vaapi_getname, + .create = vaapi_create, + .destroy = vaapi_destroy, + .encode = vaapi_encode, + .get_defaults = vaapi_defaults, + .get_properties = vaapi_properties, + .get_extra_data = vaapi_extra_data, + .get_sei_data = vaapi_sei_data, + .get_video_info = vaapi_video_info +}; + +#endif diff --git a/plugins/obs-ffmpeg/obs-ffmpeg.c b/plugins/obs-ffmpeg/obs-ffmpeg.c index 3ccef9b..808e5a0 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg.c @@ -2,12 +2,23 @@ #include #include #include +#include #include #include #include +#ifdef _WIN32 +#include +#include +#include +#endif + OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("obs-ffmpeg", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "FFmpeg based sources/outputs/encoders"; +} extern struct obs_source_info ffmpeg_source; extern struct obs_output_info ffmpeg_output; @@ -17,6 +28,14 @@ extern struct obs_encoder_info aac_encoder_info; extern struct obs_encoder_info opus_encoder_info; extern struct obs_encoder_info nvenc_encoder_info; +#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 27, 100) +#define LIBAVUTIL_VAAPI_AVAILABLE +#endif + +#ifdef LIBAVUTIL_VAAPI_AVAILABLE +extern struct obs_encoder_info vaapi_encoder_info; +#endif + static DARRAY(struct log_context { void *context; char str[4096]; @@ -121,6 +140,130 @@ cleanup: static const char *nvenc_check_name = "nvenc_check"; +#ifdef _WIN32 +static const wchar_t *blacklisted_adapters[] = { + L"720M", + L"730M", + L"740M", + L"745M", + L"820M", + L"830M", + L"840M", + L"845M", + L"920M", + L"930M", + L"940M", + L"945M", + L"1030", + L"MX110", + L"MX130", + L"MX150", + L"MX230", + L"MX250", + L"M520", + L"M500", + L"P500", + L"K620M" +}; + +static const size_t num_blacklisted = + sizeof(blacklisted_adapters) / sizeof(blacklisted_adapters[0]); + +static bool is_adapter(const wchar_t *name, const wchar_t *adapter) +{ + const wchar_t *find = wstrstri(name, adapter); + if (!find) { + return false; + } + + /* check before string for potential numeric mismatch */ + if (find > name && iswdigit(find[-1]) && iswdigit(find[0])) { + return false; + } + + /* check after string for potential numeric mismatch */ + size_t len = wcslen(adapter); + if (iswdigit(find[len - 1]) && iswdigit(find[len])) { + return false; + } + + return true; +} + +static bool is_blacklisted(const wchar_t *name) +{ + for (size_t i = 0; i < num_blacklisted; i++) { + const wchar_t *blacklisted_adapter = blacklisted_adapters[i]; + if (is_adapter(name, blacklisted_adapter)) { + return true; + } + } + + return false; +} + +typedef HRESULT (WINAPI *create_dxgi_proc)(const IID *, IDXGIFactory1 **); + +static bool nvenc_device_available(void) +{ + static HMODULE dxgi = NULL; + static create_dxgi_proc create = NULL; + IDXGIFactory1 *factory; + IDXGIAdapter1 *adapter; + bool available = false; + HRESULT hr; + UINT i = 0; + + if (!dxgi) { + dxgi = GetModuleHandleW(L"dxgi"); + if (!dxgi) { + dxgi = LoadLibraryW(L"dxgi"); + if (!dxgi) { + return true; + } + } + } + + if (!create) { + create = (create_dxgi_proc)GetProcAddress(dxgi, + "CreateDXGIFactory1"); + if (!create) { + return true; + } + } + + hr = create(&IID_IDXGIFactory1, &factory); + if (FAILED(hr)) { + return true; + } + + while (factory->lpVtbl->EnumAdapters1(factory, i++, &adapter) == S_OK) { + DXGI_ADAPTER_DESC desc; + + hr = adapter->lpVtbl->GetDesc(adapter, &desc); + adapter->lpVtbl->Release(adapter); + + if (FAILED(hr)) { + continue; + } + + if (wstrstri(desc.Description, L"nvidia") && + !is_blacklisted(desc.Description)) { + available = true; + goto finish; + } + } + +finish: + factory->lpVtbl->Release(factory); + return available; +} +#endif + +#ifdef _WIN32 +extern bool load_nvenc_lib(void); +#endif + static bool nvenc_supported(void) { av_register_all(); @@ -136,10 +279,12 @@ static bool nvenc_supported(void) } #if defined(_WIN32) - if (sizeof(void*) == 8) { - lib = os_dlopen("nvEncodeAPI64.dll"); - } else { - lib = os_dlopen("nvEncodeAPI.dll"); + if (!nvenc_device_available()) { + goto cleanup; + } + if (load_nvenc_lib()) { + success = true; + goto finish; } #else lib = os_dlopen("libnvidia-encode.so.1"); @@ -152,12 +297,28 @@ static bool nvenc_supported(void) cleanup: if (lib) os_dlclose(lib); +#if defined(_WIN32) +finish: +#endif profile_end(nvenc_check_name); return success; } #endif +#ifdef LIBAVUTIL_VAAPI_AVAILABLE +static bool vaapi_supported(void) +{ + AVCodec *vaenc = avcodec_find_encoder_by_name("h264_vaapi"); + return !!vaenc; +} +#endif + +#ifdef _WIN32 +extern void jim_nvenc_load(void); +extern void jim_nvenc_unload(void); +#endif + bool obs_module_load(void) { da_init(active_log_contexts); @@ -174,8 +335,19 @@ bool obs_module_load(void) #ifndef __APPLE__ if (nvenc_supported()) { blog(LOG_INFO, "NVENC supported"); +#ifdef _WIN32 + if (get_win_ver_int() > 0x0601) { + jim_nvenc_load(); + } +#endif obs_register_encoder(&nvenc_encoder_info); } +#if !defined(_WIN32) && defined(LIBAVUTIL_VAAPI_AVAILABLE) + if (vaapi_supported()) { + blog(LOG_INFO, "FFMPEG VAAPI supported"); + obs_register_encoder(&vaapi_encoder_info); + } +#endif #endif return true; } @@ -197,4 +369,8 @@ void obs_module_unload(void) da_free(active_log_contexts); da_free(cached_log_contexts); + +#ifdef _WIN32 + jim_nvenc_unload(); +#endif } diff --git a/plugins/obs-filters/CMakeLists.txt b/plugins/obs-filters/CMakeLists.txt index ec4289c..d6cf13c 100644 --- a/plugins/obs-filters/CMakeLists.txt +++ b/plugins/obs-filters/CMakeLists.txt @@ -1,13 +1,23 @@ project(obs-filters) -find_package(Libspeexdsp QUIET) -if(LIBSPEEXDSP_FOUND) - set(obs-filters_LIBSPEEXDSP_SOURCES - noise-suppress-filter.c) - set(obs-filters_LIBSPEEXDSP_LIBRARIES - ${LIBSPEEXDSP_LIBRARIES}) +option(DISABLE_SPEEXDSP "Disable building of the SpeexDSP-based Noise Suppression filter" OFF) + +if(DISABLE_SPEEXDSP) + message(STATUS "SpeexDSP support disabled") + set(LIBSPEEXDSP_FOUND FALSE) else() - message(STATUS "Speexdsp library not found, speexdsp filters disabled") + find_package(Libspeexdsp QUIET) + + if(NOT LIBSPEEXDSP_FOUND) + message(STATUS "SpeexDSP support not found") + set(LIBSPEEXDSP_FOUND FALSE) + else() + message(STATUS "SpeexDSP supported") + set(obs-filters_LIBSPEEXDSP_SOURCES + noise-suppress-filter.c) + set(obs-filters_LIBSPEEXDSP_LIBRARIES + ${LIBSPEEXDSP_LIBRARIES}) + endif() endif() configure_file("${CMAKE_CURRENT_SOURCE_DIR}/obs-filters-config.h.in" @@ -38,7 +48,11 @@ set(obs-filters_SOURCES gain-filter.c noise-gate-filter.c mask-filter.c - compressor-filter.c) + invert-audio-polarity.c + compressor-filter.c + limiter-filter.c + expander-filter.c + luma-key-filter.c) add_library(obs-filters MODULE ${obs-filters_SOURCES} diff --git a/plugins/obs-filters/chroma-key-filter.c b/plugins/obs-filters/chroma-key-filter.c index 728135e..3fa9790 100644 --- a/plugins/obs-filters/chroma-key-filter.c +++ b/plugins/obs-filters/chroma-key-filter.c @@ -35,7 +35,6 @@ struct chroma_key_filter_data { gs_eparam_t *pixel_size_param; gs_eparam_t *chroma_param; - gs_eparam_t *key_rgb_param; gs_eparam_t *similarity_param; gs_eparam_t *smoothness_param; gs_eparam_t *spill_param; @@ -45,7 +44,6 @@ struct chroma_key_filter_data { float brightness; float gamma; - struct vec4 key_rgb; struct vec2 chroma; float similarity; float smoothness; @@ -97,6 +95,7 @@ static inline void chroma_settings_update( SETTING_KEY_COLOR); const char *key_type = obs_data_get_string(settings, SETTING_COLOR_TYPE); + struct vec4 key_rgb; struct vec4 key_color_v4; struct matrix4 yuv_mat_m4; @@ -107,10 +106,10 @@ static inline void chroma_settings_update( else if (strcmp(key_type, "magenta") == 0) key_color = 0xFF00FF; - vec4_from_rgba(&filter->key_rgb, key_color | 0xFF000000); + vec4_from_rgba(&key_rgb, key_color | 0xFF000000); memcpy(&yuv_mat_m4, yuv_mat, sizeof(yuv_mat)); - vec4_transform(&key_color_v4, &filter->key_rgb, &yuv_mat_m4); + vec4_transform(&key_color_v4, &key_rgb, &yuv_mat_m4); vec2_set(&filter->chroma, key_color_v4.y, key_color_v4.z); filter->similarity = (float)similarity / 1000.0f; @@ -161,8 +160,6 @@ static void *chroma_key_create(obs_data_t *settings, obs_source_t *context) filter->effect, "gamma"); filter->chroma_param = gs_effect_get_param_by_name( filter->effect, "chroma_key"); - filter->key_rgb_param = gs_effect_get_param_by_name( - filter->effect, "key_rgb"); filter->pixel_size_param = gs_effect_get_param_by_name( filter->effect, "pixel_size"); filter->similarity_param = gs_effect_get_param_by_name( @@ -205,7 +202,6 @@ static void chroma_key_render(void *data, gs_effect_t *effect) gs_effect_set_float(filter->brightness_param, filter->brightness); gs_effect_set_float(filter->gamma_param, filter->gamma); gs_effect_set_vec2(filter->chroma_param, &filter->chroma); - gs_effect_set_vec4(filter->key_rgb_param, &filter->key_rgb); gs_effect_set_vec2(filter->pixel_size_param, &pixel_size); gs_effect_set_float(filter->similarity_param, filter->similarity); gs_effect_set_float(filter->smoothness_param, filter->smoothness); @@ -251,7 +247,8 @@ static obs_properties_t *chroma_key_properties(void *data) obs_properties_add_int_slider(props, SETTING_SPILL, TEXT_SPILL, 1, 1000, 1); - obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, + 0, 100, 1); obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, diff --git a/plugins/obs-filters/color-key-filter.c b/plugins/obs-filters/color-key-filter.c index 1b1c310..17a64f2 100644 --- a/plugins/obs-filters/color-key-filter.c +++ b/plugins/obs-filters/color-key-filter.c @@ -218,7 +218,8 @@ static obs_properties_t *color_key_properties(void *data) obs_properties_add_int_slider(props, SETTING_SMOOTHNESS, TEXT_SMOOTHNESS, 1, 1000, 1); - obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, + 0, 100, 1); obs_properties_add_float_slider(props, SETTING_CONTRAST, TEXT_CONTRAST, -1.0, 1.0, 0.01); obs_properties_add_float_slider(props, SETTING_BRIGHTNESS, diff --git a/plugins/obs-filters/data/chroma_key_filter.effect b/plugins/obs-filters/data/chroma_key_filter.effect index 8a75968..c7d41f3 100644 --- a/plugins/obs-filters/data/chroma_key_filter.effect +++ b/plugins/obs-filters/data/chroma_key_filter.effect @@ -12,7 +12,6 @@ uniform float brightness; uniform float gamma; uniform float2 chroma_key; -uniform float4 key_rgb; uniform float2 pixel_size; uniform float similarity; uniform float smoothness; @@ -55,17 +54,15 @@ float4 SampleTexture(float2 uv) float GetBoxFilteredChromaDist(float3 rgb, float2 texCoord) { - float distVal = GetChromaDist(rgb); - distVal += GetChromaDist(SampleTexture(texCoord-pixel_size).rgb); - distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, 0.0)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord-float2(pixel_size.x, -pixel_size.y)).rgb); - - distVal += GetChromaDist(SampleTexture(texCoord-float2(0.0, pixel_size.y)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+float2(0.0, pixel_size.y)).rgb); - - distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, -pixel_size.y)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+float2(pixel_size.x, 0.0)).rgb); - distVal += GetChromaDist(SampleTexture(texCoord+pixel_size).rgb); + float2 h_pixel_size = pixel_size / 2.0; + float2 point_0 = float2(pixel_size.x, h_pixel_size.y); + float2 point_1 = float2(h_pixel_size.x, -pixel_size.y); + float distVal = GetChromaDist(SampleTexture(texCoord-point_0).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+point_0).rgb); + distVal += GetChromaDist(SampleTexture(texCoord-point_1).rgb); + distVal += GetChromaDist(SampleTexture(texCoord+point_1).rgb); + distVal *= 2.0; + distVal += GetChromaDist(rgb); return distVal / 9.0; } @@ -76,6 +73,7 @@ float4 ProcessChromaKey(float4 rgba, VertData v_in) float fullMask = pow(saturate(baseMask / smoothness), 1.5); float spillVal = pow(saturate(baseMask / spill), 1.5); + rgba.rgba *= color; rgba.a *= fullMask; float desat = (rgba.r * 0.2126 + rgba.g * 0.7152 + rgba.b * 0.0722); @@ -86,7 +84,7 @@ float4 ProcessChromaKey(float4 rgba, VertData v_in) float4 PSChromaKeyRGBA(VertData v_in) : TARGET { - float4 rgba = image.Sample(textureSampler, v_in.uv) * color; + float4 rgba = image.Sample(textureSampler, v_in.uv); return ProcessChromaKey(rgba, v_in); } diff --git a/plugins/obs-filters/data/color_key_filter.effect b/plugins/obs-filters/data/color_key_filter.effect index 599d088..1af6b9d 100644 --- a/plugins/obs-filters/data/color_key_filter.effect +++ b/plugins/obs-filters/data/color_key_filter.effect @@ -39,17 +39,9 @@ float GetColorDist(float3 rgb) return distance(key_color.rgb, rgb); } -float4 SampleYUVToRGB(float2 uv) -{ - float4 yuv = image.Sample(textureSampler, uv); - yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max); - return saturate(mul(float4(yuv.xyz, 1.0), color_matrix)); -} - float4 ProcessColorKey(float4 rgba, VertData v_in) { float colorDist = GetColorDist(rgba.rgb); - float baseMask = colorDist - similarity; rgba.a *= saturate(max(colorDist - similarity, 0.0) / smoothness); return CalcColor(rgba); diff --git a/plugins/obs-filters/data/locale/bg-BG.ini b/plugins/obs-filters/data/locale/bg-BG.ini new file mode 100644 index 0000000..c65da8a --- /dev/null +++ b/plugins/obs-filters/data/locale/bg-BG.ini @@ -0,0 +1,4 @@ +Limiter="Ограничител" +Limiter.Threshold="Праг на отсичане (dB)" +Limiter.ReleaseTime="Време за отговор (мс)" + diff --git a/plugins/obs-filters/data/locale/ca-ES.ini b/plugins/obs-filters/data/locale/ca-ES.ini index 455357a..f3e0047 100644 --- a/plugins/obs-filters/data/locale/ca-ES.ini +++ b/plugins/obs-filters/data/locale/ca-ES.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Retard de processament" UndistortCenter="No distorsionis el centre de la imatge en escalar des d'una ultrapanoràmica" NoiseGate="Porta de soroll" NoiseSuppress="Supressió de soroll" +InvertPolarity="Inverteix la polaritat" Gain="Guany" DelayMs="Retard (en mil·lisegons)" Type="Tipus" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Temps d'alliberar (mil·lisegons)" Gain.GainDB="Guany (dB)" StretchImage="Expandir imatge (descarta la relació d'aspecte d'imatge)" Resolution="Resolució" +Base.Canvas="Resolució base (Llenç)" None="Cap" ScaleFiltering="Escala de filtratge" ScaleFiltering.Point="Punt" ScaleFiltering.Bilinear="Bilineal" ScaleFiltering.Bicubic="Bicúbic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Àrea" NoiseSuppress.SuppressLevel="Nivell de supressió (dB)" Saturation="Saturació" HueShift="Cavi de tonalitat" @@ -74,4 +77,25 @@ Compressor.AttackTime="Atac (ms)" Compressor.ReleaseTime="Llançament (ms)" Compressor.OutputGain="Guany de sortida (dB)" Compressor.SidechainSource="Font d'atenuació/reducció" +Limiter="Límit" +Limiter.Threshold="Llindar (dB)" +Limiter.ReleaseTime="Llançament (ms)" +Expander="Expansor" +Expander.Ratio="Ràtio (X:1)" +Expander.Threshold="Llindar (dB)" +Expander.AttackTime="Atac (ms)" +Expander.ReleaseTime="Llançament (ms)" +Expander.OutputGain="Guany de sortida (dB)" +Expander.Detector="Detecció" +Expander.RMS="RMS" +Expander.Peak="Límit" +Expander.None="Cap" +Expander.Presets="Predefinits" +Expander.Presets.Expander="Expansor" +Expander.Presets.Gate="Porta" +LumaKeyFilter="Clau Luma" +Luma.LumaMax="Màx. Luma" +Luma.LumaMin="Mín. Luma" +Luma.LumaMaxSmooth="Suavitzat màx. Luma" +Luma.LumaMinSmooth="Suavitzat mín. Luma" diff --git a/plugins/obs-filters/data/locale/cs-CZ.ini b/plugins/obs-filters/data/locale/cs-CZ.ini index abbcaeb..6af9711 100644 --- a/plugins/obs-filters/data/locale/cs-CZ.ini +++ b/plugins/obs-filters/data/locale/cs-CZ.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Zpoždění vykreslování" UndistortCenter="Zlepší střed obrázku při škálování z ultra-širokého obrazu" NoiseGate="Šumová brána" NoiseSuppress="Potlačení šumu" +InvertPolarity="Obrátit polaritu" Gain="Zisk" DelayMs="Zpoždění (ms)" Type="Typ" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Čas uvolnění (ms)" Gain.GainDB="Zisk (dB)" StretchImage="Roztáhnout obrázek (ignorovat poměr stran)" Resolution="Rozlišení" +Base.Canvas="Základní rozlišení" None="Žádné" ScaleFiltering="Filtrování rozsahu" ScaleFiltering.Point="Bod" ScaleFiltering.Bilinear="Bilineární" ScaleFiltering.Bicubic="Bikubický" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Oblast" NoiseSuppress.SuppressLevel="Úroveň potlačení (dB)" Saturation="Saturace" HueShift="Posun odstínu" @@ -74,4 +77,25 @@ Compressor.AttackTime="Stažení (v ms)" Compressor.ReleaseTime="Uvolnění (v ms)" Compressor.OutputGain="Síla výstupu (v dB)" Compressor.SidechainSource="Zdroj pro side-chain/ducking" +Limiter="Omezovač" +Limiter.Threshold="Práh (v dB)" +Limiter.ReleaseTime="Uvolnění (v ms)" +Expander="Expander" +Expander.Ratio="Poměr (X:1)" +Expander.Threshold="Práh (v dB)" +Expander.AttackTime="Stažení (v ms)" +Expander.ReleaseTime="Uvolnění (v ms)" +Expander.OutputGain="Síla výstupu (v dB)" +Expander.Detector="Detekce" +Expander.RMS="RMS" +Expander.Peak="Špičky" +Expander.None="Žádná" +Expander.Presets="Předvolby" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Brána" +LumaKeyFilter="Luma klíč" +Luma.LumaMax="Luma maximum" +Luma.LumaMin="Luma minimum" +Luma.LumaMaxSmooth="Luma maximální vyhlazení" +Luma.LumaMinSmooth="Luma minimální vyhlazení" diff --git a/plugins/obs-filters/data/locale/da-DK.ini b/plugins/obs-filters/data/locale/da-DK.ini index e9a125b..ab73964 100644 --- a/plugins/obs-filters/data/locale/da-DK.ini +++ b/plugins/obs-filters/data/locale/da-DK.ini @@ -1,10 +1,10 @@ ColorFilter="Farvekorrektion" ColorGradeFilter="Anvend LUT" -MaskFilter="Billede maske/blanding" -AsyncDelayFilter="Video forsinkelse (asynkron)" +MaskFilter="Billedmaskering/-blanding" +AsyncDelayFilter="Videoforsinkelse (asynkron)" CropFilter="Beskæring/Polstring" ScrollFilter="Rul" -ChromaKeyFilter="Chroma nøgle" +ChromaKeyFilter="Chroma-nøgle" ColorKeyFilter="Farvenøgle" SharpnessFilter="Skarphed" ScaleFilter="Skalering/Formatforhold" @@ -12,14 +12,15 @@ GPUDelayFilter="Renderingsforsinkelse" UndistortCenter="Fjern forvrængning af billedets midte ved skalering fra ultrabred" NoiseGate="Noise Gate" NoiseSuppress="Støjundertrykkelse" +InvertPolarity="Invertér polaritet" Gain="Forstærkning" DelayMs="Forsinkelse (millisekunder)" Type="Type" -MaskBlendType.MaskColor="Alpha maske (farvekanal)" -MaskBlendType.MaskAlpha="Alpha maske (Alpha kanal)" -MaskBlendType.BlendMultiply="Blend (formere)" -MaskBlendType.BlendAddition="Blanding (tilføjelse)" -MaskBlendType.BlendSubtraction="Blanding (subtraktion)" +MaskBlendType.MaskColor="Alpha-maske (farvekanal)" +MaskBlendType.MaskAlpha="Alpha-maske (Alpha-kanal)" +MaskBlendType.BlendMultiply="Bland (formere)" +MaskBlendType.BlendAddition="Bland (tilføjelse)" +MaskBlendType.BlendSubtraction="Bland (subtraktion)" Path="Sti" Color="Farve" Opacity="Gennemsigtighed" @@ -28,11 +29,11 @@ Brightness="Lysstyrke" Gamma="Gamma" BrowsePath.Images="Alle billedfiler" BrowsePath.AllFiles="Alle filer" -KeyColorType="Nøglefarve type" -KeyColor="Nøglefarven" -Similarity="Lighed (1-1000)" -Smoothness="Glathed (1-1000)" -ColorSpillReduction="Nøglefarve udslipsreduktion (1-1000)" +KeyColorType="Nøglefarvetype" +KeyColor="Nøglefarve" +Similarity="Lighed (1-1.000)" +Smoothness="Glathed (1-1.000)" +ColorSpillReduction="Nøglefarve udslipsreduktion (1-1.000)" Crop.Left="Venstre" Crop.Right="Højre" Crop.Top="Top" @@ -44,25 +45,27 @@ ScrollFilter.SpeedX="Horisontal hastighed" ScrollFilter.SpeedY="Vertikal hastighed" ScrollFilter.LimitWidth="Begræns bredde" ScrollFilter.LimitHeight="Begræns højde" -CustomColor="Brugerdefineret farve" +CustomColor="Tilpasset farve" Red="Rød" Green="Grøn" Blue="Blå" Magenta="Magenta" -NoiseGate.OpenThreshold="Åbne-tærskel (dB)" -NoiseGate.CloseThreshold="Lukke-tærskel (dB)" -NoiseGate.AttackTime="Effektueringstid (millisek.)" +NoiseGate.OpenThreshold="Åbningstærskel (dB)" +NoiseGate.CloseThreshold="Lukningstærskel (dB)" +NoiseGate.AttackTime="Responstid (millisek.)" NoiseGate.HoldTime="Holdetid (millisek.)" NoiseGate.ReleaseTime="Frigivelsestid (millisek.)" Gain.GainDB="Forstærkning (dB)" -StretchImage="Stræk billedet (ignorer størrelsesforhold)" +StretchImage="Stræk billede (ignorér størrelsesforhold)" Resolution="Opløsning" +Base.Canvas="Grundopløsning (lærred)" None="Ingen" ScaleFiltering="Skaleringsfilter" ScaleFiltering.Point="Punkt" ScaleFiltering.Bilinear="Bilineær" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" NoiseSuppress.SuppressLevel="Undertrykkelsesniveau (dB)" Saturation="Mætning" HueShift="Nuanceskift" @@ -70,8 +73,29 @@ Amount="Værdi" Compressor="Kompressor" Compressor.Ratio="Forhold (X:1)" Compressor.Threshold="Grænse (dB)" -Compressor.AttackTime="Attack (ms)" -Compressor.ReleaseTime="Release (ms)" -Compressor.OutputGain="Output øgning (dB)" -Compressor.SidechainSource="Sidechain/Ducking-kilde" +Compressor.AttackTime="Responstid (ms)" +Compressor.ReleaseTime="Frigivelse (ms)" +Compressor.OutputGain="Outputforstærkning (dB)" +Compressor.SidechainSource="Sidechain-/Ducking-kilde" +Limiter="Begrænser" +Limiter.Threshold="Grænse (dB)" +Limiter.ReleaseTime="Frigivelse (ms)" +Expander="Expander" +Expander.Ratio="Forhold (X:1)" +Expander.Threshold="Grænse (dB)" +Expander.AttackTime="Responstid (ms)" +Expander.ReleaseTime="Frigivelse (ms)" +Expander.OutputGain="Outputforstærkning (dB)" +Expander.Detector="Detektering" +Expander.RMS="RMS" +Expander.Peak="Spids" +Expander.None="Ingen" +Expander.Presets="Forvalg" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Gate" +LumaKeyFilter="Luma Key" +Luma.LumaMax="Luma maks." +Luma.LumaMin="Luma min." +Luma.LumaMaxSmooth="Luma maks. glidende" +Luma.LumaMinSmooth="Luma min. glidende" diff --git a/plugins/obs-filters/data/locale/de-DE.ini b/plugins/obs-filters/data/locale/de-DE.ini index d1ae53b..449e752 100644 --- a/plugins/obs-filters/data/locale/de-DE.ini +++ b/plugins/obs-filters/data/locale/de-DE.ini @@ -1,25 +1,26 @@ ColorFilter="Farbkorrektur" ColorGradeFilter="LUT anwenden" -MaskFilter="Bild Maske/Blend" +MaskFilter="Bildmaske/-Vermischung" AsyncDelayFilter="Videoverzögerung (Asynchron)" CropFilter="Zuschneiden/Pad" ScrollFilter="Bewegung" ChromaKeyFilter="Chroma Key" ColorKeyFilter="Color Key" -SharpnessFilter="Schärfen" +SharpnessFilter="Schärfung" ScaleFilter="Skalierung/Seitenverhältnis" GPUDelayFilter="Renderverzögerung" -UndistortCenter="Entzerre Mitte des Bildes bei der Skalierung von Ultraweitwinkel" +UndistortCenter="Mitte des Bildes bei der Skalierung von Ultraweitwinkel entzerren" NoiseGate="Noise Gate" NoiseSuppress="Rauschunterdrückung" +InvertPolarity="Audiopolarität umkehren" Gain="Gain" DelayMs="Verzögerung (Millisekunden)" Type="Art" MaskBlendType.MaskColor="Alphamaske (Farbkanal)" MaskBlendType.MaskAlpha="Alphamaske (Alphakanal)" MaskBlendType.BlendMultiply="Blend (Multiplizieren)" -MaskBlendType.BlendAddition="Blend (Addition)" -MaskBlendType.BlendSubtraction="Blend (Subtraktion)" +MaskBlendType.BlendAddition="Blend (Addieren)" +MaskBlendType.BlendSubtraction="Blend (Subtrahieren)" Path="Pfad" Color="Farbe" Opacity="Deckkraft" @@ -28,11 +29,11 @@ Brightness="Helligkeit" Gamma="Gamma" BrowsePath.Images="Alle Bilddateien" BrowsePath.AllFiles="Alle Dateien" -KeyColorType="Key-Farbe-Typ" +KeyColorType="Key-Farbtyp" KeyColor="Key-Farbe" -Similarity="Ähnlichkeit (1-1000)" -Smoothness="Glätte (1-1000)" -ColorSpillReduction="Key-Farbe Spill Reduktion (1-1000)" +Similarity="Ähnlichkeit (1 — 1000)" +Smoothness="Glätte (1 — 1000)" +ColorSpillReduction="Key-Farbe-Spill-Reduzierung (1 — 1000)" Crop.Left="Links" Crop.Right="Rechts" Crop.Top="Oben" @@ -57,21 +58,44 @@ NoiseGate.ReleaseTime="Release-Zeit (Millisekunden)" Gain.GainDB="Gain (dB)" StretchImage="Bild strecken (Bildseitenverhältnis verwerfen)" Resolution="Auflösung" +Base.Canvas="Basis-(Leinwand-)Auflösung" None="Keine" ScaleFiltering="Skalierungsfilterung" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Bereich" NoiseSuppress.SuppressLevel="Unterdrückungspegel (dB)" Saturation="Sättigung" HueShift="Farbtonverschiebung" Amount="Betrag" Compressor="Kompressor" Compressor.Ratio="Verhältnis (X:1)" -Compressor.Threshold="Schwelle (dB)" +Compressor.Threshold="Schwellenwert (dB)" Compressor.AttackTime="Angriff (ms)" -Compressor.ReleaseTime="Freigabe (ms)" +Compressor.ReleaseTime="Abfallzeit (ms)" Compressor.OutputGain="Ausgangspegel (dB)" -Compressor.SidechainSource="Sidechain/Ducking Quelle" +Compressor.SidechainSource="Sidechain-/Ducking-Quelle" +Limiter="Begrenzer" +Limiter.Threshold="Schwellenwert (dB)" +Limiter.ReleaseTime="Abfallzeit (ms)" +Expander="Expander" +Expander.Ratio="Verhältnis (X:1)" +Expander.Threshold="Schwellenwert (dB)" +Expander.AttackTime="Angriff (ms)" +Expander.ReleaseTime="Abfallzeit (ms)" +Expander.OutputGain="Ausgangspegel (dB)" +Expander.Detector="Erkennung" +Expander.RMS="RMS" +Expander.Peak="Spitze" +Expander.None="Keine" +Expander.Presets="Voreinstellungen" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Gate" +LumaKeyFilter="Luma-Key" +Luma.LumaMax="Max. Luma" +Luma.LumaMin="Min. Luma" +Luma.LumaMaxSmooth="Max. Luma-Glätte" +Luma.LumaMinSmooth="Min. Luma-Glätte" diff --git a/plugins/obs-filters/data/locale/en-US.ini b/plugins/obs-filters/data/locale/en-US.ini index 241cbee..cf49d70 100644 --- a/plugins/obs-filters/data/locale/en-US.ini +++ b/plugins/obs-filters/data/locale/en-US.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Render Delay" UndistortCenter="Undistort center of image when scaling from ultrawide" NoiseGate="Noise Gate" NoiseSuppress="Noise Suppression" +InvertPolarity="Invert Polarity" Gain="Gain" DelayMs="Delay (milliseconds)" Type="Type" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Release Time (milliseconds)" Gain.GainDB="Gain (dB)" StretchImage="Stretch Image (discard image aspect ratio)" Resolution="Resolution" +Base.Canvas="Base (Canvas) Resolution" None="None" ScaleFiltering="Scale Filtering" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Area" NoiseSuppress.SuppressLevel="Suppression Level (dB)" Saturation="Saturation" HueShift="Hue Shift" @@ -74,3 +77,24 @@ Compressor.AttackTime="Attack (ms)" Compressor.ReleaseTime="Release (ms)" Compressor.OutputGain="Output Gain (dB)" Compressor.SidechainSource="Sidechain/Ducking Source" +Limiter="Limiter" +Limiter.Threshold="Threshold (dB)" +Limiter.ReleaseTime="Release (ms)" +Expander="Expander" +Expander.Ratio="Ratio (X:1)" +Expander.Threshold="Threshold (dB)" +Expander.AttackTime="Attack (ms)" +Expander.ReleaseTime="Release (ms)" +Expander.OutputGain="Output Gain (dB)" +Expander.Detector="Detection" +Expander.RMS="RMS" +Expander.Peak="Peak" +Expander.None="None" +Expander.Presets="Presets" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Gate" +LumaKeyFilter="Luma Key" +Luma.LumaMax="Luma Max" +Luma.LumaMin="Luma Min" +Luma.LumaMaxSmooth="Luma Max Smooth" +Luma.LumaMinSmooth="Luma Min Smooth" diff --git a/plugins/obs-filters/data/locale/es-ES.ini b/plugins/obs-filters/data/locale/es-ES.ini index 25a6492..5e1336b 100644 --- a/plugins/obs-filters/data/locale/es-ES.ini +++ b/plugins/obs-filters/data/locale/es-ES.ini @@ -1,17 +1,18 @@ ColorFilter="Corrección de color" ColorGradeFilter="Aplicar LUT" MaskFilter="Imagen máscara/mezcla" -AsyncDelayFilter="Retardo de Video (asincróno)" +AsyncDelayFilter="Retardo de Vídeo (asíncrono)" CropFilter="Recortar/Acolchar" -ScrollFilter="desplazamiento" +ScrollFilter="Desplazamiento" ChromaKeyFilter="Fondro croma" ColorKeyFilter="Filtro de color" SharpnessFilter="Filtro de enfoque" ScaleFilter="Escala/Relación de Aspecto" GPUDelayFilter="Retardo de procesamiento" -UndistortCenter="No distorsionar el centro de la imagen en escalar des de una ultrapanorámica" +UndistortCenter="No distorsionar el centro de la imagen al escalar desde una ultrapanorámica" NoiseGate="Puerta anti-ruidos" NoiseSuppress="Eliminación de ruido" +InvertPolarity="Invertir polaridad" Gain="Ganancia" DelayMs="Retardo (milisegundos)" Type="Tipo" @@ -41,7 +42,7 @@ Crop.Width="Ancho" Crop.Height="Alto" Crop.Relative="Relativo" ScrollFilter.SpeedX="Velocidad Horizontal" -ScrollFilter.SpeedY="VElocidad Vertical" +ScrollFilter.SpeedY="Velocidad Vertical" ScrollFilter.LimitWidth="Limitar el ancho" ScrollFilter.LimitHeight="Limitar la altura" CustomColor="Color Personalizado" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Tiempo (en milisegundos) de liberacion" Gain.GainDB="Ganancia (dB)" StretchImage="Expandir imagen (descartar relación de aspecto de imagen)" Resolution="Resolución" +Base.Canvas="Resolución base (Lienzo)" None="Ninguno" ScaleFiltering="Escala de filtrado" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilineal" ScaleFiltering.Bicubic="Bicúbico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" NoiseSuppress.SuppressLevel="Nivel de eliminación de ruido (dB)" Saturation="Saturación" HueShift="Cambio de tonalidad" @@ -74,4 +77,25 @@ Compressor.AttackTime="Ataque (ms)" Compressor.ReleaseTime="Liberación (ms)" Compressor.OutputGain="Ganancia de salida (dB)" Compressor.SidechainSource="Fuente de atenuación/reducción" +Limiter="Limitador" +Limiter.Threshold="Umbral (dB)" +Limiter.ReleaseTime="Soltar (ms)" +Expander="Expansor" +Expander.Ratio="Relación (X:1)" +Expander.Threshold="Umbral (dB)" +Expander.AttackTime="Atacar (ms)" +Expander.ReleaseTime="Soltar (ms)" +Expander.OutputGain="Ganancia de salida (dB)" +Expander.Detector="Detección" +Expander.RMS="RMS" +Expander.Peak="Pico" +Expander.None="Ninguna" +Expander.Presets="Pre-ajustes" +Expander.Presets.Expander="Expansor" +Expander.Presets.Gate="Puerta" +LumaKeyFilter="Clave Luma" +Luma.LumaMax="Máx. Luma" +Luma.LumaMin="Min. Luma" +Luma.LumaMaxSmooth="Suavizado Máximo Luma" +Luma.LumaMinSmooth="Suavizado Mínimo Luma" diff --git a/plugins/obs-filters/data/locale/eu-ES.ini b/plugins/obs-filters/data/locale/eu-ES.ini index d9e7d5c..851669e 100644 --- a/plugins/obs-filters/data/locale/eu-ES.ini +++ b/plugins/obs-filters/data/locale/eu-ES.ini @@ -6,12 +6,13 @@ CropFilter="Moztu/Bete" ScrollFilter="Korritu" ChromaKeyFilter="Kroma" ColorKeyFilter="Kolore gakoa" -SharpnessFilter="Enfokea" +SharpnessFilter="Fokatzea" ScaleFilter="Eskala/Aspektu-erlazioa" GPUDelayFilter="Errendatzearen atzerapena" UndistortCenter="Ez distortsionatu irudiaren erdigunea ultra zabala eskalatzean" NoiseGate="Zarata atalasea" NoiseSuppress="Zarata kendu" +InvertPolarity="Polaritatea alderantzikatu" Gain="Irabazia" DelayMs="Atzerapena (milisegundo)" Type="Mota" @@ -49,20 +50,22 @@ Red="Gorria" Green="Berdea" Blue="Urdina" Magenta="Magenta" -NoiseGate.OpenThreshold="Irekiera muga (dB)" -NoiseGate.CloseThreshold="Itxiera muga (dB)" +NoiseGate.OpenThreshold="Irekiera atalasea (dB)" +NoiseGate.CloseThreshold="Itxiera atalasea (dB)" NoiseGate.AttackTime="Eraso denbora (milisegundo)" NoiseGate.HoldTime="Euste denbora (milisegundo)" NoiseGate.ReleaseTime="Askatze denbora (milisegundo)" Gain.GainDB="Irabazia (dB)" StretchImage="Luzatu irudia (baztertu irudiaren aspektu-erlazioa)" Resolution="Bereizmena" +Base.Canvas="Oinarriaren (oihalaren) bereizmena" None="Ezer ez" ScaleFiltering="Iragazketa-eskala" ScaleFiltering.Point="Puntua" ScaleFiltering.Bilinear="Bilineala" ScaleFiltering.Bicubic="Bikubikoa" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Area" NoiseSuppress.SuppressLevel="Kenketaren maila (dB)" Saturation="Margoasetasuna" HueShift="Nabardura Aldaketa" @@ -74,4 +77,25 @@ Compressor.AttackTime="Erasoa (ms)" Compressor.ReleaseTime="Askapena (ms)" Compressor.OutputGain="Irteerako irabazia (dB)" Compressor.SidechainSource="Sidechain/Ducking iturburua" +Limiter="Mugatzailea" +Limiter.Threshold="Atalasea (dB)" +Limiter.ReleaseTime="Askatze denbora (ms)" +Expander="Deskonprimagailua" +Expander.Ratio="Erlazioa (X:1)" +Expander.Threshold="Atalasea (dB)" +Expander.AttackTime="Erasoa (ms)" +Expander.ReleaseTime="Askapena (ms)" +Expander.OutputGain="Irteerako irabazia (dB)" +Expander.Detector="Detekzioa" +Expander.RMS="RMS" +Expander.Peak="Gailurra" +Expander.None="Bat ere ez" +Expander.Presets="Aurrez ezarritakoak" +Expander.Presets.Expander="Deskonprimagailua" +Expander.Presets.Gate="Atea" +LumaKeyFilter="Luma gakoa" +Luma.LumaMax="Luma max" +Luma.LumaMin="Luma min" +Luma.LumaMaxSmooth="Luma leuntasun max" +Luma.LumaMinSmooth="Luma leuntasun min" diff --git a/plugins/obs-filters/data/locale/fa-IR.ini b/plugins/obs-filters/data/locale/fa-IR.ini new file mode 100644 index 0000000..9453392 --- /dev/null +++ b/plugins/obs-filters/data/locale/fa-IR.ini @@ -0,0 +1,18 @@ +ColorFilter="اصلاح رنگ" +ColorGradeFilter="درخواست LUT" +MaskFilter="تصویر ماسک/مخلوط" +ChromaKeyFilter="صحنه کلیدی(کروماکی)" +ColorKeyFilter="رنگ کلیدی" +SharpnessFilter="تیزکردن" +BrowsePath.AllFiles="همه‌ی فایل ها" +KeyColorType="نوع رنگ کلیدی" +Crop.Left="چپ" +Crop.Right="راست" +Crop.Top="بالا" +Crop.Bottom="پایین" +Crop.Width="عرض" +Crop.Height="ارتفاع" +Red="قرمز" +Green="سبز" +ScaleFiltering.Area="ناحیه" + diff --git a/plugins/obs-filters/data/locale/fi-FI.ini b/plugins/obs-filters/data/locale/fi-FI.ini index e456d6d..7ebad95 100644 --- a/plugins/obs-filters/data/locale/fi-FI.ini +++ b/plugins/obs-filters/data/locale/fi-FI.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Renderoinnin viive" UndistortCenter="Poista vääristymä keskeltä kuvaa skaalattaessa ultra-leveästä" NoiseGate="Noise Gate" NoiseSuppress="Melunvaimennus" +InvertPolarity="Käännä Audio-napaisuus" Gain="Vahvistus" DelayMs="Viive (millisekuntia)" Type="Tyyppi" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Vapautumisaika (millisekuntia)" Gain.GainDB="Vahvistus (dB)" StretchImage="Venytä kuvaa (Ohita kuvasuhde)" Resolution="Resoluutio" +Base.Canvas="Piirtoalueen (kanvaasin) resoluutio" None="Ei mitään" ScaleFiltering="Skaalauksen suodatus" ScaleFiltering.Point="Piste" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Alue" NoiseSuppress.SuppressLevel="Vaimennustaso (dB)" Saturation="Värikylläisyys" HueShift="Värisävy" @@ -74,4 +77,25 @@ Compressor.AttackTime="Attack-aika (ms)" Compressor.ReleaseTime="Vapautumisaika (ms)" Compressor.OutputGain="Signaalin vahvistus (dB)" Compressor.SidechainSource="Lähteen väistäminen" +Limiter="Rajoitin" +Limiter.Threshold="Kynnysarvo (dB)" +Limiter.ReleaseTime="Vapautumisaika (ms)" +Expander="Laajentaja" +Expander.Ratio="Suhde (X:1)" +Expander.Threshold="Kynnysarvo (dB)" +Expander.AttackTime="Attack-aika (ms)" +Expander.ReleaseTime="Vapautumisaika (ms)" +Expander.OutputGain="Signaalin vahvistus (dB)" +Expander.Detector="Havaitseminen" +Expander.RMS="RMS" +Expander.Peak="Huippu" +Expander.None="Ei mitään" +Expander.Presets="Esiasetukset" +Expander.Presets.Expander="Laajentaja" +Expander.Presets.Gate="Gate" +LumaKeyFilter="Luma-avain" +Luma.LumaMax="Luma-maksimi" +Luma.LumaMin="Luma-minimi" +Luma.LumaMaxSmooth="Luma-maksimin pehmennys" +Luma.LumaMinSmooth="Luma-minimin pehmennys" diff --git a/plugins/obs-filters/data/locale/fr-FR.ini b/plugins/obs-filters/data/locale/fr-FR.ini index 38855f7..608d8aa 100644 --- a/plugins/obs-filters/data/locale/fr-FR.ini +++ b/plugins/obs-filters/data/locale/fr-FR.ini @@ -1,17 +1,18 @@ ColorFilter="Corrections colorimétrique" -ColorGradeFilter="Appliquer LUT" +ColorGradeFilter="Appliquer un LUT" MaskFilter="Masque d'image/mélange" -AsyncDelayFilter="Retard vidéo (async.)" +AsyncDelayFilter="Retard vidéo (asynchrone)" CropFilter="Rogner / Encadrer" ScrollFilter="Défilement" -ChromaKeyFilter="Clé chromatique" -ColorKeyFilter="Couleur d'incrustation" +ChromaKeyFilter="Incrustation par chrominance (Chroma Key)" +ColorKeyFilter="Incrustation par couleur" SharpnessFilter="Accentuer" -ScaleFilter="Mise à l’échelle / Ratio d'affichage" +ScaleFilter="Mise à l’échelle / Rapport d'affichage" GPUDelayFilter="Délai de rendu" UndistortCenter="Ne pas déformer le centre de l'image lors d'une mise à l'échelle ultra large" NoiseGate="Noise Gate" NoiseSuppress="Suppression du bruit" +InvertPolarity="Inverser la polarité" Gain="Gain" DelayMs="Retard (en millisecondes)" Type="Type " @@ -26,7 +27,7 @@ Opacity="Opacité" Contrast="Contraste" Brightness="Luminosité" Gamma="Gamma" -BrowsePath.Images="Tous les fichiers images" +BrowsePath.Images="Tous les fichiers Image" BrowsePath.AllFiles="Tous les fichiers" KeyColorType="Type de couleur-clé" KeyColor="Couleur-clé" @@ -53,16 +54,18 @@ NoiseGate.OpenThreshold="Seuil d'ouverture (dB)" NoiseGate.CloseThreshold="Seuil de fermeture (dB)" NoiseGate.AttackTime="Temps d'attaque (millisecondes)" NoiseGate.HoldTime="Temps de maintien (millisecondes)" -NoiseGate.ReleaseTime="Temps d'arrêt (millisecondes)" +NoiseGate.ReleaseTime="Temps de relâche (ou \"release\" en millisecondes)" Gain.GainDB="Gain (dB)" StretchImage="Étirer l'Image (ignorer ses proportions)" Resolution="Résolution" +Base.Canvas="Résolution de base (canevas)" None="Aucune" ScaleFiltering="Échelle de filtrage" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinéaire" ScaleFiltering.Bicubic="Bicubique" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Zone" NoiseSuppress.SuppressLevel="Seuil de suppression (en dB)" Saturation="Saturation" HueShift="Décalage de teinte" @@ -71,7 +74,28 @@ Compressor="Compresseur" Compressor.Ratio="Ratio (X:1)" Compressor.Threshold="Seuil (dB)" Compressor.AttackTime="Attaque (ms)" -Compressor.ReleaseTime="Libération (ms)" -Compressor.OutputGain="Sortie Gain (dB)" -Compressor.SidechainSource="Source Sidechain/Ducking" +Compressor.ReleaseTime="Relâchement (ou \"release\" en ms)" +Compressor.OutputGain="Gain en Sortie (dB)" +Compressor.SidechainSource="Source pour la Sidechain/Ducking" +Limiter="Limiteur" +Limiter.Threshold="Seuil (dB)" +Limiter.ReleaseTime="Relâchement (\"release\" en ms)" +Expander="Expandeur" +Expander.Ratio="Ratio (X:1)" +Expander.Threshold="Seuil (dB)" +Expander.AttackTime="Attaque (ms)" +Expander.ReleaseTime="Relâchement (\"release\" en ms)" +Expander.OutputGain="Gain en sortie (dB)" +Expander.Detector="Détection" +Expander.RMS="RMS" +Expander.Peak="Crête" +Expander.None="Aucune" +Expander.Presets="Pré-réglages" +Expander.Presets.Expander="Expandeur" +Expander.Presets.Gate="Gate" +LumaKeyFilter="Incrustation par luminance (Luma Key)" +Luma.LumaMax="Luminance max." +Luma.LumaMin="Luminance min." +Luma.LumaMaxSmooth="Adoucissement luminance max." +Luma.LumaMinSmooth="Adoucissement luminance min." diff --git a/plugins/obs-filters/data/locale/hu-HU.ini b/plugins/obs-filters/data/locale/hu-HU.ini index 32e9b79..6b4478e 100644 --- a/plugins/obs-filters/data/locale/hu-HU.ini +++ b/plugins/obs-filters/data/locale/hu-HU.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Render késleltetés" UndistortCenter="Kép közepének zavarosságának a csökkentése ultraszélesről való skálázás esetén" NoiseGate="Zajgát" NoiseSuppress="Zajcsökkentés" +InvertPolarity="Polaritás megfordítása" Gain="Erősítés" DelayMs="Késleltetés (ezredmásodperc)" Type="Típus" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Felengedés ideje (ezredmásodperc)" Gain.GainDB="Erősítés (dB)" StretchImage="Kép nyújtása (képarány elvetésével)" Resolution="Felbontás" +Base.Canvas="Alap (Vászon) felbontás" None="Nincs" ScaleFiltering="Skála-szűrés" ScaleFiltering.Point="Pont" ScaleFiltering.Bilinear="Bilineáris" ScaleFiltering.Bicubic="Kettős köbös" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Terület" NoiseSuppress.SuppressLevel="Csökkentési szint (dB)" Saturation="Telítettség" HueShift="Színezet váltása" @@ -74,4 +77,25 @@ Compressor.AttackTime="Aktiválás (ms)" Compressor.ReleaseTime="Felengedés (ms)" Compressor.OutputGain="Kimeneti erősítés (dB)" Compressor.SidechainSource="Oldallánc/Buktatott forrás" +Limiter="Limiter" +Limiter.Threshold="Küszöb (dB)" +Limiter.ReleaseTime="Kiadás (ms)" +Expander="Expander" +Expander.Ratio="Arány (X:1)" +Expander.Threshold="Küszöb (dB)" +Expander.AttackTime="Aktiválás (ms)" +Expander.ReleaseTime="Felengedés (ms)" +Expander.OutputGain="Kimeneti erősítés (dB)" +Expander.Detector="Észlelés" +Expander.RMS="RMS" +Expander.Peak="Csúcs" +Expander.None="Nincs" +Expander.Presets="Készletek" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Kapu" +LumaKeyFilter="Luma kulcs" +Luma.LumaMax="Luma maximum" +Luma.LumaMin="Luma minimum" +Luma.LumaMaxSmooth="Luma maximum simított" +Luma.LumaMinSmooth="Luma minimum simított" diff --git a/plugins/obs-filters/data/locale/it-IT.ini b/plugins/obs-filters/data/locale/it-IT.ini index 1c83914..542a9c0 100644 --- a/plugins/obs-filters/data/locale/it-IT.ini +++ b/plugins/obs-filters/data/locale/it-IT.ini @@ -1,77 +1,101 @@ -ColorFilter="Correzione colore" +ColorFilter="Correzione del colore" ColorGradeFilter="Applica LUT" -MaskFilter="Immagine maschera/miscela" +MaskFilter="Maschera/miscela l'immagine" AsyncDelayFilter="Ritardo video (Asincrono)" -CropFilter="Crop/Pad" +CropFilter="Ritaglia/aggiungi una cornice" ScrollFilter="Scorrimento" -ChromaKeyFilter="Chroma Key" -ColorKeyFilter="Chiave Colore" +ChromaKeyFilter="Chiave chroma" +ColorKeyFilter="Chiave colore" SharpnessFilter="Nitidizza" -ScaleFilter="Ridimensionamento/Aspect Ratio" -GPUDelayFilter="Ritardo di rendering" -UndistortCenter="Rimuovi distorsione del centro immagine quando si scala da un rapporto molto alto" +ScaleFilter="Ridimensionamento/proporzioni" +GPUDelayFilter="Ritardo del rendering" +UndistortCenter="Rimuovi la distorsione del centro immagine quando si scala da un rapporto dello schermo ultrawide" NoiseGate="Sensibilità dell'ingresso" -NoiseSuppress="Soppressione rumore" -Gain="Incremento" -DelayMs="Ritardo (millisecondi)" +NoiseSuppress="Riduzione del rumore" +InvertPolarity="Inverti la polarità" +Gain="Guadagno" +DelayMs="Ritardo (in millisecondi)" Type="Tipo" MaskBlendType.MaskColor="Maschera alfa (canale di colore)" -MaskBlendType.MaskAlpha="Maschera alfa (Canale alpha)" +MaskBlendType.MaskAlpha="Maschera alfa (canale alfa)" MaskBlendType.BlendMultiply="Miscela (moltiplica)" -MaskBlendType.BlendAddition="Miscela (aggiunta)" -MaskBlendType.BlendSubtraction="Miscela (sottrazione)" +MaskBlendType.BlendAddition="Miscela (additiva)" +MaskBlendType.BlendSubtraction="Miscela (sottrattiva)" Path="Percorso" Color="Colore" Opacity="Opacità" Contrast="Contrasto" Brightness="Luminosità" Gamma="Gamma" -BrowsePath.Images="Tutti i file di immagine" +BrowsePath.Images="Tutti i file immagine" BrowsePath.AllFiles="Tutti i file" -KeyColorType="Tipo di Color Key" -KeyColor="Key Color" +KeyColorType="Tipo di chiave colore" +KeyColor="Chiave colore" Similarity="Somiglianza (1-1000)" -Smoothness="Scorrevolezza (1-1000)" -ColorSpillReduction="Key Color Spill Reduction (1-1000)" +Smoothness="Finezza (1-1000)" +ColorSpillReduction="Riduzione della sbavatura della chiave colore (1-1000)" Crop.Left="A sinistra" Crop.Right="A destra" Crop.Top="In alto" -Crop.Bottom="In Basso" +Crop.Bottom="In basso" Crop.Width="Larghezza" Crop.Height="Altezza" Crop.Relative="Relativo" ScrollFilter.SpeedX="Velocità orizzontale" ScrollFilter.SpeedY="Velocità verticale" -ScrollFilter.LimitWidth="Limite larghezza" -ScrollFilter.LimitHeight="Limite altezza" -CustomColor="Personalizza colore" +ScrollFilter.LimitWidth="Limite della larghezza" +ScrollFilter.LimitHeight="Limite dell'altezza" +CustomColor="Colore personalizzato" Red="Rosso" Green="Verde" Blue="Blu" Magenta="Magenta" -NoiseGate.OpenThreshold="Apri soglia (dB)" -NoiseGate.CloseThreshold="Chiudo soglia (dB)" -NoiseGate.AttackTime="Tempo d'inizio (millisecondi)" -NoiseGate.HoldTime="Tempo d'attesa (millisecondi)" -NoiseGate.ReleaseTime="Tempo di rilascio (millisecondi)" -Gain.GainDB="Incremento (dB)" -StretchImage="Stendi immagine (scarta proporzioni immagine)" +NoiseGate.OpenThreshold="Soglia di apertura (in dB)" +NoiseGate.CloseThreshold="Soglia di chiusura (in dB)" +NoiseGate.AttackTime="Tempo di attivazione (in millisecondi)" +NoiseGate.HoldTime="Tempo di attesa (in millisecondi)" +NoiseGate.ReleaseTime="Tempo di rilascio (in millisecondi)" +Gain.GainDB="Guadagno (in dB)" +StretchImage="Adatta l'immagine allo schermo (ignorando le proporzioni)" Resolution="Risoluzione" -None="Nessuno" +Base.Canvas="Risoluzione di base (inquadratura)" +None="Nessuna" ScaleFiltering="Scala di filtraggio" ScaleFiltering.Point="Punto" ScaleFiltering.Bilinear="Bilineare" ScaleFiltering.Bicubic="Bicubico" ScaleFiltering.Lanczos="Lanczos" -NoiseSuppress.SuppressLevel="Livello di soppressione (dB)" +ScaleFiltering.Area="Zona" +NoiseSuppress.SuppressLevel="Livello di riduzione (in dB)" Saturation="Saturazione" HueShift="Cambio di tonalità" Amount="Quantità" Compressor="Compressore" -Compressor.Ratio="Rapporto (X:1)" -Compressor.Threshold="Soglia (dB)" -Compressor.AttackTime="Attacco (ms)" -Compressor.ReleaseTime="Rilascio (ms)" -Compressor.OutputGain="Guadagno di uscita (dB)" -Compressor.SidechainSource="Sidechain/Ducking Sorgente" +Compressor.Ratio="Rapporto/proporzioni (X:1)" +Compressor.Threshold="Soglia (in dB)" +Compressor.AttackTime="Attivazione (in ms)" +Compressor.ReleaseTime="Rilascio (in ms)" +Compressor.OutputGain="Guadagno in uscita (in dB)" +Compressor.SidechainSource="Fonte per sidechain/ducking" +Limiter="Limitatore" +Limiter.Threshold="Soglia (in dB)" +Limiter.ReleaseTime="Rilascio (in ms)" +Expander="Espansore" +Expander.Ratio="Rapporto/proporzioni (X:1)" +Expander.Threshold="Soglia (in dB)" +Expander.AttackTime="Attivazione (in ms)" +Expander.ReleaseTime="Rilascio (in ms)" +Expander.OutputGain="Guadagno in uscita (in dB)" +Expander.Detector="Tipo di rilevamento" +Expander.RMS="RMS" +Expander.Peak="Picco" +Expander.None="Nessuno" +Expander.Presets="Preset" +Expander.Presets.Expander="Espansore" +Expander.Presets.Gate="Sensibilità" +LumaKeyFilter="Chiave Luma" +Luma.LumaMax="Luma massima" +Luma.LumaMin="Luma minima" +Luma.LumaMaxSmooth="Sfumatura massima di Luma" +Luma.LumaMinSmooth="Sfumatura minima di Luma" diff --git a/plugins/obs-filters/data/locale/ja-JP.ini b/plugins/obs-filters/data/locale/ja-JP.ini index 1dd1194..ae19476 100644 --- a/plugins/obs-filters/data/locale/ja-JP.ini +++ b/plugins/obs-filters/data/locale/ja-JP.ini @@ -12,6 +12,7 @@ GPUDelayFilter="レンダリング遅延" UndistortCenter="超広角からスケーリングするときに画像の中心を歪めない" NoiseGate="ノイズゲート" NoiseSuppress="ノイズ抑制" +InvertPolarity="極性を反転する" Gain="ゲイン" DelayMs="遅延時間 (ミリ秒)" Type="種別" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="解除時間 (ミリ秒)" Gain.GainDB="ゲイン (dB)" StretchImage="画像を拡大 (アスペクト比を破棄)" Resolution="解像度" +Base.Canvas="基本 (キャンバス) 解像度" None="なし" ScaleFiltering="スケールフィルタ" ScaleFiltering.Point="ポイント" ScaleFiltering.Bilinear="バイリニア" ScaleFiltering.Bicubic="バイキュービック" ScaleFiltering.Lanczos="ランチョス" +ScaleFiltering.Area="エリア" NoiseSuppress.SuppressLevel="抑制レベル (dB)" Saturation="彩度" HueShift="色相シフト" @@ -74,4 +77,25 @@ Compressor.AttackTime="アタックタイム (ms)" Compressor.ReleaseTime="リリースタイム (ms)" Compressor.OutputGain="出力ゲイン (dB)" Compressor.SidechainSource="サイドチェーン/ダッキングソース" +Limiter="リミッター" +Limiter.Threshold="閾値 (dB)" +Limiter.ReleaseTime="リリースタイム (ms)" +Expander="エキスパンダー" +Expander.Ratio="比率 (X:1)" +Expander.Threshold="閾値 (dB)" +Expander.AttackTime="アタックタイム (ms)" +Expander.ReleaseTime="リリースタイム (ms)" +Expander.OutputGain="出力ゲイン (dB)" +Expander.Detector="検出" +Expander.RMS="RMS" +Expander.Peak="ピーク" +Expander.None="未設定" +Expander.Presets="プリセット" +Expander.Presets.Expander="エキスパンダー" +Expander.Presets.Gate="ゲート" +LumaKeyFilter="ルマキー" +Luma.LumaMax="最大輝度" +Luma.LumaMin="最小輝度" +Luma.LumaMaxSmooth="ルマ最大スムーズ" +Luma.LumaMinSmooth="ルマ最小スムーズ" diff --git a/plugins/obs-filters/data/locale/ka-GE.ini b/plugins/obs-filters/data/locale/ka-GE.ini index 7547556..b8a465c 100644 --- a/plugins/obs-filters/data/locale/ka-GE.ini +++ b/plugins/obs-filters/data/locale/ka-GE.ini @@ -12,6 +12,7 @@ GPUDelayFilter="დაყოვნება დამუშავებისა UndistortCenter="ზეფართო სურათის შუაგულის გამრუდების არიდება, ზომების შეცვლისას" NoiseGate="ხმაურის შეზღუდვა" NoiseSuppress="ხმაურის დახშობა" +InvertPolarity="შებრუნებული პოლარობა" Gain="სიგნალის გაძლიერება" DelayMs="დაყოვნება (მილიწამი)" Type="სახეობა" @@ -32,7 +33,7 @@ KeyColorType="საკვანძო ფერის სახე" KeyColor="საკვანძო ფერი" Similarity="მსგავსება (1-1000)" Smoothness="სიგლუვე (1-1000)" -ColorSpillReduction="საკვანძო ფერთა გაბნევის შემცირება (1-1000)" +ColorSpillReduction="საკვანძო ფერის გაბნევის შემცირება (1-1000)" Crop.Left="მარცხენა" Crop.Right="მარჯვენა" Crop.Top="ზედა" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="შემცირების (Release) ხანგრ Gain.GainDB="გაძლიერება (dB)" StretchImage="სურათის გაწელვა (გვერდების თანაფარდობის უგულებელყოფა)" Resolution="გაფართოება" +Base.Canvas="ძირითადი (ფონის) გაფართოება" None="არცერთი" ScaleFiltering="მასშტაბირების ფილტრი" ScaleFiltering.Point="წერტილოვანი" ScaleFiltering.Bilinear="ორხაზოვანი" ScaleFiltering.Bicubic="ბიკუბური" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="სივრცე" NoiseSuppress.SuppressLevel="დახშობის ხარისხი (dB)" Saturation="გაჯერებულობა" HueShift="შეფერილობის შეცვლა" @@ -74,4 +77,25 @@ Compressor.AttackTime="მომატება (მწ)" Compressor.ReleaseTime="შემცირება (მწ)" Compressor.OutputGain="გამომავალი სიგნალის გაძლიერება (dB)" Compressor.SidechainSource="Sidechain/ხმის დონის დადაბლების წყარო" +Limiter="შემზღუდველი" +Limiter.Threshold="ზღურბლი (dB)" +Limiter.ReleaseTime="შემცირება (მწ)" +Expander="გამშლელი" +Expander.Ratio="ფარდობა (X:1)" +Expander.Threshold="ზღურბლი (dB)" +Expander.AttackTime="მომატება (მწ)" +Expander.ReleaseTime="შემცირება (მწ)" +Expander.OutputGain="გამომავალი სიგნალის გაძლიერება (dB)" +Expander.Detector="დადგენა" +Expander.RMS="საშ. კვადრატული (RMS)" +Expander.Peak="ხანმოკლე" +Expander.None="არცერთი" +Expander.Presets="მზა პარამეტრები" +Expander.Presets.Expander="გამშლელი" +Expander.Presets.Gate="ჩამკეტი" +LumaKeyFilter="კაშკაშა არეების ჩანაცვლება (Luma Key)" +Luma.LumaMax="სიკაშკაშის ზედა ზღვარი" +Luma.LumaMin="სიკაშკაშის ქვედა ზღვარი" +Luma.LumaMaxSmooth="სიკაშკაშის ზედა ზღვრის სიგლუვე" +Luma.LumaMinSmooth="სიკაშკაშის ქვედა ზღვრის სიგლუვე" diff --git a/plugins/obs-filters/data/locale/ko-KR.ini b/plugins/obs-filters/data/locale/ko-KR.ini index e03702b..0241c1c 100644 --- a/plugins/obs-filters/data/locale/ko-KR.ini +++ b/plugins/obs-filters/data/locale/ko-KR.ini @@ -12,6 +12,7 @@ GPUDelayFilter="렌더링 지연" UndistortCenter="울트라와이드에서 크기조정 시 이미지 중앙의 왜곡을 수정" NoiseGate="노이즈 게이트" NoiseSuppress="소음 억제" +InvertPolarity="극성 반전" Gain="증폭" DelayMs="지연 (밀리초)" Type="형식" @@ -53,16 +54,18 @@ NoiseGate.OpenThreshold="개방 역치값 (dB)" NoiseGate.CloseThreshold="폐쇄 역치값 (dB)" NoiseGate.AttackTime="개방 준비 시간 (밀리세컨드)" NoiseGate.HoldTime="개방 유지 시간 (밀리세컨드)" -NoiseGate.ReleaseTime="폐쇄 준비 시간 (밀리세컨드)" +NoiseGate.ReleaseTime="폐쇄 준비 시간 (밀리세컨드)" Gain.GainDB="증폭 (dB)" StretchImage="이미지 늘리기 (이미지 가로 세로 비율 포기)" Resolution="해상도" +Base.Canvas="기본 (캔버스) 해상도" None="없음" ScaleFiltering="비율 필터링" ScaleFiltering.Point="점" ScaleFiltering.Bilinear="이중선형" ScaleFiltering.Bicubic="쌍삼차" ScaleFiltering.Lanczos="란초스" +ScaleFiltering.Area="영역" NoiseSuppress.SuppressLevel="억제 세기 (dB)" Saturation="채도" HueShift="색조 변화" @@ -74,4 +77,25 @@ Compressor.AttackTime="신호 감지 후 반응까지 걸리는 시간 (ms)" Compressor.ReleaseTime="신호 세기가 감퇴 이후 증폭이 회복하는 시간 (ms)" Compressor.OutputGain="출력 증폭 (dB)" Compressor.SidechainSource="사이드체인/더킹 소스" +Limiter="음성 제한" +Limiter.Threshold="임계값 (dB)" +Limiter.ReleaseTime="해제 (ms)" +Expander="확장기" +Expander.Ratio="비율 (X:1)" +Expander.Threshold="임계값 (dB)" +Expander.AttackTime="반응 시간 (ms)" +Expander.ReleaseTime="해제 (ms)" +Expander.OutputGain="출력 증폭 (dB)" +Expander.Detector="측정 감지" +Expander.RMS="RMS" +Expander.Peak="최고조" +Expander.None="없음" +Expander.Presets="사전 설정" +Expander.Presets.Expander="확장기" +Expander.Presets.Gate="게이트" +LumaKeyFilter="루마 키" +Luma.LumaMax="루마 최대값" +Luma.LumaMin="루마 최소값" +Luma.LumaMaxSmooth="루마 스무스 최대값" +Luma.LumaMinSmooth="루마 스무스 최소값" diff --git a/plugins/obs-filters/data/locale/nb-NO.ini b/plugins/obs-filters/data/locale/nb-NO.ini index b7c7979..22d2f8f 100644 --- a/plugins/obs-filters/data/locale/nb-NO.ini +++ b/plugins/obs-filters/data/locale/nb-NO.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Rendringsforsinkelse" UndistortCenter="Fjern forstyrring av bildets midtområde, når det skaleres ned fra ultrabredhet" NoiseGate="Støyterskel" NoiseSuppress="Lyddemping" +InvertPolarity="Inverter polaritet" Gain="Forsterkning" DelayMs="Forsinkelse (millisekunder)" Type="Type" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Løslatelsestid (millisekunder)" Gain.GainDB="Forsterkning (dB)" StretchImage="Strekk bilde (ignorer bildets sideforhold)" Resolution="Oppløsning" +Base.Canvas="Grunnoppløsning (lerret)" None="Ingen" ScaleFiltering="Skala Filtrering" ScaleFiltering.Point="Punkt" ScaleFiltering.Bilinear="Bilineær" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" NoiseSuppress.SuppressLevel="Dempelse Nivå (dB)" Saturation="Metning" HueShift="Fargetone Skifte" @@ -74,4 +77,25 @@ Compressor.AttackTime="Angrep (ms)" Compressor.ReleaseTime="Slipp (ms)" Compressor.OutputGain="Utdataforsterkning (dB)" Compressor.SidechainSource="Lydduppe-kilde" +Limiter="Begrenser" +Limiter.Threshold="Terskel (dB)" +Limiter.ReleaseTime="Slipp (ms)" +Expander="Utvider" +Expander.Ratio="Forhold (X:1)" +Expander.Threshold="Terskel (dB)" +Expander.AttackTime="Responstid (ms)" +Expander.ReleaseTime="Slipp (ms)" +Expander.OutputGain="Utdataforsterkning (dB)" +Expander.Detector="Identifisering" +Expander.RMS="RMS" +Expander.Peak="Topp" +Expander.None="Ingen" +Expander.Presets="Forhåndsinnstillinger" +Expander.Presets.Expander="Utvider" +Expander.Presets.Gate="Port" +LumaKeyFilter="Luma Key" +Luma.LumaMax="Luma maks." +Luma.LumaMin="Luma min." +Luma.LumaMaxSmooth="Luma maks. glidende" +Luma.LumaMinSmooth="Luma min. glidende" diff --git a/plugins/obs-filters/data/locale/nl-NL.ini b/plugins/obs-filters/data/locale/nl-NL.ini index 386a24b..4773aad 100644 --- a/plugins/obs-filters/data/locale/nl-NL.ini +++ b/plugins/obs-filters/data/locale/nl-NL.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Rendervertraging" UndistortCenter="Verbeter beeldverhouding in het midden van bij schalen vanaf ultrawide" NoiseGate="Noise Gate" NoiseSuppress="Ruisonderdrukking" +InvertPolarity="Polariteit omkeren" Gain="Gain" DelayMs="Vertraging (milliseconden)" Type="Type" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Release-tijd (milliseconden)" Gain.GainDB="Gain (dB)" StretchImage="Afbeelding uitrekken (negeer beeldverhouding van de afbeelding)" Resolution="Resolutie" +Base.Canvas="Basisresolutie (Canvas)" None="Geen" ScaleFiltering="Schaal-filter" ScaleFiltering.Point="Point" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Gebied" NoiseSuppress.SuppressLevel="Onderdrukkingsniveau (dB)" Saturation="Verzadiging" HueShift="Tintverschuiving" @@ -74,4 +77,20 @@ Compressor.AttackTime="Attack (ms)" Compressor.ReleaseTime="Release (ms)" Compressor.OutputGain="Uitvoergain (dB)" Compressor.SidechainSource="Sidechain/Ducking Bron" +Limiter="Begrenzer" +Limiter.Threshold="Drempel (dB)" +Limiter.ReleaseTime="Vrijgave (ms)" +Expander="Uitbreiding" +Expander.Ratio="Verhouding (X:1)" +Expander.Threshold="Drempel (dB)" +Expander.AttackTime="Aanval (ms)" +Expander.ReleaseTime="Vrijgave (ms)" +Expander.OutputGain="Uitvoer versterking (dB)" +Expander.Detector="Detectie" +Expander.RMS="RMS" +Expander.Peak="Piek" +Expander.None="Geen" +Expander.Presets="Vooraf ingestelde instellingen" +Expander.Presets.Expander="Uitbreiding" +Expander.Presets.Gate="Hek" diff --git a/plugins/obs-filters/data/locale/pl-PL.ini b/plugins/obs-filters/data/locale/pl-PL.ini index 05fcefb..f491c19 100644 --- a/plugins/obs-filters/data/locale/pl-PL.ini +++ b/plugins/obs-filters/data/locale/pl-PL.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Opóźnienie renderowania" UndistortCenter="Usuń przekłamania przy skalowaniu źródeł o dużej szerokości" NoiseGate="Bramka szumów" NoiseSuppress="Tłumienie hałasu" +InvertPolarity="Odwrócenie polaryzacji" Gain="Poziom" DelayMs="Opóźnienie (milisekundy)" Type="Typ" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Czas zwolnienia (milisekundy)" Gain.GainDB="Poziom (dB)" StretchImage="Rozciągnięcie obrazu (ignoruj proporcje)" Resolution="Rozdzielczość" +Base.Canvas="Rozdzielczość bazowa (obraz)" None="Brak" ScaleFiltering="Filtrowanie" ScaleFiltering.Point="Punktowe" ScaleFiltering.Bilinear="Dwuliniowe" ScaleFiltering.Bicubic="Dwusześcienne" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Obszar" NoiseSuppress.SuppressLevel="Poziom tłumienia (dB)" Saturation="Nasycenie" HueShift="Przesunięcie barwy" @@ -74,4 +77,25 @@ Compressor.AttackTime="Atak (ms)" Compressor.ReleaseTime="Odpuszczenie (ms)" Compressor.OutputGain="Zysk na wyjściu (dB)" Compressor.SidechainSource="Źródło poboczne" +Limiter="Limiter" +Limiter.Threshold="Próg odcięcia (dB)" +Limiter.ReleaseTime="Czas reakcji (ms)" +Expander="Expander" +Expander.Ratio="Stosunek (X:1)" +Expander.Threshold="Próg (dB)" +Expander.AttackTime="Aktywacja (ms)" +Expander.ReleaseTime="Odpuszczenie (ms)" +Expander.OutputGain="Zysk na wyjściu (dB)" +Expander.Detector="Wykrywanie" +Expander.RMS="RMS" +Expander.Peak="Punkt szczytowy" +Expander.None="Brak" +Expander.Presets="Predefiniowane" +Expander.Presets.Expander="Expander" +Expander.Presets.Gate="Brama" +LumaKeyFilter="Kluczowanie luma key" +Luma.LumaMax="Luma Max" +Luma.LumaMin="Luma Min" +Luma.LumaMaxSmooth="Luma wygładzanie max" +Luma.LumaMinSmooth="Luma wygładzanie min" diff --git a/plugins/obs-filters/data/locale/pt-BR.ini b/plugins/obs-filters/data/locale/pt-BR.ini index 886dd2a..8cbee2a 100644 --- a/plugins/obs-filters/data/locale/pt-BR.ini +++ b/plugins/obs-filters/data/locale/pt-BR.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Atraso de Renderização" UndistortCenter="Remover distorção do centro da imagem ao redimensionar de ultralargo" NoiseGate="Filtro de Rúido" NoiseSuppress="Redução de ruídos" +InvertPolarity="Inverter Polaridade" Gain="Ganho" DelayMs="Atraso (milissegundos)" Type="Tipo" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Tempo de liberação (milissegundos)" Gain.GainDB="Ganho (dB)" StretchImage="Esticar a Imagem (descartar aspecto da imagem)" Resolution="Resolução" +Base.Canvas="Resolução Base (Tela)" None="Nenhum" ScaleFiltering="Filtragem de escala" ScaleFiltering.Point="Ponto" ScaleFiltering.Bilinear="Bilinear" ScaleFiltering.Bicubic="Bicúbico" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Área" NoiseSuppress.SuppressLevel="Nível de redução (dB)" Saturation="Saturação" HueShift="Alteração de matiz" @@ -74,4 +77,25 @@ Compressor.AttackTime="Ataque (ms)" Compressor.ReleaseTime="Liberação (ms)" Compressor.OutputGain="Ganho na saída (dB)" Compressor.SidechainSource="Fonte de Cadeia Lateral/Oscilação de Áudio" +Limiter="Limitador" +Limiter.Threshold="Limiar (dB)" +Limiter.ReleaseTime="Liberação (ms)" +Expander="Expansor" +Expander.Ratio="Razão (X:1)" +Expander.Threshold="Limiar (dB)" +Expander.AttackTime="Ataque (ms)" +Expander.ReleaseTime="Liberação (ms)" +Expander.OutputGain="Ganho na Saída (dB)" +Expander.Detector="Detecção" +Expander.RMS="RMS" +Expander.Peak="Pico" +Expander.None="Nenhuma" +Expander.Presets="Predefinições" +Expander.Presets.Expander="Expansor" +Expander.Presets.Gate="Portão" +LumaKeyFilter="Luma Key" +Luma.LumaMax="Luminância Máxima" +Luma.LumaMin="Luminância Mínima" +Luma.LumaMaxSmooth="Suavização da Luminância Máxima" +Luma.LumaMinSmooth="Suavização da Luminância Mínima" diff --git a/plugins/obs-filters/data/locale/pt-PT.ini b/plugins/obs-filters/data/locale/pt-PT.ini index 8a2f817..8c5b5cb 100644 --- a/plugins/obs-filters/data/locale/pt-PT.ini +++ b/plugins/obs-filters/data/locale/pt-PT.ini @@ -1,4 +1,5 @@ ColorFilter="Correção de cor" +ColorGradeFilter="Aplicar LUT" MaskFilter="Máscara/mistura de imagem" AsyncDelayFilter="Atraso de vídeo (Async)" ScrollFilter="Percorre" @@ -6,6 +7,7 @@ ChromaKeyFilter="Chroma Key" ColorKeyFilter="Color Key" SharpnessFilter="Nitidez" NoiseGate="Filtro de ruído" +InvertPolarity="Inverter Polaridade" Gain="Ganho" DelayMs="Atraso (milissegundos)" Type="Topo" @@ -50,4 +52,32 @@ NoiseGate.HoldTime="Tempo de bloqueio (milissegundos)" NoiseGate.ReleaseTime="Tempo de libertação (milissegundos)" Gain.GainDB="Ganho (dB)" StretchImage="Esticar a imagem (relação de aspeto de imagem de descarte)" +Resolution="Resolução" +None="Nenhum" +NoiseSuppress.SuppressLevel="Nível de Supressão (dB)" +Saturation="Saturação" +Amount="Montante" +Compressor="Compressor" +Compressor.Ratio="Relação (X:1)" +Compressor.Threshold="Limiar (dB)" +Compressor.AttackTime="Ataque (ms)" +Compressor.ReleaseTime="Liberação (ms)" +Compressor.OutputGain="Ganho de saída (dB)" +Compressor.SidechainSource="Sidechain/Ducking Source" +Limiter="Limitador" +Limiter.Threshold="Limiar (dB)" +Limiter.ReleaseTime="Release (ms)" +Expander="Expansor" +Expander.Ratio="Relação (X:1)" +Expander.Threshold="Limiar (dB)" +Expander.AttackTime="Ataque (ms)" +Expander.ReleaseTime="Liberação (ms)" +Expander.OutputGain="Ganho de saída (dB)" +Expander.Detector="Deteção" +Expander.RMS="RMS" +Expander.Peak="Pico" +Expander.None="Nenhum" +Expander.Presets="Predefinições" +Expander.Presets.Expander="Expansor" +Expander.Presets.Gate="Portão" diff --git a/plugins/obs-filters/data/locale/ro-RO.ini b/plugins/obs-filters/data/locale/ro-RO.ini index ee175a8..f677080 100644 --- a/plugins/obs-filters/data/locale/ro-RO.ini +++ b/plugins/obs-filters/data/locale/ro-RO.ini @@ -7,6 +7,7 @@ ColorKeyFilter="Culoare cheie" SharpnessFilter="Accentuare" ScaleFilter="Scalare/Rație Aspect" NoiseGate="Poartă de zgomot" +InvertPolarity="Inversează polaritatea" Gain="Amplificare" DelayMs="Întârziere (milisecunde)" Type="Tip" @@ -26,7 +27,7 @@ BrowsePath.AllFiles="Toate fișierele" KeyColorType="Tipul culorii cheie" KeyColor="Culoare cheie" Similarity="Similaritate (1-100)" -Smoothness="Netezire (1-1000)" +Smoothness="Netezime (1-1000)" ColorSpillReduction="Reducere pentru devărsarea culorii cheie (1-1000)" Crop.Left="Stânga" Crop.Right="Dreapta" @@ -52,9 +53,28 @@ NoiseGate.ReleaseTime="Timp de eliberare (milisecunde)" Gain.GainDB="Amplificare (dB)" StretchImage="Întinde imaginea (renunță la raportul de aspect al imaginii)" Resolution="Rezoluție" +Base.Canvas="Rezoluție (planșă) de bază" None="Fără" ScaleFiltering.Bilinear="Biliniar" ScaleFiltering.Bicubic="Bicubic" ScaleFiltering.Lanczos="Lanczos" Saturation="Saturație" +Compressor="Compresor" +Compressor.Ratio="Raport (X:1)" +Compressor.Threshold="Prag (dB)" +Compressor.AttackTime="Atacare (ms)" +Compressor.ReleaseTime="Eliberare (ms)" +Compressor.OutputGain="Amplificare pentru ieșire (dB)" +Limiter="Limitor" +Limiter.Threshold="Prag (dB)" +Limiter.ReleaseTime="Eliberare (ms)" +Expander.Ratio="Raport (X:1)" +Expander.Threshold="Prag (dB)" +Expander.OutputGain="Amplificare pentru ieșire (dB)" +Expander.Detector="Detectare" +Expander.RMS="RMS" +Expander.Peak="Valoare de vârf" +Expander.None="Niciuna" +Expander.Presets="Presetări" +Expander.Presets.Expander="Expandor" diff --git a/plugins/obs-filters/data/locale/ru-RU.ini b/plugins/obs-filters/data/locale/ru-RU.ini index 1fe92ef..e56c70d 100644 --- a/plugins/obs-filters/data/locale/ru-RU.ini +++ b/plugins/obs-filters/data/locale/ru-RU.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Задержка отображения" UndistortCenter="Не искривлять центр изображения при масштабировании Ultrawide разрешения" NoiseGate="Пропускной уровень шума" NoiseSuppress="Шумоподавление" +InvertPolarity="Инвертировать полярность" Gain="Усиление" DelayMs="Задержка (миллисекунд)" Type="Тип" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Длительность затухания (миллис Gain.GainDB="Усиление (дБ)" StretchImage="Растянуть изображение (игнорировать пропорции изображения)" Resolution="Разрешение" +Base.Canvas="Базовое (основное) разрешение" None="Нет" ScaleFiltering="Фильтр масштабирования" ScaleFiltering.Point="Точечный" ScaleFiltering.Bilinear="Билинейный" ScaleFiltering.Bicubic="Бикубический" ScaleFiltering.Lanczos="Метод Ланцоша" +ScaleFiltering.Area="Область" NoiseSuppress.SuppressLevel="Уровень подавления (дБ)" Saturation="Насыщенность" HueShift="Сдвиг оттенка" @@ -74,4 +77,25 @@ Compressor.AttackTime="Атака (мс)" Compressor.ReleaseTime="Спад (мс)" Compressor.OutputGain="Выходное усиление (дБ)" Compressor.SidechainSource="Источник приглушения/сайдчейн-компрессии" +Limiter="Лимитер" +Limiter.Threshold="Порог срабатывания (дБ)" +Limiter.ReleaseTime="Восстановление (мс)" +Expander="Экспандер" +Expander.Ratio="Соотношение (X:1)" +Expander.Threshold="Порог срабатывания (дБ)" +Expander.AttackTime="Атака (мс)" +Expander.ReleaseTime="Восстановление (мс)" +Expander.OutputGain="Выходное усиление (дБ)" +Expander.Detector="Обнаружение" +Expander.RMS="RMS" +Expander.Peak="Пик" +Expander.None="Нет" +Expander.Presets="Предустановки" +Expander.Presets.Expander="Экспандер" +Expander.Presets.Gate="Гейт" +LumaKeyFilter="Яркостный ключ" +Luma.LumaMax="Макс. яркость" +Luma.LumaMin="Мин. яркость" +Luma.LumaMaxSmooth="Сглаживание макс. яркости" +Luma.LumaMinSmooth="Сглаживание мин. яркости" diff --git a/plugins/obs-filters/data/locale/sk-SK.ini b/plugins/obs-filters/data/locale/sk-SK.ini index d9ddbdf..161f4db 100644 --- a/plugins/obs-filters/data/locale/sk-SK.ini +++ b/plugins/obs-filters/data/locale/sk-SK.ini @@ -1,15 +1,26 @@ ColorFilter="Korekcia farieb" ColorGradeFilter="Použiť LUT" +MaskFilter="Maska/miešanie obrazu" AsyncDelayFilter="Oneskorenie videa (Async)" CropFilter="Orezať/odsadiť" +ScrollFilter="Rolovanie" ChromaKeyFilter="Chroma Key" ColorKeyFilter="Farebný kľúč" SharpnessFilter="Zaostriť" ScaleFilter="Škálovanie/pomer strán" +GPUDelayFilter="Oneskorenie vykresľovania" +UndistortCenter="Odstrániť skreslenie pri škálovaní zo širokouhlého obrazu" +NoiseGate="Hluková brána" NoiseSuppress="Potlačenie šumu" +InvertPolarity="Invertovať polaritu" Gain="Zosilnenie" DelayMs="Oneskorenie (v milisekundách)" Type="Typ" +MaskBlendType.MaskColor="Maska priehľadnosti (kanál farieb)" +MaskBlendType.MaskAlpha="Maska priehľadnosti (kanál priehľadnosti)" +MaskBlendType.BlendMultiply="Zmiešať (násobenie)" +MaskBlendType.BlendAddition="Zmiešať (sčítanie)" +MaskBlendType.BlendSubtraction="Zmiešať (odčítanie)" Path="Cesta" Color="Farba" Opacity="Priehľadnosť" @@ -21,6 +32,8 @@ BrowsePath.AllFiles="Všetky súbory" KeyColorType="Typ kľúčovej farby" KeyColor="Kľúčová farba" Similarity="Podobnosť (1-1000)" +Smoothness="Hladkosť (1-1000)" +ColorSpillReduction="Redukcia color spill-u (1-1000)" Crop.Left="Vľavo" Crop.Right="Vpravo" Crop.Top="Hore" @@ -28,6 +41,8 @@ Crop.Bottom="Dole" Crop.Width="Šírka" Crop.Height="Výška" Crop.Relative="Relatívne" +ScrollFilter.SpeedX="Horizontálna rýchlosť" +ScrollFilter.SpeedY="Vertikálna rýchlosť" ScrollFilter.LimitWidth="Obmedziť šírku" ScrollFilter.LimitHeight="Obmedziť výšku" CustomColor="Vlastná farba" @@ -37,16 +52,27 @@ Blue="Modrá" Magenta="Purpurová" NoiseGate.OpenThreshold="Hladina otvorenia (dB)" NoiseGate.CloseThreshold="Hladina zatvorenia (dB)" +NoiseGate.AttackTime="Čas nástupu (milisekundy)" +NoiseGate.HoldTime="Čas podržania (milisekundy)" +NoiseGate.ReleaseTime="Čas uvoľnenia (milisekundy)" +Gain.GainDB="Zisk (dB)" +StretchImage="Roztiahnutie obrázka (pomer strán obrazu zahodiť)" Resolution="Rozlíšenie" +Base.Canvas="Základné (Plátnové) rozlíšenie" None="Žiadne" ScaleFiltering="Filtrovanie rozsahu" ScaleFiltering.Point="Bodové" ScaleFiltering.Bilinear="Bilineárne" ScaleFiltering.Bicubic="Bikubické" ScaleFiltering.Lanczos="Lanczos" +NoiseSuppress.SuppressLevel="Úroveň potlačenia (dB)" Saturation="Sýtosť" +HueShift="Posun odtieňa" Amount="Množstvo" Compressor="Kompresor" Compressor.Ratio="Pomer (X:1)" Compressor.Threshold="Prah (dB)" +Compressor.AttackTime="Nástup (ms)" +Compressor.ReleaseTime="Uvoľnenie (ms)" +Compressor.OutputGain="Zosilnenie výstupu (dB)" diff --git a/plugins/obs-filters/data/locale/sr-CS.ini b/plugins/obs-filters/data/locale/sr-CS.ini index 181a708..39cbc03 100644 --- a/plugins/obs-filters/data/locale/sr-CS.ini +++ b/plugins/obs-filters/data/locale/sr-CS.ini @@ -1,16 +1,20 @@ ColorFilter="Promena boja" +ColorGradeFilter="Primeni LUT" MaskFilter="Slika maske i stapanja" -AsyncDelayFilter="Video pauza (asinhrono)" +AsyncDelayFilter="Video kašnjenje (asinhrono)" CropFilter="Odsecanje/okvir" ScrollFilter="Pomeranje" ChromaKeyFilter="Ključ providnosti" ColorKeyFilter="Ključ boje" SharpnessFilter="Izoštravanje" ScaleFilter="Uvećanje/Odnos" +GPUDelayFilter="Kašnjenje u radu" +UndistortCenter="Ukloni distorziju centra slike tokom skaliranja sa ultra široke slike na normalnu" NoiseGate="Kapija šuma" NoiseSuppress="Suzbijanje šuma" +InvertPolarity="Invertuj polaritet" Gain="Pojačanje" -DelayMs="Pauza (milisekunde)" +DelayMs="Kašnjenje (milisekunde)" Type="Vrsta" MaskBlendType.MaskColor="Maska prozirnosti (kanal boje)" MaskBlendType.MaskAlpha="Maska prozirnosti (prozirni kanal)" @@ -54,6 +58,7 @@ NoiseGate.ReleaseTime="Vreme otpuštanja (milisekunde)" Gain.GainDB="Pojačanje (dB)" StretchImage="Istegni sliku (zanemari odnos visine i širine slike)" Resolution="Rezolucija" +Base.Canvas="Osnovna rezolucija" None="Nijedno" ScaleFiltering="Filter uvećanja" ScaleFiltering.Point="Tačka" @@ -61,4 +66,30 @@ ScaleFiltering.Bilinear="Bilinearno" ScaleFiltering.Bicubic="Bikubično" ScaleFiltering.Lanczos="Lankoz" NoiseSuppress.SuppressLevel="Nivo suzbijanja (dB)" +Saturation="Zasićenje" +HueShift="Promena nijanse" +Amount="Količina" +Compressor="Kompresor" +Compressor.Ratio="Razmera (X:1)" +Compressor.Threshold="Prag (dB)" +Compressor.AttackTime="Napad (ms)" +Compressor.ReleaseTime="Vreme otpuštanja (ms)" +Compressor.OutputGain="Pojačanje izlaza (dB)" +Compressor.SidechainSource="Sidechain/Ducking Izvor" +Limiter="Limiter" +Limiter.Threshold="Prag (dB)" +Limiter.ReleaseTime="Vreme otpuštanja (ms)" +Expander="Ekspander" +Expander.Ratio="Razmera (X:1)" +Expander.Threshold="Prag (dB)" +Expander.AttackTime="Napad (ms)" +Expander.ReleaseTime="Vreme otpuštanja (ms)" +Expander.OutputGain="Pojačanje izlaza (dB)" +Expander.Detector="Detekcija" +Expander.RMS="RMS" +Expander.Peak="Vrhunac (ekspander reaguje na kratke vrhunce)" +Expander.None="Bez" +Expander.Presets="Predefinisana podešavanja" +Expander.Presets.Expander="Ekspander" +Expander.Presets.Gate="Prolaz (eng. Gate)" diff --git a/plugins/obs-filters/data/locale/sr-SP.ini b/plugins/obs-filters/data/locale/sr-SP.ini index 0aa7561..c8ac575 100644 --- a/plugins/obs-filters/data/locale/sr-SP.ini +++ b/plugins/obs-filters/data/locale/sr-SP.ini @@ -1,16 +1,20 @@ ColorFilter="Промена боја" +ColorGradeFilter="Примени LUT" MaskFilter="Слика маске и стапања" -AsyncDelayFilter="Видео пауза (асинхроно)" +AsyncDelayFilter="Видео кашњење (асинхроно)" CropFilter="Одсецање/оквир" ScrollFilter="Померање" ChromaKeyFilter="Кључ провидности" ColorKeyFilter="Кључ боје" SharpnessFilter="Изоштравање" ScaleFilter="Увећање/однос" +GPUDelayFilter="Кашњење у раду" +UndistortCenter="Уклони дисторзију центра слике током скалирања са ултра широке слике на нормалну" NoiseGate="Капија шума" NoiseSuppress="Сузбијање шума" +InvertPolarity="Инвертуј поларитет" Gain="Појачање" -DelayMs="Пауза (милисекунде)" +DelayMs="Кашњење (милисекунде)" Type="Врста" MaskBlendType.MaskColor="Маска прозирности (канал боје)" MaskBlendType.MaskAlpha="Маска прозирности (прозирни канал)" @@ -54,6 +58,7 @@ NoiseGate.ReleaseTime="Време отпуштања (милисекунде)" Gain.GainDB="Појачање (dB)" StretchImage="Истегни слику (занемари однос висине и ширине слике)" Resolution="Резолуција" +Base.Canvas="Основна резолуција" None="Ниједно" ScaleFiltering="Филтер увећања" ScaleFiltering.Point="Тачка" @@ -61,4 +66,30 @@ ScaleFiltering.Bilinear="Билинеарно" ScaleFiltering.Bicubic="Бикубично" ScaleFiltering.Lanczos="Ланкоз" NoiseSuppress.SuppressLevel="Ниво сузбијања (dB)" +Saturation="Засићење" +HueShift="Промена нијансе" +Amount="Количина" +Compressor="Компресор" +Compressor.Ratio="Размера (X:1)" +Compressor.Threshold="Праг (dB)" +Compressor.AttackTime="Напад (ms)" +Compressor.ReleaseTime="Време отпуштања (ms)" +Compressor.OutputGain="Појачање излаза (dB)" +Compressor.SidechainSource="Sidechain/Ducking Извор" +Limiter="Лимитер" +Limiter.Threshold="Праг (dB)" +Limiter.ReleaseTime="Време отпуштања (ms)" +Expander="Експандер" +Expander.Ratio="Размера (X:1)" +Expander.Threshold="Праг (dB)" +Expander.AttackTime="Напад (ms)" +Expander.ReleaseTime="Време отпуштања (ms)" +Expander.OutputGain="Појачање излаза (dB)" +Expander.Detector="Детекција" +Expander.RMS="RMS" +Expander.Peak="Врхунац (експандер реагује на кратке врхунце)" +Expander.None="Без" +Expander.Presets="Предефинисана подешавања" +Expander.Presets.Expander="Експандер" +Expander.Presets.Gate="Пролаз (енг. Gate)" diff --git a/plugins/obs-filters/data/locale/sv-SE.ini b/plugins/obs-filters/data/locale/sv-SE.ini index 6562a77..0c8b2d5 100644 --- a/plugins/obs-filters/data/locale/sv-SE.ini +++ b/plugins/obs-filters/data/locale/sv-SE.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Renderingsfördröjning" UndistortCenter="Återställ bildens centrum vid skalning från ultrawide" NoiseGate="Brusblockering" NoiseSuppress="Brusreducering" +InvertPolarity="Invertera polaritet" Gain="Förstärkning" DelayMs="Fördröjning (millisekunder)" Type="Typ" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Släpptid (millisekunder)" Gain.GainDB="Förstärkning (dB)" StretchImage="Sträck bild (ignorera bildförhållandet)" Resolution="Upplösning" +Base.Canvas="Grundupplösning (kanvas)" None="Ingen" ScaleFiltering="Skalningsfiltrering" ScaleFiltering.Point="Punkt" ScaleFiltering.Bilinear="Bilinjär" ScaleFiltering.Bicubic="Bikubisk" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="Område" NoiseSuppress.SuppressLevel="Brusreduceringsnivå (dB)" Saturation="Mättnad" HueShift="Nyansväxling" @@ -74,4 +77,25 @@ Compressor.AttackTime="Attack (ms)" Compressor.ReleaseTime="Frigör (ms)" Compressor.OutputGain="Utmatningsförstärkning (dB)" Compressor.SidechainSource="Sidechain/Ducking-källa" +Limiter="Begränsare" +Limiter.Threshold="Tröskel (dB)" +Limiter.ReleaseTime="Frigör (ms)" +Expander="Utvidgare" +Expander.Ratio="Förhållande (X:1)" +Expander.Threshold="Tröskel (dB)" +Expander.AttackTime="Attack (ms)" +Expander.ReleaseTime="Frigör (ms)" +Expander.OutputGain="Utmatningsförstärkning (dB)" +Expander.Detector="Identifiering" +Expander.RMS="RMS" +Expander.Peak="Maxpunkt" +Expander.None="Ingen" +Expander.Presets="Förinställningar" +Expander.Presets.Expander="Utvidgare" +Expander.Presets.Gate="Port" +LumaKeyFilter="Ljusstyrkefilter" +Luma.LumaMax="Maximal ljusstyrka" +Luma.LumaMin="Minimal ljusstyrka" +Luma.LumaMaxSmooth="Max. utjämning av ljusstyrka" +Luma.LumaMinSmooth="Min. utjämning av ljusstyrka" diff --git a/plugins/obs-filters/data/locale/tr-TR.ini b/plugins/obs-filters/data/locale/tr-TR.ini index ee2a738..a79f5fd 100644 --- a/plugins/obs-filters/data/locale/tr-TR.ini +++ b/plugins/obs-filters/data/locale/tr-TR.ini @@ -12,6 +12,7 @@ GPUDelayFilter="İşleyici Gecikmesi" UndistortCenter="Ultra genişten boyutlandırırken görüntü merkezindeki bozulmayı düzelt" NoiseGate="Gürültü Filtresi" NoiseSuppress="Gürültü Bastırma" +InvertPolarity="Polariteyi ters çevir" Gain="Kazanç" DelayMs="Gecikme (milisaniye)" Type="Türü" @@ -57,6 +58,7 @@ NoiseGate.ReleaseTime="Bırakma Süresi (milisaniye)" Gain.GainDB="Kazanç (dB)" StretchImage="Görüntüyü Uzat (görüntü en-boy oranını görmezden gel)" Resolution="Çözünürlük" +Base.Canvas="Temel (Tuval) Çözünürlüğü" None="Hiçbiri" ScaleFiltering="Ölçek Filtreleme" ScaleFiltering.Point="Nokta" @@ -74,4 +76,18 @@ Compressor.AttackTime="Atak (ms)" Compressor.ReleaseTime="Bırakma (ms)" Compressor.OutputGain="Çıkış Kazancı (dB)" Compressor.SidechainSource="Yan-Zincir/Alçaltma Kaynağı" +Limiter="Sınırlayıcı" +Limiter.Threshold="Eşik (dB)" +Limiter.ReleaseTime="Bırakma süresi (ms)" +Expander="Genişletici" +Expander.Ratio="Oran (X:1)" +Expander.Threshold="Eşik (dB)" +Expander.AttackTime="Tepki Süresi (ms)" +Expander.ReleaseTime="Bırakma Süresi (ms)" +Expander.OutputGain="Çıkış Kazancı (dB)" +Expander.Detector="Algılama" +Expander.None="Hiçbiri" +Expander.Presets="Hazır Ayarlar" +Expander.Presets.Expander="Genişletici" +Expander.Presets.Gate="Geçit" diff --git a/plugins/obs-filters/data/locale/uk-UA.ini b/plugins/obs-filters/data/locale/uk-UA.ini index 3df87f8..e028e64 100644 --- a/plugins/obs-filters/data/locale/uk-UA.ini +++ b/plugins/obs-filters/data/locale/uk-UA.ini @@ -12,6 +12,7 @@ GPUDelayFilter="Затримка візуалізації" UndistortCenter="Зменшити викривлення у центрі, якщо масштабувати з надширокоформатного" NoiseGate="Пороговий шумопонижувач" NoiseSuppress="Подавлення шуму" +InvertPolarity="Інверсія сигналу" Gain="Підсилення" DelayMs="Затримка (мілісекунд)" Type="Тип" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="Тривалість спаду сигналу (мілі Gain.GainDB="Підсилення (дБ)" StretchImage="Розтягнути зображення (ігнорувати пропорції зображення)" Resolution="Новий розмір" +Base.Canvas="Роздільна здатність (Полотно)" None="Не вказано" ScaleFiltering="Фільтр масштабування" ScaleFiltering.Point="Ступінчастий" ScaleFiltering.Bilinear="Білінійний" ScaleFiltering.Bicubic="Бікубічний" ScaleFiltering.Lanczos="Ланцош" +ScaleFiltering.Area="Усереднення площ" NoiseSuppress.SuppressLevel="Рівень подавлення (дБ)" Saturation="Насиченість" HueShift="Відтінок" @@ -74,4 +77,25 @@ Compressor.AttackTime="Атака (мс)" Compressor.ReleaseTime="Затухання (мс)" Compressor.OutputGain="Підсилення виводу (dB)" Compressor.SidechainSource="Джерело Коригування/Приглушення" +Limiter="Обмежувач амплітуди" +Limiter.Threshold="Поріг (дБ)" +Limiter.ReleaseTime="Затухання (мс)" +Expander="Експандер" +Expander.Ratio="Відношення (X:1)" +Expander.Threshold="Поріг (дБ)" +Expander.AttackTime="Атака (мс)" +Expander.ReleaseTime="Затухання (мс)" +Expander.OutputGain="Підсилення виводу (dB)" +Expander.Detector="Детектор" +Expander.RMS="Середньоквадратичний (RMS)" +Expander.Peak="Піковий" +Expander.None="Немає (миттєві значення)" +Expander.Presets="Шаблони" +Expander.Presets.Expander="Експандер" +Expander.Presets.Gate="Пороговий" +LumaKeyFilter="Фільтр яскравості" +Luma.LumaMax="Максимум яскравості" +Luma.LumaMin="Мінімум яскравості" +Luma.LumaMaxSmooth="Максимум яскравості припуск" +Luma.LumaMinSmooth="Мінімум яскравості припуск" diff --git a/plugins/obs-filters/data/locale/zh-CN.ini b/plugins/obs-filters/data/locale/zh-CN.ini index cd4daad..463045e 100644 --- a/plugins/obs-filters/data/locale/zh-CN.ini +++ b/plugins/obs-filters/data/locale/zh-CN.ini @@ -12,6 +12,7 @@ GPUDelayFilter="渲染延迟" UndistortCenter="当从超宽扩展时, 让图片中心不失真" NoiseGate="噪音阈值" NoiseSuppress="噪声抑制" +InvertPolarity="反转极性" Gain="增益" DelayMs="延迟(毫秒)" Type="类型" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="释放时间(毫秒)" Gain.GainDB="增益 (dB)" StretchImage="伸展图像 (丢弃图像纵横比)" Resolution="分辨率" +Base.Canvas="基础 (Canvas) 分辨率" None="无" ScaleFiltering="尺度滤波" ScaleFiltering.Point="点" ScaleFiltering.Bilinear="双线性算法" ScaleFiltering.Bicubic="双立方算法" ScaleFiltering.Lanczos="兰索斯算法" +ScaleFiltering.Area="区域" NoiseSuppress.SuppressLevel="抑制程度 (dB)" Saturation="饱和度" HueShift="色调偏移" @@ -70,8 +73,29 @@ Amount="数值" Compressor="压缩器" Compressor.Ratio="比率 (X:1)" Compressor.Threshold="阈值 (dB)" -Compressor.AttackTime="攻击 (ms)" +Compressor.AttackTime="起始时间(毫秒)" Compressor.ReleaseTime="释放 (ms)" Compressor.OutputGain="输出增益 (dB)" Compressor.SidechainSource="避免来源" +Limiter="限幅" +Limiter.Threshold="阈值 (dB)" +Limiter.ReleaseTime="释放 (ms)" +Expander="扩展效果" +Expander.Ratio="比率 (X:1)" +Expander.Threshold="阈值 (dB)" +Expander.AttackTime="起始时间(毫秒)" +Expander.ReleaseTime="释放时间(毫秒)" +Expander.OutputGain="输出增益 (dB)" +Expander.Detector="检测" +Expander.RMS="均方根" +Expander.Peak="峰值" +Expander.None="无" +Expander.Presets="预设" +Expander.Presets.Expander="扩展效果" +Expander.Presets.Gate="门限" +LumaKeyFilter="亮度键" +Luma.LumaMax="最大亮度" +Luma.LumaMin="最小亮度" +Luma.LumaMaxSmooth="最大亮度平滑" +Luma.LumaMinSmooth="最小亮度平滑" diff --git a/plugins/obs-filters/data/locale/zh-TW.ini b/plugins/obs-filters/data/locale/zh-TW.ini index 0925595..b9a83c3 100644 --- a/plugins/obs-filters/data/locale/zh-TW.ini +++ b/plugins/obs-filters/data/locale/zh-TW.ini @@ -12,6 +12,7 @@ GPUDelayFilter="繪製延遲" UndistortCenter="從超寬影像縮放時彌補影像中心的畸變" NoiseGate="噪音閾" NoiseSuppress="雜訊抑制" +InvertPolarity="反轉極性" Gain="增益" DelayMs="延遲 (毫秒)" Type="類型" @@ -57,12 +58,14 @@ NoiseGate.ReleaseTime="釋音時間 (Release time)(毫秒)" Gain.GainDB="增益 (dB)" StretchImage="伸展圖像 (無視圖像比例)" Resolution="解析度" +Base.Canvas="來源(畫布)解析度" None="無" ScaleFiltering="縮放濾鏡" ScaleFiltering.Point="點" ScaleFiltering.Bilinear="雙線性插值" ScaleFiltering.Bicubic="雙三次插值" ScaleFiltering.Lanczos="Lanczos" +ScaleFiltering.Area="範圍" NoiseSuppress.SuppressLevel="抑制標準 (dB)" Saturation="飽合度" HueShift="色調偏移" @@ -74,4 +77,25 @@ Compressor.AttackTime="起始時間 (ms)" Compressor.ReleaseTime="釋放時間 (ms)" Compressor.OutputGain="輸出增益 (dB)" Compressor.SidechainSource="側鏈/回避源" +Limiter="限制器" +Limiter.Threshold="臨界值 (dB)" +Limiter.ReleaseTime="釋放時間 (ms)" +Expander="展開特效" +Expander.Ratio="比例 (X:1)" +Expander.Threshold="閾值 (dB)" +Expander.AttackTime="起始時間 (ms)" +Expander.ReleaseTime="釋放時間 (ms)" +Expander.OutputGain="輸出增益 (dB)" +Expander.Detector="偵測" +Expander.RMS="方均根" +Expander.Peak="峰值" +Expander.None="無" +Expander.Presets="預先設定" +Expander.Presets.Expander="展開特效" +Expander.Presets.Gate="開門特效" +LumaKeyFilter="亮度鍵" +Luma.LumaMax="亮度最大值" +Luma.LumaMin="亮度最小值" +Luma.LumaMaxSmooth="亮度最大平滑度" +Luma.LumaMinSmooth="亮度最小平滑度" diff --git a/plugins/obs-filters/data/luma_key_filter.effect b/plugins/obs-filters/data/luma_key_filter.effect new file mode 100644 index 0000000..77cd40d --- /dev/null +++ b/plugins/obs-filters/data/luma_key_filter.effect @@ -0,0 +1,51 @@ +uniform float4x4 ViewProj; +uniform texture2d image; + +uniform float lumaMax; +uniform float lumaMin; +uniform float lumaMaxSmooth; +uniform float lumaMinSmooth; + +sampler_state textureSampler { + Filter = Linear; + AddressU = Clamp; + AddressV = Clamp; +}; + +struct VertData { + float4 pos : POSITION; + float2 uv : TEXCOORD0; +}; + +VertData VSDefault(VertData v_in) +{ + VertData vert_out; + vert_out.pos = mul(float4(v_in.pos.xyz, 1.0), ViewProj); + vert_out.uv = v_in.uv; + return vert_out; +} + +float4 PSALumaKeyRGBA(VertData v_in) : TARGET +{ + float4 rgba = image.Sample(textureSampler, v_in.uv); + + float4 lumaCoef = float4(0.2989, 0.5870, 0.1140, 0.0); + + float luminance = dot(rgba, lumaCoef); + + float clo = smoothstep(lumaMin, lumaMin + lumaMinSmooth, luminance); + float chi = 1. - smoothstep(lumaMax - lumaMaxSmooth, lumaMax, luminance); + + float amask = clo * chi; + + return float4(rgba.rgb, amask); +} + +technique Draw +{ + pass + { + vertex_shader = VSDefault(v_in); + pixel_shader = PSALumaKeyRGBA(v_in); + } +} diff --git a/plugins/obs-filters/data/sharpness.effect b/plugins/obs-filters/data/sharpness.effect index 54a023e..ea88e17 100644 --- a/plugins/obs-filters/data/sharpness.effect +++ b/plugins/obs-filters/data/sharpness.effect @@ -5,7 +5,6 @@ uniform float4x4 ViewProj; uniform texture2d image; uniform texture2d target; -uniform float4 color = {1.0, 1.0, 1.0, 1.0}; uniform float sharpness; uniform float texture_width; @@ -24,7 +23,6 @@ struct VertInOut { struct VertOut { float4 pos : POSITION; - float4 col : COLOR; float2 uv : TEXCOORD0; float4 t1 : TEXCOORD1; float4 t2 : TEXCOORD2; @@ -36,7 +34,6 @@ VertOut VSDefault(VertInOut vert_in) VertOut vert_out; vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj); vert_out.uv = vert_in.uv; - vert_out.col = color; float2 ps = float2(1.0/texture_width, 1.0/texture_height); float dx = ps.x; @@ -52,23 +49,23 @@ float4 PSDrawBare(VertOut vert_in) : TARGET { float4 E = image.Sample(def_sampler, vert_in.uv); - float4 colorx = 8*E; + float4 color = 8*E; float4 B = image.Sample(def_sampler, vert_in.t1.yw); float4 D = image.Sample(def_sampler, vert_in.t2.xw); float4 F = image.Sample(def_sampler, vert_in.t2.zw); float4 H = image.Sample(def_sampler, vert_in.t3.yw); - colorx -= image.Sample(def_sampler, vert_in.t1.xw); - colorx -= B; - colorx -= image.Sample(def_sampler, vert_in.t1.zw); - colorx -= D; - colorx -= F; - colorx -= image.Sample(def_sampler, vert_in.t3.xw); - colorx -= H; - colorx -= image.Sample(def_sampler, vert_in.t3.zw); + color -= image.Sample(def_sampler, vert_in.t1.xw); + color -= B; + color -= image.Sample(def_sampler, vert_in.t1.zw); + color -= D; + color -= F; + color -= image.Sample(def_sampler, vert_in.t3.xw); + color -= H; + color -= image.Sample(def_sampler, vert_in.t3.zw); - colorx = ((E!=F && E!=D) || (E!=B && E!=H)) ? saturate(E + colorx*sharpness) : E; + color = ((E!=F && E!=D) || (E!=B && E!=H)) ? saturate(E + color*sharpness) : E; - return colorx; + return color; } technique Draw diff --git a/plugins/obs-filters/expander-filter.c b/plugins/obs-filters/expander-filter.c new file mode 100644 index 0000000..dc4e821 --- /dev/null +++ b/plugins/obs-filters/expander-filter.c @@ -0,0 +1,419 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* -------------------------------------------------------- */ + +#define do_log(level, format, ...) \ + blog(level, "[expander: '%s'] " format, \ + obs_source_get_name(cd->context), ##__VA_ARGS__) + +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) + +#ifdef _DEBUG +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* -------------------------------------------------------- */ + +#define S_RATIO "ratio" +#define S_THRESHOLD "threshold" +#define S_ATTACK_TIME "attack_time" +#define S_RELEASE_TIME "release_time" +#define S_OUTPUT_GAIN "output_gain" +#define S_DETECTOR "detector" +#define S_PRESETS "presets" + +#define MT_ obs_module_text +#define TEXT_RATIO MT_("expander.Ratio") +#define TEXT_THRESHOLD MT_("expander.Threshold") +#define TEXT_ATTACK_TIME MT_("expander.AttackTime") +#define TEXT_RELEASE_TIME MT_("expander.ReleaseTime") +#define TEXT_OUTPUT_GAIN MT_("expander.OutputGain") +#define TEXT_DETECTOR MT_("expander.Detector") +#define TEXT_PEAK MT_("expander.Peak") +#define TEXT_RMS MT_("expander.RMS") +#define TEXT_NONE MT_("expander.None") +#define TEXT_PRESETS MT_("expander.Presets") +#define TEXT_PRESETS_EXP MT_("expander.Presets.Expander") +#define TEXT_PRESETS_GATE MT_("expander.Presets.Gate") + +#define MIN_RATIO 1.0f +#define MAX_RATIO 20.0f +#define MIN_THRESHOLD_DB -60.0f +#define MAX_THRESHOLD_DB 0.0f +#define MIN_OUTPUT_GAIN_DB -32.0f +#define MAX_OUTPUT_GAIN_DB 32.0f +#define MIN_ATK_RLS_MS 1 +#define MAX_RLS_MS 1000 +#define MAX_ATK_MS 100 +#define DEFAULT_AUDIO_BUF_MS 10 + +#define MS_IN_S 1000 +#define MS_IN_S_F ((float)MS_IN_S) + +/* -------------------------------------------------------- */ + +struct expander_data { + obs_source_t *context; + float *envelope_buf[MAX_AUDIO_CHANNELS]; + size_t envelope_buf_len; + + float ratio; + float threshold; + float attack_gain; + float release_gain; + float output_gain; + + size_t num_channels; + size_t sample_rate; + float envelope[MAX_AUDIO_CHANNELS]; + float slope; + int detector; + float runave[MAX_AUDIO_CHANNELS]; + bool is_gate; + float *runaverage[MAX_AUDIO_CHANNELS]; + size_t runaverage_len; + float *gaindB[MAX_AUDIO_CHANNELS]; + size_t gaindB_len; + float gaindB_buf[MAX_AUDIO_CHANNELS]; + float *env_in; + size_t env_in_len; +}; + +enum { + RMS_DETECT, + RMS_STILLWELL_DETECT, + PEAK_DETECT, + NO_DETECT, +}; +/* -------------------------------------------------------- */ + +static void resize_env_buffer(struct expander_data *cd, size_t len) +{ + cd->envelope_buf_len = len; + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) + cd->envelope_buf[i] = brealloc(cd->envelope_buf[i], + cd->envelope_buf_len * sizeof(float)); +} + +static void resize_runaverage_buffer(struct expander_data *cd, size_t len) +{ + cd->runaverage_len = len; + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) + cd->runaverage[i] = brealloc(cd->runaverage[i], + cd->runaverage_len * sizeof(float)); +} + +static void resize_env_in_buffer(struct expander_data *cd, size_t len) +{ + cd->env_in_len = len; + cd->env_in = brealloc(cd->env_in, cd->env_in_len * sizeof(float)); +} + +static void resize_gaindB_buffer(struct expander_data *cd, size_t len) +{ + cd->gaindB_len = len; + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) + cd->gaindB[i] = brealloc(cd->gaindB[i], + cd->gaindB_len * sizeof(float)); +} + +static inline float gain_coefficient(uint32_t sample_rate, float time) +{ + return expf(-1.0f / (sample_rate * time)); +} + +static const char *expander_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return obs_module_text("Expander"); +} + +static void expander_defaults(obs_data_t *s) +{ + const char *presets = obs_data_get_string(s, S_PRESETS); + bool is_expander_preset = true; + if (strcmp(presets, "gate") == 0) + is_expander_preset = false; + obs_data_set_default_string(s, S_PRESETS, is_expander_preset ? + "expander" : "gate"); + obs_data_set_default_double(s, S_RATIO, is_expander_preset ? + 2.0 : 10.0); + obs_data_set_default_double(s, S_THRESHOLD, -40.0f); + obs_data_set_default_int(s, S_ATTACK_TIME, 10); + obs_data_set_default_int(s, S_RELEASE_TIME, is_expander_preset ? + 50 : 125); + obs_data_set_default_double(s, S_OUTPUT_GAIN, 0.0); + obs_data_set_default_string(s, S_DETECTOR, "RMS"); +} + +static void expander_update(void *data, obs_data_t *s) +{ + struct expander_data *cd = data; + const char *presets = obs_data_get_string(s, S_PRESETS); + if (strcmp(presets, "expander") == 0 && cd->is_gate) { + obs_data_clear(s); + obs_data_set_string(s, S_PRESETS, "expander"); + expander_defaults(s); + cd->is_gate = false; + } + if (strcmp(presets, "gate") == 0 && !cd->is_gate) { + obs_data_clear(s); + obs_data_set_string(s, S_PRESETS, "gate"); + expander_defaults(s); + cd->is_gate = true; + } + + const uint32_t sample_rate = + audio_output_get_sample_rate(obs_get_audio()); + const size_t num_channels = + audio_output_get_channels(obs_get_audio()); + const float attack_time_ms = + (float)obs_data_get_int(s, S_ATTACK_TIME); + const float release_time_ms = + (float)obs_data_get_int(s, S_RELEASE_TIME); + const float output_gain_db = + (float)obs_data_get_double(s, S_OUTPUT_GAIN); + + cd->ratio = (float)obs_data_get_double(s, S_RATIO); + + cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); + cd->attack_gain = gain_coefficient(sample_rate, + attack_time_ms / MS_IN_S_F); + cd->release_gain = gain_coefficient(sample_rate, + release_time_ms / MS_IN_S_F); + cd->output_gain = db_to_mul(output_gain_db); + cd->num_channels = num_channels; + cd->sample_rate = sample_rate; + cd->slope = 1.0f - cd->ratio; + + const char *detect_mode = obs_data_get_string(s, S_DETECTOR); + if (strcmp(detect_mode, "RMS") == 0) + cd->detector = RMS_DETECT; + if (strcmp(detect_mode, "peak") == 0) + cd->detector = PEAK_DETECT; + + size_t sample_len = sample_rate * DEFAULT_AUDIO_BUF_MS / MS_IN_S; + if (cd->envelope_buf_len == 0) + resize_env_buffer(cd, sample_len); + if (cd->runaverage_len == 0) + resize_runaverage_buffer(cd, sample_len); + if (cd->env_in_len == 0) + resize_env_in_buffer(cd, sample_len); + if (cd->gaindB_len == 0) + resize_gaindB_buffer(cd, sample_len); +} + +static void *expander_create(obs_data_t *settings, obs_source_t *filter) +{ + struct expander_data *cd = bzalloc(sizeof(struct expander_data)); + cd->context = filter; + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) { + cd->runave[i] = 0; + cd->envelope[i] = 0; + cd->gaindB_buf[i] = 0; + } + cd->is_gate = false; + const char *presets = obs_data_get_string(settings, S_PRESETS); + if (strcmp(presets, "gate") == 0) + cd->is_gate = true; + + expander_update(cd, settings); + return cd; +} + +static void expander_destroy(void *data) +{ + struct expander_data *cd = data; + + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) { + bfree(cd->envelope_buf[i]); + bfree(cd->runaverage[i]); + bfree(cd->gaindB[i]); + } + bfree(cd->env_in); + bfree(cd); +} + +// detection stage +static void analyze_envelope(struct expander_data *cd, + float **samples, const uint32_t num_samples) +{ + if (cd->envelope_buf_len < num_samples) + resize_env_buffer(cd, num_samples); + if (cd->runaverage_len < num_samples) + resize_runaverage_buffer(cd, num_samples); + if (cd->env_in_len < num_samples) + resize_env_in_buffer(cd, num_samples); + + // 10 ms RMS window + const float rmscoef = exp2f(-100.0f / cd->sample_rate); + + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) { + memset(cd->envelope_buf[i], 0, + num_samples * sizeof(cd->envelope_buf[i][0])); + memset(cd->runaverage[i], 0, + num_samples * sizeof(cd->runaverage[i][0])); + } + memset(cd->env_in, 0, num_samples * sizeof(cd->env_in[0])); + + for (size_t chan = 0; chan < cd->num_channels; ++chan) { + if (!samples[chan]) + continue; + + float *envelope_buf = cd->envelope_buf[chan]; + float *runave = cd->runaverage[chan]; + float *env_in = cd->env_in; + + if (cd->detector == RMS_DETECT) { + runave[0] = rmscoef * cd->runave[chan] + + (1 - rmscoef) * powf(samples[chan][0], 2.0f); + env_in[0] = sqrtf(fmaxf(runave[0], 0)); + for (uint32_t i = 1; i < num_samples; ++i) { + runave[i] = rmscoef * runave[i - 1] + + (1 - rmscoef) * + powf(samples[chan][i], 2.0f); + env_in[i] = sqrtf(runave[i]); + } + } else if (cd->detector == PEAK_DETECT) { + for (uint32_t i = 0; i < num_samples; ++i) { + runave[i] = powf(samples[chan][i], 2); + env_in[i] = fabsf(samples[chan][i]); + } + } + + cd->runave[chan] = runave[num_samples-1]; + for (uint32_t i = 0; i < num_samples; ++i) + envelope_buf[i] = fmaxf(envelope_buf[i], env_in[i]); + cd->envelope[chan] = cd->envelope_buf[chan][num_samples - 1]; + } +} + +// gain stage and ballistics in dB domain +static inline void process_expansion(struct expander_data *cd, + float **samples, uint32_t num_samples) +{ + const float attack_gain = cd->attack_gain; + const float release_gain = cd->release_gain; + + if (cd->gaindB_len < num_samples) + resize_gaindB_buffer(cd, num_samples); + for (int i = 0; i < MAX_AUDIO_CHANNELS; i++) + memset(cd->gaindB[i], 0, num_samples * sizeof(cd->gaindB[i][0])); + + for (size_t chan = 0; chan < cd->num_channels; chan++) { + for (size_t i = 0; i < num_samples; ++i) { + // gain stage of expansion + float env_db = mul_to_db(cd->envelope_buf[chan][i]); + float gain = cd->threshold - env_db > 0.0f ? + fmaxf(cd->slope * + (cd->threshold - env_db), -60.0f) : + 0.0f; + // ballistics (attack/release) + if (i > 0) { + if (gain > cd->gaindB[chan][i - 1]) + cd->gaindB[chan][i] = attack_gain * + cd->gaindB[chan][i - 1] + + (1.0f - attack_gain) * gain; + else + cd->gaindB[chan][i] = release_gain * + cd->gaindB[chan][i - 1] + + (1.0f - release_gain) * gain; + } else { + if (gain > cd->gaindB_buf[chan]) + cd->gaindB[chan][i] = attack_gain * + cd->gaindB_buf[chan] + + (1.0f - attack_gain) * gain; + else + cd->gaindB[chan][i] = release_gain * + cd->gaindB_buf[chan] + + (1.0f - release_gain) * gain; + } + + gain = db_to_mul(fminf(0, cd->gaindB[chan][i])); + if (samples[chan]) + samples[chan][i] *= gain * cd->output_gain; + } + cd->gaindB_buf[chan] = cd->gaindB[chan][num_samples - 1]; + } +} + +static struct obs_audio_data *expander_filter_audio(void *data, + struct obs_audio_data *audio) +{ + struct expander_data *cd = data; + + const uint32_t num_samples = audio->frames; + if (num_samples == 0) + return audio; + + float **samples = (float**)audio->data; + + analyze_envelope(cd, samples, num_samples); + process_expansion(cd, samples, num_samples); + return audio; +} + +static bool presets_changed(obs_properties_t *props, obs_property_t *prop, + obs_data_t *settings) +{ + UNUSED_PARAMETER(props); + UNUSED_PARAMETER(prop); + UNUSED_PARAMETER(settings); + return true; +} + +static obs_properties_t *expander_properties(void *data) +{ + obs_properties_t *props = obs_properties_create(); + + obs_property_t *presets = obs_properties_add_list(props, S_PRESETS, + TEXT_PRESETS, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + obs_property_list_add_string(presets, TEXT_PRESETS_EXP, "expander"); + obs_property_list_add_string(presets, TEXT_PRESETS_GATE, "gate"); + obs_property_set_modified_callback(presets, presets_changed); + obs_properties_add_float_slider(props, S_RATIO, + TEXT_RATIO, MIN_RATIO, MAX_RATIO, 0.1); + obs_properties_add_float_slider(props, S_THRESHOLD, + TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, + 0.1); + obs_properties_add_int_slider(props, S_ATTACK_TIME, + TEXT_ATTACK_TIME, MIN_ATK_RLS_MS, MAX_ATK_MS, 1); + obs_properties_add_int_slider(props, S_RELEASE_TIME, + TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); + obs_properties_add_float_slider(props, S_OUTPUT_GAIN, + TEXT_OUTPUT_GAIN, MIN_OUTPUT_GAIN_DB, + MAX_OUTPUT_GAIN_DB, 0.1); + obs_property_t *detect = obs_properties_add_list(props, S_DETECTOR, + TEXT_DETECTOR, OBS_COMBO_TYPE_LIST, + OBS_COMBO_FORMAT_STRING); + obs_property_list_add_string(detect, TEXT_RMS, "RMS"); + obs_property_list_add_string(detect, TEXT_PEAK, "peak"); + + UNUSED_PARAMETER(data); + return props; +} + +struct obs_source_info expander_filter = { + .id = "expander_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_AUDIO, + .get_name = expander_name, + .create = expander_create, + .destroy = expander_destroy, + .update = expander_update, + .filter_audio = expander_filter_audio, + .get_defaults = expander_defaults, + .get_properties = expander_properties, +}; diff --git a/plugins/obs-filters/invert-audio-polarity.c b/plugins/obs-filters/invert-audio-polarity.c new file mode 100644 index 0000000..8c63508 --- /dev/null +++ b/plugins/obs-filters/invert-audio-polarity.c @@ -0,0 +1,49 @@ +#include + +static const char *invert_polarity_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return obs_module_text("InvertPolarity"); +} + +static void invert_polarity_destroy(void *data) +{ + UNUSED_PARAMETER(data); +} + +static void *invert_polarity_create(obs_data_t *settings, obs_source_t *filter) +{ + UNUSED_PARAMETER(settings); + return filter; +} + +static struct obs_audio_data *invert_polarity_filter_audio(void *unused, + struct obs_audio_data *audio) +{ + float **adata = (float**)audio->data; + + for (size_t c = 0; c < MAX_AV_PLANES; c++) { + register float *channel_data = adata[c]; + register float *channel_end = channel_data + audio->frames; + + if (!channel_data) + break; + + while (channel_data < channel_end) { + *(channel_data++) *= -1.0f; + } + } + + UNUSED_PARAMETER(unused); + return audio; +} + +struct obs_source_info invert_polarity_filter = { + .id = "invert_polarity_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_AUDIO, + .get_name = invert_polarity_name, + .create = invert_polarity_create, + .destroy = invert_polarity_destroy, + .filter_audio = invert_polarity_filter_audio, +}; diff --git a/plugins/obs-filters/limiter-filter.c b/plugins/obs-filters/limiter-filter.c new file mode 100644 index 0000000..c6bc139 --- /dev/null +++ b/plugins/obs-filters/limiter-filter.c @@ -0,0 +1,215 @@ +#include +#include +#include + +#include +#include +#include + +/* -------------------------------------------------------- */ + +#define do_log(level, format, ...) \ + blog(level, "[limiter: '%s'] " format, \ + obs_source_get_name(cd->context), ##__VA_ARGS__) + +#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__) +#define info(format, ...) do_log(LOG_INFO, format, ##__VA_ARGS__) + +#ifdef _DEBUG +#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__) +#else +#define debug(format, ...) +#endif + +/* -------------------------------------------------------- */ + +#define S_THRESHOLD "threshold" +#define S_RELEASE_TIME "release_time" + +#define MT_ obs_module_text +#define TEXT_THRESHOLD MT_("Limiter.Threshold") +#define TEXT_RELEASE_TIME MT_("Limiter.ReleaseTime") + +#define MIN_THRESHOLD_DB -60.0 +#define MAX_THRESHOLD_DB 0.0f +#define MIN_ATK_RLS_MS 1 +#define MAX_RLS_MS 1000 +#define DEFAULT_AUDIO_BUF_MS 10 +#define ATK_TIME 0.001f +#define MS_IN_S 1000 +#define MS_IN_S_F ((float)MS_IN_S) + +/* -------------------------------------------------------- */ + +struct limiter_data { + obs_source_t *context; + float *envelope_buf; + size_t envelope_buf_len; + + float threshold; + float attack_gain; + float release_gain; + float output_gain; + + size_t num_channels; + size_t sample_rate; + float envelope; + float slope; +}; + +/* -------------------------------------------------------- */ + +static void resize_env_buffer(struct limiter_data *cd, size_t len) +{ + cd->envelope_buf_len = len; + cd->envelope_buf = brealloc(cd->envelope_buf, len * sizeof(float)); +} + +static inline float gain_coefficient(uint32_t sample_rate, float time) +{ + return (float)exp(-1.0f / (sample_rate * time)); +} + +static const char *limiter_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return obs_module_text("Limiter"); +} + +static void limiter_update(void *data, obs_data_t *s) +{ + struct limiter_data *cd = data; + + const uint32_t sample_rate = + audio_output_get_sample_rate(obs_get_audio()); + const size_t num_channels = + audio_output_get_channels(obs_get_audio()); + float attack_time_ms = ATK_TIME; + + const float release_time_ms = + (float)obs_data_get_int(s, S_RELEASE_TIME); + const float output_gain_db = 0; + + cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); + + cd->attack_gain = gain_coefficient(sample_rate, + attack_time_ms / MS_IN_S_F); + cd->release_gain = gain_coefficient(sample_rate, + release_time_ms / MS_IN_S_F); + cd->output_gain = db_to_mul(output_gain_db); + cd->num_channels = num_channels; + cd->sample_rate = sample_rate; + cd->slope = 1.0f; + + size_t sample_len = sample_rate * DEFAULT_AUDIO_BUF_MS / MS_IN_S; + if (cd->envelope_buf_len == 0) + resize_env_buffer(cd, sample_len); +} + +static void *limiter_create(obs_data_t *settings, obs_source_t *filter) +{ + struct limiter_data *cd = bzalloc(sizeof(struct limiter_data)); + cd->context = filter; + + limiter_update(cd, settings); + return cd; +} + +static void limiter_destroy(void *data) +{ + struct limiter_data *cd = data; + + bfree(cd->envelope_buf); + bfree(cd); +} + +static void analyze_envelope(struct limiter_data *cd, + float **samples, const uint32_t num_samples) +{ + if (cd->envelope_buf_len < num_samples) { + resize_env_buffer(cd, num_samples); + } + + const float attack_gain = cd->attack_gain; + const float release_gain = cd->release_gain; + + memset(cd->envelope_buf, 0, num_samples * sizeof(cd->envelope_buf[0])); + for (size_t chan = 0; chan < cd->num_channels; ++chan) { + if (!samples[chan]) + continue; + + float *envelope_buf = cd->envelope_buf; + float env = cd->envelope; + for (uint32_t i = 0; i < num_samples; ++i) { + const float env_in = fabsf(samples[chan][i]); + if (env < env_in) { + env = env_in + attack_gain * (env - env_in); + } else { + env = env_in + release_gain * (env - env_in); + } + envelope_buf[i] = fmaxf(envelope_buf[i], env); + } + } + cd->envelope = cd->envelope_buf[num_samples - 1]; +} + +static inline void process_compression(const struct limiter_data *cd, + float **samples, uint32_t num_samples) +{ + for (size_t i = 0; i < num_samples; ++i) { + const float env_db = mul_to_db(cd->envelope_buf[i]); + float gain = cd->slope * (cd->threshold - env_db); + gain = db_to_mul(fminf(0, gain)); + + for (size_t c = 0; c < cd->num_channels; ++c) { + if (samples[c]) { + samples[c][i] *= gain * cd->output_gain; + } + } + } +} + +static struct obs_audio_data *limiter_filter_audio(void *data, + struct obs_audio_data *audio) +{ + struct limiter_data *cd = data; + + const uint32_t num_samples = audio->frames; + if (num_samples == 0) + return audio; + + float **samples = (float**)audio->data; + analyze_envelope(cd, samples, num_samples); + process_compression(cd, samples, num_samples); + return audio; +} + +static void limiter_defaults(obs_data_t *s) +{ + obs_data_set_default_double(s, S_THRESHOLD, -6.0f); + obs_data_set_default_int(s, S_RELEASE_TIME, 60); +} + +static obs_properties_t *limiter_properties(void *data) +{ + obs_properties_t *props = obs_properties_create(); + + obs_properties_add_float_slider(props, S_THRESHOLD, TEXT_THRESHOLD, MIN_THRESHOLD_DB, MAX_THRESHOLD_DB, 0.1); + obs_properties_add_int_slider(props, S_RELEASE_TIME, TEXT_RELEASE_TIME, MIN_ATK_RLS_MS, MAX_RLS_MS, 1); + + UNUSED_PARAMETER(data); + return props; +} + +struct obs_source_info limiter_filter = { + .id = "limiter_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_AUDIO, + .get_name = limiter_name, + .create = limiter_create, + .destroy = limiter_destroy, + .update = limiter_update, + .filter_audio = limiter_filter_audio, + .get_defaults = limiter_defaults, + .get_properties = limiter_properties, +}; diff --git a/plugins/obs-filters/luma-key-filter.c b/plugins/obs-filters/luma-key-filter.c new file mode 100644 index 0000000..b738a1c --- /dev/null +++ b/plugins/obs-filters/luma-key-filter.c @@ -0,0 +1,153 @@ +#include + +#define SETTING_LUMA_MAX "luma_max" +#define SETTING_LUMA_MIN "luma_min" +#define SETTING_LUMA_MAX_SMOOTH "luma_max_smooth" +#define SETTING_LUMA_MIN_SMOOTH "luma_min_smooth" + +#define TEXT_LUMA_MAX obs_module_text("Luma.LumaMax") +#define TEXT_LUMA_MIN obs_module_text("Luma.LumaMin") +#define TEXT_LUMA_MAX_SMOOTH obs_module_text("Luma.LumaMaxSmooth") +#define TEXT_LUMA_MIN_SMOOTH obs_module_text("Luma.LumaMinSmooth") + +struct luma_key_filter_data { + obs_source_t *context; + + gs_effect_t *effect; + + gs_eparam_t *luma_max_param; + gs_eparam_t *luma_min_param; + gs_eparam_t *luma_max_smooth_param; + gs_eparam_t *luma_min_smooth_param; + + float luma_max; + float luma_min; + float luma_max_smooth; + float luma_min_smooth; +}; + +static const char *luma_key_name(void *unused) +{ + UNUSED_PARAMETER(unused); + return obs_module_text("LumaKeyFilter"); +} + +static void luma_key_update(void *data, obs_data_t *settings) +{ + struct luma_key_filter_data *filter = data; + + double lumaMax = obs_data_get_double(settings, SETTING_LUMA_MAX); + double lumaMin = obs_data_get_double(settings, SETTING_LUMA_MIN); + double lumaMaxSmooth = obs_data_get_double(settings, SETTING_LUMA_MAX_SMOOTH); + double lumaMinSmooth = obs_data_get_double(settings, SETTING_LUMA_MIN_SMOOTH); + + filter->luma_max = (float)lumaMax; + filter->luma_min = (float)lumaMin; + filter->luma_max_smooth = (float)lumaMaxSmooth; + filter->luma_min_smooth = (float)lumaMinSmooth; +} + +static void luma_key_destroy(void *data) +{ + struct luma_key_filter_data *filter = data; + + if (filter->effect) { + obs_enter_graphics(); + gs_effect_destroy(filter->effect); + obs_leave_graphics(); + } + + bfree(data); +} + +static void *luma_key_create(obs_data_t *settings, obs_source_t *context) +{ + struct luma_key_filter_data *filter = + bzalloc(sizeof(struct luma_key_filter_data)); + char *effect_path = obs_module_file("luma_key_filter.effect"); + + filter->context = context; + + obs_enter_graphics(); + + filter->effect = gs_effect_create_from_file(effect_path, NULL); + if (filter->effect) { + filter->luma_max_param = gs_effect_get_param_by_name( + filter->effect, "lumaMax"); + filter->luma_min_param = gs_effect_get_param_by_name( + filter->effect, "lumaMin"); + filter->luma_max_smooth_param = gs_effect_get_param_by_name( + filter->effect, "lumaMaxSmooth"); + filter->luma_min_smooth_param = gs_effect_get_param_by_name( + filter->effect, "lumaMinSmooth"); + } + + obs_leave_graphics(); + + bfree(effect_path); + + if (!filter->effect) { + luma_key_destroy(filter); + return NULL; + } + + luma_key_update(filter, settings); + return filter; +} + +static void luma_key_render(void *data, gs_effect_t *effect) +{ + struct luma_key_filter_data *filter = data; + + if (!obs_source_process_filter_begin(filter->context, GS_RGBA, + OBS_ALLOW_DIRECT_RENDERING)) + return; + + gs_effect_set_float(filter->luma_max_param, filter->luma_max); + gs_effect_set_float(filter->luma_min_param, filter->luma_min); + gs_effect_set_float(filter->luma_max_smooth_param, filter->luma_max_smooth); + gs_effect_set_float(filter->luma_min_smooth_param, filter->luma_min_smooth); + + obs_source_process_filter_end(filter->context, filter->effect, 0, 0); + + UNUSED_PARAMETER(effect); +} + +static obs_properties_t *luma_key_properties(void *data) +{ + obs_properties_t *props = obs_properties_create(); + + obs_properties_add_float_slider(props, SETTING_LUMA_MAX, + TEXT_LUMA_MAX, 0, 1, 0.01); + obs_properties_add_float_slider(props, SETTING_LUMA_MAX_SMOOTH, + TEXT_LUMA_MAX_SMOOTH, 0, 1, 0.01); + obs_properties_add_float_slider(props, SETTING_LUMA_MIN, + TEXT_LUMA_MIN, 0, 1, 0.01); + obs_properties_add_float_slider(props, SETTING_LUMA_MIN_SMOOTH, + TEXT_LUMA_MIN_SMOOTH, 0, 1, 0.01); + + UNUSED_PARAMETER(data); + return props; +} + +static void luma_key_defaults(obs_data_t *settings) +{ + obs_data_set_default_double(settings, SETTING_LUMA_MAX, 1.0); + obs_data_set_default_double(settings, SETTING_LUMA_MIN, 0.0); + obs_data_set_default_double(settings, SETTING_LUMA_MAX_SMOOTH, 0.0); + obs_data_set_default_double(settings, SETTING_LUMA_MIN_SMOOTH, 0.0); +} + + +struct obs_source_info luma_key_filter = { + .id = "luma_key_filter", + .type = OBS_SOURCE_TYPE_FILTER, + .output_flags = OBS_SOURCE_VIDEO, + .get_name = luma_key_name, + .create = luma_key_create, + .destroy = luma_key_destroy, + .video_render = luma_key_render, + .update = luma_key_update, + .get_properties = luma_key_properties, + .get_defaults = luma_key_defaults +}; diff --git a/plugins/obs-filters/mask-filter.c b/plugins/obs-filters/mask-filter.c index ae6e5d1..d832232 100644 --- a/plugins/obs-filters/mask-filter.c +++ b/plugins/obs-filters/mask-filter.c @@ -46,6 +46,7 @@ static void mask_filter_update(void *data, obs_data_t *settings) int opacity = (int)obs_data_get_int(settings, SETTING_OPACITY); char *effect_path; + color &= 0xFFFFFF; color |= (uint32_t)(((double)opacity) * 2.55) << 24; vec4_from_rgba(&filter->color, color); @@ -115,7 +116,8 @@ static obs_properties_t *mask_filter_properties(void *data) obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH, OBS_PATH_FILE, filter_str.array, NULL); obs_properties_add_color(props, SETTING_COLOR, TEXT_COLOR); - obs_properties_add_int(props, SETTING_OPACITY, TEXT_OPACITY, 0, 100, 1); + obs_properties_add_int_slider(props, SETTING_OPACITY, TEXT_OPACITY, + 0, 100, 1); obs_properties_add_bool(props, SETTING_STRETCH, TEXT_STRETCH); dstr_free(&filter_str); diff --git a/plugins/obs-filters/obs-filters.c b/plugins/obs-filters/obs-filters.c index 02ac63d..c60e6ee 100644 --- a/plugins/obs-filters/obs-filters.c +++ b/plugins/obs-filters/obs-filters.c @@ -2,8 +2,11 @@ #include "obs-filters-config.h" OBS_DECLARE_MODULE() - OBS_MODULE_USE_DEFAULT_LOCALE("obs-filters", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "OBS core filters"; +} extern struct obs_source_info mask_filter; extern struct obs_source_info crop_filter; @@ -20,8 +23,12 @@ extern struct obs_source_info async_delay_filter; #if SPEEXDSP_ENABLED extern struct obs_source_info noise_suppress_filter; #endif +extern struct obs_source_info invert_polarity_filter; extern struct obs_source_info noise_gate_filter; extern struct obs_source_info compressor_filter; +extern struct obs_source_info limiter_filter; +extern struct obs_source_info expander_filter; +extern struct obs_source_info luma_key_filter; bool obs_module_load(void) { @@ -40,7 +47,11 @@ bool obs_module_load(void) #if SPEEXDSP_ENABLED obs_register_source(&noise_suppress_filter); #endif + obs_register_source(&invert_polarity_filter); obs_register_source(&noise_gate_filter); obs_register_source(&compressor_filter); + obs_register_source(&limiter_filter); + obs_register_source(&expander_filter); + obs_register_source(&luma_key_filter); return true; } diff --git a/plugins/obs-filters/scale-filter.c b/plugins/obs-filters/scale-filter.c index 3a1cfef..c4c4022 100644 --- a/plugins/obs-filters/scale-filter.c +++ b/plugins/obs-filters/scale-filter.c @@ -17,12 +17,15 @@ #define T_SAMPLING_BILINEAR obs_module_text("ScaleFiltering.Bilinear") #define T_SAMPLING_BICUBIC obs_module_text("ScaleFiltering.Bicubic") #define T_SAMPLING_LANCZOS obs_module_text("ScaleFiltering.Lanczos") +#define T_SAMPLING_AREA obs_module_text("ScaleFiltering.Area") #define T_UNDISTORT obs_module_text("UndistortCenter") +#define T_BASE obs_module_text("Base.Canvas") #define S_SAMPLING_POINT "point" #define S_SAMPLING_BILINEAR "bilinear" #define S_SAMPLING_BICUBIC "bicubic" #define S_SAMPLING_LANCZOS "lanczos" +#define S_SAMPLING_AREA "area" struct scale_filter_data { obs_source_t *context; @@ -42,6 +45,7 @@ struct scale_filter_data { bool target_valid; bool valid; bool undistort; + bool base_canvas_resolution; }; static const char *scale_filter_name(void *unused) @@ -59,18 +63,29 @@ static void scale_filter_update(void *data, obs_data_t *settings) const char *sampling = obs_data_get_string(settings, S_SAMPLING); filter->valid = true; + filter->base_canvas_resolution = false; - ret = sscanf(res_str, "%dx%d", &filter->cx_in, &filter->cy_in); - if (ret == 2) { + if (strcmp(res_str, T_BASE) == 0) { + struct obs_video_info ovi; + obs_get_video_info(&ovi); filter->aspect_ratio_only = false; + filter->base_canvas_resolution = true; + filter->cx_in = ovi.base_width; + filter->cy_in = ovi.base_height; } else { - ret = sscanf(res_str, "%d:%d", &filter->cx_in, &filter->cy_in); - if (ret != 2) { - filter->valid = false; - return; - } + ret = sscanf(res_str, "%dx%d", &filter->cx_in, &filter->cy_in); + if (ret == 2) { + filter->aspect_ratio_only = false; + } else { + ret = sscanf(res_str, "%d:%d", &filter->cx_in, + &filter->cy_in); + if (ret != 2) { + filter->valid = false; + return; + } - filter->aspect_ratio_only = true; + filter->aspect_ratio_only = true; + } } if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) { @@ -82,6 +97,9 @@ static void scale_filter_update(void *data, obs_data_t *settings) } else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) { filter->sampling = OBS_SCALE_LANCZOS; + } else if (astrcmpi(sampling, S_SAMPLING_AREA) == 0) { + filter->sampling = OBS_SCALE_AREA; + } else { /* S_SAMPLING_BICUBIC */ filter->sampling = OBS_SCALE_BICUBIC; } @@ -126,6 +144,13 @@ static void scale_filter_tick(void *data, float seconds) int cx; int cy; + if (filter->base_canvas_resolution) { + struct obs_video_info ovi; + obs_get_video_info(&ovi); + filter->cx_in = ovi.base_width; + filter->cy_in = ovi.base_height; + } + target = obs_filter_get_target(filter->context); filter->cx_out = 0; filter->cy_out = 0; @@ -198,6 +223,7 @@ static void scale_filter_tick(void *data, float seconds) case OBS_SCALE_BILINEAR: type = OBS_EFFECT_DEFAULT; break; case OBS_SCALE_BICUBIC: type = OBS_EFFECT_BICUBIC; break; case OBS_SCALE_LANCZOS: type = OBS_EFFECT_LANCZOS; break; + case OBS_SCALE_AREA: type = OBS_EFFECT_AREA; break; } } @@ -289,15 +315,15 @@ static bool sampling_modified(obs_properties_t *props, obs_property_t *p, bool has_undistort; if (astrcmpi(sampling, S_SAMPLING_POINT) == 0) { has_undistort = false; - } else if (astrcmpi(sampling, S_SAMPLING_BILINEAR) == 0) { has_undistort = false; - } else if (astrcmpi(sampling, S_SAMPLING_LANCZOS) == 0) { has_undistort = true; - + } + else if (astrcmpi(sampling, S_SAMPLING_AREA) == 0) { + has_undistort = false; } else { /* S_SAMPLING_BICUBIC */ has_undistort = true; @@ -340,6 +366,7 @@ static obs_properties_t *scale_filter_properties(void *data) obs_property_list_add_string(p, T_SAMPLING_BILINEAR, S_SAMPLING_BILINEAR); obs_property_list_add_string(p, T_SAMPLING_BICUBIC, S_SAMPLING_BICUBIC); obs_property_list_add_string(p, T_SAMPLING_LANCZOS, S_SAMPLING_LANCZOS); + obs_property_list_add_string(p, T_SAMPLING_AREA, S_SAMPLING_AREA); /* ----------------- */ @@ -347,6 +374,7 @@ static obs_properties_t *scale_filter_properties(void *data) OBS_COMBO_TYPE_EDITABLE, OBS_COMBO_FORMAT_STRING); obs_property_list_add_string(p, T_NONE, T_NONE); + obs_property_list_add_string(p, T_BASE, T_BASE); for (size_t i = 0; i < NUM_ASPECTS; i++) obs_property_list_add_string(p, aspects[i], aspects[i]); diff --git a/plugins/obs-libfdk/data/locale/da-DK.ini b/plugins/obs-libfdk/data/locale/da-DK.ini index 7ad6ce7..d136485 100644 --- a/plugins/obs-libfdk/data/locale/da-DK.ini +++ b/plugins/obs-libfdk/data/locale/da-DK.ini @@ -1,4 +1,4 @@ LibFDK="libfdk AAC Encoder" -Bitrate="Bitrate" -Afterburner="Aktivere AAC Afterburner" +Bitrate="Bit-hastighed" +Afterburner="Aktivér AAC Afterburner" diff --git a/plugins/obs-libfdk/data/locale/de-DE.ini b/plugins/obs-libfdk/data/locale/de-DE.ini index 3ae777b..6092b11 100644 --- a/plugins/obs-libfdk/data/locale/de-DE.ini +++ b/plugins/obs-libfdk/data/locale/de-DE.ini @@ -1,4 +1,4 @@ -LibFDK="libfdk AAC Codierer" +LibFDK="libfdk-AAC-Kodierer" Bitrate="Bitrate" -Afterburner="AAC Afterburner aktivieren" +Afterburner="AAC-Afterburner aktivieren" diff --git a/plugins/obs-libfdk/data/locale/fr-FR.ini b/plugins/obs-libfdk/data/locale/fr-FR.ini index 494658a..ab1ab31 100644 --- a/plugins/obs-libfdk/data/locale/fr-FR.ini +++ b/plugins/obs-libfdk/data/locale/fr-FR.ini @@ -1,4 +1,4 @@ LibFDK="Encodeur AAC libfdk" Bitrate="Débit" -Afterburner="Activer \"AAC Afterburner\"" +Afterburner="Activer l'Afterburner" diff --git a/plugins/obs-libfdk/data/locale/it-IT.ini b/plugins/obs-libfdk/data/locale/it-IT.ini index f1dff2b..a78d865 100644 --- a/plugins/obs-libfdk/data/locale/it-IT.ini +++ b/plugins/obs-libfdk/data/locale/it-IT.ini @@ -1,4 +1,4 @@ -LibFDK="Libfdk codificatore AAC" -Bitrate="Bitrate" -Afterburner="Abilita AAC Afterburner" +LibFDK="Codifica libfdk AAC" +Bitrate="Velocità in bit" +Afterburner="Attiva AAC Afterburner" diff --git a/plugins/obs-libfdk/obs-libfdk.c b/plugins/obs-libfdk/obs-libfdk.c index d6eb496..94b139d 100644 --- a/plugins/obs-libfdk/obs-libfdk.c +++ b/plugins/obs-libfdk/obs-libfdk.c @@ -9,7 +9,6 @@ #include - static const char *libfdk_get_error(AACENC_ERROR err) { switch(err) { @@ -224,7 +223,7 @@ static bool libfdk_encode(void *data, struct encoder_frame *frame, void *in_ptr; void *out_ptr; AACENC_ERROR err; - + int64_t encoderDelay; in_ptr = frame->data[0]; in_size = enc->frame_size_bytes; @@ -261,10 +260,13 @@ static bool libfdk_encode(void *data, struct encoder_frame *frame, } *received_packet = true; - - packet->pts = enc->total_samples - - enc->info.encoderDelay; // TODO: Just a guess, find out if that's actualy right - packet->dts = enc->total_samples - enc->info.encoderDelay; +#if (AACENCODER_LIB_VL0 >= 4) + encoderDelay= enc->info.nDelay; +#else + encoderDelay= enc->info.encoderDelay; +#endif + packet->pts = enc->total_samples - encoderDelay; + packet->dts = enc->total_samples - encoderDelay; packet->data = enc->packet_buffer; packet->size = out_args.numOutBytes; packet->type = OBS_ENCODER_AUDIO; diff --git a/plugins/obs-outputs/data/locale/bg-BG.ini b/plugins/obs-outputs/data/locale/bg-BG.ini new file mode 100644 index 0000000..888d99a --- /dev/null +++ b/plugins/obs-outputs/data/locale/bg-BG.ini @@ -0,0 +1,11 @@ +RTMPStream="RTMP поток" +RTMPStream.DropThreshold="Нисък праг (милисекунди)" +FLVOutput="Изходен файл FLV" +FLVOutput.FilePath="Път до файла" +Default="По подразбиране" + +ConnectionTimedOut="Връзката се разпадна. Уверете се, че сте настроили правилно услугата за излъчване и че връзката не е блокирана от защитна стена." +PermissionDenied="Връзката беше блокирана. Проверете Вашата защитна стена и/или антивирусна програма и се уверете, че OBS Studio има пълен достъп до интернет." +ConnectionAborted="Връзката беше прекратена. Това обикновено посочва за проблеми с интернет връзката до услугата за излъчване." +SSLCertVerifyFailed="RTMP сървърът изпрати неправилен SSL сертификат." + diff --git a/plugins/obs-outputs/data/locale/ca-ES.ini b/plugins/obs-outputs/data/locale/ca-ES.ini index 1471d15..5e942e9 100644 --- a/plugins/obs-outputs/data/locale/ca-ES.ini +++ b/plugins/obs-outputs/data/locale/ca-ES.ini @@ -9,7 +9,7 @@ PermissionDenied="La connexió ha estat bloquejada. Comproveu la configuració d ConnectionAborted="La connexió ha estat avortada. Normalment això indica que hi ha problemes de connexió entre el vostre equip i el servei de transmissió." ConnectionReset="La connexió s'ha acabat. Normalment això indica que hi ha problemes de connexió entre el vostre equip i el servei de transmissió." HostNotFound="Nom d'amfitrió no trobat. Assegureu-vos que hi hagi configurat un servidor de transmissió vàlid i que la seva connexió a Internet / DNS estiguin funcionant correctament." -NoData="Nom d'amfitrió trobat, però no hi ha dades del tipus sol·licitat. Això pot passar si heu enllaçat a una adreça IPv6 i el seu servei de transmissió només té adreces IPv4 (veure configuració / avançada)." -AddressNotAvailable="Direcció no disponible. Potser heu intentat enllaçar amb una adreça IP no vàlida (veure configuració / avançada)." +NoData="S'ha trobat el nom d'amfitrió, però no hi ha dades del tipus sol·licitat. Això pot passar si heu enllaçat a una adreça IPv6 i el seu servei de transmissió només té adreces IPv4 (veieu configuració → avançada)." +AddressNotAvailable="Adreça no disponible. Potser heu intentat enllaçar amb una adreça IP no vàlida (veieu configuració → avançada)." SSLCertVerifyFailed="El servidor RTMP ha enviat un certificat SSL no vàlid." diff --git a/plugins/obs-outputs/data/locale/cs-CZ.ini b/plugins/obs-outputs/data/locale/cs-CZ.ini index e48340d..731e9eb 100644 --- a/plugins/obs-outputs/data/locale/cs-CZ.ini +++ b/plugins/obs-outputs/data/locale/cs-CZ.ini @@ -9,7 +9,7 @@ PermissionDenied="Připojení bylo zablokováno. Zkontrolujte, zda má OBS povol ConnectionAborted="Připojení bylo přerušeno. Toto obvykle znamená, že nastaly problémy s připojením mezi vámi a vysílací službou." ConnectionReset="Připojení bylo resetováno druhou stranou. Toto obvykle znamená, že nastaly problémy s připojením mezi vámi a vysílací službou." HostNotFound="Hostitel nebyl nalezen. Zkontrolujte, zda jste zadali správný vysílací server a že vaše připojení k internetu / DNS funguje jak má." -NoData="Hostitel byl nalezen, ale žádná data požadovaného typu. Toto se může stát, pokud používáte IPv6 adresu, ale vaše vysílací služba podporuje pouze připojení přes svou IPv4 adresu (viz. Nastavení / Rozšířené)." -AddressNotAvailable="Adresa není k dispozici. Možná jste se snažili použít chybnou IP adresu (viz. Nastavení / Rozšířené)." +NoData="Hostitel byl nalezen, ale žádná data požadovaného typu. Toto se může stát, pokud používáte IPv6 adresu, ale vaše vysílací služba podporuje pouze připojení přes svou IPv4 adresu (viz. Nastavení → Rozšířené)." +AddressNotAvailable="Adresa není k dispozici. Možná jste se snažili použít chybnou IP adresu (viz. Nastavení → Rozšířené)." SSLCertVerifyFailed="RTMP server odeslal neplatný SSL certifikát." diff --git a/plugins/obs-outputs/data/locale/da-DK.ini b/plugins/obs-outputs/data/locale/da-DK.ini index eb3f973..6dafcbd 100644 --- a/plugins/obs-outputs/data/locale/da-DK.ini +++ b/plugins/obs-outputs/data/locale/da-DK.ini @@ -1,15 +1,15 @@ RTMPStream="RTMP Strøm" -RTMPStream.DropThreshold="Tabstærskel (millisekunder)" -FLVOutput="FLV File Output" +RTMPStream.DropThreshold="Drop-tærskel (millisek.)" +FLVOutput="FLV-fil output" FLVOutput.FilePath="Filsti" Default="Standard" -ConnectionTimedOut="Forbindelsen fik timeout. Tjek venligst at du har opsat en gyldig streaming-tjeneste og at ingen firewall blokerer forbindelsen." -PermissionDenied="Forbindelsen blev blokeret. Tjek venligst indstillingerne for firewall/antivirus for at sikre, at OBS har fuld adgang til Internet." -ConnectionAborted="Forbindelsen blev afbrudt. Dette indikerer typisk et problem med Internetforbindelsen mellem dig og streaming-tjenesten." -ConnectionReset="Forbindelsen blev afbrudt. Dette indikerer typisk et problem med Internetforbindelsen mellem dig og streaming-tjenesten." -HostNotFound="Værtsnavn ikke fundet. Tjek at du har angivet en gyldig streaming-server, og at din Internetforbindelse/DNS fungerer korrekt." -NoData="Værtsnavn fundet, men ingen data af den ønskede type. Dette kan forekomme, hvis du har tildelt en IPv6-adresse, og din streaming-tjeneste kun benytter IPv4-adresser (se Indstillinger/Avanceret)." -AddressNotAvailable="Adresse utilgængelig. Du kan have forsøgt at tildele en ugyldig IP-adresse (se Indstillinger/Avanceret)." +ConnectionTimedOut="Forbindelsen fik timeout. Tjek, at du har opsat en gyldig streamingtjeneste samt at ingen firewall blokerer forbindelsen." +PermissionDenied="Forbindelsen blev blokeret. Tjek indstillingerne for firewall/antivirus for at sikre, at OBS har fuld Internetadgang." +ConnectionAborted="Forbindelsen blev afbrudt. Dette indikerer typisk et problem med Internetforbindelsen mellem dig og streamingtjenesten." +ConnectionReset="Forbindelsen afbrudt af modpart. Dette indikerer typisk et problem med Internetforbindelsen mellem dig og streamingtjenesten." +HostNotFound="Værtsnavn ikke fundet. Tjek, at du har angivet en gyldig streamingserver, samt at din Internetforbindelse/DNS fungerer korrekt." +NoData="Værtsnavn fundet, men ingen data af den forespurgte type. Kan f.eks. forekomme ved en tilknyttet IPv6-adresse ifm. en streamingtjeneste, der alene benytter IPv4-adresser (se Indstillinger → Avanceret)." +AddressNotAvailable="Adresse utilgængelig. En ugyldig IP-adresse kan være forsøgt tilknyttet (se Indstillinger → Avanceret)." SSLCertVerifyFailed="RTMP-serveren har sendt et ugyldig SSL-certifikat." diff --git a/plugins/obs-outputs/data/locale/de-DE.ini b/plugins/obs-outputs/data/locale/de-DE.ini index 031a6c0..e332a7a 100644 --- a/plugins/obs-outputs/data/locale/de-DE.ini +++ b/plugins/obs-outputs/data/locale/de-DE.ini @@ -1,15 +1,15 @@ -RTMPStream="RTMP Stream" -RTMPStream.DropThreshold="Drop Threshold (Millisekunden)" -FLVOutput="FLV Dateiausgabe" +RTMPStream="RTMP-Stream" +RTMPStream.DropThreshold="Drop-Threshold (Millisekunden)" +FLVOutput="FLV-Dateiausgabe" FLVOutput.FilePath="Dateipfad" Default="Standard" -ConnectionTimedOut="Zeitüberschreitung bei der Verbindung. Stellen Sie sicher, dass Sie einen gültigen Streaming-Service konfiguriert haben und keine Firewall die Verbindung blockiert." +ConnectionTimedOut="Zeitüberschreitung bei der Verbindung. Stellen Sie sicher, dass Sie einen gültigen Streamingdienst konfiguriert haben und keine Firewall die Verbindung blockiert." PermissionDenied="Die Verbindung wurde blockiert. Überprüfen Sie Ihre Firewall / Anti-Virus-Einstellungen, um sicherzustellen, dass OBS vollen Internetzugang hat." -ConnectionAborted="Die Verbindung wurde abgebrochen. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streaming-Dienst." -ConnectionReset="Die Verbindung wurde durch Kommunikationspartner zurückgesetzt. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streaming-Dienst." -HostNotFound="Hostname nicht gefunden. Stellen Sie sicher, dass Sie einen gültigen Streaming-Server eingegeben haben und Ihre Internetverbindung / DNS korrekt arbeiten." -NoData="Hostname gefunden, aber keine Daten des angeforderten Typs. Dies kann auftreten, wenn Sie eine IPv6-Adresse verwenden und Ihr Streaming-Dienst nur über IPv4-Adressen verfügt (siehe Einstellungen / Erweitert)." -AddressNotAvailable="Adresse nicht Verfügbar. Sie haben möglicherweise versucht, eine ungültige IP-Adresse zu verwenden (siehe Einstellungen / Erweitert)." +ConnectionAborted="Die Verbindung wurde abgebrochen. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst." +ConnectionReset="Die Verbindung wurde durch Kommunikationspartner zurückgesetzt. Dies bedeutet in der Regel Probleme mit der Internetverbindung zwischen Ihnen und dem Streamingdienst." +HostNotFound="Hostname nicht gefunden. Stellen Sie sicher, dass Sie einen gültigen Streamingserver eingegeben haben und Ihre Internetverbindung/DNS korrekt arbeiten." +NoData="Hostname gefunden, aber keine Daten des angeforderten Typs vorhanden. Dies kann auftreten, wenn Sie eine IPv6-Adresse verwenden, aber Ihr Streamingdienst nur über IPv4-Adressen verfügt (siehe Einstellungen → Erweitert)." +AddressNotAvailable="Adresse nicht verfügbar. Sie haben möglicherweise eine ungültige IP-Adresse versucht zu verwenden (siehe Einstellungen → Erweitert)." SSLCertVerifyFailed="Der RTMP-Server hat ein ungültiges SSL-Zertifikat gesendet." diff --git a/plugins/obs-outputs/data/locale/el-GR.ini b/plugins/obs-outputs/data/locale/el-GR.ini index 3b8cb12..621bd41 100644 --- a/plugins/obs-outputs/data/locale/el-GR.ini +++ b/plugins/obs-outputs/data/locale/el-GR.ini @@ -9,6 +9,4 @@ PermissionDenied="Αποκλείστηκε η σύνδεση. Ελέγξτε τ ConnectionAborted="Η σύνδεση ματαιώθηκε. Αυτό συνήθως υποδεικνύει προβλήματα σύνδεσης στο διαδίκτυο ανάμεσα σε εσάς και την υπηρεσία συνεχούς ροής." ConnectionReset="Η σύνδεση ήταν επαναφέρθηκε στον ομότιμο υπολογιστή. Αυτό συνήθως υποδεικνύει προβλήματα σύνδεσης στο διαδίκτυο ανάμεσα σε εσάς και την υπηρεσία συνεχούς ροής." HostNotFound="Το όνομα του κεντρικού υπολογιστή δεν βρέθηκε. Βεβαιωθείτε ότι πληκτρολογήσατε έναν έγκυρο διακομιστή συνεχούς ροής και η σύνδεση στο διαδίκτυο / DNS λειτουργεί σωστά." -NoData="Το όνομα του κεντρικού υπολογιστή βρέθηκε, αλλά χωρίς δεδομένα του ζητούμενου τύπου. Αυτό μπορεί να συμβεί αν έχετε δεσμεύσει μια διεύθυνση IPv6 και για την υπηρεσία συνεχούς ροής μόνο διευθύνσεις IPv4 (ανατρέξτε στην ενότητα ρυθμίσεις)." -AddressNotAvailable="Η διεύθυνση δεν είναι διαθέσιμη. Μπορεί να έχετε δοκιμάσει να συνδεθείτε σε μια άκυρη διεύθυνση IP (βλ. ρυθμίσεις)." diff --git a/plugins/obs-outputs/data/locale/en-US.ini b/plugins/obs-outputs/data/locale/en-US.ini index 3a915ce..0e98788 100644 --- a/plugins/obs-outputs/data/locale/en-US.ini +++ b/plugins/obs-outputs/data/locale/en-US.ini @@ -9,6 +9,6 @@ PermissionDenied="The connection was blocked. Check your firewall / anti-virus s ConnectionAborted="The connection was aborted. This usually indicates internet connection problems between you and the streaming service." ConnectionReset="The connection was reset by the peer. This usually indicates internet connection problems between you and the streaming service." HostNotFound="Hostname not found. Make sure you entered a valid streaming server and your internet connection / DNS are working correctly." -NoData="Hostname found, but no data of the requested type. This can occur if you have bound to an IPv6 address and your streaming service only has IPv4 addresses (see Settings / Advanced)." -AddressNotAvailable="Address not available. You may have tried to bind to an invalid IP address (see Settings / Advanced)." +NoData="Hostname found, but no data of the requested type. This can occur if you have bound to an IPv6 address and your streaming service only has IPv4 addresses (see Settings → Advanced)." +AddressNotAvailable="Address not available. You may have tried to bind to an invalid IP address (see Settings → Advanced)." SSLCertVerifyFailed="The RTMP server sent an invalid SSL certificate." diff --git a/plugins/obs-outputs/data/locale/es-ES.ini b/plugins/obs-outputs/data/locale/es-ES.ini index 80a91bb..49a385a 100644 --- a/plugins/obs-outputs/data/locale/es-ES.ini +++ b/plugins/obs-outputs/data/locale/es-ES.ini @@ -9,7 +9,7 @@ PermissionDenied="La conexión ha sido bloqueada. Compruebe su configuración de ConnectionAborted="La conexión ha sido abortada. Normalmente esto indica que hay problemas de conexión entre tu equipo y el servicio de transmisión." ConnectionReset="La conexión se ha terminado. Normalmente esto indica que hay problemas de conexión entre tu equipo y el servicio de transmisión." HostNotFound="Nombre de host no encontrado. Asegúrese que haya configurado un servidor de transmisión valido y que su conexión a Internet / DNS estén funcionando correctamente." -NoData="Nombre de host encontrado, pero no hay datos del tipo solicitado. Esto puede ocurrir si has enlazado a una dirección IPv6 y su servicio de streaming sólo tiene direcciones IPv4 (ver Configuración / Avanzada)." -AddressNotAvailable="Dirección no disponible. Puede que hayas intentado enlazar con una dirección IP no valida (vea Configuración / Avanzado)." +NoData="Nombre de host encontrado, pero no hay datos del tipo solicitado. Esto puede ocurrir si has enlazado a una dirección IPv6 y su servicio de streaming sólo tiene direcciones IPv4 (ver Configuración → Avanzado)." +AddressNotAvailable="Dirección no disponible. Puede que hayas intentado enlazar con una dirección IP no válida (vea Configuración → Avanzado)." SSLCertVerifyFailed="El servidor RTMP envió un certificado SSL no válido." diff --git a/plugins/obs-outputs/data/locale/fi-FI.ini b/plugins/obs-outputs/data/locale/fi-FI.ini index bed1ff4..07a0381 100644 --- a/plugins/obs-outputs/data/locale/fi-FI.ini +++ b/plugins/obs-outputs/data/locale/fi-FI.ini @@ -9,7 +9,7 @@ PermissionDenied="Yhteys estettiin. Tarkista palomuurin / virusturvan asetukset ConnectionAborted="Yhteys katkaistiin. Tämä tarkoittaa yleensä yhteysongelmia sinun ja lähetyspalvelun välillä." ConnectionReset="Yhteys katkaistiin. Tämä tarkoittaa yleensä yhteysongelmia sinun ja lähetyspalvelun välillä." HostNotFound="Isäntänimeä ei löytynyt. Varmista että syötit voimassaolevan lähetyspalvelimen ja että internet-yhteytesi tai DNS-palvelimesi toimivat oikein." -NoData="Isäntänimi löytyi, mutta ei oikeanlaista pyydettyä dataa. Näin voi tapahtua jos olet rajannut yhteytesi IPv6 -osoitteeseen ja lähetyspalvelusi tukee vain IPv4-osoitteita (Katso Asetukset / Lisäasetukset)." -AddressNotAvailable="Osoite ei ole saatavilla. Voi olla että yritit kiinnittää väärän IP-osoitteen (Katso Asetukset / Lisäasetukset)." +NoData="Isäntänimi löytyi, mutta pyydetyn tyyppistä dataa ei löydetty. Näin voi tapahtua jos olet rajannut yhteytesi IPv6 -osoitteeseen ja lähetyspalvelusi tukee vain IPv4-osoitteita (Katso Asetukset → Lisäasetukset)." +AddressNotAvailable="Osoite ei ole saatavilla. Saatoit yrittää kiinnittää väärän IP-osoitteen (Katso Asetukset → Lisäasetukset)." SSLCertVerifyFailed="RTMP-palvelin lähetti virheellisen SSL-sertifikaatin." diff --git a/plugins/obs-outputs/data/locale/fil-PH.ini b/plugins/obs-outputs/data/locale/fil-PH.ini index dc224e9..48b23b0 100644 --- a/plugins/obs-outputs/data/locale/fil-PH.ini +++ b/plugins/obs-outputs/data/locale/fil-PH.ini @@ -1,4 +1,4 @@ -RTMPStream="Ang RTMP Stream" +RTMPStream="RTMP Stream" RTMPStream.DropThreshold="Ang Drop Treshold (millisegundos)" FLVOutput="Ang FLV File Awput" FLVOutput.FilePath="Ang Landas ng File" @@ -9,6 +9,4 @@ PermissionDenied="Ang koneksyon ay hinarang. Suriin ang firewall / anti-virus se ConnectionAborted="Ang koneksyon ay naudlot. Ito ay karaniwang nagpapahiwatig na may problema sa iyong internet koneksyon at sa streaming service." ConnectionReset="Ang koneksyon ay na i-reset ng peer. Ito ay karaniwang nagpapahiwatig na may problema sa iyong internet koneksyon at sa streaming service." HostNotFound="Hindi makita ang Hostname. Siguraduhin na nilagay mo ay balidong streaming server at ang iyong internet koneksyon / DNS ay gumagana ng mabuti." -NoData="Ang hostname ay nakita, pero walang hinihinging tipo ng datus. Ito ay ay nangyayari kapag naka bound sa IPv6 address at ang iyong streaming service ay IPv4 lamang (tignan Settings / Advanced)." -AddressNotAvailable="Hindi magamit ang address. Ikaw ay gumamit at na i-bind ito sa di balidong IP address ( tingan ang Settings / Advanced)." diff --git a/plugins/obs-outputs/data/locale/fr-FR.ini b/plugins/obs-outputs/data/locale/fr-FR.ini index 454150f..23ccfe4 100644 --- a/plugins/obs-outputs/data/locale/fr-FR.ini +++ b/plugins/obs-outputs/data/locale/fr-FR.ini @@ -1,15 +1,15 @@ RTMPStream="Flux RTMP" -RTMPStream.DropThreshold="Seuil de baisse (en millisecondes)" -FLVOutput="Fichier FLV sortant" +RTMPStream.DropThreshold="Seuil de perte de paquets (en millisecondes)" +FLVOutput="Sortie vers fichier FLV" FLVOutput.FilePath="Chemin du fichier" Default="Interface par défaut" -ConnectionTimedOut="La connexion à expiré. Assurez-vous que vous avez configuré un service de streaming valide et qu'aucun pare-feu ne bloque la connexion." -PermissionDenied="La connexion a été bloquée. Vérifiez vos paramètres de pare-feu / antivirus pour vous assurer OBS est autorisé à avoir l'accès complet d'internet." -ConnectionAborted="La connexion à été interrompue. Cela indique généralement des problèmes de connexion internet entre vous et le service de streaming." -ConnectionReset="La connexion à été interrompue. Cela indique généralement des problèmes de connexion internet entre vous et le service de diffusion." -HostNotFound="Nom d’hôte non trouvé. Assurez-vous que vous avez spécifié un serveur de diffusion valide et que votre connexion internet / DNS fonctionnent correctement." -NoData="Nom d’hôte trouvé, mais aucune donnée du type requis. Cela peut se produire si vous avez lié à une adresse IPv6 et votre service de diffusion ne possède que des adresses IPv4 (voir Paramètres / Avancé)." -AddressNotAvailable="Adresse non disponible. Vous avez peut-être essayé de la lier à une adresse IP non valide (voir Paramètres / Avancé)." +ConnectionTimedOut="La connexion a expiré. Assurez-vous que vous avez configuré un service de streaming valide et qu'aucun pare-feu ne bloque la connexion." +PermissionDenied="La connexion a été bloquée. Vérifiez vos paramètres de pare-feu / antivirus pour vous assurer qu'OBS est autorisé à avoir un accès complet à Internet." +ConnectionAborted="La connexion à été interrompue. Cela indique généralement des problèmes de connexion Internet entre vous et le service de streaming." +ConnectionReset="La connexion à été interrompue. Cela indique généralement des problèmes de connexion Internet entre vous et le service de streaming." +HostNotFound="Nom d’hôte introuvable. Vérifiez l'adresse du serveur de streaming et assurez-vous que votre connexion Internet fonctionne." +NoData="Nom d’hôte trouvé, mais aucune donnée du type requis. Cela peut se produire si vous utilisez une adresse IPv6 et que le service de streaming ne possède que des adresses IPv4 (voir Paramètres → Avancé)." +AddressNotAvailable="Adresse non disponible. Vous avez peut-être essayé de la lier à une adresse IP non valide (voir Paramètres → Avancé)." SSLCertVerifyFailed="Le serveur RTMP a fourni un certificat SSL incorrect." diff --git a/plugins/obs-outputs/data/locale/gd-GB.ini b/plugins/obs-outputs/data/locale/gd-GB.ini index 2c1f2f6..38ff6b6 100644 --- a/plugins/obs-outputs/data/locale/gd-GB.ini +++ b/plugins/obs-outputs/data/locale/gd-GB.ini @@ -4,4 +4,10 @@ FLVOutput="Às-chur faidhle FLV" FLVOutput.FilePath="Slighe an fhaidhle" Default="Bun-roghainn" +ConnectionTimedOut="Dh’fhalbh an ùine air a’ cheangal. Dèan cinnteach gun do shuidhich thu seirbheis sruthaidh dhligheach ’s nach eil cachaileith-theine a’ bacadh a’ cheangail." +PermissionDenied="Chaidh an ceangal a bhacadh. Thoir sùil air roghainnean na cachaileith-theine / a’ bhathair-bhog an aghaidh bhìorasan agad a dhèanamh cinnteach gu bheil cead làn-inntrigidh dhan eadar-lìon aig OBS." +ConnectionAborted="Chaidh sgur dhen cheangal. Dh’fhaoidte gu bheil duilgheadas leis a’ cheangal eadar-lìn eadar thu fhèin agus an t-seirbheis sruthaidh." +ConnectionReset="Chaidh an ceangal ath-shuidheachadh leis an t-seise. Dh’fhaoidte gu bheil duilgheadas leis a’ cheangal eadar-lìn eadar thu fhèin agus an t-seirbheis sruthaidh." +HostNotFound="Cha deach an t-ainm-òstair a lorg. Dèan cinnteach gun do chuir thu a-steach frithealaiche sruthaidh dligheach ’s gu bheil an ceangal gun eadar-lìn / an DNS agad ag obair mar bu chòir." +SSLCertVerifyFailed="Chuir am frithealaiche RTMP teisteanas SSL mì-dhligheach a-nall." diff --git a/plugins/obs-outputs/data/locale/hu-HU.ini b/plugins/obs-outputs/data/locale/hu-HU.ini index 631f19f..af1d54a 100644 --- a/plugins/obs-outputs/data/locale/hu-HU.ini +++ b/plugins/obs-outputs/data/locale/hu-HU.ini @@ -9,7 +9,7 @@ PermissionDenied="A kapcsolat blokkolásra került. Ellenőrizze a tűzfal / ant ConnectionAborted="A kapcsolat megszakadt. Ez általában azt jelzi, hogy az internetkapcsolat a stream kiszolgáló és ön között problémákkal néz szembe." ConnectionReset="A kapcsolat a peer által megszakítva. Ez általában azt jelzi, hogy az internetkapcsolat a stream kiszolgáló és ön között problémákkal néz szembe." HostNotFound="A hostnév nem található. Győződjön meg róla, hogy érvényes stream szervert adott meg és az internetkapcsolata / DNS szerver megfelelően működik." -NoData="Hostnév megtalálva, viszont a kért típusú állomány nem elérhető. Ez akkor fordul elő, ha IPv6 címhez van rendelve és a stream kiszolgálójának csak IPv4 címei állnak rendelkezésre (lásd: Beállítások / Haladó)." -AddressNotAvailable="A cím nem elérhető. Valószínűleg egy érvénytelen IP címet adott meg (Lásd: Beállítások / Haladó)." +NoData="A hostnév megtalálva, viszont a kért állománytípus nem elérhető. Ez akkor fordulhat elő, ha a IPv6 címhez van kötve, de a stream kiszolgálójának csak IPv4 címei állnak rendelkezésre. (Lásd: Beállítások → Haladó)." +AddressNotAvailable="A cím nem elérhető. Valószínűleg érvénytelen IP címet adott meg (Lásd: Beállítások → Haladó)." SSLCertVerifyFailed="Az RTMP kiszolgáló által küldött SSL tanúsítvány érvénytelen." diff --git a/plugins/obs-outputs/data/locale/it-IT.ini b/plugins/obs-outputs/data/locale/it-IT.ini index b9cf420..8577529 100644 --- a/plugins/obs-outputs/data/locale/it-IT.ini +++ b/plugins/obs-outputs/data/locale/it-IT.ini @@ -1,14 +1,15 @@ RTMPStream="Stream RTMP" -RTMPStream.DropThreshold="Abbassa il limite (millisecondi)" +RTMPStream.DropThreshold="Abbassa il limite (in millisecondi)" FLVOutput="Uscita file FLV" -FLVOutput.FilePath="Destinazione file" +FLVOutput.FilePath="Percorso file" Default="Predefinito" -ConnectionTimedOut="Timeout della connessione. Assicurarsi di aver configurato un valido servizio di streaming e nessun firewall sta bloccando la connessione." -PermissionDenied="La connessione è stata bloccata. Controlla il tuo firewall / impostazioni di anti-virus per assicurarsi che per OBS sia consentito accesso completo a internet." -ConnectionAborted="La connessione è stata interrotta. In genere indica problemi di connessione tra l'utente e il servizio di streaming." -ConnectionReset="La connessione è stata ripristinata dal peer. In genere indica problemi di connessione tra l'utente e il servizio di streaming." -HostNotFound="Nome host non trovato. Assicurarsi di aver inserito un valido server per lo streaming e che la connessione a internet / DNS funzioni correttamente." -NoData="Nome host trovato, ma nessun dato del tipo richiesto. Ciò può verificarsi se è stato associato a un indirizzo IPv6 e il servizio di streaming ha solo indirizzi IPv4 (vedere Impostazioni / avanzate)." -AddressNotAvailable="Indirizzo non disponibile. Si è cercato di associare un indirizzo IP non valido (vedere Impostazioni / avanzate)." +ConnectionTimedOut="La connessione è scaduta. Assicurati di aver configurato un servizio di dirette valido e controlla che non ci siano firewall che bloccano la connessione." +PermissionDenied="La connessione è stata bloccata. Controlla il tuo firewall e le impostazioni dell'antivirus, assicurati che OBS abbia l'accesso completo a internet." +ConnectionAborted="La connessione è stata interrotta. Generalmente questo problema riguarda la connessione tra l'utente e il servizio di dirette." +ConnectionReset="La connessione è stata ripristinata dal peer. Generalmente questo problema riguarda la connessione tra l'utente e il servizio di dirette." +HostNotFound="Nome dell'host non trovato. Assicurati di aver configurato un servizio di dirette valido e controlla che la connessione a internet e il tuo DNS funzionino correttamente." +NoData="Nome dell'host trovato, ma nessun dato del tipo richiesto. Ciò può verificarsi se sei collegato tramite un indirizzo IPv6 e il servizio di dirette funziona solo con indirizzi IPv4 (vai a controllare: Impostazioni → Avanzate)." +AddressNotAvailable="L'indirizzo non è disponibile. Probabilmente hai cercato di associare un indirizzo IP non valido (vai a controllare: Impostazioni → Avanzate)." +SSLCertVerifyFailed="Il server RTMP ha inviato un certificato SSL non valido." diff --git a/plugins/obs-outputs/data/locale/ja-JP.ini b/plugins/obs-outputs/data/locale/ja-JP.ini index 0366cfb..8319d4c 100644 --- a/plugins/obs-outputs/data/locale/ja-JP.ini +++ b/plugins/obs-outputs/data/locale/ja-JP.ini @@ -4,12 +4,12 @@ FLVOutput="FLV ファイル出力" FLVOutput.FilePath="ファイルのパス" Default="既定" -ConnectionTimedOut="接続がタイムアウトしました。 有効なストリーミングサービスを設定し、ファイアウォールが接続をブロックしていないことを確認してください。" +ConnectionTimedOut="接続がタイムアウトしました。 有効な配信サービスを設定し、ファイアウォールが接続をブロックしていないことを確認してください。" PermissionDenied="接続がブロックされました。 ファイアウォール/アンチウィルスの設定をチェックして、OBSにインターネットへのアクセスがすべて許可されていることを確認してください。" -ConnectionAborted="接続は中止されました。 ストリーミングサービスとの間のインターネット接続に問題があることを示しています。" -ConnectionReset="接続はピアによってリセットされました。 ストリーミングサービスとの間のインターネット接続に問題があることを示しています。" +ConnectionAborted="接続は中止されました。配信サービスとの間のインターネット接続に問題があることを示しています。" +ConnectionReset="接続はピアによってリセットされました。 配信サービスとの間のインターネット接続に問題があることを示しています。" HostNotFound="ホスト名が見つかりません。 有効なストリーミングサーバーを入力していることとインターネット接続/DNSが正しく機能していることを確認してください。" -NoData="ホスト名が見つかりましたが、要求されたタイプのデータがありません。 これはIPv6アドレスにバインドしている状態でストリーミングサービスにIPv4アドレスしかない場合に発生します。 (設定 / 詳細設定 を参照)" -AddressNotAvailable="アドレスを利用できません。 無効なIPアドレスにバインドしようとした可能性があります。 (設定 / 詳細設定 を参照)" +NoData="ホスト名が見つかりましたが、要求されたタイプのデータがありません。 これはIPv6アドレスにバインドしている状態で配信サービスにIPv4アドレスしかない場合に発生します。 (設定 → 詳細設定 を参照)" +AddressNotAvailable="アドレスを利用できません。 無効なIPアドレスにバインドしようとした可能性があります。 (設定 → 詳細設定 を参照)" SSLCertVerifyFailed="RTMPサーバーが無効なSSL証明書を送信しました。" diff --git a/plugins/obs-outputs/data/locale/ka-GE.ini b/plugins/obs-outputs/data/locale/ka-GE.ini index 933c06b..c0ed80e 100644 --- a/plugins/obs-outputs/data/locale/ka-GE.ini +++ b/plugins/obs-outputs/data/locale/ka-GE.ini @@ -1,6 +1,6 @@ -RTMPStream="RTMP ნაკადი" +RTMPStream="RTMP-ნაკადი" RTMPStream.DropThreshold="ქვედა ზღურბლი (მილიწამი)" -FLVOutput="გამომავალი FLV ფაილი" +FLVOutput="გამოტანილი FLV-ფაილი" FLVOutput.FilePath="ფაილის მისამართი" Default="ნაგულისხმევი" @@ -9,7 +9,7 @@ PermissionDenied="კავშირი შეიზღუდა. გადა ConnectionAborted="კავშირი გაუქმდა. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვების მომსახურების მომწოდებელს შორის." ConnectionReset="კავშირი გაწყდა ერთ-ერთი მხარის მიერ. ძირითადად, ეს მიუთითებს ინტერნეტკავშირის ხარვეზების არსებობას, თქვენსა და ნაკადის გაშვების მომსახურების მომწოდებელს შორის." HostNotFound="დაკავშირების წერტილი ვერ მოიძებნა. დარწმუნდით, რომ სწორად უთითებთ ნაკადის გაშვების მომსახურების მონაცემებს და თქვენი DNS / ინტერნეტკავშირის პარამეტრებიც სწორადაა გამართული." -NoData="დაკავშირების წერტილი მოიძებნა, მაგრამ მოთხოვნილი სახის მონაცემები არა. ეს შეიძლება გამოწვეული იყოს იმით, რომ თქვენ უკავშირდებით IPv6 მისამართზე, ხოლო თქვენს ნაკადის გაშვების მომსახურებას, მხოლოდ IPv4 მისამართები გააჩნია (იხილეთ პარამეტრები / დამატებითი)." -AddressNotAvailable="მისამართი მიუწვდომელია. შესაძლოა, თქვენ ცდილობთ მცდარ IP მისამართზე დაკავშირებას (იხილეთ პარამეტრები / დამატებითი)." +NoData="დაკავშირების წერტილი მოიძებნა, მაგრამ მოთხოვნილი სახის მონაცემები არა. ეს შეიძლება გამოწვეული იყოს იმით, რომ თქვენ უკავშირდებით IPv6 მისამართზე, ხოლო თქვენს ნაკადის გაშვების მომსახურებას, მხოლოდ IPv4 მისამართები გააჩნია (იხილეთ პარამეტრები → დამატებითი)." +AddressNotAvailable="მისამართი მიუწვდომელია. შესაძლოა, თქვენ ცდილობთ მცდარ IP-მისამართზე დაკავშირებას (იხილეთ პარამეტრები → დამატებით)." SSLCertVerifyFailed="RTMP სერვერმა გაგზავნა არამართებული SSL სერტიფიკატი." diff --git a/plugins/obs-outputs/data/locale/ko-KR.ini b/plugins/obs-outputs/data/locale/ko-KR.ini index f3c114f..9330e31 100644 --- a/plugins/obs-outputs/data/locale/ko-KR.ini +++ b/plugins/obs-outputs/data/locale/ko-KR.ini @@ -9,7 +9,7 @@ PermissionDenied="연결이 차단되었습니다. 방화벽이나 백신 설정 ConnectionAborted="연결이 취소되었습니다. 보통 사용자와 방송 서비스 간의 연결 상태에 문제가 있음을 의미합니다." ConnectionReset="상호 연결 문제로 초기화되었습니다. 보통 사용자와 방송 서비스 간의 연결 상태에 문제가 있음을 의미합니다." HostNotFound="호스트 이름을 찾을 수 없습니다. 방송 서버 정보가 제대로 입력되었는지 확인하고, 인터넷 접속 혹은 DNS가 제대로 작동하고 있는지 점검하십시오." -NoData="호스트 이름은 찾았지만 요청한 형식의 데이터가 없습니다. 이 문제는 보통 사용자가 IPv6 형식의 주소를 고정하여 사용하면서 IPv4 형식의 주소만 지원하는 방송 서비스에 접속을 시도한 경우 나타납니다 (설정 / 고급 창을 확인하십시오)." -AddressNotAvailable="주소를 사용할 수 없습니다. 잘못된 IP주소를 고정하고 있습니다 (설정 / 고급 창을 확인하십시오)." +NoData="호스트 이름은 찾았지만 요청한 형식의 데이터가 없습니다. 이 문제는 보통 사용자가 IPv6 형식의 주소를 고정하여 사용하면서 IPv4 형식의 주소만 지원하는 방송 서비스에 접속을 시도한 경우 나타납니다 (설정 → 고급 창을 확인하세요)." +AddressNotAvailable="주소를 사용할 수 없습니다. 잘못된 IP주소를 고정하고 있습니다 (설정 → 고급 창을 확인하세요)." SSLCertVerifyFailed="해당 RTMP 서버는 잘못된 SSL 인증서를 보냈습니다." diff --git a/plugins/obs-outputs/data/locale/mn-MN.ini b/plugins/obs-outputs/data/locale/mn-MN.ini new file mode 100644 index 0000000..c22f94e --- /dev/null +++ b/plugins/obs-outputs/data/locale/mn-MN.ini @@ -0,0 +1,3 @@ +Default="Үндсэн" + + diff --git a/plugins/obs-outputs/data/locale/nb-NO.ini b/plugins/obs-outputs/data/locale/nb-NO.ini index 7be490c..e82bb1c 100644 --- a/plugins/obs-outputs/data/locale/nb-NO.ini +++ b/plugins/obs-outputs/data/locale/nb-NO.ini @@ -9,7 +9,7 @@ PermissionDenied="Tilkoblingen ble blokkert. Sjekk at OBS har full internettilga ConnectionAborted="Tilkoblingen ble avbrutt. Dette betyr vanligvis at det er problemer med nettverkskoblingen mellom deg og strømmetjenesten." ConnectionReset="Tilkoblingen ble avbrutt. Dette betyr vanligvis at det er problemer med nettverkskoblingen mellom deg og strømmetjenesten." HostNotFound="Tjeneren ble ikke funnet. Kontroller at du har angitt en gyldig streaming server og at tilkoblingen / DNS fungerer." -NoData="Tjeneren funnet, men ingen data for den forespurte typen. Dette kan skje hvis du har bundet til en IPv6-adresse og streaming tjeneste har bare IPv4-adresser (se Snnstillinger / Avansert)." -AddressNotAvailable="Adresse ikke tilgjengelig. Du prøvde å binde til en ugyldig IP-adresse (se Innstillinger / Avansert)." +NoData="Tjeneren funnet, men ingen data for den forespurte typen. Dette kan skje hvis du har bundet til en IPv6-adresse og streaming tjeneste har bare IPv4-adresser (se Innstillinger → Avansert)." +AddressNotAvailable="Adresse ikke tilgjengelig. Du prøvde å binde til en ugyldig IP-adresse (se Innstillinger → Avansert)." SSLCertVerifyFailed="RTMP-tjeneren sendte et ugyldig SSL-sertifikat." diff --git a/plugins/obs-outputs/data/locale/nl-NL.ini b/plugins/obs-outputs/data/locale/nl-NL.ini index e72f7a1..d4ef9b5 100644 --- a/plugins/obs-outputs/data/locale/nl-NL.ini +++ b/plugins/obs-outputs/data/locale/nl-NL.ini @@ -9,7 +9,7 @@ PermissionDenied="De verbinding was geblokkeerd. Controleer je firewall/anti-vir ConnectionAborted="De verbinding was afgebroken. Dit duidt meestal op verbindingsproblemen tussen jou en de streaming service." ConnectionReset="De verbinding was gereset door de andere partij. Dit duidt meestal op verbindingsproblemen tussen jou en de streaming service." HostNotFound="Hostname niet gevonden. Controleer dat je een geldige streaming service hebt ingevuld en dat je internetverbinding / DNS correct werken." -NoData="Hostname gevonden, maar geen data van het verwachte type. Dit kan gebeuren als je aan een IPv6 adres hebt gebonden, en je streaming service alleen IPv4 adressen heeft (zie Instellingen / Geavanceerd)." -AddressNotAvailable="Adres niet beschikbaar. Je hebt misschien geprobeerd om aan een ongeldig IP adres te binden (zie Instellingen / Geavanceerd)." +NoData="Hostname gevonden, maar geen data van het verwachte type. Dit kan gebeuren als je aan een IPv6 adres hebt gebonden, en je streaming service alleen IPv4 adressen heeft (zie Instellingen → Geavanceerd)." +AddressNotAvailable="Adres niet beschikbaar. Je hebt misschien geprobeerd om aan een ongeldig IP adres te binden (zie Instellingen → Geavanceerd)." SSLCertVerifyFailed="De RTMP-server heeft een ongeldig SSL-certificaat verzonden." diff --git a/plugins/obs-outputs/data/locale/pl-PL.ini b/plugins/obs-outputs/data/locale/pl-PL.ini index 735c3c3..9012e61 100644 --- a/plugins/obs-outputs/data/locale/pl-PL.ini +++ b/plugins/obs-outputs/data/locale/pl-PL.ini @@ -1,7 +1,7 @@ RTMPStream="Strumień RTMP" RTMPStream.DropThreshold="Próg odrzucania (w milisekundach)" FLVOutput="Wyjście do pliku FLV" -FLVOutput.FilePath="Scieżka do pliku" +FLVOutput.FilePath="Ścieżka pliku" Default="Domyślne" ConnectionTimedOut="Upłynął limit czasu połączenia. Upewnij się, że usługa strumieniowania jest poprawnie skonfigurowana a zapora internetowa nie blokuje połączenia." @@ -9,7 +9,7 @@ PermissionDenied="Połączenie zostało zablokowane. Sprawdź stan zapory intern ConnectionAborted="Połączenie zostało przerwane. Wskazuje to najczęściej na problemy w połączeniu między Tobą a usługą strumieniowania." ConnectionReset="Połączenie zostało przerwane po stronie serwera. Wskazuje to najczęściej na problemy w połączeniu między Tobą a usługą strumieniowania." HostNotFound="Nie znaleziono nazwy hosta. Upewnij się, że wprowadzono prawidłowe dane serwera przesyłania strumieniowego i połączenie z internetem / DNS są poprawne." -NoData="Nazwa serwera została znaleziona ale nie stwierdzono poprawności odbieranych danych. Dzieje się tak najczęściej po przypisaniu aplikacji do adresu IPv6, gdy usługa strumieniowania obsługuje jedynie adresy IPv4 (zobacz Ustawienia -> Zaawansowane)." -AddressNotAvailable="Adres IP niedostępny. Być może powiązano aplikację z nieprawidłowym adresem IP (zobacz Ustawienia -> Zaawansowane)." +NoData="Nazwa serwera została znaleziona ale nie stwierdzono poprawności odbieranych danych. Dzieje się tak najczęściej po przypisaniu aplikacji do adresu IPv6, gdy usługa strumieniowania obsługuje jedynie adresy IPv4 (zobacz Ustawienia → Zaawansowane)." +AddressNotAvailable="Adres IP niedostępny. Być może powiązano aplikację z nieprawidłowym adresem IP (zobacz Ustawienia → Zaawansowane)." SSLCertVerifyFailed="Serwer RTMP wysłał nieprawidłowy certyfikat SSL." diff --git a/plugins/obs-outputs/data/locale/pt-BR.ini b/plugins/obs-outputs/data/locale/pt-BR.ini index 7cd9b39..8e80741 100644 --- a/plugins/obs-outputs/data/locale/pt-BR.ini +++ b/plugins/obs-outputs/data/locale/pt-BR.ini @@ -9,7 +9,7 @@ PermissionDenied="A conexão foi bloqueada. Verifique seu firewall / configuraç ConnectionAborted="A conexão foi abortada. Isso geralmente indica problemas de conexão entre você e o serviço de transmissão." ConnectionReset="A conexão foi redefinida pelo usuário. Isso geralmente indica problemas de conexão entre você e o serviço de transmissão." HostNotFound="Host não encontrado. Verifique se você inseriu um servidor válido de transmissão e se sua conexão de internet / DNS estão funcionando corretamente." -NoData="Host encontrado, mas não há dados do tipo solicitado. Isso pode ocorrer se você tiver vinculado a um endereço IPv6 e seu serviço de transmissão tem apenas endereços IPv4 (consulte Configurações / Avançado)." -AddressNotAvailable="Endereço não disponível. Você pode ter tentado se vincular a um endereço IP inválido (consulte Configurações / Avançado)." +NoData="Host encontrado, mas não há dados do tipo solicitado. Isso pode ocorrer se você tiver vinculado a um endereço IPv6 e seu serviço de transmissão tem apenas endereços IPv4 (consulte Configurações → Avançado)." +AddressNotAvailable="Endereço indisponível. Você pode ter tentado se vincular a um endereço IP inválido (consulte Configurações → Avançado)." SSLCertVerifyFailed="O servidor RTMP enviou um certificado SSL inválido." diff --git a/plugins/obs-outputs/data/locale/pt-PT.ini b/plugins/obs-outputs/data/locale/pt-PT.ini index c3442dd..4623c8e 100644 --- a/plugins/obs-outputs/data/locale/pt-PT.ini +++ b/plugins/obs-outputs/data/locale/pt-PT.ini @@ -2,5 +2,14 @@ RTMPStream="RTMP Stream" RTMPStream.DropThreshold="Limite de corte (milissegundos)" FLVOutput="Ficheiro de saída FLV" FLVOutput.FilePath="Caminho do ficheiro" +Default="Padrão" +ConnectionTimedOut="A ligação acabou. Verifique se você configurou um serviço de streaming válido e se nenhum firewall está bloqueando a conexão." +PermissionDenied="A ligação foi bloqueada. Verifique as configurações do seu firewall/anti-vírus para se certificar de que o OBS tem acesso total à Internet." +ConnectionAborted="A ligação foi abortada. Isso normalmente indica problemas de conexão de internet entre você e o serviço de streaming." +ConnectionReset="A ligação foi restabelecida pelo colega. Isso normalmente indica problemas de conexão de internet entre você e o serviço de streaming." +HostNotFound="Hostname não encontrado. Verifique se você digitou um servidor de streaming válido e se sua conexão de internet / DNS está funcionando corretamente." +NoData="Hostname encontrado, mas nenhum dado do tipo solicitado. Isso pode ocorrer se você tiver um endereço IPv6 e seu serviço de streaming tiver apenas endereços IPv4 (consulte Configurações → Avançado)." +AddressNotAvailable="Endereço não disponível. Você pode ter tentado vincular-se a um endereço IP inválido (consulte Configurações → Avançado)." +SSLCertVerifyFailed="O servidor RTMP enviou um certificado SSL inválido." diff --git a/plugins/obs-outputs/data/locale/ro-RO.ini b/plugins/obs-outputs/data/locale/ro-RO.ini index 9d67c92..50778e0 100644 --- a/plugins/obs-outputs/data/locale/ro-RO.ini +++ b/plugins/obs-outputs/data/locale/ro-RO.ini @@ -2,5 +2,6 @@ RTMPStream="Flux RTMP" RTMPStream.DropThreshold="Prag de pierderi (milisecunde)" FLVOutput="Ieșire fișier FLV" FLVOutput.FilePath="Calea fișierului" +Default="Implicit" diff --git a/plugins/obs-outputs/data/locale/ru-RU.ini b/plugins/obs-outputs/data/locale/ru-RU.ini index 3834a25..907e1f9 100644 --- a/plugins/obs-outputs/data/locale/ru-RU.ini +++ b/plugins/obs-outputs/data/locale/ru-RU.ini @@ -1,4 +1,4 @@ -RTMPStream="Поток RTMP" +RTMPStream="RTMP-трансляция" RTMPStream.DropThreshold="Нижний порог (мс)" FLVOutput="Выходной файл FLV" FLVOutput.FilePath="Путь к файлу" @@ -9,7 +9,7 @@ PermissionDenied="Соединение было заблокировано. Пр ConnectionAborted="Соединение было прервано. Обычно это указывает на проблемы с интернет-соединением между вами и службой вещания." ConnectionReset="Соединение было сброшено одноранговым узлом. Обычно это указывает на проблемы с интернет-соединением между вами и службой вещания." HostNotFound="Имя узла не найдено. Убедитесь, что вы ввели действительный сервер вещания и ваше подключение к интернету/DNS работают правильно." -NoData="Имя узла найдено, но нет данных запрошенного типа. Такое может случиться, если вы привязаны к IPv6-адресу, а ваш сервис вещания имеет только IPv4-адреса (смотрите Настройки - Расширенные)." -AddressNotAvailable="Адрес недоступен. Возможно вы пытались привязаться к недействительному IP-адресу (смотрите Настройки - Расширенные)." +NoData="Имя узла найдено, но нет данных запрошенного типа. Такое может случиться, если вы привязаны к IPv6-адресу, а ваш сервис вещания имеет только IPv4-адреса (смотрите Настройки → Расширенные)." +AddressNotAvailable="Адрес недоступен. Возможно вы пытались привязаться к недействительному IP-адресу (смотрите Настройки → Расширенные)." SSLCertVerifyFailed="RTMP сервер отправил недействительный сертификат SSL." diff --git a/plugins/obs-outputs/data/locale/sk-SK.ini b/plugins/obs-outputs/data/locale/sk-SK.ini index d2b5d11..a071fff 100644 --- a/plugins/obs-outputs/data/locale/sk-SK.ini +++ b/plugins/obs-outputs/data/locale/sk-SK.ini @@ -5,5 +5,4 @@ FLVOutput.FilePath="Cesta k súboru" Default="Predvolené" ConnectionReset="Pripojenie bolo resetované druhou stranou. Toto obvykle znamená, že nastali problémy s pripojením medzi vami a streaming službou." -AddressNotAvailable="Adresa nie je k dispozícii. Môžno ste sa snažili naviazať na neplatnú IP adresu (pozrite si Nastavenia / Rozšírené)." diff --git a/plugins/obs-outputs/data/locale/sr-CS.ini b/plugins/obs-outputs/data/locale/sr-CS.ini index 2310a6e..20b587f 100644 --- a/plugins/obs-outputs/data/locale/sr-CS.ini +++ b/plugins/obs-outputs/data/locale/sr-CS.ini @@ -1,7 +1,13 @@ RTMPStream="RTMP strim" -RTMPStream.DropThreshold="Tolerancija ispuštanja (milisekunde)" -FLVOutput="Izlaz u FLV datoteku" +RTMPStream.DropThreshold="Donji prag (milisekunde)" +FLVOutput="Izlaz FLV datoteke" FLVOutput.FilePath="Putanja datoteke" Default="Podrazumevani" +ConnectionTimedOut="Konekcija je istekla. Proverite da li ste podesili ispravan servis za strimovanje i da li firewall blokira konekciju." +PermissionDenied="Konekcija je blokirana. Proverite Vaša firewall / anti-virus podešavanja kako biste bili sigurni da OBS ima pristup internetu u potpunosti." +ConnectionAborted="Konekcija je obustavljena. Ovo je obično znak problema sa internet konekcijom između Vas i striming servisa." +ConnectionReset="Veza je resetovana od strane ravnopravnog uređaja. Ovo je obično znak problema sa internet konekcijom između Vas i servisa za strimovanje." +HostNotFound="Naziv hosta nije pronađen. Proverite da li ste uneli ispravan striming server i da Vaša internet konekcija i DNS rade ispravno." +SSLCertVerifyFailed="RTMP server je poslao nevažeći SSL sertifikat." diff --git a/plugins/obs-outputs/data/locale/sr-SP.ini b/plugins/obs-outputs/data/locale/sr-SP.ini index ceb2473..6b4b726 100644 --- a/plugins/obs-outputs/data/locale/sr-SP.ini +++ b/plugins/obs-outputs/data/locale/sr-SP.ini @@ -1,7 +1,13 @@ RTMPStream="RTMP стрим" -RTMPStream.DropThreshold="Толеранција испуштања (milisekunde)" -FLVOutput="Излаз у FLV датотеку" +RTMPStream.DropThreshold="Доњи праг (милисекунде)" +FLVOutput="Излаз FLV датотеке" FLVOutput.FilePath="Путања датотеке" Default="Подразумевана" +ConnectionTimedOut="Конекција је истекла. Проверите да ли сте подесили исправан сервис за стримовање и да ли firewall блокира конекцију." +PermissionDenied="Конекција је блокирана. Проверите Ваша firewall /анти-вирус подешавања како бисте били сигурни да OBS има приступ интернету у потпуности." +ConnectionAborted="Конекција је обустављена. Ово је обично знак проблема са интернет конекцијом између Вас и стриминг сервиса." +ConnectionReset="Веза је ресетована од стране равноправног уређаја. Ово је обично знак проблема са интернет конекцијом између Вас и сервиса за стримовање." +HostNotFound="Назив хоста није пронађен. Проверите да ли сте унели исправан стриминг сервер и да Ваша интернет конекција и DNS раде исправно." +SSLCertVerifyFailed="RTMP сервер је послао неважећи SSL сертификат." diff --git a/plugins/obs-outputs/data/locale/sv-SE.ini b/plugins/obs-outputs/data/locale/sv-SE.ini index f124ace..d306a83 100644 --- a/plugins/obs-outputs/data/locale/sv-SE.ini +++ b/plugins/obs-outputs/data/locale/sv-SE.ini @@ -9,7 +9,7 @@ PermissionDenied="Anslutningen blockerades. Kontrollera inställningarna för di ConnectionAborted="Anslutningen avbröts. Detta kan indikera problem med Internetanslutningen mellan dig och strömningstjänsten." ConnectionReset="Anslutningen återställdes av en peer. Detta kan indikera problem med Internetanslutningen mellan dig och strömningstjänsten." HostNotFound="Värdnamnet hittades inte. Se till att du har angivit en giltigt strömningstjänst och att din Internetanslutning / DNS fungerar på rätt sätt." -NoData="Värdnamnet hittades, men ingen data av den begärda typen. Detta kan hända om du ansluter till en IPv6-adress och din strömningstjänst endast har IPv4-adresser (gå till Inställningar / Avancerat)." -AddressNotAvailable="Adressen är inte tillgänglig. Du kanske försökte ansluta till en ogiltig IP-adress (gå till Inställningar / Avancerat)." +NoData="Värdnamnet hittades, men ingen data av den begärda typen. Detta kan förekomma om du har bundit till en IPv6-adress och din strömtjänst endast har IPv4-adresser (se Inställningar → Avancerat)." +AddressNotAvailable="Adressen är inte tillgänglig. Du kanske har försökt binda till en ogiltig IP-adress (se Inställningar → Avancerat)." SSLCertVerifyFailed="RTMP-servern skickade ett ogiltigt SSL-certifikat." diff --git a/plugins/obs-outputs/data/locale/tl-PH.ini b/plugins/obs-outputs/data/locale/tl-PH.ini index 8ae0ace..1e01e19 100644 --- a/plugins/obs-outputs/data/locale/tl-PH.ini +++ b/plugins/obs-outputs/data/locale/tl-PH.ini @@ -9,6 +9,4 @@ PermissionDenied="Ang koneksyon ay na-block. I-check ang iyong firewall / anti-v ConnectionAborted="Ang koneksyon ay nabigo. Ito ay kadalasang indikasyon na ang internet nakoneksyon ay may problema sa'yo o kay sa serbisyo ng streaming." ConnectionReset="Ang koneksyon ay ni-reset ng peer. Ito ay kadalasang indikasyon na ang internet nakoneksyon ay may problema sa'yo o kay sa serbisyo ng streaming." HostNotFound="Ang hostname ay hindi matagpuan. Siguraduhing ang nilagay mo ay isang balidong stereaming server at ang iyong internet koneksyon / DNS ay gumagana ng sakto." -NoData="Ang hostname ay natagpuan, ngunit walang data sa ni-request na tipo. Ito ay pwedeng mangyari kung wala kang bound para sa IPv6 na address at ang iyong streaming service ay meron lang IPv4 na mga address (tingnan ang Setting / Advanced)." -AddressNotAvailable="Ang address ay hindi pwede. Pwede kang sumubok na i-bind sa isang hindi balidong IP address (tingnan ang Setting / Advanced)." diff --git a/plugins/obs-outputs/data/locale/tr-TR.ini b/plugins/obs-outputs/data/locale/tr-TR.ini index 61aa6c6..e96d745 100644 --- a/plugins/obs-outputs/data/locale/tr-TR.ini +++ b/plugins/obs-outputs/data/locale/tr-TR.ini @@ -9,7 +9,7 @@ PermissionDenied="Bağlantı engellendi. Güvenlik duvarı / virüs koruma ayarl ConnectionAborted="Bağlantı iptal edildi. Bu genellikle sizin ve yayın servisinin arasındaki internet bağlantısı sorununa işaret eder." ConnectionReset="Bağlantı karşı taraftan sıfırlandı. Bu genellikle sizin ve yayın servisinin arasındaki internet bağlantısı sorununa işaret eder." HostNotFound="Ana bilgisayar adı bulunamadı. Geçerli bir yayın sunucusu girdiğinizden ve internet bağlantınızın / DNS'nizin düzgün çalıştığını emin olun." -NoData="Ana bilgisayar adı bulundu, ancak istenen türde veri bulunamadı. Bu bir IPv6 adresine bağlamış ve yayın servisinizin sadece IPv4 adresleri varsa oluşabilir (bkz: Ayarlar / Gelişmiş)." -AddressNotAvailable="Adres kullanılamaz. Geçersiz bir IP adresi bağlamayı denemiş olabilirsiniz (bakın: Ayarlar / Gelişmiş)." +NoData="Ana bilgisayar adı bulundu, ancak istenen türde veri bulunamadı. Bu bir IPv6 adresine bağlamış ve yayın servisinizin sadece IPv4 adresleri varsa oluşabilir (bkz: Ayarlar → Gelişmiş)." +AddressNotAvailable="Adres kullanılamaz. Geçersiz bir IP adresi bağlamayı denemiş olabilirsiniz (bakın: Ayarlar → Gelişmiş)." SSLCertVerifyFailed="RTMP sunucusu geçersiz bir SSL sertifikası gönderdi." diff --git a/plugins/obs-outputs/data/locale/uk-UA.ini b/plugins/obs-outputs/data/locale/uk-UA.ini index 6ab98ef..a5e4dff 100644 --- a/plugins/obs-outputs/data/locale/uk-UA.ini +++ b/plugins/obs-outputs/data/locale/uk-UA.ini @@ -9,7 +9,7 @@ PermissionDenied="З'єднання було заблоковано. Перев ConnectionAborted="З'єднання було перервано. Зазвичай свідчить про проблеми з Інтернет підключенням між вами і постачальником з сервісу трансляцій." ConnectionReset="З'єднання було скинуте рівноправним вузлом (reset by peer). Зазвичай свідчить про проблеми з Інтернет підключенням між вами і постачальником з сервісу трансляцій." HostNotFound="Ім'я хоста, не знайдено. Переконайтеся, що ви ввели дійсний сервер трансляцій і підключення до Інтернету / DNS працює правильно." -NoData="Ім'я хоста знайдено, але нема жодних даних вказаного типу. Це може статися, якщо ви вказали прив'язку до IPv6-адресу, але ваш сервіс трансляцій підтримує лише адреси IPv4 (див. Налаштування / Розширені)." -AddressNotAvailable="Адреса недоступна. Напевно ви спробували прив'язатись до адаптера з неіснуючую IP-адресою (див. Налаштування / Розширені)." +NoData="Ім'я хоста знайдено, але нема жодних даних вказаного типу. Це може статися, якщо ви вказали прив'язку до IPv6-адресу, але ваш сервіс трансляцій підтримує лише адреси IPv4 (див. Налаштування → Розширені)." +AddressNotAvailable="Адреса недоступна. Напевно ви спробували прив'язатись до адаптера з неіснуючою IP-адресою (див. Налаштування → Розширені)." SSLCertVerifyFailed="RTMP сервер надіслав неприпустимий сертифікат SSL." diff --git a/plugins/obs-outputs/data/locale/vi-VN.ini b/plugins/obs-outputs/data/locale/vi-VN.ini index 5b2e11f..9a6d3b8 100644 --- a/plugins/obs-outputs/data/locale/vi-VN.ini +++ b/plugins/obs-outputs/data/locale/vi-VN.ini @@ -1,4 +1,4 @@ -RTMPStream="RTMP Stream" +RTMPStream="Luồng RTMP" RTMPStream.DropThreshold="Drop Threshold (mili giây)" FLVOutput="FLV tập tin đầu ra" FLVOutput.FilePath="Đường dẫn tệp" @@ -9,6 +9,4 @@ PermissionDenied="Kết nối đã bị chặn. Hãy kiểm tra tường lửa / ConnectionAborted="Kết nối đã bị hủy bỏ. Điều này thường chỉ ra kết nối internet giữa bạn và dịch vụ trực tuyến có vấn đề." ConnectionReset="Kết nối đã được đặt lại bởi peer. Điều này thường chỉ ra các sự cố kết nối Internet giữa bạn và dịch vụ truyền trực tuyến." HostNotFound="Tên máy chủ không tìm thấy. Đảm bảo rằng bạn đã nhập vào một máy chủ stream hợp lệ và kết nối internet của bạn / DNS đang hoạt động tốt." -NoData="Tên máy chủ được tìm thấy nhưng không có dữ liệu được yêu cầu. Điều này có thể xảy ra nếu bạn sử dụng địa chỉ IPv6 và dịch vụ stream của bạn chỉ có địa chỉ IPv4 (xem Cài đặt / Nâng cao)." -AddressNotAvailable="Địa chỉ không có sẵn. Bạn có thể đã cố gắng liên kết với một địa chỉ IP không hợp lệ (xem Cài đặt / Nâng cao)." diff --git a/plugins/obs-outputs/data/locale/zh-CN.ini b/plugins/obs-outputs/data/locale/zh-CN.ini index e8a99af..39c959e 100644 --- a/plugins/obs-outputs/data/locale/zh-CN.ini +++ b/plugins/obs-outputs/data/locale/zh-CN.ini @@ -4,12 +4,12 @@ FLVOutput="FLV 文件输出" FLVOutput.FilePath="文件路径" Default="默认" -ConnectionTimedOut="连接超时. 请确保您已经配置了一个有效的流媒体服务并且没有防火墙阻止连接." -PermissionDenied="连接被阻止. 检查您的防火墙 / 防病毒设置以确保允许 OBS 自由访问互联网." -ConnectionAborted="连接被中止. 这通常表明你和流媒体服务之间的互联网连接问题." -ConnectionReset="对方重置连接. 这通常表明你和流媒体服务之间的互联网连接问题." -HostNotFound="找不到 Hostname. 请确保您输入一个有效的流媒体服务器并且您的互联网连接 / DNS 工作正常." -NoData="Hostname 发现, 但没有请求的类型的数据的主机名. 这有可能因为你绑定到 IPv6 地址并且你的流媒体服务仅有 IPv4 地址 (请参阅设置 / 高级)." -AddressNotAvailable="没有可用的地址. 你可能在试图绑定到一个无效的 IP 地址 (请参阅设置 / 高级)." +ConnectionTimedOut="连接超时。请确保您已经配置了一个有效的流媒体服务并且没有防火墙阻止连接。" +PermissionDenied="连接被阻止。检查您的防火墙 / 防病毒设置以确保允许 OBS 自由访问互联网。" +ConnectionAborted="连接被中止。这通常表明你和流媒体服务器间的互联网存在连接问题。" +ConnectionReset="对方重置了连接。这通常表明你和流媒体服务器间的互联网存在连接问题。" +HostNotFound="找不到主机名。请确保您输入了有效的流媒体服务器并且您的互联网连接 / DNS 工作正常。" +NoData="找到主机名,但没有所请求类型的数据。如果绑定到 IPv6 地址并且流式服务只有 IPv4 地址,则可能发生这种情况(请参阅设置→高级)。" +AddressNotAvailable="地址不可用。您可能试图绑定到一个无效的 IP 地址(请参阅设置→高级)。" SSLCertVerifyFailed="RTMP 服务器发送了无效的 SSL 证书。" diff --git a/plugins/obs-outputs/data/locale/zh-TW.ini b/plugins/obs-outputs/data/locale/zh-TW.ini index 15d5fc6..b444073 100644 --- a/plugins/obs-outputs/data/locale/zh-TW.ini +++ b/plugins/obs-outputs/data/locale/zh-TW.ini @@ -9,7 +9,7 @@ PermissionDenied="連線被阻擋。請檢查防火牆 / 防毒設定以確保 O ConnectionAborted="連線被中止。通常這代表您與串流服務之間有網際網路連線問題。" ConnectionReset="連線被對方重置。通常這代表您與串流服務之間有網際網路連線問題。" HostNotFound="找不到主機名稱。請確定輸入了一個有效的串流服務器且網路連線跟 DNS 工作正常。" -NoData="找到主機名稱,但沒有要求類型的資料。這可能發生在您綁定於 IPv6 位址但串流服務只有 IPv4 位址 (請看 設定/進階)。" -AddressNotAvailable="位址不可用。可能因為嘗試綁定到一個不正確 IP 位址(請確認 設定/進階 的設定)。" +NoData="找到主機名稱,但沒有要求類型的資料。這可能會在您綁定於 IPv6 位址但串流服務只有 IPv4 位址時發生(請看 設定 → 進階)。" +AddressNotAvailable="無法使用位址。可能是因為嘗試綁定到不正確的 IP 位址(請檢視 設定 → 進階 的設定)。" SSLCertVerifyFailed="RTMP 伺服器發送了一則不合法的 SSL 憑證。" diff --git a/plugins/obs-outputs/flv-output.c b/plugins/obs-outputs/flv-output.c index 680a954..de093aa 100644 --- a/plugins/obs-outputs/flv-output.c +++ b/plugins/obs-outputs/flv-output.c @@ -193,7 +193,7 @@ static void flv_output_stop(void *data, uint64_t ts) os_atomic_set_bool(&stream->stopping, true); } -static void flv_output_actual_stop(struct flv_output *stream) +static void flv_output_actual_stop(struct flv_output *stream, int code) { os_atomic_set_bool(&stream->active, false); @@ -203,7 +203,11 @@ static void flv_output_actual_stop(struct flv_output *stream) fclose(stream->file); } - obs_output_end_data_capture(stream->output); + if (code) { + obs_output_signal_stop(stream->output, code); + } else { + obs_output_end_data_capture(stream->output); + } info("FLV file output complete"); } @@ -218,9 +222,14 @@ static void flv_output_data(void *data, struct encoder_packet *packet) if (!active(stream)) goto unlock; + if (!packet) { + flv_output_actual_stop(stream, OBS_OUTPUT_ENCODE_ERROR); + goto unlock; + } + if (stopping(stream)) { if (packet->sys_dts_usec >= (int64_t)stream->stop_ts) { - flv_output_actual_stop(stream); + flv_output_actual_stop(stream, 0); goto unlock; } } diff --git a/plugins/obs-outputs/ftl-stream.c b/plugins/obs-outputs/ftl-stream.c index 1ea06de..6bd155f 100644 --- a/plugins/obs-outputs/ftl-stream.c +++ b/plugins/obs-outputs/ftl-stream.c @@ -72,6 +72,7 @@ struct ftl_stream { volatile bool active; volatile bool disconnected; + volatile bool encode_error; pthread_t send_thread; int max_shutdown_time_sec; @@ -516,8 +517,12 @@ static void *send_thread(void *data) } } + bool encode_error = os_atomic_load_bool(&stream->encode_error); + if (disconnected(stream)) { info("Disconnected from %s", stream->path.array); + } else if (encode_error) { + info("Encoder error, disconnecting"); } else { info("User stopped the stream"); } @@ -525,6 +530,8 @@ static void *send_thread(void *data) if (!stopping(stream)) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); + } else if (encode_error) { + obs_output_signal_stop(stream->output, OBS_OUTPUT_ENCODE_ERROR); } else { obs_output_end_data_capture(stream->output); } @@ -809,6 +816,13 @@ static void ftl_stream_data(void *data, struct encoder_packet *packet) if (disconnected(stream) || !active(stream)) return; + /* encoder failure */ + if (!packet) { + os_atomic_set_bool(&stream->encode_error, true); + os_sem_post(stream->send_sem); + return; + } + if (packet->type == OBS_ENCODER_VIDEO) obs_parse_avc_packet(&new_packet, packet); else @@ -1034,6 +1048,7 @@ static int init_connect(struct ftl_stream *stream) } os_atomic_set_bool(&stream->disconnected, false); + os_atomic_set_bool(&stream->encode_error, false); stream->total_bytes_sent = 0; stream->dropped_frames = 0; stream->min_priority = 0; diff --git a/plugins/obs-outputs/librtmp/handshake.h b/plugins/obs-outputs/librtmp/handshake.h index 8cd3e32..f14a0a8 100644 --- a/plugins/obs-outputs/librtmp/handshake.h +++ b/plugins/obs-outputs/librtmp/handshake.h @@ -34,9 +34,9 @@ typedef mbedtls_md_context_t *HMAC_CTX; #define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \ mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \ mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len) -#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig) -#define HMAC_close(ctx) mbedtls_md_free(ctx); free(ctx); ctx = NULL +#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len) +#define HMAC_finish(ctx, dig) mbedtls_md_hmac_finish(ctx, dig) +#define HMAC_close(ctx) mbedtls_md_free(ctx); free(ctx); ctx = NULL typedef mbedtls_arc4_context* RC4_handle; #define RC4_alloc(h) *h = malloc(sizeof(mbedtls_arc4_context)); mbedtls_arc4_init(*h) @@ -54,7 +54,7 @@ typedef mbedtls_arc4_context* RC4_handle; #define HMAC_CTX sha2_context #define HMAC_setup(ctx, key, len) sha2_hmac_starts(&ctx, (unsigned char *)key, len, 0) #define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig) +#define HMAC_finish(ctx, dig) sha2_hmac_finish(&ctx, dig) typedef arc4_context * RC4_handle; #define RC4_alloc(h) *h = malloc(sizeof(arc4_context)) @@ -73,7 +73,7 @@ typedef arc4_context * RC4_handle; #define HMAC_CTX struct hmac_sha256_ctx #define HMAC_setup(ctx, key, len) hmac_sha256_set_key(&ctx, len, key) #define HMAC_crunch(ctx, buf, len) hmac_sha256_update(&ctx, len, buf) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig) +#define HMAC_finish(ctx, dig) hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig) #define HMAC_close(ctx) typedef struct arcfour_ctx* RC4_handle; @@ -92,7 +92,7 @@ typedef struct arcfour_ctx* RC4_handle; #endif #define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key, len, EVP_sha256(), 0) #define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, buf, len) -#define HMAC_finish(ctx, dig, dlen) HMAC_Final(&ctx, dig, &dlen); HMAC_CTX_cleanup(&ctx) +#define HMAC_finish(ctx, dig, len) HMAC_Final(&ctx, dig, &len); HMAC_CTX_cleanup(&ctx) typedef RC4_KEY * RC4_handle; #define RC4_alloc(h) *h = malloc(sizeof(RC4_KEY)) @@ -139,7 +139,9 @@ static void InitRC4Encryption uint8_t * pubKeyOut, RC4_handle *rc4keyIn, RC4_handle *rc4keyOut) { uint8_t digest[SHA256_DIGEST_LENGTH]; +#if !(defined(USE_MBEDTLS) || defined(USE_POLARSSL) || defined(USE_GNUTLS)) unsigned int digestLen = 0; +#endif HMAC_CTX ctx; RC4_alloc(rc4keyIn); @@ -147,7 +149,11 @@ static void InitRC4Encryption HMAC_setup(ctx, secretKey, 128); HMAC_crunch(ctx, pubKeyIn, 128); +#if defined(USE_MBEDTLS) || defined(USE_POLARSSL) || defined(USE_GNUTLS) + HMAC_finish(ctx, digest); +#else HMAC_finish(ctx, digest, digestLen); +#endif RTMP_Log(RTMP_LOGDEBUG, "RC4 Out Key: "); RTMP_LogHex(RTMP_LOGDEBUG, digest, 16); @@ -156,7 +162,11 @@ static void InitRC4Encryption HMAC_setup(ctx, secretKey, 128); HMAC_crunch(ctx, pubKeyOut, 128); +#if defined(USE_MBEDTLS) || defined(USE_POLARSSL) || defined(USE_GNUTLS) + HMAC_finish(ctx, digest); +#else HMAC_finish(ctx, digest, digestLen); +#endif RTMP_Log(RTMP_LOGDEBUG, "RC4 In Key: "); RTMP_LogHex(RTMP_LOGDEBUG, digest, 16); @@ -303,7 +313,13 @@ HMACsha256(const uint8_t *message, size_t messageLen, const uint8_t *key, HMAC_setup(ctx, key, keylen); HMAC_crunch(ctx, message, messageLen); + +#if defined(USE_MBEDTLS) || defined(USE_POLARSSL) || defined(USE_GNUTLS) + digestLen = SHA256_DIGEST_LENGTH; + HMAC_finish(ctx, digest); +#else HMAC_finish(ctx, digest, digestLen); +#endif assert(digestLen == 32); } diff --git a/plugins/obs-outputs/librtmp/hashswf.c b/plugins/obs-outputs/librtmp/hashswf.c index b6c2b61..bbc8d31 100644 --- a/plugins/obs-outputs/librtmp/hashswf.c +++ b/plugins/obs-outputs/librtmp/hashswf.c @@ -39,9 +39,9 @@ typedef mbedtls_md_context_t *HMAC_CTX; #define HMAC_setup(ctx, key, len) ctx = malloc(sizeof(mbedtls_md_context_t)); mbedtls_md_init(ctx); \ mbedtls_md_setup(ctx, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1); \ mbedtls_md_hmac_starts(ctx, (const unsigned char *)key, len) -#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; mbedtls_md_hmac_finish(ctx, dig) -#define HMAC_close(ctx) free(ctx); mbedtls_md_free(ctx); ctx = NULL +#define HMAC_crunch(ctx, buf, len) mbedtls_md_hmac_update(ctx, buf, len) +#define HMAC_finish(ctx, dig) mbedtls_md_hmac_finish(ctx, dig) +#define HMAC_close(ctx) free(ctx); mbedtls_md_free(ctx); ctx = NULL #elif defined(USE_POLARSSL) #include @@ -51,7 +51,7 @@ typedef mbedtls_md_context_t *HMAC_CTX; #define HMAC_CTX sha2_context #define HMAC_setup(ctx, key, len) sha2_hmac_starts(&ctx, (unsigned char *)key, len, 0) #define HMAC_crunch(ctx, buf, len) sha2_hmac_update(&ctx, buf, len) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; sha2_hmac_finish(&ctx, dig) +#define HMAC_finish(ctx, dig) sha2_hmac_finish(&ctx, dig) #define HMAC_close(ctx) #elif defined(USE_GNUTLS) @@ -63,7 +63,7 @@ typedef mbedtls_md_context_t *HMAC_CTX; #define HMAC_CTX struct hmac_sha256_ctx #define HMAC_setup(ctx, key, len) hmac_sha256_set_key(&ctx, len, key) #define HMAC_crunch(ctx, buf, len) hmac_sha256_update(&ctx, len, buf) -#define HMAC_finish(ctx, dig, dlen) dlen = SHA256_DIGEST_LENGTH; hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig) +#define HMAC_finish(ctx, dig) hmac_sha256_digest(&ctx, SHA256_DIGEST_LENGTH, dig) #define HMAC_close(ctx) #else /* USE_OPENSSL */ @@ -73,7 +73,7 @@ typedef mbedtls_md_context_t *HMAC_CTX; #include #define HMAC_setup(ctx, key, len) HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, (unsigned char *)key, len, EVP_sha256(), 0) #define HMAC_crunch(ctx, buf, len) HMAC_Update(&ctx, (unsigned char *)buf, len) -#define HMAC_finish(ctx, dig, dlen) HMAC_Final(&ctx, (unsigned char *)dig, &dlen); +#define HMAC_finish(ctx, dig, len) HMAC_Final(&ctx, (unsigned char *)dig, &len); #define HMAC_close(ctx) HMAC_CTX_cleanup(&ctx) #endif @@ -658,7 +658,11 @@ RTMP_HashSWF(const char *url, unsigned int *size, unsigned char *hash, if (!in.first) { +#if defined(USE_MBEDTLS) || defined(USE_POLARSSL) || defined(USE_GNUTLS) + HMAC_finish(in.ctx, hash); +#else HMAC_finish(in.ctx, hash, hlen); +#endif *size = in.size; fprintf(f, "date: %s\n", date); diff --git a/plugins/obs-outputs/librtmp/rtmp.c b/plugins/obs-outputs/librtmp/rtmp.c index 09e965e..289ab51 100644 --- a/plugins/obs-outputs/librtmp/rtmp.c +++ b/plugins/obs-outputs/librtmp/rtmp.c @@ -34,6 +34,10 @@ #include +#if !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL 0 +#endif + #ifdef CRYPTO #ifdef __APPLE__ @@ -242,8 +246,10 @@ int RTMPPacket_Alloc(RTMPPacket *p, uint32_t nSize) { char *ptr; +#if ARCH_BITS == 32 if (nSize > SIZE_MAX - RTMP_MAX_HEADER_SIZE) return FALSE; +#endif ptr = calloc(1, nSize + RTMP_MAX_HEADER_SIZE); if (!ptr) @@ -928,6 +934,11 @@ RTMP_Connect0(RTMP *r, struct sockaddr * service, socklen_t addrlen) if (r->m_sb.sb_socket != INVALID_SOCKET) { +#ifndef _WIN32 +#ifdef SO_NOSIGPIPE + setsockopt(r->m_sb.sb_socket, SOL_SOCKET, SO_NOSIGPIPE, &(int){ 1 }, sizeof(int)); +#endif +#endif if(r->m_bindIP.addrLen) { if (bind(r->m_sb.sb_socket, (const struct sockaddr *)&r->m_bindIP.addr, r->m_bindIP.addrLen) < 0) @@ -4587,7 +4598,7 @@ RTMPSockBuf_Fill(RTMPSockBuf *sb) else #endif { - nBytes = recv(sb->sb_socket, sb->sb_start + sb->sb_size, nBytes, 0); + nBytes = recv(sb->sb_socket, sb->sb_start + sb->sb_size, nBytes, MSG_NOSIGNAL); } if (nBytes > 0) { @@ -4640,7 +4651,7 @@ RTMPSockBuf_Send(RTMPSockBuf *sb, const char *buf, int len) else #endif { - rc = send(sb->sb_socket, buf, len, 0); + rc = send(sb->sb_socket, buf, len, MSG_NOSIGNAL); } return rc; } diff --git a/plugins/obs-outputs/librtmp/rtmp.h b/plugins/obs-outputs/librtmp/rtmp.h index bd3abe6..dd90fb0 100644 --- a/plugins/obs-outputs/librtmp/rtmp.h +++ b/plugins/obs-outputs/librtmp/rtmp.h @@ -381,6 +381,7 @@ extern "C" void RTMP_Init(RTMP *r); void RTMP_Close(RTMP *r); RTMP *RTMP_Alloc(void); + void RTMP_TLS_Free(); void RTMP_Free(RTMP *r); void RTMP_EnableWrite(RTMP *r); diff --git a/plugins/obs-outputs/net-if.c b/plugins/obs-outputs/net-if.c index f467f2a..9f91cad 100644 --- a/plugins/obs-outputs/net-if.c +++ b/plugins/obs-outputs/net-if.c @@ -175,7 +175,7 @@ static inline PIP_ADAPTER_ADDRESSES get_adapters(void) { PIP_ADAPTER_ADDRESSES adapter = NULL; unsigned long ret = 0; - unsigned long out_buf_len = 4096; + unsigned long out_buf_len = 16384; unsigned long flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | diff --git a/plugins/obs-outputs/obs-outputs.c b/plugins/obs-outputs/obs-outputs.c index 43e0e89..e8fbe48 100644 --- a/plugins/obs-outputs/obs-outputs.c +++ b/plugins/obs-outputs/obs-outputs.c @@ -9,6 +9,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("obs-outputs", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "OBS core RTMP/FLV/null/FTL outputs"; +} extern struct obs_output_info rtmp_output_info; extern struct obs_output_info null_output_info; diff --git a/plugins/obs-outputs/rtmp-stream.c b/plugins/obs-outputs/rtmp-stream.c index def2788..93629df 100644 --- a/plugins/obs-outputs/rtmp-stream.c +++ b/plugins/obs-outputs/rtmp-stream.c @@ -92,6 +92,7 @@ static void rtmp_stream_destroy(void *data) } } + RTMP_TLS_Free(); free_packets(stream); dstr_free(&stream->path); dstr_free(&stream->key); @@ -486,8 +487,12 @@ static void *send_thread(void *data) } } + bool encode_error = os_atomic_load_bool(&stream->encode_error); + if (disconnected(stream)) { info("Disconnected from %s", stream->path.array); + } else if (encode_error) { + info("Encoder error, disconnecting"); } else { info("User stopped the stream"); } @@ -506,6 +511,8 @@ static void *send_thread(void *data) if (!stopping(stream)) { pthread_detach(stream->send_thread); obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED); + } else if (encode_error) { + obs_output_signal_stop(stream->output, OBS_OUTPUT_ENCODE_ERROR); } else { obs_output_end_data_capture(stream->output); } @@ -885,6 +892,7 @@ static bool init_connect(struct rtmp_stream *stream) return false; os_atomic_set_bool(&stream->disconnected, false); + os_atomic_set_bool(&stream->encode_error, false); stream->total_bytes_sent = 0; stream->dropped_frames = 0; stream->min_priority = 0; @@ -1102,6 +1110,13 @@ static void rtmp_stream_data(void *data, struct encoder_packet *packet) if (disconnected(stream) || !active(stream)) return; + /* encoder fail */ + if (!packet) { + os_atomic_set_bool(&stream->encode_error, true); + os_sem_post(stream->send_sem); + return; + } + if (packet->type == OBS_ENCODER_VIDEO) { if (!stream->got_first_video) { stream->start_dts_offset = diff --git a/plugins/obs-outputs/rtmp-stream.h b/plugins/obs-outputs/rtmp-stream.h index 1c4715a..77d1b44 100644 --- a/plugins/obs-outputs/rtmp-stream.h +++ b/plugins/obs-outputs/rtmp-stream.h @@ -59,6 +59,7 @@ struct rtmp_stream { volatile bool active; volatile bool disconnected; + volatile bool encode_error; pthread_t send_thread; int max_shutdown_time_sec; diff --git a/plugins/obs-text/data/locale/ar-SA.ini b/plugins/obs-text/data/locale/ar-SA.ini new file mode 100644 index 0000000..e7936ec --- /dev/null +++ b/plugins/obs-text/data/locale/ar-SA.ini @@ -0,0 +1,34 @@ +TextGDIPlus="نص (GDI+)" +Font="الخط" +Text="النص" +ReadFromFile="قراءة من ملف" +TextFile="ملف نصي (UTF-8)" +Filter.TextFiles="ملفات نصية" +Filter.AllFiles="جميع أنواع الملفات" +Color="اللون" +Opacity="الشفافيّة" +Gradient="تدرج" +Gradient.Color="لون التدرج" +Gradient.Opacity="شفافية التدرج" +Gradient.Direction="إتجاه التدرج" +BkColor="لون الخلفية" +BkOpacity="شفافية الخلفية" +Alignment="المحاذاة" +Alignment.Left="يسار" +Alignment.Center="وسط" +Alignment.Right="يمين" +Vertical="عمودياً/رأسياً" +VerticalAlignment="المحاذاة العمودية" +VerticalAlignment.Top="إلى أعلى" +VerticalAlignment.Bottom="إلى أسفل" +Outline="حد خارجي" +Outline.Size="حجم الحد الخارجي" +Outline.Color="لون الحد الخارجي" +Outline.Opacity="شفافية الحد الخارجي" +ChatlogMode="وضعية الدردشة" +ChatlogMode.Lines="الحد الأقصى لعدد الاسطر" +UseCustomExtents="استخدام أبعاد مخصصة لصندوق النص" +UseCustomExtents.Wrap="التفاف النص" +Width="العرض" +Height="الارتفاع" + diff --git a/plugins/obs-text/data/locale/ca-ES.ini b/plugins/obs-text/data/locale/ca-ES.ini index 0c81137..e7a6c22 100644 --- a/plugins/obs-text/data/locale/ca-ES.ini +++ b/plugins/obs-text/data/locale/ca-ES.ini @@ -31,4 +31,8 @@ UseCustomExtents="Utilitza extensions de text personalitzat" UseCustomExtents.Wrap="Ajusta" Width="Amplada" Height="Alçada" +Transform="Transformació de text" +Transform.None="Cap" +Transform.Uppercase="Majúscula" +Transform.Lowercase="Minúscula" diff --git a/plugins/obs-text/data/locale/cs-CZ.ini b/plugins/obs-text/data/locale/cs-CZ.ini index 9a0d01c..4abd92b 100644 --- a/plugins/obs-text/data/locale/cs-CZ.ini +++ b/plugins/obs-text/data/locale/cs-CZ.ini @@ -31,4 +31,8 @@ UseCustomExtents="Použít vlastní rozsah textu" UseCustomExtents.Wrap="Zalomit" Width="Šířka" Height="Výška" +Transform="Transformace textu" +Transform.None="Žádná" +Transform.Uppercase="VELKÝMI PÍSMENY" +Transform.Lowercase="malými písmeny" diff --git a/plugins/obs-text/data/locale/da-DK.ini b/plugins/obs-text/data/locale/da-DK.ini index f914eec..f8fed23 100644 --- a/plugins/obs-text/data/locale/da-DK.ini +++ b/plugins/obs-text/data/locale/da-DK.ini @@ -8,11 +8,11 @@ Filter.AllFiles="Alle filer" Color="Farve" Opacity="Gennemsigtighed" Gradient="Gradient" -Gradient.Color="Gradient farve" -Gradient.Opacity="Gradient gennemsigtighed" -Gradient.Direction="Gradient retning" +Gradient.Color="Gradientfarve" +Gradient.Opacity="Gradientgennemsigtighed" +Gradient.Direction="Gradientretning" BkColor="Baggrundsfarve" -BkOpacity="Baggrunds gennemsigtighed" +BkOpacity="Baggrundsgennemsigtighed" Alignment="Justering" Alignment.Left="Venstre" Alignment.Center="Centreret" @@ -22,13 +22,17 @@ VerticalAlignment="Vertikal justering" VerticalAlignment.Top="Top" VerticalAlignment.Bottom="Bund" Outline="Kontur" -Outline.Size="Kontur størrelse" -Outline.Color="Kontur farve" -Outline.Opacity="Kontur gennemsigtighed" -ChatlogMode="Chatlog tilstand" -ChatlogMode.Lines="Chatlog linebegrænsning" -UseCustomExtents="Brug tilpasset tekstomfang" +Outline.Size="Konturstørrelse" +Outline.Color="Konturfarve" +Outline.Opacity="Konturgennemsigtighed" +ChatlogMode="Chatlog-tilstand" +ChatlogMode.Lines="Chatlog-linebegrænsning" +UseCustomExtents="Benyt tilpasset tekstomfang" UseCustomExtents.Wrap="Ombryd" Width="Bredde" Height="Højde" +Transform="Teksttransformation" +Transform.None="Ingen" +Transform.Uppercase="Versaler" +Transform.Lowercase="Minuskler" diff --git a/plugins/obs-text/data/locale/de-DE.ini b/plugins/obs-text/data/locale/de-DE.ini index b8980fc..ee44b97 100644 --- a/plugins/obs-text/data/locale/de-DE.ini +++ b/plugins/obs-text/data/locale/de-DE.ini @@ -25,10 +25,14 @@ Outline="Kontur" Outline.Size="Konturgröße" Outline.Color="Konturfarbe" Outline.Opacity="Deckkraft der Kontur" -ChatlogMode="Chatlog-Modus" -ChatlogMode.Lines="Chatlog Zeilenlimit" -UseCustomExtents="Nutze benutzerdefinierten Textbereich" +ChatlogMode="Chatprotokollmodus" +ChatlogMode.Lines="Chatprotokollzeilenlimit" +UseCustomExtents="Benutzerdefinierten Textbereich benutzen" UseCustomExtents.Wrap="Umbruch" Width="Breite" Height="Höhe" +Transform="Texttransformation" +Transform.None="Keine" +Transform.Uppercase="Großbuchstaben" +Transform.Lowercase="Kleinbuchstaben" diff --git a/plugins/obs-text/data/locale/en-US.ini b/plugins/obs-text/data/locale/en-US.ini index d048ce7..260243b 100644 --- a/plugins/obs-text/data/locale/en-US.ini +++ b/plugins/obs-text/data/locale/en-US.ini @@ -31,3 +31,7 @@ UseCustomExtents="Use Custom Text Extents" UseCustomExtents.Wrap="Wrap" Width="Width" Height="Height" +Transform="Text Transform" +Transform.None="None" +Transform.Uppercase="Uppercase" +Transform.Lowercase="Lowercase" diff --git a/plugins/obs-text/data/locale/es-ES.ini b/plugins/obs-text/data/locale/es-ES.ini index 35cea31..d02ed34 100644 --- a/plugins/obs-text/data/locale/es-ES.ini +++ b/plugins/obs-text/data/locale/es-ES.ini @@ -31,4 +31,8 @@ UseCustomExtents="Usar extensiones de texto personalizado" UseCustomExtents.Wrap="Ajustar" Width="Ancho" Height="Alto" +Transform="Transformación de Texto" +Transform.None="Ninguno" +Transform.Uppercase="Mayúscula" +Transform.Lowercase="Minúscula" diff --git a/plugins/obs-text/data/locale/eu-ES.ini b/plugins/obs-text/data/locale/eu-ES.ini index 6c998b0..a03b482 100644 --- a/plugins/obs-text/data/locale/eu-ES.ini +++ b/plugins/obs-text/data/locale/eu-ES.ini @@ -31,4 +31,8 @@ UseCustomExtents="Erabili testu hedapen pertsonalak" UseCustomExtents.Wrap="Egokitu" Width="Zabalera" Height="Altuera" +Transform="Testu-eraldaketa" +Transform.None="Gabe" +Transform.Uppercase="Hizki-larriak" +Transform.Lowercase="Hizki-xeheak" diff --git a/plugins/obs-text/data/locale/fa-IR.ini b/plugins/obs-text/data/locale/fa-IR.ini new file mode 100644 index 0000000..b7d7218 --- /dev/null +++ b/plugins/obs-text/data/locale/fa-IR.ini @@ -0,0 +1,38 @@ +TextGDIPlus="متن (GDI+)" +Font="فونت" +Text="متن" +ReadFromFile="از فایل بخوان" +TextFile="فایل متن (UTF-8)" +Filter.TextFiles="پرونده های متنی" +Filter.AllFiles="همه فایل ها" +Color="رنگ" +Opacity="شفافیت" +Gradient="شیب" +Gradient.Color="رنگ شیب" +Gradient.Opacity="شفافیت شیب" +Gradient.Direction="جهت شیب" +BkColor="رنگ پس زمینه" +BkOpacity="شفافیت پس زمینه" +Alignment="تراز چینش" +Alignment.Left="چپ" +Alignment.Center="مرکز" +Alignment.Right="راست" +Vertical="عمودی" +VerticalAlignment="تراز عمودی" +VerticalAlignment.Top="بالا" +VerticalAlignment.Bottom="پایین" +Outline="برون نما" +Outline.Size="اندازه طرح کلی" +Outline.Color="رنگ طرح کلی" +Outline.Opacity="تاری دید" +ChatlogMode="حالت Chatlog" +ChatlogMode.Lines="محدودیت Chatlog Line" +UseCustomExtents="استفاده از متن سفارشی" +UseCustomExtents.Wrap="پیچ وتاب" +Width="عرض" +Height="ارتفاع" +Transform="تبدیل متن" +Transform.None="هیچ‌کدام" +Transform.Uppercase="حروف بزرگ" +Transform.Lowercase="حروف کوچک" + diff --git a/plugins/obs-text/data/locale/fi-FI.ini b/plugins/obs-text/data/locale/fi-FI.ini index 1df85fd..51b8991 100644 --- a/plugins/obs-text/data/locale/fi-FI.ini +++ b/plugins/obs-text/data/locale/fi-FI.ini @@ -31,4 +31,8 @@ UseCustomExtents="Käytä valinnaisia fonttilaajennuksia" UseCustomExtents.Wrap="Sido" Width="Leveys" Height="Korkeus" +Transform="Tekstin muunnos" +Transform.None="Ei mitään" +Transform.Uppercase="Isot kirjaimet" +Transform.Lowercase="Pienet kirjaimet" diff --git a/plugins/obs-text/data/locale/fr-FR.ini b/plugins/obs-text/data/locale/fr-FR.ini index 3a9bbca..0aac42b 100644 --- a/plugins/obs-text/data/locale/fr-FR.ini +++ b/plugins/obs-text/data/locale/fr-FR.ini @@ -1,7 +1,7 @@ TextGDIPlus="Texte (GDI+)" Font="Police" Text="Texte" -ReadFromFile="Lire depuis un fichier" +ReadFromFile="Lire à partir d'un fichier" TextFile="Fichier texte (UTF-8)" Filter.TextFiles="Fichiers texte" Filter.AllFiles="Tous les fichiers" @@ -31,4 +31,8 @@ UseCustomExtents="Utiliser une taille personnalisée" UseCustomExtents.Wrap="Retour à la ligne automatique" Width="Largeur" Height="Hauteur" +Transform="Transformer le texte" +Transform.None="Aucune" +Transform.Uppercase="Majuscules" +Transform.Lowercase="Minuscules" diff --git a/plugins/obs-text/data/locale/hu-HU.ini b/plugins/obs-text/data/locale/hu-HU.ini index b5d5966..d622ff9 100644 --- a/plugins/obs-text/data/locale/hu-HU.ini +++ b/plugins/obs-text/data/locale/hu-HU.ini @@ -31,4 +31,8 @@ UseCustomExtents="Egyedi szövegdoboz használata" UseCustomExtents.Wrap="Sortörés" Width="Szélesség" Height="Magasság" +Transform="Szöveg alakítása" +Transform.None="Egyik sem" +Transform.Uppercase="Nagybetűs" +Transform.Lowercase="Kisbetűs" diff --git a/plugins/obs-text/data/locale/it-IT.ini b/plugins/obs-text/data/locale/it-IT.ini index 5200095..1671058 100644 --- a/plugins/obs-text/data/locale/it-IT.ini +++ b/plugins/obs-text/data/locale/it-IT.ini @@ -1,5 +1,5 @@ TextGDIPlus="Testo (GDI+)" -Font="Font" +Font="Carattere" Text="Testo" ReadFromFile="Leggi da file" TextFile="File di testo (UTF-8)" @@ -8,27 +8,31 @@ Filter.AllFiles="Tutti i file" Color="Colore" Opacity="Opacità" Gradient="Sfumato" -Gradient.Color="Colore sfumatura" -Gradient.Opacity="Opacità sfumatura" -Gradient.Direction="Direzione sfumatura" +Gradient.Color="Colore della sfumatura" +Gradient.Opacity="Opacità della sfumatura" +Gradient.Direction="Direzione della sfumatura" BkColor="Colore dello sfondo" -BkOpacity="Opacità Sfondo" +BkOpacity="Opacità dello sfondo" Alignment="Allineamento" Alignment.Left="A sinistra" Alignment.Center="Al centro" Alignment.Right="A destra" Vertical="Verticale" VerticalAlignment="Allineamento verticale" -VerticalAlignment.Top="Alto" -VerticalAlignment.Bottom="Dal basso" -Outline="Contorno" -Outline.Size="Dimensione contorno" +VerticalAlignment.Top="In alto" +VerticalAlignment.Bottom="In basso" +Outline="Contorno del testo" +Outline.Size="Dimensione del contorno" Outline.Color="Colore del contorno" -Outline.Opacity="Opacità contorno" -ChatlogMode="Modalità Chatlog" -ChatlogMode.Lines="Limite linea Chatlog" -UseCustomExtents="Usa personalizzazioni testo" +Outline.Opacity="Opacità del contorno" +ChatlogMode="Modalità chat" +ChatlogMode.Lines="Righe da visualizzare in modalità chat" +UseCustomExtents="Utilizza un formato del testo personalizzato" UseCustomExtents.Wrap="A capo automatico" Width="Larghezza" Height="Altezza" +Transform="Trasformazione del testo" +Transform.None="Nessuna" +Transform.Uppercase="In lettere maiuscole" +Transform.Lowercase="In lettere minuscole" diff --git a/plugins/obs-text/data/locale/ja-JP.ini b/plugins/obs-text/data/locale/ja-JP.ini index 386b4ce..e2d0b17 100644 --- a/plugins/obs-text/data/locale/ja-JP.ini +++ b/plugins/obs-text/data/locale/ja-JP.ini @@ -31,4 +31,8 @@ UseCustomExtents="テキスト領域の範囲を指定する" UseCustomExtents.Wrap="折り返す" Width="幅" Height="高さ" +Transform="テキスト変換" +Transform.None="未設定" +Transform.Uppercase="大文字" +Transform.Lowercase="小文字" diff --git a/plugins/obs-text/data/locale/ka-GE.ini b/plugins/obs-text/data/locale/ka-GE.ini index 37643c8..e36caa6 100644 --- a/plugins/obs-text/data/locale/ka-GE.ini +++ b/plugins/obs-text/data/locale/ka-GE.ini @@ -7,12 +7,12 @@ Filter.TextFiles="ტექსტური ფაილები" Filter.AllFiles="ყველა ფაილი" Color="ფერი" Opacity="გაუმჭვირვალობა" -Gradient="გრადიენტი" -Gradient.Color="გრადიენტის ფერი" -Gradient.Opacity="გრადიენტის გაუმჭვირვალობა" -Gradient.Direction="გრადიენტის მიმართულება" +Gradient="გარდამავალი" +Gradient.Color="გარდამავალი ფერი" +Gradient.Opacity="გარდამავლობის გაუმჭვირვალობა" +Gradient.Direction="გარდამავლობის მიმართულება" BkColor="ფონის ფერი" -BkOpacity="ფონის გაუმჭვივალობა" +BkOpacity="ფონის გამჭვირვალობა" Alignment="განლაგება" Alignment.Left="მარცხნივ" Alignment.Center="შუაში" @@ -31,4 +31,8 @@ UseCustomExtents="ტექსტის ველის მითითებუ UseCustomExtents.Wrap="ხაზზე გადატანა" Width="სიგანე" Height="სიმაღლე" +Transform="ტექსტის გარდაქმნა" +Transform.None="არცერთი" +Transform.Uppercase="მთავრული" +Transform.Lowercase="ნუსხური" diff --git a/plugins/obs-text/data/locale/ko-KR.ini b/plugins/obs-text/data/locale/ko-KR.ini index 1d2a0dd..e52ecf3 100644 --- a/plugins/obs-text/data/locale/ko-KR.ini +++ b/plugins/obs-text/data/locale/ko-KR.ini @@ -31,4 +31,8 @@ UseCustomExtents="사용자 정의 텍스트 설정" UseCustomExtents.Wrap="자동 줄 바꿈" Width="너비" Height="높이" +Transform="글자 변환" +Transform.None="없음" +Transform.Uppercase="대문자" +Transform.Lowercase="소문자" diff --git a/plugins/obs-text/data/locale/mn-MN.ini b/plugins/obs-text/data/locale/mn-MN.ini new file mode 100644 index 0000000..c622ccf --- /dev/null +++ b/plugins/obs-text/data/locale/mn-MN.ini @@ -0,0 +1,25 @@ +Font="Фонт" +Text="Текст" +ReadFromFile="Файлаас уншуулах" +TextFile="Текст Файл (UTF-8)" +Filter.TextFiles="Текст файлууд" +Filter.AllFiles="Бүх файлууд" +Color="Өнгө" +Opacity="Харанхуйлах" +Gradient="Уусгалтай" +Gradient.Color="Уусгалтай Өнгө" +Gradient.Opacity="Уусгалтай Харанхуйлах" +BkColor="Дэвсгэрийн Өнгө" +Alignment.Left="Зүүн" +Alignment.Center="Төв" +Alignment.Right="Баруун" +Vertical="Босоо" +VerticalAlignment.Top="Дээд хэсэг" +VerticalAlignment.Bottom="Доод хэсэг" +Outline="Гадуурх зураас" +Outline.Size="Гадуурх Зураасны Хэмжээ" +Outline.Color="Гадуурх Зураасны Өнгө" +UseCustomExtents.Wrap="Доош Эгнээх" +Width="Өргөн" +Height="Өндөр" + diff --git a/plugins/obs-text/data/locale/nb-NO.ini b/plugins/obs-text/data/locale/nb-NO.ini index 97eed0a..eeb9709 100644 --- a/plugins/obs-text/data/locale/nb-NO.ini +++ b/plugins/obs-text/data/locale/nb-NO.ini @@ -31,4 +31,8 @@ UseCustomExtents="Bruk egendefinerte tekst-utvidelser" UseCustomExtents.Wrap="Ordbrytning" Width="Bredde" Height="Høyde" +Transform="Tekst transformering" +Transform.None="Ingen" +Transform.Uppercase="Store bokstaver" +Transform.Lowercase="Små bokstaver" diff --git a/plugins/obs-text/data/locale/nl-NL.ini b/plugins/obs-text/data/locale/nl-NL.ini index 098be9f..c9bcab5 100644 --- a/plugins/obs-text/data/locale/nl-NL.ini +++ b/plugins/obs-text/data/locale/nl-NL.ini @@ -31,4 +31,8 @@ UseCustomExtents="Aangepaste tekst-extents gebruiken" UseCustomExtents.Wrap="Terugloop" Width="Breedte" Height="Hoogte" +Transform="Tekst transformatie" +Transform.None="Geen" +Transform.Uppercase="Hoofdletters" +Transform.Lowercase="Kleine letters" diff --git a/plugins/obs-text/data/locale/pl-PL.ini b/plugins/obs-text/data/locale/pl-PL.ini index 384ca15..12c3eca 100644 --- a/plugins/obs-text/data/locale/pl-PL.ini +++ b/plugins/obs-text/data/locale/pl-PL.ini @@ -31,4 +31,8 @@ UseCustomExtents="Użyj niestandardowego zakresu tekstu" UseCustomExtents.Wrap="Zawiń" Width="Szerokość" Height="Wysokość" +Transform="Przekształcanie tekstu" +Transform.None="Brak" +Transform.Uppercase="Wielkie litery" +Transform.Lowercase="Małe litery" diff --git a/plugins/obs-text/data/locale/pt-BR.ini b/plugins/obs-text/data/locale/pt-BR.ini index 64a966e..5b6e42d 100644 --- a/plugins/obs-text/data/locale/pt-BR.ini +++ b/plugins/obs-text/data/locale/pt-BR.ini @@ -31,4 +31,8 @@ UseCustomExtents="Usar extensões de texto personalizadas" UseCustomExtents.Wrap="Ajustar" Width="Largura" Height="Altura" +Transform="Transformação" +Transform.None="Nenhuma" +Transform.Uppercase="Letras Maiúsculas" +Transform.Lowercase="Letras Minúsculas" diff --git a/plugins/obs-text/data/locale/pt-PT.ini b/plugins/obs-text/data/locale/pt-PT.ini index d2338c7..555ac8c 100644 --- a/plugins/obs-text/data/locale/pt-PT.ini +++ b/plugins/obs-text/data/locale/pt-PT.ini @@ -7,10 +7,12 @@ Gradient="Gradiente" Gradient.Color="Cor do Gradiente" Gradient.Opacity="Opacidade do Gradiente" Gradient.Direction="Direção do Gradiente" +Alignment="Alinhamento" Alignment.Left="Esquerda" Alignment.Center="Centro" Alignment.Right="Direita" Vertical="Vertical" +VerticalAlignment="Alinhamento Vertical" VerticalAlignment.Top="Topo" Width="Largura" Height="Altura" diff --git a/plugins/obs-text/data/locale/ru-RU.ini b/plugins/obs-text/data/locale/ru-RU.ini index 07dafec..45c66d7 100644 --- a/plugins/obs-text/data/locale/ru-RU.ini +++ b/plugins/obs-text/data/locale/ru-RU.ini @@ -31,4 +31,8 @@ UseCustomExtents="Свои размеры текстового поля" UseCustomExtents.Wrap="Перенос строк" Width="Ширина" Height="Высота" +Transform="Преобразование текста" +Transform.None="Нет" +Transform.Uppercase="Верхний регистр" +Transform.Lowercase="Нижний регистр" diff --git a/plugins/obs-text/data/locale/sk-SK.ini b/plugins/obs-text/data/locale/sk-SK.ini index 9704ae3..3199c88 100644 --- a/plugins/obs-text/data/locale/sk-SK.ini +++ b/plugins/obs-text/data/locale/sk-SK.ini @@ -31,4 +31,8 @@ UseCustomExtents="Použiť vlastné rozsahy textu" UseCustomExtents.Wrap="Zalomiť" Width="Šírka" Height="Výška" +Transform="Transformácia textu" +Transform.None="Žiadna" +Transform.Uppercase="Veľké písmená" +Transform.Lowercase="Malé písmená" diff --git a/plugins/obs-text/data/locale/sv-SE.ini b/plugins/obs-text/data/locale/sv-SE.ini index 7f108f8..402c94a 100644 --- a/plugins/obs-text/data/locale/sv-SE.ini +++ b/plugins/obs-text/data/locale/sv-SE.ini @@ -31,4 +31,8 @@ UseCustomExtents="Använd anpassade textmått" UseCustomExtents.Wrap="Radbryt" Width="Bredd" Height="Höjd" +Transform="Textomvandling" +Transform.None="Ingen" +Transform.Uppercase="Versaler" +Transform.Lowercase="Gemener" diff --git a/plugins/obs-text/data/locale/tr-TR.ini b/plugins/obs-text/data/locale/tr-TR.ini index 289e570..a54bcc4 100644 --- a/plugins/obs-text/data/locale/tr-TR.ini +++ b/plugins/obs-text/data/locale/tr-TR.ini @@ -31,4 +31,8 @@ UseCustomExtents="İsteğe Bağlı Metin Boyutu Kullan" UseCustomExtents.Wrap="Metni Kaydır" Width="Genişlik" Height="Yükseklik" +Transform="Metin Dönüşümü" +Transform.None="Yok" +Transform.Uppercase="Büyük harf" +Transform.Lowercase="Küçük harf" diff --git a/plugins/obs-text/data/locale/uk-UA.ini b/plugins/obs-text/data/locale/uk-UA.ini index a6c9ba9..6f489bb 100644 --- a/plugins/obs-text/data/locale/uk-UA.ini +++ b/plugins/obs-text/data/locale/uk-UA.ini @@ -31,4 +31,8 @@ UseCustomExtents="Особливі властивості текстового UseCustomExtents.Wrap="Перенос слів" Width="Ширина" Height="Висота" +Transform="Перетворення тексту" +Transform.None="Немає" +Transform.Uppercase="До верхнього регістру" +Transform.Lowercase="До нижнього регістру" diff --git a/plugins/obs-text/data/locale/zh-CN.ini b/plugins/obs-text/data/locale/zh-CN.ini index 83d0361..f7a084b 100644 --- a/plugins/obs-text/data/locale/zh-CN.ini +++ b/plugins/obs-text/data/locale/zh-CN.ini @@ -31,4 +31,8 @@ UseCustomExtents="使用自定义文本区" UseCustomExtents.Wrap="自动换行" Width="宽度" Height="高度" +Transform="文本转换" +Transform.None="无" +Transform.Uppercase="大写" +Transform.Lowercase="小写" diff --git a/plugins/obs-text/data/locale/zh-TW.ini b/plugins/obs-text/data/locale/zh-TW.ini index 8f18a35..29010fa 100644 --- a/plugins/obs-text/data/locale/zh-TW.ini +++ b/plugins/obs-text/data/locale/zh-TW.ini @@ -31,4 +31,8 @@ UseCustomExtents="使用自動文字區塊大小" UseCustomExtents.Wrap="自動換行" Width="寬度" Height="高度" +Transform="文字變型" +Transform.None="無" +Transform.Uppercase="大寫" +Transform.Lowercase="小寫" diff --git a/plugins/obs-text/gdiplus/obs-text.cpp b/plugins/obs-text/gdiplus/obs-text.cpp index 2efc108..3619126 100644 --- a/plugins/obs-text/gdiplus/obs-text.cpp +++ b/plugins/obs-text/gdiplus/obs-text.cpp @@ -62,6 +62,7 @@ using namespace Gdiplus; #define S_EXTENTS_WRAP "extents_wrap" #define S_EXTENTS_CX "extents_cx" #define S_EXTENTS_CY "extents_cy" +#define S_TRANSFORM "transform" #define S_ALIGN_LEFT "left" #define S_ALIGN_CENTER "center" @@ -71,6 +72,10 @@ using namespace Gdiplus; #define S_VALIGN_CENTER S_ALIGN_CENTER #define S_VALIGN_BOTTOM "bottom" +#define S_TRANSFORM_NONE 0 +#define S_TRANSFORM_UPPERCASE 1 +#define S_TRANSFORM_LOWERCASE 2 + #define T_(v) obs_module_text(v) #define T_FONT T_("Font") #define T_USE_FILE T_("ReadFromFile") @@ -97,6 +102,7 @@ using namespace Gdiplus; #define T_EXTENTS_WRAP T_("UseCustomExtents.Wrap") #define T_EXTENTS_CX T_("Width") #define T_EXTENTS_CY T_("Height") +#define T_TRANSFORM T_("Transform") #define T_FILTER_TEXT_FILES T_("Filter.TextFiles") #define T_FILTER_ALL_FILES T_("Filter.AllFiles") @@ -109,6 +115,10 @@ using namespace Gdiplus; #define T_VALIGN_CENTER T_ALIGN_CENTER #define T_VALIGN_BOTTOM T_("VerticalAlignment.Bottom") +#define T_TRANSFORM_NONE T_("Transform.None") +#define T_TRANSFORM_UPPERCASE T_("Transform.Uppercase") +#define T_TRANSFORM_LOWERCASE T_("Transform.Lowercase") + /* ------------------------------------------------------------------------- */ static inline DWORD get_alpha_val(uint32_t opacity) @@ -229,6 +239,8 @@ struct TextSource { uint32_t extents_cx = 0; uint32_t extents_cy = 0; + int text_transform = S_TRANSFORM_NONE; + bool chatlog_mode = false; int chatlog_lines = 6; @@ -266,7 +278,7 @@ struct TextSource { inline void Update(obs_data_t *settings); inline void Tick(float seconds); - inline void Render(gs_effect_t *effect); + inline void Render(); }; static time_t get_modified_timestamp(const char *filename) @@ -659,6 +671,7 @@ inline void TextSource::Update(obs_data_t *s) bool new_extents_wrap = obs_data_get_bool(s, S_EXTENTS_WRAP); uint32_t n_extents_cx = obs_data_get_uint32(s, S_EXTENTS_CX); uint32_t n_extents_cy = obs_data_get_uint32(s, S_EXTENTS_CY); + int new_text_transform = (int)obs_data_get_int(s, S_TRANSFORM); const char *font_face = obs_data_get_string(font_obj, "face"); int font_size = (int)obs_data_get_int(font_obj, "size"); @@ -712,6 +725,7 @@ inline void TextSource::Update(obs_data_t *s) wrap = new_extents_wrap; extents_cx = n_extents_cx; extents_cy = n_extents_cy; + text_transform = new_text_transform; if (!gradient) { color2 = color; @@ -737,6 +751,10 @@ inline void TextSource::Update(obs_data_t *s) if (!text.empty()) text.push_back('\n'); } + if(text_transform == S_TRANSFORM_UPPERCASE) + transform(text.begin(), text.end(), text.begin(), towupper); + else if(text_transform == S_TRANSFORM_LOWERCASE) + transform(text.begin(), text.end(), text.begin(), towlower); use_outline = new_outline; outline_color = new_o_color; @@ -789,13 +807,22 @@ inline void TextSource::Tick(float seconds) } } -inline void TextSource::Render(gs_effect_t *effect) +inline void TextSource::Render() { if (!tex) return; + gs_effect_t *effect = obs_get_base_effect(OBS_EFFECT_DEFAULT); + gs_technique_t *tech = gs_effect_get_technique(effect, "Draw"); + + gs_technique_begin(tech); + gs_technique_begin_pass(tech, 0); + gs_effect_set_texture(gs_effect_get_param_by_name(effect, "image"), tex); gs_draw_sprite(tex, 0, cx, cy); + + gs_technique_end_pass(tech); + gs_technique_end(tech); } /* ------------------------------------------------------------------------- */ @@ -804,6 +831,10 @@ static ULONG_PTR gdip_token = 0; OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("obs-text", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "Windows GDI+ text source"; +} #define set_vis(var, val, show) \ do { \ @@ -898,6 +929,13 @@ static obs_properties_t *get_properties(void *data) obs_properties_add_path(props, S_FILE, T_FILE, OBS_PATH_FILE, filter.c_str(), path.c_str()); + p = obs_properties_add_list(props, S_TRANSFORM, T_TRANSFORM, + OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_INT); + obs_property_list_add_int(p, T_TRANSFORM_NONE, S_TRANSFORM_NONE); + obs_property_list_add_int(p, T_TRANSFORM_UPPERCASE, S_TRANSFORM_UPPERCASE); + obs_property_list_add_int(p, T_TRANSFORM_LOWERCASE, S_TRANSFORM_LOWERCASE); + + obs_properties_add_bool(props, S_VERTICAL, T_VERTICAL); obs_properties_add_color(props, S_COLOR, T_COLOR); obs_properties_add_int_slider(props, S_OPACITY, T_OPACITY, 0, 100, 1); @@ -910,7 +948,7 @@ static obs_properties_t *get_properties(void *data) T_GRADIENT_OPACITY, 0, 100, 1); obs_properties_add_float_slider(props, S_GRADIENT_DIR, T_GRADIENT_DIR, 0, 360, 0.1); - + obs_properties_add_color(props, S_BKCOLOR, T_BKCOLOR); obs_properties_add_int_slider(props, S_BKOPACITY, T_BKOPACITY, 0, 100, 1); @@ -956,7 +994,7 @@ bool obs_module_load(void) obs_source_info si = {}; si.id = "text_gdiplus"; si.type = OBS_SOURCE_TYPE_INPUT; - si.output_flags = OBS_SOURCE_VIDEO; + si.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW; si.get_properties = get_properties; si.get_name = [] (void*) @@ -1002,6 +1040,7 @@ bool obs_module_load(void) obs_data_set_default_bool(settings, S_EXTENTS_WRAP, true); obs_data_set_default_int(settings, S_EXTENTS_CX, 100); obs_data_set_default_int(settings, S_EXTENTS_CY, 100); + obs_data_set_default_int(settings, S_TRANSFORM, S_TRANSFORM_NONE); obs_data_release(font_obj); }; @@ -1013,9 +1052,9 @@ bool obs_module_load(void) { reinterpret_cast(data)->Tick(seconds); }; - si.video_render = [] (void *data, gs_effect_t *effect) + si.video_render = [] (void *data, gs_effect_t*) { - reinterpret_cast(data)->Render(effect); + reinterpret_cast(data)->Render(); }; obs_register_source(&si); diff --git a/plugins/obs-transitions/data/fade_to_color_transition.effect b/plugins/obs-transitions/data/fade_to_color_transition.effect index 130d44a..0e8417c 100644 --- a/plugins/obs-transitions/data/fade_to_color_transition.effect +++ b/plugins/obs-transitions/data/fade_to_color_transition.effect @@ -14,8 +14,6 @@ struct VertData { float2 uv : TEXCOORD0; }; -#include "premultiplied.inc" - VertData VSDefault(VertData v_in) { VertData vert_out; @@ -26,7 +24,8 @@ VertData VSDefault(VertData v_in) float4 PSFadeToColor(VertData v_in) : TARGET { - return lerp(convert_pmalpha(tex.Sample(textureSampler, v_in.uv)), color, swp); + float4 premultiplied = float4(color.rgb * color.a, color.a); + return lerp(tex.Sample(textureSampler, v_in.uv), premultiplied, swp); } technique FadeToColor diff --git a/plugins/obs-transitions/data/fade_transition.effect b/plugins/obs-transitions/data/fade_transition.effect index bba5031..f728f3a 100644 --- a/plugins/obs-transitions/data/fade_transition.effect +++ b/plugins/obs-transitions/data/fade_transition.effect @@ -14,8 +14,6 @@ struct VertData { float2 uv : TEXCOORD0; }; -#include "premultiplied.inc" - VertData VSDefault(VertData v_in) { VertData vert_out; @@ -26,8 +24,8 @@ VertData VSDefault(VertData v_in) float4 PSFade(VertData v_in) : TARGET { - float4 a_val = convert_pmalpha(tex_a.Sample(textureSampler, v_in.uv)); - float4 b_val = convert_pmalpha(tex_b.Sample(textureSampler, v_in.uv)); + float4 a_val = tex_a.Sample(textureSampler, v_in.uv); + float4 b_val = tex_b.Sample(textureSampler, v_in.uv); return lerp(a_val, b_val, fade_val); } diff --git a/plugins/obs-transitions/data/locale/da-DK.ini b/plugins/obs-transitions/data/locale/da-DK.ini index 52e60c6..18c3b2f 100644 --- a/plugins/obs-transitions/data/locale/da-DK.ini +++ b/plugins/obs-transitions/data/locale/da-DK.ini @@ -1,39 +1,39 @@ FadeTransition="Overgang" CutTransition="Klip" -SwipeTransition="Swipe" +SwipeTransition="Stryg" SlideTransition="Glide" StingerTransition="Stinger-overgang" -FadeToColorTransition="Fade til farve" +FadeToColorTransition="Farveovergang" Direction="Retning" Direction.Left="Venstre" Direction.Right="Højre" Direction.Up="Op" Direction.Down="Ned" -SwipeIn="Swipe ind" +SwipeIn="Stryg ind" Color="Farve" VideoFile="Videofil" -TransitionPoint="Overgangspunkt (millisekunder)" -TransitionPointFrame="Overgangspunkt (ramme)" +TransitionPoint="Overgangspunkt (millisek.)" +TransitionPointFrame="Overgangspunkt (billede)" TransitionPointType="Overgangspunkttype" TransitionPointTypeFrame="Billede" -TransitionPointTypeTime="Tid (ms)" +TransitionPointTypeTime="Tid (millisek.)" AudioFadeStyle="Lydudtoningsstil" AudioFadeStyle.FadeOutFadeIn="Udtone til overgangspunkt, dernæst indtone" AudioFadeStyle.CrossFade="Krydstoning (crossfade)" -SwitchPoint="Farvepeakpunkt (procent)" -LumaWipeTransition="Luma overgang" +SwitchPoint="Farvespidspunkt (procent)" +LumaWipeTransition="Luma-overgang" LumaWipe.Image="Billede" -LumaWipe.Invert="Inverter" +LumaWipe.Invert="Invertér" LumaWipe.Softness="Blødhed" LumaWipe.Type.BarndoorBottomLeft="Stalddør nederst til venstre" LumaWipe.Type.BarndoorHorizontal="Stalddør horisontal" LumaWipe.Type.BarndoorTopLeft="Stalddør øverst til venstre" LumaWipe.Type.BarndoorVertical="Stalddør vertikal" LumaWipe.Type.BlindsHorizontal="Persienne horisontal" -LumaWipe.Type.BoxBottomLeft="Boks nederst til venstre" -LumaWipe.Type.BoxBottomRight="Boks nederst til højre" -LumaWipe.Type.BoxTopLeft="Boks øverst til venstre" -LumaWipe.Type.BoxTopRight="Boks øverst til højre" +LumaWipe.Type.BoxBottomLeft="Kasse nederst til venstre" +LumaWipe.Type.BoxBottomRight="Kasse nederst til højre" +LumaWipe.Type.BoxTopLeft="Kasse øverst til venstre" +LumaWipe.Type.BoxTopRight="Kasse øverst til højre" LumaWipe.Type.Burst="Sprængning" LumaWipe.Type.CheckerboardSmall="Små skaktern" LumaWipe.Type.Circles="Cirkler" diff --git a/plugins/obs-transitions/data/locale/de-DE.ini b/plugins/obs-transitions/data/locale/de-DE.ini index 8913752..3e2a034 100644 --- a/plugins/obs-transitions/data/locale/de-DE.ini +++ b/plugins/obs-transitions/data/locale/de-DE.ini @@ -3,7 +3,7 @@ CutTransition="Schnitt" SwipeTransition="Swipe" SlideTransition="Slide" StingerTransition="Stinger" -FadeToColorTransition="Fade to Color" +FadeToColorTransition="Farbübergang" Direction="Richtung" Direction.Left="Links" Direction.Right="Rechts" @@ -17,13 +17,13 @@ TransitionPointFrame="Übergangspunkt (Frame)" TransitionPointType="Übergangspunkttyp" TransitionPointTypeFrame="Frame" TransitionPointTypeTime="Zeit (Millisekunden)" -AudioFadeStyle="Audio Überblendstil" +AudioFadeStyle="Audioüberblendstil" AudioFadeStyle.FadeOutFadeIn="Zu Übergangspunkt ausblenden und dann einblenden" AudioFadeStyle.CrossFade="Überblendung" -SwitchPoint="Peakfarbpunkt (Prozent)" +SwitchPoint="Spitzenfarbpunkt (in Prozent)" LumaWipeTransition="Luma Wipe" LumaWipe.Image="Bild" -LumaWipe.Invert="Invertieren" +LumaWipe.Invert="Umkehren" LumaWipe.Softness="Weichheit" LumaWipe.Type.BarndoorBottomLeft="Scheunentor unten links" LumaWipe.Type.BarndoorHorizontal="Scheunentor Horizontal" @@ -61,6 +61,6 @@ LumaWipe.Type.ZigzagHorizontal="Zigzag horizontal" LumaWipe.Type.ZigzagVertical="Zigzag vertikal" AudioMonitoring="Audiomonitoring" AudioMonitoring.None="Monitor aus" -AudioMonitoring.MonitorOnly="Nur Monitor (Ausgabe stumm schalten)" +AudioMonitoring.MonitorOnly="Nur Monitor (Ausgabe stummschalten)" AudioMonitoring.Both="Monitor und Ausgabe" diff --git a/plugins/obs-transitions/data/locale/eu-ES.ini b/plugins/obs-transitions/data/locale/eu-ES.ini index 688e65b..f155235 100644 --- a/plugins/obs-transitions/data/locale/eu-ES.ini +++ b/plugins/obs-transitions/data/locale/eu-ES.ini @@ -60,7 +60,7 @@ LumaWipe.Type.Watercolor="Akuarela" LumaWipe.Type.ZigzagHorizontal="Sigi-saga horizontala" LumaWipe.Type.ZigzagVertical="Sigi-saga bertikala" AudioMonitoring="Adioaren monitorizazioa" -AudioMonitoring.None="Monitorea itzalita" -AudioMonitoring.MonitorOnly="Monitorea bakarrik (isildu irteera)" +AudioMonitoring.None="Ez monitorizatu" +AudioMonitoring.MonitorOnly="Monitorea bakarrik (irteera mututua)" AudioMonitoring.Both="Monitorea eta irteera" diff --git a/plugins/obs-transitions/data/locale/fr-FR.ini b/plugins/obs-transitions/data/locale/fr-FR.ini index e4ed43c..6fcb4b3 100644 --- a/plugins/obs-transitions/data/locale/fr-FR.ini +++ b/plugins/obs-transitions/data/locale/fr-FR.ini @@ -3,7 +3,7 @@ CutTransition="Coupure" SwipeTransition="Balayage" SlideTransition="Glissement" StingerTransition="Stinger" -FadeToColorTransition="Fondu avec couleur" +FadeToColorTransition="Fondu vers couleur" Direction="Direction" Direction.Left="Gauche" Direction.Right="Droite" @@ -21,7 +21,7 @@ AudioFadeStyle="Style de fondu audio" AudioFadeStyle.FadeOutFadeIn="Fondu en fermeture jusqu'au point de transition puis fondu en ouverture" AudioFadeStyle.CrossFade="Fondu enchaîné" SwitchPoint="Point de couleur maximal (pourcentage)" -LumaWipeTransition="Luma" +LumaWipeTransition="Balayage Luma" LumaWipe.Image="Image" LumaWipe.Invert="Inverser" LumaWipe.Softness="Douceur" @@ -59,8 +59,8 @@ LumaWipe.Type.StripsVertical="Bandes verticales" LumaWipe.Type.Watercolor="Aquarelle" LumaWipe.Type.ZigzagHorizontal="Zigzags à l'horizontale" LumaWipe.Type.ZigzagVertical="Zigzags à la verticale" -AudioMonitoring="Surveillance audio" -AudioMonitoring.None="Pas de surveillance" -AudioMonitoring.MonitorOnly="Surveillance seule (sortie en sourdine)" -AudioMonitoring.Both="Surveillance et sortie" +AudioMonitoring="Monitoring audio" +AudioMonitoring.None="Pas de Monitoring" +AudioMonitoring.MonitorOnly="Monitoring seul (sortie coupée)" +AudioMonitoring.Both="Monotoring et sortie" diff --git a/plugins/obs-transitions/data/locale/it-IT.ini b/plugins/obs-transitions/data/locale/it-IT.ini index dbf3438..4cd1f2c 100644 --- a/plugins/obs-transitions/data/locale/it-IT.ini +++ b/plugins/obs-transitions/data/locale/it-IT.ini @@ -1,66 +1,66 @@ FadeTransition="Dissolvenza" CutTransition="Taglio" -SwipeTransition="Scorri" +SwipeTransition="Scorrimento" SlideTransition="Scivola" StingerTransition="Stinger" -FadeToColorTransition="Dissolvenza a colore" +FadeToColorTransition="Dissolvenza ad un colore" Direction="Direzione" -Direction.Left="Sinistra" -Direction.Right="Destra" -Direction.Up="Sù" -Direction.Down="Giù" -SwipeIn="Scorri verso l'alto" +Direction.Left="Verso sinistra" +Direction.Right="Verso destra" +Direction.Up="Verso l'alto" +Direction.Down="Verso il basso" +SwipeIn="Inverti l'effetto" Color="Colore" VideoFile="File video" -TransitionPoint="Punto di transizione (millisecondi)" -TransitionPointFrame="Punto di transizione (frame)" -TransitionPointType="Tipo di punto di transizione" -TransitionPointTypeFrame="Fotogramma" -TransitionPointTypeTime="Tempo (millisecondi)" -AudioFadeStyle="Stile dissolvenza audio" +TransitionPoint="Punto di transizione (in millisecondi)" +TransitionPointFrame="Punto di transizione (in fotogrammi)" +TransitionPointType="Tipo del punto di transizione" +TransitionPointTypeFrame="In fotogrammi" +TransitionPointTypeTime="A tempo (in millisecondi)" +AudioFadeStyle="Stile della dissolvenza audio" AudioFadeStyle.FadeOutFadeIn="Dissolvenza fino al punto di transizione, poi dissolvenza in entrata" -AudioFadeStyle.CrossFade="Dissolvenza" -SwitchPoint="Picco Punto Colore (percentuale)" -LumaWipeTransition="Luma Wipe" +AudioFadeStyle.CrossFade="Dissolvenza incrociata" +SwitchPoint="Picco del colore (in percentuale)" +LumaWipeTransition="Scansione Luma" LumaWipe.Image="Immagine" LumaWipe.Invert="Inverti" LumaWipe.Softness="Morbidezza" LumaWipe.Type.BarndoorBottomLeft="Portello in basso a sinistra" -LumaWipe.Type.BarndoorHorizontal="Portello Orizzontale" +LumaWipe.Type.BarndoorHorizontal="Portello orizzontale" LumaWipe.Type.BarndoorTopLeft="Portello in alto a sinistra" LumaWipe.Type.BarndoorVertical="Portello verticale" -LumaWipe.Type.BlindsHorizontal="Tapparelle Orizzontale" -LumaWipe.Type.BoxBottomLeft="Box in basso a sinistra" -LumaWipe.Type.BoxBottomRight="Box in basso a destra" -LumaWipe.Type.BoxTopLeft="Box in alto a sinistra" -LumaWipe.Type.BoxTopRight="Box in alto a destra" -LumaWipe.Type.Burst="Burst" +LumaWipe.Type.BlindsHorizontal="Tapparelle orizzontali" +LumaWipe.Type.BoxBottomLeft="Casella in basso a sinistra" +LumaWipe.Type.BoxBottomRight="Casella in basso a destra" +LumaWipe.Type.BoxTopLeft="Casella in alto a sinistra" +LumaWipe.Type.BoxTopRight="Casella in alto a destra" +LumaWipe.Type.Burst="Esplosione" LumaWipe.Type.CheckerboardSmall="Scacchiera piccola" LumaWipe.Type.Circles="Cerchi" LumaWipe.Type.Clock="Orologio" LumaWipe.Type.Cloud="Nuvola" -LumaWipe.Type.Curtain="Cortina" +LumaWipe.Type.Curtain="Tendina" LumaWipe.Type.Fan="Ventola" LumaWipe.Type.Fractal="Frattale" LumaWipe.Type.Iris="Diaframma" -LumaWipe.Type.LinearHorizontal="Lineare Orizzontale" +LumaWipe.Type.LinearHorizontal="Lineare orizzontale" LumaWipe.Type.LinearTopLeft="Lineare in alto a sinistra" LumaWipe.Type.LinearTopRight="Lineare in alto a destra" LumaWipe.Type.LinearVertical="Lineare verticale" LumaWipe.Type.ParallelZigzagHorizontal="Parallelo a zig-zag orizzontale" LumaWipe.Type.ParallelZigzagVertical="Parallelo a zig-zag verticale" -LumaWipe.Type.Sinus9="Sinusale 9" +LumaWipe.Type.Sinus9="Plasma" LumaWipe.Type.Spiral="Spirale" LumaWipe.Type.Square="Quadrato" LumaWipe.Type.Squares="Quadrati" LumaWipe.Type.Stripes="Striscie" -LumaWipe.Type.StripsHorizontal="Striscie Orizzontale" +LumaWipe.Type.StripsHorizontal="Striscie orizzontali" LumaWipe.Type.StripsVertical="Striscie verticali" LumaWipe.Type.Watercolor="Acquerello" LumaWipe.Type.ZigzagHorizontal="Zig-zag orizzontale" LumaWipe.Type.ZigzagVertical="Zig-zag verticale" -AudioMonitoring="Monitoraggio Audio" -AudioMonitoring.None="Monitoraggio off" -AudioMonitoring.MonitorOnly="Solo Monitoraggio (output mutato)" -AudioMonitoring.Both="Monitoraggio e Output" +AudioMonitoring="Monitoraggio audio" +AudioMonitoring.None="Disattivato" +AudioMonitoring.MonitorOnly="Solo monitoraggio (uscita audio nel file disattivata)" +AudioMonitoring.Both="Monitora l'audio e invia all'uscita" diff --git a/plugins/obs-transitions/data/locale/ka-GE.ini b/plugins/obs-transitions/data/locale/ka-GE.ini index 948601b..77b411e 100644 --- a/plugins/obs-transitions/data/locale/ka-GE.ini +++ b/plugins/obs-transitions/data/locale/ka-GE.ini @@ -22,7 +22,7 @@ AudioFadeStyle.FadeOutFadeIn="თანდათან მილევა გა AudioFadeStyle.CrossFade="ჯვარედინი გადასვლა" SwitchPoint="ფერის უმაღლესი წერტილი (პროცენტი)" LumaWipeTransition="Luma Wipe" -LumaWipe.Image="სურათი" +LumaWipe.Image="გამოსახულება" LumaWipe.Invert="შებრუნება" LumaWipe.Softness="სირბილე" LumaWipe.Type.BarndoorBottomLeft="მარცხნივ ქვემოთ დახრილი გადაფარვა" @@ -30,10 +30,10 @@ LumaWipe.Type.BarndoorHorizontal="თარაზული გადაფარ LumaWipe.Type.BarndoorTopLeft="მარცხნივ ზემოთ დახრილი გადაფარვა" LumaWipe.Type.BarndoorVertical="შვეული გადაფარვა" LumaWipe.Type.BlindsHorizontal="თარაზული ჟალუზები" -LumaWipe.Type.BoxBottomLeft="ქვედა მარცხენა კუთხიდან გადაფარვა" -LumaWipe.Type.BoxBottomRight="ქვედა მარჯვენა კუთხიდან გადაფარვა" -LumaWipe.Type.BoxTopLeft="ზედა მარცხენა კუთხიდან გადაფარვა" -LumaWipe.Type.BoxTopRight="ზედა მარჯვენა კუთხიდან გადაფარვა" +LumaWipe.Type.BoxBottomLeft="ქვედა მარცხენა კუთხისკენ გადაფარვა" +LumaWipe.Type.BoxBottomRight="ქვედა მარჯვენა კუთხისკენ გადაფარვა" +LumaWipe.Type.BoxTopLeft="ზედა მარცხენა კუთხისკენ გადაფარვა" +LumaWipe.Type.BoxTopRight="ზედა მარჯვენა კუთხისკენ გადაფარვა" LumaWipe.Type.Burst="აფეთქება" LumaWipe.Type.CheckerboardSmall="უჯრები" LumaWipe.Type.Circles="წრეები" @@ -61,6 +61,6 @@ LumaWipe.Type.ZigzagHorizontal="თარაზული ტეხილი" LumaWipe.Type.ZigzagVertical="შვეული ტეხილი" AudioMonitoring="ხმის მოსმენა" AudioMonitoring.None="მოსმენის გარეშე" -AudioMonitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამომავალი სიგნალით)" +AudioMonitoring.MonitorOnly="მხოლოდ მოსმენა (უხმო გამოტანა)" AudioMonitoring.Both="მოსმენა და გამოტანა" diff --git a/plugins/obs-transitions/data/locale/pt-PT.ini b/plugins/obs-transitions/data/locale/pt-PT.ini index ac3a110..880cf60 100644 --- a/plugins/obs-transitions/data/locale/pt-PT.ini +++ b/plugins/obs-transitions/data/locale/pt-PT.ini @@ -2,6 +2,7 @@ FadeTransition="Desvanecer" CutTransition="Cortar" SwipeTransition="Deslizar" SlideTransition="Deslizar" +StingerTransition="Ferrão" FadeToColorTransition="Desvanecer para Cor" Direction="Direção" Direction.Left="Esquerda" @@ -10,5 +11,10 @@ Direction.Up="Cima" Direction.Down="Baixo" SwipeIn="Deslizar para dentro" Color="Cor" +VideoFile="Ficheiro Vídeo" +TransitionPoint="Ponto de Transição (milissegundos)" +TransitionPointFrame="Ponto de transição (quadro)" +TransitionPointType="Tipo de Ponto de Transição" +TransitionPointTypeTime="Tempo (milissegundos)" SwitchPoint="Ponto de pico de Cor (percentagem)" diff --git a/plugins/obs-transitions/data/locale/ro-RO.ini b/plugins/obs-transitions/data/locale/ro-RO.ini index c8f7860..b7bef52 100644 --- a/plugins/obs-transitions/data/locale/ro-RO.ini +++ b/plugins/obs-transitions/data/locale/ro-RO.ini @@ -1,18 +1,31 @@ FadeTransition="Estompare" -CutTransition="Tăiere" +CutTransition="Decupare" SwipeTransition="Glisare" -SlideTransition="Gliseaza" +SlideTransition="Culisare" +StingerTransition="Stinger" FadeToColorTransition="Estompare prin culoare" Direction="Direcție" Direction.Left="Stânga" Direction.Right="Dreapta" Direction.Up="Sus" Direction.Down="Jos" -SwipeIn="Glisați înauntru" +SwipeIn="Glisează peste" Color="Culoare" +TransitionPoint="Punct de tranziție (milisecunde)" +TransitionPointFrame="Punct de tranziție (fotogramă)" +TransitionPointType="Tipul punctului de tranziție" +TransitionPointTypeFrame="Fotogramă" +TransitionPointTypeTime="Timp (milisecunde)" SwitchPoint="Punctul de vârf al culorii (procent)" LumaWipe.Image="Imagine" +LumaWipe.Invert="Inversează" +LumaWipe.Softness="Moliciune" +LumaWipe.Type.Clock="Ceas" LumaWipe.Type.Cloud="Cloud" LumaWipe.Type.ZigzagHorizontal="Zigzag orizontal" LumaWipe.Type.ZigzagVertical="Zigzag Vertical" +AudioMonitoring="Monitorizare audio" +AudioMonitoring.None="Monitorizare dezactivată" +AudioMonitoring.MonitorOnly="Numai monitorizare (amuțește ieșirea)" +AudioMonitoring.Both="Monitorizare și ieșire" diff --git a/plugins/obs-transitions/data/locale/sk-SK.ini b/plugins/obs-transitions/data/locale/sk-SK.ini index 6f80bac..3d3bf31 100644 --- a/plugins/obs-transitions/data/locale/sk-SK.ini +++ b/plugins/obs-transitions/data/locale/sk-SK.ini @@ -26,4 +26,13 @@ LumaWipe.Type.Curtain="Záves" LumaWipe.Type.Fan="Ventilátor" LumaWipe.Type.Fractal="Fractal" LumaWipe.Type.Iris="Iris" +LumaWipe.Type.Sinus9="Sínus 9" +LumaWipe.Type.Spiral="Špirála" +LumaWipe.Type.Square="Štvorec" +LumaWipe.Type.Squares="Štvorce" +LumaWipe.Type.Stripes="Pásiky" +AudioMonitoring="Monitorovanie zvuku" +AudioMonitoring.None="Vypnuté monitorovanie" +AudioMonitoring.MonitorOnly="Iba monitorovanie (žiaden výstup)" +AudioMonitoring.Both="Monitorovanie a výstup" diff --git a/plugins/obs-transitions/data/locale/sr-CS.ini b/plugins/obs-transitions/data/locale/sr-CS.ini index 473e46f..14be8c6 100644 --- a/plugins/obs-transitions/data/locale/sr-CS.ini +++ b/plugins/obs-transitions/data/locale/sr-CS.ini @@ -2,6 +2,7 @@ FadeTransition="Zatamnjenje" CutTransition="Sečenje" SwipeTransition="Prevlačenje" SlideTransition="Klizanje" +StingerTransition="Stinger" FadeToColorTransition="Iščezavanje u boju" Direction="Pravac" Direction.Left="Levo" @@ -10,6 +11,15 @@ Direction.Up="Gore" Direction.Down="Dole" SwipeIn="Uvlačenje" Color="Boja" +VideoFile="Video fajl" +TransitionPoint="Početak prelaza (milisekunde)" +TransitionPointFrame="Početak prelaza (frejm)" +TransitionPointType="Tip početka prelaza" +TransitionPointTypeFrame="Frejm" +TransitionPointTypeTime="Vreme (milisekunde)" +AudioFadeStyle="Način na koji zvuk nestaje" +AudioFadeStyle.FadeOutFadeIn="Nestaje do tačke prelaza a zatim se ponovo vraća" +AudioFadeStyle.CrossFade="Nestaje unakrsno" SwitchPoint="Tačka vrhunca boje (procenat)" LumaWipeTransition="Luma brisanje" LumaWipe.Image="Slika" @@ -21,7 +31,7 @@ LumaWipe.Type.BarndoorTopLeft="Ambarska vrata odozgo sleva" LumaWipe.Type.BarndoorVertical="Ambarska vrata vertikalna" LumaWipe.Type.BlindsHorizontal="Zastori horizontalno" LumaWipe.Type.BoxBottomLeft="Kutija odozdo sleva" -LumaWipe.Type.BoxBottomRight="Kutija odozdo sdesna" +LumaWipe.Type.BoxBottomRight="Kutija odozdo zdesna" LumaWipe.Type.BoxTopLeft="Kutija odozgo sleva" LumaWipe.Type.BoxTopRight="Kutija odozgo sdesna" LumaWipe.Type.Burst="Rafal" @@ -35,7 +45,7 @@ LumaWipe.Type.Fractal="Fraktal" LumaWipe.Type.Iris="Žiža" LumaWipe.Type.LinearHorizontal="Linijski horizontalno" LumaWipe.Type.LinearTopLeft="Linijski odozgo sleva" -LumaWipe.Type.LinearTopRight="Linijski odozgo sdesna" +LumaWipe.Type.LinearTopRight="Linijski odozgo zdesna" LumaWipe.Type.LinearVertical="Linijski vertikalno" LumaWipe.Type.ParallelZigzagHorizontal="Paralelni cik-cak horizontalno" LumaWipe.Type.ParallelZigzagVertical="Paralelni cik-cak vertikalni" @@ -49,4 +59,8 @@ LumaWipe.Type.StripsVertical="Trake vertikalno" LumaWipe.Type.Watercolor="Vodene bojice" LumaWipe.Type.ZigzagHorizontal="Cik-cak horizontalno" LumaWipe.Type.ZigzagVertical="Cik-cak vertikalno" +AudioMonitoring="Audio nadzor" +AudioMonitoring.None="Monitor je isključen" +AudioMonitoring.MonitorOnly="Uključen je samo monitor (isključen je zvuk)" +AudioMonitoring.Both="Uključeni su i monitor i zvuk" diff --git a/plugins/obs-transitions/data/locale/sr-SP.ini b/plugins/obs-transitions/data/locale/sr-SP.ini index 12be3a2..0934699 100644 --- a/plugins/obs-transitions/data/locale/sr-SP.ini +++ b/plugins/obs-transitions/data/locale/sr-SP.ini @@ -2,6 +2,7 @@ FadeTransition="Затамњење" CutTransition="Сечење" SwipeTransition="Превлачење" SlideTransition="Клизање" +StingerTransition="Stinger" FadeToColorTransition="Ишчезавање у боју" Direction="Правац" Direction.Left="Лево" @@ -10,6 +11,15 @@ Direction.Up="Горе" Direction.Down="Доле" SwipeIn="Увлачење" Color="Боја" +VideoFile="Видео фајл" +TransitionPoint="Почетак прелаза (милисекунде)" +TransitionPointFrame="Почетак прелаза (фрејм)" +TransitionPointType="Тип почетка прелаза" +TransitionPointTypeFrame="Фрејм" +TransitionPointTypeTime="Време (милисекунде)" +AudioFadeStyle="Начин на који звук нестаје" +AudioFadeStyle.FadeOutFadeIn="Нестаје до тачке прелаза а затим се поново враћа" +AudioFadeStyle.CrossFade="Нестаје унакрсно" SwitchPoint="Тачка врхунца боје (проценат)" LumaWipeTransition="Лума брисање" LumaWipe.Image="Слика" @@ -21,7 +31,7 @@ LumaWipe.Type.BarndoorTopLeft="Амбарска врата одозго слев LumaWipe.Type.BarndoorVertical="Амбарска врата вертикална" LumaWipe.Type.BlindsHorizontal="Застори хоризонтално" LumaWipe.Type.BoxBottomLeft="Кутија одоздо слева" -LumaWipe.Type.BoxBottomRight="Кутија одоздо сдесна" +LumaWipe.Type.BoxBottomRight="Кутија одоздо здесна" LumaWipe.Type.BoxTopLeft="Кутија одозго слева" LumaWipe.Type.BoxTopRight="Кутија одозго сдесна" LumaWipe.Type.Burst="Рафал" @@ -35,7 +45,7 @@ LumaWipe.Type.Fractal="Фрактал" LumaWipe.Type.Iris="Жижа" LumaWipe.Type.LinearHorizontal="Линијски хоризонтално" LumaWipe.Type.LinearTopLeft="Линијски одозго слева" -LumaWipe.Type.LinearTopRight="Линијски одозго сдесна" +LumaWipe.Type.LinearTopRight="Линијски одозго здесна" LumaWipe.Type.LinearVertical="Линијски вертикално" LumaWipe.Type.ParallelZigzagHorizontal="Паралелни цик-цак хоризонтално" LumaWipe.Type.ParallelZigzagVertical="Паралални цик-цак вертикално" @@ -49,4 +59,8 @@ LumaWipe.Type.StripsVertical="Траке вертикално" LumaWipe.Type.Watercolor="Водене бојице" LumaWipe.Type.ZigzagHorizontal="Цик-цак хоризонтално" LumaWipe.Type.ZigzagVertical="Цик-цак вертикално" +AudioMonitoring="Аудио надзор" +AudioMonitoring.None="Монитор је искључен" +AudioMonitoring.MonitorOnly="Укључен је само монитор (искључен је звук)" +AudioMonitoring.Both="Укључени су и монитор и звук" diff --git a/plugins/obs-transitions/data/locale/zh-CN.ini b/plugins/obs-transitions/data/locale/zh-CN.ini index bfd17d7..7bd0868 100644 --- a/plugins/obs-transitions/data/locale/zh-CN.ini +++ b/plugins/obs-transitions/data/locale/zh-CN.ini @@ -1,22 +1,22 @@ FadeTransition="淡出" -CutTransition="剪切" -SwipeTransition="滑动" -SlideTransition="滑动" -StingerTransition="毒刺" +CutTransition="直接切换" +SwipeTransition="滑入滑出" +SlideTransition="幻灯片" +StingerTransition="插入视频" FadeToColorTransition="色彩淡入淡出" Direction="方向" Direction.Left="左" Direction.Right="右" Direction.Up="上" Direction.Down="下" -SwipeIn="向上滑动" +SwipeIn="滑入" Color="色彩" VideoFile="视频文件" -TransitionPoint="转换点 (毫秒)" -TransitionPointFrame="转换点 (帧)" +TransitionPoint="转换点(毫秒)" +TransitionPointFrame="转换点(帧)" TransitionPointType="转换点类型" TransitionPointTypeFrame="帧" -TransitionPointTypeTime="时间 (毫秒)" +TransitionPointTypeTime="时间(毫秒)" AudioFadeStyle="音频淡入淡出样式" AudioFadeStyle.FadeOutFadeIn="淡出到过渡点然后淡入" AudioFadeStyle.CrossFade="交叉淡入淡出" @@ -24,10 +24,10 @@ SwitchPoint="峰值颜色点(百分比)" LumaWipeTransition="亮度擦除" LumaWipe.Image="图像" LumaWipe.Invert="反转" -LumaWipe.Softness="柔和" +LumaWipe.Softness="柔和度" LumaWipe.Type.BarndoorBottomLeft="左下角门" LumaWipe.Type.BarndoorHorizontal="水平门" -LumaWipe.Type.BarndoorTopLeft="右上角门" +LumaWipe.Type.BarndoorTopLeft="左上角门" LumaWipe.Type.BarndoorVertical="垂直门" LumaWipe.Type.BlindsHorizontal="水平百叶窗" LumaWipe.Type.BoxBottomLeft="左下角盒子" @@ -41,17 +41,17 @@ LumaWipe.Type.Clock="时钟" LumaWipe.Type.Cloud="云" LumaWipe.Type.Curtain="窗帘" LumaWipe.Type.Fan="风扇" -LumaWipe.Type.Fractal="不规则碎片" +LumaWipe.Type.Fractal="分形" LumaWipe.Type.Iris="中心" LumaWipe.Type.LinearHorizontal="线性水平" LumaWipe.Type.LinearTopLeft="线性左上" LumaWipe.Type.LinearTopRight="线性右上" LumaWipe.Type.LinearVertical="线性垂直" -LumaWipe.Type.ParallelZigzagHorizontal="平行水波水平" -LumaWipe.Type.ParallelZigzagVertical="平行水波垂直" +LumaWipe.Type.ParallelZigzagHorizontal="并排Z字形水平" +LumaWipe.Type.ParallelZigzagVertical="并排Z字形垂直" LumaWipe.Type.Sinus9="Sinus 9" LumaWipe.Type.Spiral="螺旋" -LumaWipe.Type.Square="正方型" +LumaWipe.Type.Square="正方形" LumaWipe.Type.Squares="方块" LumaWipe.Type.Stripes="条纹" LumaWipe.Type.StripsHorizontal="条纹水平" @@ -59,8 +59,8 @@ LumaWipe.Type.StripsVertical="条纹垂直" LumaWipe.Type.Watercolor="水彩" LumaWipe.Type.ZigzagHorizontal="Z字形水平" LumaWipe.Type.ZigzagVertical="Z字形垂直" -AudioMonitoring="音频监测" -AudioMonitoring.None="关闭监视" -AudioMonitoring.MonitorOnly="仅显示器(输出静音)" -AudioMonitoring.Both="显示器和输出" +AudioMonitoring="音频监听" +AudioMonitoring.None="关闭监听" +AudioMonitoring.MonitorOnly="仅监听(不输出音频)" +AudioMonitoring.Both="监听并输出" diff --git a/plugins/obs-transitions/data/luma_wipe_transition.effect b/plugins/obs-transitions/data/luma_wipe_transition.effect index 92fb318..baab294 100644 --- a/plugins/obs-transitions/data/luma_wipe_transition.effect +++ b/plugins/obs-transitions/data/luma_wipe_transition.effect @@ -20,8 +20,6 @@ struct VertData { float2 uv : TEXCOORD0; }; -#include "premultiplied.inc" - VertData VSDefault(VertData v_in) { VertData vert_out; @@ -33,8 +31,8 @@ VertData VSDefault(VertData v_in) float4 PSLumaWipe(VertData v_in) : TARGET { float2 uv = v_in.uv; - float4 a_color = convert_pmalpha(a_tex.Sample(textureSampler, uv)); - float4 b_color = convert_pmalpha(b_tex.Sample(textureSampler, uv)); + float4 a_color = a_tex.Sample(textureSampler, uv); + float4 b_color = b_tex.Sample(textureSampler, uv); float luma = l_tex.Sample(textureSampler, uv).x; if (invert) diff --git a/plugins/obs-transitions/data/premultiplied.inc b/plugins/obs-transitions/data/premultiplied.inc deleted file mode 100644 index 450f6d4..0000000 --- a/plugins/obs-transitions/data/premultiplied.inc +++ /dev/null @@ -1,9 +0,0 @@ -float4 convert_pmalpha(float4 color) -{ - float4 ret = color; - if (color.a >= 0.001) - ret.xyz /= color.a; - else - ret = float4(0.0, 0.0, 0.0, 0.0); - return ret; -} diff --git a/plugins/obs-transitions/data/slide_transition.effect b/plugins/obs-transitions/data/slide_transition.effect index 489ae7d..3193893 100644 --- a/plugins/obs-transitions/data/slide_transition.effect +++ b/plugins/obs-transitions/data/slide_transition.effect @@ -16,8 +16,6 @@ struct VertData { float2 uv : TEXCOORD0; }; -#include "premultiplied.inc" - VertData VSDefault(VertData v_in) { VertData vert_out; @@ -37,7 +35,7 @@ float4 PSSlide(VertData v_in) : TARGET ? tex_b.Sample(textureSampler, tex_b_uv) : tex_a.Sample(textureSampler, tex_a_uv); - return convert_pmalpha(outc); + return outc; } technique Slide diff --git a/plugins/obs-transitions/data/swipe_transition.effect b/plugins/obs-transitions/data/swipe_transition.effect index 532399e..e2e6dd1 100644 --- a/plugins/obs-transitions/data/swipe_transition.effect +++ b/plugins/obs-transitions/data/swipe_transition.effect @@ -14,8 +14,6 @@ struct VertData { float2 uv : TEXCOORD0; }; -#include "premultiplied.inc" - VertData VSDefault(VertData v_in) { VertData vert_out; @@ -34,7 +32,7 @@ float4 PSSwipe(VertData v_in) : TARGET ? tex_b.Sample(textureSampler, v_in.uv) : tex_a.Sample(textureSampler, swipe_uv); - return convert_pmalpha(outc); + return outc; } technique Swipe diff --git a/plugins/obs-transitions/obs-transitions.c b/plugins/obs-transitions/obs-transitions.c index 22276d3..3646993 100644 --- a/plugins/obs-transitions/obs-transitions.c +++ b/plugins/obs-transitions/obs-transitions.c @@ -1,8 +1,11 @@ #include OBS_DECLARE_MODULE() - OBS_MODULE_USE_DEFAULT_LOCALE("obs-transitions", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "OBS core transitions"; +} extern struct obs_source_info cut_transition; extern struct obs_source_info fade_transition; diff --git a/plugins/obs-x264/data/locale/da-DK.ini b/plugins/obs-x264/data/locale/da-DK.ini index 6c22fff..d3eb6ec 100644 --- a/plugins/obs-x264/data/locale/da-DK.ini +++ b/plugins/obs-x264/data/locale/da-DK.ini @@ -1,13 +1,13 @@ -Bitrate="Bitrate" -CustomBufsize="Brug brugerdefineret bufferstørrelse" -BufferSize="Bufferstørrelsen" +Bitrate="Bit-hastighed" +CustomBufsize="Benyt tilpasset bufferstørrelse" +BufferSize="Bufferstørrelse" RateControl="Rate kontrol" CRF="CRF" -KeyframeIntervalSec="Keyframe interval (sekunder, 0 = auto)" -CPUPreset="CPU forbrug indstilling (højere = mindre CPU)" +KeyframeIntervalSec="Keyframe-interval (sek., 0 = auto)" +CPUPreset="CPU-forbrugsforvalg (højere = mindre CPU)" Profile="Profil" -Tune="Stil ind" +Tune="Tuning" None="(Ingen)" -EncoderOptions="x264 indstillinger (adskilt af mellemrum)" -VFR="Variable framerate (VFR)" +EncoderOptions="x264-indstillinger (adskilt af mellemrum)" +VFR="Variable billedhastighed (VFR)" diff --git a/plugins/obs-x264/data/locale/de-DE.ini b/plugins/obs-x264/data/locale/de-DE.ini index 15adf9e..904eab9 100644 --- a/plugins/obs-x264/data/locale/de-DE.ini +++ b/plugins/obs-x264/data/locale/de-DE.ini @@ -8,6 +8,6 @@ CPUPreset="Prozessorauslastung-Voreinstellung (höher = weniger CPU Auslastung)" Profile="Profil" Tune="Tune" None="(Nichts)" -EncoderOptions="x264 Optionen (durch Leerzeichen getrennt)" +EncoderOptions="x264-Optionen (durch Leerzeichen getrennt)" VFR="Variable Framerate (VFR)" diff --git a/plugins/obs-x264/data/locale/fa-IR.ini b/plugins/obs-x264/data/locale/fa-IR.ini new file mode 100644 index 0000000..3da9807 --- /dev/null +++ b/plugins/obs-x264/data/locale/fa-IR.ini @@ -0,0 +1,13 @@ +Bitrate="نرخ بیت" +CustomBufsize="استفاده از اندازه بافر سفارشی" +BufferSize="اندازه بافر" +RateControl="کنترل نرخ" +CRF="سی آر اف" +KeyframeIntervalSec="فاصله Keyframe (ثانیه 0 = خودکار)" +CPUPreset="استفاده پیشفرض از CPU (بالاتر = CPU کمتر)" +Profile="پروفایل" +Tune="تون" +None="(هیچ کدام)" +EncoderOptions="آپشن های x264 (با فضای جدا شده )" +VFR="فریم های متغیر (وی اف ار)" + diff --git a/plugins/obs-x264/data/locale/fr-FR.ini b/plugins/obs-x264/data/locale/fr-FR.ini index 949d7cb..eddaa3a 100644 --- a/plugins/obs-x264/data/locale/fr-FR.ini +++ b/plugins/obs-x264/data/locale/fr-FR.ini @@ -1,13 +1,13 @@ Bitrate="Débit" -CustomBufsize="Utiliser une taille de buffer personnalisée" +CustomBufsize="Utiliser une taille de tampon personnalisée" BufferSize="Taille du tampon" RateControl="Contrôle du débit" CRF="CRF" KeyframeIntervalSec="Intervalle d'image-clé (en secondes, 0 = auto)" -CPUPreset="Réglages prédéfinis du CPU (élevé = charge CPU faible)" +CPUPreset="Pré-réglages (plus rapide = charge CPU plus faible)" Profile="Profil" -Tune="Régler" +Tune="Réglage fin" None="(Aucun)" EncoderOptions="Options x264 (séparées par un espace)" -VFR="Fréquence d'images variable (VFR)" +VFR="Débit d'images variable (VFR)" diff --git a/plugins/obs-x264/data/locale/it-IT.ini b/plugins/obs-x264/data/locale/it-IT.ini index dd6ffc2..f953c4e 100644 --- a/plugins/obs-x264/data/locale/it-IT.ini +++ b/plugins/obs-x264/data/locale/it-IT.ini @@ -1,13 +1,13 @@ -Bitrate="Bitrate" -CustomBufsize="Usa dimensione personalizzata del buffer" -BufferSize="Grandezza buffer" -RateControl="Controllo frequenza" -CRF="CRF" -KeyframeIntervalSec="Intervallo keyframe (secondi, 0=auto)" -CPUPreset="Preset di utilizzo della CPU (superiore = meno CPU)" +Bitrate="Velocità in bit" +CustomBufsize="Utilizza una dimensione personalizzata del buffer" +BufferSize="Dimensione del buffer" +RateControl="Tipo di controllo della frequenza" +CRF="Fattore costante della frequenza (CRF)" +KeyframeIntervalSec="Intervallo dei fotogrammi chiave (in secondi, 0=automatico)" +CPUPreset="Preset dell'utilizzo della CPU (superiore = meno CPU)" Profile="Profilo" -Tune="Regola" +Tune="Regolazione di precisione" None="(nessuno)" -EncoderOptions="Opzioni x264 (separati da spazio)" -VFR="Framerate variabile (VFR)" +EncoderOptions="Parametri x264 (separati da uno spazio)" +VFR="Velocità dei fotogrammi variabile (VFR)" diff --git a/plugins/obs-x264/data/locale/ko-KR.ini b/plugins/obs-x264/data/locale/ko-KR.ini index f00a1ce..fd9ad08 100644 --- a/plugins/obs-x264/data/locale/ko-KR.ini +++ b/plugins/obs-x264/data/locale/ko-KR.ini @@ -1,5 +1,5 @@ Bitrate="비트레이트" -CustomBufsize="사용자 임의 버퍼 크기 설정" +CustomBufsize="사용자 임의 버퍼 크기 설정" BufferSize="버퍼 크기" RateControl="데이터율 제어" CRF="CRF" diff --git a/plugins/obs-x264/data/locale/mn-MN.ini b/plugins/obs-x264/data/locale/mn-MN.ini new file mode 100644 index 0000000..d6085d1 --- /dev/null +++ b/plugins/obs-x264/data/locale/mn-MN.ini @@ -0,0 +1,13 @@ +Bitrate="Битийн хурд" +CustomBufsize="Өөр Хэмжээг Хэрэглэх" +BufferSize="Өөр Хэмжээ" +RateControl="Чанарын Хяналт" +CRF="CRF" +KeyframeIntervalSec="Гол Фрэймийн Интервал (секунд, 0=авто)" +CPUPreset="CPU-ны хэрэглэх хурд (илүү өндөр = бага CPU)" +Profile="Профайл" +Tune="Тааруулах" +None="(Байхгүй)" +EncoderOptions="x264 Сонголт (зайгаар тусгаарлагдсан)" +VFR="Тогтмол Биш Фрэйм-ийн хэмжээ (VFR)" + diff --git a/plugins/obs-x264/data/locale/ro-RO.ini b/plugins/obs-x264/data/locale/ro-RO.ini index b308056..ff909b8 100644 --- a/plugins/obs-x264/data/locale/ro-RO.ini +++ b/plugins/obs-x264/data/locale/ro-RO.ini @@ -1,6 +1,7 @@ Bitrate="Rată de biți" -CustomBufsize="Folosește dimensiune personalizată pentru buffer" +CustomBufsize="Folosește dimensiune personalizată pentru zona tampon" BufferSize="Dimensiune pentru buffer" +RateControl="Controlul ratei" CRF="CRF" KeyframeIntervalSec="Interval de cadre cheie (secunde, 0=auto)" CPUPreset="Presetare pentru utilizare CPU (mai mare = mai puțin CPU)" diff --git a/plugins/obs-x264/data/locale/sk-SK.ini b/plugins/obs-x264/data/locale/sk-SK.ini index fb2e74c..b4117ed 100644 --- a/plugins/obs-x264/data/locale/sk-SK.ini +++ b/plugins/obs-x264/data/locale/sk-SK.ini @@ -1,9 +1,13 @@ -Bitrate="Bitrate" +Bitrate="Dátový tok" CustomBufsize="Použiť vlastnú veľkosť medzipamäte" BufferSize="Veľkosť medzipamäte" +RateControl="Riadenie toku" CRF="CRF" KeyframeIntervalSec="Kľúčová snímka každých (sekúnd, 0 = automaticky)" +CPUPreset="CPU predvoľba používania (vyššie = menej CPU)" Profile="Profil" Tune="Vyladenie" -None="(Žiadny)" +None="(Žiadne)" +EncoderOptions="Možnosti enkodéra x264 (oddelené medzerou)" +VFR="Premenlivá rýchlosť snímkov (VFR)" diff --git a/plugins/obs-x264/data/locale/zh-CN.ini b/plugins/obs-x264/data/locale/zh-CN.ini index 058c829..08767a2 100644 --- a/plugins/obs-x264/data/locale/zh-CN.ini +++ b/plugins/obs-x264/data/locale/zh-CN.ini @@ -1,12 +1,12 @@ Bitrate="比特率" CustomBufsize="使用自定义缓存大小" BufferSize="缓冲大小" -RateControl="速率控制" +RateControl="码率控制" CRF="CRF" KeyframeIntervalSec="关键帧间隔(秒, 0=自动)" CPUPreset="CPU 使用预设 (高 = 较少的 CPU占用)" -Profile="Profile" -Tune="协调(类型)" +Profile="配置(Profile)" +Tune="微调(Tune)" None="(无)" EncoderOptions="x264 选项 (用空格分隔)" VFR="可变帧率 (VFR)" diff --git a/plugins/obs-x264/obs-x264-plugin-main.c b/plugins/obs-x264/obs-x264-plugin-main.c index fbb4c2c..71d7d02 100644 --- a/plugins/obs-x264/obs-x264-plugin-main.c +++ b/plugins/obs-x264/obs-x264-plugin-main.c @@ -2,6 +2,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("obs-x264", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "x264 based encoder"; +} extern struct obs_encoder_info obs_x264_encoder; diff --git a/plugins/obs-x264/obs-x264.c b/plugins/obs-x264/obs-x264.c index d177a8e..6e0d2e6 100644 --- a/plugins/obs-x264/obs-x264.c +++ b/plugins/obs-x264/obs-x264.c @@ -179,7 +179,9 @@ static obs_properties_t *obs_x264_props(void *unused) obs_property_set_modified_callback(list, rate_control_modified); - obs_properties_add_int(props, "bitrate", TEXT_BITRATE, 50, 10000000, 1); + p = obs_properties_add_int(props, "bitrate", + TEXT_BITRATE, 50, 10000000, 50); + obs_property_int_set_suffix(p, " Kbps"); p = obs_properties_add_bool(props, "use_bufsize", TEXT_CUSTOM_BUF); obs_property_set_modified_callback(p, use_bufsize_modified); diff --git a/plugins/rtmp-services/data/locale/da-DK.ini b/plugins/rtmp-services/data/locale/da-DK.ini index 0c413be..294a759 100644 --- a/plugins/rtmp-services/data/locale/da-DK.ini +++ b/plugins/rtmp-services/data/locale/da-DK.ini @@ -1,11 +1,11 @@ -StreamingServices="Streaming Tjenester" -CustomStreamingServer="Brugerdefineret Streaming Server" -Service="Service" +StreamingServices="Streamingtjenester" +CustomStreamingServer="Tilpasset Streamingserver" +Service="Tjeneste" Server="Server" Server.Auto="Auto (anbefalet)" -StreamKey="Stream nøgle" -UseAuth="Brug godkendelse" +StreamKey="Streamnøgle" +UseAuth="Benyt godkendelse" Username="Brugernavn" -Password="Kodeord" -ShowAll="Vis alle services" +Password="Adgangskode" +ShowAll="Vis alle tjenester" diff --git a/plugins/rtmp-services/data/locale/it-IT.ini b/plugins/rtmp-services/data/locale/it-IT.ini index 384d30d..2b18124 100644 --- a/plugins/rtmp-services/data/locale/it-IT.ini +++ b/plugins/rtmp-services/data/locale/it-IT.ini @@ -1,11 +1,11 @@ -StreamingServices="Servizi di streaming" -CustomStreamingServer="Personalizza il server di streaming" +StreamingServices="Servizi di trasmissione/dirette" +CustomStreamingServer="Server di trasmissione/dirette personalizzato" Service="Servizio" Server="Server" -Server.Auto="Auto (consigliato)" -StreamKey="Chiave Stream" -UseAuth="Usa autenticazione" -Username="Username" +Server.Auto="Automatico (consigliato)" +StreamKey="Codice delle dirette" +UseAuth="Utilizza l'autenticazione" +Username="Nome utente" Password="Password" ShowAll="Mostra tutti i servizi" diff --git a/plugins/rtmp-services/data/locale/ja-JP.ini b/plugins/rtmp-services/data/locale/ja-JP.ini index 80623e5..bf89ba7 100644 --- a/plugins/rtmp-services/data/locale/ja-JP.ini +++ b/plugins/rtmp-services/data/locale/ja-JP.ini @@ -1,4 +1,4 @@ -StreamingServices="ストリーミングサービス" +StreamingServices="配信サービス" CustomStreamingServer="カスタムストリーミングサーバー" Service="サービス" Server="サーバー" diff --git a/plugins/rtmp-services/data/locale/ka-GE.ini b/plugins/rtmp-services/data/locale/ka-GE.ini index a095db7..1d04352 100644 --- a/plugins/rtmp-services/data/locale/ka-GE.ini +++ b/plugins/rtmp-services/data/locale/ka-GE.ini @@ -4,7 +4,7 @@ Service="მომსახურება" Server="სერვერი" Server.Auto="ავტომატური (სასურველია)" StreamKey="ნაკადის გასაღები" -UseAuth="ანგარიშზე შესვლის გამოყენება" +UseAuth="ანგარიშზე შესვლით" Username="მომხმარებლის სახელი" Password="პაროლი" ShowAll="ყველა მომსახურების ჩვენება" diff --git a/plugins/rtmp-services/data/locale/mn-MN.ini b/plugins/rtmp-services/data/locale/mn-MN.ini new file mode 100644 index 0000000..a3fbe1c --- /dev/null +++ b/plugins/rtmp-services/data/locale/mn-MN.ini @@ -0,0 +1,11 @@ +StreamingServices="Цацалтийн Сервис" +CustomStreamingServer="Өөр Цацалтийн Сервис" +Service="Сервис" +Server="Сервер" +Server.Auto="Авто (Зохимжтой)" +StreamKey="Цацалтын түлхүүр үгс" +UseAuth="Цахим баталгаажуулалт" +Username="Хэрэглэгчийн нэр" +Password="Нууц үг" +ShowAll="Бүх сервисийг харуул" + diff --git a/plugins/rtmp-services/data/locale/pt-PT.ini b/plugins/rtmp-services/data/locale/pt-PT.ini index 9e092d3..baa732a 100644 --- a/plugins/rtmp-services/data/locale/pt-PT.ini +++ b/plugins/rtmp-services/data/locale/pt-PT.ini @@ -2,6 +2,7 @@ StreamingServices="Serviço de transmissão" CustomStreamingServer="Servidor de transmissão personalizado" Service="Serviço" Server="Servidor" +Server.Auto="Automático (Recomendado)" StreamKey="Chave da transmissão" UseAuth="Utilizar autenticação" Username="Nome de utilizador" diff --git a/plugins/rtmp-services/data/locale/ro-RO.ini b/plugins/rtmp-services/data/locale/ro-RO.ini index 4e3ae39..1fa6543 100644 --- a/plugins/rtmp-services/data/locale/ro-RO.ini +++ b/plugins/rtmp-services/data/locale/ro-RO.ini @@ -1,10 +1,11 @@ -StreamingServices="Servicii de streaming" -CustomStreamingServer="Server de streaming personalizat" +StreamingServices="Servicii de transmisiune" +CustomStreamingServer="Server personalizat de transmisiune" Service="Serviciu" Server="Server" -StreamKey="Cheie de stream" -UseAuth="Folosește autentificare" +Server.Auto="Automat (Recomandat)" +StreamKey="Cheie de transmisiune" +UseAuth="Folosește autentificarea" Username="Nume de utilizator" Password="Parolă" -ShowAll="Arată toate serviciile" +ShowAll="Afișează toate serviciile" diff --git a/plugins/rtmp-services/data/locale/sr-CS.ini b/plugins/rtmp-services/data/locale/sr-CS.ini index ef513b6..db1ce28 100644 --- a/plugins/rtmp-services/data/locale/sr-CS.ini +++ b/plugins/rtmp-services/data/locale/sr-CS.ini @@ -2,6 +2,7 @@ StreamingServices="Servisi za strimovanje" CustomStreamingServer="Posebni server za strim" Service="Servis" Server="Server" +Server.Auto="Automatski (Preporučljivo)" StreamKey="Strim ključ" UseAuth="Koristi autentifikaciju" Username="Korisničko ime" diff --git a/plugins/rtmp-services/data/locale/sr-SP.ini b/plugins/rtmp-services/data/locale/sr-SP.ini index f09913a..a5c7ffc 100644 --- a/plugins/rtmp-services/data/locale/sr-SP.ini +++ b/plugins/rtmp-services/data/locale/sr-SP.ini @@ -2,6 +2,7 @@ StreamingServices="Сервиси за стримовање" CustomStreamingServer="Посебни сервер за стрим" Service="Сервис" Server="Сервер" +Server.Auto="Аутоматски (препоручљиво)" StreamKey="Стрим кључ" UseAuth="Користи аутентификацију" Username="Корисничко име" diff --git a/plugins/rtmp-services/data/locale/uk-UA.ini b/plugins/rtmp-services/data/locale/uk-UA.ini index c7ab4df..12a84af 100644 --- a/plugins/rtmp-services/data/locale/uk-UA.ini +++ b/plugins/rtmp-services/data/locale/uk-UA.ini @@ -4,7 +4,7 @@ Service="Сервіс" Server="Сервер" Server.Auto="Автоматично (рекомендується)" StreamKey="Ключ трансляції" -UseAuth="Використовувати авторизацію" +UseAuth="Використовувати автентифікацію" Username="Логін" Password="Пароль" ShowAll="Показати всі сервіси" diff --git a/plugins/rtmp-services/data/locale/vi-VN.ini b/plugins/rtmp-services/data/locale/vi-VN.ini index 7694d88..77bc84a 100644 --- a/plugins/rtmp-services/data/locale/vi-VN.ini +++ b/plugins/rtmp-services/data/locale/vi-VN.ini @@ -1,4 +1,4 @@ -StreamingServices="Dịch vụ stream" +StreamingServices="Dịch vụ truyền" CustomStreamingServer="Tùy chọn máy chủ truyền trực tuyến" Service="Dịch vụ" Server="Máy chủ" diff --git a/plugins/rtmp-services/data/package.json b/plugins/rtmp-services/data/package.json index 0f439c3..f514d10 100644 --- a/plugins/rtmp-services/data/package.json +++ b/plugins/rtmp-services/data/package.json @@ -1,10 +1,10 @@ { "url": "https://obsproject.com/obs2_update/rtmp-services", - "version": 88, + "version": 107, "files": [ { "name": "services.json", - "version": 88 + "version": 107 } ] } diff --git a/plugins/rtmp-services/data/services.json b/plugins/rtmp-services/data/services.json index 416ecd8..9276a35 100644 --- a/plugins/rtmp-services/data/services.json +++ b/plugins/rtmp-services/data/services.json @@ -1,5 +1,5 @@ { - "format_version": 1, + "format_version": 2, "services": [ { "name": "Twitch", @@ -37,6 +37,10 @@ "name": "EU: Berlin, DE", "url": "rtmp://live-ber.twitch.tv/app" }, + { + "name": "Europe: Copenhagen, DK", + "url": "rtmp://live-cph.twitch.tv/app" + }, { "name": "EU: Frankfurt, DE", "url": "rtmp://live-fra.twitch.tv/app" @@ -220,26 +224,10 @@ "name": "EU-North: Amsterdam, Netherlands", "url": "rtmp://live.ams.hitbox.tv/push" }, - { - "name": "EU-West: Frankfurt, Germany", - "url": "rtmp://live.fra.hitbox.tv/push" - }, { "name": "EU-West: Paris, France", "url": "rtmp://live.cdg.hitbox.tv/push" }, - { - "name": "EU-West: London, United Kingdom", - "url": "rtmp://live.lhr.hitbox.tv/push" - }, - { - "name": "EU-Central: Nurnberg, Germany", - "url": "rtmp://live.nbg.hitbox.tv/push" - }, - { - "name": "EU-East: Vienna, Austria", - "url": "rtmp://live.vie.hitbox.tv/push" - }, { "name": "EU-South: Milan, Italia", "url": "rtmp://live.mxp.hitbox.tv/push" @@ -249,17 +237,9 @@ "url": "rtmp://live.dme.hitbox.tv/push" }, { - "name": "US-East: New York - 1", + "name": "US-East: New York", "url": "rtmp://live.jfk.hitbox.tv/push" }, - { - "name": "US-East: New York - 2", - "url": "rtmp://live.nyc.hitbox.tv/push" - }, - { - "name": "US-Central: Denver", - "url": "rtmp://live.den.hitbox.tv/push" - }, { "name": "US-West: San Francisco", "url": "rtmp://live.sfo.hitbox.tv/push" @@ -272,18 +252,10 @@ "name": "South America: Sao Paulo, Brazil", "url": "rtmp://live.gru.hitbox.tv/push" }, - { - "name": "South Korea: Seoul", - "url": "rtmp://live.icn.hitbox.tv/push" - }, { "name": "Asia: Singapore", "url": "rtmp://live.sin.hitbox.tv/push" }, - { - "name": "China: Hong Kong", - "url": "rtmp://live.hkg.hitbox.tv/push" - }, { "name": "Oceania: Sydney, Australia", "url": "rtmp://live.syd.hitbox.tv/push" @@ -378,7 +350,7 @@ } ], "recommended": { - "keyint": 3, + "keyint": 2, "output": "ftl_output", "max audio bitrate": 160, "max video bitrate": 10000, @@ -468,7 +440,7 @@ } ], "recommended": { - "keyint": 3, + "keyint": 2, "max audio bitrate": 160, "max video bitrate": 10000, "profile": "main" @@ -490,23 +462,19 @@ } }, { - "name": "DailyMotion", - "common": true, + "name": "GamePlank", "servers": [ { "name": "Primary", - "url": "rtmp://publish.dailymotion.com/publish-dm" + "url": "rtmp://live.gameplank.tv/go" } - ] - }, - { - "name": "WatchPeopleCode.com", - "servers": [ - { - "name": "Primary", - "url": "rtmp://streaming.watchpeoplecode.com/live" - } - ] + ], + "recommended": { + "keyint": 1, + "profile": "main", + "max video bitrate": 2500, + "max audio bitrate": 160 + } }, { "name": "Web.TV", @@ -532,33 +500,6 @@ } ] }, - { - "name": "GamePlank", - "servers": [ - { - "name": "Primary", - "url": "rtmp://live.gameplank.tv/app" - }, - { - "name": "US: Oregon", - "url": "rtmp://live-or.gameplank.tv/app" - }, - { - "name": "US: Virginia", - "url": "rtmp://live-va.gameplank.tv/app" - }, - { - "name": "UK: London", - "url": "rtmp://live-ldn.gameplank.tv/app" - } - ], - "recommended": { - "keyint": 1, - "max video bitrate": 1500, - "max audio bitrate": 160, - "x264opts": "scenecut=0" - } - }, { "name": "Vaughn Live / iNSTAGIB", "servers": [ @@ -664,7 +605,10 @@ } }, { - "name": "Restream.io", + "name": "Restream.io - RTMP", + "alt_names": [ + "Restream.io" + ], "common": true, "servers": [ { @@ -743,6 +687,10 @@ "name": "Asia (Tokyo, Japan)", "url": "rtmp://tokyo.restream.io/live" }, + { + "name": "India (Bangalore)", + "url": "rtmp://india.restream.io/live" + }, { "name": "Australia (Sydney)", "url": "rtmp://au.restream.io/live" @@ -752,6 +700,109 @@ "keyint": 2 } }, + { + "name": "Restream.io - FTL", + "common": true, + "servers": [ + { + "name": "Autodetect", + "url": "live.restream.io" + }, + { + "name": "EU-West (London, GB)", + "url": "eu-london.restream.io" + }, + { + "name": "EU-West (Amsterdam, NL)", + "url": "eu-ams.restream.io" + }, + { + "name": "EU-West (Luxembourg)", + "url": "eu-luxembourg.restream.io" + }, + { + "name": "EU-West (Paris, FR)", + "url": "eu-paris.restream.io" + }, + { + "name": "EU-Central (Frankfurt, DE)", + "url": "eu-central.restream.io" + }, + { + "name": "EU-East (Falkenstein, DE)", + "url": "eu-east.restream.io" + }, + { + "name": "EU-South (Madrid, Spain)", + "url": "eu-madrid.restream.io" + }, + { + "name": "Russia (Moscow)", + "url": "ru.restream.io" + }, + { + "name": "US-West (Seattle, WA)", + "url": "us-seattle.restream.io" + }, + { + "name": "US-West (San Jose, CA)", + "url": "us-west.restream.io" + }, + { + "name": "US-Central (Dallas, TX)", + "url": "us-central.restream.io" + }, + { + "name": "US-East (Washington, DC)", + "url": "us-east.restream.io" + }, + { + "name": "US-East (Miami, FL)", + "url": "us-miami.restream.io" + }, + { + "name": "NA-East (Toronto, Canada)", + "url": "na-toronto.restream.io" + }, + { + "name": "SA (Saint Paul, Brazil)", + "url": "sa.restream.io" + }, + { + "name": "Asia (Singapore)", + "url": "singapore.restream.io" + }, + { + "name": "Asia (Seoul, South Korea)", + "url": "seoul.restream.io" + }, + { + "name": "Asia (Tokyo, Japan)", + "url": "tokyo.restream.io" + }, + { + "name": "Australia (Sydney)", + "url": "au.restream.io" + } + ], + "recommended": { + "keyint": 2, + "output": "ftl_output", + "max audio bitrate": 160, + "max video bitrate": 10000, + "profile": "main", + "bframes": 0 + } + }, + { + "name": "GameTips.TV", + "servers": [ + { + "name": "Server Iran", + "url": "rtmp://rtmp.cdn.server1.gametips.tv:1935/hls" + } + ] + }, { "name": "Nood", "servers": [ @@ -838,6 +889,10 @@ "name": "Los Angeles US", "url": "rtmp://la.castr.io" }, + { + "name": "New York US", + "url": "rtmp://ny.castr.io" + }, { "name": "Montreal CA", "url": "rtmp://qc.castr.io" @@ -850,6 +905,10 @@ "name": "Frankfurt DE", "url": "rtmp://de.castr.io" }, + { + "name": "Frankfurt DE 2", + "url": "rtmp://fr.castr.io" + }, { "name": "Moscow RU", "url": "rtmp://ru.castr.io" @@ -861,6 +920,34 @@ { "name": "Sydney AU", "url": "rtmp://au.castr.io" + }, + { + "name": "Brazil", + "url": "rtmp://br.castr.io" + }, + { + "name": "US Central", + "url": "rtmp://us-central.castr.io" + }, + { + "name": "US West", + "url": "rtmp://us-west.castr.io" + }, + { + "name": "US East", + "url": "rtmp://us-east.castr.io" + }, + { + "name": "US South", + "url": "rtmp://us-south.castr.io" + }, + { + "name": "South America", + "url": "rtmp://south-am.castr.io" + }, + { + "name": "EU Central", + "url": "rtmp://eu-central.castr.io" } ], "recommended": { @@ -917,10 +1004,6 @@ { "name": "Asia : Singapore", "url": "rtmp://rtmpmanager-aws-sg.afreeca.tv/live" - }, - { - "name": "Asia : South Korea", - "url": "rtmp://rtmpmanager-en-ko.afreeca.tv/live" } ], "recommended": { @@ -930,44 +1013,6 @@ "max audio bitrate": 192 } }, - { - "name": "アフリカTV", - "servers": [ - { - "name": "Japan", - "url": "rtmp://rtmpmanager-aws-jp.afreeca.tv/live/" - }, - { - "name": "South Korea", - "url": "rtmp://rtmpmanager-jp.afreeca.tv/live/" - } - ], - "recommended": { - "keyint": 1, - "profile": "main", - "max video bitrate": 5000, - "max audio bitrate": 192 - } - }, - { - "name": "艾菲卡TV", - "servers": [ - { - "name": "Taiwan", - "url": "rtmp://rtmpmanager-gcp-tw.afreeca.tv/live/" - }, - { - "name": "South Korea", - "url": "rtmp://rtmpmanager-tw-ko.afreeca.tv/live/" - } - ], - "recommended": { - "keyint": 1, - "profile": "main", - "max video bitrate": 5000, - "max audio bitrate": 192 - } - }, { "name": "아프리카TV", "servers": [ @@ -1042,62 +1087,76 @@ "name": "Chaturbate", "servers": [ { - "name": "Default Global Auto Select - Recommended", + "name": "Global Main Fastest - Recommended", "url": "rtmp://live.stream.highwebmedia.com/live-origin" }, { - "name": "US West", - "url": "rtmp://live-us-west.stream.highwebmedia.com/live-origin" + "name": "Global Backup", + "url": "rtmp://live-backup.stream.highwebmedia.com/live-origin" }, { - "name": "US Central", - "url": "rtmp://live-us-central.stream.highwebmedia.com/live-origin" + "name": "US West: Seattle, WA", + "url": "rtmp://live-sea.stream.highwebmedia.com/live-origin" }, { - "name": "US East", - "url": "rtmp://live-us-east.stream.highwebmedia.com/live-origin" + "name": "US West: Phoenix, AZ", + "url": "rtmp://live-phx.stream.highwebmedia.com/live-origin" }, { - "name": "Europe West", - "url": "rtmp://live-eu-west.stream.highwebmedia.com/live-origin" + "name": "US Central: Salt Lake City, UT", + "url": "rtmp://live-slc.stream.highwebmedia.com/live-origin" }, { - "name": "Europe East", - "url": "rtmp://live-eu-east.stream.highwebmedia.com/live-origin" + "name": "US Central: Chicago, IL", + "url": "rtmp://live-chi.stream.highwebmedia.com/live-origin" }, { - "name": "Asia/Pacific South", - "url": "rtmp://live-as-south.stream.highwebmedia.com/live-origin" + "name": "US East: Atlanta, GA", + "url": "rtmp://live-atl.stream.highwebmedia.com/live-origin" }, { - "name": "Asia/Pacific North-East", - "url": "rtmp://live-as-northeast.stream.highwebmedia.com/live-origin" + "name": "US East: Ashburn, VA", + "url": "rtmp://live-ash.stream.highwebmedia.com/live-origin" + }, + { + "name": "South America: Sao Paulo, Brazil", + "url": "rtmp://live-gru.stream.highwebmedia.com/live-origin" + }, + { + "name": "EU: Amsterdam, NL", + "url": "rtmp://live-nld.stream.highwebmedia.com/live-origin" + }, + { + "name": "EU: Alblasserdam, NL", + "url": "rtmp://live-alb.stream.highwebmedia.com/live-origin" + }, + { + "name": "EU: Frankfurt, DE", + "url": "rtmp://live-fra.stream.highwebmedia.com/live-origin" + }, + { + "name": "EU: Belgrade, Serbia", + "url": "rtmp://live-srb.stream.highwebmedia.com/live-origin" + }, + { + "name": "Asia: Singapore", + "url": "rtmp://live-sin.stream.highwebmedia.com/live-origin" + }, + { + "name": "Asia: Tokyo, Japan", + "url": "rtmp://live-nrt.stream.highwebmedia.com/live-origin" + }, + { + "name": "Australia: Sydney", + "url": "rtmp://live-syd.stream.highwebmedia.com/live-origin" } ], "recommended": { "keyint": 2, - "max video bitrate": 20000, + "max video bitrate": 50000, "max audio bitrate": 192 } }, - { - "name": "LiveEdu.tv", - "common": true, - "servers": [ - { - "name": "US", - "url": "rtmp://usmedia11.liveedu.tv/liveedutv" - }, - { - "name": "EU", - "url": "rtmp://eumedia8.liveedu.tv/liveedutv" - }, - { - "name": "Asia", - "url": "rtmp://apmedia1.liveedu.tv/liveedutv" - } - ] - }, { "name": "Twitter / Periscope", "common": true, @@ -1242,16 +1301,22 @@ } }, { - "name": "Lahzenegar - لحظه نگار", + "name": "Lahzenegar - StreamG | لحظه‌نگار - استریمجی", "servers": [ { "name": "Primary", - "url": "rtmp://live.lahzenegar.com:80/pro" + "url": "rtmp://rtmp.lahzecdn.com/pro" + }, + { + "name": "Iran", + "url": "rtmp://rtmp-iran.lahzecdn.com/pro" } ], "recommended": { - "max video bitrate": 1000, - "max audio bitrate": 96 + "keyint": 2, + "profile": "main", + "max video bitrate": 2800, + "max audio bitrate": 128 } }, { @@ -1326,13 +1391,120 @@ } }, { - "name": "DTube", + "name": "STAGE TEN", + "servers": [ + { + "name": "STAGE TEN", + "url": "rtmps://app-rtmp.stageten.tv:443/stageten" + } + ], + "recommended": { + "keyint": 2, + "profile": "baseline", + "max video bitrate": 4000, + "max audio bitrate": 128 + } + }, + { + "name": "DLive", "servers": [ { "name": "Default", - "url": "rtmp://stream.dtube.top/live/" + "url": "rtmp://stream.dlive.tv/live" } - ] + ], + "recommend": { + "keyint": 2, + "max video bitrate": 6000, + "max audio bitrate": 160 + } + }, + { + "name": "Lightcast.com", + "servers": [ + { + "name": "North America / East", + "url": "rtmp://us-east.live.lightcast.com/202E1F/default" + }, + { + "name": "North America / West", + "url": "rtmp://us-west.live.lightcast.com/202E1F/default" + }, + { + "name": "Europe / Amsterdam", + "url": "rtmp://europe.live.lightcast.com/202E1F/default" + }, + { + "name": "Europe / Frankfurt", + "url": "rtmp://europe-fra.live.lightcast.com/202E1F/default" + }, + { + "name": "Europe / Stockholm", + "url": "rtmp://europe-sto.live.lightcast.com/202E1F/default" + }, + { + "name": "Asia / Hong Kong", + "url": "rtmp://asia.live.lightcast.com/202E1F/default" + }, + { + "name": "Australia / Sydney", + "url": "rtmp://australia.live.lightcast.com/202E1F/default" + } + ], + "recommend": { + "keyint": 2, + "max video bitrate": 6000, + "max audio bitrate": 160 + } + }, + { + "name": "Bongacams", + "servers": [ + { + "name": "Default", + "url": "rtmp://origin.bcrncdn.com:1934/live" + } + ], + "recommend": { + "keyint": 2, + "max video bitrate": 6000, + "max audio bitrate": 192 + } + }, + { + "name": "Camplace", + "servers": [ + { + "name": "Camplace - Default", + "url": "rtmp://rtmp.camplace.com" + } + ], + "recommend": { + "keyint": 2, + "max video bitrate": 3000, + "max audio bitrate": 128 + } + }, + { + "name": "OnlyFans.com", + "servers": [ + { + "name": "USA", + "url": "rtmp://route0.onlyfans.com/live" + }, + { + "name": "Europe", + "url": "rtmp://route0-dc2.onlyfans.com/live" + } + ], + "recommend": { + "keyint": 2, + "profile": "main", + "max video bitrate": 2500, + "max audio bitrate": 192, + "bframes": 0, + "x264opts": "tune=zerolatency" + } } ] } diff --git a/plugins/rtmp-services/rtmp-common.c b/plugins/rtmp-services/rtmp-common.c index b7bce8c..272fa77 100644 --- a/plugins/rtmp-services/rtmp-common.c +++ b/plugins/rtmp-services/rtmp-common.c @@ -21,7 +21,8 @@ static const char *rtmp_common_getname(void *unused) } static json_t *open_services_file(void); -static inline json_t *find_service(json_t *root, const char *name); +static inline json_t *find_service(json_t *root, const char *name, + const char **p_new_name); static inline const char *get_string_val(json_t *service, const char *key); extern void twitch_ingests_refresh(int seconds); @@ -75,7 +76,14 @@ static void rtmp_common_update(void *data, obs_data_t *settings) json_t *root = open_services_file(); if (root) { - json_t *serv = find_service(root, service->service); + const char *new_name; + json_t *serv = find_service(root, service->service, &new_name); + + if (new_name) { + bfree(service->service); + service->service = bstrdup(new_name); + } + if (serv) { json_t *rec = json_object_get(serv, "recommended"); if (rec && json_is_object(rec)) { @@ -191,7 +199,7 @@ static void add_services(obs_property_t *list, json_t *root, bool show_all, add_service(list, service, show_all, cur_service); } - service = find_service(root, cur_service); + service = find_service(root, cur_service, NULL); if (!service && cur_service && *cur_service) { obs_property_list_insert_string(list, 0, cur_service, cur_service); @@ -346,16 +354,32 @@ static void fill_servers(obs_property_t *servers_prop, json_t *service, } } -static inline json_t *find_service(json_t *root, const char *name) +static inline json_t *find_service(json_t *root, const char *name, + const char **p_new_name) { size_t index; json_t *service; + if (p_new_name) *p_new_name = NULL; + json_array_foreach (root, index, service) { const char *cur_name = get_string_val(service, "name"); if (strcmp(name, cur_name) == 0) return service; + + /* check for alternate names */ + json_t *alt_names = json_object_get(service, "alt_names"); + size_t alt_name_idx; + json_t *alt_name_obj; + + json_array_foreach (alt_names, alt_name_idx, alt_name_obj) { + const char *alt_name = json_string_value(alt_name_obj); + if (alt_name && strcmp(name, alt_name) == 0) { + if (p_new_name) *p_new_name = cur_name; + return service; + } + } } return NULL; @@ -367,11 +391,12 @@ static bool service_selected(obs_properties_t *props, obs_property_t *p, const char *name = obs_data_get_string(settings, "service"); json_t *root = obs_properties_get_param(props); json_t *service; + const char *new_name; if (!name || !*name) return false; - service = find_service(root, name); + service = find_service(root, name, &new_name); if (!service) { const char *server = obs_data_get_string(settings, "server"); @@ -383,6 +408,10 @@ static bool service_selected(obs_properties_t *props, obs_property_t *p, obs_property_list_item_disable(p, 0, true); return true; } + if (new_name) { + name = new_name; + obs_data_set_string(settings, "service", name); + } fill_servers(obs_properties_get(props, "server"), service, name); @@ -498,7 +527,7 @@ static void apply_audio_encoder_settings(obs_data_t *settings, static void initialize_output(struct rtmp_common *service, json_t *root, obs_data_t *video_settings, obs_data_t *audio_settings) { - json_t *json_service = find_service(root, service->service); + json_t *json_service = find_service(root, service->service, NULL); json_t *recommended; if (!json_service) { diff --git a/plugins/rtmp-services/rtmp-format-ver.h b/plugins/rtmp-services/rtmp-format-ver.h index b861e18..8e4952a 100644 --- a/plugins/rtmp-services/rtmp-format-ver.h +++ b/plugins/rtmp-services/rtmp-format-ver.h @@ -1,3 +1,3 @@ #pragma once -#define RTMP_SERVICES_FORMAT_VERSION 1 +#define RTMP_SERVICES_FORMAT_VERSION 2 diff --git a/plugins/rtmp-services/rtmp-services-main.c b/plugins/rtmp-services/rtmp-services-main.c index 145d5b1..0eeaa73 100644 --- a/plugins/rtmp-services/rtmp-services-main.c +++ b/plugins/rtmp-services/rtmp-services-main.c @@ -10,6 +10,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("rtmp-services", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "OBS core RTMP services"; +} #define RTMP_SERVICES_LOG_STR "[rtmp-services plugin] " #define RTMP_SERVICES_VER_STR "rtmp-services plugin (libobs " OBS_VERSION ")" diff --git a/plugins/text-freetype2/data/locale/bg-BG.ini b/plugins/text-freetype2/data/locale/bg-BG.ini new file mode 100644 index 0000000..4a32502 --- /dev/null +++ b/plugins/text-freetype2/data/locale/bg-BG.ini @@ -0,0 +1,12 @@ +TextFreetype2="Текст (FreeType 2)" +Font="Шрифт" +Text="Текст" +TextFile="Текстов файл (UTF-8 или UTF-16)" +TextFileFilter="Текстови файлове (*.txt);;" +Color1="Цвят 1" +Color2="Цвят 2" +Outline="Контур" +DropShadow="Слагане на сянка" +ReadFromFile="Четене от файл" +CustomWidth="Специфична ширина на текста" + diff --git a/plugins/text-freetype2/data/locale/da-DK.ini b/plugins/text-freetype2/data/locale/da-DK.ini index bff6d6e..ffb05d0 100644 --- a/plugins/text-freetype2/data/locale/da-DK.ini +++ b/plugins/text-freetype2/data/locale/da-DK.ini @@ -1,7 +1,7 @@ TextFreetype2="Tekst (FreeType 2)" Font="Skrifttype" Text="Tekst" -TextFile="Tekstfil (UTF-8- eller UTF-16)" +TextFile="Tekstfil (UTF-8/-16)" TextFileFilter="Tekstfiler (*.txt);;" ChatLogMode="Chatlogtilstand" ChatLogLines="Chatloglinjer" @@ -9,7 +9,7 @@ Color1="Farve 1" Color2="Farve 2" Outline="Kontur" DropShadow="Drop Shadow" -ReadFromFile="Læse fra fil" -CustomWidth="Brugerdefineret tekstbredde" +ReadFromFile="Læs fra fil" +CustomWidth="Tilpasset tekstbredde" WordWrap="Tekstombrydning" diff --git a/plugins/text-freetype2/data/locale/de-DE.ini b/plugins/text-freetype2/data/locale/de-DE.ini index c043f37..46db766 100644 --- a/plugins/text-freetype2/data/locale/de-DE.ini +++ b/plugins/text-freetype2/data/locale/de-DE.ini @@ -3,8 +3,8 @@ Font="Schriftart" Text="Text" TextFile="Textdatei (UTF-8 oder UTF-16)" TextFileFilter="Textdateien (*.txt);;" -ChatLogMode="Chatlogmodus" -ChatLogLines="Chatlogzeilen" +ChatLogMode="Chatprotokollmodus" +ChatLogLines="Chatprotokollzeilen" Color1="Farbe 1" Color2="Farbe 2" Outline="Umrandung" diff --git a/plugins/text-freetype2/data/locale/fa-IR.ini b/plugins/text-freetype2/data/locale/fa-IR.ini new file mode 100644 index 0000000..6a1e508 --- /dev/null +++ b/plugins/text-freetype2/data/locale/fa-IR.ini @@ -0,0 +1,15 @@ +TextFreetype2="متن (FreeType 2)" +Font="فونت" +Text="متن" +TextFile="فایل متن (UTF-8 یا UTF-16)" +TextFileFilter="فایل های متنی (*.txt);;" +ChatLogMode="حالت Chatlog" +ChatLogLines="خط های Chatlog" +Color1="رنگ 1" +Color2="رنگ 2" +Outline="برون نما" +DropShadow="افتادن سایه" +ReadFromFile="از فایل بخوان" +CustomWidth="رنگ متن سفارشی" +WordWrap="بسته بندی کلمات" + diff --git a/plugins/text-freetype2/data/locale/fr-FR.ini b/plugins/text-freetype2/data/locale/fr-FR.ini index 9960695..2b8ffa3 100644 --- a/plugins/text-freetype2/data/locale/fr-FR.ini +++ b/plugins/text-freetype2/data/locale/fr-FR.ini @@ -11,5 +11,5 @@ Outline="Contour" DropShadow="Ombre portée" ReadFromFile="Lire depuis le fichier" CustomWidth="Largeur du texte personnalisée" -WordWrap="Retour à la ligne" +WordWrap="Retour à la ligne automatique" diff --git a/plugins/text-freetype2/data/locale/it-IT.ini b/plugins/text-freetype2/data/locale/it-IT.ini index fd54ce2..57313f9 100644 --- a/plugins/text-freetype2/data/locale/it-IT.ini +++ b/plugins/text-freetype2/data/locale/it-IT.ini @@ -3,13 +3,13 @@ Font="Carattere" Text="Testo" TextFile="File di testo (UTF-8 o UTF-16)" TextFileFilter="File di testo (*.txt);;" -ChatLogMode="Modalità di chat log" -ChatLogLines="Modalità di chat righe" +ChatLogMode="Modalità chat" +ChatLogLines="Righe da visualizzare in modalità chat" Color1="Colore 1" Color2="Colore 2" -Outline="Contorno linea" -DropShadow="Ombra esterna" +Outline="Contorno del testo" +DropShadow="Ombreggiatura del testo" ReadFromFile="Leggi da file" -CustomWidth="Larghezza testo personalizzato" -WordWrap="Word Wrap" +CustomWidth="Larghezza del testo personalizzata" +WordWrap="A capo automatico" diff --git a/plugins/text-freetype2/data/locale/mn-MN.ini b/plugins/text-freetype2/data/locale/mn-MN.ini new file mode 100644 index 0000000..b7e53dd --- /dev/null +++ b/plugins/text-freetype2/data/locale/mn-MN.ini @@ -0,0 +1,15 @@ +TextFreetype2="Текст (FreeType 2)" +Font="Фонт" +Text="Текст" +TextFile="Текст Файл (UTF-8 or UTF-16)" +TextFileFilter="Текст Файл (*.txt);;" +ChatLogMode="Чат маягийн горим" +ChatLogLines="Чат маягийн шугам" +Color1="1-р Өнгө" +Color2="2-р Өнгө" +Outline="Гадуурх зураас" +DropShadow="Сүүдэр Оруулах" +ReadFromFile="Файлаас уншуулах" +CustomWidth="Өөр өргөн текст" +WordWrap="Үг доошоо дараалах" + diff --git a/plugins/text-freetype2/data/locale/pt-PT.ini b/plugins/text-freetype2/data/locale/pt-PT.ini index e30102f..6234345 100644 --- a/plugins/text-freetype2/data/locale/pt-PT.ini +++ b/plugins/text-freetype2/data/locale/pt-PT.ini @@ -3,6 +3,8 @@ Font="Tipo de letra" Text="Texto" TextFile="Ficheiro de texto (UTF-8 ou UTF-16)" TextFileFilter="Ficheiros de texto (*.txt);;" +ChatLogMode="Modo de registo de chat" +ChatLogLines="Linhas do registo de chat" Color1="Cor 1" Color2="Cor 2" Outline="Contorno" diff --git a/plugins/text-freetype2/data/locale/sk-SK.ini b/plugins/text-freetype2/data/locale/sk-SK.ini index 3ef3bee..a7fc002 100644 --- a/plugins/text-freetype2/data/locale/sk-SK.ini +++ b/plugins/text-freetype2/data/locale/sk-SK.ini @@ -3,6 +3,8 @@ Font="Písmo" Text="Text" TextFile="Textový súbor (UTF-8 alebo UTF-16)" TextFileFilter="Textové súbory (*.txt);;" +ChatLogMode="Režim chatu" +ChatLogLines="Počet riadkov v režime chatu" Color1="Farba 1" Color2="Farba 2" Outline="Obrys" diff --git a/plugins/text-freetype2/data/locale/sr-CS.ini b/plugins/text-freetype2/data/locale/sr-CS.ini index 04947b3..9517468 100644 --- a/plugins/text-freetype2/data/locale/sr-CS.ini +++ b/plugins/text-freetype2/data/locale/sr-CS.ini @@ -3,6 +3,8 @@ Font="Font" Text="Tekst" TextFile="Tekstualni dokument (UTF-8 ili UTF-16)" TextFileFilter="Tekstualne datoteke (*.txt);;" +ChatLogMode="Režim prijavljivanja na chat" +ChatLogLines="Broj linija za prijavu na chat" Color1="Boja 1" Color2="Boja 2" Outline="Ivice" diff --git a/plugins/text-freetype2/data/locale/sr-SP.ini b/plugins/text-freetype2/data/locale/sr-SP.ini index 0fad95b..1ad9c97 100644 --- a/plugins/text-freetype2/data/locale/sr-SP.ini +++ b/plugins/text-freetype2/data/locale/sr-SP.ini @@ -3,6 +3,8 @@ Font="Фонт" Text="Текст" TextFile="Текстуални документ (UTF-8 или UTF-16)" TextFileFilter="Текстуалне датотеке (*.txt);;" +ChatLogMode="Режим пријављивања на сhat" +ChatLogLines="Број линија за пријаву на сhat" Color1="Боја 1" Color2="Боја 2" Outline="Ивице" diff --git a/plugins/text-freetype2/obs-convenience.h b/plugins/text-freetype2/obs-convenience.h index 7a717d7..3da3b98 100644 --- a/plugins/text-freetype2/obs-convenience.h +++ b/plugins/text-freetype2/obs-convenience.h @@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ******************************************************************************/ +#pragma once + #include gs_vertbuffer_t *create_uv_vbuffer(uint32_t num_verts, bool add_color); diff --git a/plugins/text-freetype2/text-freetype2.c b/plugins/text-freetype2/text-freetype2.c index 68dd655..9940ec7 100644 --- a/plugins/text-freetype2/text-freetype2.c +++ b/plugins/text-freetype2/text-freetype2.c @@ -28,6 +28,10 @@ FT_Library ft2_lib; OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("text-freetype2", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "FreeType2 text source"; +} uint32_t texbuf_w = 2048, texbuf_h = 2048; diff --git a/plugins/text-freetype2/text-freetype2.h b/plugins/text-freetype2/text-freetype2.h index a3fd49b..654b303 100644 --- a/plugins/text-freetype2/text-freetype2.h +++ b/plugins/text-freetype2/text-freetype2.h @@ -15,6 +15,8 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . ******************************************************************************/ +#pragma once + #include #include diff --git a/plugins/vlc-video/data/locale/ar-SA.ini b/plugins/vlc-video/data/locale/ar-SA.ini index 6802d44..94e77d3 100644 --- a/plugins/vlc-video/data/locale/ar-SA.ini +++ b/plugins/vlc-video/data/locale/ar-SA.ini @@ -1,3 +1,5 @@ VLCSource="مصدر فيديو VLC" Playlist="قائمة تشغيل" +SubtitleTrack="مسار الترجمة" +SubtitleEnable="تفعيل الترجمة" diff --git a/plugins/vlc-video/data/locale/bg-BG.ini b/plugins/vlc-video/data/locale/bg-BG.ini new file mode 100644 index 0000000..dd0ac7c --- /dev/null +++ b/plugins/vlc-video/data/locale/bg-BG.ini @@ -0,0 +1,15 @@ +VLCSource="Видеоизточник за VLC" +Playlist="Списък за изпълнение" +LoopPlaylist="Повтаряне на списъка за изпълнение" +Shuffle="Разбъркване на списъка за изпълнение" +PlaybackBehavior="Поведение при видимост" +PlaybackBehavior.StopRestart="Спиране, когато не се вижда, рестартиране когато се вижда" +PlaybackBehavior.PauseUnpause="Пауза, когато не се вижда, премахване на паузата, когато се вижда" +PlaybackBehavior.AlwaysPlay="Винаги да се пуска, дори когато не се вижда" +NetworkCaching="Мрежово кеширане (мс)" +PlayPause="Пускане/пауза" +Restart="Рестартиране" +Stop="Спиране" +PlaylistNext="Напред" +PlaylistPrev="Назад" + diff --git a/plugins/vlc-video/data/locale/ca-ES.ini b/plugins/vlc-video/data/locale/ca-ES.ini index 76247f9..19e2d79 100644 --- a/plugins/vlc-video/data/locale/ca-ES.ini +++ b/plugins/vlc-video/data/locale/ca-ES.ini @@ -12,4 +12,7 @@ Restart="Reinicia" Stop="Atura" PlaylistNext="Següent" PlaylistPrev="Anterior" +AudioTrack="Pista d'àudio" +SubtitleTrack="Pista de subtítols" +SubtitleEnable="Subtítols activats" diff --git a/plugins/vlc-video/data/locale/cs-CZ.ini b/plugins/vlc-video/data/locale/cs-CZ.ini index a7a10c7..0a4829c 100644 --- a/plugins/vlc-video/data/locale/cs-CZ.ini +++ b/plugins/vlc-video/data/locale/cs-CZ.ini @@ -12,4 +12,7 @@ Restart="Restartovat" Stop="Zastavit" PlaylistNext="Další" PlaylistPrev="Předchozí" +AudioTrack="Zvuková stopa" +SubtitleTrack="Stopa titulků" +SubtitleEnable="Zapnout titulky" diff --git a/plugins/vlc-video/data/locale/da-DK.ini b/plugins/vlc-video/data/locale/da-DK.ini index 402a022..28e8dc1 100644 --- a/plugins/vlc-video/data/locale/da-DK.ini +++ b/plugins/vlc-video/data/locale/da-DK.ini @@ -1,7 +1,7 @@ VLCSource="VLC-videokilde" Playlist="Afspilningsliste" LoopPlaylist="Gentag afspilningsliste" -Shuffle="Bland playliste" +Shuffle="Bland afspilningsliste" PlaybackBehavior="Synlighedsadfærd" PlaybackBehavior.StopRestart="Stop når ikke synlig, genstart når synlig" PlaybackBehavior.PauseUnpause="Pause når ikke synlig, genoptage når synlig" @@ -11,5 +11,8 @@ PlayPause="Afspil/Pause" Restart="Genstart" Stop="Stop" PlaylistNext="Næste" -PlaylistPrev="Forrige" +PlaylistPrev="Foregående" +AudioTrack="Lydspor" +SubtitleTrack="Undertekstspor" +SubtitleEnable="Undertekster aktiveret" diff --git a/plugins/vlc-video/data/locale/de-DE.ini b/plugins/vlc-video/data/locale/de-DE.ini index 2834a70..62d0d45 100644 --- a/plugins/vlc-video/data/locale/de-DE.ini +++ b/plugins/vlc-video/data/locale/de-DE.ini @@ -1,15 +1,18 @@ -VLCSource="VLC Videoquelle" +VLCSource="VLC-Videoquelle" Playlist="Wiedergabeliste" LoopPlaylist="Wiedergabeliste wiederholen" Shuffle="Wiedergabeliste zufällig wiedergeben" PlaybackBehavior="Sichtbarkeitsverhalten" -PlaybackBehavior.StopRestart="Anhalten wenn nicht sichtbar, neu starten wenn sichtbar" -PlaybackBehavior.PauseUnpause="Pausieren wenn nicht sichtbar, fortsetzen wenn sichtbar" +PlaybackBehavior.StopRestart="Anhalten, wenn nicht sichtbar, neustarten, wenn sichtbar" +PlaybackBehavior.PauseUnpause="Pausieren, wenn nicht sichtbar, fortsetzen, wenn sichtbar" PlaybackBehavior.AlwaysPlay="Immer abspielen, auch wenn nicht sichtbar" NetworkCaching="Netzwerkpuffer (ms)" PlayPause="Abspielen/Pausieren" -Restart="Neu starten" +Restart="Neustarten" Stop="Stop" PlaylistNext="Weiter" PlaylistPrev="Zurück" +AudioTrack="Audiospur" +SubtitleTrack="Untertitelspur" +SubtitleEnable="Untertitel aktivieren" diff --git a/plugins/vlc-video/data/locale/en-US.ini b/plugins/vlc-video/data/locale/en-US.ini index 7bf2004..c107364 100644 --- a/plugins/vlc-video/data/locale/en-US.ini +++ b/plugins/vlc-video/data/locale/en-US.ini @@ -12,3 +12,6 @@ Restart="Restart" Stop="Stop" PlaylistNext="Next" PlaylistPrev="Previous" +AudioTrack="Audio Track" +SubtitleTrack="Subtitle Track" +SubtitleEnable="Subtitles Enabled" diff --git a/plugins/vlc-video/data/locale/es-ES.ini b/plugins/vlc-video/data/locale/es-ES.ini index 8ff5597..35b0423 100644 --- a/plugins/vlc-video/data/locale/es-ES.ini +++ b/plugins/vlc-video/data/locale/es-ES.ini @@ -12,4 +12,7 @@ Restart="Reiniciar" Stop="Detener" PlaylistNext="Siguiente" PlaylistPrev="Anterior" +AudioTrack="Pista de audio" +SubtitleTrack="Rastreador de subtítulos" +SubtitleEnable="Subtítulos activados" diff --git a/plugins/vlc-video/data/locale/eu-ES.ini b/plugins/vlc-video/data/locale/eu-ES.ini index 5ba5fdb..37d38dd 100644 --- a/plugins/vlc-video/data/locale/eu-ES.ini +++ b/plugins/vlc-video/data/locale/eu-ES.ini @@ -12,4 +12,7 @@ Restart="Berrabiarazi" Stop="Gelditu" PlaylistNext="Hurrengoa" PlaylistPrev="Aurrekoa" +AudioTrack="Audio-pista" +SubtitleTrack="Azpitituluen pista" +SubtitleEnable="Azpitituluak gaituta" diff --git a/plugins/vlc-video/data/locale/fa-IR.ini b/plugins/vlc-video/data/locale/fa-IR.ini new file mode 100644 index 0000000..3a98f47 --- /dev/null +++ b/plugins/vlc-video/data/locale/fa-IR.ini @@ -0,0 +1,14 @@ +VLCSource="منبع ویدئو VLC" +Playlist="لیست پخش" +LoopPlaylist="فهرست پخش چرخشی" +Shuffle="پخش درهم" +PlaybackBehavior="کنش های دیداری" +PlaybackBehavior.StopRestart="توقف زمانی که قابل مشاهده نیست، راه اندازی مجدد زمانی که قابل مشاهده است" +PlaybackBehavior.PauseUnpause="توقف زمانی که قابل مشاهده نیست، راه اندازی مجدد زمانی که قابل مشاهده است" +NetworkCaching="ذخیره سازی اینترنت (ms)" +PlayPause="پخش/توقف" +Restart="راه اندازی مجدد" +Stop="توقف" +PlaylistNext="بعدی" +PlaylistPrev="قبلی" + diff --git a/plugins/vlc-video/data/locale/fi-FI.ini b/plugins/vlc-video/data/locale/fi-FI.ini index 869f774..5c604f7 100644 --- a/plugins/vlc-video/data/locale/fi-FI.ini +++ b/plugins/vlc-video/data/locale/fi-FI.ini @@ -12,4 +12,7 @@ Restart="Aloita alusta" Stop="Pysäytä" PlaylistNext="Seuraava" PlaylistPrev="Edellinen" +AudioTrack="Ääniraita" +SubtitleTrack="Tekstitysraita" +SubtitleEnable="Tekstitykset käytössä" diff --git a/plugins/vlc-video/data/locale/fr-FR.ini b/plugins/vlc-video/data/locale/fr-FR.ini index d5b6eea..eaa219b 100644 --- a/plugins/vlc-video/data/locale/fr-FR.ini +++ b/plugins/vlc-video/data/locale/fr-FR.ini @@ -1,15 +1,18 @@ VLCSource="Source vidéo VLC" Playlist="Liste de lecture" LoopPlaylist="Répéter la liste de lecture" -Shuffle="Playlist Hazard" +Shuffle="Lecture aléatoire" PlaybackBehavior="Comportement de visibilité" -PlaybackBehavior.StopRestart="Arrêter quand elle n'est pas visible, redémarrer lorsqu'elle est visible" -PlaybackBehavior.PauseUnpause="Suspendre lorsqu'elle n'est pas visible, reprendre lorsqu'elle est visible" -PlaybackBehavior.AlwaysPlay="Toujours jouer même lorsqu'elle n'est pas visible" +PlaybackBehavior.StopRestart="Arrêter quand la source n'est pas visible, redémarrer lorsqu'elle est visible" +PlaybackBehavior.PauseUnpause="Mettre en pause lorsque la source n'est pas visible, reprendre lorsqu'elle est visible" +PlaybackBehavior.AlwaysPlay="Toujours lire même lorsque la source n'est pas visible" NetworkCaching="Mise en cache réseau (ms)" PlayPause="Lecture/Pause" Restart="Redémarrer" Stop="Arrêter" PlaylistNext="Suivant" PlaylistPrev="Précédent" +AudioTrack="Piste audio" +SubtitleTrack="Piste de sous-titre" +SubtitleEnable="Activer les sous-titres" diff --git a/plugins/vlc-video/data/locale/he-IL.ini b/plugins/vlc-video/data/locale/he-IL.ini index b9c8430..d3ef14b 100644 --- a/plugins/vlc-video/data/locale/he-IL.ini +++ b/plugins/vlc-video/data/locale/he-IL.ini @@ -1,6 +1,6 @@ VLCSource="מקור וידאו VLC" Playlist="רשימת השמעה" -LoopPlaylist="לולאת רשימת השמעה" +LoopPlaylist="נגינה חוזרת של רשימת ההשמעה" Shuffle="ערבב רשימת השמעה" PlaybackBehavior="התנהגות ניראות" PlaybackBehavior.StopRestart="עצור כאשר אינו נראה, התחל מחדש כאשר נראה" diff --git a/plugins/vlc-video/data/locale/hu-HU.ini b/plugins/vlc-video/data/locale/hu-HU.ini index 1fa1ffe..28ef03c 100644 --- a/plugins/vlc-video/data/locale/hu-HU.ini +++ b/plugins/vlc-video/data/locale/hu-HU.ini @@ -12,4 +12,7 @@ Restart="Újraindítás" Stop="Leállítás" PlaylistNext="Következő" PlaylistPrev="Előző" +AudioTrack="Hangsáv" +SubtitleTrack="Feliratsáv" +SubtitleEnable="Feliratok engedélyezése" diff --git a/plugins/vlc-video/data/locale/it-IT.ini b/plugins/vlc-video/data/locale/it-IT.ini index 5a8e1cc..d71f06d 100644 --- a/plugins/vlc-video/data/locale/it-IT.ini +++ b/plugins/vlc-video/data/locale/it-IT.ini @@ -1,15 +1,18 @@ -VLCSource="Source Video VLC" +VLCSource="Fonte video di VLC" Playlist="Playlist" -LoopPlaylist="Riproduci playlist di continuo" -Shuffle="Playlist casuale" +LoopPlaylist="Ripeti la playlist" +Shuffle="Mescola la playlist" PlaybackBehavior="Comportamento visibilità" -PlaybackBehavior.StopRestart="Interrompi quando non visibile, riavvia quando visibile" +PlaybackBehavior.StopRestart="Interrompi quando non visibile, ricomincia quando visibile" PlaybackBehavior.PauseUnpause="Pausa quando non visibile, riprendi quando visibile" -PlaybackBehavior.AlwaysPlay="Continua anche quando non visibile" -NetworkCaching="Network Caching (ms)" -PlayPause="Play/Pausa" -Restart="Riavvia" +PlaybackBehavior.AlwaysPlay="Continua sempre anche quando non visibile" +NetworkCaching="Caching di rete (in ms)" +PlayPause="Riproduci/pausa" +Restart="Ricomincia" Stop="Interrompi" PlaylistNext="Successivo" PlaylistPrev="Precedente" +AudioTrack="Traccia audio" +SubtitleTrack="Traccia sottotitoli" +SubtitleEnable="Sottotitoli attivati" diff --git a/plugins/vlc-video/data/locale/ja-JP.ini b/plugins/vlc-video/data/locale/ja-JP.ini index 0812205..732733c 100644 --- a/plugins/vlc-video/data/locale/ja-JP.ini +++ b/plugins/vlc-video/data/locale/ja-JP.ini @@ -12,4 +12,7 @@ Restart="再開" Stop="停止" PlaylistNext="次へ" PlaylistPrev="前へ" +AudioTrack="音声トラック" +SubtitleTrack="字幕トラック" +SubtitleEnable="字幕を有効にする" diff --git a/plugins/vlc-video/data/locale/ka-GE.ini b/plugins/vlc-video/data/locale/ka-GE.ini index 3f39162..d21f9aa 100644 --- a/plugins/vlc-video/data/locale/ka-GE.ini +++ b/plugins/vlc-video/data/locale/ka-GE.ini @@ -12,4 +12,7 @@ Restart="თავიდან გაშვება" Stop="შეწყვეტა" PlaylistNext="შემდეგი" PlaylistPrev="წინა" +AudioTrack="ხმოვანი ბილიკი" +SubtitleTrack="სუბტიტრების ჩანაწერი" +SubtitleEnable="სუბტიტრები ჩართულია" diff --git a/plugins/vlc-video/data/locale/ko-KR.ini b/plugins/vlc-video/data/locale/ko-KR.ini index 20d85e0..c2cc00c 100644 --- a/plugins/vlc-video/data/locale/ko-KR.ini +++ b/plugins/vlc-video/data/locale/ko-KR.ini @@ -12,4 +12,7 @@ Restart="재시작" Stop="중단" PlaylistNext="다음" PlaylistPrev="이전" +AudioTrack="음성 트랙" +SubtitleTrack="자막 트랙:" +SubtitleEnable="자막 활성화" diff --git a/plugins/vlc-video/data/locale/nb-NO.ini b/plugins/vlc-video/data/locale/nb-NO.ini index 59c3280..5f9a1ff 100644 --- a/plugins/vlc-video/data/locale/nb-NO.ini +++ b/plugins/vlc-video/data/locale/nb-NO.ini @@ -12,4 +12,7 @@ Restart="Start på nytt" Stop="Stopp avspilling" PlaylistNext="Neste" PlaylistPrev="Forrige" +AudioTrack="Lydspor" +SubtitleTrack="Undertekstspor" +SubtitleEnable="Undertekster aktivert" diff --git a/plugins/vlc-video/data/locale/nl-NL.ini b/plugins/vlc-video/data/locale/nl-NL.ini index 1516ac0..c9f6370 100644 --- a/plugins/vlc-video/data/locale/nl-NL.ini +++ b/plugins/vlc-video/data/locale/nl-NL.ini @@ -12,4 +12,7 @@ Restart="Herstart" Stop="Stop" PlaylistNext="Volgende" PlaylistPrev="Vorige" +AudioTrack="Geluidsspoor" +SubtitleTrack="Ondertitelspoor" +SubtitleEnable="Ondertitels ingeschakeld" diff --git a/plugins/vlc-video/data/locale/pl-PL.ini b/plugins/vlc-video/data/locale/pl-PL.ini index 60f8922..c329796 100644 --- a/plugins/vlc-video/data/locale/pl-PL.ini +++ b/plugins/vlc-video/data/locale/pl-PL.ini @@ -12,4 +12,7 @@ Restart="Zrestartuj" Stop="Zatrzymaj" PlaylistNext="Następny" PlaylistPrev="Poprzedni" +AudioTrack="Ścieżka audio" +SubtitleTrack="Ścieżka napisów" +SubtitleEnable="Napisy włączone" diff --git a/plugins/vlc-video/data/locale/pt-BR.ini b/plugins/vlc-video/data/locale/pt-BR.ini index 8cdc6eb..23f0d0c 100644 --- a/plugins/vlc-video/data/locale/pt-BR.ini +++ b/plugins/vlc-video/data/locale/pt-BR.ini @@ -12,4 +12,7 @@ Restart="Reiniciar" Stop="Parar" PlaylistNext="Próximo" PlaylistPrev="Anterior" +AudioTrack="Faixa de áudio" +SubtitleTrack="Faixa de legenda" +SubtitleEnable="Legendas ativadas" diff --git a/plugins/vlc-video/data/locale/ro-RO.ini b/plugins/vlc-video/data/locale/ro-RO.ini index 21720d9..1988c04 100644 --- a/plugins/vlc-video/data/locale/ro-RO.ini +++ b/plugins/vlc-video/data/locale/ro-RO.ini @@ -1,2 +1,15 @@ VLCSource="Sursă Video VLC" +Playlist="Listă de redare" +LoopPlaylist="Repetă lista de redare" +Shuffle="Amestecă lista de redare" +PlaybackBehavior="Comportament vizibilitate" +PlaybackBehavior.StopRestart="Oprește cand nu este vizibil, repornește cand este vizibil" +PlaybackBehavior.PauseUnpause="Pauză cand nu este vizibil, continuă cand este vizibil" +PlaybackBehavior.AlwaysPlay="Redă întotdeauna chiar si când nu este vizibil" +NetworkCaching="Caching de rețea (ms)" +PlayPause="Redă/Pauză" +Restart="Repornește" +Stop="Oprește" +PlaylistNext="Următorul" +PlaylistPrev="Anteriorul" diff --git a/plugins/vlc-video/data/locale/ru-RU.ini b/plugins/vlc-video/data/locale/ru-RU.ini index a6c6b52..03c12b0 100644 --- a/plugins/vlc-video/data/locale/ru-RU.ini +++ b/plugins/vlc-video/data/locale/ru-RU.ini @@ -12,4 +12,7 @@ Restart="Перезапустить" Stop="Остановить" PlaylistNext="Следующий" PlaylistPrev="Предыдущий" +AudioTrack="Звуковая дорожка" +SubtitleTrack="Дорожка субтитров" +SubtitleEnable="Субтитры включены" diff --git a/plugins/vlc-video/data/locale/sk-SK.ini b/plugins/vlc-video/data/locale/sk-SK.ini index 516690b..0140a08 100644 --- a/plugins/vlc-video/data/locale/sk-SK.ini +++ b/plugins/vlc-video/data/locale/sk-SK.ini @@ -1,5 +1,5 @@ VLCSource="VLC Video zdroj" -Playlist="Playlist" +Playlist="Zoznam skladieb" LoopPlaylist="Opakovať zoznam skladieb" Shuffle="Prehrať zoznam skladieb náhodne" PlaybackBehavior="Fungovanie podľa viditeľnosti" @@ -12,4 +12,7 @@ Restart="Reštartovať" Stop="Zastaviť" PlaylistNext="Ďalší" PlaylistPrev="Predchádzajúci" +AudioTrack="Zvuková stopa" +SubtitleTrack="Stopa titulkov" +SubtitleEnable="Zapnuté titulky" diff --git a/plugins/vlc-video/data/locale/sr-CS.ini b/plugins/vlc-video/data/locale/sr-CS.ini index a136269..ff2ec80 100644 --- a/plugins/vlc-video/data/locale/sr-CS.ini +++ b/plugins/vlc-video/data/locale/sr-CS.ini @@ -1,8 +1,15 @@ VLCSource="VLC video izvor" Playlist="Plejlista" LoopPlaylist="Ponavljanje plejliste" +Shuffle="Puštaj nasumično" PlaybackBehavior="Ponašanje pri (ne)vidljivosti" PlaybackBehavior.StopRestart="Zaustavi kada se ne vidi, ponovi kad se vidi" PlaybackBehavior.PauseUnpause="Pauziraj kada se ne vidi, odpauziraj kada se vidi" PlaybackBehavior.AlwaysPlay="Uvek reprodukuj čak i kada se ne vidi" +NetworkCaching="Kešing mreže (ms)" +PlayPause="Pusti/Pauziraj" +Restart="Restartuj" +Stop="Zaustavi" +PlaylistNext="Sledeći" +PlaylistPrev="Prethodni" diff --git a/plugins/vlc-video/data/locale/sr-SP.ini b/plugins/vlc-video/data/locale/sr-SP.ini index 6a670cd..bba1c79 100644 --- a/plugins/vlc-video/data/locale/sr-SP.ini +++ b/plugins/vlc-video/data/locale/sr-SP.ini @@ -1,8 +1,15 @@ VLCSource="VLC видео извор" Playlist="Плејлиста" LoopPlaylist="Понављање плејлисте" +Shuffle="Пуштај насумично" PlaybackBehavior="Понашање при (не)видљивости" PlaybackBehavior.StopRestart="Заустави када се не види, понови када се види" PlaybackBehavior.PauseUnpause="Паузирај када се не види, одпаузирај када се види" PlaybackBehavior.AlwaysPlay="Увек репродукуј чак и када се не види" +NetworkCaching="Кешинг мреже (ms)" +PlayPause="Пусти/Паузирај" +Restart="Рестартуј" +Stop="Заустави" +PlaylistNext="Следећи" +PlaylistPrev="Претходни" diff --git a/plugins/vlc-video/data/locale/sv-SE.ini b/plugins/vlc-video/data/locale/sv-SE.ini index 3659b6d..9d1c603 100644 --- a/plugins/vlc-video/data/locale/sv-SE.ini +++ b/plugins/vlc-video/data/locale/sv-SE.ini @@ -12,4 +12,7 @@ Restart="Starta om" Stop="Stoppa" PlaylistNext="Nästa" PlaylistPrev="Föregående" +AudioTrack="Ljudspår" +SubtitleTrack="Undertextspår" +SubtitleEnable="Aktivera undertexter" diff --git a/plugins/vlc-video/data/locale/tr-TR.ini b/plugins/vlc-video/data/locale/tr-TR.ini index 6613990..1973625 100644 --- a/plugins/vlc-video/data/locale/tr-TR.ini +++ b/plugins/vlc-video/data/locale/tr-TR.ini @@ -12,4 +12,7 @@ Restart="Yeniden Başlat" Stop="Durdur" PlaylistNext="Sonraki" PlaylistPrev="Önceki" +AudioTrack="Ses Parçası" +SubtitleTrack="Altyazı Parçası" +SubtitleEnable="Altyazılar Etkin" diff --git a/plugins/vlc-video/data/locale/uk-UA.ini b/plugins/vlc-video/data/locale/uk-UA.ini index 0ee636f..009ac30 100644 --- a/plugins/vlc-video/data/locale/uk-UA.ini +++ b/plugins/vlc-video/data/locale/uk-UA.ini @@ -12,4 +12,7 @@ Restart="Грати з початку" Stop="Зупинити" PlaylistNext="Наступний" PlaylistPrev="Попередній" +AudioTrack="Аудіо доріжка" +SubtitleTrack="Доріжка субтитрів" +SubtitleEnable="Увімкнути субтитри" diff --git a/plugins/vlc-video/data/locale/zh-CN.ini b/plugins/vlc-video/data/locale/zh-CN.ini index d033d57..9e77e43 100644 --- a/plugins/vlc-video/data/locale/zh-CN.ini +++ b/plugins/vlc-video/data/locale/zh-CN.ini @@ -12,4 +12,7 @@ Restart="重启" Stop="停止" PlaylistNext="下一个" PlaylistPrev="上一个" +AudioTrack="音频轨道" +SubtitleTrack="字幕轨道" +SubtitleEnable="开启字幕" diff --git a/plugins/vlc-video/data/locale/zh-TW.ini b/plugins/vlc-video/data/locale/zh-TW.ini index c5c2664..b794fbd 100644 --- a/plugins/vlc-video/data/locale/zh-TW.ini +++ b/plugins/vlc-video/data/locale/zh-TW.ini @@ -12,4 +12,7 @@ Restart="重新開始" Stop="停止" PlaylistNext="下一個" PlaylistPrev="前一個" +AudioTrack="音樂曲目" +SubtitleTrack="字幕軌" +SubtitleEnable="字幕已啟用" diff --git a/plugins/vlc-video/vlc-video-plugin.c b/plugins/vlc-video/vlc-video-plugin.c index d87ae51..b0668e0 100644 --- a/plugins/vlc-video/vlc-video-plugin.c +++ b/plugins/vlc-video/vlc-video-plugin.c @@ -7,6 +7,10 @@ OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("vlc-video", "en-US") +MODULE_EXPORT const char *obs_module_description(void) +{ + return "VLC playlist source"; +} /* libvlc core */ LIBVLC_NEW libvlc_new_; diff --git a/plugins/vlc-video/vlc-video-source.c b/plugins/vlc-video/vlc-video-source.c index 09c6da4..a436e2e 100644 --- a/plugins/vlc-video/vlc-video-source.c +++ b/plugins/vlc-video/vlc-video-source.c @@ -18,6 +18,9 @@ #define S_BEHAVIOR_PAUSE_UNPAUSE "pause_unpause" #define S_BEHAVIOR_ALWAYS_PLAY "always_play" #define S_NETWORK_CACHING "network_caching" +#define S_TRACK "track" +#define S_SUBTITLE_ENABLE "subtitle_enable" +#define S_SUBTITLE_TRACK "subtitle" #define T_(text) obs_module_text(text) #define T_PLAYLIST T_("Playlist") @@ -28,6 +31,9 @@ #define T_BEHAVIOR_PAUSE_UNPAUSE T_("PlaybackBehavior.PauseUnpause") #define T_BEHAVIOR_ALWAYS_PLAY T_("PlaybackBehavior.AlwaysPlay") #define T_NETWORK_CACHING T_("NetworkCaching") +#define T_TRACK T_("AudioTrack") +#define T_SUBTITLE_ENABLE T_("SubtitleEnable") +#define T_SUBTITLE_TRACK T_("SubtitleTrack") /* ------------------------------------------------------------------------- */ @@ -176,7 +182,7 @@ static enum video_format convert_vlc_video_format(char *chroma, bool *full) /* 4:4:4 formats */ CHROMA_TEST("I444", VIDEO_FORMAT_I444); - CHROMA_CONV_FULL("J444", "J444", VIDEO_FORMAT_I444); + CHROMA_CONV_FULL("J444", "RGBA", VIDEO_FORMAT_RGBA); CHROMA_CONV("YUVA", "RGBA", VIDEO_FORMAT_RGBA); /* 4:4:0 formats */ @@ -403,7 +409,8 @@ static int vlcs_audio_setup(void **p_data, char *format, unsigned *rate, } static void add_file(struct vlc_source *c, struct darray *array, - const char *path, int network_caching) + const char *path, int network_caching, int track_index, + int subtitle_index, bool subtitle_enable) { DARRAY(struct media_file_data) new_files; struct media_file_data data; @@ -436,6 +443,19 @@ static void add_file(struct vlc_source *c, struct darray *array, network_caching_option.array); dstr_free(&network_caching_option); } + struct dstr track_option = { 0 }; + dstr_catf(&track_option, + ":audio-track=%d", track_index - 1); + libvlc_media_add_option_(new_media, track_option.array); + dstr_free(&track_option); + + struct dstr sub_option = {0}; + if (subtitle_enable) { + dstr_catf(&sub_option, + ":sub-track=%d", subtitle_index - 1); + } + libvlc_media_add_option_(new_media, sub_option.array); + dstr_free(&sub_option); data.path = new_path.array; data.media = new_media; @@ -490,6 +510,9 @@ static void vlcs_update(void *data, obs_data_t *settings) const char *behavior; size_t count; int network_caching; + int track_index; + int subtitle_index; + bool subtitle_enable; da_init(new_files); da_init(old_files); @@ -503,6 +526,12 @@ static void vlcs_update(void *data, obs_data_t *settings) network_caching = (int)obs_data_get_int(settings, S_NETWORK_CACHING); + track_index = (int)obs_data_get_int(settings, S_TRACK); + + subtitle_index = (int)obs_data_get_int(settings, S_SUBTITLE_TRACK); + + subtitle_enable = obs_data_get_bool(settings, S_SUBTITLE_ENABLE); + if (astrcmpi(behavior, S_BEHAVIOR_PAUSE_UNPAUSE) == 0) { c->behavior = BEHAVIOR_PAUSE_UNPAUSE; } else if (astrcmpi(behavior, S_BEHAVIOR_ALWAYS_PLAY) == 0) { @@ -540,13 +569,17 @@ static void vlcs_update(void *data, obs_data_t *settings) dstr_cat_ch(&dir_path, '/'); dstr_cat(&dir_path, ent->d_name); add_file(c, &new_files.da, dir_path.array, - network_caching); + network_caching, track_index, + subtitle_index, + subtitle_enable); } dstr_free(&dir_path); os_closedir(dir); } else { - add_file(c, &new_files.da, path, network_caching); + add_file(c, &new_files.da, path, network_caching, + track_index, subtitle_index, + subtitle_enable); } obs_data_release(item); @@ -833,6 +866,9 @@ static void vlcs_defaults(obs_data_t *settings) obs_data_set_default_string(settings, S_BEHAVIOR, S_BEHAVIOR_STOP_RESTART); obs_data_set_default_int(settings, S_NETWORK_CACHING, 400); + obs_data_set_default_int(settings, S_TRACK, 1); + obs_data_set_default_bool(settings, S_SUBTITLE_ENABLE, false); + obs_data_set_default_int(settings, S_SUBTITLE_TRACK, 1); } static obs_properties_t *vlcs_properties(void *data) @@ -902,6 +938,10 @@ static obs_properties_t *vlcs_properties(void *data) obs_properties_add_int(ppts, S_NETWORK_CACHING, T_NETWORK_CACHING, 100, 60000, 10); + obs_properties_add_int(ppts, S_TRACK, T_TRACK, 1, 10, 1); + obs_properties_add_bool(ppts, S_SUBTITLE_ENABLE, T_SUBTITLE_ENABLE); + obs_properties_add_int(ppts, S_SUBTITLE_TRACK, T_SUBTITLE_TRACK, + 1, 10, 1); return ppts; }