Change slide upload folder structure

488 views
Skip to first unread message

Truong Chuong Duong

unread,
Nov 24, 2017, 4:01:52 AM11/24/17
to BigBlueButton-dev
I want to change the slide upload folder to use only single folder for every room.
I mean
  1. I have lot of uploaded slide under /var/bigbluebutton/uploadedslides, all slides are in BBB slide format/structure.
  2. Every one who create new room, he/she will see all slide here instead of slide under /var/bigbluebutton/<HASH>-<NUM>/<HASH>-<NUM>
  3. If moderator upload new slide while launching a room, that new slide will be saved into /var/bigbluebutton/uploadedslide and every other future room will see this.

What module/file/folder should I take a look into to implement my feature?


Many thank for any of your suggestion

Chad Pilkey

unread,
Nov 24, 2017, 1:33:00 PM11/24/17
to BigBlueButton-dev
You'd be looking in bigbluebutton-web and bbb-common-web for anything marked for "presentation". There's quite a few locations in both projects.

The "<HASH>-<NUM>" that you point out is just the internal meeting id. The difficulty you'll have will be getting the presentation information back in to the meetings because you'd be introducing the ability for one meeting to affect another.

Truong Chuong Duong

unread,
Nov 26, 2017, 10:36:37 PM11/26/17
to BigBlueButton-dev
Thanks Chad Pilkey, I will check it.

Vào 01:33:00 UTC+7 Thứ Bảy, ngày 25 tháng 11 năm 2017, Chad Pilkey đã viết:

Truong Chuong Duong

unread,
Nov 27, 2017, 2:24:01 AM11/27/17
to BigBlueButton-dev
Hi Chad Pilkey,

Do you know how to get externelMettingID while I only know the internalMettingID?
Or how can I get the whole creating room param called by API in any bbb-common-web module?

Such as I have created the metting info:

INFO  org.bigbluebutton.api.MeetingService  - Create meeting: data={"duration":0,"record":false,"name":"21291","des
cription":"Create meeting.","meetingId":"68679b4b6ade92602985b6adc6589fc1ab5e5223-1511767323771","externalMeetingId":"21291","isBreakout":fa
lse,"event":"create_meeting"}

How can I get the externalMeetingId in org.bigbluebutton.web.services.PresentationService?

Thanks,


Vào 01:33:00 UTC+7 Thứ Bảy, ngày 25 tháng 11 năm 2017, Chad Pilkey đã viết:
You'd be looking in bigbluebutton-web and bbb-common-web for anything marked for "presentation". There's quite a few locations in both projects.

Truong Chuong Duong

unread,
Nov 27, 2017, 2:52:36 AM11/27/17
to BigBlueButton-dev
I had just found it, just use below code:

      Meeting meeting = meetingService.getMeeting(room);
      String externalMeetingId = meeting.getExternalId();


Vào 14:24:01 UTC+7 Thứ Hai, ngày 27 tháng 11 năm 2017, Truong Chuong Duong đã viết:

Truong Chuong Duong

unread,
Nov 27, 2017, 7:24:27 AM11/27/17
to BigBlueButton-dev
I succeed to change the new upload slides folders but I am stuck in new issue:
  • If I quit the room without ended it, I still see the slide here when come back
  • But if I quit and end the room, I don't see the old slide any more. The BBB still stores the new and default slide into my old folder but it doesn't show any slide already here.
  • I guess some where we have a function which read the slide folder and listing them but cannot found yet.
  • I tried to change the method listPresentations on class org.bigbluebutton.web.services.PresentationService but found it never run. I added some logger into here but it doesn't show anything so I guess BBB doesn't use this function anymore.

Could some one know where is the function which listing existing slide?


Many thanks for your help,


Vào 16:01:52 UTC+7 Thứ Sáu, ngày 24 tháng 11 năm 2017, Truong Chuong Duong đã viết:

Chad Pilkey

unread,
Nov 27, 2017, 12:52:39 PM11/27/17
to BigBlueButton-dev
If you still see uploaded presentations after you leave and rejoin you're probably just getting the same meeting. It takes a minute or two for the server to garbage collect a meeting once no one is in it.

What you're actually looking for will be anything pertaining to the "default presentation". The default value for the default presentation is "default.pdf". When a meeting is created that default presentation is converted and the presentation information is sent to akka-apps. You'll have to do something with the default presentation code so instead of converting a presentation it tells the new meeting about the old presentation information. I'm not sure how you'd go about storing and retrieving that presentation information though because right now it's in RAM and you'd need it to persist between server restarts.

Truong Chuong Duong

unread,
Nov 27, 2017, 10:02:11 PM11/27/17
to BigBlueButton-dev
Do you know where is the function which store and getting the presentation information? I can re-write my own if found that, unfortunately I am not an expert Java and Flex developer (I am PHP web developer) and BBB almost doesn't have any comment in the code so not easy for me to understand.

