diff --git a/build.gradle b/build.gradle
index a7acc1c124..df412d3fe8 100644
--- a/build.gradle
+++ b/build.gradle
@@ -50,7 +50,7 @@ allprojects {
                 includeGroupByRegex 'nl\\.dionsegijn'
 
                 // Voice RecordView
-                includeGroupByRegex 'com\\.github\\.3llomi'
+                includeGroupByRegex 'com\\.github\\.Armen101'
             }
         }
         maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
diff --git a/vector/build.gradle b/vector/build.gradle
index 991e483e98..2d662ea242 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -331,7 +331,7 @@ dependencies {
     implementation "androidx.recyclerview:recyclerview:1.2.1"
     implementation 'androidx.appcompat:appcompat:1.3.0'
     implementation "androidx.fragment:fragment-ktx:$fragment_version"
-    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+    implementation 'androidx.constraintlayout:constraintlayout:2.1.0-beta02'
     implementation "androidx.sharetarget:sharetarget:1.1.0"
     implementation 'androidx.core:core-ktx:1.5.0'
     implementation "androidx.media:media:1.3.1"
@@ -393,7 +393,7 @@ dependencies {
     implementation "androidx.autofill:autofill:$autofill_version"
     implementation 'jp.wasabeef:glide-transformations:4.3.0'
     implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
-    implementation 'com.github.3llomi:RecordView:3.0.1'
+    implementation 'com.github.Armen101:AudioRecordView:1.0.5'
 
     // Custom Tab
     implementation 'androidx.browser:browser:1.3.0'
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
index 6672027133..7833864707 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt
@@ -20,6 +20,7 @@ import android.content.Context
 import android.net.Uri
 import android.text.Editable
 import android.util.AttributeSet
+import android.view.KeyEvent
 import android.view.ViewGroup
 import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.constraintlayout.widget.ConstraintSet
@@ -48,9 +49,7 @@ class TextComposerView @JvmOverloads constructor(
         fun onCloseRelatedMessage()
         fun onSendMessage(text: CharSequence)
         fun onAddAttachment()
-        fun onVoiceRecordingStarted()
-        fun onVoiceRecordingEnded(recordTime: Long)
-        fun checkVoiceRecordingPermission(): Boolean
+        fun onTouchVoiceRecording()
     }
 
     val views: ComposerLayoutBinding
@@ -78,7 +77,7 @@ class TextComposerView @JvmOverloads constructor(
             override fun onTextEmptyStateChanged(isEmpty: Boolean) {
                 val shouldShowSendButton = currentConstraintSetId == R.layout.composer_layout_constraint_set_expanded || !isEmpty
                 views.sendButton.isInvisible = !shouldShowSendButton
-                views.voiceMessageRecorderView.isVisible = !shouldShowSendButton
+                callback?.onTextEmptyStateChanged(isEmpty)
             }
         }
         views.composerRelatedMessageCloseButton.setOnClickListener {
@@ -94,28 +93,6 @@ class TextComposerView @JvmOverloads constructor(
         views.attachmentButton.setOnClickListener {
             callback?.onAddAttachment()
         }
-
-        views.voiceMessageRecorderView.callback = object : VoiceMessageRecorderView.Callback {
-            override fun onVoiceRecordingStarted() {
-                views.attachmentButton.isVisible = false
-                views.composerEditText.isVisible = false
-                views.composerEmojiButton.isVisible = false
-                views.composerEditTextOuterBorder.isVisible = false
-                callback?.onVoiceRecordingStarted()
-            }
-
-            override fun onVoiceRecordingEnded(recordTime: Long) {
-                views.attachmentButton.isVisible = true
-                views.composerEditText.isVisible = true
-                views.composerEmojiButton.isVisible = true
-                views.composerEditTextOuterBorder.isVisible = true
-                callback?.onVoiceRecordingEnded(recordTime)
-            }
-
-            override fun checkVoiceRecordingPermission(): Boolean {
-                return callback?.checkVoiceRecordingPermission().orFalse()
-            }
-        }
     }
 
     fun collapse(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) {
@@ -128,7 +105,6 @@ class TextComposerView @JvmOverloads constructor(
 
         val shouldShowSendButton = !views.composerEditText.text.isNullOrEmpty()
         views.sendButton.isInvisible = !shouldShowSendButton
-        views.voiceMessageRecorderView.isVisible = !shouldShowSendButton
     }
 
     fun expand(animate: Boolean = true, transitionComplete: (() -> Unit)? = null) {
@@ -139,7 +115,6 @@ class TextComposerView @JvmOverloads constructor(
         currentConstraintSetId = R.layout.composer_layout_constraint_set_expanded
         applyNewConstraintSet(animate, transitionComplete)
         views.sendButton.isInvisible = false
-        views.voiceMessageRecorderView.isVisible = false
     }
 
     private fun applyNewConstraintSet(animate: Boolean, transitionComplete: (() -> Unit)?) {
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecordingHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecordingHelper.kt
deleted file mode 100644
index 63cbbe6e79..0000000000
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageRecordingHelper.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2021 New Vector Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package im.vector.app.features.home.room.detail.composer
-
-import android.content.Context
-import android.media.MediaRecorder
-import androidx.core.content.FileProvider
-import androidx.core.net.toUri
-import im.vector.app.BuildConfig
-import im.vector.lib.multipicker.entity.MultiPickerAudioType
-import im.vector.lib.multipicker.utils.toMultiPickerAudioType
-import timber.log.Timber
-import java.io.File
-import java.io.FileOutputStream
-import java.lang.RuntimeException
-import java.util.UUID
-import javax.inject.Inject
-
-/**
- * Helper class to record audio for voice messages.
- */
-class VoiceMessageRecordingHelper @Inject constructor(
-        private val context: Context
-) {
-
-    private lateinit var mediaRecorder: MediaRecorder
-    private val outputDirectory = File(context.cacheDir, "downloads")
-    private var outputFile: File? = null
-
-    init {
-        if (!outputDirectory.exists()) {
-            outputDirectory.mkdirs()
-        }
-    }
-
-    private fun refreshMediaRecorder() {
-        mediaRecorder = MediaRecorder()
-        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT)
-        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.OGG)
-        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.OPUS)
-        mediaRecorder.setAudioEncodingBitRate(24000)
-        mediaRecorder.setAudioSamplingRate(48000)
-    }
-
-    fun startRecording() {
-        outputFile = File(outputDirectory, UUID.randomUUID().toString() + ".ogg")
-        FileOutputStream(outputFile).use { fos ->
-            refreshMediaRecorder()
-            mediaRecorder.setOutputFile(fos.fd)
-            mediaRecorder.prepare()
-            mediaRecorder.start()
-        }
-    }
-
-    fun stopRecording(recordTime: Long): MultiPickerAudioType? {
-        try {
-            mediaRecorder.stop()
-            mediaRecorder.reset()
-            mediaRecorder.release()
-            outputFile?.let {
-                val outputFileUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", it)
-                return outputFileUri?.toMultiPickerAudioType(context)
-            } ?: return null
-        } catch (e: RuntimeException) { // Usually thrown when the record is less than 1 second.
-            Timber.e(e, "Voice message is not valid. Record time: %s", recordTime)
-            return null
-        }
-    }
-
-    fun deleteRecording() {
-        outputFile?.delete()
-    }
-}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
new file mode 100644
index 0000000000..cfca70840a
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.home.room.detail.timeline.item
+
+import android.text.format.DateUtils
+import android.view.ViewGroup
+import android.widget.ImageButton
+import android.widget.TextView
+import androidx.core.view.isVisible
+import com.airbnb.epoxy.EpoxyAttribute
+import com.airbnb.epoxy.EpoxyModelClass
+import com.visualizer.amplitude.AudioRecordView
+import im.vector.app.R
+import im.vector.app.core.epoxy.ClickListener
+import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder
+import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
+import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker
+
+@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
+abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() {
+
+    @EpoxyAttribute
+    var mxcUrl: String = ""
+
+    @EpoxyAttribute
+    var duration: Int = 0
+
+    @EpoxyAttribute
+    var waveform: List<Int> = emptyList()
+
+    @EpoxyAttribute
+    var izLocalFile = false
+
+    @EpoxyAttribute
+    var izDownloaded = false
+
+    @EpoxyAttribute
+    lateinit var contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder
+
+    @EpoxyAttribute
+    lateinit var contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder
+
+    @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
+    var playbackControlButtonClickListener: ClickListener? = null
+
+    @EpoxyAttribute
+    lateinit var voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker
+
+
+    override fun bind(holder: Holder) {
+        super.bind(holder)
+        renderSendState(holder.voiceLayout, null)
+        if (!attributes.informationData.sendState.hasFailed()) {
+            contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, izLocalFile, holder.progressLayout)
+        } else {
+            holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_cross)
+            holder.progressLayout.isVisible = false
+        }
+
+        holder.voicePlaybackTime.text = formatPlaybackTime(duration)
+
+        holder.voicePlaybackWaveform.post {
+            holder.voicePlaybackWaveform.recreate()
+            waveform.forEach { amplitude ->
+                holder.voicePlaybackWaveform.update(amplitude)
+            }
+        }
+
+        holder.voicePlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) }
+
+        voiceMessagePlaybackTracker.track(attributes.informationData.eventId, object : VoiceMessagePlaybackTracker.Listener {
+            override fun onUpdate(state: VoiceMessagePlaybackTracker.Listener.State) {
+                when (state) {
+                    is VoiceMessagePlaybackTracker.Listener.State.Idle    -> handleIdleState(holder, state)
+                    is VoiceMessagePlaybackTracker.Listener.State.Playing -> handlePlayingState(holder, state)
+                }
+            }
+        })
+    }
+
+    private fun handleIdleState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Idle) {
+        holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_voice_play)
+        if (state.playbackTime > 0) {
+            holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime)
+        } else {
+            holder.voicePlaybackTime.text = formatPlaybackTime(duration)
+        }
+    }
+
+    private fun handlePlayingState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Playing) {
+        holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_voice_pause)
+        if (state.playbackTime > 0) {
+            holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime)
+        } else {
+            holder.voicePlaybackTime.text = formatPlaybackTime(duration)
+        }
+    }
+
+    private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong())
+
+    override fun unbind(holder: Holder) {
+        super.unbind(holder)
+        contentUploadStateTrackerBinder.unbind(attributes.informationData.eventId)
+        contentDownloadStateTrackerBinder.unbind(mxcUrl)
+    }
+
+    override fun getViewType() = STUB_ID
+
+    class Holder : AbsMessageItem.Holder(STUB_ID) {
+        val voiceLayout by bind<ViewGroup>(R.id.voiceLayout)
+        val voicePlaybackControlButton by bind<ImageButton>(R.id.voicePlaybackControlButton)
+        val voicePlaybackTime by bind<TextView>(R.id.voicePlaybackTime)
+        val voicePlaybackWaveform by bind<AudioRecordView>(R.id.voicePlaybackWaveform)
+        val progressLayout by bind<ViewGroup>(R.id.messageFileUploadProgressLayout)
+    }
+
+    companion object {
+        private const val STUB_ID = R.id.messageContentVoiceStub
+    }
+}
diff --git a/vector/src/main/res/drawable/bg_voice_play_pause_button.xml b/vector/src/main/res/drawable/bg_voice_play_pause_button.xml
new file mode 100644
index 0000000000..c0b14c77e9
--- /dev/null
+++ b/vector/src/main/res/drawable/bg_voice_play_pause_button.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
+    <size android:width="32dp" android:height="32dp" />
+    <solid android:color="?vctr_voice_message_play_pause_button_background" />
+</shape>
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/bg_voice_playback.xml b/vector/src/main/res/drawable/bg_voice_playback.xml
new file mode 100644
index 0000000000..db31e29bc7
--- /dev/null
+++ b/vector/src/main/res/drawable/bg_voice_playback.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="?vctr_voice_message_playback_background" />
+    <size
+        android:width="240dp"
+        android:height="44dp" />
+    <corners
+        android:bottomLeftRadius="12dp"
+        android:bottomRightRadius="12dp"
+        android:topLeftRadius="12dp"
+        android:topRightRadius="12dp" />
+</shape>
\ No newline at end of file
diff --git a/vector/src/main/res/drawable/ic_voice_locked.xml b/vector/src/main/res/drawable/ic_voice_message_locked.xml
similarity index 100%
rename from vector/src/main/res/drawable/ic_voice_locked.xml
rename to vector/src/main/res/drawable/ic_voice_message_locked.xml
diff --git a/vector/src/main/res/drawable/ic_voice_pause.xml b/vector/src/main/res/drawable/ic_voice_pause.xml
new file mode 100644
index 0000000000..af74dec46c
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_voice_pause.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="10dp"
+    android:height="12dp"
+    android:viewportWidth="10"
+    android:viewportHeight="12">
+  <path
+      android:pathData="M1,0L2,0A1,1 0,0 1,3 1L3,11A1,1 0,0 1,2 12L1,12A1,1 0,0 1,0 11L0,1A1,1 0,0 1,1 0z"
+      android:fillColor="#737D8C"/>
+  <path
+      android:pathData="M8,0L9,0A1,1 0,0 1,10 1L10,11A1,1 0,0 1,9 12L8,12A1,1 0,0 1,7 11L7,1A1,1 0,0 1,8 0z"
+      android:fillColor="#737D8C"/>
+</vector>
diff --git a/vector/src/main/res/drawable/ic_voice_play.xml b/vector/src/main/res/drawable/ic_voice_play.xml
new file mode 100644
index 0000000000..ad90006799
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_voice_play.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="13dp"
+    android:height="16dp"
+    android:viewportWidth="13"
+    android:viewportHeight="16">
+  <path
+      android:pathData="M0,14.2104V1.7896C0,1.0072 0.8578,0.5279 1.5241,0.9379L11.6161,7.1483C12.2506,7.5388 12.2506,8.4612 11.6161,8.8517L1.5241,15.0621C0.8578,15.4721 0,14.9928 0,14.2104Z"
+      android:fillColor="#737D8C"/>
+</vector>
diff --git a/vector/src/main/res/layout/composer_layout.xml b/vector/src/main/res/layout/composer_layout.xml
index 7c9c23645d..5e40ab275e 100644
--- a/vector/src/main/res/layout/composer_layout.xml
+++ b/vector/src/main/res/layout/composer_layout.xml
@@ -131,10 +131,16 @@
         android:src="@drawable/ic_send"
         tools:ignore="MissingConstraints" />
 
