もくもく会の結果
とりあえず30分くらいで映像通信はできたのでシェアします。
準備
AndroidManifest.xmlをいじる
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="santapj.co.jp.santa">
<!-- ここから -->
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- ここまでを追加 -->
<application
....
</application>
</manifest>
skyway.arrを設定

ここに置いてModuleのgradleを
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
android {
compileSdkVersion 26
buildToolsVersion "26.0.2"
defaultConfig {
applicationId "santapj.co.jp.santa"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
compile (name:'skyway',ext:'aar')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
}
repositories{
flatDir{
dirs 'libs'
}
mavenCentral()
}
こうじゃ。graldeでリポジトリ指定してimportできなかったけど、きっと何か事情あるんだろう。
実装
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="santapj.co.jp.santa.MainActivity">
<view
android:layout_width="140dp"
android:layout_height="140dp"
class="io.skyway.Peer.Browser.Canvas"
android:id="@+id/remoteStreamView" />
<view
android:layout_width="140dp"
android:layout_height="140dp"
class="io.skyway.Peer.Browser.Canvas"
android:id="@+id/localStreamView" />
</LinearLayout>
MainActivity.kt
package santapj.co.jp.santa
import android.content.pm.PackageManager
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import io.skyway.Peer.Browser.Canvas
import io.skyway.Peer.Peer
class MainActivity : AppCompatActivity() {
lateinit var viewModel:ViewModel
lateinit var localStreamView:Canvas
lateinit var remoteStreamView:Canvas
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
localStreamView = findViewById(R.id.localStreamView) as Canvas
remoteStreamView = findViewById(R.id.remoteStreamView) as Canvas
viewModel = ViewModel(this, localStreamView, remoteStreamView)
viewModel.setup()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
0 -> {
if (grantResults.count() > 0 && grantResults[0] === PackageManager.PERMISSION_GRANTED) {
viewModel.setupPeer()
} else {
print("Error")
}
}
}
}
}
viewModel.kt
package santapj.co.jp.santa
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.util.Log
import io.skyway.Peer.Browser.Canvas
import io.skyway.Peer.Browser.MediaConstraints
import io.skyway.Peer.Browser.MediaStream
import io.skyway.Peer.Browser.Navigator
import io.skyway.Peer.MediaConnection
import io.skyway.Peer.OnCallback
import io.skyway.Peer.Peer
import io.skyway.Peer.PeerOption
/**
* Created by kentaro.haneda on 2017/12/06.
*/
class ViewModel (val activity: MainActivity, val localStreamView:Canvas, val remoteStreamView:Canvas){
companion object {
val API_KEY = "XXXXXX"
val DOMAIN = "XXXXXX"
}
var peer:Peer? = null
var remoteStream:MediaStream? = null
var localStream:MediaStream? = null
var mediaConnection:MediaConnection? = null
fun setup(){
checkPermission()
}
fun setupPeer(){
val option = PeerOption()
option.key = API_KEY
option.domain = DOMAIN
option.debug = Peer.DebugLevelEnum.ALL_LOGS
this.peer = Peer(activity, option)
this.setupPeerCallBack()
}
private fun setupPeerCallBack(){
this.peer?.on(Peer.PeerEventEnum.OPEN, object : OnCallback {
override fun onCallback(p0: Any?) {
(p0 as? String)?.let{
peerID ->
Log.d("debug", "peerID: ${peerID}")
startLocalStream()
}
}
})
this.peer?.on(Peer.PeerEventEnum.ERROR, object : OnCallback {
override fun onCallback(p0: Any?) {
Log.d("debug", "peer error ${p0}")
}
})
this.peer?.on(Peer.PeerEventEnum.CALL, object : OnCallback {
override fun onCallback(p0: Any?) {
(p0 as? MediaConnection)?.let{
this@ViewModel.mediaConnection = it
this@ViewModel.setupMediaCallBack()
this@ViewModel.mediaConnection?.answer(localStream)
}
}
})
}
private fun checkPermission(){
if (ContextCompat.checkSelfPermission(activity,
Manifest.permission.CAMERA) !== PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(activity,
Manifest.permission.RECORD_AUDIO) !== PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, arrayOf<String>(Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO), 0)
} else {
this.setupPeer()
}
}
private fun startLocalStream(){
val constraints = MediaConstraints()
constraints.maxWidth = 960
constraints.maxHeight = 540
constraints.cameraPosition = MediaConstraints.CameraPositionEnum.FRONT
Navigator.initialize(peer)
localStream = Navigator.getUserMedia(constraints)
localStream?.addVideoRenderer(localStreamView, 0)
}
fun setupMediaCallBack(){
mediaConnection?.on(MediaConnection.MediaEventEnum.STREAM, object : OnCallback {
override fun onCallback(p0: Any?) {
(p0 as? MediaStream)?.let{
this@ViewModel.remoteStream = it
this@ViewModel.remoteStream?.addVideoRenderer(remoteStreamView, 0)
}
}
})
}
}
でとりあえず動く。イカしたサンプルは後日こちらへプルリク投げナス