Support video constraints and use key/value pairs.
- Remove the minre and maxre parameters in favour of setting video constraints directly. - In order to support non-boolean values, have constraints passed as key/value pairs, rather than the leading "-" syntax used earlier to specify false. TESTED=Verified that setting various audio and video constraints has the desired effect, including "true" and "false". Verified that the "hd" parameter still works. R=fischman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/2360005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4931 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -118,45 +118,31 @@ def on_message(room, user, message):
|
|||||||
new_message.put()
|
new_message.put()
|
||||||
logging.info('Saved message for user ' + user)
|
logging.info('Saved message for user ' + user)
|
||||||
|
|
||||||
def make_media_constraints(audio, video, min_resolution, max_resolution):
|
def make_media_track_constraints(constraints_string):
|
||||||
if not audio or audio.lower() == 'true':
|
if not constraints_string or constraints_string.lower() == 'true':
|
||||||
audio_constraints = True
|
track_constraints = True
|
||||||
elif audio.lower() == 'false':
|
elif constraints_string.lower() == 'false':
|
||||||
audio_constraints = False
|
track_constraints = False
|
||||||
else:
|
else:
|
||||||
audio_constraints = { 'mandatory': {}, 'optional': [] }
|
track_constraints = {'mandatory': {}, 'optional': []}
|
||||||
if audio:
|
for constraint_string in constraints_string.split(','):
|
||||||
for constraint in audio.split(','):
|
constraint = constraint_string.split('=')
|
||||||
# TODO(ajm): We should probably be using the optional list here, but
|
if len(constraint) != 2:
|
||||||
# Chrome M31 won't override its default settings unless the constraints
|
logging.error('Ignoring malformed constraint: ' + constraint_string)
|
||||||
# are mandatory. Chrome M32+, however, won't override optional settings.
|
continue
|
||||||
if constraint.startswith('-'):
|
if constraint[0].startswith('goog'):
|
||||||
audio_constraints['mandatory'][constraint[1:]] = False
|
track_constraints['optional'].append({constraint[0]: constraint[1]})
|
||||||
else:
|
|
||||||
audio_constraints['mandatory'][constraint] = True
|
|
||||||
|
|
||||||
if not video or video.lower() == 'true':
|
|
||||||
video_constraints = True
|
|
||||||
elif video.lower() == 'false':
|
|
||||||
video_constraints = False
|
|
||||||
else:
|
|
||||||
video_constraints = { 'mandatory': {}, 'optional': [] }
|
|
||||||
if min_resolution:
|
|
||||||
min_sizes = min_resolution.split('x')
|
|
||||||
if len(min_sizes) == 2:
|
|
||||||
video_constraints['mandatory']['minWidth'] = min_sizes[0]
|
|
||||||
video_constraints['mandatory']['minHeight'] = min_sizes[1]
|
|
||||||
else:
|
else:
|
||||||
logging.info('Ignored invalid minre: ' + min_resolution)
|
track_constraints['mandatory'][constraint[0]] = constraint[1]
|
||||||
if max_resolution:
|
|
||||||
max_sizes = max_resolution.split('x')
|
|
||||||
if len(max_sizes) == 2:
|
|
||||||
video_constraints['mandatory']['maxWidth'] = max_sizes[0]
|
|
||||||
video_constraints['mandatory']['maxHeight'] = max_sizes[1]
|
|
||||||
else:
|
|
||||||
logging.info('Ignored invalid maxre: ' + max_resolution)
|
|
||||||
|
|
||||||
return { 'audio': audio_constraints, 'video': video_constraints }
|
return track_constraints
|
||||||
|
|
||||||
|
def make_media_stream_constraints(audio, video):
|
||||||
|
stream_constraints = (
|
||||||
|
{'audio': make_media_track_constraints(audio),
|
||||||
|
'video': make_media_track_constraints(video)})
|
||||||
|
logging.info('Applying media constraints: ' + str(stream_constraints))
|
||||||
|
return stream_constraints
|
||||||
|
|
||||||
def make_pc_constraints(compat):
|
def make_pc_constraints(compat):
|
||||||
constraints = { 'optional': [] }
|
constraints = { 'optional': [] }
|
||||||
@ -316,6 +302,10 @@ class MainPage(webapp2.RequestHandler):
|
|||||||
def get(self):
|
def get(self):
|
||||||
"""Renders the main page. When this page is shown, we create a new
|
"""Renders the main page. When this page is shown, we create a new
|
||||||
channel to push asynchronous updates to the client."""
|
channel to push asynchronous updates to the client."""
|
||||||
|
|
||||||
|
# Append strings to this list to have them thrown up in message boxes. This
|
||||||
|
# will also cause the app to fail.
|
||||||
|
error_messages = []
|
||||||
# Get the base url without arguments.
|
# Get the base url without arguments.
|
||||||
base_url = self.request.path_url
|
base_url = self.request.path_url
|
||||||
user_agent = self.request.headers['User-Agent']
|
user_agent = self.request.headers['User-Agent']
|
||||||
@ -327,32 +317,45 @@ class MainPage(webapp2.RequestHandler):
|
|||||||
|
|
||||||
ts_pwd = self.request.get('tp')
|
ts_pwd = self.request.get('tp')
|
||||||
|
|
||||||
# Use "audio" and "video" to set the media stream constraints. "true" and
|
# Use "audio" and "video" to set the media stream constraints. Defined here:
|
||||||
# "false" are recognized and interpreted as bools, for example:
|
# http://dev.w3.org/2011/webrtc/editor/getusermedia.html#idl-def-MediaStreamConstraints
|
||||||
# "?audio=true&video=false" (start an audio-only call).
|
|
||||||
# "?audio=false" (start a video-only call)
|
|
||||||
# If unspecified, the constraint defaults to True.
|
|
||||||
#
|
#
|
||||||
# audio-specific parsing:
|
# "true" and "false" are recognized and interpreted as bools, for example:
|
||||||
# To set certain constraints, pass in a comma-separated list of audio
|
# "?audio=true&video=false" (Start an audio-only call.)
|
||||||
# constraint strings. If preceded by a "-", the constraint will be set to
|
# "?audio=false" (Start a video-only call.)
|
||||||
# False, and otherwise to True. There is no validation of constraint
|
# If unspecified, the stream constraint defaults to True.
|
||||||
# strings. Examples:
|
#
|
||||||
# "?audio=googEchoCancellation" (enables echo cancellation)
|
# To specify media track constraints, pass in a comma-separated list of
|
||||||
# "?audio=-googEchoCancellation,googAutoGainControl" (disables echo
|
# key/value pairs, separated by a "=". Examples:
|
||||||
# cancellation and enables gain control)
|
# "?audio=googEchoCancellation=false,googAutoGainControl=true"
|
||||||
# The strings are defined here:
|
# (Disable echo cancellation and enable gain control.)
|
||||||
|
#
|
||||||
|
# "?video=minWidth=1280,minHeight=720,googNoiseReduction=true"
|
||||||
|
# (Set the minimum resolution to 1280x720 and enable noise reduction.)
|
||||||
|
#
|
||||||
|
# Keys starting with "goog" will be added to the "optional" key; all others
|
||||||
|
# will be added to the "mandatory" key.
|
||||||
|
#
|
||||||
|
# The audio keys are defined here:
|
||||||
# https://code.google.com/p/webrtc/source/browse/trunk/talk/app/webrtc/localaudiosource.cc
|
# https://code.google.com/p/webrtc/source/browse/trunk/talk/app/webrtc/localaudiosource.cc
|
||||||
#
|
#
|
||||||
# TODO(ajm): There is currently no video functionality beyond True/False.
|
# The video keys are defined here:
|
||||||
# Move the resolution settings here instead?
|
# https://code.google.com/p/webrtc/source/browse/trunk/talk/app/webrtc/videosource.cc
|
||||||
audio = self.request.get('audio')
|
audio = self.request.get('audio')
|
||||||
video = self.request.get('video')
|
video = self.request.get('video')
|
||||||
min_resolution = self.request.get('minre')
|
|
||||||
max_resolution = self.request.get('maxre')
|
if self.request.get('hd').lower() == 'true':
|
||||||
hd_video = self.request.get('hd')
|
if video:
|
||||||
if hd_video.lower() == 'true':
|
message = 'The "hd" parameter has overridden video=' + str(video)
|
||||||
min_resolution = '1280x720'
|
logging.error(message)
|
||||||
|
error_messages.append(message)
|
||||||
|
video = 'minWidth=1280,minHeight=720'
|
||||||
|
|
||||||
|
if self.request.get('minre') or self.request.get('maxre'):
|
||||||
|
message = ('The "minre" and "maxre" parameters are no longer supported. '
|
||||||
|
'Use "video" instead.')
|
||||||
|
logging.error(message)
|
||||||
|
error_messages.append(message)
|
||||||
|
|
||||||
audio_send_codec = self.request.get('asc')
|
audio_send_codec = self.request.get('asc')
|
||||||
if not audio_send_codec:
|
if not audio_send_codec:
|
||||||
@ -430,9 +433,9 @@ class MainPage(webapp2.RequestHandler):
|
|||||||
pc_config = make_pc_config(stun_server, turn_server, ts_pwd)
|
pc_config = make_pc_config(stun_server, turn_server, ts_pwd)
|
||||||
pc_constraints = make_pc_constraints(compat)
|
pc_constraints = make_pc_constraints(compat)
|
||||||
offer_constraints = make_offer_constraints()
|
offer_constraints = make_offer_constraints()
|
||||||
media_constraints = make_media_constraints(audio, video, min_resolution,
|
media_constraints = make_media_stream_constraints(audio, video)
|
||||||
max_resolution)
|
template_values = {'error_messages': error_messages,
|
||||||
template_values = {'token': token,
|
'token': token,
|
||||||
'me': user,
|
'me': user,
|
||||||
'room_key': room_key,
|
'room_key': room_key,
|
||||||
'room_link': room_link,
|
'room_link': room_link,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
var errorMessages = {{ error_messages }};
|
||||||
var channelToken = '{{ token }}';
|
var channelToken = '{{ token }}';
|
||||||
var me = '{{ me }}';
|
var me = '{{ me }}';
|
||||||
var roomKey = '{{ room_key }}';
|
var roomKey = '{{ room_key }}';
|
||||||
|
@ -22,6 +22,13 @@ var isAudioMuted = false;
|
|||||||
var gatheredIceCandidateTypes = { Local: {}, Remote: {} };
|
var gatheredIceCandidateTypes = { Local: {}, Remote: {} };
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
|
if (errorMessages.length > 0) {
|
||||||
|
for (i = 0; i < errorMessages.length; ++i) {
|
||||||
|
window.alert(errorMessages[i]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
console.log('Initializing; room=' + roomKey + '.');
|
console.log('Initializing; room=' + roomKey + '.');
|
||||||
card = document.getElementById('card');
|
card = document.getElementById('card');
|
||||||
localVideo = document.getElementById('localVideo');
|
localVideo = document.getElementById('localVideo');
|
||||||
|
Reference in New Issue
Block a user