-    <im.vector.app.features.home.room.detail.composer.VoiceMessageRecorderView
-        android:id="@+id/voiceMessageRecorderView"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        tools:ignore="MissingConstraints" />
+    <!--
+    <ImageButton
+        android:id="@+id/voiceMessageMicButton"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginEnd="12dp"
+        android:layout_marginBottom="12dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:contentDescription="@string/a11y_start_voice_message"
+        android:src="@drawable/ic_voice_mic" />
+    -->
 
 </merge>
diff --git a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml
index b51f69302a..e429cf7d16 100644
--- a/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml
+++ b/vector/src/main/res/layout/composer_layout_constraint_set_compact.xml
@@ -178,12 +178,18 @@
         tools:ignore="MissingPrefix"
         tools:visibility="visible" />
 
-    <im.vector.app.features.home.room.detail.composer.VoiceMessageRecorderView
-        android:id="@+id/voiceMessageRecorderView"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
+    <!--
+    <ImageButton
+        android:id="@+id/voiceMessageMicButton"
+        android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginEnd="12dp"
+        android:layout_marginBottom="12dp"
+        android:background="?android:attr/selectableItemBackground"
+        android:contentDescription="@string/a11y_start_voice_message"
+        android:src="@drawable/ic_voice_mic"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent" />
+        app:layout_constraintEnd_toEndOf="parent" />
+    -->
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/fragment_room_detail.xml b/vector/src/main/res/layout/fragment_room_detail.xml
index ae7494894c..6a5cae4452 100644
--- a/vector/src/main/res/layout/fragment_room_detail.xml
+++ b/vector/src/main/res/layout/fragment_room_detail.xml
@@ -248,4 +248,12 @@
         android:background="?vctr_chat_effect_snow_background"
         android:visibility="invisible" />
 
