Merge pull request #14911 from GuiLeme/issue-9789
This commit is contained in:
commit
14815184e6
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* BigBlueButton 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.bigbluebutton.core.record.events
|
||||||
|
|
||||||
|
class MeetingConfigurationEvent extends StarterConfigurationEvent {
|
||||||
|
import MeetingConfigurationEvent._
|
||||||
|
|
||||||
|
setEvent("MeetingConfigurationEvent")
|
||||||
|
|
||||||
|
def setWebcamsOnlyForModerator(webcamsOnlyForModerator: Boolean) {
|
||||||
|
eventMap.put(WEBCAMS_ONLY_FOR_MODERATOR, webcamsOnlyForModerator.toString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object MeetingConfigurationEvent {
|
||||||
|
val WEBCAMS_ONLY_FOR_MODERATOR = "webcamsOnlyForModerator"
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* Foundation; either version 3.0 of the License, or (at your option) any later
|
||||||
|
* version.
|
||||||
|
*
|
||||||
|
* BigBlueButton 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.bigbluebutton.core.record.events
|
||||||
|
|
||||||
|
trait StarterConfigurationEvent extends RecordEvent {
|
||||||
|
setModule("CONFIG")
|
||||||
|
}
|
@ -116,6 +116,7 @@ class RedisRecorderActor(
|
|||||||
case m: RecordStatusResetSysMsg => handleRecordStatusResetSysMsg(m)
|
case m: RecordStatusResetSysMsg => handleRecordStatusResetSysMsg(m)
|
||||||
case m: WebcamsOnlyForModeratorChangedEvtMsg => handleWebcamsOnlyForModeratorChangedEvtMsg(m)
|
case m: WebcamsOnlyForModeratorChangedEvtMsg => handleWebcamsOnlyForModeratorChangedEvtMsg(m)
|
||||||
case m: MeetingEndingEvtMsg => handleEndAndKickAllSysMsg(m)
|
case m: MeetingEndingEvtMsg => handleEndAndKickAllSysMsg(m)
|
||||||
|
case m: MeetingCreatedEvtMsg => handleStarterConfigurations(m)
|
||||||
|
|
||||||
// Recording
|
// Recording
|
||||||
case m: RecordingChapterBreakSysMsg => handleRecordingChapterBreakSysMsg(m)
|
case m: RecordingChapterBreakSysMsg => handleRecordingChapterBreakSysMsg(m)
|
||||||
@ -622,4 +623,10 @@ class RedisRecorderActor(
|
|||||||
log.error("recording database is not available.")
|
log.error("recording database is not available.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def handleStarterConfigurations(msg: MeetingCreatedEvtMsg): Unit = {
|
||||||
|
val ev = new MeetingConfigurationEvent()
|
||||||
|
ev.setWebcamsOnlyForModerator(msg.body.props.usersProp.webcamsOnlyForModerator)
|
||||||
|
record(msg.body.props.meetingProp.intId, ev.toMap().asJava)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ import org.bigbluebutton.api.messaging.converters.messages.DeletedRecordingMessa
|
|||||||
import org.bigbluebutton.api.messaging.messages.*;
|
import org.bigbluebutton.api.messaging.messages.*;
|
||||||
import org.bigbluebutton.api2.IBbbWebApiGWApp;
|
import org.bigbluebutton.api2.IBbbWebApiGWApp;
|
||||||
import org.bigbluebutton.api2.domain.UploadedTrack;
|
import org.bigbluebutton.api2.domain.UploadedTrack;
|
||||||
|
import org.bigbluebutton.common2.msgs.MeetingCreatedEvtMsg;
|
||||||
import org.bigbluebutton.common2.redis.RedisStorageService;
|
import org.bigbluebutton.common2.redis.RedisStorageService;
|
||||||
import org.bigbluebutton.presentation.PresentationUrlDownloadService;
|
import org.bigbluebutton.presentation.PresentationUrlDownloadService;
|
||||||
import org.bigbluebutton.presentation.imp.SwfSlidesGenerationProgressNotifier;
|
import org.bigbluebutton.presentation.imp.SwfSlidesGenerationProgressNotifier;
|
||||||
|
@ -112,8 +112,60 @@ module BigBlueButton
|
|||||||
start_events
|
start_events
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.to_boolean(obj)
|
||||||
|
return obj.to_s.downcase == "true"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.is_user_moderator(user_id, list_user_info)
|
||||||
|
user_role = list_user_info[user_id]
|
||||||
|
if !user_role.nil?
|
||||||
|
if user_role == "MODERATOR"
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get_id_from_filename(filename)
|
||||||
|
return filename.split("/")[-1].split("-")[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.extract_filename_from_userId(userId, filenames_list)
|
||||||
|
filename_return = ""
|
||||||
|
filenames_list.each do |filename|
|
||||||
|
if !filename.match(userId).nil?
|
||||||
|
filename_return = filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return filename_return
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.process_webcamsOnlyForModerator(list_user_info, active_videos, inactive_videos, webcamsOnlyForModerator)
|
||||||
|
|
||||||
|
if webcamsOnlyForModerator
|
||||||
|
list_user_info.each do |user_id, user_role|
|
||||||
|
# If the user is a viewer:
|
||||||
|
if !BigBlueButton::Events.is_user_moderator(user_id, list_user_info)
|
||||||
|
filename = BigBlueButton::Events.extract_filename_from_userId(user_id, active_videos)
|
||||||
|
if filename != ""
|
||||||
|
active_videos.delete(filename)
|
||||||
|
inactive_videos << filename
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# If the WebcamsOnlyForModerator is false, all previously inactive videos will become active
|
||||||
|
inactive_videos.each do |filename|
|
||||||
|
active_videos << filename
|
||||||
|
end
|
||||||
|
inactive_videos.clear
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Build a webcam EDL
|
# Build a webcam EDL
|
||||||
def self.create_webcam_edl(events, archive_dir)
|
def self.create_webcam_edl(events, archive_dir, show_moderator_viewpoint)
|
||||||
recording = events.at_xpath('/recording')
|
recording = events.at_xpath('/recording')
|
||||||
meeting_id = recording['meeting_id']
|
meeting_id = recording['meeting_id']
|
||||||
event = events.at_xpath('/recording/event[position()=1]')
|
event = events.at_xpath('/recording/event[position()=1]')
|
||||||
@ -125,57 +177,203 @@ module BigBlueButton
|
|||||||
|
|
||||||
videos = {}
|
videos = {}
|
||||||
active_videos = []
|
active_videos = []
|
||||||
|
inactive_videos = []
|
||||||
video_edl = []
|
video_edl = []
|
||||||
|
|
||||||
video_edl << {
|
video_edl << {
|
||||||
:timestamp => 0,
|
:timestamp => 0,
|
||||||
:areas => { :webcam => [] }
|
:areas => { :webcam => [] }
|
||||||
}
|
}
|
||||||
|
list_user_info = {}
|
||||||
events.xpath('/recording/event[@module="WEBCAM" or (@module="bbb-webrtc-sfu" and (@eventname="StartWebRTCShareEvent" or @eventname="StopWebRTCShareEvent"))]').each do |event|
|
webcamsOnlyForModerator = false
|
||||||
timestamp = event['timestamp'].to_i - initial_timestamp
|
if show_moderator_viewpoint
|
||||||
# Determine the video filename
|
events.xpath('/recording/event[@module="WEBCAM" or (@module="bbb-webrtc-sfu" and (@eventname="StartWebRTCShareEvent" or @eventname="StopWebRTCShareEvent"))]').each do |event|
|
||||||
case event['eventname']
|
timestamp = event['timestamp'].to_i - initial_timestamp
|
||||||
when 'StartWebcamShareEvent', 'StopWebcamShareEvent'
|
# Determine the video filename
|
||||||
stream = event.at_xpath('stream').text
|
case event['eventname']
|
||||||
filename = "#{video_dir}/#{stream}.flv"
|
when 'StartWebcamShareEvent', 'StopWebcamShareEvent'
|
||||||
when 'StartWebRTCShareEvent', 'StopWebRTCShareEvent'
|
stream = event.at_xpath('stream').text
|
||||||
uri = event.at_xpath('filename').text
|
filename = "#{video_dir}/#{stream}.flv"
|
||||||
filename = "#{video_dir}/#{File.basename(uri)}"
|
when 'StartWebRTCShareEvent', 'StopWebRTCShareEvent'
|
||||||
|
uri = event.at_xpath('filename').text
|
||||||
|
filename = "#{video_dir}/#{File.basename(uri)}"
|
||||||
|
end
|
||||||
|
raise "Couldn't determine webcam filename" if filename.nil?
|
||||||
|
|
||||||
|
# Add the video to the EDL
|
||||||
|
case event['eventname']
|
||||||
|
when 'StartWebcamShareEvent', 'StartWebRTCShareEvent'
|
||||||
|
videos[filename] = { :timestamp => timestamp }
|
||||||
|
active_videos << filename
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
when 'StopWebcamShareEvent', 'StopWebRTCShareEvent'
|
||||||
|
active_videos.delete(filename)
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
end
|
||||||
end
|
end
|
||||||
raise "Couldn't determine webcam filename" if filename.nil?
|
else
|
||||||
|
events.xpath('/recording/event[@module="WEBCAM" or (@module="bbb-webrtc-sfu" and (@eventname="StartWebRTCShareEvent" or @eventname="StopWebRTCShareEvent")) or (@module="PARTICIPANT" and (@eventname="ParticipantStatusChangeEvent" or @eventname="ParticipantJoinEvent")) or @eventname="WebcamsOnlyForModeratorEvent" or @eventname="MeetingConfigurationEvent"]').each do |event|
|
||||||
|
timestamp = event['timestamp'].to_i - initial_timestamp
|
||||||
|
|
||||||
# Add the video to the EDL
|
# Determine the video filename if event is as the following
|
||||||
case event['eventname']
|
case event['eventname']
|
||||||
when 'StartWebcamShareEvent', 'StartWebRTCShareEvent'
|
when 'StartWebcamShareEvent', 'StopWebcamShareEvent'
|
||||||
videos[filename] = { :timestamp => timestamp }
|
stream = event.at_xpath('stream').text
|
||||||
active_videos << filename
|
filename = "#{video_dir}/#{stream}.flv"
|
||||||
|
when 'StartWebRTCShareEvent', 'StopWebRTCShareEvent'
|
||||||
edl_entry = {
|
uri = event.at_xpath('filename').text
|
||||||
:timestamp => timestamp,
|
filename = "#{video_dir}/#{File.basename(uri)}"
|
||||||
:areas => { :webcam => [] }
|
|
||||||
}
|
|
||||||
active_videos.each do |filename|
|
|
||||||
edl_entry[:areas][:webcam] << {
|
|
||||||
:filename => filename,
|
|
||||||
:timestamp => timestamp - videos[filename][:timestamp]
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
video_edl << edl_entry
|
|
||||||
when 'StopWebcamShareEvent', 'StopWebRTCShareEvent'
|
|
||||||
active_videos.delete(filename)
|
|
||||||
|
|
||||||
edl_entry = {
|
# Add the video to the EDL
|
||||||
:timestamp => timestamp,
|
case event['eventname']
|
||||||
:areas => { :webcam => [] }
|
when 'StartWebcamShareEvent', 'StartWebRTCShareEvent'
|
||||||
}
|
userId = BigBlueButton::Events.get_id_from_filename(filename)
|
||||||
active_videos.each do |filename|
|
is_in_forbidden_period = webcamsOnlyForModerator
|
||||||
edl_entry[:areas][:webcam] << {
|
|
||||||
:filename => filename,
|
if (!is_in_forbidden_period) || (is_in_forbidden_period && BigBlueButton::Events.is_user_moderator(userId, list_user_info))
|
||||||
:timestamp => timestamp - videos[filename][:timestamp]
|
|
||||||
|
videos[filename] = { :timestamp => timestamp }
|
||||||
|
active_videos << filename
|
||||||
|
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp],
|
||||||
|
:user_id => BigBlueButton::Events.get_id_from_filename(filename)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
elsif is_in_forbidden_period && !BigBlueButton::Events.is_user_moderator(userId, list_user_info)
|
||||||
|
inactive_videos << filename
|
||||||
|
videos[filename] = { :timestamp => timestamp }
|
||||||
|
end
|
||||||
|
when 'StopWebcamShareEvent', 'StopWebRTCShareEvent'
|
||||||
|
userId = BigBlueButton::Events.get_id_from_filename(filename)
|
||||||
|
is_in_forbidden_period = webcamsOnlyForModerator
|
||||||
|
|
||||||
|
if (!is_in_forbidden_period) || (is_in_forbidden_period && BigBlueButton::Events.is_user_moderator(userId, list_user_info))
|
||||||
|
active_videos.delete(filename)
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp],
|
||||||
|
:user_id => BigBlueButton::Events.get_id_from_filename(filename)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
elsif is_in_forbidden_period && !BigBlueButton::Events.is_user_moderator(userId, list_user_info)
|
||||||
|
inactive_videos.delete(filename)
|
||||||
|
end
|
||||||
|
when "ParticipantJoinEvent"
|
||||||
|
user_id = event.at_xpath('userId').text
|
||||||
|
list_user_info[user_id] = event.at_xpath('role').text
|
||||||
|
|
||||||
|
when "ParticipantStatusChangeEvent"
|
||||||
|
is_in_forbidden_period = webcamsOnlyForModerator
|
||||||
|
userId = ""
|
||||||
|
filename_to_add = ""
|
||||||
|
|
||||||
|
if event.at_xpath('status').text == "role"
|
||||||
|
userId = event.at_xpath('userId').text
|
||||||
|
|
||||||
|
if is_in_forbidden_period && event.at_xpath('value').text == "MODERATOR"
|
||||||
|
filename_to_add = BigBlueButton::Events.extract_filename_from_userId(userId, inactive_videos)
|
||||||
|
if filename_to_add != ""
|
||||||
|
inactive_videos.delete(filename_to_add)
|
||||||
|
active_videos << filename_to_add
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp],
|
||||||
|
:user_id => userId
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
end
|
||||||
|
elsif is_in_forbidden_period && event.at_xpath('value').text == "VIEWER"
|
||||||
|
filename_to_add = BigBlueButton::Events.extract_filename_from_userId(userId, active_videos)
|
||||||
|
if filename != ""
|
||||||
|
active_videos.delete(filename_to_add)
|
||||||
|
inactive_videos << filename_to_add
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp],
|
||||||
|
:user_id => userId
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
end
|
||||||
|
end
|
||||||
|
user_id = event.at_xpath('userId').text
|
||||||
|
list_user_info[user_id] = event.at_xpath('value').text
|
||||||
|
end
|
||||||
|
|
||||||
|
when "MeetingConfigurationEvent"
|
||||||
|
webcamsOnlyForModerator = BigBlueButton::Events.to_boolean(event.at_xpath('webcamsOnlyForModerator').text)
|
||||||
|
|
||||||
|
when "WebcamsOnlyForModeratorEvent"
|
||||||
|
# Change active and inactive videos.
|
||||||
|
BigBlueButton::Events.process_webcamsOnlyForModerator(list_user_info, active_videos, inactive_videos, BigBlueButton::Events.to_boolean(event.at_xpath("webcamsOnlyForModerator").text))
|
||||||
|
|
||||||
|
edl_entry = {
|
||||||
|
:timestamp => timestamp,
|
||||||
|
:areas => { :webcam => [] }
|
||||||
}
|
}
|
||||||
|
active_videos.each do |filename|
|
||||||
|
edl_entry[:areas][:webcam] << {
|
||||||
|
:filename => filename,
|
||||||
|
:timestamp => timestamp - videos[filename][:timestamp],
|
||||||
|
:user_id => userId
|
||||||
|
}
|
||||||
|
end
|
||||||
|
video_edl << edl_entry
|
||||||
|
|
||||||
|
webcamsOnlyForModerator = BigBlueButton::Events.to_boolean(event.at_xpath('webcamsOnlyForModerator').text)
|
||||||
end
|
end
|
||||||
video_edl << edl_entry
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ require File.expand_path('../../edl', __FILE__)
|
|||||||
module BigBlueButton
|
module BigBlueButton
|
||||||
|
|
||||||
|
|
||||||
def BigBlueButton.process_webcam_videos(target_dir, raw_archive_dir, output_width, output_height, output_framerate, audio_offset, processed_audio_file, video_formats=['webm'])
|
def BigBlueButton.process_webcam_videos(target_dir, raw_archive_dir, output_width, output_height, output_framerate, audio_offset, processed_audio_file, video_formats=['webm'], show_moderator_viewpoint=false)
|
||||||
BigBlueButton.logger.info("Processing webcam videos")
|
BigBlueButton.logger.info("Processing webcam videos")
|
||||||
|
|
||||||
# raw_archive_dir already contains meeting_id
|
# raw_archive_dir already contains meeting_id
|
||||||
@ -38,7 +38,7 @@ module BigBlueButton
|
|||||||
start_time = BigBlueButton::Events.first_event_timestamp(events)
|
start_time = BigBlueButton::Events.first_event_timestamp(events)
|
||||||
end_time = BigBlueButton::Events.last_event_timestamp(events)
|
end_time = BigBlueButton::Events.last_event_timestamp(events)
|
||||||
webcam_edl = BigBlueButton::Events.create_webcam_edl(
|
webcam_edl = BigBlueButton::Events.create_webcam_edl(
|
||||||
events, raw_archive_dir)
|
events, raw_archive_dir, show_moderator_viewpoint)
|
||||||
user_video_edl = BigBlueButton::Events.edl_match_recording_marks_video(
|
user_video_edl = BigBlueButton::Events.edl_match_recording_marks_video(
|
||||||
webcam_edl, events, start_time, end_time)
|
webcam_edl, events, start_time, end_time)
|
||||||
BigBlueButton::EDL::Video.dump(user_video_edl)
|
BigBlueButton::EDL::Video.dump(user_video_edl)
|
||||||
|
@ -40,6 +40,11 @@ anonymize_chat: false
|
|||||||
# meta param: meta_bbb-anonymize-chat-moderators (true/false)
|
# meta param: meta_bbb-anonymize-chat-moderators (true/false)
|
||||||
anonymize_chat_moderators: false
|
anonymize_chat_moderators: false
|
||||||
|
|
||||||
|
# By default, recordings assume the Viewer viewpoint (with all locks)
|
||||||
|
# so when webcamsOnlyForModerator=true, only moderators webcams are included in recordings.
|
||||||
|
# Use this option to ignore locks and assume Moderator viewpoint instead.
|
||||||
|
show_moderator_viewpoint: false
|
||||||
|
|
||||||
# Sequence of recording steps. Keys are the current step, values
|
# Sequence of recording steps. Keys are the current step, values
|
||||||
# are the next step(s). Examples:
|
# are the next step(s). Examples:
|
||||||
# current_step: next_step
|
# current_step: next_step
|
||||||
|
@ -225,7 +225,7 @@ unless FileTest.directory?(target_dir)
|
|||||||
|
|
||||||
webcam_framerate = 15 if webcam_framerate.nil?
|
webcam_framerate = 15 if webcam_framerate.nil?
|
||||||
processed_audio_file = BigBlueButton::AudioProcessor.get_processed_audio_file(raw_archive_dir, "#{target_dir}/audio")
|
processed_audio_file = BigBlueButton::AudioProcessor.get_processed_audio_file(raw_archive_dir, "#{target_dir}/audio")
|
||||||
BigBlueButton.process_webcam_videos(target_dir, raw_archive_dir, webcam_width, webcam_height, webcam_framerate, presentation_props['audio_offset'], processed_audio_file, presentation_props['video_formats'])
|
BigBlueButton.process_webcam_videos(target_dir, raw_archive_dir, webcam_width, webcam_height, webcam_framerate, presentation_props['audio_offset'], processed_audio_file, presentation_props['video_formats'], props['show_moderator_viewpoint'])
|
||||||
end
|
end
|
||||||
|
|
||||||
if !Dir["#{raw_archive_dir}/deskshare/*"].empty? && presentation_props['include_deskshare']
|
if !Dir["#{raw_archive_dir}/deskshare/*"].empty? && presentation_props['include_deskshare']
|
||||||
|
@ -84,7 +84,7 @@ begin
|
|||||||
logger.info "Generating video events list"
|
logger.info "Generating video events list"
|
||||||
|
|
||||||
# Webcams
|
# Webcams
|
||||||
webcam_edl = BigBlueButton::Events.create_webcam_edl(events, raw_archive_dir)
|
webcam_edl = BigBlueButton::Events.create_webcam_edl(events, raw_archive_dir, props['show_moderator_viewpoint'])
|
||||||
logger.debug "Webcam EDL:"
|
logger.debug "Webcam EDL:"
|
||||||
BigBlueButton::EDL::Video.dump(webcam_edl)
|
BigBlueButton::EDL::Video.dump(webcam_edl)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user