<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://wiki.linuxformat.ru/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF130%3AClutter</id>
		<title>LXF130:Clutter - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linuxformat.ru/wiki/index.php?action=history&amp;feed=atom&amp;title=LXF130%3AClutter"/>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF130:Clutter&amp;action=history"/>
		<updated>2026-05-13T13:37:58Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.19.20+dfsg-0+deb7u3</generator>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF130:Clutter&amp;diff=11837&amp;oldid=prev</id>
		<title>Crazy Rebel в 11:54, 15 апреля 2011</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF130:Clutter&amp;diff=11837&amp;oldid=prev"/>
				<updated>2011-04-15T11:54:12Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table class='diff diff-contentalign-left'&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
				&lt;col class='diff-marker' /&gt;
				&lt;col class='diff-content' /&gt;
			&lt;tr valign='top'&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
			&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 11:54, 15 апреля 2011&lt;/td&gt;
			&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 28:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 28:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Если вы в курсе предыдущих эпизодов нашего учебника, вам это должно показаться знакомым. Для новичков скажем, что здесь импортируются самые важные модули (заметьте, что наряду с '''gst''' нам понадобится '''cluttergst'''), создается объект '''Stage''' (окно, на языке ''Clutter''), ему дается заголовок, размер и цвет фона, а затем он отображается. Вы увидите белое окно. Если нет, проверьте синтаксис, или скопируйте файл '''listing''' с DVD.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Если вы в курсе предыдущих эпизодов нашего учебника, вам это должно показаться знакомым. Для новичков скажем, что здесь импортируются самые важные модули (заметьте, что наряду с '''gst''' нам понадобится '''cluttergst'''), создается объект '''Stage''' (окно, на языке ''Clutter''), ему дается заголовок, размер и цвет фона, а затем он отображается. Вы увидите белое окно. Если нет, проверьте синтаксис, или скопируйте файл '''listing''' с DVD.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;−&lt;/td&gt;&lt;td style=&quot;background: #ffa; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Весь мир — сцена==&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;===Весь мир — сцена&lt;ins class=&quot;diffchange diffchange-inline&quot;&gt;=&lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Теперь начнется интересное. Объекты, отображаемые на сцене ''Clutter'', называются актерами [actor]. Существует несколько типов актеров. Некоторые относятся к базовым, например, объекты «прямоугольник» и «текст», и живут в главном модуле ''Clutter'', но есть и другие, специальные актеры из внешних библиотек.&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt;&amp;#160;&lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;Теперь начнется интересное. Объекты, отображаемые на сцене ''Clutter'', называются актерами [actor]. Существует несколько типов актеров. Некоторые относятся к базовым, например, объекты «прямоугольник» и «текст», и живут в главном модуле ''Clutter'', но есть и другие, специальные актеры из внешних библиотек.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	<entry>
		<id>http://wiki.linuxformat.ru/wiki/index.php?title=LXF130:Clutter&amp;diff=11836&amp;oldid=prev</id>
		<title>Crazy Rebel: викификация, оформление, иллюстрация</title>
		<link rel="alternate" type="text/html" href="http://wiki.linuxformat.ru/wiki/index.php?title=LXF130:Clutter&amp;diff=11836&amp;oldid=prev"/>
				<updated>2011-04-15T11:53:43Z</updated>
		
		<summary type="html">&lt;p&gt;викификация, оформление, иллюстрация&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;: '''''Python''''' Настоящие задачи, чтобы вы поупражнялись в кодировании&lt;br /&gt;