+    <im.vector.app.features.home.room.detail.composer.VoiceMessageRecorderView
+        android:id="@+id/voiceMessageRecorderView"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent" />
+
 </androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml
index e4d7aa7d9f..f753bc18a9 100644
--- a/vector/src/main/res/layout/item_timeline_event_base.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base.xml
@@ -132,6 +132,13 @@
             android:layout_marginEnd="56dp"
             android:layout="@layout/item_timeline_event_option_buttons_stub" />
 
+        <ViewStub
+            android:id="@+id/messageContentVoiceStub"
+            style="@style/TimelineContentStubBaseParams"
+            android:layout="@layout/item_timeline_event_voice_stub"
+            android:layout_marginEnd="56dp"
+            tools:visibility="visible" />
+
     </FrameLayout>
 
     <im.vector.app.core.ui.views.SendStateImageView
diff --git a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
index 35e1b097d7..797323832b 100644
--- a/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
+++ b/vector/src/main/res/layout/item_timeline_event_base_noinfo.xml
@@ -10,8 +10,8 @@
         android:id="@+id/messageSelectedBackground"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_alignParentBottom="true"
         android:layout_alignParentTop="true"
+        android:layout_alignParentBottom="true"
         android:background="@drawable/highlighted_message_background" />
 
     <View
