This summer, I participated as a Google Summer of Code student under VideoLAN. GSoC is undoubtedly one of the best summer programs out there. From designing interfaces and interactions to writing production-level code, I’ve learned tons of exciting stuff!
I was blessed to have great mentors and learned a lot about the open-source community.
Project and Proposal
The VLC media player has an Editor which enables you to customize the player controlbar UI; you can arrange buttons like the play button as per your liking. My main task was to implement this Editor functionality in the new UI for VLC.
I made an account on VideoLAN’s Gitlab and worked on this repository. I used to push all my commits there to get them reviewed. Then made patches out of them and sent commits to the VLC-developer mailing list. A few other people would then review the patches. Finally, after making the required changes, the patches would get merged.
Here is a list of all my patches.
A big thanks to the team and my mentors who helped me with my endless doubts!
- Abel Tesfaye (GSoC Student)
- Sagar Kohli (GSoC Student)
- Jean-Baptiste Kempf (VideoLAN president)
- Pierre Lamot (Software engineer at Videolabs)
- Alexandre Janniaux (Software engineer at Videolabs)
- Rohan Rajpal (Me)
Our communication was mainly via emails and #vlc-gsoc on IRC.
What work was done?
I had made some contributions towards the player controlbar and further wanted to work on it. Jean then suggested I should work on the Editor. Making the Editor was a big task to do, we divided it into the following parts:
- Create a model of all the buttons/widgets on the player ControlBar.
- Load the player buttons from the model instead of hardcoding them.
- Make a simple drag and drop interface which changes the model by dragging and dropping and updates the config
- Make a View from which you can drag and add buttons to the player ControlBar.
- Add profiles combobox via which you can load, make and delete configurations for the player.
- Populate the miniplayer from the model
- Make miniplayer editable and add a tab for it in the editor
I have also worked on a few other things
- Add all the missing buttons and widgets. I’ve added the following:
- Volume Widget
- Teletext Widget
- Aspect Ratio widget
- Record button
- Spacer widget
- Extended Spacer widget
- FullScreen button
- Record button
- AB Loop button
- Snapshot button
- Stop button
- Media Info button
- Frame by frame button
- Faster button
- Slower button
- Open media button
- Extended settings button
- Step forward button
- Step backward button
- Quit button
- Volume Widget
- Create a topbar for non editable buttons
What’s left to do?
Although I completed every task I was assigned, below-mentioned tasks are best suited as a follow-up for my work done:
- If too many widgets come on one side the center buttons don’t remain in the center anymore. This has to be fixed.
- The design of the Teletext and a few other widgets isn’t final and work needs to be done.
Have a look on how the VLC Editor works below:
Highlights and Challenges
Make a generic player controlbar
The first task was to make a model that had all the button and widget data. Then I had to use that model to populate the player ControlBar. Loaders are quite helpful when you have to load a component in QML.
After making the buttons model. The next step was to make a QtAbstractListModel to maintain a list of the buttons in current config. This is how the player ControlBar is populated now:
- The model would load the config from VLC Core API.
- The player controlbar model would then add the respective buttons to the list.
- The main controlbar would then use this model to get the list and ids which would then load the button from the buttons model.
Make sure VLC is accessible via keyboard
One had to make sure that VLC is easily useable via the Keyboard as well. KeyNavigation and Focuscope are the critical things you’ll work with when you are working with Focus.
With a lot of documentation reading, experimenting, and Pierre’s help, I successfully got the KeyNavigation right.
Drag and Drop
We all use drag and drop interfaces quite frequently. Making such interfaces made me understand the design and the logic behind it.
To make an item draggable, you have to set it as a drag target. Similarly, to make it possible to drop a draggable, you need to declare a DropArea.
I also had to add functionalities like move, insert and delete to the model, because Drag and Drop involve all these actions.
Have a look at some of the actions below:
The next task was to code the cancel and close buttons. The player controlbar should only be updated when the user presses the close button. To implement this, I used signals.
When you press the close button, the toolbarConfUpdated signal emits, and the playerControlBar is updated.
Signals and Slots are used for communication between objects in Qt. Here’s the signal sent when toolbar is updated:
Hinting the user
For the user to easily use the drag and drop interface, we have to provide some hints.
When you hover over a draggable item, the cursor changes to an open hand cursor. If you click and hold over it, the cursor changes to a closed hand cursor.
The cursor changes to ForbiddenCursor if you take the draggable to a place where it’s not possible to drop.
Profiles help someone easily save their preferences. For this, I kept the configs of both the player and the mini-player controlbar and split them using a delimiter.
Different parts of the Editor
One interesting thing about this editor is that it is a mix of QML and Qt/C++. The window, profiles section and action buttons are coded in Qt. The whole drag and drop part is in QML.
Why use Qt when all can be done in QML? Because:
- qml takes more ram
- qml accessibility is hard to get
- qml is harder to debug, and helps doing some big qml files, which we want to avoid at all cost.
The picture below shows the division.
Things I learned
- Tricks like fixup and autosquash help a lot in keeping the commits clean.
- Rebase and reset is quite helpful when you need to edit or rearrange commits.
- How to work with patches, send emails from git directly.
- Handling merge conflicts like a pro.
- How to split commits? A nice trick is if the commit message has bullet points, it can further be split.
- Avoid writing over-engineered code
- How to work on a huge codebase. Things like Memory leaks, ram consumption, learned how to use the VLC Core API.
- Design patterns like the D-pointer strategy and Model View Delegate.
- Qt/C++, QML and writing production-level code in them.
- QtCreator, one of the best IDEs I’ve used.
- Learned design concepts like form follows the flow.
- Prototyping, brainstorming on interactions.
- Thinking design solutions keeping the code in mind.