Skip to content

Commit 48f8167

Browse files
authored
Merge pull request #13 from tuuhin/feature_editor
Adding a editor to the project
2 parents d01c2a9 + 32a87d2 commit 48f8167

164 files changed

Lines changed: 6628 additions & 1587 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.idea/gradle.xml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
# :studio_microphone: RecorderApp
22

33
An android audio recorder app, designed to simplify the process of capturing and managing
4-
recordings.With a clean and intuitive interface, this app offers a seamless user experience.
4+
recordings.
5+
With a clean and intuitive interface, this app offers a seamless user experience.
56

67
## 💁 About
78

8-
A fully functioned recorder app with an ability to record over multiple media codec like **acc**,*
9-
*amr**,**opus** over different quality. The app can continue its recording in the background, so you
9+
A fully functioned recorder app with an ability to record over multiple media codec like **acc**,\*
10+
\*amr**,**opus\*\* over different quality. The app can continue its recording in the background, so you
1011
never miss a moment. Once the recording, you can easily manage your files within the app.
1112
There `built-in player`, you can listen to your recordings directly within the app or use the
1213
convenient media notification for playback control.
14+
Want to remove certain section of your recordings, use the audio editor that allows you to easily
15+
cut and trim unwanted sections.
1316
The apps also features creating `category` for the recordings the categories help to keep the
1417
recording organized, you can also add `bookmarks` to the portion of the recording.
1518

@@ -19,10 +22,10 @@ What are the features this app can provide, here's some:
1922

2023
- :musical_keyboard: **Effortless Recording**: Start recording instantly with a single tap of a
2124
button.
22-
- :chart_with_upwards_trend: **Visualization**: Watch the amplitude levels fluctuate in real-time as
23-
you record or play the media.
24-
- :loop: **Background Recording**: Keep recording even when you switch to other apps or lock
25-
your device.
25+
- :chart_with_upwards_trend: **Real time Visualization**: Watch the amplitude levels fluctuate in
26+
real-time as you record or play the media.
27+
- :loop: **Background Recording**: Keep recording even when you switch to other apps or lock your
28+
device.
2629
- :bellhop_bell: **Convenient Notifications**: Control your recordings directly from
2730
notifications,without having to return to the app.
2831
- :file_cabinet: **File Management**: Organize, delete, share, or rename your own recordings with
@@ -31,6 +34,7 @@ What are the features this app can provide, here's some:
3134
can easily find the required one.
3235
- :record_button: **Built-in Player**: Listen to your recordings directly within the app, complete
3336
with a media notification for easy playback control.
37+
- 👨‍🍳 **Build in Editor** : Seamlessly trim and cut section of your recording or other files.
3438
- :bookmark: **Bookmarks** : You can add multiple bookmarks with the recording to easily remember
3539
the important portions of your recording. You can too export the bookmarks as csv file.
3640
- :eight_spoked_asterisk: **Widgets And Shortcuts** : App comes with two `widgets` and few
@@ -47,7 +51,7 @@ These are some screen shorts for the app
4751
<img src="./screenshots/player_base_framed.png" width="24%" />
4852
<img src="./screenshots/app_settings_framed.png" width="24%" />
4953
<img src="./screenshots/recordings_search_screen_framed.png" width="24%">
50-
<img src="./screenshots/recording_categories_framed.png" width="24%" />
54+
<img src="./screenshots/edit_screen_normal.png" width="21%" />
5155
<img src="./screenshots/player_bookmarks_framed.png" width="24%" />
5256
<img src="./screenshots/app_widget_preview_framed.png" width="24%" />
5357
</p>
@@ -73,13 +77,30 @@ playing stuff.
7377

7478
## :new: What's new
7579

76-
The current version have these new changes added to the app
80+
This update introduces a **built-in Audio Editor** alongside significant enhancements to the player:
7781

78-
- **Search recordings** Finding old recording was a mess thus a search feature is added, user can
79-
search via `time`, `category` and obviously via name
82+
- **✂️ Unleash Your Inner Editor:** Now you can precisely `trim` and `cut` your recordings directly
83+
within the app! Remove unwanted sections and refine your audio effortlessly.
84+
- 💾 **Save Your Edits:** Preserve your edited masterpieces! The app now allows you to **save the
85+
modified audio files** to your device's storage.
86+
- ⏯️ **Dedicated Editor Player:** A **secondary player** is integrated within the editor, providing
87+
you with focused playback control during the editing process, with undo and redo options to
88+
reapply your edits.
89+
- 🚀 **Under the Hood Improvements:** Fix issues with visualization via `new-visualizer` logic. A new
90+
speed selected UI is added to the player and others.
8091