diff --git a/vector/src/main/res/layout/item_timeline_event_voice_stub.xml b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml
new file mode 100644
index 0000000000..6809fa6722
--- /dev/null
+++ b/vector/src/main/res/layout/item_timeline_event_voice_stub.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/voiceLayout"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content">
+
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/voicePlaybackLayout"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:background="@drawable/bg_voice_playback"
+        android:minHeight="48dp"
+        android:paddingStart="8dp"
+        android:paddingTop="6dp"
+        android:paddingEnd="8dp"
+        android:paddingBottom="6dp"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageButton
+            android:id="@+id/voicePlaybackControlButton"
+            android:layout_width="32dp"
+            android:layout_height="32dp"
+            android:background="@drawable/bg_voice_play_pause_button"
+            android:contentDescription="@string/a11y_play_voice_message"
+            android:paddingStart="3dp"
+            android:paddingEnd="0dp"
+            android:src="@drawable/ic_voice_play"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent" />
+
+        <TextView
+            android:id="@+id/voicePlaybackTime"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="6dp"
+            android:lineSpacingExtra="4sp"
+            android:textColor="@color/palette_gray_200"
+            android:textSize="14sp"
+            app:layout_constraintBottom_toBottomOf="@id/voicePlaybackControlButton"
+            app:layout_constraintStart_toEndOf="@id/voicePlaybackControlButton"
+            app:layout_constraintTop_toTopOf="@id/voicePlaybackControlButton"
+            tools:text="0:23" />
+
+        <com.visualizer.amplitude.AudioRecordView
+            android:id="@+id/voicePlaybackWaveform"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            app:chunkAlignTo="center"
+            app:chunkColor="@color/palette_gray_300"
+            app:chunkMinHeight="1dp"
+            app:chunkRoundedCorners="true"
+            app:chunkSoftTransition="true"
+            app:chunkSpace="2dp"
+            app:chunkWidth="2dp"
+            app:direction="leftToRight"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintEnd_toEndOf="parent"
+            app:layout_constraintStart_toEndOf="@id/voicePlaybackTime"
+            app:layout_constraintTop_toTopOf="parent" />
+
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+
+    <include
+        android:id="@+id/messageFileUploadProgressLayout"
+        layout="@layout/media_upload_download_progress_layout"
+        android:layout_width="0dp"
+        android:layout_height="46dp"
+        android:layout_marginStart="8dp"
+        android:layout_marginTop="8dp"
+        android:layout_marginEnd="32dp"
+        android:visibility="gone"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@+id/voicePlaybackLayout"
+        tools:visibility="visible" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/layout/view_voice_message_recorder.xml b/vector/src/main/res/layout/view_voice_message_recorder.xml
index 3b124ae7ef..bf48ee1513 100644
--- a/vector/src/main/res/layout/view_voice_message_recorder.xml
+++ b/vector/src/main/res/layout/view_voice_message_recorder.xml
@@ -2,68 +2,217 @@
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/voice_message_recording_layout"
+    android:minHeight="200dp"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginEnd="2dp">
+    android:layout_height="match_parent">
 
     <View
         android:id="@+id/voiceMessageLockBackground"
