David Liu

Add some basic controls

@@ -3,7 +3,6 @@ package io.livekit.android.sample @@ -3,7 +3,6 @@ package io.livekit.android.sample
3 import android.media.AudioManager 3 import android.media.AudioManager
4 import android.os.Bundle 4 import android.os.Bundle
5 import android.os.Parcelable 5 import android.os.Parcelable
6 -import android.os.PersistableBundle  
7 import androidx.appcompat.app.AppCompatActivity 6 import androidx.appcompat.app.AppCompatActivity
8 import com.github.ajalt.timberkt.Timber 7 import com.github.ajalt.timberkt.Timber
9 import com.google.android.material.tabs.TabLayoutMediator 8 import com.google.android.material.tabs.TabLayoutMediator
@@ -62,7 +61,17 @@ class CallActivity : AppCompatActivity() { @@ -62,7 +61,17 @@ class CallActivity : AppCompatActivity() {
62 val videoTrack = room.localParticipant.videoTracks.values 61 val videoTrack = room.localParticipant.videoTracks.values
63 .firstOrNull() 62 .firstOrNull()
64 ?.track as? LocalVideoTrack 63 ?.track as? LocalVideoTrack
65 - videoTrack?.addRenderer(binding.pipVideoView) 64 +
  65 + videoTrack?.let {
  66 + it.addRenderer(binding.pipVideoView)
  67 + binding.videoButton.setOnClickListener {
  68 + room.localParticipant.unpublishTrack(videoTrack)
  69 + Timber.e { "unpublishing video" }
  70 + binding.videoButton.setOnClickListener(null)
  71 + }
  72 + }
  73 +
  74 +
66 } 75 }
67 val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager 76 val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
68 with(audioManager) { 77 with(audioManager) {
@@ -108,8 +108,8 @@ class MainActivity : AppCompatActivity() { @@ -108,8 +108,8 @@ class MainActivity : AppCompatActivity() {
108 const val PREFERENCES_KEY_URL = "url" 108 const val PREFERENCES_KEY_URL = "url"
109 const val PREFERENCES_KEY_TOKEN = "token" 109 const val PREFERENCES_KEY_TOKEN = "token"
110 110
111 - const val URL = "wss://livekit.watercooler.fm" 111 + const val URL = "ws://192.168.11.5:7880"
112 const val TOKEN = 112 const val TOKEN =
113 - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE5ODQyMzE0OTgsImlzcyI6IkFQSU1teGlMOHJxdUt6dFpFb1pKVjlGYiIsImp0aSI6ImZvcnRoIiwibmJmIjoxNjI0MjMxNDk4LCJ2aWRlbyI6eyJyb29tIjoibXlyb29tIiwicm9vbUpvaW4iOnRydWV9fQ.PVx_lXAIGxcD2VRslosrbkigc777GXbu-DQME8hjJKI" 113 + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzI2MjcyNzEsImlzcyI6IkFQSVNRdmdrYWJZdXFUQSIsImp0aSI6InBob25lIiwibmJmIjoxNjMwMDM1MjcxLCJzdWIiOiJwaG9uZSIsInZpZGVvIjp7InJvb20iOiJteXJvb20iLCJyb29tSm9pbiI6dHJ1ZX19.2viZNxAXSwfpm9-sDbW5eWEibWqGv9yIg3KuSA2TmyA"
114 } 114 }
115 } 115 }
@@ -37,6 +37,14 @@ class ParticipantItem( @@ -37,6 +37,14 @@ class ParticipantItem(
37 setupVideoIfNeeded(track, viewBinding) 37 setupVideoIfNeeded(track, viewBinding)
38 } 38 }
39 } 39 }
  40 +
  41 + override fun onTrackUnpublished(
  42 + publication: RemoteTrackPublication,
  43 + participant: RemoteParticipant
  44 + ) {
  45 + super.onTrackUnpublished(publication, participant)
  46 + Timber.e { "Track unpublished" }
  47 + }
