{"id":403394,"date":"2024-06-29T17:06:10","date_gmt":"2024-06-29T17:06:10","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=403394"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-06-29T17:06:10","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=403394","title":{"rendered":"<span>\u0423\u0441\u043a\u043e\u0440\u044f\u0435\u043c \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0443 \u043c\u0430\u0448\u0438\u043d\u044b \u0432\u00a0\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0410\u0432\u0442\u043e.\u0440\u0443<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ev\/y0\/j3\/evy0j3ktg6bmpn8afvb3ozingzk.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/ev\/y0\/j3\/evy0j3ktg6bmpn8afvb3ozingzk.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0410\u0432\u0442\u043e.\u0440\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0444\u0438\u0447\u0430 \u2014 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u044b \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u0435\u0439. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c 3D-\u0444\u043e\u0442\u043e \u0441\u0432\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b, \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0435\u0451 \u0432\u043e \u0432\u0441\u0435\u0439 \u043a\u0440\u0430\u0441\u0435. \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043a\u0430\u043a \u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u0438\u0437 ML \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d \u0442\u043e, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u0446\u0435\u043b\u043e\u0433\u043e \u0430\u043d\u0433\u0430\u0440\u0430, \u043d\u0430\u043f\u0438\u0447\u043a\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c, <a href=\"https:\/\/habr.com\/ru\/users\/yaantonn\/\" class=\"user_link\">yaantonn<\/a> \u0443\u0436\u0435 <a href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/508180\/\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b<\/a> \u043d\u0430 \u0425\u0430\u0431\u0440\u0435. <\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043e\u0442\u0441\u043d\u044f\u0442\u044c \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0443 \u2014 \u043b\u0438\u0448\u044c \u043f\u043e\u043b\u0434\u0435\u043b\u0430. \u0417\u0430\u0442\u0435\u043c \u0435\u0451 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0430 \u0442\u043e\u043f\u043e\u0432\u043e\u043c \u0444\u043b\u0430\u0433\u043c\u0430\u043d\u0435, \u0438 \u043d\u0430 \u0431\u044e\u0434\u0436\u0435\u0442\u043d\u043e\u043c \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0435.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"chto-za-panorama-takaya\">\u0427\u0442\u043e \u0437\u0430 \u00ab\u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0430\u00bb \u0442\u0430\u043a\u0430\u044f?<\/h2>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/qw\/74\/dp\/qw74dpehwfcq1nw03rj3j-rnqvk.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/qw\/74\/dp\/qw74dpehwfcq1nw03rj3j-rnqvk.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u041f\u0430\u043d\u043e\u0440\u0430\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f \u2014 \u043d\u0435 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0430 \u043f\u0435\u0439\u0437\u0430\u0436\u0430.<\/p>\n<p>  <\/p>\n<p><b>\u0421 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b<\/b><\/p>\n<p>  <\/p>\n<p>\u041f\u0430\u043d\u043e\u0440\u0430\u043c\u043e\u0439 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f \u043c\u044b \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c 3D-\u0444\u043e\u0442\u043e \u043c\u0430\u0448\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u043e\u0440\u043e\u043d, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u00ab\u0443\u0434\u0430\u0447\u043d\u044b\u0445\u00bb \u0440\u0430\u043a\u0443\u0440\u0441\u043e\u0432, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0434\u0430\u0432\u0446\u043e\u043c \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0442\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u044d\u043a\u0441\u0442\u0435\u0440\u044c\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u00ab\u0442\u043e\u0447\u0435\u043a \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430\u00bb.<\/p>\n<p>  <\/p>\n<p><b>\u0421 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/fd\/bv\/hj\/fdbvhjdlg24wrwe8ypunp-nkmdy.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/fd\/bv\/hj\/fdbvhjdlg24wrwe8ypunp-nkmdy.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0445\u043e\u0442\u044c \u043c\u044b \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0432\u0444\u0435\u043c\u0438\u0437\u043c \u00ab3D-\u0444\u043e\u0442\u043e\u00bb, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0430 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f \u2014 \u044d\u0442\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0435 \u0432\u0438\u0434\u0435\u043e (\u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043d\u0430 120 \u043a\u0430\u0434\u0440\u043e\u0432), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0435\u043e\u0431\u044b\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. <\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u043e\u0435 \u0432\u0438\u0434\u0435\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0441\u043c\u043e\u0442\u0440\u044f\u0442 \u043e\u0442 \u043d\u0430\u0447\u0430\u043b\u0430 \u0438 \u0434\u043e \u043a\u043e\u043d\u0446\u0430, \u0438\u0437\u0440\u0435\u0434\u043a\u0430 \u043f\u0435\u0440\u0435\u043c\u0430\u0442\u044b\u0432\u0430\u044f \u0432\u043f\u0435\u0440\u0451\u0434. \u041d\u0430\u0448\u0435 \u0436\u0435 \u0432\u0438\u0434\u0435\u043e \u0441\u0442\u043e\u0438\u0442 \u043d\u0430 \u043f\u0430\u0443\u0437\u0435, \u0438 \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u043a\u0440\u043e\u043b\u043b\u0438\u0442\u044c \u0435\u0433\u043e, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u0434\u0440\u043e\u0432 \u0432\u043f\u0435\u0440\u0451\u0434 \u0438\u043b\u0438 \u043d\u0430\u0437\u0430\u0434, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043b\u043b\u044e\u0437\u0438\u044e \u043e\u0431\u044a\u0451\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<h2 id=\"naivnyy-podhod--prosto-pleer\">\u041d\u0430\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043b\u0435\u0435\u0440<\/h2>\n<p>  <\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 \u0437\u0432\u0443\u0447\u0430\u043b\u0430 \u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0437\u0430 \u043a\u043e\u043d\u0441\u0443\u043b\u044c\u0442\u0430\u0446\u0438\u0435\u0439 \u043a iOS-\u043a\u043e\u043c\u0430\u043d\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b\u0430 \u043a \u044d\u0442\u043e\u0439 \u0444\u0438\u0447\u0435 \u0447\u0443\u0442\u044c \u0440\u0430\u043d\u044c\u0448\u0435. \u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0414\u0438\u043c\u0430 \u043e\u0442\u0432\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u043e\u043d\u0438 \u0432\u0437\u044f\u043b\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u043b\u0435\u0435\u0440, \u0437\u0430\u043f\u0438\u0445\u043d\u0443\u043b\u0438 \u0432 \u043d\u0435\u0433\u043e \u0432\u0438\u0434\u043e\u0441\u0438\u043a \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u043f\u0440\u043e\u043c\u0430\u0442\u044b\u0432\u0430\u044e\u0442 \u0435\u0433\u043e \u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0430\u0434\u0440 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043f\u0430\u043b\u044c\u0446\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c. <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0440\u0430\u0434\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u0437\u0430 \u043a\u043e\u043b\u043b\u0435\u0433, \u043c\u044b \u0432\u0437\u044f\u043b\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u0441 ExoPlayer, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0436\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043a\u0440\u0443\u0442\u0438\u0432 \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 GestureDetector, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u043d\u0430\u0448 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f \u043d\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0435 \u0438\u2026<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/wb\/lg\/mj\/wblgmjedkmel8exnthplkq7goj4.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/wb\/lg\/mj\/wblgmjedkmel8exnthplkq7goj4.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u043b\u0430\u0431\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u0445 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u043d\u0438\u044f, \u043a\u0430\u043a \u0443 \u043a\u043e\u043b\u043b\u0435\u0433 \u043d\u0430 iOS, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043b\u0430\u0439\u0434-\u0448\u043e\u0443. \u041d\u0430 \u0441\u0432\u0435\u0436\u0438\u0445, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 <a href=\"https:\/\/source.android.com\/devices\/media\/low-latency-media?hl=en\">Low Latency Media API<\/a>, \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e. \u041f\u0440\u043e\u0444\u0430\u0439\u043b\u0435\u0440 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0441\u043e\u043a\u0443\u044e \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043a \u043a\u0430\u0434\u0440\u0430\u043c \u0438 \u043f\u0435\u0440\u0435\u043c\u043e\u0442\u043a\u0435. \u0414\u0430 \u0432\u044b \u0438 \u0441\u0430\u043c\u0438 \u0432\u0438\u0434\u0438\u0442\u0435 \u0432\u0441\u0451 \u043d\u0430 \u0433\u0438\u0444\u043a\u0435. <\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0436, \u043d\u0430 \u0442\u043e \u043c\u044b \u0438 Android-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0436\u0438\u0437\u043d\u044c \u043c\u0451\u0434\u043e\u043c \u043d\u0435 \u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u0430 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0439 UX \u0438 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u041f\u043e\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0443 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 R&amp;D \u0438 \u043d\u0430\u0447\u0430\u043b\u0438 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c, \u043e\u0442\u0447\u0435\u0433\u043e \u043d\u0430\u0448\u0438 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u044b \u0442\u0430\u043a \u043b\u0430\u0433\u0430\u044e\u0442.<\/p>\n<p>  <\/p>\n<h2 id=\"chto-ne-tak-s-naivnym-podhodom\">\u0427\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0441 \u043d\u0430\u0438\u0432\u043d\u044b\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c?<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432\u044b\u0448\u0435, \u0432\u0438\u0434\u0435\u043e \u0441 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u043e\u0439 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u0430\u0447\u0435, \u0447\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u0435. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u0434\u0440\u044b \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c, \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043a\u0430\u0434\u0440: \u0442\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043c\u043e\u0436\u0435\u0442 \u043a\u0440\u0443\u0442\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044c \u043f\u0430\u043b\u044c\u0446\u0435\u043c \u0432\u043f\u0435\u0440\u0451\u0434-\u043d\u0430\u0437\u0430\u0434, \u043a\u0430\u043a \u0435\u043c\u0443 \u0432\u0437\u0434\u0443\u043c\u0430\u0435\u0442\u0441\u044f. \u0421\u043f\u043e\u0439\u043b\u0435\u0440: \u0432 \u044d\u0442\u043e\u043c \u0438 \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e, \u0432\u0435\u0434\u044c \u0432\u0438\u0434\u0435\u043e\u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u041d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<p>  <\/p>\n<p><b>\u041a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u0432\u0438\u0434\u0435\u043e\u0444\u043e\u0440\u043c\u0430\u0442\u044b?<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/3b\/zl\/h_\/3bzlh_xsk_ks4is7dkd6qoucso8.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/3b\/zl\/h_\/3bzlh_xsk_ks4is7dkd6qoucso8.jpeg\" data-blurred=\"true\"\/><\/p>\n<p>  <\/p>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0438\u0434\u0435\u043e \u2014 \u044d\u0442\u043e, \u043f\u043e \u0441\u0443\u0442\u0438, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u043a\u0430\u0434\u0440\u0430\u043c\u0438. \u041a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u2014 \u0443\u0436\u0435 \u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u044f \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043f\u043e \u043e\u0441\u044f\u043c <em>x<\/em> \u0438 <em>y<\/em>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0446\u0432\u0435\u0442\u043e\u0432. \u0423\u043c\u043d\u043e\u0436\u0438\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0451\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 24, 30, \u0430 \u0442\u043e \u0438 60 \u0438\u043b\u0438 120 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443 \u0438 \u0441\u0442\u0430\u043d\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 \u0432\u0438\u0434\u0435\u043e \u0431\u0435\u0437 \u0441\u0436\u0430\u0442\u0438\u044f \u0432\u044b \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u0435 \u0432 \u043f\u043e\u0432\u0441\u0435\u0434\u043d\u0435\u0432\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438. \u041d\u0430\u0448\u0430 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u0441\u0435\u0433\u043e \u0438\u0437 120 \u043a\u0430\u0434\u0440\u043e\u0432 (3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u043f\u0440\u0438 \u043f\u043e\u0447\u0442\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c 30FPS) \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c 1280\u0445720 \u0438 \u0431\u0435\u0437 \u0441\u0436\u0430\u0442\u0438\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430 \u0431\u044b \u043e\u043a\u043e\u043b\u043e 316 \u041c\u0411. \u042d\u0442\u043e \u043a\u0430\u0442\u0430\u0441\u0442\u0440\u043e\u0444\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043d\u043e\u0433\u043e, \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0432\u0438\u0434\u0435\u043e \u043f\u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u0412\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043a\u0443\u043f\u0438\u0442\u0435 \u0441\u0435\u0431\u0435 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0435, \u0447\u0435\u043c \u0434\u043e\u0436\u0434\u0451\u0442\u0435\u0441\u044c \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><b>Spatial compression<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/5t\/bs\/oc\/5tbsoclak9fmz778y-fd5gthnha.jpeg\" width=\"500\" data-src=\"https:\/\/habrastorage.org\/webt\/5t\/bs\/oc\/5tbsoclak9fmz778y-fd5gthnha.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0433\u043e\u043b\u043e\u0432\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0434\u043b\u044f \u0441\u0436\u0430\u0442\u0438\u044f \u0432\u0438\u0434\u0435\u043e \u2014 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0435 \u0442\u0440\u044e\u043a\u0438 \u0434\u043b\u044f \u0441\u0436\u0430\u0442\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u041d\u043e \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u043f\u0435\u0440\u0435\u0436\u0430\u043b\u0438 \u0432\u0441\u0435 \u043a\u0430\u0434\u0440\u044b \u0432\u0438\u0434\u0435\u043e \u0432 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 JPEG, \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0430\u0448 \u0442\u0440\u0451\u0445\u0441\u0435\u043a\u0443\u043d\u0434\u043d\u044b\u0439 \u0432\u0438\u0434\u043e\u0441\u0438\u043a \u0437\u0430\u043d\u0438\u043c\u0430\u043b \u0431\u044b \u043e\u043a\u043e\u043b\u043e 31 \u041c\u0411 (\u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u043e\u0432). <\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u0436\u0430\u0442\u0438\u044f \u0432\u0438\u0434\u0435\u043e, \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u0430\u043f. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0439\u0442\u0438 \u0435\u0449\u0451 \u0434\u0430\u043b\u044c\u0448\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0442\u044c \u043c\u044b\u0441\u043b\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u043c\u0438 \u043a\u0430\u0434\u0440\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p><b>Temporal compression<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ws\/mb\/2z\/wsmb2z0kqjxylf4aykplid7ddfw.png\" width=\"400\" data-src=\"https:\/\/habrastorage.org\/webt\/ws\/mb\/2z\/wsmb2z0kqjxylf4aykplid7ddfw.png\"\/>  <\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0432\u0438\u0434\u0435\u043e, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0444\u043e\u043d \u043f\u043e\u0437\u0430\u0434\u0438 \u0433\u043e\u043b\u043e\u0432\u044b \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430) \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0434\u0432\u0438\u0436\u043d\u044b\u043c\u0438 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u0430\u0434\u0440\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439. \u042d\u0442\u043e \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f temporal redundancy, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u043a\u0443\u0441\u043e\u0447\u043a\u0438 \u0438\u0437 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0443\u0447\u0430\u0441\u0442\u043a\u043e\u0432 \u043a\u0430\u0434\u0440\u0430 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u0430\u0434\u0440\u0430\u0445. \u041f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c \u043d\u0430 MPEG-2. \u0412 \u043d\u0451\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0442\u0440\u0438 \u0432\u0438\u0434\u0430 \u043a\u0430\u0434\u0440\u043e\u0432: I-, P- \u0438 B-\u043a\u0430\u0434\u0440\u044b.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/c8\/zo\/6o\/c8zo6oehpaytpzwv9iunl8d2bym.png\" data-src=\"https:\/\/habrastorage.org\/webt\/c8\/zo\/6o\/c8zo6oehpaytpzwv9iunl8d2bym.png\"\/><\/p>\n<p>  <\/p>\n<ul>\n<li>I-\u043a\u0430\u0434\u0440\u044b<\/li>\n<\/ul>\n<p>  <\/p>\n<p>I-\u043a\u0430\u0434\u0440\u044b \u0435\u0449\u0451 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u00ab\u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438\u00bb \u2014 \u0432 \u043d\u0438\u0445 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u043c\u043f\u043e\u0440\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u0436\u0430\u0442\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u043f\u043e\u0440\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0438\u0434\u043e\u0432 \u043a\u0430\u0434\u0440\u043e\u0432. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u0441\u043b\u0443\u0436\u0430\u0442 \u00ab\u043f\u0430\u043b\u0438\u0442\u0440\u043e\u0439\u00bb \u0434\u043b\u044f \u0442\u0435\u0445 \u043a\u0443\u0441\u043a\u043e\u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u043a\u0430\u0434\u0440\u0443 \u0431\u0435\u0437 \u043e\u0441\u043e\u0431\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>  <\/p>\n<ul>\n<li>P-\u043a\u0430\u0434\u0440\u044b<\/li>\n<\/ul>\n<p>  <\/p>\n<p>P-\u043a\u0430\u0434\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043a\u0430\u0434\u0440\u043e\u0432. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438, \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a\u043e\u0439 \u0443\u0447\u0430\u0441\u0442\u043e\u043a \u043a\u0430\u043a\u043e\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d, \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438 \u0432 \u043a\u0430\u043a\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c.<\/p>\n<p>  <\/p>\n<ul>\n<li>B-\u043a\u0430\u0434\u0440\u044b<\/li>\n<\/ul>\n<p>  <\/p>\n<p>B-\u043a\u0430\u0434\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043a\u0430\u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445, \u0442\u0430\u043a \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u0430\u0434\u0440\u043e\u0432. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0439\u0442\u0438 \u0434\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e I-\u043a\u0430\u0434\u0440\u0430.<\/p>\n<p>  <\/p>\n<p><b>\u0422\u0430\u043a \u043f\u043e\u0447\u0435\u043c\u0443 \u0436\u0435 \u043d\u0430\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442?<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/yu\/pg\/wf\/yupgwfew6s5ra2uw6aikeowbymy.png\" width=\"400\" data-src=\"https:\/\/habrastorage.org\/webt\/yu\/pg\/wf\/yupgwfew6s5ra2uw6aikeowbymy.png\"\/>  <\/p>\n<p>  <\/p>\n<p>\u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u0438\u0432\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u043b\u0435\u0435\u0440 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u043a\u0430\u0434\u0440\u0430\u043c \u0440\u0430\u0441\u0441\u044b\u043f\u0430\u0435\u0442\u0441\u044f, \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u0432\u0448\u0438\u0441\u044c \u0441 P- \u0438 B-\u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0432\u0438\u0434\u0435\u043e. \u0412\u0435\u0434\u044c \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u0434\u0440\u044b, \u043d\u0443\u0436\u043d\u043e:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041d\u0430\u0439\u0442\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 B-\u043a\u0430\u0434\u0440\u0430 \u0435\u0449\u0451 \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439) I-\u043a\u0430\u0434\u0440. <\/li>\n<li>\u0420\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0432\u0441\u0435 \u043a\u0430\u0434\u0440\u044b \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c \u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u043c \u043d\u0430\u0441 \u043a\u0430\u0434\u0440\u043e\u043c. <\/li>\n<li>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0439 \u043d\u0430\u0441 \u043a\u0430\u0434\u0440 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0447\u0451\u043c \u043f\u043b\u0435\u0435\u0440, \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0434 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e, \u0432\u0440\u044f\u0434 \u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043f\u043e\u0434 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0443\u0436\u0435 \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u043a\u0430\u0434\u0440\u043e\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043c\u0430\u043b\u0435\u0439\u0448\u0435\u043c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0438 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u043d\u043e\u0432\u043e.<\/p>\n<p>  <\/p>\n<h2 id=\"raspakovyvaem-video-pri-pomoschi-mediametadataretriever\">\u0420\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432\u0438\u0434\u0435\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 MediaMetadataRetriever<\/h2>\n<p>  <\/p>\n<p>\u041c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u0440\u0438\u0431\u0435\u0433\u043d\u0443\u0442\u044c \u043a \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u0435\u043a\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u043e\u043d\u0442\u0430\u0436\u0430 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e\u0435 \u0441\u0436\u0430\u0442\u0438\u0435 \u043f\u0440\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0438\u0445 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u043c \u043a\u0430\u0434\u0440\u0430\u043c \u0432\u0438\u0434\u0435\u043e. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043e\u043f\u0440\u0430\u0432\u0434\u0430\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u043e\u0437\u0440\u043e\u0441\u043b\u0430 \u0431\u044b \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u0441\u0435\u0442\u044c, \u0434\u0430 \u0438 \u043d\u0435 \u0432\u0441\u0435 \u0434\u0435\u0432\u0430\u0439\u0441\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u044d\u0442\u0438 \u043a\u043e\u0434\u0435\u043a\u0438. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0441\u0442\u0430\u0440\u044b\u0435 \u043c\u043e\u0434\u0435\u043b\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u0438 \u0445\u043e\u0442\u0435\u043b\u0438 \u043f\u043e\u0447\u0438\u043d\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. <\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0438\u0437\u043a\u0438\u0439 \u043e\u0431\u044a\u0451\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u043e \u0441\u0435\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u043c\u0435\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u0430\u0434\u0440\u0430\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0451 \u0432\u0438\u0434\u0435\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u043d\u0430\u0432\u0438\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0436\u0435 \u043f\u043e \u043d\u0438\u043c.<\/p>\n<p>  <\/p>\n<p><b>MediaMetadataRetriever API<\/b><\/p>\n<p>  <\/p>\n<p>\u0423 MediaMetadataRetriever \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e-\u0442\u0430\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0435 API. \u041d\u0430\u043c \u0432\u0441\u0435\u0433\u043e-\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c URI \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u0438\u0434\u0435\u043e \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0441\u0435 \u0444\u0440\u0435\u0439\u043c\u044b \u0432 \u0431\u0438\u0442\u043c\u0430\u043f\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    val retriever = MediaMetadataRetriever()     try {         retriever.setDataSource(context, videoUri)         val framesCount = retriever             .extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT)             ?.toIntOrNull() ?: 0         for (i in 0 until framesCount) {             retriever.getFrameAtIndex(i)?.let { bm ->                 bm.writeToFile(file)                 bm.recycle()             }         }     } finally {         retriever.release()     }<\/code><\/pre>\n<p>  <\/p>\n<p><b>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/k2\/bv\/qn\/k2bvqnu6mbtpsisshvddhmavr-e.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/k2\/bv\/qn\/k2bvqnu6mbtpsisshvddhmavr-e.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c, \u0440\u0430\u0431\u043e\u0442\u0430\u044f \u0441 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u0430\u0434\u0440\u0430\u043c\u0438 \u0431\u0435\u0437 \u0442\u0435\u043c\u043f\u043e\u0440\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0436\u0430\u0442\u0438\u044f, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043b\u0430\u0432\u043d\u0443\u044e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u0431\u0435\u0437 \u0440\u044b\u0432\u043a\u043e\u0432 \u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<p>  <\/p>\n<p><b>\u0417\u0430\u043c\u0435\u0440\u044f\u0435\u043c \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0443<\/b><\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u043d\u0438\u0435\u043c \u0432\u0438\u0434\u0435\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u044d\u0442\u0430\u043f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0431\u044b\u043b\u043e \u0435\u0433\u043e \u0437\u0430\u043c\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0434 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u043b\u0438 \u0433\u0440\u0443\u0441\u0442\u043d\u0443\u044e \u043a\u0440\u0443\u0442\u0438\u043b\u043a\u0443 \u043f\u0430\u043d\u043e\u0440\u0430\u043c. \u041d\u0430 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u0443\u0445\u043e\u0434\u0438\u043b\u043e \u0442\u0440\u0438 \u0441\u0435\u043a\u0443\u043d\u0434\u044b. \u0412\u0440\u0435\u043c\u044f \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0435\u0435, \u043d\u043e \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0435. <\/p>\n<p>  <\/p>\n<p>\u0418 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u043e\u0441\u0442\u0430\u043b\u0438 \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e <a href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/485050\/\">\u0413\u0438\u043f\u0435\u0440\u043a\u0443\u0431\u0430<\/a> Nexus 6. \u041a\u043e\u0433\u0434\u0430-\u0442\u043e \u00ab\u0442\u043e\u043f \u0437\u0430 \u0441\u0432\u043e\u0438 \u0434\u0435\u043d\u044c\u0433\u0438\u00bb, \u044d\u0442\u043e\u0442 \u043b\u0435\u0433\u0435\u043d\u0434\u0430\u0440\u043d\u044b\u0439 \u0441\u0442\u0430\u0440\u0438\u0447\u043e\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0440\u043e\u043b\u044c \u0440\u0435\u0444\u0435\u0440\u0435\u043d\u0441\u0430 low-end-\u0434\u0435\u0432\u0430\u0439\u0441\u0430. \u0423\u0445, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u043e\u043d \u043e\u0431\u043b\u043e\u043c\u0430\u043b \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043a\u0430\u0442\u043a\u043e\u0439. \u041e\u0431\u043b\u043e\u043c\u0430\u043b \u043e\u043d \u0438 \u043d\u0430\u0441: \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 35 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0430 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u043b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0436\u0430\u0441\u0435\u043d. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a R&amp;D \u0438 \u0434\u0443\u043c\u0430\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c.<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\">\n<thead>\n<tr>\n<th>\u0414\u0435\u0432\u0430\u0439\u0441<\/th>\n<th>\u0412\u0440\u0435\u043c\u044f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>OnePlus 9 Pro<\/td>\n<td>3,5 \u0441<\/td>\n<\/tr>\n<tr>\n<td>Nexus 6<\/td>\n<td>35 \u0441<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<h2 id=\"ischem-sposoby-sdelat-eto-bystree-na-low-level\">\u0418\u0449\u0435\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043d\u0430 Low Level<\/h2>\n<p>  <\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0447\u0442\u043e-\u0442\u043e \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u0438 \u0432\u0437\u044f\u0442\u044c \u0434\u0435\u043b\u043e \u0432 \u0441\u0432\u043e\u0438 \u0440\u0443\u043a\u0438. \u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 <a href=\"https:\/\/cs.android.com\/android\/platform\/superproject\/+\/master:frameworks\/av\/media\/libmediaplayerservice\/StagefrightMetadataRetriever.cpp;drc=master;bpv=1;bpt=1;l=276?gsn=getFrameInternal&amp;gs=kythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%3Flang%3Dc%252B%252B%3Fpath%3Dframeworks%2Fav%2Fmedia%2Flibmediaplayerservice%2FStagefrightMetadataRetriever.h%23NUWC41nS4x6mOe2qfz-Z_CslRaTNQZlcvoRUmORotj0&amp;gs=kythe%3A%2F%2Fandroid.googlesource.com%2Fplatform%2Fsuperproject%3Flang%3Dc%252B%252B%3Fpath%3Dframeworks%2Fav%2Fmedia%2Flibmediaplayerservice%2FStagefrightMetadataRetriever.cpp%23H5z-ovjySCzMEXGRYVeBtN4Vsi9bpMWurqLMN2_qE2Q\">\u0441\u043e\u0440c\u043e\u0432 MediaMetadataRetriever<\/a> \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u0432 \u0447\u0451\u043c \u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430\u044f \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0442\u043e\u0440\u043c\u043e\u0437\u043e\u0432: \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 getFrameAtIndex \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0434\u0435\u043a\u043e\u0434\u0435\u0440 \u0438 \u043e\u0442\u043c\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0430\u0434\u0440. \u0410 \u043a\u0430\u043a \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u0434\u0440\u0430\u043c \u2014 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u0430\u044f \u0448\u0442\u0443\u043a\u0430. <\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, Android \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c API \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u0430\u043c\u0438. \u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0432\u0430\u0436\u043d\u044b\u0445 \u0434\u043b\u044f \u043d\u0430\u0441 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f MediaCodec, \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u0434\u0435\u043a\u0430\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0435\u0432\u0430\u0439\u0441.<\/p>\n<p>  <\/p>\n<p><b>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u043e\u0434\u0435\u043a\u0438 \u0432 Android<\/b><\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/60\/3j\/9b\/603j9brfxrqxl-omuxt3bovstjs.gif\" width=\"500\" data-src=\"https:\/\/habrastorage.org\/webt\/60\/3j\/9b\/603j9brfxrqxl-omuxt3bovstjs.gif\"\/>  <\/p>\n<p>  <\/p>\n<p>MediaCodec \u2014 \u044d\u0442\u043e \u0441\u0438\u0433\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c \u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c \u0431\u0443\u0444\u0435\u0440\u0430\u043c\u0438. \u041c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448\u0438 \u0431\u0430\u0439\u0442\u0438\u043a\u0438 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u0430\u0434\u0440\u044b \u0432 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u043c.<\/p>\n<p>  <\/p>\n<p><b>MediaExtractor<\/b><\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0438 \u0436\u0434\u0430\u0442\u044c \u0447\u0443\u0434\u0430. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0434\u0435\u043a \u043c\u043e\u0433 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0435 \u0432\u0438\u0434\u0435\u043e, \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u0437\u043d\u0430\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: \u0444\u043e\u0440\u043c\u0430\u0442, \u0431\u0438\u0442\u0440\u0435\u0439\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0438 \u0431\u044b\u043b \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b. <\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0432\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u0441\u0430\u043c\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430. \u0410 \u0432 Low Level Media API \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 MediaExtractor, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0430\u043d\u0435\u0442 \u0432\u0441\u0451 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0437\u0430 \u043d\u0430\u0441.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    \/\/ \u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u0434\u0435\u043a     val extractor = MediaExtractor()     extractor.setDataSource(context, uri, null)      var format: MediaFormat? = null     var decoder: MediaCodec? = null     for (i in 0 until extractor.trackCount) {         \/\/ \u043d\u0430\u0445\u043e\u0434\u0438\u043c mime \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a\u0430         format = extractor.getTrackFormat(i)         val mime = format.getString(MediaFormat.KEY_MIME)         if (mime != null &amp;&amp; mime.startsWith(\"video\/\")) {             extractor.selectTrack(i)             \/\/ \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u043e\u0434\u0435\u043a \u0441 \u044d\u0442\u0438\u043c mime             decoder = MediaCodec.createByCodecName(mime)             break         }     }      \/\/ \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e, \u043e\u043d\u043e \u043d\u0430\u043c \u0435\u0449\u0451 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f     val width = format.getInteger(MediaFormat.KEY_WIDTH)     val height = format.getInteger(MediaFormat.KEY_HEIGHT)     val surface = createSurface(width, height)      \/\/ \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0444\u043e\u0440\u043c\u0430\u0442\u0435     \/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u043a\u043e\u0434\u0435\u043a\u0443     decoder.configure(format, surface, null, 0)<\/code><\/pre>\n<p>  <\/p>\n<p><b>\u0421\u0442\u0435\u0439\u0442-\u043c\u0430\u0448\u0438\u043d\u0430<\/b><\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u0442\u0430\u0449\u0438\u043b\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0438 \u043d\u0430\u0442\u0440\u0430\u0432\u0438\u043b\u0438 \u043d\u0430 \u043d\u0438\u0445 \u043d\u0430\u0448 \u043a\u043e\u0434\u0435\u043a, \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u043a \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0435. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043d\u0430 <a href=\"https:\/\/developers.android.com\">https:\/\/developers.android.com<\/a> \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0435\u043a\u0430. \u0421\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0432 \u043d\u0435\u0439 \u2014 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u0434\u0435\u043a\u0430.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/is\/yw\/rb\/isywrb3hll3f1p5do9jcswzuvxw.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/is\/yw\/rb\/isywrb3hll3f1p5do9jcswzuvxw.jpeg\" data-blurred=\"true\"\/><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 <code>decoder.configure(...)<\/code> \u043d\u0430\u0448 \u043a\u043e\u0434\u0435\u043a \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>configured<\/code> \u0438 \u0436\u0434\u0451\u0442, \u043f\u043e\u043a\u0430 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0435\u0433\u043e \u0438 \u043d\u0430\u0447\u043d\u0451\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u0412\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0447\u0442\u0438 \u0443\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b, \u0432 \u0445\u043e\u0434\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0435 \u0447\u0430\u043d\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e MediaExtractor \u0438 \u043e\u0442\u0434\u0430\u0451\u043c \u0438\u0445 \u043a\u043e\u0434\u0435\u043a\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    fun doExtract(         extractor: MediaExtractor,         decoder: MediaCodec,         onFrameDecoded: () -> Unit     ) {         val infor = MediaCodec.BufferInfo()         val isOutputDone = false         val isInputDone = false         val frameIndex = 0         while (!isOutputDone) {             \/\/ \u0414\u0430\u0451\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043d\u0430 \u0432\u0445\u043e\u0434 \u043a\u043e\u0434\u0435\u043a\u0443             if (!isInputDone) {                 \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u0431\u0443\u0444\u0435\u0440\u0430                 val inputBufferIndex = decoder.dequeueInputBuffer(BUFFER_TIMEOUT_US)                 \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0443\u043b\u044f, \u0442\u043e \u044d\u0442\u043e\u0442 \u0431\u0443\u0444\u0435\u0440 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0438                 if (inputBufferIndex >= 0) {                     val inputBuffer = decoder.getInputBuffer(inputBufferIndex)                     val chunkSize = extractor.readSampleData(inputBuffer, 0)                     \/\/ \u0415\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0441\u0442\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u0447\u0430\u043d\u043a\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435 \u043d\u0443\u043b\u044f, \u0442\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0441\u044f                     if (chunkSize &lt; 0) {                         \/\/ \u0418 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441\u0438\u0433\u043d\u0430\u043b \u043e\u0431 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0438 \u043f\u043e\u0442\u043e\u043a\u0430 \u0432 \u043a\u043e\u0434\u0435\u043a                         decoder.queueInputBuffer(inputBufferIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM)                         isInputDone = true                     } else {                         \/\/ \u0418\u043d\u0430\u0447\u0435 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043d\u043e\u0432\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0432 \u043a\u043e\u0434\u0435\u043a                         val presentationTimeUs = extractor.sampleTime                         decoder.queueInputBuffer(inputBufferIndex, 0, chunkSize, presentationTimeUs, 0)                         \/\/ \u0418 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u044d\u043a\u0441\u0442\u0440\u0430\u043a\u0442\u043e\u0440 \u0434\u0430\u043b\u044c\u0448\u0435, \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0434\u0435\u043a\u0441                         extractor.advance()                     }                 }             }             \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u043e\u0434\u0435\u043a\u0430             if (!isOutputDone) {                 val decoderStatus = dequeueOutputBuffer(info, BUFFER_TIMEOUT_US)                 when {                     decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER -> {                         \/\/ \u0412\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u0435\u0449\u0451 \u043f\u0443\u0441\u0442                     }                     decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED -> {                         \/\/ \u0414\u043b\u044f \u043d\u0430\u0441 \u043d\u0435 \u0432\u0430\u0436\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Surface                     }                     decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED -> {                         \/\/ \u0412\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u0441\u044f                     }                     decoderStatus &lt; 0 -> {                         error(\"unexpected result from decoder.dequeueOutputBuffer: $decoderStatus\")                     }                     decoderStatus >= 0 -> { \/\/ \u0412\u0441\u0451 \u043e\u043a, \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435                         \/\/ \u0415\u0441\u043b\u0438 \u043c\u044b \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438 \u043a\u043e\u043d\u0446\u0430 \u043f\u043e\u0442\u043e\u043a\u0430, \u0442\u043e \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0442\u044c \u0446\u0438\u043a\u043b                         if ((info.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {                             isOutputDone = true                         }                         \/\/ \u041d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u0435\u0441\u0442\u044c                         val doRender = info.size != 0                         \/\/ \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043a\u043e\u0434\u0435\u043a\u0443, \u0447\u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u043e\u0439 \u0431\u0443\u0444\u0435\u0440 \u043d\u0430 surface                         decoder.releaseOutputBuffer(decoderStatus, doRender)                         if (doRender) {                             \/\/ \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u0432 \u043a\u043e\u043b\u043b\u0431\u044d\u043a, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u043a\u0430\u0434\u0440                             onFrameDecoded(frameIndex)                             frameIndex++                         }                     }                 }             }         }     }<\/code><\/pre>\n<p>  <\/p>\n<p><b>Surface<\/b><\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041c\u044b \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0438\u0445 \u043f\u043e\u043a\u0430\u0434\u0440\u043e\u0432\u043e \u0432 \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u0441\u044b\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u0434\u0435\u043a\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0431\u0438\u0442\u043c\u0430\u043f. \u0412 \u044d\u0442\u043e\u043c \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0434\u0440\u043e\u0432 \u043d\u0430 Surface \u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0435\u0433\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0432 \u0431\u0438\u0442\u043c\u0430\u043f. <\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 Surface \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c. \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0435\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u044e\u0442 TextureView \u0438 SurfaceView, \u043d\u043e \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u044d\u0442\u043e\u0442 Surface, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u043c\u044b \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0433\u043e \u0441\u0430\u043c\u0438. \u0412 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0441 \u0441\u0435\u043c\u043f\u043b\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Low Level Media API <a href=\"https:\/\/github.com\/google\/grafika\">https:\/\/github.com\/google\/grafika<\/a> \u0435\u0441\u0442\u044c \u043d\u0435\u043f\u043b\u043e\u0445\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c off-screen Surface \u0438 \u043f\u0430\u0440\u0430 \u0443\u0442\u0438\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u043a \u0441\u0435\u0431\u0435 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442. \u041e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u2014 EglCore, \u043f\u0440\u044f\u0447\u0443\u0449\u0438\u0439 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442 \u0432\u0441\u044f\u043a\u0438\u0435 OpenGL-\u0444\u043b\u0430\u0436\u043e\u0447\u043a\u0438 \u0438 \u0437\u0430 \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u044e\u0449\u0438\u0439 Surface \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    import com.android.grafika.gles.EglCore      val eglCore = EglCore(null, EglCore.FLAG_TRY_GLES3)     val eglSurface = eglCore.createOffscreenSurface(width, height)     eglCore.makeCurrent(eglSurface)     val textureRenderProgram = TextureRenderProgram()     val surfaceTexture = SurfaceTexture(textureRenderProgram.textureId)     surfaceTexture.setOnFrameAvailableListener(this)     val surface = Surface(surfaceTexture)<\/code><\/pre>\n<p>  <\/p>\n<p><b>TextureRenderProgram<\/b><\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0448\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 Surface, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 \u0435\u043c\u0443 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043d\u0443\u044e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043e\u0431\u0440\u0430\u0437\u0438\u0442\u044c \u043d\u0430\u0448 \u043a\u0430\u0434\u0440 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439 \u043d\u0430 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435, \u0440\u0430\u0441\u0442\u044f\u043d\u0443\u0442\u043e\u043c \u043d\u0430 \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432 OpenGL \u0434\u0430\u0436\u0435 \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435 \u0442\u0430\u043a \u043b\u0435\u0433\u043a\u043e. \u0414\u0430\u0436\u0435 \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 OpenGL \u043d\u0443\u0436\u043d\u043e \u0434\u0432\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430: \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u044b\u0439 \u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    fun createTextureRenderProgram(): Int {         val vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER)         val fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER)         val program: Int = GLES20.glCreateProgram()         GLES20.glAttachShader(program, vertexShader)         GLES20.glAttachShader(program, fragmentShader)         GLES20.glLinkProgram(program)         return program     }<\/code><\/pre>\n<p>  <\/p>\n<p><b>\u0412\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440<\/b><\/p>\n<p>  <\/p>\n<p>\u0425\u043e\u0442\u044f \u0431\u044b \u0448\u0435\u0439\u0434\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435. \u0421\u0443\u0442\u044c \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430 \u2014 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u043d\u0430\u0434 \u0432\u0435\u0440\u0448\u0438\u043d\u0430\u043c\u0438 \u0438 \u043a\u0430\u043a-\u0442\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440. \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0432 <code>gl_Position<\/code>. \u0410 \u0432\u043e\u0442 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043c\u044b \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u043c \u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u043d\u0430 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    uniform mat4 uTextureMatrix;     attribute vec4 aPosition;     attribute vec4 aTextureCoord;     varying vec2 vTextureCoord;     void main() {       gl_Position = aPosition;       vTextureCoord = (uTextureMatrix * aTextureCoord).xy;     }<\/code><\/pre>\n<p>  <\/p>\n<p><b>\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440<\/b><\/p>\n<p>  <\/p>\n<p>\u0424\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u043e\u043a\u0440\u0430\u0441\u043a\u0443 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435 \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u043e\u0433\u043e. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u0435, \u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0432\u0441\u0451.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    #extension GL_OES_EGL_image_external : require     precision mediump float;     varying vec2 vTextureCoord;     uniform samplerExternalOES sTexture;     void main() {       gl_FragColor = texture2D(sTexture, vTextureCoord);     }<\/code><\/pre>\n<p>  <\/p>\n<p><b>\u0421\u043e\u0447\u0438\u043d\u044f\u0435\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0434\u043b\u044f \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u043e\u0433\u043e \u0448\u0435\u0439\u0434\u0435\u0440\u0430<\/b><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043d\u044b\u0439 \u0448\u0435\u0439\u0434\u0435\u0440 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u043c\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c. \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0444\u0440\u0435\u0439\u043c\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u0435\u0451 \u0446\u0435\u043d\u0442\u0440 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 (0, 0), \u0430 \u043f\u043e \u043a\u0440\u0430\u044f\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0430\u0440\u044c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043e\u0442 (-1, -1) \u0441\u043b\u0435\u0432\u0430 \u0432\u043d\u0438\u0437\u0443 \u0434\u043e (1, 1) \u0441\u043f\u0440\u0430\u0432\u0430 \u0432\u0432\u0435\u0440\u0445\u0443. \u0417\u043d\u0430\u044f \u044d\u0442\u043e, \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u0441\u043e\u0447\u0438\u043d\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0442\u044f\u043d\u0443\u0442\u044c \u043d\u0430\u0448 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u043d\u0430 \u0432\u0435\u0441\u044c \u0444\u0440\u0435\u0439\u043c.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/8g\/6n\/rn\/8g6nrnao_lqivmakykg2mhraea8.jpeg\" data-src=\"https:\/\/habrastorage.org\/webt\/8g\/6n\/rn\/8g6nrnao_lqivmakykg2mhraea8.jpeg\" data-blurred=\"true\"\/><\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    val triangleVerticesData = floatArrayOf(          \/\/ X,     Y,  Z,  U,  V         -1.0f, -1.0f, 0f, 0f, 0f,          1.0f, -1.0f, 0f, 1f, 0f,         -1.0f,  1.0f, 0f, 0f, 1f,          1.0f,  1.0f, 0f, 1f, 1f,     )     const val FLOAT_SIZE_BYTES = 4     const val TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES     val triangleVertices: FloatBuffer =         ByteBuffer.allocateDirect(triangleVerticesData.size * FLOAT_SIZE_BYTES)             .order(ByteOrder.nativeOrder())             .asFloatBuffer()<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0440\u044f\u0434 \u044d\u0442\u043e\u0439 \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0442\u043e\u0447\u043a\u0438. \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0442\u043e\u0447\u043a\u0438 \u043a\u0430\u043a \u0431\u044b \u0437\u0438\u0433\u0437\u0430\u0433\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e OpenGL \u0443\u043c\u0435\u0435\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0447\u043a\u0438, \u043b\u0438\u043d\u0438\u0438 \u0438 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0442\u043e\u0447\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u00ab\u0437\u0430\u043a\u0440\u044b\u0442\u044c\u00bb \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438, \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/cy\/za\/vd\/cyzavdz8uf0lz0ejpeervwd9qmu.jpeg\" width=\"280\" data-src=\"https:\/\/habrastorage.org\/webt\/cy\/za\/vd\/cyzavdz8uf0lz0ejpeervwd9qmu.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c UV-\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b, \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 (0, 0) \u043e\u043a\u0430\u0437\u0430\u043b\u0430\u0441\u044c \u0432 \u043b\u0435\u0432\u043e\u043c \u043d\u0438\u0436\u043d\u0435\u043c \u0443\u0433\u043b\u0443 \u044d\u043a\u0440\u0430\u043d\u0430, \u0430 (1, 1) \u2014 \u0432 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/webt\/3u\/mi\/e_\/3umie_lgfhxhqbnhjd2kzt0emku.jpeg\" width=\"280\" data-src=\"https:\/\/habrastorage.org\/webt\/3u\/mi\/e_\/3umie_lgfhxhqbnhjd2kzt0emku.jpeg\" data-blurred=\"true\"\/>  <\/p>\n<p>  <\/p>\n<p><b>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043d\u0430\u0448 \u0444\u0440\u0435\u0439\u043c<\/b><\/p>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0448\u0435\u0439\u0434\u0435\u0440\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0434\u043b\u044f \u043d\u0438\u0445 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438: \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0442\u0435\u043a\u0441\u043e\u0432 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0447\u0438\u0442\u0430\u0442\u044c \u0431\u0430\u0439\u0442\u044b. \u0422\u0430\u043a\u0436\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0448\u0443 \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u043f\u043e\u043f\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0449\u0438\u0435 \u0448\u0435\u0439\u0434\u0435\u0440.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    val aPosition = GLES20.glGetAttribLocation(program, \"aPosition\")     val aTextureCoord = GLES20.glGetAttribLocation(program, \"aTextureCoord\")     val uSTMatrix = GLES20.glGetUniformLocation(program, \"uTextureMatrix\")     val textures = IntArray(1)     GLES20.glGenTextures(1, textures, 0)     val textureId = textures[0]     GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, textureId)     triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET)      GLES20.glVertexAttribPointer(programSetup.aPosition, 3, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices)     GLES20.glEnableVertexAttribArray(programSetup.aPosition)      GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false, TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices)     GLES20.glEnableVertexAttribArray(maTextureHandle)<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043e\u0431\u043d\u043e\u0432\u0438\u0432 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0438\u0437 \u043a\u043e\u043b\u043b\u0431\u044d\u043a\u0430 \u043a\u043e\u0434\u0435\u043a\u0430 (\u0432\u044b \u0436\u0435 \u0435\u0449\u0451 \u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u043f\u0440\u043e \u043a\u043e\u0434\u0435\u043a?), \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0435\u0451 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0438 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044c\u043d\u044b\u0439 \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0433\u043e\u043d\u043a\u0438 \u0432 \u0431\u0438\u0442\u043c\u0430\u043f.<\/p>\n<p>  <\/p>\n<pre><code class=\"kotlin\">    surfaceTexture.updateTexImage()     textureRenderProgram.drawFrame(surfaceTexture)     val pixelBuf: ByteBuffer = ByteBuffer.allocateDirect(width * height * 4).apply {         order(ByteOrder.LITTLE_ENDIAN)     }     \/\/ Wait for onFrameAvailable() to signal us.     pixelBuf.rewind()     GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pixelBuf)     return pixelBuf.toBitmap(width, height)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0431\u0438\u0442\u043c\u0430\u043f, \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0434\u0438\u0441\u043a, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e, \u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043d\u0438\u043c \u0432\u0441\u0451 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e.<\/p>\n<p>  <\/p>\n<p><b>\u0412\u0441\u0435 \u0435\u0449\u0451 \u0434\u043e\u043b\u0433\u043e \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f?<\/b><\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435. \u0423\u0434\u0430\u043b\u043e\u0441\u044c \u043b\u0438 \u043d\u0430\u043c \u0432\u044b\u0438\u0433\u0440\u0430\u0442\u044c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438? \u0417\u0430\u043c\u0435\u0440\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442, \u0447\u0442\u043e \u0434\u0430, \u0438 \u043d\u0430\u043c\u043d\u043e\u0433\u043e. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u0430 \u043a\u043e\u0434\u0435\u043a\u0430 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0430 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0431\u0435\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 getFrameAtIndex \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0432\u0435\u0440\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u0411\u044b\u043b\u043e:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/wb\/lg\/mj\/wblgmjedkmel8exnthplkq7goj4.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/wb\/lg\/mj\/wblgmjedkmel8exnthplkq7goj4.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0430\u043b\u043e:<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/9x\/ln\/3y\/9xln3ylaubps_vrerhkxry7y6_w.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/9x\/ln\/3y\/9xln3ylaubps_vrerhkxry7y6_w.gif\"\/><\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\">\n<thead>\n<tr>\n<th>Device<\/th>\n<th>MediaMetadataRetriever<\/th>\n<th>Custom solution<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>OnePlus 9 Pro<\/td>\n<td>3,5 \u0441<\/td>\n<td>2,5 \u0441<\/td>\n<\/tr>\n<tr>\n<td>Nexus 6<\/td>\n<td>35 \u0441<\/td>\n<td>9 \u0441<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>C \u0442\u0430\u043a\u0438\u043c\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0436\u0438\u0442\u044c! \u0414\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0439 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0430\u0435\u0442\u0441\u044f \u043a \u00ab\u043a\u0440\u0430\u0441\u043d\u043e\u0439 \u0437\u043e\u043d\u0435\u00bb \u043f\u043e \u0428\u0438\u043f\u0438\u043b\u0435\u0432\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u0448\u0430\u0433\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c \u0438 \u043f\u0443\u0441\u0442\u0438\u043b\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u043b\u0438\u0437!<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/post_images\/61c\/5bc\/f62\/61c5bcf6276799416defef9ab13da858.png\" width=\"600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/61c\/5bc\/f62\/61c5bcf6276799416defef9ab13da858.png\"\/>  <\/p>\n<p>  <\/p>\n<h2 id=\"vyvody\">\u0412\u044b\u0432\u043e\u0434\u044b<\/h2>\n<p>  <\/p>\n<p>\u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0438 \u043c\u0438\u043d\u0443\u0441\u044b. \u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e 120 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0434\u0436\u0438\u043f\u0435\u0433\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e\u0435 \u043f\u043e \u043c\u0435\u0440\u043a\u0430\u043c \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u043c\u0435\u0441\u0442\u043e? \u0425\u043e\u0442\u044c \u043c\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u043a\u0430\u0434\u0440\u043e\u0432\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u0430\u0434\u0440\u044b. \u041e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430: \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u0430\u043d\u043e\u0440\u0430\u043c \u0432 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043a\u0435\u0448\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u0442\u0430\u0440\u044b\u0435 \u043a\u0430\u0434\u0440\u044b. \u041d\u043e \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0438\u0441\u0441 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u043f\u043e \u0441\u0435\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0432\u0435\u0440\u0445\u0435\u0434\u043e\u043c \u043d\u0430 \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0435\u043e. \u0414\u043b\u044f \u043d\u0430\u0441 \u0431\u044b\u043b\u043e \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0432 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u043c \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0430\u043c\u0438 \u043e\u0431\u0437\u0430\u0432\u0435\u0434\u0443\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043e \u043f\u0440\u043e\u0434\u0430\u0436\u0435 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u0435\u0439, \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0410\u0432\u0442\u043e.\u0440\u0443 \u043d\u0435 \u0441\u0442\u0430\u043b\u043e \u0431\u044b \u0433\u043b\u0430\u0432\u043d\u044b\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0435\u043c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u043d\u0430 \u0432\u0430\u0448\u0435\u043c \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0435. <\/p>\n<p>  <\/p>\n<p>\u0410 \u043a\u0430\u043a \u0431\u044b \u0432\u044b \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0432 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435? \u041f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/595135\/\"> https:\/\/habr.com\/ru\/articles\/595135\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ev\/y0\/j3\/evy0j3ktg6bmpn8afvb3ozingzk.gif\" data-src=\"https:\/\/habrastorage.org\/webt\/ev\/y0\/j3\/evy0j3ktg6bmpn8afvb3ozingzk.gif\"\/><\/p>\n<p>  <\/p>\n<p>\u0412 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0410\u0432\u0442\u043e.\u0440\u0443 \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0430\u044f \u0444\u0438\u0447\u0430 \u2014 \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u044b \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u0435\u0439. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c 3D-\u0444\u043e\u0442\u043e \u0441\u0432\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u044b, \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0435\u0451 \u0432\u043e \u0432\u0441\u0435\u0439 \u043a\u0440\u0430\u0441\u0435. \u041a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043a\u0430\u043a \u043d\u0430\u0448\u0438\u043c \u043a\u043e\u043b\u043b\u0435\u0433\u0430\u043c \u0438\u0437 ML \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d \u0442\u043e, \u0447\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e \u0446\u0435\u043b\u043e\u0433\u043e \u0430\u043d\u0433\u0430\u0440\u0430, \u043d\u0430\u043f\u0438\u0447\u043a\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u0440\u043e\u0433\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u043c \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c, <a href=\"https:\/\/habr.com\/ru\/users\/yaantonn\/\" class=\"user_link\">yaantonn<\/a> \u0443\u0436\u0435 <a href=\"https:\/\/habr.com\/ru\/company\/yandex\/blog\/508180\/\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b<\/a> \u043d\u0430 \u0425\u0430\u0431\u0440\u0435. <\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043e\u0442\u0441\u043d\u044f\u0442\u044c \u043f\u0430\u043d\u043e\u0440\u0430\u043c\u0443 \u2014 \u043b\u0438\u0448\u044c \u043f\u043e\u043b\u0434\u0435\u043b\u0430. \u0417\u0430\u0442\u0435\u043c \u0435\u0451 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438, \u043f\u0440\u0438\u0447\u0451\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0438 \u043d\u0430 \u0442\u043e\u043f\u043e\u0432\u043e\u043c \u0444\u043b\u0430\u0433\u043c\u0430\u043d\u0435, \u0438 \u043d\u0430 \u0431\u044e\u0434\u0436\u0435\u0442\u043d\u043e\u043c \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0435.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-403394","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/403394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=403394"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/403394\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=403394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=403394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=403394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}