-        android:layout_width="56dp"
+        android:layout_width="52dp"
         android:layout_height="160dp"
         android:background="@drawable/bg_voice_message_lock"
         android:visibility="gone"
+        tools:visibility="visible"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toTopOf="parent"
-        tools:visibility="visible" />
+        app:layout_constraintTop_toBottomOf="@id/voiceMessageMicButton" />
 
-    <com.devlomi.record_view.RecordView
-        android:id="@+id/voiceMessageRecordView"
-        android:layout_width="0dp"
+    <ImageButton
+        android:id="@+id/voiceMessageMicButton"
+        android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        app:counter_time_color="@color/palette_gray_200"
-        app:layout_constraintBottom_toBottomOf="@+id/voiceMessageButton"
-        app:layout_constraintEnd_toStartOf="@+id/voiceMessageButton"
-        app:layout_constraintStart_toStartOf="parent"
-        app:slide_to_cancel_arrow="@drawable/ic_voice_slide_to_cancel_arrow"
-        app:slide_to_cancel_arrow_color="@color/palette_gray_300"
-        app:slide_to_cancel_text="@string/voice_message_slide_to_cancel" />
-
-    <com.devlomi.record_view.RecordButton
-        android:id="@+id/voiceMessageButton"
-        android:layout_width="56dp"
-        android:layout_height="56dp"
         android:background="?android:attr/selectableItemBackground"
         android:contentDescription="@string/a11y_start_voice_message"