Vào 00:52:39 UTC+7 Thứ Ba, ngày 28 tháng 11 năm 2017, Chad Pilkey đã viết:

Chad Pilkey

unread,
Nov 28, 2017, 12:32:01 PM11/28/17
to BigBlueButton-dev
I'm not that familiar with the bbb-web code sorry. A change like you want isn't going to be one function though, you're looking at a pretty big change I think.

Truong Chuong Duong

unread,
Nov 29, 2017, 6:16:17 AM11/29/17
to BigBlueButton-dev
I think I found the function root variable which store the list of slide in RAM. It is the parametter presentations in class org.bigbluebutton.core.apps.PresentationModel (https://github.com/bigbluebutton/bigbluebutton/blob/b9dc10ede4480747aea2aaf32741c3286d226fdb/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala)

Just add new code on the constructor to add existing presentation which on HDD into that variable, BBB will display them.

I am trying to learning scala languages and changing it.

Many thank You, Chad Pilkey, you mentioned about akka-apps and it was helped me a lot.

Vào 00:32:01 UTC+7 Thứ Tư, ngày 29 tháng 11 năm 2017, Chad Pilkey đã viết:

Chad Pilkey

unread,
Nov 29, 2017, 11:57:02 AM11/29/17
to BigBlueButton-dev
I don't think you should have to change much (if anything) in akka-apps. There's already logic for pre-uploaded presentations in bbb-web and they get propagated through to akka-apps. Theoretically you could just have your stored presentations function like pre-uploaded ones just without the uploading part.

Truong Chuong Duong

unread,
Dec 7, 2017, 2:52:10 AM12/7/17
to BigBlueButton-dev
It doesn't too complex to change, just few code on the presentation model.
Use pre-uploaded feature is one of our first solution unfortunately that is impossible. This topic is just the simpleness of my tasks. Image: We have around 400GB of presentations are used by around 10.000 conversation room, each room use a unique of listing of slides every time it open (like the class room) and it can open/close many time.
So we cannot re-create a room then use pre-uploaded presentation every time some one try to open it, we also cannot keep a room open forever. So use the fixed presentation folder is the best solution.

Vào 23:57:02 UTC+7 Thứ Tư, ngày 29 tháng 11 năm 2017, Chad Pilkey đã viết:

Chad Pilkey

unread,
Dec 7, 2017, 9:44:42 AM12/7/17
to BigBlueButton-dev
Sorry, I didn't mean to suggest sending the presentations through bbb-web's presentation processing. I meant that in bbb-web you can have your own initialization steps in bbb-web that looks for existing presentation information in the file system or elsewhere and then create a pre-uploaded presentation message and send it across redis to akka-apps.

Also if you want recordings you'll have to make sure to copy the presentations into the meeting directory so the recording scripts can pick them up.

Vladimir Kozlovskiy

unread,
Apr 16, 2018, 5:50:45 AM4/16/18
to BigBlueButton-dev
Hello Truong Chuong Duong, 

I'm looking a solution of a problem similar like yours, have you found a solution?

Thanks for any comment.


пятница, 24 ноября 2017 г., 12:01:52 UTC+3 пользователь Truong Chuong Duong написал:

Truong Chuong Duong

unread,
Apr 16, 2018, 6:15:09 AM4/16/18
to BigBlueButton-dev
I did the success and wrote about. Just check the  code for akka-apps and change the files:

























1. /components/bigbluebutton/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/GetPresentationInfoReqMsgHdlr.scala
2. /components/bigbluebutton/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/PresentationModel.scala

In file 2. I added new method:


  def getNumberOfPresentations() : Int =
  {
     presentations.size
  } 

It will help me to identify does that object having data or not.

In file 1. I changed the existing method  handleGetPresentationInfoReqMsg

I added below codes at beginning of that method to scan the slide folder and get back the uploaded slides:
     24         if (liveMeeting.presModel.getNumberOfPresentations() <= 1) { //This object is not yet inited
           
    26           MeetingActor.mettingId = liveMeeting.props.meetingProp.intId
    28      
    29           var presentationData = new scala.collection.immutable.HashMap[String, Presentation]
    30      
    31           val path = "<PATH_TO_SLIDE_FOLDER>/Preloaded/"
    32           val rootUri = "http://<BBB_DOMAIN_OR_IP>/bigbluebutton/presentation/"
    33      
    34           val d = new File(path)
    35           val presentationsFiles = d.listFiles.filter(_.isDirectory).toList
    36      
    37           log.warning("Openning folder " + path)
    38      
    39           var notFoundCurrent: Boolean = true
    40      
    41           for (f <- presentationsFiles) {
    42            
    43             if (notFoundCurrent || !f.getName().startsWith("d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f")) {
           
    44               val d = new File(f.getAbsolutePath())
    45               val pageFiles = d.listFiles.filter(_.isFile).toList
    46      
    47               val pages = new collection.mutable.HashMap[String, PageVO]
    48               var num = 1;
    49               for (p <- pageFiles) {
    50                 if (p.getName().endsWith(".swf")) {
    51                   val thumbUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/thumbnail/" + num
    52                   val swfUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/slide/" + num
    53                   val txtUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/textfiles/" + num
    54                   val svgUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/svg/" + num
    55      
    56                   val page = PageVO(f.getName() + "/" + num, num, thumbUri, swfUri, txtUri, svgUri, num == 1, 0, 0, 100, 100)
    57                   pages += page.id -> page
    58                   num = num + 1
    59                 }
    60               }
    61      
    62               var isCurrent: Boolean = false
    63      
    64               if (notFoundCurrent &&
    65                 (
    66                   f.getName().startsWith("d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f") || f.getName().startsWith("default")
    67                 )) {
    68                 isCurrent = true
    69                 notFoundCurrent = false
    70               }
    71               val pr = new Presentation(f.getName(), f.getName(), isCurrent, pages.toMap, false)
    72               presentationData += pr.id -> pr
    73               liveMeeting.presModel.addPresentation(pr)
    74             }
    75           }
    76      
    78         } 

Vào 16:50:45 UTC+7 Thứ Hai, ngày 16 tháng 4 năm 2018, Vladimir Kozlovskiy đã viết:

Vladimir Kozlovskiy

unread,
Apr 23, 2018, 1:22:13 AM4/23/18
to BigBlueButton-dev
Hello Truong Chuong Duong,

It's me again, i need your help very much. I changed the files like you did, after that i rebuilt akka-bbb-apps (sbt clean, sbt run) and rebuilt bigbluebutton-client. After that i copied the presentations slides (.swf) in "preloaded" folder, but when i get start a session and open upload form i don't see them.
There is one difference, i do it with bigbluebutton 2.0. Is it bad or i did something wrong ?

files:

2. PresentationModel.scala -  I pasted the code at the beginning of the class PresentationModel


class PresentationModel {
  private var presentations = new scala.collection.immutable.HashMap[String, Presentation]

  def getNumberOfPresentations(): Int =
    {
      presentations.size
    } 


1. GetPresentationInfoReqMsgHdlr.scala - and here i pasted the code at the beginning of the method handleGetPresentationInfoReqMsg


def handleGetPresentationInfoReqMsg(msg: GetPresentationInfoReqMsg): Unit = {
    log.debug("Received GetPresentationInfoReqMsg")

    if (liveMeeting.presModel.getNumberOfPresentations() <= 1) { //This object is not yet inited

      MeetingActor.mettingId = liveMeeting.props.meetingProp.intId

      var presentationData = new scala.collection.immutable.HashMap[String, Presentation]

      val path = "/var/bigbluebutton/Preloaded/"

      val d = new File(path)
      val presentationsFiles = d.listFiles.filter(_.isDirectory).toList

      log.warning("Openning folder " + path)

      var notFoundCurrent: Boolean = true

      for (f <- presentationsFiles) {

        if (notFoundCurrent || !f.getName().startsWith("d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f")) {

          val d = new File(f.getAbsolutePath())
          val pageFiles = d.listFiles.filter(_.isFile).toList

          val pages = new collection.mutable.HashMap[String, PageVO]
          var num = 1;
          for (p <- pageFiles) {
            if (p.getName().endsWith(".swf")) {
              val thumbUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/thumbnail/" + num
              val swfUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/slide/" + num
              val txtUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/textfiles/" + num
              val svgUri = rootUri + liveMeeting.props.meetingProp.intId + "/" + liveMeeting.props.meetingProp.intId + "/" + f.getName() + "/svg/" + num

              val page = PageVO(f.getName() + "/" + num, num, thumbUri, swfUri, txtUri, svgUri, num == 1, 0, 0, 100, 100)
              pages += page.id -> page
              num = num + 1
            }
          }

          var isCurrent: Boolean = false

          if (notFoundCurrent &&
            (
              f.getName().startsWith("d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f") || f.getName().startsWith("default")
            )) {
            isCurrent = true
            notFoundCurrent = false
          }
          val pr = new Presentation(f.getName(), f.getName(), isCurrent, pages.toMap, false)
          presentationData += pr.id -> pr
          liveMeeting.presModel.addPresentation(pr)
        }
      }

    }





понедельник, 16 апреля 2018 г., 13:15:09 UTC+3 пользователь Truong Chuong Duong написал:

Vladimir Kozlovskiy

unread,
Apr 29, 2018, 7:28:37 AM4/29/18
to BigBlueButton-dev
Hello Truong Chuong Duong,

I have one error with the compiler: GetPresentationInfoReqMsgHdlr.scala:22: value meetingId is not a member of object org.bigbluebutton.core.running.MeetingActor
Your original code was "mettingId", but it is also not correct.

Can you explain me how to fix it ?



понедельник, 16 апреля 2018 г., 13:15:09 UTC+3 пользователь Truong Chuong Duong написал:
Reply all
Reply to author
Forward
0 new messages