40 } 48 }
41 val existingTrack = getVideoTrack() 49 val existingTrack = getVideoTrack()
42 if (existingTrack != null) { 50 if (existingTrack != null) {
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + android:width="24dp"
  3 + android:height="24dp"
  4 + android:viewportWidth="24"
  5 + android:viewportHeight="24"
  6 + android:tint="?attr/colorControlNormal">
  7 + <path
  8 + android:fillColor="@android:color/white"
  9 + android:pathData="M12,14c1.66,0 3,-1.34 3,-3L15,5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17.91,11c-0.49,0 -0.9,0.36 -0.98,0.85C16.52,14.2 14.47,16 12,16s-4.52,-1.8 -4.93,-4.15c-0.08,-0.49 -0.49,-0.85 -0.98,-0.85 -0.61,0 -1.09,0.54 -1,1.14 0.49,3 2.89,5.35 5.91,5.78L11,20c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-2.08c3.02,-0.43 5.42,-2.78 5.91,-5.78 0.1,-0.6 -0.39,-1.14 -1,-1.14z"/>
  10 +</vector>
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + android:width="24dp"
  3 + android:height="24dp"
  4 + android:viewportWidth="24"
  5 + android:viewportHeight="24"
  6 + android:tint="?attr/colorControlNormal">
  7 + <path
  8 + android:fillColor="@android:color/white"
  9 + android:pathData="M15,10.6L15,5c0,-1.66 -1.34,-3 -3,-3 -1.54,0 -2.79,1.16 -2.96,2.65L15,10.6zM18.08,11c-0.41,0 -0.77,0.3 -0.83,0.71 -0.05,0.32 -0.12,0.64 -0.22,0.93l1.27,1.27c0.3,-0.6 0.52,-1.25 0.63,-1.94 0.07,-0.51 -0.33,-0.97 -0.85,-0.97zM3.71,3.56c-0.39,0.39 -0.39,1.02 0,1.41L9,10.27v0.43c0,1.19 0.6,2.32 1.63,2.91 0.75,0.43 1.41,0.44 2.02,0.31l1.66,1.66c-0.71,0.33 -1.5,0.52 -2.31,0.52 -2.54,0 -4.88,-1.77 -5.25,-4.39 -0.06,-0.41 -0.42,-0.71 -0.83,-0.71 -0.52,0 -0.92,0.46 -0.85,0.97 0.46,2.96 2.96,5.3 5.93,5.75L11,20c0,0.55 0.45,1 1,1s1,-0.45 1,-1v-2.28c0.91,-0.13 1.77,-0.45 2.55,-0.9l3.49,3.49c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L5.12,3.56c-0.39,-0.39 -1.02,-0.39 -1.41,0z"/>
  10 +</vector>
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + android:width="24dp"
  3 + android:height="24dp"
  4 + android:viewportWidth="24"
  5 + android:viewportHeight="24"
  6 + android:tint="?attr/colorControlNormal">
  7 + <path
  8 + android:fillColor="@android:color/white"
  9 + android:pathData="M17,10.5V7c0,-0.55 -0.45,-1 -1,-1H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.55,0 1,-0.45 1,-1v-3.5l2.29,2.29c0.63,0.63 1.71,0.18 1.71,-0.71V8.91c0,-0.89 -1.08,-1.34 -1.71,-0.71L17,10.5z"/>
  10 +</vector>
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + android:width="24dp"
  3 + android:height="24dp"
  4 + android:viewportWidth="24"
  5 + android:viewportHeight="24"
  6 + android:tint="?attr/colorControlNormal">
  7 + <path
  8 + android:fillColor="@android:color/white"
  9 + android:pathData="M21,14.2V8.91c0,-0.89 -1.08,-1.34 -1.71,-0.71L17,10.5V7c0,-0.55 -0.45,-1 -1,-1h-5.61l8.91,8.91c0.62,0.63 1.7,0.18 1.7,-0.71zM2.71,2.56c-0.39,0.39 -0.39,1.02 0,1.41L4.73,6H4c-0.55,0 -1,0.45 -1,1v10c0,0.55 0.45,1 1,1h12c0.21,0 0.39,-0.08 0.55,-0.18l2.48,2.48c0.39,0.39 1.02,0.39 1.41,0 0.39,-0.39 0.39,-1.02 0,-1.41L4.12,2.56c-0.39,-0.39 -1.02,-0.39 -1.41,0z"/>
  10 +</vector>
@@ -17,11 +17,44 @@ @@ -17,11 +17,44 @@
17 app:layout_constraintBottom_toBottomOf="parent" 17 app:layout_constraintBottom_toBottomOf="parent"
18 app:layout_constraintTop_toBottomOf="@id/tabs" /> 18 app:layout_constraintTop_toBottomOf="@id/tabs" />
19 19
20 - <io.livekit.android.renderer.TextureViewRenderer  
21 - android:id="@+id/pip_video_view" 20 + <androidx.constraintlayout.widget.ConstraintLayout
22 android:layout_height="144dp" 21 android:layout_height="144dp"
23 android:layout_width="144dp" 22 android:layout_width="144dp"
24 app:layout_constraintBottom_toBottomOf="parent" 23 app:layout_constraintBottom_toBottomOf="parent"
25 - app:layout_constraintEnd_toEndOf="parent" 24 + app:layout_constraintEnd_toEndOf="parent">
  25 +
  26 + <io.livekit.android.renderer.TextureViewRenderer
  27 + android:id="@+id/pip_video_view"
  28 + android:layout_width="match_parent"
  29 + android:layout_height="match_parent"
26 android:layout_margin="16dp" /> 30 android:layout_margin="16dp" />
  31 +
  32 + <LinearLayout
  33 + android:layout_width="wrap_content"
  34 + android:layout_height="wrap_content"
  35 + android:layout_margin="30dp"
  36 + android:orientation="horizontal"
  37 + app:layout_constraintBottom_toBottomOf="parent"
  38 + app:layout_constraintEnd_toEndOf="parent"
  39 + app:layout_constraintStart_toStartOf="parent">
  40 +
  41 + <ImageButton
  42 + android:id="@+id/mic_button"
  43 + android:layout_width="32dp"
  44 + android:layout_height="32dp"
  45 + android:src="@drawable/ic_round_mic_24" />
  46 +
  47 + <Space
  48 + android:layout_width="20dp"
  49 + android:layout_height="1dp" />
  50 +
  51 + <ImageButton
  52 + android:id="@+id/video_button"
  53 + android:layout_width="32dp"
  54 + android:layout_height="32dp"
  55 + android:src="@drawable/ic_round_videocam_24" />
  56 +
  57 + </LinearLayout>
  58 +
  59 + </androidx.constraintlayout.widget.ConstraintLayout>
27 </androidx.constraintlayout.widget.ConstraintLayout> 60 </androidx.constraintlayout.widget.ConstraintLayout>