Skip to content

Commit f29996a

Browse files
committed
增加android 自定义音视频采集示例
1 parent 82cbfb9 commit f29996a

File tree

11 files changed

+104
-25
lines changed

11 files changed

+104
-25
lines changed

Prj-Android/app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ android {
99

1010
defaultConfig {
1111
applicationId "io.anyrtc.liveplayer"
12-
minSdk 19
12+
minSdk 21
1313
targetSdk 31
1414
versionCode 1
1515
versionName "1.0"
@@ -60,5 +60,6 @@ dependencies {
6060
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
6161
implementation("io.coil-kt:coil-gif:1.4.0")
6262
implementation("io.coil-kt:coil:1.4.0")
63+
implementation 'com.github.LxzBUG:ScreenShare:1.1.6'
6364

6465
}

Prj-Android/app/src/main/java/io/anyrtc/liveplayer/InputActivity.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class InputActivity : BaseActivity(),RadioGroup.OnCheckedChangeListener,View.OnC
2222
private var resolution = 0 //0-720 1-540 2-360
2323
private val config = Config()
2424
private var requestPermission: ActivityResultLauncher<Array<String>>?=null
25+
val VIDEO_1 = "https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-tpl-cc-us-20170912_1920x1080h.mp4"
26+
2527
override fun onCreate(savedInstanceState: Bundle?) {
2628
super.onCreate(savedInstanceState)
2729
setContentView(binding.root)
@@ -71,9 +73,12 @@ class InputActivity : BaseActivity(),RadioGroup.OnCheckedChangeListener,View.OnC
7173
R.id.rb_camera-> {
7274
this@InputActivity.pushType = 0
7375
}
74-
else->{
76+
R.id.rb_screen->{
7577
this@InputActivity.pushType = 1
7678
}
79+
else->{
80+
this@InputActivity.pushType = 2
81+
}
7782
}
7883
}
7984

@@ -89,7 +94,7 @@ class InputActivity : BaseActivity(),RadioGroup.OnCheckedChangeListener,View.OnC
8994
requestPermission?.launch(arrayOf(android.Manifest.permission.CAMERA,android.Manifest.permission.RECORD_AUDIO))
9095
}
9196
1->{
92-
go(PullActivity::class.java, Pair("url",binding.etUrl.text.toString()))
97+
go(PullActivity::class.java, Pair("url",VIDEO_1))
9398
}
9499
}
95100
}

Prj-Android/app/src/main/java/io/anyrtc/liveplayer/PullActivity.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@ class PullActivity : AppCompatActivity() {
8282
) {
8383
super.onReceiveSeiMessage(player, payloadType, data)
8484

85-
binding.tvStatus.setText(String(data!!))
86-
8785
}
8886

8987
override fun onRenderVideoFrame(
@@ -169,9 +167,12 @@ class PullActivity : AppCompatActivity() {
169167
}
170168
}
171169

170+
}
172171

173-
174-
172+
override fun onBackPressed() {
173+
player.stopPlay()
174+
ArLiveEngine.release()
175+
finish()
175176
}
176177

