Dana
2025-12-23 bfc959385fd59284fca3e417af217d02d80cb845
app/src/main/java/com/anyun/h264/H264EncodeService2.java
@@ -8,6 +8,7 @@
import com.anyun.h264.model.ResourceInfo;
import com.anyun.h264.model.WatermarkInfo;
import com.anyun.h264.util.FileUtil;
import org.json.JSONException;
import org.json.JSONObject;
@@ -102,6 +103,7 @@
        int height;
        int framerate;
        String simPhone;
        boolean useTFCard = false; // 是否使用TF卡
        
        // 从JSON解析配置
        static EncodeConfig fromJson(String jsonConfig) throws JSONException {
@@ -114,6 +116,7 @@
                config.ip = null;
                config.port = 0;
                config.simPhone = null;
                config.useTFCard = false; // 默认不使用TF卡
                return config;
            }
            
@@ -124,6 +127,7 @@
            config.ip = json.optString("ip", null);
            config.port = json.optInt("port", 0);
            config.simPhone = json.optString("simPhone", null);
            config.useTFCard = json.optBoolean("useTFCard", false);
            
            return config;
        }
@@ -216,10 +220,61 @@
    }
    
    /**
     * 获取输出文件目录(根据useTFCard配置)
     * @param useTFCard 是否使用TF卡
     * @return 输出目录路径
     */
    private String getOutputFileDirectory(boolean useTFCard) {
        if (useTFCard) {
            // 使用TF卡:/sdcard/h264/当前日期/
            try {
                String storagePath = FileUtil.getStoragePath(this, true);
                if (storagePath == null || storagePath.trim().isEmpty()) {
                    Timber.w("TF card storage path not available, fallback to app directory (camera2)");
                    return outputFileDirectory;
                }
                File externalStorage = new File(storagePath);
                if (!externalStorage.exists()) {
                    Timber.w("TF card storage directory does not exist: %s, fallback to app directory (camera2)", storagePath);
                    return outputFileDirectory;
                }
                // 获取当前日期(格式:yyyyMMdd,如20250123)
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd", Locale.CHINA);
                String dateDir = dateFormat.format(new Date());
                // 构建路径:/sdcard/h264/20250123/
                File h264Dir = new File(externalStorage, "h264");
                File dateDirFile = new File(h264Dir, dateDir);
                // 创建目录(如果不存在)
                if (!dateDirFile.exists()) {
                    boolean created = dateDirFile.mkdirs();
                    if (!created && !dateDirFile.exists()) {
                        Timber.e("Failed to create TF card directory: %s, fallback to app directory (camera2)", dateDirFile.getAbsolutePath());
                        return outputFileDirectory;
                    }
                }
                String tfCardPath = dateDirFile.getAbsolutePath();
                Timber.d("Using TF card directory (camera2): %s", tfCardPath);
                return tfCardPath;
            } catch (Exception e) {
                Timber.e(e, "Error getting TF card directory, fallback to app directory (camera2)");
                return outputFileDirectory;
            }
        } else {
            // 使用应用外部存储目录
            return outputFileDirectory;
        }
    }
    /**
     * 启动文件编码模式(只写入文件,不进行网络推送)
     */
    private int startFileEncode(EncodeConfig config) {
        Timber.d("Starting file encode mode (camera2)");
        Timber.d("Starting file encode mode (camera2), useTFCard: %b", config != null ? config.useTFCard : false);
        
        // 如果编码器已经在运行,先停止
        if (h264Encoder != null) {
@@ -238,9 +293,13 @@
            int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
            h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
            // 获取输出文件目录(根据useTFCard配置)
            boolean useTFCard = config != null && config.useTFCard;
            String outputDir = getOutputFileDirectory(useTFCard);
            // 设置输出文件目录(H264Encoder会自动管理文件创建,每分钟一个文件)
            // 使用一个临时文件名来设置目录,H264Encoder会在初始化时创建第一个文件
            File tempFile = new File(outputFileDirectory, "temp.h264");
            File tempFile = new File(outputDir, "temp.h264");
            h264Encoder.setOutputFile(tempFile.getAbsolutePath());
            h264Encoder.setEnableFileOutput(true); // 启用文件输出
            
@@ -299,9 +358,13 @@
            int framerate = config != null && config.framerate > 0 ? config.framerate : DEFAULT_FRAME_RATE;
            h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
            // 获取输出文件目录(根据useTFCard配置)
            boolean useTFCard = config != null && config.useTFCard;
            String outputDir = getOutputFileDirectory(useTFCard);
            // 设置输出文件目录(H264Encoder会自动管理文件创建,每分钟一个文件)
            // 使用一个临时文件名来设置目录,H264Encoder会在初始化时创建第一个文件
            File tempFile = new File(outputFileDirectory, "temp.h264");
            File tempFile = new File(outputDir, "temp.h264");
            h264Encoder.setOutputFile(tempFile.getAbsolutePath());
            h264Encoder.setEnableFileOutput(true); // 启用文件输出