&lt;br /&gt;
==''Python'': Потоки видео==&lt;br /&gt;
&lt;br /&gt;
{{Цикл/Python}}&lt;br /&gt;
&lt;br /&gt;
: Скомбинируйте мощь видео от ''GStreamer'' с графической изощренностью ''Clutter'' – получится то, что '''Ник Вейч''' называет «чистая работа».&lt;br /&gt;
&lt;br /&gt;
Первичная задача ''Clutter''’а – упрощение процесса создания приятных графических интерфейсов. Он применяет подход «выстрелилизабыл» ко множеству вещей – в частности, к анимации: задав последовательность, запустите ее, и пусть себе выполняется.&lt;br /&gt;
&lt;br /&gt;
Однако самому ''Clutter'' со всем этим не справиться. Анимация в главном модуле превосходна, но в других областях есть изъяны. Начнем с того, что в ''Clutter'' есть всего несколько примитивных объектовактеров; поэтому к нему и прилагается расширение на базе ''Cairo'' (на следующем уроке мы рассмотрим его подробнее).&lt;br /&gt;
&lt;br /&gt;
Другая библиотека, на которую опирается ''Clutter'' – это ''GStreamer'', кудесник по части потоков медиаданных. Когда речь заходит о мультимедиа, ''GStreamer'' – одна из наиболее часто используемых библиотек, и неудивительно, что для нее есть модуль ''Python''. Чтобы применять его в своих приложениях, нужно немного разобраться в инструментарии ''GStreamer'', но здесь, как всегда, на это мало места. К счастью, он не сложен. Нам и не нужно ничего замысловатого – есть у нас URI видеофайла или какогонибудь другого источника, вот мы и хотим его воспроизвести.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF130_76_1.jpg|300px]] Мы еще не написали ни строки кода, а в окне уже вовсю идет потоковое видео.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Сначала зададим обычную сцену [stage] в ''Clutter'':&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import gst&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import clutter&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; import cluttergst&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage=clutter.Stage()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_title(“Clutter_Streamer”)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_size(320,290)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.set_color(clutter.Color(255,255,255,255) )&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.show()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если вы в курсе предыдущих эпизодов нашего учебника, вам это должно показаться знакомым. Для новичков скажем, что здесь импортируются самые важные модули (заметьте, что наряду с '''gst''' нам понадобится '''cluttergst'''), создается объект '''Stage''' (окно, на языке ''Clutter''), ему дается заголовок, размер и цвет фона, а затем он отображается. Вы увидите белое окно. Если нет, проверьте синтаксис, или скопируйте файл '''listing''' с DVD.&lt;br /&gt;
&lt;br /&gt;
===Весь мир — сцена==&lt;br /&gt;
&lt;br /&gt;
Теперь начнется интересное. Объекты, отображаемые на сцене ''Clutter'', называются актерами [actor]. Существует несколько типов актеров. Некоторые относятся к базовым, например, объекты «прямоугольник» и «текст», и живут в главном модуле ''Clutter'', но есть и другие, специальные актеры из внешних библиотек.&lt;br /&gt;
&lt;br /&gt;
Объект '''VideoTexture''' находится в модуле '''cluttergst''', и он похож на актера '''rectangle'''. У него много свойств из тех, что мы исследовали ранее, но он особый, так как подцепляется к проигрывателю видео и использует его для обновления своей текстуры. Это одна из сильных сторон Clutter – задав актера или даже установив ему анимацию на выполнение, незачем возвращаться к нему для контроля: он продолжит работать и делать то, что ему велено.&lt;br /&gt;
&lt;br /&gt;
Проигрыватель видео известен под названием '''playbin'''; это встраиваемый плейер. Вы задаете ему ресурс для воспроизведения, и он увязывает все остальное самостоятельно. Давайте так и поступим:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid=cluttergst.VideoTexture()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; playbin=vid.get_playbin()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; playbin.set_property(‘uri’,’mmsh://live.camstreams.com/cscamglobal16MSWMExt=.asf’)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Сначала мы задали актера текстуры видео, затем извлекли созданный объект '''playbin'''. Прежде чем воспроизводить чтолибо, укажем источник. Лучший способ сделать это – вызвать метод '''set_property''' объекта '''playbin''', включающий свойство, которое мы хотим задать (URI), и то, что мы хотим ему присвоить. Здесь мы использовали webадрес видео в Интернете: камера отслеживает дорожное движение на площади Пикадилли в Лондоне и дает поток живого видео (в отличие от тех, что просто обновляют картинку каждые пять секунд). Вам сразу же захочется избежать головокружительного восторга от вида двух дюжин автобусов, бодающихся перед светофором, и использовать локальный файл. Это значит, что все в порядке.&lt;br /&gt;
&lt;br /&gt;
URI может ссылаться на файл или вообще что угодно, распознаваемое как корректный источник. ''GStreamer'' определит, что это такое и что с этим делать, при наличии правильных модулей расширения. Если таковых нет, возникнет сообщение об ошибке, говорящее о невозможности воспроизвести поток. Возьмите что-нибудь попроще: например, файл видео, который вы уже успешно просмотрели в ''Totem''.&lt;br /&gt;
&lt;br /&gt;
Для URI файлов (или чего угодно) потребуется префикс подходящего протокола. Например, правильным URI для локального файла будет file:///home/evilnick/Videos/killmike.ogg. Затем создадим другой объект ''GStreamer'', чтобы использовать его для управления ранее созданным объектом '''playbin''':&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe=gst.Pipeline(“pipe”)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe.add(playbin)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.add(vid)&lt;br /&gt;
&lt;br /&gt;
Создав объект '''pipe''', мы подключили его к '''playbin''', с помощью pipe’овского метода '''add()'''. '''pipe''' используется просто как контейнер для нашего плейера. Наконец, на сцену можно добавить объект текстуры видео – именно он обновляется при воспроизведении потока.&lt;br /&gt;
&lt;br /&gt;
Теперь у нас есть белое окно с отображаемой в нем текстурой видео, но посмотреть его пока нельзя: ведь оно еще не включено.&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF130_77_1.jpg|300px]] Ух ты! Поискав, вы найдете немало любопытных web-камер. Или возьмите свои файлы.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe.set_state(gst.STATE_PLAYING)&lt;br /&gt;
 &amp;lt;enum GST_STATE_CHANGE_ASYNC of type GstStateChangeReturn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Контейнер '''pipe''' используется для управления потоком. С помощью предопределенной в '''gst''' константы '''gst.STATE_PLAYING''' мы включили плейер. Если вы воспроизводите файл, то увидите изображение сразу же. Если видна только часть картинки, расширьте сцену. Мы все еще находимся в интерактивном режиме ''Python'', так что поправить сцену можно методом '''stage.set_size.stage.set_size(640,480)''' Мы также можем поменять состояние плейера, сделав паузу:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe.set_state(gst.STATE_PAUSED)&lt;br /&gt;
 &amp;lt;enum GST_STATE_CHANGE_SUCCESS of type GstStateChangeReturn&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe.set_state(gst.STATE_PLAYING)&lt;br /&gt;
 &amp;lt;enum GST_STATE_CHANGE_ASYNC of type GstStateChangeReturn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметьте, что поток видео действительно приостановился. Вы воображаете, что такое бывает только с файлом, но и с подачей от webкамеры будет то же самое.&lt;br /&gt;