-        android:scaleType="center"
+        android:layout_marginBottom="12dp"
+        android:layout_marginEnd="12dp"
+        android:src="@drawable/ic_voice_mic"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:mic_icon="@drawable/ic_voice_mic"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <ImageButton
+        android:id="@+id/voiceMessageSendButton"
+        android:layout_width="56dp"
+        android:layout_height="56dp"
+        android:contentDescription="@string/send"
+        android:background="@drawable/bg_send"
+        android:scaleType="center"
+        android:visibility="gone"
+        tools:visibility="visible"
+        android:src="@drawable/ic_send"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent" />
+
+    <ImageView
+        android:id="@+id/voiceMessageTimerIndicator"
+        android:layout_width="10dp"
+        android:layout_height="10dp"
+        android:layout_marginStart="20dp"
+        android:contentDescription="@string/a11y_recording_voice_message"
+        android:src="@drawable/circle"
+        android:visibility="gone"
+        tools:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="@id/voiceMessageMicButton"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@id/voiceMessageMicButton"
+        app:tint="@color/palette_vermilion"
         tools:ignore="MissingPrefix" />
 
+    <TextView
+        android:id="@+id/voiceMessageTimer"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginStart="4dp"
+        android:lineSpacingExtra="4dp"
+        android:textColor="@color/palette_gray_200"
+        android:textSize="14sp"
+        android:visibility="gone"
+        tools:visibility="visible"
+        app:layout_constraintBottom_toBottomOf="@id/voiceMessageMicButton"
+        app:layout_constraintStart_toEndOf="@id/voiceMessageTimerIndicator"
+        app:layout_constraintTop_toTopOf="@id/voiceMessageMicButton"
+        tools:text="00:03" />
+
+    <TextView
+        android:id="@+id/voiceMessageSlideToCancel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:text="@string/voice_message_slide_to_cancel"
+        android:textColor="@color/palette_gray_300"
+        android:textSize="14sp"
+        android:visibility="gone"
+        tools:visibility="visible"
+        app:drawableStartCompat="@drawable/ic_voice_slide_to_cancel_arrow"
+        app:layout_constraintBottom_toBottomOf="@id/voiceMessageMicButton"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="@id/voiceMessageMicButton" />
+
+    <ImageView
+        android:id="@+id/voiceMessageLockImage"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="16dp"
+        android:contentDescription="@string/a11y_lock_voice_message"
+        android:src="@drawable/ic_voice_message_unlocked"
+        android:visibility="gone"
+        tools:visibility="visible"
+        app:layout_constraintEnd_toEndOf="@id/voiceMessageLockBackground"
+        app:layout_constraintStart_toStartOf="@id/voiceMessageLockBackground"
+        app:layout_constraintTop_toTopOf="@id/voiceMessageLockBackground" />
+
     <ImageView
         android:id="@+id/voiceMessageLockArrow"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:src="@drawable/ic_voice_lock_arrow"
         android:visibility="gone"
-        app:layout_constraintBottom_toTopOf="@+id/voiceMessageButton"
+        tools:visibility="visible"
+        app:layout_constraintBottom_toTopOf="@id/voiceMessageMicButton"
         app:layout_constraintEnd_toEndOf="@id/voiceMessageLockBackground"
         app:layout_constraintStart_toStartOf="@id/voiceMessageLockBackground"
-        android:layout_marginBottom="24dp"
-        tools:ignore="ContentDescription"
-        tools:visibility="visible" />
+        tools:ignore="ContentDescription" />
 
-    <ImageView
-        android:id="@+id/voiceMessageLockImage"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginTop="18dp"
-        android:contentDescription="@string/a11y_lock_voice_message"
-        android:src="@drawable/ic_voice_message_unlocked"
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/voiceMessagePlaybackLayout"
+        android:layout_width="0dp"
+        android:layout_height="44dp"
+        android:layout_marginStart="16dp"
+        android:layout_marginEnd="16dp"
         android:visibility="gone"
