src/pyams_media/video.py
changeset 10 9296741c1470
parent 0 fd39db613f8b
child 24 0f4851b0aef3
equal deleted inserted replaced
9:7c73df1106b4 10:9296741c1470
    19 
    19 
    20 from tempfile import NamedTemporaryFile
    20 from tempfile import NamedTemporaryFile
    21 
    21 
    22 # import interfaces
    22 # import interfaces
    23 from pyams_file.interfaces import IVideo, IThumbnail
    23 from pyams_file.interfaces import IVideo, IThumbnail
       
    24 from pyams_media.interfaces import IVideoType
       
    25 from pyams_utils.interfaces.tales import ITALESExtension
    24 from zope.annotation.interfaces import IAnnotations
    26 from zope.annotation.interfaces import IAnnotations
    25 from zope.traversing.interfaces import ITraversable
    27 from zope.traversing.interfaces import ITraversable
    26 
    28 
    27 # import packages
    29 # import packages
    28 import transaction
    30 import transaction
    29 
    31 
    30 from pyams_file.file import ImageFile, get_magic_content_type
    32 from pyams_file.file import ImageFile, get_magic_content_type
    31 from pyams_file.image import ThumbnailGeometrry
    33 from pyams_file.image import ThumbnailGeometrry
    32 from pyams_media.ffbase import FFmpeg
    34 from pyams_media.ffbase import FFmpeg
    33 from pyams_utils.adapter import adapter_config, ContextAdapter
    35 from pyams_utils.adapter import adapter_config, ContextAdapter, ContextRequestViewAdapter
    34 from pyramid.threadlocal import get_current_registry
    36 from pyramid.threadlocal import get_current_registry
       
    37 from zope.interface import Interface
    35 from zope.lifecycleevent import ObjectCreatedEvent, ObjectAddedEvent
    38 from zope.lifecycleevent import ObjectCreatedEvent, ObjectAddedEvent
    36 from zope.location import locate
    39 from zope.location import locate
    37 
    40 
    38 
    41 
    39 THUMBNAIL_ANNOTATION_KEY = 'pyams_media.video.thumbnail'
    42 THUMBNAIL_ANNOTATION_KEY = 'pyams_media.video.thumbnail'
    51     def get_image_size(self):
    54     def get_image_size(self):
    52         if self.thumbnail is not None:
    55         if self.thumbnail is not None:
    53             return self.thumbnail.get_image_size()
    56             return self.thumbnail.get_image_size()
    54         else:
    57         else:
    55             mpeg = FFmpeg('ffprobe')
    58             mpeg = FFmpeg('ffprobe')
    56             streams = mpeg.info(self.video)
    59             streams = mpeg.info(self.video).get('streams', ())
    57             if streams:
    60             for stream in streams:
    58                 for stream in streams:
    61                 if stream.get('codec_type') != 'video':
    59                     if stream.get('codec_type') != 'video':
    62                     continue
    60                         continue
    63                 return stream.get('width'), stream.get('height')
    61                     return stream.get('width'), stream.get('height')
       
    62 
    64 
    63     def get_thumbnail_size(self, thumbnail_name, forced=False):
    65     def get_thumbnail_size(self, thumbnail_name, forced=False):
    64         if self.thumbnail is not None:
    66         if self.thumbnail is not None:
    65             return IThumbnail(self.thumbnail).get_thumbnail_size(thumbnail_name, forced)
    67             return IThumbnail(self.thumbnail).get_thumbnail_size(thumbnail_name, forced)
    66         else:
    68         else:
   159             format = None
   161             format = None
   160         thumbnails = IThumbnail(self.context)
   162         thumbnails = IThumbnail(self.context)
   161         result = thumbnails.get_thumbnail(thumbnail_name, format)
   163         result = thumbnails.get_thumbnail(thumbnail_name, format)
   162         transaction.commit()
   164         transaction.commit()
   163         return result
   165         return result
       
   166 
       
   167 
       
   168 #
       
   169 # Custom video types
       
   170 #
       
   171 
       
   172 @adapter_config(context=IVideo, provides=IVideoType)
       
   173 class VideoTypeAdapter(ContextAdapter):
       
   174     """Default video content type adapter"""
       
   175 
       
   176     @property
       
   177     def video_type(self):
       
   178         return self.context.content_type
       
   179 
       
   180 
       
   181 @adapter_config(name='video/x-flv', context=IVideo, provides=IVideoType)
       
   182 class FlashVideoTypeAdapter(ContextAdapter):
       
   183     """Flash video content type adapter"""
       
   184 
       
   185     @property
       
   186     def video_type(self):
       
   187         return b'video/flash'
       
   188 
       
   189 
       
   190 @adapter_config(name='video_type', context=(IVideo, Interface, Interface), provides=ITALESExtension)
       
   191 class VideoTypeExtension(ContextRequestViewAdapter):
       
   192     """extension:video_type(media) TALES extension"""
       
   193 
       
   194     def render(self, context=None):
       
   195         if context is None:
       
   196             context = self.context
       
   197         registry = self.request.registry
       
   198         adapter = registry.queryAdapter(context, IVideoType, name=context.content_type.decode())
       
   199         if adapter is None:
       
   200             adapter = registry.queryAdapter(context, IVideoType)
       
   201         if adapter is not None:
       
   202             return adapter.video_type.decode()