Dana
2025-12-01 3d3db1ddbf227749c2de72856669171a9345937e
1.h264Encoder加上 日志写入文件
2.返回文件列表修改
2个文件已修改
105 ■■■■■ 已修改文件
app/src/main/java/com/anyun/h264/H264EncodeService.java 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/anyun/h264/H264Encoder.java 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/anyun/h264/H264EncodeService.java
@@ -536,12 +536,33 @@
     */
    private ResourceInfo createResourceInfoFromFile(File file, Date startDate, Date endDate) {
        try {
            // 从文件名或文件修改时间获取文件时间
            // 这里假设文件名包含时间戳,或者使用文件修改时间
            Date fileDate = new Date(file.lastModified());
            // 从文件名中提取时间戳(格式:h264_1234567890123.h264)
            String fileName = file.getName();
            Date startTimeFromFileName = null;
            if (fileName.startsWith("h264_") && fileName.endsWith(".h264")) {
                try {
                    // 提取文件名中的时间戳(h264_ 和 .h264 之间的部分)
                    String timestampStr = fileName.substring(5, fileName.length() - 5); // 去掉 "h264_" 和 ".h264"
                    long timestamp = Long.parseLong(timestampStr);
                    startTimeFromFileName = new Date(timestamp);
                } catch (NumberFormatException e) {
                    Timber.w("Failed to parse timestamp from filename: %s", fileName);
                }
            }
            // 如果无法从文件名解析时间戳,则使用文件修改时间作为开始时间
            if (startTimeFromFileName == null) {
                startTimeFromFileName = new Date(file.lastModified());
            }
            // 结束时间使用文件修改时间
            Date endTimeFromFile = new Date(file.lastModified());
            
            // 检查文件时间是否在指定范围内
            if (fileDate.before(startDate) || fileDate.after(endDate)) {
            // 开始时间应该 >= startDate,结束时间应该 <= endDate
            // 如果文件的开始时间在范围内,或者结束时间在范围内,或者文件时间范围包含查询范围,则包含该文件
            if (startTimeFromFileName.after(endDate) || endTimeFromFile.before(startDate)) {
                return null; // 不在时间范围内
            }
            
@@ -551,13 +572,12 @@
            // 逻辑通道号(默认值,实际应从配置获取)
            resourceInfo.setLogicalChannelNumber((byte) 1);
            
            // 开始时间和结束时间(使用文件修改时间)
            // 开始时间:从文件名中的时间戳
            SimpleDateFormat bcdFormat = new SimpleDateFormat("yyMMddHHmmss", Locale.CHINA);
            resourceInfo.setStartTime(bcdFormat.format(fileDate));
            // 结束时间可以使用文件修改时间加上一个默认时长(例如1分钟)
            long fileDuration = 60000; // 默认1分钟,实际应该根据文件内容计算
            Date endTime = new Date(fileDate.getTime() + fileDuration);
            resourceInfo.setEndTime(bcdFormat.format(endTime));
            resourceInfo.setStartTime(bcdFormat.format(startTimeFromFileName));
            // 结束时间:使用文件修改时间
            resourceInfo.setEndTime(bcdFormat.format(endTimeFromFile));
            
            // 报警标志(默认值,实际应从文件元数据获取)
            resourceInfo.setAlarmFlag(0L);
app/src/main/java/com/anyun/h264/H264Encoder.java
@@ -3,7 +3,6 @@
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import com.anyun.libusbcamera.UsbCamera;
import java.io.File;
@@ -12,6 +11,8 @@
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import timber.log.Timber;
/**
 * H264视频编码器
@@ -143,7 +144,7 @@
     */
    public void setEnableNetworkTransmission(boolean enable) {
        this.enableNetworkTransmission = enable;
        Log.d(TAG, "Network transmission " + (enable ? "enabled" : "disabled"));
        Timber.d("Network transmission " + (enable ? "enabled" : "disabled"));
    }
    /**
@@ -167,27 +168,27 @@
                if (result == 0) {
                    // 成功,跳出循环
                    if (attempt > 0) {
                        Log.d(TAG, "prepareCamera succeeded on attempt " + (attempt + 1));
                        Timber.d("prepareCamera succeeded on attempt " + (attempt + 1));
                    }
                    break;
                } else {
                    // 失败,记录日志
                    Log.w(TAG, "prepareCamera failed on attempt " + (attempt + 1) + ": " + result);
                    Timber.w( "prepareCamera failed on attempt " + (attempt + 1) + ": " + result);
                    if (attempt < maxRetries - 1) {
                        Log.d(TAG, "Retrying prepareCamera...");
                        Timber.d( "Retrying prepareCamera...");
                    }
                }
            }
            if (result != 0) {
                Log.e(TAG, "prepareCamera failed after " + maxRetries + " attempts: " + result);
                Timber.e("prepareCamera failed after " + maxRetries + " attempts: " + result);
                return false;
            }
            // 更新实际分辨率
            width = actualResolution[0];
            height = actualResolution[1];
            Log.d(TAG, "Camera initialized with resolution: " + width + "x" + height);
            Timber.d("Camera initialized with resolution: " + width + "x" + height);
            // 3. 初始化H264编码器
            initEncoder();
@@ -199,19 +200,19 @@
                    return false;
                }
            } else {
                Log.d(TAG, "Network transmission disabled, skipping socket initialization");
                Timber.d("Network transmission disabled, skipping socket initialization");
            }
            // 5. 初始化文件输出(仅创建文件,SPS/PPS在第一次输出时写入)
            if (enableFileOutput && outputFilePath != null && !outputFilePath.isEmpty()) {
                if (!initFileOutput()) {
                    Log.w(TAG, "File output initialization failed, continuing without file output");
                    Timber.w("File output initialization failed, continuing without file output");
                }
            }
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Initialize failed", e);
            Timber.e(e,"Initialize failed");
            return false;
        }
    }
@@ -230,7 +231,7 @@
        encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
        encoder.start();
        Log.d(TAG, "H264 encoder initialized");
        Timber.d( "H264 encoder initialized");
    }
    /**
@@ -244,7 +245,7 @@
            if (parentDir != null && !parentDir.exists()) {
                boolean created = parentDir.mkdirs();
                if (!created && !parentDir.exists()) {
                    Log.e(TAG, "Failed to create parent directory: " + parentDir.getAbsolutePath());
                    Timber.e("Failed to create parent directory: " + parentDir.getAbsolutePath());
                    return false;
                }
            }
@@ -252,15 +253,15 @@
            fileOutputStream = new FileOutputStream(file);
            spsPpsWritten = false;
            Log.d(TAG, "File output initialized: " + outputFilePath);
            Timber.d("File output initialized: " + outputFilePath);
            return true;
        } catch (Exception e) {
            Log.e(TAG, "Initialize file output failed", e);
            Timber.e(e,"Initialize file output failed");
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException ie) {
                    Log.e(TAG, "Close file output stream failed", ie);
                    Timber.e(ie, "Close file output stream failed");
                }
                fileOutputStream = null;
            }
@@ -321,12 +322,12 @@
                fileOutputStream.flush();
                spsPpsWritten = true;
                Log.d(TAG, "SPS/PPS written to file, SPS size: " + spsLength + ", PPS size: " + ppsLength);
                Timber.d("SPS/PPS written to file, SPS size: " + spsLength + ", PPS size: " + ppsLength);
            } else {
                Log.w(TAG, "SPS/PPS not found in CSD, will extract from first key frame");
                Timber.w("SPS/PPS not found in CSD, will extract from first key frame");
            }
        } catch (Exception e) {
            Log.e(TAG, "Write SPS/PPS to file error", e);
            Timber.e(e,"Write SPS/PPS to file error");
        }
    }
@@ -335,7 +336,7 @@
     */
    public void start() {
        if (isRunning.get()) {
            Log.w(TAG, "Encoder is already running");
            Timber.w("Encoder is already running");
            return;
        }
@@ -350,7 +351,7 @@
        });
        encodeThread.start();
        Log.d(TAG, "H264 encoder started");
        Timber.d("H264 encoder started");
    }
    /**
@@ -371,7 +372,7 @@
                // processCamera - 读取一帧
                int processResult = usbCamera.processCamera();
                if (processResult != 0) {
                    Log.w(TAG, "processCamera returned: " + processResult);
                    Timber.w("processCamera returned: " + processResult);
                    Thread.sleep(10);
                    continue;
                }
@@ -384,7 +385,7 @@
                encodeFrame(nv12ToNV21(yuvBuffer,width,height), timestamp, bufferInfo);
            } catch (Exception e) {
                Log.e(TAG, "Encode loop error", e);
                Timber.e(e, "Encode loop error");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ie) {
@@ -393,7 +394,7 @@
            }
        }
        Log.d(TAG, "Encode loop exited");
        Timber.d( "Encode loop exited");
    }
    /**
@@ -441,7 +442,7 @@
            }
        } catch (Exception e) {
            Log.e(TAG, "Encode frame error", e);
            Timber.e(e,"Encode frame error");
        }
    }
@@ -462,7 +463,7 @@
                // MediaCodec输出的关键帧通常已经包含SPS/PPS,但为了确保文件完整性,
                // 我们已经从CSD写入,这里直接写入关键帧数据即可
                if (!spsPpsWritten) {
                    Log.d(TAG, "SPS/PPS will be included in key frame data");
                    Timber.d("SPS/PPS will be included in key frame data");
                }
            }
@@ -471,7 +472,7 @@
            fileOutputStream.write(data);
            fileOutputStream.flush();
        } catch (IOException e) {
            Log.e(TAG, "Write to file error", e);
            Timber.e(e, "Write to file error");
        }
    }
@@ -531,7 +532,7 @@
            }
        } catch (Exception e) {
            Log.e(TAG, "Send encoded data error", e);
            Timber.e(e,"Send encoded data error");
        }
    }
@@ -550,7 +551,7 @@
            try {
                encodeThread.join(2000);
            } catch (InterruptedException e) {
                Log.e(TAG, "Wait encode thread error", e);
                Timber.e(e, "Wait encode thread error");
            }
        }
@@ -566,7 +567,7 @@
                encoder.release();
                encoder = null;
            } catch (Exception e) {
                Log.e(TAG, "Release encoder error", e);
                Timber.e(e, "Release encoder error");
            }
        }
@@ -579,7 +580,7 @@
        // 关闭文件输出
        closeFileOutput();
        Log.d(TAG, "H264 encoder stopped");
        Timber.d("H264 encoder stopped");
    }
    /**
@@ -590,9 +591,9 @@
            try {
                fileOutputStream.flush();
                fileOutputStream.close();
                Log.d(TAG, "File output closed: " + outputFilePath);
                Timber.d("File output closed: " + outputFilePath);
            } catch (IOException e) {
                Log.e(TAG, "Close file output error", e);
                Timber.e(e, "Close file output error");
            } finally {
                fileOutputStream = null;
                spsPpsWritten = false;