[Jingle] Audio/video input/output now configurable
This commit is contained in:
parent
e42bed8a56
commit
132d71b08b
|
@ -20,19 +20,11 @@ import gobject
|
|||
import xmpp
|
||||
import farsight, gst
|
||||
|
||||
import gajim
|
||||
|
||||
from jingle_transport import JingleTransportICEUDP
|
||||
from jingle_content import contents, JingleContent
|
||||
|
||||
# TODO: Will that be even used?
|
||||
def get_first_gst_element(elements):
|
||||
"""
|
||||
Return, if it exists, the first available element of the list
|
||||
"""
|
||||
for name in elements:
|
||||
factory = gst.element_factory_find(name)
|
||||
if factory:
|
||||
return factory.create()
|
||||
|
||||
|
||||
class JingleRTPContent(JingleContent):
|
||||
def __init__(self, session, media, transport=None):
|
||||
|
@ -260,25 +252,25 @@ class JingleAudio(JingleRTPContent):
|
|||
self.p2psession.set_codec_preferences(codecs)
|
||||
|
||||
# the local parts
|
||||
# TODO: use gconfaudiosink?
|
||||
# sink = get_first_gst_element(['alsasink', 'osssink', 'autoaudiosink'])
|
||||
self.sink = gst.element_factory_make('alsasink')
|
||||
self.sink.set_property('sync', False)
|
||||
#sink.set_property('latency-time', 20000)
|
||||
#sink.set_property('buffer-time', 80000)
|
||||
try:
|
||||
self.sink = gst.parse_bin_from_description(gajim.config.get('audio_output_device'), True)
|
||||
except:
|
||||
self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
|
||||
_("Couldn't setup audio output. Check your audio configuration.")))
|
||||
|
||||
# TODO: use gconfaudiosrc?
|
||||
src_mic = gst.element_factory_make('alsasrc')
|
||||
src_mic.set_property('blocksize', 320)
|
||||
try:
|
||||
src_bin = gst.parse_bin_from_description(gajim.config.get('audio_input_device'), True)
|
||||
except:
|
||||
self.session.connection.dispatch('ERROR', (_("Audio configuration error"),
|
||||
_("Couldn't setup audio input. Check your audio configuration.")))
|
||||
|
||||
self.mic_volume = gst.element_factory_make('volume')
|
||||
self.mic_volume = src_bin.get_by_name('gajim_vol')
|
||||
self.mic_volume.set_property('volume', 1)
|
||||
|
||||
# link gst elements
|
||||
self.pipeline.add(self.sink, src_mic, self.mic_volume)
|
||||
src_mic.link(self.mic_volume)
|
||||
self.pipeline.add(self.sink, src_bin)
|
||||
|
||||
self.mic_volume.get_pad('src').link(self.p2psession.get_property(
|
||||
src_bin.get_pad('src').link(self.p2psession.get_property(
|
||||
'sink-pad'))
|
||||
self.p2pstream.connect('src-pad-added', self._on_src_pad_added)
|
||||
|
||||
|
@ -296,21 +288,27 @@ class JingleVideo(JingleRTPContent):
|
|||
# sometimes, one window won't show up,
|
||||
# sometimes it'll freeze...
|
||||
JingleRTPContent.setup_stream(self)
|
||||
|
||||
# the local parts
|
||||
src_vid = gst.element_factory_make('videotestsrc')
|
||||
src_vid.set_property('is-live', True)
|
||||
videoscale = gst.element_factory_make('videoscale')
|
||||
try:
|
||||
src_bin = gst.parse_bin_from_description(gajim.config.get('video_input_device'), True)
|
||||
except:
|
||||
self.session.connection.dispatch('ERROR', (_("Video configuration error"),
|
||||
_("Couldn't setup video input. Check your video configuration.")))
|
||||
caps = gst.element_factory_make('capsfilter')
|
||||
caps.set_property('caps', gst.caps_from_string('video/x-raw-yuv, width=320, height=240'))
|
||||
colorspace = gst.element_factory_make('ffmpegcolorspace')
|
||||
|
||||
self.pipeline.add(src_vid, videoscale, caps, colorspace)
|
||||
gst.element_link_many(src_vid, videoscale, caps, colorspace)
|
||||
self.pipeline.add(src_bin, caps)
|
||||
src_bin.link(caps)
|
||||
|
||||
self.sink = gst.element_factory_make('xvimagesink')
|
||||
try:
|
||||
self.sink = gst.parse_bin_from_description(gajim.config.get('video_output_device'), True)
|
||||
except:
|
||||
self.session.connection.dispatch('ERROR', (_("Video configuration error"),
|
||||
_("Couldn't setup video output. Check your video configuration.")))
|
||||
self.pipeline.add(self.sink)
|
||||
|
||||
colorspace.get_pad('src').link(self.p2psession.get_property('sink-pad'))
|
||||
caps.get_pad('src').link(self.p2psession.get_property('sink-pad'))
|
||||
self.p2pstream.connect('src-pad-added', self._on_src_pad_added)
|
||||
|
||||
# The following is needed for farsight to process ICE requests:
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
##
|
||||
## Copyright (C) 2009 Thibaut GIRKA <thib AT sitedethib.com>
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published
|
||||
## by the Free Software Foundation; version 2 only.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
|
||||
import gst
|
||||
|
||||
|
||||
class DeviceManager(object):
|
||||
def __init__(self):
|
||||
self.devices = {}
|
||||
|
||||
def detect(self):
|
||||
self.devices = {}
|
||||
|
||||
def get_devices(self):
|
||||
if not self.devices:
|
||||
self.detect()
|
||||
return self.devices
|
||||
|
||||
def detect_element(self, name, text, pipe='%s'):
|
||||
try:
|
||||
element = gst.element_factory_make(name, '%spresencetest' % name)
|
||||
if isinstance(element, gst.interfaces.PropertyProbe):
|
||||
element.set_state(gst.STATE_READY)
|
||||
devices = element.probe_get_values_name('device')
|
||||
if devices:
|
||||
self.devices[text % _(' Default device')] = pipe % name
|
||||
for device in devices:
|
||||
element.set_property('device', device)
|
||||
device_name = element.get_property('device-name')
|
||||
self.devices[text % device_name] = pipe % '%s device=%s' % (name, device)
|
||||
element.set_state(gst.STATE_NULL)
|
||||
else:
|
||||
self.devices[text] = pipe % name
|
||||
except gst.ElementNotFoundError:
|
||||
print 'element \'%s\' not found' % name
|
||||
|
||||
|
||||
class AudioInputManager(DeviceManager):
|
||||
def detect(self):
|
||||
self.devices = {}
|
||||
# Test src
|
||||
self.detect_element('audiotestsrc', _('Audio test'),
|
||||
'%s is-live=true name=gajim_vol')
|
||||
# Auto src
|
||||
self.detect_element('autoaudiosrc', _('Autodetect'),
|
||||
'%s ! volume name=gajim_vol')
|
||||
# Alsa src
|
||||
self.detect_element('alsasrc', _('ALSA: %s'),
|
||||
'%s ! volume name=gajim_vol')
|
||||
|
||||
|
||||
class AudioOutputManager(DeviceManager):
|
||||
def detect(self):
|
||||
self.devices = {}
|
||||
# Fake sink
|
||||
self.detect_element('fakesink', _('Fake audio output'))
|
||||
# Auto sink
|
||||
self.detect_element('autoaudiosink', _('Autodetect'))
|
||||
# Alsa sink
|
||||
self.detect_element('alsasink', _('ALSA: %s'),
|
||||
'%s sync=false')
|
||||
|
||||
|
||||
class VideoInputManager(DeviceManager):
|
||||
def detect(self):
|
||||
self.devices = {}
|
||||
# Test src
|
||||
self.detect_element('videotestsrc', _('Video test'),
|
||||
'%s is-live=true')
|
||||
# Auto src
|
||||
self.detect_element('autovideosrc', _('Autodetect'),
|
||||
'%s ! videoscale ! ffmpegcolorspace')
|
||||
# V4L2 src ; TODO: Figure out why it doesn't work
|
||||
self.detect_element('v4l2src', _('V4L2: %s'),
|
||||
'%s ! videoscale ! ffmpegcolorspace')
|
||||
# Funny things, just to test...
|
||||
# self.devices['GOOM'] = 'audiotestsrc ! goom'
|
||||
# self.devices['screen'] = 'ximagesrc'
|
||||
|
||||
|
||||
class VideoOutputManager(DeviceManager):
|
||||
def detect(self):
|
||||
self.devices = {}
|
||||
# Fake video output
|
||||
self.detect_element('fakesink', _('Fake audio output'))
|
||||
# Auto sink
|
||||
self.detect_element('autovideosink', _('Autodetect'))
|
||||
# xvimage sink
|
||||
self.detect_element('xvimagesink', _('X Window System (X11/XShm/Xv): %s'))
|
||||
# ximagesink
|
||||
self.detect_element('ximagesink', _('X Window System (without Xv)'))
|
||||
|
||||
|
|
@ -59,6 +59,8 @@ from common.zeroconf import connection_zeroconf
|
|||
from common import dataforms
|
||||
from common import GnuPG
|
||||
|
||||
from common.multimedia_helpers import AudioInputManager, AudioOutputManager, VideoInputManager, VideoOutputManager
|
||||
|
||||
from common.exceptions import GajimGeneralException
|
||||
|
||||
#---------- PreferencesWindow class -------------#
|
||||
|
@ -429,10 +431,10 @@ class PreferencesWindow:
|
|||
if gajim.config.get(opt_name + '_device') == value:
|
||||
combobox.set_active(index)
|
||||
|
||||
create_av_combobox('audio_input', {'test': 'test'})
|
||||
create_av_combobox('audio_output', {'test': 'test'})
|
||||
create_av_combobox('video_input', {'test': 'test'})
|
||||
create_av_combobox('video_output', {'test': 'test'})
|
||||
create_av_combobox('audio_input', AudioInputManager().get_devices())
|
||||
create_av_combobox('audio_output', AudioOutputManager().get_devices())
|
||||
create_av_combobox('video_input', VideoInputManager().get_devices())
|
||||
create_av_combobox('video_output', VideoOutputManager().get_devices())
|
||||
### Advanced tab ###
|
||||
# open links with
|
||||
if os.name == 'nt':
|
||||
|
|
Loading…
Reference in New Issue