-        app:layout_constraintEnd_toEndOf="@id/voiceMessageLockBackground"
-        app:layout_constraintStart_toStartOf="@id/voiceMessageLockBackground"
-        app:layout_constraintTop_toTopOf="@id/voiceMessageLockBackground"
-        tools:visibility="visible" />
+        tools:visibility="visible"
+        android:layout_marginBottom="4dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@id/voiceMessageMicButton"
+        app:layout_constraintStart_toStartOf="parent" >
+
+        <ImageButton
+            android:id="@+id/voiceMessageDeletePlayback"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:background="?android:attr/selectableItemBackground"
+            android:contentDescription="@string/a11y_delete_recorded_voice_message"
+            android:src="@drawable/recv_ic_delete"
+            app:layout_constraintBottom_toBottomOf="parent"
+            app:layout_constraintStart_toStartOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:tint="@color/palette_gray_200"
+            tools:ignore="MissingPrefix" />
+
+        <androidx.constraintlayout.widget.ConstraintLayout
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            app:layout_constraintStart_toEndOf="@id/voiceMessageDeletePlayback"
+            app:layout_constraintEnd_toEndOf="parent"
+            android:backgroundTint="?vctr_voice_message_recording_playback_background"
+            android:background="@drawable/bg_voice_playback"
+            android:layout_marginStart="16dp"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintBottom_toBottomOf="parent">
+
+            <ImageView
+                android:id="@+id/voiceMessagePlaybackTimerIndicator"
+                android:layout_width="10dp"
+                android:layout_height="10dp"
+                android:layout_marginStart="8dp"
+                android:contentDescription="@string/a11y_recording_voice_message"
+                android:src="@drawable/circle"
+                app:layout_goneMarginStart="24dp"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toTopOf="parent"
+                app:tint="@color/palette_vermilion"
+                tools:ignore="MissingPrefix" />
+
+            <ImageButton
+                android:id="@+id/voicePlaybackControlButton"
+                android:layout_width="32dp"
+                android:layout_height="32dp"
+                android:background="@drawable/bg_voice_play_pause_button"
+                android:contentDescription="@string/a11y_play_voice_message"
+                android:paddingStart="3dp"
+                android:layout_marginStart="8dp"
+                android:paddingEnd="0dp"
+                android:src="@drawable/ic_voice_play"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintLeft_toLeftOf="parent"
+                app:layout_constraintTop_toTopOf="parent" />
+
+            <TextView
+                android:id="@+id/voicePlaybackTime"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginStart="6dp"
+                android:lineSpacingExtra="4sp"
+                android:textColor="@color/palette_gray_200"
+                app:layout_goneMarginStart="24dp"
+                android:textSize="14sp"
+                app:layout_constraintBottom_toBottomOf="@id/voicePlaybackControlButton"
+                app:layout_constraintStart_toEndOf="@id/voicePlaybackControlButton"
+                app:layout_constraintTop_toTopOf="@id/voicePlaybackControlButton"
+                tools:text="0:23" />
+
+            <com.visualizer.amplitude.AudioRecordView
+                android:id="@+id/voicePlaybackWaveform"
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                android:layout_marginStart="8dp"
+                android:layout_marginEnd="8dp"
+                app:chunkAlignTo="center"
+                app:chunkColor="@color/palette_gray_300"
+                app:chunkMinHeight="1dp"
+                app:chunkRoundedCorners="true"
+                app:chunkSoftTransition="true"
+                app:chunkSpace="2dp"
+                app:chunkWidth="2dp"
+                app:direction="leftToRight"
+                app:layout_constraintBottom_toBottomOf="parent"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintStart_toEndOf="@id/voicePlaybackTime"
+                app:layout_constraintTop_toTopOf="parent" />
+
+        </androidx.constraintlayout.widget.ConstraintLayout>
+
+    </androidx.constraintlayout.widget.ConstraintLayout>
 
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/vector/src/main/res/values/colors.xml b/vector/src/main/res/values/colors.xml
index f66476a795..f756b4f243 100644
--- a/vector/src/main/res/values/colors.xml
+++ b/vector/src/main/res/values/colors.xml
@@ -135,6 +135,17 @@
     <attr name="vctr_voice_message_lock_background" format="color" />
     <color name="vctr_voice_message_lock_background_light">#FFF3F8FD</color>
     <color name="vctr_voice_message_lock_background_dark">#22252B</color>
