{"id":87067,"date":"2020-07-03T07:42:03","date_gmt":"2020-07-03T05:42:03","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2"},"modified":"2020-07-03T07:42:03","modified_gmt":"2020-07-03T05:42:03","slug":"izuchaem-voip-dvizhok-mediastreamer2-chast-2","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2","title":{"rendered":"Badanie silnika VoIP Mediastreamer2. Cz\u0119\u015b\u0107 2","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Materia\u0142 artyku\u0142u pochodzi z mojego <noindex><a rel=\"nofollow\" href=\"https:\/\/zen.yandex.ru\/id\/5e3f8e0751f5346faab4fc7a\">kana\u0142u Zen<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Badanie silnika VoIP Mediastreamer2. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2020\/07\/1afc1603a438f865c56bba72012d591e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h2 id=\"sozdaem-tonalnyy-generator\">Tworzymy generator tonalny<\/h2>\n<p><\/p>\n<p>W poprzednim <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/495702\/\">artyku\u0142<\/a><\/noindex> Zainstalowali\u015bmy bibliotek\u0119 do strumieniowania medi\u00f3w, narz\u0119dzia deweloperskie i sprawdzili\u015bmy ich dzia\u0142anie, tworz\u0105c aplikacj\u0119 pr\u00f3bk\u0119.<\/p>\n<p><\/p>\n<p>Dzi\u015b stworzymy aplikacj\u0119, kt\u00f3ra b\u0119dzie mog\u0142a generowa\u0107 tonalny sygna\u0142 na karcie d\u017awi\u0119kowej. Aby rozwi\u0105za\u0107 to zadanie, musimy po\u0142\u0105czy\u0107 filtry w pokazanej poni\u017cej schemacie generatora d\u017awi\u0119ku:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Badanie silnika VoIP Mediastreamer2. Cz\u0119\u015b\u0107 2\" src=\"\/wp-content\/uploads\/2020\/07\/249759aec6235d3285e6ba6c28524710.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Czytamy schemat z lewej do prawej, w tym kierunku p\u0142ynie nasz strumie\u0144 danych. Strza\u0142ki r\u00f3wnie\u017c to sugeruj\u0105. Prostok\u0105ty oznaczaj\u0105 filtry, kt\u00f3re przetwarzaj\u0105 bloki danych i wystawiaj\u0105 wynik na wyj\u015bcie. Wewn\u0105trz prostok\u0105ta podana jest jego rola, a poni\u017cej wielkimi literami typ filtru. Strza\u0142ki \u0142\u0105cz\u0105ce prostok\u0105ty to kolejki danych, po kt\u00f3rych bloki danych s\u0105 dostarczane z filtra do filtra. W og\u00f3lnym przypadku filtr mo\u017ce mie\u0107 wiele wej\u015b\u0107 i wyj\u015b\u0107.<\/p>\n<p><\/p>\n<p>Wszystko zaczyna si\u0119 od \u017ar\u00f3d\u0142a takt\u00f3w, kt\u00f3re ustala tempo, w jakim przetwarzane s\u0105 dane w filtrach. W rytmie jego takt\u00f3w ka\u017cdy filtr przetwarza wszystkie bloki danych, kt\u00f3re znajduj\u0105 si\u0119 na jego wej\u015bciu, i wystawia bloki z wynikiem na wyj\u015bcie \u2014 do kolejki. Najpierw obliczenia wykonuje filtr najbli\u017cszy \u017ar\u00f3d\u0142u takt\u00f3w, nast\u0119pnie filtry pod\u0142\u0105czone do jego wyj\u015b\u0107 (mo\u017ce ich by\u0107 wiele) i tak dalej. Kiedy ostatni filtr w \u0142a\u0144cuchu zako\u0144czy obliczenia, wykonanie zatrzymuje si\u0119 do momentu, gdy nadejdzie nowy takt. Takty, domy\u015blnie, nast\u0119puj\u0105 w odst\u0119pach 10 milisekund. <\/p>\n<p><\/p>\n<p>Wr\u00f3\u0107my do naszego schematu. Takty trafiaj\u0105 na wej\u015bcie \u017ar\u00f3d\u0142a ciszy, to jest filtr, kt\u00f3ry generuje na swoim wyj\u015bciu blok danych zawieraj\u0105cy zera na ka\u017cdy takt. Je\u015bli spojrze\u0107 na ten blok jako na blok pomiar\u00f3w d\u017awi\u0119ku, to nie jest nic innego jak cisza. Na pierwszy rzut oka wydaje si\u0119 to dziwne, generowa\u0107 bloki danych z ciszy \u2014 przecie\u017c nie mo\u017cna jej us\u0142ysze\u0107, ale te bloki s\u0105 niezb\u0119dne do dzia\u0142ania generatora sygna\u0142u d\u017awi\u0119kowego. Generator wykorzystuje te bloki jak czyst\u0105 kartk\u0119 papieru, zapisuj\u0105c na nich pomiary d\u017awi\u0119kowe. W swoim normalnym stanie generator jest wy\u0142\u0105czony i po prostu przesy\u0142a bloki wej\u015bciowe na wyj\u015bcie. W ten spos\u00f3b bloki ciszy przechodz\u0105 bez zmian przez ca\u0142y schemat z lewej do prawej, trafiaj\u0105c do karty d\u017awi\u0119kowej. Karta d\u017awi\u0119kowa cicho odbiera bloki z kolejki pod\u0142\u0105czonej do jej wej\u015bcia.<\/p>\n<p><\/p>\n<p>Jednak wszystko zmienia si\u0119, gdy generator otrzymuje polecenie odtwarzania d\u017awi\u0119ku, zaczyna generowa\u0107 pomiary d\u017awi\u0119kowe i zast\u0119puje nimi pomiary w blokach wej\u015bciowych, wystawiaj\u0105c zmodyfikowane bloki na wyj\u015bcie. Karta d\u017awi\u0119kowa zaczyna odtwarza\u0107 d\u017awi\u0119k. Poni\u017cej znajduje si\u0119 program, kt\u00f3ry realizuje powy\u017cej opisan\u0105 prac\u0119:<\/p>\n<p><\/p>\n<pre><code class=\"cpp\">\/* \u0424\u0430\u0439\u043b mstest2.c *\/\n#include &lt;mediastreamer2\/msfilter.h&gt;\n#include &lt;mediastreamer2\/msticker.h&gt;\n#include &lt;mediastreamer2\/dtmfgen.h&gt;\n#include &lt;mediastreamer2\/mssndcard.h&gt;\nint main()\n{\n    ms_init();\n\n    \/* \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432. *\/\n    MSFilter  *voidsource = ms_filter_new(MS_VOID_SOURCE_ID);\n    MSFilter  *dtmfgen = ms_filter_new(MS_DTMF_GEN_ID);\n    MSSndCard *card_playback = ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());\n    MSFilter  *snd_card_write = ms_snd_card_create_writer(card_playback);\n\n    \/* \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u0438\u043a\u0435\u0440. *\/\n    MSTicker *ticker = ms_ticker_new();\n\n    \/* \u0421\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443. *\/\n    ms_filter_link(voidsource, 0, dtmfgen, 0);\n    ms_filter_link(dtmfgen, 0, snd_card_write, 0);\n\n   \/* \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0442\u0430\u043a\u0442\u043e\u0432. *\/\n   ms_ticker_attach(ticker, voidsource);\n\n   \/* \u0412\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440. *\/\n   char key='1';\n   ms_filter_call_method(dtmfgen, MS_DTMF_GEN_PLAY, (void*)&amp;key);\n\n   \/* \u0414\u0430\u0435\u043c, \u0432\u0440\u0435\u043c\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u0435 \u0431\u043b\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439.*\/\n   ms_sleep(2);   \n}<\/code><\/pre>\n<p><\/p>\n<p>Po zainicjowaniu mediastreamera nast\u0119puje utworzenie trzech filtr\u00f3w: <em>voidsource, dtmfgen, snd_card_write<\/em>. Tworzony jest \u017ar\u00f3d\u0142o sygna\u0142u taktowego.<\/p>\n<p><\/p>\n<p>Nast\u0119pnie nale\u017cy po\u0142\u0105czy\u0107 filtry zgodnie z naszym schematem, a \u017ar\u00f3d\u0142o takt\u00f3w pod\u0142\u0105czy\u0107 jako ostatnie, poniewa\u017c natychmiast po tym zacznie dzia\u0142a\u0107 schemat. Je\u015bli pod\u0142\u0105czysz \u017ar\u00f3d\u0142o takt\u00f3w do niedoko\u0144czonego schematu, mo\u017ce si\u0119 zdarzy\u0107, \u017ce strumie\u0144 medi\u00f3w zako\u0144czy dzia\u0142anie awaryjnie, je\u015bli wykryje w \u0142a\u0144cuchu chocia\u017c jeden filtr, kt\u00f3rego wszystkie wej\u015bcia lub wszystkie wyj\u015bcia \"wisz\u0105 w powietrzu\" (nie s\u0105 pod\u0142\u0105czone). <\/p>\n<p><\/p>\n<p>Po\u0142\u0105czenie filtr\u00f3w wykonuje si\u0119 za pomoc\u0105 funkcji <\/p>\n<p><\/p>\n<pre><code class=\"cpp\">ms_filter_link(src, src_out, dst, dst_in)<\/code><\/pre>\n<p><\/p>\n<p>, gdzie pierwszy argument to wska\u017anik na filtr \u017ar\u00f3d\u0142owy, drugi argument to numer wyj\u015bcia \u017ar\u00f3d\u0142a (zwr\u00f3\u0107 uwag\u0119, \u017ce wej\u015bcia i wyj\u015bcia s\u0105 numerowane od zera). Trzeci argument to wska\u017anik na filtr odbieraj\u0105cy, czwarty \u2014 numer wej\u015bcia odbiornika.<\/p>\n<p><\/p>\n<p>Wszystkie filtry s\u0105 po\u0142\u0105czone, a ostatnim pod\u0142\u0105czanym \u017ar\u00f3d\u0142em jest generator takt\u00f3w (dalej b\u0119dziemy go nazywa\u0107 tikkerem). Po tym nasza schemat d\u017awi\u0119kowa zaczyna dzia\u0142a\u0107, ale w g\u0142o\u015bnikach komputera na razie nic nie s\u0142ycha\u0107 \u2014 generator d\u017awi\u0119ku jest wy\u0142\u0105czony i po prostu przepuszcza przez siebie dane wej\u015bciowe z cisz\u0105. Aby uruchomi\u0107 generacj\u0119 sygna\u0142u tonalnego, konieczne jest wykonanie metody filtra generatora.<\/p>\n<p><\/p>\n<p>B\u0119dziemy generowa\u0107 sygna\u0142 dwutonowy (DTMF) odpowiadaj\u0105cy naci\u015bni\u0119ciu na telefonie przycisku \"1\". W tym celu skorzystamy z funkcji <em>ms_filter_call_method()<\/em> wywo\u0142ujemy metod\u0119 MS_DTMF_GEN_PLAY, przekazuj\u0105c jej jako argument wska\u017anik na kod, kt\u00f3remu powinien odpowiada\u0107 odtwarzany sygna\u0142.<\/p>\n<p><\/p>\n<p>Pozostaje skompilowa\u0107 program:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ gcc mstest2.c -o mstest2 `pkg-config mediastreamer --libs --cflags`<\/code><\/pre>\n<p><\/p>\n<p>I uruchomi\u0107:<\/p>\n<p><\/p>\n<pre><code class=\"bash\">$ .\/mstest2<\/code><\/pre>\n<p><\/p>\n<p>Po uruchomieniu programu us\u0142yszysz w g\u0142o\u015bnikach komputera kr\u00f3tki sygna\u0142 d\u017awi\u0119kowy sk\u0142adaj\u0105cy si\u0119 z dw\u00f3ch ton\u00f3w.<\/p>\n<p><\/p>\n<p>Zbudowali\u015bmy i uruchomili\u015bmy nasz\u0105 pierwsz\u0105 schemat d\u017awi\u0119kow\u0105. Zobaczyli\u015bmy, jak tworzy\u0107 instancje filtr\u00f3w, jak je \u0142\u0105czy\u0107 i jak wywo\u0142ywa\u0107 ich metody. Ciesz\u0105c si\u0119 z pierwszego sukcesu, musimy jednak zwr\u00f3ci\u0107 uwag\u0119 na to, \u017ce nasz program nie zwalnia przydzielonej pami\u0119ci przed zako\u0144czeniem. W nast\u0119pnym <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/495780\/\">artyku\u0142<\/a><\/noindex> nauczymy si\u0119 sprz\u0105ta\u0107 po sobie.<\/p>\n<p>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/495728\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043c\u0435\u0434\u0438\u0430\u0441\u0442\u0440\u0438\u043c\u0435\u0440\u0430, \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b\u0438 \u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435, \u0441\u043e\u0431\u0440\u0430\u0432 \u043f\u0440\u043e\u0431\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u043f\u0438\u043b\u0438\u043a\u0430\u0442\u044c \u043d\u0430 \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u0435 \u0442\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u0433\u043d\u0430\u043b. \u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0432 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u043d\u0438\u0436\u0435 \u0441\u0445\u0435\u043c\u0443 \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430: \u0427\u0438\u0442\u0430\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u0441\u043b\u0435\u0432\u0430 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":87068,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87067","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0418\u0437\u0443\u0447\u0430\u0435\u043c VoIP-\u0434\u0432\u0438\u0436\u043e\u043a Mediastreamer2. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-03T05:42:03+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-03T05:42:03+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Zg\u0142\u0119biamy silnik VoIP Mediastreamer2. Cz\u0119\u015b\u0107 2 | ProHoster","description":"Materia\u0142 artyku\u0142u pochodzi z mojego kana\u0142u Dzen.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0418\u0437\u0443\u0447\u0430\u0435\u043c VoIP-\u0434\u0432\u0438\u0436\u043e\u043a Mediastreamer2. \u0427\u0430\u0441\u0442\u044c 2 | ProHoster","og:description":"\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u0437\u044f\u0442 \u0441 \u043c\u043e\u0435\u0433\u043e \u0434\u0437\u0435\u043d-\u043a\u0430\u043d\u0430\u043b\u0430.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/izuchaem-voip-dvizhok-mediastreamer2-chast-2","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-03T05:42:03+00:00","article:modified_time":"2020-07-03T05:42:03+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87067","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:59:55","updated":"2022-10-04 22:45:55","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/87067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=87067"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/87067\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/87068"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=87067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=87067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=87067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}