&lt;br /&gt;
===Мой поток отказал===&lt;br /&gt;
&lt;br /&gt;
Если канал ''GStreamer''’а закрывается с ошибкой, или, реже, просто ничего не делает – проблема, возможно, с кодеком. Недостающие в вашем дистрибутиве кодеки можно добавить, установив пакет под названием '''gstreamer_plugins_good''' или наподобие. Все прочие пакеты, видимо, «'''bad'''» или «'''ugly'''» (здесь тонкий отсыл к мировой культуре, если кто понял). В зависимости от вашего местожительства, вы сможете законно скачать и установить дополнительные модули, чтобы увидеть больше потоков.&lt;br /&gt;
&lt;br /&gt;
===Пошалим===&lt;br /&gt;
&lt;br /&gt;
Мы всегонавсего создали ''Clutter'' ’скую версию поточного проигрывателя – как ''Kaffeine'', но с меньшим числом опций. Однако текстура нашего видео – это актер ''Clutter'' 'а, так что с ней можно проделывать всякие штуки.&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_size(100,90)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_size(100,290)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_size(320,50)&lt;br /&gt;
&lt;br /&gt;
Даже когда мы поменяли его размер, или подвинули этого актера...&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.move_by(10,10)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.move_by(10,10)&lt;br /&gt;
&lt;br /&gt;
К видео можно применять почти все методы актеров. В прошлом выпуске мы детально рассматривали методы анимации, и они сработают и для видеотекстуры. Кратко вспомним, что этот метод берет значение для эффекта анимации (константа ''Clutter'', нумерующая различные стили), длительность в миллисекундах и список пар ключ/значение для свойств. Актер преобразует их в абсолютные величины. Например:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.animate(clutter.LINEAR, 1000, ‘width’,640, ‘height’, 480, ‘x’,0,’y’,0)&lt;br /&gt;
 &amp;lt;clutter.Animation object at 0x96f3884 (ClutterAnimation at 0xb4799a00)&amp;gt;&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.animate(clutter.LINEAR, 1000, ‘width’,320, ‘height’, 240, ‘x’,160,’y’,120)&lt;br /&gt;
 &amp;lt;clutter.Animation object at 0x96f4284 (ClutterAnimation at 0xb4799c00)&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы поглубже вникнуть в анимационные преобразования, загляните в прошлый номер. Теперь для нашего маленького эксперимента с камерой у нас есть забава типа картинка-в-картинку; но необходимо разобраться еще с одним элементом. Во-первых, создадим новый видеообъект, такой же, как первый, но с другим потоком:&lt;br /&gt;