-    <color name="vctr_voice_message_lock_background_black">#22252B</color>
+
+    <attr name="vctr_voice_message_playback_background" format="color" />
+    <color name="vctr_voice_message_playback_background_light">#FFE3E8F0</color>
+    <color name="vctr_voice_message_playback_background_dark">#FF394049</color>
+
+    <attr name="vctr_voice_message_play_pause_button_background" format="color" />
+    <color name="vctr_voice_message_play_pause_button_background_light">@android:color/white</color>
+    <color name="vctr_voice_message_play_pause_button_background_dark">#FF8E99A4</color>
+
+    <attr name="vctr_voice_message_recording_playback_background" format="color" />
+    <color name="vctr_voice_message_recording_playback_background_light">#FFE3E8F0</color>
+    <color name="vctr_voice_message_recording_playback_background_dark">#FF394049</color>
 
 </resources>
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index b2519f60b2..0dbb65a138 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -2605,6 +2605,7 @@
     <string name="sent_a_video">Video.</string>
     <string name="sent_an_image">Image.</string>
     <string name="sent_an_audio_file">Audio</string>
+    <string name="sent_a_voice_message">Voice</string>
     <string name="sent_a_file">File</string>
     <string name="send_a_sticker">Sticker</string>
     <string name="sent_a_poll">Poll</string>
@@ -3403,4 +3404,11 @@
     <string name="a11y_start_voice_message">Start Voice Message</string>
     <string name="voice_message_slide_to_cancel">Slide to cancel</string>
     <string name="a11y_lock_voice_message">Voice Message Lock</string>
+    <string name="a11y_play_voice_message">Play Voice Message</string>
+    <string name="a11y_pause_voice_message">Pause Voice Message</string>
+    <string name="a11y_recording_voice_message">Recording voice message</string>
+    <string name="a11y_delete_recorded_voice_message">Delete recorded voice message</string>
+    <string name="voice_message_release_to_send_toast">Release to send</string>
+    <string name="voice_message_n_seconds_warning_toast">%1$ds left</string>
+    <string name="voice_message_tap_on_waveform_to_stop_toast">Tap on the waveform to stop and playback</string>
 </resources>
diff --git a/vector/src/main/res/values/theme_dark.xml b/vector/src/main/res/values/theme_dark.xml
index 040e73501a..385388d3d4 100644
--- a/vector/src/main/res/values/theme_dark.xml
+++ b/vector/src/main/res/values/theme_dark.xml
@@ -144,6 +144,12 @@
         <item name="vctr_social_login_button_gitlab_style">@style/WidgetButtonSocialLogin.Gitlab.Dark</item>
 
         <item name="actionModeStyle">@style/ActionModeTheme</item>
+
+        <!-- Voice Message -->
+        <item name="vctr_voice_message_lock_background">@color/vctr_voice_message_lock_background_dark</item>
+        <item name="vctr_voice_message_playback_background">@color/vctr_voice_message_playback_background_dark</item>
+        <item name="vctr_voice_message_play_pause_button_background">@color/vctr_voice_message_play_pause_button_background_dark</item>
+        <item name="vctr_voice_message_recording_playback_background">@color/vctr_voice_message_recording_playback_background_dark</item>
     </style>
 
     <style name="AppTheme.Dark" parent="AppTheme.Base.Dark" />
diff --git a/vector/src/main/res/values/theme_light.xml b/vector/src/main/res/values/theme_light.xml
index 9469b0f5e6..360eea0532 100644
--- a/vector/src/main/res/values/theme_light.xml
+++ b/vector/src/main/res/values/theme_light.xml
@@ -146,6 +146,12 @@
         <item name="vctr_social_login_button_gitlab_style">@style/WidgetButtonSocialLogin.Gitlab.Light</item>
 
         <item name="actionModeStyle">@style/ActionModeTheme</item>
+
+        <!-- Voice Message -->
+        <item name="vctr_voice_message_lock_background">@color/vctr_voice_message_lock_background_light</item>
+        <item name="vctr_voice_message_playback_background">@color/vctr_voice_message_playback_background_light</item>
+        <item name="vctr_voice_message_play_pause_button_background">@color/vctr_voice_message_play_pause_button_background_light</item>
+        <item name="vctr_voice_message_recording_playback_background">@color/vctr_voice_message_recording_playback_background_light</item>
     </style>
 
     <style name="AppTheme.Light" parent="AppTheme.Base.Light" />