You don’t have to be an Expert to contribute to Open Source

You don’t have to be an Expert to contribute to Open SourceAlbiona HotiBlockedUnblockFollowFollowingJun 15source: http://bit.

ly/2rv4HpOWe think that to contribute to Open Source you have to know everything related to that technology, as the programming language, frameworks etc.

But that’s not true, here is why!Voice is an AudioBook player, which is open source and is developed with Kotlin for Android.

As a user of Voice AudioBook player, I wanted to be able to skip silence so I could finish the book faster.

So I searched for issues in Voice apps repository, and I saw there was a feature request for skipping silence, so I started to work on it.

Disclaimer: I have no Kotlin programming experience.

The article will contain:1.

Skip Silence Feature description2.

Copying and adapting ‘Jump to’ and ‘sleep’ feature3.

Adding the skip silence feature4.

Current and Updated implementation5.

Final changes — Adding Migrations6.

TakeawaysSkip Silence Feature descriptionBefore you start to implement something, you have to find a similar functionality with the one you are thinking to work on, otherwise, it might be a project with a lot of modules and to really understand how everything works it might take you a lot of time.

The currentFor my case, the most similar functionality was ‘Jump to’ that displaces you to a specific part of the book.

So I searched for that feature on the source code.

I decided to add the skip silence feature as part of the menu because:There were other functionalities and I wanted to have the skip silence feature too.

A menu you could manipulate with the listening part of audiobook.

The final resultThis is how our final change will look like!Copying and adapting ‘Jump to’ featureI found the ‘Jump to’ in book_play.

xml file which was an Item view:<item android:id="@+id/action_time_change" android:title="@string/action_time_change" app:showAsAction="never"/>So I added an Item to skip silence:<item android:id="@+id/action_skip_silence" android:title="@string/skip_silence" android:checkable="true" app:showAsAction="never"/>From there, searching the source code with the id of the ‘Jump to’ view send me in BookPlayController.

kt file, where there was the code of that action as:R.


action_time_change -> {launchJumpToPositionDialog() true}So I continued to add the changes for the skipping audio silence:I added the function below to BookPlayController.

kt that gets triggered when clicking the skip silence menu item.



action_skip_silence -> { toggleSkipSilenceState() true // goes for setOnMenuItemClickListener}Following the ‘Jump to’ functionality, send me to the function:launchJumpToPositionDialog()which was displaying a fragment and it wasn’t something I wanted to do.

I just had to Skip Silence ????Sadly this is all where skip silence led us to.

Copying and adapting ‘sleep’ featureThere was another item called Sleep-Timer and followed it’s id same as the earlier item, and it sends me to this action:R.


action_sleep -> { presenter.

toggleSleepTimer() true}Investigated about the presenter and found out it was a presenter of bookplaycontroller.

ktWondering what is this presenter?.Didn’t care that much, found out it was a presenter of BookPlayController.

kt so I looked over the BookPlayPresenter.

kt — There I found this function:override fun toggleSleepTimer() { if (sleepTimer.

sleepTimerActive()) sleepTimer.

setActive(false) else { view.

openSleepTimeDialog() }}Hm, but sleepTimer was a class which had the functionality of sleeptTimer.

Searching in BookPlayPresenter.

kt I found the action below:override fun seekTo(position: Int, file: File?) { val book = bookRepository.

bookById(bookId) ?: return playerController.

changePosition(position, file ?: book.


currentFile)}The method changePosition directly manipulates with the audiobook player and my functionality would do the same.

Investigating into it:fun changePosition(time: Int, file: File) { fire( intent(ACTION_CHANGE).

apply { putExtra(CHANGE_TIME, time) putExtra(CHANGE_FILE, file.

absolutePath) } )}So I replicated the above functionalities by adding the skipSilence method in playBookPresenter.

ktoverride fun toggleSkipSilence() { val skipSilence = bookRepository.



skipSilence ?: return playerController.

setSkipSilence(!skipSilence)}And added the setSkipSilence() function as shown below:fun setSkipSilence(skip: Boolean) { fire( intent(ACTION_SKIP_SILENCE).

apply { putExtra(SKIP_SILENCE, skip) } )}Same as ACTION_CHANGE I looked at how I can create the ACTION_SKIP_SILENCE variables and there they were as companion objects:const val ACTION_SPEED = "de.






ACTION_SKIP_SILENCE"I followed where the ACTION_SPEED variable was used and addressed me in PlayBackService.

kt where all actions functionalities were written, for example, the ACTION_PLAY_PAUSE :PlayerController.

ACTION_PLAY_PAUSE -> { if (playStateManager.

playState == PlayState.

PLAYING) { player.

pause(true) } else player.

play()}The player called another function into it player.

play() and the play() function was written in MediaPlayer.

kt file.

So same how this method was created I started to add another method for ACTION_SKIP_SILENCE as below:PlayerController.

ACTION_SKIP_SILENCE -> { val skipSilences = intent.


SKIP_SILENCE, false) player.

setSkipSilences(skipSilences)}Where I created the function setSkipSilences in theMediaPlayer.

kt file:fun setSkipSilences(skip: Boolean) { bookContent?.

let { val copy = it.

copy(skipSilence = skip) _bookContent.

onNext(copy) player.


playbackSpeed, skip) }}— setPlayBackParameters() was a method which had been created and it accepted only the playbackSpeed parameter.

(During the time I was searching this project I found this method which started to play the audiobook and I thought this was the place I have to add a skip silence functionality)Adding the skip silence functionalityThe actual version of ExoPlayer that was being used in this project was 2.


2 which didn’t have the capability of skipping silence, so I searched for skipping silence ExoPlayer in google and found this issue — “Skip silence” feature— which was implemented in version 2.


0 of ExoPlayer.

So I switch to the new version.

Current implementationThe current implementation of ExoPlayer had only the speed feature.

fun SimpleExoPlayer.

setPlaybackSpeed(speed: Float) { if (playbackParameters?.

speed != speed) { playbackParameters = PlaybackParameters(speed, 1F) }}Updated implementationWith the updated one, you can now see the skipSilence argument.

fun SimpleExoPlayer.

setPlaybackParameters(speed: Float, skipSilence: Boolean){if (playbackParameters?.

speed != speed || playbackParameters?.

skipSilence != skipSilence) { playbackParameters = PlaybackParameters(speed, 1F, skipSilence) } }And I continued all the changes to connect the initial changes with the final one.

Final changes — Adding MigrationsEvery book can have skip silence turned on or off, which required changes in the persistence layer which included adding the property in the files -> BookFactory, BookContent, and BookStorage.

Add a new migration on PersistanceModule to add the new property to all the previous books by default being false:class Migration44to45 : IncrementalMigration(44) { override fun migrate(db: SupportSQLiteDatabase) { db.

execSQL("ALTER TABLE tableBooks ADD skipSilence INTEGER") } }TakeawaysTo implement new functionality in already existing software is not difficult as long as you can find a similar functionality that will guide you through the structure of the project.

Even if you are learning a new technology, this is the path I recommend when learning a new technology, because trying to read through all the books, and all the knowledge will lead you into Analysis Paralysis or how I like to call it Learning Paralysis.

Honestly, not all projects are nearly as good structured and architected as Voice Audiobook Player is which is developed by Paul Woitaschek, if you listen to audiobooks, I encourage you to give it a try.

Last but not least, version 4.

0 is released on 26th of December and you can use the skip silence feature ????.

. More details

Leave a Reply