177178
inner class PlayStatus{

Prj-Android/app/src/main/java/io/anyrtc/liveplayer/PushActivity.kt

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,24 @@ import io.anyrtc.live.ArLiveDef.ArLiveVideoResolution
1717
import io.anyrtc.live.ArLiveEngine
1818
import io.anyrtc.live.ArLivePusherObserver
1919
import io.anyrtc.liveplayer.databinding.ActivityPushBinding
20+
import org.loka.screensharekit.EncodeBuilder
21+
import org.loka.screensharekit.ScreenShareKit
22+
import org.loka.screensharekit.callback.AudioCallBack
23+
import org.loka.screensharekit.callback.RGBACallBack
24+
import org.loka.screensharekit.callback.StartCaptureCallback
2025

2126
class PushActivity : BaseActivity() {
2227
private val binding by lazy { ActivityPushBinding.inflate(layoutInflater) }
2328
private val liveEngine by lazy { ArLiveEngine.create(this)}
2429
private val pusher by lazy { liveEngine.createArLivePusher() }
2530
private var pushUrl = ""
26-
31+
private var pushType = 0
2732

2833
override fun onCreate(savedInstanceState: Bundle?) {
2934
super.onCreate(savedInstanceState)
3035
setContentView(binding.root)
3136
immersive(darkMode = false)
32-
val pushType = intent.getIntExtra("pushType",0);
37+
pushType = intent.getIntExtra("pushType",0);
3338
val resolution = intent.getIntExtra("resolution",0)
3439
pushUrl = intent.getStringExtra("url").toString()
3540
when(resolution){
@@ -46,11 +51,13 @@ class PushActivity : BaseActivity() {
4651
pusher.setVideoQuality(ArLiveDef.ArLiveVideoEncoderParam(ArLiveVideoResolution.ArLiveVideoResolution1920x1080))
4752
}
4853
}
49-
pusher.startMicrophone()
54+
5055
if (pushType == 0){
5156
pusher.setRenderView(binding.videoView)
5257
pusher.startCamera(true)
53-
}else{
58+
pusher.startMicrophone()
59+
pusher.startPush(pushUrl)
60+
}else if (pushType == 1){
5461
binding.ivBeauty.visibility = View.GONE
5562
val imageLoader = ImageLoader.Builder(this)
5663
.componentRegistry {
@@ -63,8 +70,51 @@ class PushActivity : BaseActivity() {
6370
.build()
6471
binding.ivGif.load("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F60ed9921abb8a968651aae697626dc816624cc4770c32-uwUmhP_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1645166781&t=ff39058ea3e782746361d8b2bea68511",imageLoader)
6572
pusher.startScreenCapture()
73+
pusher.startPush(pushUrl)
74+
}else{//自定义音视频采集
75+
pusher.enableCustomAudioCapture(true)
76+
pusher.enableCustomVideoCapture(true)
77+
ScreenShareKit.init(this).config(screenDataType = EncodeBuilder.SCREEN_DATA_TYPE.RGBA, audioCapture = true)
78+
.onRGBA(object :RGBACallBack{
79+
override fun onRGBA(
80+
rgba: ByteArray,
81+
width: Int,
82+
height: Int,
83+
stride: Int,
84+
rotation: Int,
85+
rotationChanged: Boolean
86+
) {
87+
pusher.sendCustomVideoFrame(ArLiveDef.ArLiveVideoFrame().apply {
88+
pixelFormat = ArLiveDef.ArLivePixelFormat.ArLivePixelFormatBGRA32
89+
bufferType = ArLiveDef.ArLiveBufferType.ArLiveBufferTypeByteArray
90+
data = rgba
91+
this.width = width
92+
this.height = height
93+
this.rotation = rotation
94+
this.stride = stride*4
95+
})
96+
}
97+
98+
})
99+
.onAudio(object :AudioCallBack{
100+
override fun onAudio(buffer: ByteArray?, ts: Long) {
101+
pusher.sendCustomAudioFrame(ArLiveDef.ArLiveAudioFrame().apply {
102+
data = buffer
103+
sampleRate = 16000
104+
channel = 2
105+
})
106+
}
107+
108+
})
109+
.onStart(object :StartCaptureCallback{
110+
override fun onStart() {
111+
pusher.startPush(pushUrl)
112+
}
113+
114+
})
115+
.start()
116+
66117
}
67-
pusher.startPush(pushUrl)
68118
initView()
69119

70120
}
@@ -142,6 +192,9 @@ class PushActivity : BaseActivity() {
142192

143193
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
144194
if (keyCode == KeyEvent.KEYCODE_BACK){
195+
if (pushType==2){
196+
ScreenShareKit.stop()
197+
}
145198
pusher.stopPush()
146199
ArLiveEngine.release()
147200
finish()

Prj-Android/app/src/main/res/layout/activity_input.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,21 @@
178178
android:layout_height="44dp"
179179
android:layout_weight="1"/>
180180

181+
<Space
182+
android:layout_width="25dp"
183+
android:layout_height="wrap_content"/>
184+
185+
<RadioButton
186+
android:id="@+id/rb_custom"
187+
android:layout_width="0dp"
188+
android:button="@null"
189+
android:text="自定义采集"
190+
android:textColor="@color/color_options"
191+
android:background="@drawable/select_options"
192+
android:gravity="center"
193+
android:layout_height="44dp"
194+
android:layout_weight="1"/>
195+
181196
</RadioGroup>
182197

183198
</LinearLayout>

Prj-Android/liveplayer/src/main/cpp/jni/LiveEngine.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ Java_io_anyrtc_live_internal_NativeInstance_nativeSendCustomVideoFrame(JNIEnv *e
400400
jint buffer_type,
401401
jbyteArray data,
402402
jobject buffer, jint width,
403-
jint height, jint rotation) {
403+
jint height, jint rotation,jint stride) {
404404
IArLivePusher* arLivePushKit = reinterpret_cast<IArLivePusher *>(nativePtr);
405405
jint result = -1;
406406
if (arLivePushKit!= NULL){
@@ -412,6 +412,7 @@ Java_io_anyrtc_live_internal_NativeInstance_nativeSendCustomVideoFrame(JNIEnv *e
412412
frame->rotation = static_cast<ArLiveRotation>(rotation);
413413
jbyte* arrayData=(env)->GetByteArrayElements(data, NULL);
414414
frame->data = reinterpret_cast<char *>(arrayData);
415+
frame->stride = stride;
415416
result = arLivePushKit->sendCustomVideoFrame(frame);
416417
env->ReleaseByteArrayElements(data, arrayData, 0);
417418
}

Prj-Android/liveplayer/src/main/java/io/anyrtc/live/ArLiveDef.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ public static final class ArLiveVideoFrame {
246246
public int width;
247247
public int height;
248248
public int rotation;
249+
public int stride;
249250

250251

251252
public ArLiveVideoFrame() {
@@ -254,7 +255,7 @@ public ArLiveVideoFrame() {
254255
}
255256

256257
@CalledByNative
257-
public ArLiveVideoFrame(ArLivePixelFormat pixelFormat, ArLiveBufferType bufferType, ArLiveTexture texture, byte[] data, ByteBuffer buffer, int width, int height, int rotation) {
258+
public ArLiveVideoFrame(ArLivePixelFormat pixelFormat, ArLiveBufferType bufferType, ArLiveTexture texture, byte[] data, ByteBuffer buffer, int width, int height, int rotation,int stride) {
258259
this.pixelFormat = pixelFormat;
259260
this.bufferType = bufferType;
260261
this.texture = texture;
@@ -263,6 +264,7 @@ public ArLiveVideoFrame(ArLivePixelFormat pixelFormat, ArLiveBufferType bufferTy
263264
this.width = width;
264265
this.height = height;
265266
this.rotation = rotation;
267+
this.stride = stride;
266268
}
267269
}
268270

Prj-Android/liveplayer/src/main/java/io/anyrtc/live/internal/ArLivePlayerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ public void onRenderVideoFrame(int pixelFormat, int bufferType, byte[] data, By
279279
@Override
280280
public void run() {
281281
if (arLivePlayEvent!=null){
282-
arLivePlayEvent.onRenderVideoFrame(arLivePlayer,new ArLiveDef.ArLiveVideoFrame(ArLiveDef.ArLivePixelFormat.values()[pixelFormat], ArLiveDef.ArLiveBufferType.values()[bufferType],null,data,buffer,width,height,rotation));
282+
arLivePlayEvent.onRenderVideoFrame(arLivePlayer,new ArLiveDef.ArLiveVideoFrame(ArLiveDef.ArLivePixelFormat.values()[pixelFormat], ArLiveDef.ArLiveBufferType.values()[bufferType],null,data,buffer,width,height,rotation,0));
283283
}
284284
}
285285
});

Prj-Android/liveplayer/src/main/java/io/anyrtc/live/internal/ArLivePusherImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ public int enableCustomVideoCapture(boolean var1) {
458458

459459
@Override
460460
public int sendCustomVideoFrame(ArLiveDef.ArLiveVideoFrame var1) {
461-
return nativeInstance.nativeSendCustomVideoFrame(nativeId,var1.pixelFormat.ordinal(),var1.bufferType.ordinal(),var1.data,var1.buffer,var1.width,var1.height,var1.rotation);
461+
return nativeInstance.nativeSendCustomVideoFrame(nativeId,var1.pixelFormat.ordinal(),var1.bufferType.ordinal(),var1.data,var1.buffer,var1.width,var1.height,var1.rotation, var1.stride);
462462
}
463463

464464
@Override

Prj-Android/liveplayer/src/main/java/io/anyrtc/live/internal/NativeInstance.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public static NativeInstance getSharedInstance() {
128128

129129
protected native int nativeEnableCustomVideoCapture(long nativePtr,boolean enable);
130130

131-
protected native int nativeSendCustomVideoFrame(long nativePtr, int pixelFormat, int bufferType, byte[] data, ByteBuffer buffer,int width,int height,int rotation);
131+
protected native int nativeSendCustomVideoFrame(long nativePtr, int pixelFormat, int bufferType, byte[] data, ByteBuffer buffer,int width,int height,int rotation,int stride);
132132

133133
protected native int nativeEnableCustomAudioCapture(long nativePtr,boolean enable);
134134

0 commit comments

Comments
 (0)