&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid2=cluttergst.VideoTexture()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; playbin2=vid2.get_playbin()&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; playbin2.set_property(‘uri’,’mmsh://live.camstreams.com/cscamglobal5MSWMExt=.asf’)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe2=gst.Pipeline(“pipe2”)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe2.add(playbin2)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; stage.add(vid2)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; pipe2.set_state(gst.STATE_PLAYING)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_position(0,0)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_size(100,80)&lt;br /&gt;
 &amp;gt;&amp;gt;&amp;gt; vid.set_depth(2)&lt;br /&gt;
&lt;br /&gt;
С этим мы уже сталкивались ранее, а вот последняя строка появилась впервые. Концепция глубины (depth) – одно из 2.5 измерений ''Clutter''. Объекты становятся ближе или дальше от сцены. По некой извращенной (по крайней мере, для меня) логике, для удаления от сцены глубину нужно брать положительной, а для приближения – отрицательной. Итак, если вам нужно наслоить объекты, как мы сделали здесь, возьмите глубину верхнего объекта большей, чем глубина нижнего.&lt;br /&gt;
&lt;br /&gt;
Это меняет способ визуализации актеров, согласно настройкам перспективы, но для малых значений глубины вы ничего и не заметите. Впрочем, поиграйте с параметрами.&lt;br /&gt;
&lt;br /&gt;
Теперь у нас есть все, чтобы создать многопотоковый браузер видео. В следующем куске кода будет создано настоящее приложение ''Python'', так что запустите свой любимый текстовый редактор и введите следующее (или же найдите этот текст на LXFDVD):&lt;br /&gt;
тор и введите следующее (или же найдите этот текст на LXFDVD):&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Содержание=[[Изображение:LXF130_78_1.jpg|300px]] Минуту назад мы созерцали Пикадилли, а теперь вы уже на Трафальгарской площади, или в Токио, или где-нибудь еще — был бы источник.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
 import clutter&lt;br /&gt;
 import gst&lt;br /&gt;
 import cluttergst&lt;br /&gt;
 class videobrowser:&lt;br /&gt;
     def __init__ (self):&lt;br /&gt;
       self.channel1=”mmsh://live.camstreams.com/cscamglobal16?MSWMExt=.asf”&lt;br /&gt;
       self.channel2=”mmsh://live.camstreams.com/cscamglobal5?MSWMExt=.asf”&lt;br /&gt;
       # Инициа лизируем сцену&lt;br /&gt;
       self.stage = clutter.Stage()&lt;br /&gt;
       self.stage.set_color(clutter.Color(255, 255, 255, 255))&lt;br /&gt;
       self.stage.set_size(640, 480)&lt;br /&gt;
       self.stage.set_title(‘LXF Traffic Watch ­ press “t” to toggle view’)&lt;br /&gt;
        self.stage.connect(‘key­press­event’, self.parseKeyPress)&lt;br /&gt;
        self.stage.connect(“destroy”, clutter.main_quit)&lt;br /&gt;
        # Вторая видеотексту ра&lt;br /&gt;
        self.video1 = cluttergst.VideoTexture()&lt;br /&gt;
        self.playbin1 = self.video1.get_playbin()&lt;br /&gt;
        self.playbin1.set_property(‘uri’, self.channel1)&lt;br /&gt;
        self.pipeline1 = gst.Pipeline(“pipe1”)&lt;br /&gt;
        self.pipeline1.add(self.playbin1)&lt;br /&gt;
        self.video1.set_position(0,0)&lt;br /&gt;
        self.video1.set_size(640, 480)&lt;br /&gt;
        self.video1.set_depth(­2)&lt;br /&gt;
        self.stage.add(self.video1)&lt;br /&gt;
        self.pipeline1.set_state(gst.STATE_PLAYING)&lt;br /&gt;
        # пошел второй&lt;br /&gt;
        self.video2 = cluttergst.VideoTexture()&lt;br /&gt;
        self.playbin2 = self.video2.get_playbin()&lt;br /&gt;
        self.playbin2.set_property(‘uri’, self.channel2)&lt;br /&gt;
        self.pipeline2 = gst.Pipeline(“pipe2”)&lt;br /&gt;
        self.pipeline2.add(self.playbin2)&lt;br /&gt;
        self.video2.set_position(0,0)&lt;br /&gt;
        self.video2.animate(clutter.LINEAR, 1000, ‘rotation_angle_y’, 0, ‘rotation_angle_z’, 0, ‘width’, 80, ‘height’, 60 )&lt;br /&gt;
        self.stage.add(self.video2)&lt;br /&gt;
        self.video2.set_depth(0)&lt;br /&gt;
        self.pipeline2.set_state(gst.STATE_PLAYING)&lt;br /&gt;
        # вывес ти сцену и начать работу&lt;br /&gt;
        self.stage.show_all()&lt;br /&gt;
        clutter.main()&lt;br /&gt;
      def parseKeyPress(self, stage, event):&lt;br /&gt;
        print ‘parsekey got ‘, self, event&lt;br /&gt;
        # обработаем на жатие на клавишу&lt;br /&gt;
        if event.keyval == clutter.keysyms.q:&lt;br /&gt;
           # q значит вы ход&lt;br /&gt;
           clutter.main_quit()&lt;br /&gt;
        elif event.keyval == clutter.keysyms.t:&lt;br /&gt;
           # на жатие на t меняет ролики мес тами&lt;br /&gt;
           if self.video1.get_depth() == ­2 :&lt;br /&gt;
              #video2 на ходится сверху&lt;br /&gt;
              self.video2.animate(clutter.LINEAR, 300, ‘rotation_angle_y’, 360, ‘rotation_angle_z’, 360, ‘width’, 640, ‘height’, 480 )&lt;br /&gt;
              self.video1.animate(clutter.LINEAR, 1000, ‘rotation_angle_y’, 0, ‘rotation_angle_z’, 0, ‘width’, 80, ‘height’, 60 )&lt;br /&gt;
              self.video2.set_depth(­2)&lt;br /&gt;
              self.video1.set_depth(0)&lt;br /&gt;
           else :&lt;br /&gt;
              # video 1 на ходится сверху&lt;br /&gt;
              self.video1.animate(clutter.LINEAR 300, ‘rotation_angle_y’, 360, ‘rotation_angle_z’, 360, ‘width’, 640, ‘height’, 480 )&lt;br /&gt;
              self.video2.animate(clutter.LINEAR, 1000, ‘rotation_angle_y’, 0, ‘rotation_angle_z’, 0, ‘width’, 80, ‘height’, 60 )&lt;br /&gt;
              self.video1.set_depth(­2)&lt;br /&gt;
              self.video2.set_depth(0)&lt;br /&gt;
   if __name__ == ‘__main__’:&lt;br /&gt;
      videobrowser()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Врезка|Заголовок=Скорая помощь|Содержание=К некоторому недоумению, метод '''get_uri()''' у актера '''VideoTexture''' ничего не возвращает – ведь это просто текстура; а вот в объекте '''playbin''' содержатся данные по URI, и если вы забыли, с чем связан поток, воспользуйтесь '''playbin.get_property(‘uri’)'''.|Ширина=300px}}&lt;br /&gt;
