~glitter-team/glitter/trunk

« back to all changes in this revision

Viewing changes to glitter/video.py

  • Committer: Jan Jokela
  • Date: 2008-12-10 22:18:59 UTC
  • Revision ID: janjokela@gmail.com-20081210221859-zxr2ut255a7xu15x
Hi, Glitter here

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# !/usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# Glitter Toolkit
 
5
 
 
6
__authors__ = ["Jan Jokela <janjokela@gmail.com>"]
 
7
__licenses__ = ["LICENSE.LGPL"]
 
8
__description__ = "Frame widget"
 
9
 
 
10
import os
 
11
import sys
 
12
import math
 
13
 
 
14
import gst
 
15
import gobject
 
16
import clutter
 
17
import cluttergst
 
18
 
 
19
from container import Container
 
20
 
 
21
class Video(Container):
 
22
    """
 
23
    A video widget offers easy and simple video playback backed by GStreamer. 
 
24
    Features include seamless playback, support for all GStreamer compatible 
 
25
    video streams, basic playback control and support for native, widescreen 
 
26
    (16:9), TV (4:3) and "smart" aspect ratios.
 
27
    
 
28
    """
 
29
    
 
30
    def __init__(self, source=None, aspect_ratio="native"):
 
31
        """ Initialize video widget """
 
32
        
 
33
        super(Video, self).__init__()
 
34
        
 
35
        self._source = source
 
36
        self._aspect_ratio = aspect_ratio
 
37
        
 
38
        self._texture = None
 
39
        
 
40
        self._update_style(self.style)
 
41
        
 
42
    def _update_style(self, props=None):
 
43
        """ Updates style """
 
44
        
 
45
        super(Video, self)._update_style(props)
 
46
        
 
47
        pass
 
48
        
 
49
    def _update_layout(self):
 
50
        """ Updates layout """
 
51
        
 
52
        super(Video, self)._update_layout()
 
53
        
 
54
        if not self._texture:
 
55
            self._set_source()
 
56
            
 
57
        widthu = self.get_widthu()
 
58
        heightu = self.get_heightu()
 
59
 
 
60
        # Account for 0 width or height
 
61
        #print width, height
 
62
        if widthu == 0 or heightu == 0:
 
63
            return
 
64
 
 
65
        width_delta = math.fabs(widthu - widthu * 0.5625) 
 
66
        height_delta = math.fabs(heightu - heightu * 1.7777)        
 
67
        
 
68
        # native
 
69
        if self.aspect_ratio == "native":
 
70
            self._texture.set_xu(0)
 
71
            self._texture.set_yu(0)
 
72
            self._texture.set_widthu(widthu)
 
73
            self._texture.set_heightu(heightu)
 
74
        
 
75
        # 16:9 widescreen (720p & 1080p)
 
76
        elif self.aspect_ratio == "widescreen":
 
77
            if width_delta < height_delta:
 
78
                video_height = int(widthu * 0.5625)
 
79
                self._texture.set_widthu(widthu)
 
80
                self._texture.set_heightu(video_height)
 
81
                self._texture.set_xu(0)
 
82
                self._texture.set_yu(int((heightu - video_height) / 2.0))
 
83
            else:
 
84
                video_width = int(heightu * 1.7777)
 
85
                self._texture.set_widthu(video_width)
 
86
                self._texture.set_heightu(heightu)
 
87
                self._texture.set_xu(int((widthu - video_width) / 2.0))
 
88
                self._texture.set_yu(0)
 
89
        
 
90
        # 4:3 tv-like        
 
91
        elif self.aspect_ratio == "tv":
 
92
            if width_delta < height_delta:
 
93
                video_height = int(width * 0.75)
 
94
                self._texture.set_width(width)
 
95
                self._texture.set_height(video_height)
 
96
                self._texture.set_x(0)
 
97
                self._texture.set_y(int((height - video_height) / 2.0))
 
98
            else:
 
99
                video_width = int(height * 1.3333)
 
100
                self._texture.set_width(video_width)
 
101
                self._texture.set_height(height)
 
102
                self._texture.set_x(int((width - video_width) / 2.0))
 
