Dana
2025-12-03 2d6583bf4c23cbb6209b01c0c6b27a7d3d87560b
1.startTransFileMitter  可以传目录所有的文件
1个文件已修改
125 ■■■■ 已修改文件
app/src/main/java/com/anyun/h264/MainActivity.kt 125 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/anyun/h264/MainActivity.kt
@@ -1,6 +1,8 @@
package com.anyun.h264
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -11,6 +13,7 @@
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.anyun.h264.H264FileTransmitter.OnTransmitProgressCallback
import com.anyun.h264.ui.theme.MyApplicationTheme
import timber.log.Timber
import java.io.File
@@ -18,6 +21,9 @@
class MainActivity : ComponentActivity() {
    private var h264Encoder: H264Encoder? = null
    private var transmitter: H264FileTransmitter? = null
    private var fileList: List<File> = emptyList()
    private var currentFileIndex: Int = 0
    private val handler = Handler(Looper.getMainLooper())
    companion object{
        const val TAG ="MainActivity"
    }
@@ -34,13 +40,14 @@
                        modifier = Modifier.padding(innerPadding),
                        isRunning = isRunning,
                        onStartH264Click = {
                            val success = startH264Encoder()
                            val success = startFileTransmitter()
                            if (success) {
                                isRunning = true
                            }
                        },
                        onStopH264Click = {
                            stopH264Encoder()
//                            stopH264Encoder()
                            stopFileTransmitter()
                            isRunning = false
                        }
                    )
@@ -52,16 +59,37 @@
    override fun onDestroy() {
        super.onDestroy()
        stopH264Encoder()
        stopFileTransmitter()
    }
    private fun startFileTransmitter():Boolean {
        if (transmitter != null) {
            Timber.w("H264Encoder is already running")
            Timber.w("FileTransmitter is already running")
            return false
        }
        // 获取目录中的所有 .h264 文件
        val directory = application.applicationContext.getExternalFilesDir(null)
        Timber.i("视频目录=${directory?.absolutePath}")
        if (directory?.isDirectory != true) {
            Timber.e("Directory is not valid: ${directory?.absolutePath}")
            return false
        }
        // 获取所有 .h264 文件并按文件名排序
        fileList = directory.listFiles()
            ?.filter { it.isFile && it.name.endsWith(".h264", ignoreCase = true) }
            ?.sortedBy { it.name }
            ?: emptyList()
        if (fileList.isEmpty()) {
            Timber.w("No .h264 files found in directory")
            return false
        }
        Timber.i("Found ${fileList.size} .h264 files to transmit")
        currentFileIndex = 0
        try {
            transmitter = H264FileTransmitter()
@@ -69,28 +97,99 @@
            transmitter?.setServerAddress("192.168.16.138", 1078)
            transmitter?.setProtocolType(JT1076ProtocolHelper.PROTOCOL_TYPE_TCP) // 或 PROTOCOL_TYPE_UDP
            // 设置协议参数
            transmitter?.setProtocolParams("013120122580", 1.toByte())
            // 设置帧率(用于计算时间戳间隔)
            transmitter?.setFrameRate(25)
            transmitter?.setOnTransmitProgressCallback(object : OnTransmitProgressCallback {
                override fun onProgress(currentFrame: Int, totalFrames: Int) {
                    val currentFile = if (currentFileIndex < fileList.size) fileList[currentFileIndex] else null
                    Timber.d("Transmitting file ${currentFileIndex + 1}/${fileList.size}: ${currentFile?.name}, frame: $currentFrame")
                }
                override fun onComplete() {
                    val currentFile = if (currentFileIndex < fileList.size) fileList[currentFileIndex] else null
                    Timber.i("File transmission complete: ${currentFile?.name} (${currentFileIndex + 1}/${fileList.size})")
                    // 使用 Handler 延迟调用,确保前一个文件的传输状态已重置
                    currentFileIndex++
                    handler.postDelayed({
                        transmitNextFile()
                    }, 100) // 延迟100ms,确保前一个文件的 finally 块已执行
                }
                override fun onError(error: String?) {
                    val currentFile = if (currentFileIndex < fileList.size) fileList[currentFileIndex] else null
                    Timber.e("File transmission error: ${currentFile?.name}, error: $error")
                    // 即使出错也继续传输下一个文件
                    // 使用 Handler 延迟调用,确保前一个文件的传输状态已重置
                    currentFileIndex++
                    handler.postDelayed({
                        transmitNextFile()
                    }, 100) // 延迟100ms,确保前一个文件的 finally 块已执行
                }
            })
            // 初始化Socket
            if (transmitter?.initialize()==true) {
                // 开始传输文件
                transmitter?.transmitFile("/storage/emulated/0/Android/data/com.anyun.h264/files/h264_1764574451071.h264")
            if (transmitter?.initialize() == true) {
                // 开始传输第一个文件
                transmitNextFile()
                return true
            }else{
            } else {
                Timber.e("Failed to initialize transmitter")
                transmitter = null
                return false
            }
        } catch (e: Exception) {
            Timber.e(e, "Failed to start H264Encoder")
            Timber.e(e, "Failed to start FileTransmitter")
            transmitter = null
            return false
        }
    }
    /**
     * 传输下一个文件
     */
    private fun transmitNextFile() {
        if (transmitter == null) {
            Timber.w("Transmitter is null, cannot transmit next file")
            return
        }
        if (currentFileIndex >= fileList.size) {
            Timber.i("All files transmission complete! Total: ${fileList.size} files")
            // 所有文件传输完成,停止传输器
            stopFileTransmitter()
            return
        }
        val nextFile = fileList[currentFileIndex]
        Timber.i("Starting transmission of file ${currentFileIndex + 1}/${fileList.size}: ${nextFile.name}")
        // 传输下一个文件
        transmitter?.transmitFile(nextFile.absolutePath)
    }
    /**
     * 停止文件传输器
     */
    private fun stopFileTransmitter() {
        // 移除所有待处理的 Handler 任务
        handler.removeCallbacksAndMessages(null)
        transmitter?.let { tx ->
            try {
                tx.stop()
                Timber.d("FileTransmitter stopped")
            } catch (e: Exception) {
                Timber.e(e, "Failed to stop FileTransmitter")
            }
        }
        transmitter = null
        fileList = emptyList()
        currentFileIndex = 0
    }
    private fun startH264Encoder(): Boolean {
@@ -109,11 +208,11 @@
            // 设置输出文件(可选)
            val outputFile = File(getExternalFilesDir(null), "test2.h264")
            h264Encoder?.setOutputFile(outputFile.absolutePath)
            h264Encoder?.setEnableFileOutput(false) // 启用文件输出
            h264Encoder?.setEnableFileOutput(true) // 启用文件输出
            // 设置UDP服务器地址(可选)
//             h264Encoder?.setServerAddress("58.48.93.67", 11935)
            h264Encoder?.setEnableNetworkTransmission(true)
            h264Encoder?.setEnableNetworkTransmission(false)
            h264Encoder?.setServerAddress("192.168.16.138", 1078)
            h264Encoder?.setProtocolParams("013120122580", 1)