Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev2.5.18 generate external_videos.xml for playing on the fly #215

Open
wants to merge 11 commits into
base: test2.5.18_showDiff_extVideoXml
Choose a base branch
from
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
Loading