&lt;br /&gt;
Код '''init''' создает два видеопотока, размещая один как актера над тем, что больше, а другой помещая в угол. Через несколько секунд потоки оживут, и вы увидите двухэтажные автобусы и прочее. Хитрая часть кода – перехват нажатий клавиш. Если фокус находится в окне, любое нажатие клавиши вызовет событие. Метод '''stage.connect()''' связывает этот сигнал с методом '''parseKeyPress()''', определенным в главном классе приложения. Нажатие клавиши '''t''' поменяет два видео местами. Нужно помнить о том, что глубины следует задать заново, чтобы новая, маленькая картинка переместилась вверх (по значению параметра '''depth''' определяется, какой актер находился сверху при нажатии кнопки).&lt;br /&gt;
&lt;br /&gt;
Не бойтесь экспериментировать, добавлять экраны и играть с вызовами анимации. ''Clutter'' выполнит ее за вас, и о действиях после остановки волноваться нет нужды. Клавиша '''Q '''привязана к чистому выходу из приложения.&lt;br /&gt;
&lt;br /&gt;
===Идем дальше===&lt;br /&gt;
&lt;br /&gt;
Можно добавлять другие потоки и располагать их каскадом один над другим. Вместо переключения двух потоков, их можно вращать вокруг одной точки. Также можно поиграть с анимацией: значения, задаваемые в методе animate, абсолютны, а не относительны, поэтому угловые повороты кратны 360 градусам – чтобы видеотекстура поворачивалась правильно.&lt;br /&gt;
&lt;br /&gt;
В прошлых двух частях нашего сериала мы рассматривали актеров '''clutter.Text()'''. Добавить текстового актера, чтобы вы могли видеть, какой поток воспроизводится, или поменять текст при смене экрана, опять-таки не заботясь об анимации, довольно просто. Для потоков аудио, думаю, вам захочется приглушить звук при сворачивании окна.&lt;br /&gt;
&lt;br /&gt;
Еще больше штучек с объектами GStreamer мож но отыскать в документации ''GStreamer'': на данный момент она обширнее документации по ''PyClutter''. Или взгляните на учебник ''GStreamer'' в [[LXF125:GStreamer|LXF125]].&lt;br /&gt;
&lt;br /&gt;
===Ах, этот Flash!===&lt;br /&gt;
&lt;br /&gt;
Некогда любой вид живого видеопотока был простым потоковым сокетом: присосись да пользуйся. Сейчас, кажется, они норовят требовать эти дурацкие плейеры, осно ванные на ''Flash''. Уж не знаю, зачем: то ли для статистики пользователей, то ли для «защиты» контента… однако наряду с усложнением открытия в ''Firefox'' нескольких потоков одновременно, это также затрудняет поиск подходящих живых потоков. Хорошая добыча – камеры, отслеживающие дорожное движение; а если вам хочется пошалить, знайте, что некоторые встроенные ''Flash''-плейеры любезно показывают URL сырого потока в исходном тексте страницы. Но я вам этого не говорил. Т-с-с!&lt;br /&gt;
&lt;br /&gt;
===Слово на ушко===&lt;br /&gt;
&lt;br /&gt;
Объекты ''GStreamer'' воспроизводят звук любого видеоресурса автоматически, и если вы просматриваете два источника одновременно, то услышите только какофонию. Для изменения звукового вывода (и, при желании, его перенаправления) пригодятся функции '''gst''', а для простой регулировки громкости у актера '''VideoTexture''' из ''Clutter'' есть подходящий метод '''set_audio_volume()'''.&lt;/div&gt;</summary>
		<author><name>Crazy Rebel</name></author>	</entry>

	</feed>