103
                self._texture.set_y(0)            
 
104
            
 
105
        # smart: maximum viewing area without cutting too much        
 
106
        elif self.aspect_ratio == "smart":
 
107
            if width_delta < height_delta:
 
108
                video_height = int(width * 0.5625)
 
109
                self._texture.set_width(width)
 
110
                self._texture.set_height(video_height)
 
111
                self._texture.set_x(0)
 
112
                self._texture.set_y(int((height - video_height) / 2.0))
 
113
            else:
 
114
                video_width = int(height * 1.7777)
 
115
                self._texture.set_width(video_width)
 
116
                self._texture.set_height(height)
 
117
                self._texture.set_x(int((width - video_width) / 2.0))
 
118
                self._texture.set_y(0)            
 
119
 
 
120
        
 
121
    def get_source(self):
 
122
        """ Retrieve video source (uri) """
 
123
        
 
124
        return self._source
 
125
        
 
126
    def set_source(self, value):
 
127
        """ Sets video source
 
128
        
 
129
        value -- (str) source file uri
 
130
        """
 
131
        
 
132
        self._source = value
 
133
        
 
134
    source = property(get_source, set_source)
 
135
    
 
136
    def get_aspect_ratio(self):
 
137
        """ Retireve aspect ratio """
 
138
        
 
139
        return self._aspect_ratio
 
140
        
 
141
    def set_aspect_ratio(self, value):
 
142
        """ Sets aspect ratio
 
143
        
 
144
        value -- (str) 'native', 'widescreen', 'tv' or 'smart'
 
145
        """
 
146
        
 
147
        self._aspect_ratio = value
 
148
        
 
149
    aspect_ratio = property(get_aspect_ratio, set_aspect_ratio)
 
150
    
 
151
    
 
152
    
 
153
    def play(self):
 
154
        """ Play video. Resumes or starts video playback """
 
155
        
 
156
        if not self.is_playing():
 
157
            self._texture.set_playing(True)
 
158
    
 
159
    def pause(self):
 
160
        """ Pause video playback """
 
161
        
 
162
        if self.is_playing():
 
163
            self._texture.set_playing(False)
 
164
    
 
165
    def stop(self):
 
166
        """ Stop video playback """
 
167
        
 
168
        if self._texture:
 
169
            self.remove(self._texture)
 
170
            self._texture.set_playing(False)
 
171
            self._texture.set_property("position", 0)
 
172
 
 
173
    def is_playing(self):
 
174
        """ Retrieve wether video is playing """
 
175
    
 
176
        if self._texture:
 
177
            if self._texture.get_playing():
 
178
                return True
 
179
        return False
 
180
        
 
181
    def _on_gst_message(self, bus, message):
 
182
        """ Messages from our gstreamer bus """
 
183
        
 
184
        if message.type == gst.MESSAGE_EOS:
 
185
            self.stop()
 
186
        elif message.type == gst.MESSAGE_ERROR:
 
187
            print "Gstreamer exception -- bus: " + str(bus) + ", message: " + \
 
188
                  str(message)
 
189
     
 
190
    def _set_source(self):
 
191
        """ Set texture based on given source """
 
192
        
 
193
        width = self.get_width() 
 
194
        height = self.get_height()
 
195
        
 
196
        # Account for 0 width or height
 
197
        if width == 0 or height == 0:
 
198
            return
 
199
            
 
200
        # Account for no size change
 
201
        if self._texture and \
 
202
          width == self._texture.get_width() and \
 
203
          height == self._texture.get_height():
 
204
            return
 
205
 
 
206
        if os.path.exists(self.source):
 
207
            self._texture = cluttergst.VideoTexture()
 
208
            self.playbin = self._texture.get_playbin()
 
209
            self.bus = self.playbin.get_bus()
 
210
            self.bus.add_signal_watch()
 
211
            self.bus.connect('message', self._on_gst_message)
 
212
            self._texture.show()
 
213
            self._texture.set_filename(self.source)
 
214
            self.add(self._texture)
 
215
            self.play()
 
216
        else: 
 
217
            raise AttributeError, "source doesn't exist: %s" % self.source
 
218