[Jingle] Audio/video input/output now configurable

This commit is contained in:
Thibaut GIRKA 2009-11-29 15:39:26 +01:00
parent e42bed8a56
commit 132d71b08b
3 changed files with 138 additions and 35 deletions

View File

@ -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:

View File

@ -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)'))

View File

@ -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':