open media state added

This commit is contained in:
2021-05-10 22:19:10 +03:00
parent 05c50e7acd
commit e5c0287f51
9 changed files with 81 additions and 38 deletions

View File

@@ -200,21 +200,25 @@ class HelloSurface : SurfaceView, SurfaceHolder.Callback {
}
}
fun render() {
persistentSurface?.let {
val pCanvas = it.lockCanvas(null)
clearCanvas(pCanvas)
synchronized(it) {
drawHello(pCanvas, _frameNumber)
persistentSurface?.let {surface ->
val pCanvas = surface.lockCanvas(null)
pCanvas?.let {
clearCanvas(it)
synchronized(surface) {
drawHello(it, _frameNumber)
}
surface.unlockCanvasAndPost(pCanvas)
}
it.unlockCanvasAndPost(pCanvas)
}
}
fun preview() {
val canvas = holder.lockCanvas()
clearCanvas(canvas)
drawHello(canvas, _frameNumber)
holder.unlockCanvasAndPost(canvas)
canvas?.let {
clearCanvas(it)
drawHello(it, _frameNumber)
holder.unlockCanvasAndPost(it)
}
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {

View File

@@ -12,10 +12,9 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Inspiry">
<activity android:name=".MainActivity">
<activity android:name=".ui.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

View File

@@ -0,0 +1,4 @@
package su.rst10h.inspiry
const val MEDIA_FOLDER = "test"
const val MEDIA_FILE_NAME = "TestVideo.mp4"

View File

@@ -2,5 +2,7 @@ package su.rst10h.inspiry.data
enum class ActivityState {
WAIT,
RENDER
RENDERING,
RENDERED,
OPEN_MEDIA
}

View File

@@ -7,6 +7,7 @@ import android.view.Surface
import su.rst10h.loopedworld.HelloSurface
import java.io.File
@Deprecated("Это тоже работает, но кривовато - нет синхронизации фреймов. Лучше использовать VideoEncoder")
class CanvasRecorder(private val helloSurface: HelloSurface, appPath: File) {
private var recorder: MediaRecorder

View File

@@ -8,6 +8,8 @@ import android.util.Log
import android.view.Surface
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import su.rst10h.inspiry.MEDIA_FILE_NAME
import su.rst10h.inspiry.MEDIA_FOLDER
import su.rst10h.loopedworld.HelloSurface
import java.io.File
@@ -15,8 +17,10 @@ class VideoEncoder(private val baseFileDir: File, private val helloSurface: Hell
private val bufferInfo = MediaCodec.BufferInfo()
private val mediaEncoder: MediaCodec
private val inputSurface: Surface
private lateinit var inputSurface: Surface
var onStopRecord = {}
init {
val format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1080, 1920)
format.setInteger(
@@ -31,11 +35,14 @@ class VideoEncoder(private val baseFileDir: File, private val helloSurface: Hell
inputSurface = mediaEncoder.createInputSurface()
}
private lateinit var mediaMuxer: MediaMuxer
private var muxerTrackIndex = -1
@Volatile var isRunning = false
fun startRender() {
muxerTrackIndex = -1
val file = File(prepareFilePath(baseFileDir))
if (!file.exists()) file.delete()
mediaMuxer = MediaMuxer(file.absolutePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
@@ -60,8 +67,7 @@ class VideoEncoder(private val baseFileDir: File, private val helloSurface: Hell
while (isRunning) {
val encoderStatus = mediaEncoder.dequeueOutputBuffer(bufferInfo, 10000L)
when(encoderStatus) {
MediaCodec.INFO_TRY_AGAIN_LATER -> {
}
MediaCodec.INFO_TRY_AGAIN_LATER -> { }
MediaCodec.INFO_OUTPUT_FORMAT_CHANGED -> {
Log.d("encoder", "start muxer $muxerTrackIndex")
val newFormat: MediaFormat = mediaEncoder.outputFormat
@@ -83,17 +89,20 @@ class VideoEncoder(private val baseFileDir: File, private val helloSurface: Hell
}
}
}
Log.d("encoder", "File closed")
Log.d("encoder","stop encoding")
mediaMuxer.stop()
mediaMuxer.release()
mediaEncoder.stop()
}
private fun prepareFilePath(appPath: File): String {
val fullPath = appPath.absolutePath+"/test/"
val fullPath = appPath.absolutePath+"/$MEDIA_FOLDER/"
if (!File(fullPath).exists()) {
if (!File(fullPath).mkdir()) {
Log.d("main", "directory test not created")
throw Exception("The test directory does not exist and has not been created:\n$fullPath$\n")
}
}
return fullPath+"TestVideoEncoder2.mp4"
return fullPath+MEDIA_FILE_NAME
}
}

View File

@@ -1,38 +1,50 @@
package su.rst10h.inspiry
package su.rst10h.inspiry.ui
import androidx.appcompat.app.AppCompatActivity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import su.rst10h.inspiry.MEDIA_FILE_NAME
import su.rst10h.inspiry.MEDIA_FOLDER
import su.rst10h.inspiry.R
import su.rst10h.inspiry.data.ActivityState
import su.rst10h.loopedworld.HelloSurface
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
setContentView(R.layout.activity_main)
val viewModel : MainViewModel by viewModels()
val btn = findViewById<Button>(R.id.button)
val surfaceView = findViewById<HelloSurface>(R.id.testView)
viewModel.state.observe(this,{
when(it) {
viewModel.state.observe(this, { state ->
when (state) {
ActivityState.WAIT -> {
Log.d("main", "record stopped")
btn.text = "Render Template"
btn.isEnabled = true
}
ActivityState.RENDER -> {
Log.d("main", "record started")
btn.text = "Rendering.."
ActivityState.RENDERING -> {
btn.text = "RENDERING.."
btn.isEnabled = false
}
ActivityState.RENDERED -> {
btn.isEnabled = true
btn.text = "OPEN MEDIA"
}
ActivityState.OPEN_MEDIA -> {
openMedia()
viewModel.reset_state()
}
}
})
@@ -41,7 +53,15 @@ class MainActivity : AppCompatActivity() {
}
btn.setOnClickListener {
viewModel.renderTemplate()
viewModel.action()
}
}
private fun openMedia() {
val intent = Intent(Intent.ACTION_VIEW)
intent.setDataAndType(Uri.parse(
getExternalFilesDir(null)?.absolutePath+
"/$MEDIA_FOLDER/$MEDIA_FILE_NAME"),
"video/mp4")
startActivity(intent)
}
}

View File

@@ -1,11 +1,9 @@
package su.rst10h.inspiry
package su.rst10h.inspiry.ui
import android.graphics.Canvas
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import su.rst10h.inspiry.data.*
import su.rst10h.inspiry.data.ActivityState.*
import su.rst10h.inspiry.repository.CanvasRecorder
import su.rst10h.inspiry.repository.VideoEncoder
import su.rst10h.loopedworld.HelloSurface
import java.io.File
@@ -23,18 +21,24 @@ class MainViewModel: ViewModel() {
videoEncoder = VideoEncoder(appPath, surface)
}
fun renderTemplate() {
fun reset_state() {
state.postValue(WAIT)
}
fun action() {
when (state.value) {
WAIT -> {
videoEncoder.onStopRecord = {
state.postValue(WAIT)
state.postValue(RENDERED)
}
videoEncoder.startRender()
state.postValue(RENDER)
state.postValue(RENDERING)
}
RENDER -> {
state.postValue(WAIT)
RENDERED -> {
state.postValue(OPEN_MEDIA)
}
}
}

View File

@@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
tools:context=".ui.MainActivity">
<su.rst10h.loopedworld.HelloSurface
android:id="@+id/testView"