Skip to content

Commit

Permalink
Merge branch 'release/2022.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
miosakuma committed Sep 16, 2022
2 parents 6a762d4 + 4980042 commit 0795615
Show file tree
Hide file tree
Showing 13 changed files with 402 additions and 407 deletions.
594 changes: 316 additions & 278 deletions CHANGES.md

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Sora Android SDK

[![Release](https://jitpack.io/v/shiguredo/sora-android-sdk.svg)](https://jitpack.io/#shiguredo/sora-android-sdk)
[![libwebrtc](https://img.shields.io/badge/libwebrtc-103.5060-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5060)
[![libwebrtc](https://img.shields.io/badge/libwebrtc-105.5195-blue.svg)](https://chromium.googlesource.com/external/webrtc/+/branch-heads/5195)
[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/shiguredo/sora-android-sdk.svg)](https://github.com/shiguredo/sora-android-sdk.svg)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

Expand All @@ -22,7 +22,7 @@ Please read https://github.com/shiguredo/oss before use.

- Android 5 以降 (エミュレーターでの動作は保証しません)
- Android Studio 2021.2.1 以降
- WebRTC SFU Sora 2022.1 以降
- WebRTC SFU Sora 2022.1.1 以降

## サンプル

Expand Down
14 changes: 7 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ apply plugin: "org.ajoberstar.grgit"
apply plugin: 'org.jetbrains.dokka'

buildscript {
ext.kotlin_version = '1.6.10'
ext.libwebrtc_version = '103.5060.4.0'
ext.kotlin_version = '1.7.10'
ext.libwebrtc_version = '105.5195.0.0'

ext.dokka_version = '1.6.10'
ext.dokka_version = '1.7.10'

repositories {
google()
Expand All @@ -15,14 +15,14 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:7.0.4'
classpath 'com.android.tools.build:gradle:7.2.2'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}"
classpath 'org.ajoberstar.grgit:grgit-gradle:4.1.1'
classpath 'org.ajoberstar.grgit:grgit-gradle:5.0.0'

classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
classpath "com.github.ben-manes:gradle-versions-plugin:0.41.0"
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.2.1"
classpath "com.github.ben-manes:gradle-versions-plugin:0.42.0"
classpath "org.jlleitschuh.gradle:ktlint-gradle:10.3.0"
}
}

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
14 changes: 7 additions & 7 deletions sora-android-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ apply plugin: 'org.jlleitschuh.gradle.ktlint'
group = 'com.github.shiguredo'

android {
compileSdkVersion 30
compileSdkVersion 32

defaultConfig {
minSdkVersion 21
targetSdkVersion 30
targetSdkVersion 32

buildConfigField("String", "VERSION_NAME", "\"${grgit.describe()}\"")
buildConfigField("String", "REVISION", "\"${grgit.head().abbreviatedId}\"")
Expand Down Expand Up @@ -71,7 +71,7 @@ dokkaHtml.configure {
}

ktlint {
version = "0.43.2"
version = "0.45.2"
android = false
outputToConsole = true
reporters {
Expand All @@ -86,9 +86,9 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}"

// required by "signaling" part
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

// required by "rtc" part
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Expand All @@ -97,7 +97,7 @@ dependencies {

testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test:core:1.4.0'
testImplementation('org.robolectric:robolectric:4.7.3') {
testImplementation('org.robolectric:robolectric:4.8.1') {
exclude group: 'com.google.auto.service', module: 'auto-service'
}
testImplementation "org.jetbrains.kotlin:kotlin-test-junit:${kotlin_version}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class CameraCapturerFactory {
private fun createCapturer(enumerator: CameraEnumerator, frontFacingFirst: Boolean): CameraVideoCapturer? {
var capturer: CameraVideoCapturer? = null
enumerator.deviceNames.forEach {
deviceName ->
deviceName ->
if (capturer == null) {
capturer = findDeviceCamera(enumerator, deviceName, frontFacingFirst)
}
Expand All @@ -81,7 +81,7 @@ class CameraCapturerFactory {
return capturer
}
enumerator.deviceNames.forEach {
deviceName ->
deviceName ->
if (capturer == null) {
capturer = findDeviceCamera(enumerator, deviceName, !frontFacingFirst)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,8 @@ class SoraMediaChannel @JvmOverloads constructor(
|signalingMetadata = ${this.signalingMetadata}
|clientId = ${this.clientId}
|bundleId = ${this.bundleId}
|signalingNotifyMetadata = ${this.signalingNotifyMetadata}""".trimMargin()
|signalingNotifyMetadata = ${this.signalingNotifyMetadata}
""".trimMargin()
)

if (closing) {
Expand Down Expand Up @@ -819,7 +820,7 @@ class SoraMediaChannel @JvmOverloads constructor(
},
onError = {
val msg = "[channel:$role] failure in handleInitialOffer: ${it.message}"
SoraLogger.w(TAG, msg)
SoraLogger.w(TAG, msg, it)
disconnect(SoraDisconnectReason.SIGNALING_FAILURE)
}
)
Expand Down Expand Up @@ -967,7 +968,7 @@ class SoraMediaChannel @JvmOverloads constructor(
}

private fun sendDisconnectIfNeeded(disconnectReason: SoraDisconnectReason) {
val state = peer?.connectionState() ?: null
val state = peer?.connectionState()
SoraLogger.d(
TAG,
"[channel:$role] sendDisconnectIfNeeded switched=$switchedToDataChannel, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,8 @@ class PeerChannelImpl(
private val localAudioManager = componentFactory.createAudioManager()
private val localVideoManager = componentFactory.createVideoManager()

private var localStream: MediaStream? = null

private var videoSender: RtpSender? = null
private var audioSender: RtpSender? = null
private val localStreamId: String = UUID.randomUUID().toString()

// offer.data_channels の {label:..., compress:...} から compress が true の label リストを作る
private var compressLabels: List<String> = emptyList()
Expand Down Expand Up @@ -316,17 +314,26 @@ class PeerChannelImpl(
}
return@flatMap createAnswer()
}.flatMap {
answer ->
answer ->
return@flatMap setLocalDescription(answer)
}
}

private fun setTrack(mid: String, track: MediaStreamTrack): RtpSender {
val transceiver = this.conn?.transceivers?.find { it.mid == mid }
val sender = transceiver!!.sender
transceiver!!.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY
sender!!.streams = listOf(localStreamId)
sender!!.setTrack(track, false)
SoraLogger.d(TAG, "set ${track.kind()} sender: mid=$mid, transceiver=$transceiver")
return sender
}

override fun handleInitialRemoteOffer(
offer: String,
mid: Map<String, String>?,
encodings: List<Encoding>?
): Single<SessionDescription> {

val offerSDP = SessionDescription(SessionDescription.Type.OFFER, offer)
offerEncodings = encodings

Expand All @@ -337,51 +344,29 @@ class PeerChannelImpl(
// libwebrtc のバグにより simulcast の場合 setRD -> addTrack の順序を取る必要がある。
// simulcast can not reuse transceiver when setRemoteDescription is called after addTrack
// https://bugs.chromium.org/p/chromium/issues/detail?id=944821
val mediaStreamLabels = listOf(localStream!!.id)

val audioMid = mid?.get("audio")
if (audioMid != null) {
val transceiver = this.conn?.transceivers?.find { it.mid == audioMid }
transceiver?.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY
SoraLogger.d(TAG, "set audio sender: mid=$audioMid, transceiver=$transceiver")
audioSender = transceiver?.sender
audioSender?.streams = listOf(localStream!!.id)

localStream!!.audioTracks.firstOrNull()?.let {
SoraLogger.d(TAG, "set audio track: track=$it, enabled=${it.enabled()}")
audioSender?.setTrack(it, false)
}
} else {
audioSender = localStream!!.audioTracks.firstOrNull()?.let {
conn?.addTrack(it, mediaStreamLabels)
}
}

val videoMid = mid?.get("video")
if (videoMid != null) {
val transceiver = this.conn?.transceivers?.find { it.mid == videoMid }
transceiver?.direction = RtpTransceiver.RtpTransceiverDirection.SEND_ONLY
SoraLogger.d(TAG, "set video sender: mid=$mid, transceiver=$transceiver ")
videoSender = transceiver?.sender
videoSender?.streams = listOf(localStream!!.id)

localStream!!.videoTracks.firstOrNull()?.let {
SoraLogger.d(TAG, "set video track: track=$it, enabled=${it.enabled()}")
videoSender?.setTrack(it, false)
// 問題が発生したら reactivex の onError で捕まえられるので、 force unwrap している
// setTrack 内も同様
mid?.get("audio")?.let { mid ->
localAudioManager.track?.let { track ->
setTrack(mid, track)
}
} else {
videoSender = localStream!!.videoTracks.firstOrNull()?.let {
conn?.addTrack(it, mediaStreamLabels)
} ?: SoraLogger.d(TAG, "mid for audio not found")

mid?.get("video")?.let { mid ->
localVideoManager?.track?.let { track ->
videoSender = setTrack(mid, track)
}
}
} ?: SoraLogger.d(TAG, "mid for video not found")

if (mediaOption.simulcastEnabled && mediaOption.videoUpstreamEnabled) {
videoSender?.let { updateSenderOfferEncodings(it) }
}

SoraLogger.d(TAG, "createAnswer")
return@flatMap createAnswer()
}.flatMap {
answer ->
answer ->
SoraLogger.d(TAG, "setLocalDescription")
return@flatMap setLocalDescription(answer)
}
Expand Down Expand Up @@ -489,22 +474,23 @@ class PeerChannelImpl(
dependencies
)

val localStream = factory!!.createLocalMediaStream(localStreamId)

SoraLogger.d(TAG, "local managers' initTrack: audio")
localAudioManager.initTrack(factory!!, mediaOption.audioOption)
localAudioManager.track?.let {
localStream.addTrack(it)
}

SoraLogger.d(TAG, "local managers' initTrack: video => ${mediaOption.videoUpstreamContext}")
localVideoManager.initTrack(factory!!, mediaOption.videoUpstreamContext, appContext)

SoraLogger.d(TAG, "setup local media stream")
val streamId = UUID.randomUUID().toString()
localStream = factory!!.createLocalMediaStream(streamId)
localVideoManager?.initTrack(factory!!, mediaOption.videoUpstreamContext, appContext)
localVideoManager?.track?.let {
localStream.addTrack(it)
}

localAudioManager.attachTrackToStream(localStream!!)
localVideoManager.attachTrackToStream(localStream!!)
SoraLogger.d(TAG, "attached video sender => $videoSender")
SoraLogger.d(TAG, "localStream.audioTracks.size = ${localStream.audioTracks.size}")
SoraLogger.d(TAG, "localStream.videoTracks.size = ${localStream.videoTracks.size}")

SoraLogger.d(TAG, "localStream.audioTracks.size = ${localStream!!.audioTracks.size}")
SoraLogger.d(TAG, "localStream.videoTracks.size = ${localStream!!.videoTracks.size}")
listener?.onAddLocalStream(localStream!!)
}

Expand Down Expand Up @@ -572,7 +558,8 @@ class PeerChannelImpl(
SoraLogger.d(
TAG,
"""createAnswer:onCreateSuccess: ${sdp!!.type}
|${sdp.description}""".trimMargin()
|${sdp.description}
""".trimMargin()
)
it.onSuccess(sdp)
}
Expand Down Expand Up @@ -653,7 +640,7 @@ class PeerChannelImpl(
conn?.dispose()
conn = null
localAudioManager.dispose()
localVideoManager.dispose()
localVideoManager?.dispose()
SoraLogger.d(TAG, "dispose peer connection factory")
factory?.dispose()
factory = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import jp.shiguredo.sora.sdk.util.SoraLogger
import org.webrtc.DefaultVideoDecoderFactory
import org.webrtc.MediaConstraints
import org.webrtc.PeerConnectionFactory
import org.webrtc.SoftwareVideoDecoderFactory
import org.webrtc.SoftwareVideoEncoderFactory
import org.webrtc.audio.AudioDeviceModule
import org.webrtc.audio.JavaAudioDeviceModule

Expand Down Expand Up @@ -55,8 +53,10 @@ class RTCComponentFactory(
resolutionAdjustment = mediaOption.hardwareVideoEncoderResolutionAdjustment,
)
else ->
// context が指定されていなければソフトウェアエンコーダーを使用する
SoftwareVideoEncoderFactory()
SoraDefaultVideoEncoderFactory(
null,
resolutionAdjustment = mediaOption.hardwareVideoEncoderResolutionAdjustment,
)
}

SoraLogger.d(TAG, "videoDecoderFactory => ${mediaOption.videoDecoderFactory}")
Expand All @@ -67,7 +67,7 @@ class RTCComponentFactory(
mediaOption.videoDownstreamContext != null ->
DefaultVideoDecoderFactory(mediaOption.videoDownstreamContext)
else ->
SoftwareVideoDecoderFactory()
DefaultVideoDecoderFactory(null)
}

SoraLogger.d(TAG, "decoderFactory => $decoderFactory")
Expand Down Expand Up @@ -104,12 +104,12 @@ class RTCComponentFactory(
return constraints
}

fun createVideoManager(): RTCLocalVideoManager {
val videoManager = mediaOption.videoCapturer?.let {
RTCLocalVideoManagerImpl(it)
} ?: RTCNullLocalVideoManager()
SoraLogger.d(TAG, "videoManager created: $videoManager")
return videoManager
fun createVideoManager(): RTCLocalVideoManager? {
return mediaOption.videoCapturer?.let {
val videoManager = RTCLocalVideoManager(it)
SoraLogger.d(TAG, "videoManager created: $videoManager")
videoManager
}
}

fun createAudioManager(): RTCLocalAudioManager {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import jp.shiguredo.sora.sdk.util.SoraLogger
import org.webrtc.AudioSource
import org.webrtc.AudioTrack
import org.webrtc.MediaConstraints
import org.webrtc.MediaStream
import org.webrtc.PeerConnectionFactory
import java.util.UUID

Expand All @@ -18,7 +17,7 @@ class RTCLocalAudioManager(
}

private var source: AudioSource? = null
private var track: AudioTrack? = null
var track: AudioTrack? = null

fun initTrack(factory: PeerConnectionFactory, audioOption: SoraAudioOption) {
SoraLogger.d(TAG, "initTrack: send=$send")
Expand All @@ -28,7 +27,7 @@ class RTCLocalAudioManager(
SoraLogger.d(TAG, "audio source created: $source")
val trackId = UUID.randomUUID().toString()
track = factory.createAudioTrack(trackId, source)
track!!.setEnabled(true)
track?.setEnabled(true)
SoraLogger.d(TAG, "audio track created: $track")
}
}
Expand Down Expand Up @@ -58,12 +57,6 @@ class RTCLocalAudioManager(
return constraints
}

fun attachTrackToStream(stream: MediaStream) {
if (send) {
track?.let { stream.addTrack(it) }
}
}

fun dispose() {
SoraLogger.d(TAG, "dispose")
source?.dispose()
Expand Down
Loading

0 comments on commit 0795615

Please sign in to comment.