Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ class VideoPlayer extends Component {

getCurrentTime() {
if (this.player && this.player.getCurrentTime) {
return Math.round(this.player.getCurrentTime());
return this.player.getCurrentTime();
}
return 0;
}
Expand Down Expand Up @@ -718,4 +718,4 @@ VideoPlayer.propTypes = {
fullscreenContext: PropTypes.bool.isRequired,
};

export default injectIntl(injectWbResizeEvent(VideoPlayer));
export default injectIntl(injectWbResizeEvent(VideoPlayer));
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,18 @@ def self.get_external_video_events(events_xml)
s = { :timestamp => event['timestamp'].to_i }
external_videos_events << s
end
# See: https://github.com/bigbluebutton/bbb-playback/pull/127
# You need to directly modify the script /usr/local/bigbluebutton/core/lib/recordandplayback/generators/events.rb
events_xml.xpath("recording/event[@eventname='UpdateExternalVideoRecordEvent']").each do |event|
s = {
:timestamp => event['timestamp'].to_i,
:rate => event.at_xpath("rate").text.to_f,
:state => event.at_xpath("state").text.to_i,
:status => event.at_xpath("status").text,
:time => event.at_xpath("time").text.to_f,
}
external_videos_events << s
end
external_videos_events.sort_by {|a| a[:timestamp]}
end

Expand All @@ -861,10 +873,15 @@ def self.get_start_and_stop_rec_events(events_xml, allow_empty_events=false)
def self.get_start_and_stop_external_video_events(events_xml)
BigBlueButton.logger.info "Getting start and stop externalvideo events"
external_video_events = BigBlueButton::Events.get_external_video_events(events_xml)
if external_video_events.size.odd?
n_start_and_stop_events = 0
external_video_events.each do |e|
n_start_and_stop_events += 1 unless e[:status]
end
if n_start_and_stop_events.odd?
# user did not click to stop external video before ending meeting
external_video_events << { :timestamp => BigBlueButton::Events.last_event_timestamp(events_xml) }
end
#BigBlueButton.logger.info "get_start_and_stop_external_video_events: #{external_video_events.sort_by {|a| a[:timestamp]}}"
external_video_events.sort_by {|a| a[:timestamp]}
end

Expand All @@ -883,19 +900,31 @@ def self.match_start_and_stop_rec_events(rec_events)
matched_rec_events
end

# Match external video start and stop events
def self.match_start_and_stop_external_video_events(external_video_events)
# Match external video start, update, and stop events
def self.match_all_external_video_events(external_video_events)
BigBlueButton.logger.info ("Matching external video events")
matched_external_video_events = []
external_video_events.each_with_index do |evt,i|
if i.even?
external_video_events.each do |evt|
if evt[:status]
matched_external_video_events[-1][:updates] << {
:timestamp => evt[:timestamp],
:rate => evt[:rate],
:state => evt[:state],
:status => evt[:status],
:time => evt[:time]
}
elsif evt[:external_video_url]
matched_external_video_events << {
:start_timestamp => evt[:timestamp],
:stop_timestamp => external_video_events[i + 1][:timestamp],
:external_video_url => evt[:external_video_url],
:updates => []
}
else
e = matched_external_video_events[-1]
e[:stop_timestamp] = evt[:timestamp]
end
end
#BigBlueButton.logger.info (match_all_external_video_events: "#{matched_external_video_events}")
matched_external_video_events
end

Expand Down Expand Up @@ -1097,4 +1126,4 @@ def self.screenshare_has_audio?(events, deskshare_dir)
end

end
end
end
2 changes: 2 additions & 0 deletions record-and-playback/presentation/scripts/presentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ deskshare_output_framerate: 5
# audio_offset = 1200 means that the audio will be delayed by 1200ms
audio_offset: 0
include_deskshare: true
# you need to directly modify /usr/local/bigbluebutton/core/scripts/presentation.yml
include_external_videos: true

# For PRODUCTION
publish_dir: /var/bigbluebutton/published/presentation
Expand Down
80 changes: 75 additions & 5 deletions record-and-playback/presentation/scripts/publish/presentation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -734,12 +734,16 @@ def events_parse_clear(shapes, event, current_presentation, current_slide, times
end
end

# Changes must be directly applied to /usr/local/bigbluebutton/core/scripts/publish/presentation.rb
def events_get_image_info(slide)
slide_deskshare = slide[:deskshare]
slide_external_videos = slide[:external_videos]
slide_presentation = slide[:presentation]

if slide_deskshare
slide[:src] = 'presentation/deskshare.png'
elsif slide_external_videos
slide[:src] = 'presentation/externalVideos.png'
elsif slide_presentation == ''
slide[:src] = 'presentation/logo.png'
else
Expand All @@ -754,7 +758,7 @@ def events_get_image_info(slide)
# Emergency last-ditch blank image creation
FileUtils.mkdir_p(File.dirname(image_path))
command = \
if slide_deskshare
if slide_deskshare || slide_external_videos
['convert', '-size',
"#{@presentation_props['deskshare_output_width']}x#{@presentation_props['deskshare_output_height']}", 'xc:transparent', '-background', 'transparent', image_path,]
else
Expand Down Expand Up @@ -845,6 +849,15 @@ def process_presentation(package_dir)
slide_changed = true
end

when 'StartExternalVideoRecordEvent'
external_videos = slide_changed = true if @presentation_props['include_external_videos']

when 'StopExternalVideoRecordEvent'
if @presentation_props['include_external_videos']
external_videos = false
slide_changed = true
end

when 'AddShapeEvent', 'ModifyTextEvent'
events_parse_shape(shapes, event, current_presentation, current_slide, timestamp)

Expand Down Expand Up @@ -882,7 +895,8 @@ def process_presentation(package_dir)
if slide &&
(slide[:presentation] == current_presentation) &&
(slide[:slide] == current_slide) &&
(slide[:deskshare] == deskshare)
(slide[:deskshare] == deskshare) &&
(slide[:external_videos] == external_videos)
BigBlueButton.logger.info('Presentation/Slide: skipping, no changes')
else
if slide
Expand All @@ -896,6 +910,7 @@ def process_presentation(package_dir)
slide: current_slide,
in: timestamp,
deskshare: deskshare,
external_videos: external_videos,
}
events_get_image_info(slide)
slides << slide
Expand Down Expand Up @@ -1121,7 +1136,7 @@ def process_external_video_events(_events, package_dir)
BigBlueButton.logger.info('Processing external video events')

# Retrieve external video events
external_video_events = BigBlueButton::Events.match_start_and_stop_external_video_events(
external_video_events = BigBlueButton::Events.match_all_external_video_events(
BigBlueButton::Events.get_start_and_stop_external_video_events(@doc)
)

Expand All @@ -1130,14 +1145,18 @@ def process_external_video_events(_events, package_dir)
external_video_events.each do |event|
BigBlueButton.logger.info("Processing rec event #{re} and external video event #{event}")
start_timestamp = event[:start_timestamp]
stop_timestamp = event[:stop_timestamp]
timestamp = (translate_timestamp(start_timestamp) / 1000).to_i
# do not add same external_video twice
next if external_videos.find { |ev| ev[:timestamp] == timestamp }

re_start_timestamp = re[:start_timestamp]
re_stop_timestamp = re[:stop_timestamp]
next unless ((start_timestamp >= re_start_timestamp) && (start_timestamp <= re_stop_timestamp)) ||
((start_timestamp < re_start_timestamp) && (re_stop_timestamp >= re_start_timestamp))
#next unless ((start_timestamp >= re_start_timestamp) && (start_timestamp <= re_stop_timestamp)) ||
# ((start_timestamp < re_start_timestamp) && (re_stop_timestamp >= re_start_timestamp))
next unless ((start_timestamp >= re_start_timestamp) && (start_timestamp < re_stop_timestamp)) ||
((stop_timestamp > re_start_timestamp) && (stop_timestamp <= re_stop_timestamp)) ||
((start_timestamp <= re_start_timestamp) && (stop_timestamp >= re_stop_timestamp) && (re_stop_timestamp > re_start_timestamp))

external_videos << {
timestamp: timestamp,
Expand All @@ -1147,6 +1166,57 @@ def process_external_video_events(_events, package_dir)
end

generate_json_file(package_dir, 'external_videos.json', external_videos)

# Generate external_videos.xml for playback video within a presentation
# See: https://github.com/bigbluebutton/bbb-playback/pull/127
# You need to directly modify the script /usr/local/bigbluebutton/core/scripts/publish/presentation.rb
external_videos_play = []
@rec_events.each do |re|
external_video_events.each do |event|
start_timestamp = event[:start_timestamp]
stop_timestamp = event[:stop_timestamp]
# do not add same external_video twice
next if external_videos_play.find { |ev| ev[:start_timestamp] == start_timestamp }

re_start_timestamp = re[:start_timestamp]
re_stop_timestamp = re[:stop_timestamp]
#next unless ((start_timestamp >= re_start_timestamp) && (start_timestamp <= re_stop_timestamp)) ||
# ((start_timestamp < re_start_timestamp || stop_timestamp > re_stop_timestamp) && (re_stop_timestamp >= re_start_timestamp))
next unless ((start_timestamp >= re_start_timestamp) && (start_timestamp < re_stop_timestamp)) ||
((stop_timestamp > re_start_timestamp) && (stop_timestamp <= re_stop_timestamp)) ||
((start_timestamp <= re_start_timestamp) && (stop_timestamp >= re_stop_timestamp) && (re_stop_timestamp > re_start_timestamp))

updates = []
event[:updates].each do |update|
update[:timestamp] = (translate_timestamp(update[:timestamp]) / 1000)
update[:type] = update[:status]
update.delete(:status)
update[:playing] = update[:state] == 0 ? false : true
update.delete(:state)
updates << update
end

external_videos_play << {
start_timestamp: (translate_timestamp(event[:start_timestamp]) / 1000),
stop_timestamp: (translate_timestamp(event[:stop_timestamp]) / 1000),
url: event[:external_video_url],
updates: updates
}
end
end

xml_object = Nokogiri::XML::Builder.new do |xml|
xml.recording(:id => "external_videos_events") do
external_videos_play.each do |video|
xml.video(:start_timestamp => video[:start_timestamp], :stop_timestamp => video[:stop_timestamp], :url => video[:url]) do
video[:updates].each do |update|
xml.event(update)
end
end
end
end
end
File.open("#{package_dir}/external_videos.xml", 'w') { |f| f.puts(Nokogiri::XML(xml_object.to_xml, nil, 'utf-8').to_xml) }
end

def generate_done_or_fail_file(success)
Expand Down