81-
- **Transitions** Added some shared bounds transition to the app,animations like
82-
`containter-transform` is added.
92+
This update is all about giving you more control over your recordings, from capture to refinement.
93+
94+
## :next_track_button: What's next
95+
96+
For the time being, RecorderApp encompasses all initially planned features and is considered
97+
complete. Future releases are not currently scheduled.
98+
99+
If you have any new ideas or suggestions for enhancements, we encourage you to create a
100+
new [Issue](https://github.com/tuuhin/RecorderApp/issues) on GitHub.
101+
102+
We are considering potential additions to the audio editor, such as audio processors like `db-gain`
103+
and `low-pass-filter`.
83104

84105
## :hammer_and_wrench: Getting Started
85106

@@ -107,17 +128,16 @@ Contributions are always welcomed from the community
107128
- Create your feature branch (git checkout -b feature/YourFeature).
108129
- Commit your changes (git commit -am 'Add some feature').
109130
- Push to the branch (git push origin feature/YourFeature).
110-
- Create a new Pull Request.
131+
- Submit a request to merge your changes onto `dev` branch of main project.
111132

112133
### :curly_loop: Feedback and Support
113134

114-
Yes, there maybe some issues regarding the app or some unwanted scenario or any new feature that can
115-
be added to the app. Please add
116-
an [issue](https://github.com/tuuhin/RecorderApp/issues) if you have one.
135+
A app is never perfect there may issue here and there which are not caught.If you encounter any
136+
issues, have suggestions for new features, or just want to share your thoughts, please don't
137+
hesitate to reach out by creating a new [Issue](https://github.com/tuuhin/RecorderApp/issues) on
138+
GitHub. Your feedback is invaluable!
117139

118-
### :next_track_button: What's next
140+
### :end: Conclusion
119141

120-
The app development is complete for now, with the core features fully implemented. Although the
121-
`edit` feature has not yet been rolled out, a significant amount of time and effort has been
122-
invested in this project. For the time being, it is considered completed, and further enhancements
123-
will be addressed as needed in the future.
142+
The app can be marked as finished for now.A significant amount of time and effort has been invested
143+
in this project hope you all love it.

app/src/main/java/com/eva/recorderapp/navigation/AppNavHost.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@ import androidx.navigation.compose.rememberNavController
1313
import com.eva.feature_categories.routes.categoryPickerRoute
1414
import com.eva.feature_categories.routes.createOrEditCategoryRoute
1515
import com.eva.feature_categories.routes.manageRecordingCategories
16-
import com.eva.feature_editor.audioEditorRoute
17-
import com.eva.feature_player.audioPlayerRoute
1816
import com.eva.feature_recorder.recorderRoute
1917
import com.eva.feature_recordings.bin.trashRecordingsRoute
2018
import com.eva.feature_recordings.recordings.recordingsRoute
2119
import com.eva.feature_recordings.rename.renameRecordingDialog
2220
import com.eva.feature_recordings.search.recordingsSearchRoute
2321
import com.eva.feature_settings.settingsRoute
22+
import com.eva.recorderapp.navigation.navgraph.playerNavGraph
2423
import com.eva.recorderapp.navigation.routes.appInfoDialog
2524
import com.eva.ui.navigation.NavRoutes
2625
import com.eva.ui.utils.LocalSharedTransitionScopeProvider
@@ -51,14 +50,14 @@ fun AppNavHost(
5150
trashRecordingsRoute(controller = navController)
5251
recordingsSearchRoute(controller = navController)
5352
manageRecordingCategories(controller = navController)
54-
audioPlayerRoute(controller = navController)
55-
audioEditorRoute(controller = navController)
5653
settingsRoute(controller = navController)
5754
categoryPickerRoute(controller = navController)
5855
createOrEditCategoryRoute(controller = navController)
5956
//dialogs
6057
appInfoDialog()
6158
renameRecordingDialog(controller = navController)
59+
// subgraph
60+
playerNavGraph(controller = navController)
6261
}
6362
}
6463
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.eva.recorderapp.navigation.navgraph
2+
3+
import androidx.navigation.NavGraphBuilder
4+
import androidx.navigation.NavHostController
5+
import androidx.navigation.navigation
6+
import com.eva.feature_editor.audioEditorRoute
7+
import com.eva.feature_player.audioPlayerRoute
8+
import com.eva.ui.navigation.PlayerSubGraph
9+
10+
fun NavGraphBuilder.playerNavGraph(controller: NavHostController) =
11+
navigation<PlayerSubGraph.NavGraph>(
12+
startDestination = PlayerSubGraph.AudioPlayerRoute::class
13+
) {
14+
audioPlayerRoute(controller = controller)
15+
audioEditorRoute(controller = controller)
16+
}

core/ui/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@ dependencies {
1818
implementation(libs.androidx.navigation.compose)
1919
implementation(libs.kotlinx.serialization.json)
2020

21+
// hilt viewmodel
22+
implementation(libs.androidx.hilt.navigation.compose)
23+
2124
//dynamic font
2225
implementation(libs.androidx.ui.text.google.fonts)
2326

2427
//commons
2528
api(libs.kotlinx.collections.immutable)
2629
api(libs.androidx.graphics.shapes)
30+
//icons
31+
api(libs.androidx.icons.extended)
2732
}

core/ui/src/main/java/com/eva/ui/animation/SharedElementModifiers.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fun Modifier.sharedElementWrapper(
4343
val state = rememberSharedContentState(key)
4444

4545
Modifier.sharedElement(
46-
state = state,
46+
sharedContentState = state,
4747
animatedVisibilityScope = visibilityScope,
4848
renderInOverlayDuringTransition = renderInOverlayDuringTransition,
4949
zIndexInOverlay = zIndexInOverlay,

core/ui/src/main/java/com/eva/ui/animation/SharedElementTransitionKeys.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package com.eva.ui.animation
22

33
object SharedElementTransitionKeys {
44

5-
const val RECORDINGS_LIST_SHARED_BOUNDS = "recordings_list_screen"
5+
const val RECORDINGS_LIST_SHARED_BOUNDS = "recordings_list_screen"
66
const val RECORDING_BIN_SHARED_BOUNDS = "recording_bin_screen"
7+
const val RECORDING_EDITOR_SHARED_BOUNDS = "recordings_editor_screen"
78

89
fun categoryCardSharedBoundsTransition(id: Long = -1) = "category_card_container_transition_$id"
910
fun recordSharedEntryTitle(id: Long) = "record_entry_${id}_title"
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.eva.ui.composables
2+
3+
import androidx.compose.material3.MaterialTheme
4+
import androidx.compose.material3.Text
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.remember
7+
import androidx.compose.ui.Modifier
8+
import androidx.compose.ui.text.TextStyle
9+
import androidx.compose.ui.text.font.FontFamily
10+
import androidx.compose.ui.text.font.FontWeight
11+
import java.time.Instant
12+
import java.time.ZoneOffset
13+
import java.time.format.DateTimeFormatter
14+
import java.util.Locale
15+
import kotlin.time.Duration
16+
import kotlin.time.toJavaDuration
17+
18+
@Composable
19+
fun DurationText(
20+
duration: Duration,
21+
modifier: Modifier = Modifier,
22+
style: TextStyle = MaterialTheme.typography.bodyMedium,
23+
formatToLocale: Boolean = true,
24+
fontFamily: FontFamily? = null,
25+
fontWeight: FontWeight? = null,
26+
) {
27+
val locale = remember(formatToLocale) { if (formatToLocale) Locale.getDefault() else Locale.US }
28+
29+
val formattedDuration = remember(duration) {
30+
val pattern = when {
31+
duration.inWholeHours > 0 -> "HH:mm:ss"
32+
else -> "mm:ss"
33+
}
34+
val formatter = DateTimeFormatter.ofPattern(pattern, locale)
35+
val instant = Instant.EPOCH.plus(duration.toJavaDuration())
36+
formatter.format(instant.atOffset(ZoneOffset.UTC))
37+
}
38+
Text(
39+
text = formattedDuration,
40+
modifier = modifier,
41+
style = style,
42+
fontFamily = fontFamily,
43+
fontWeight = fontWeight
44+
)
45+
}

core/ui/src/main/java/com/eva/ui/navigation/NavRoutes.kt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ sealed interface NavRoutes {
1616
@Serializable
1717
data object ManageCategories : NavRoutes
1818

19-
@Serializable
20-
data class AudioPlayer(val audioId: Long) : NavRoutes
21-
22-
@Serializable
23-
data object AudioEditor : NavRoutes
24-
2519
@Serializable
2620
data object AudioSettings : NavRoutes
2721

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.eva.ui.navigation
2+
3+
import kotlinx.serialization.Serializable
4+
5+
@Serializable
6+
sealed interface PlayerSubGraph {
7+
8+
// we need audio id to mark to get the route data from saved state handle
9+
@Serializable
10+
data class NavGraph(val audioId: Long) : PlayerSubGraph
11+
12+
// we need the audio id to let deep links work
13+
@Serializable
14+
data class AudioPlayerRoute(val audioId: Long) : PlayerSubGraph
15+
16+
@Serializable
17+
data object AudioEditorRoute : PlayerSubGraph
18+
}

0 commit comments

Comments
 (0)