#include #include #include #include #include "code/base/logger.h" #include "code/player/player_core_v2.h" #include #include #include #include #include using namespace av::player; using namespace av::utils; // 增强的事件回调类,包含更详细的调试信息 class DebugPlayerCallback : public PlayerEventCallback { public: void onStateChanged(PlayerState newState) override { std::string stateStr; switch (newState) { case PlayerState::Idle: stateStr = "Idle"; break; case PlayerState::Opening: stateStr = "Opening"; break; case PlayerState::Stopped: stateStr = "Stopped"; break; case PlayerState::Playing: stateStr = "Playing"; break; case PlayerState::Paused: stateStr = "Paused"; break; case PlayerState::Seeking: stateStr = "Seeking"; break; case PlayerState::Error: stateStr = "Error"; break; } Logger::instance().info("[EVENT] State changed to: " + stateStr); } void onPositionChanged(int64_t position) override { static auto lastUpdate = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now(); if (std::chrono::duration_cast(now - lastUpdate).count() >= 1) { double seconds = position / 1000000.0; Logger::instance().debug("[EVENT] Position: " + std::to_string(seconds) + "s"); lastUpdate = now; } } void onMediaInfoChanged(const MediaInfo& info) override { Logger::instance().info("[EVENT] Media info changed:"); Logger::instance().info(" File: " + info.filename); Logger::instance().info(" Duration: " + std::to_string(info.duration / 1000000.0) + "s"); Logger::instance().info(" Has Video: " + std::string(info.hasVideo ? "Yes" : "No")); Logger::instance().info(" Has Audio: " + std::string(info.hasAudio ? "Yes" : "No")); if (info.hasAudio) { Logger::instance().info(" Audio: " + std::to_string(info.sampleRate) + " Hz, " + std::to_string(info.channels) + " channels"); } } void onErrorOccurred(const std::string& error) override { Logger::instance().error("[ERROR] " + error); } void onFrameDropped(int64_t totalDropped) override { Logger::instance().warningf("[WARNING] Frame dropped, total: " + std::to_string(totalDropped)); } void onSyncError(double error, const std::string& reason) override { Logger::instance().warningf("[WARNING] Sync error: " + std::to_string(error * 1000) + "ms, reason: " + reason); } void onEndOfFile() override { Logger::instance().info("[EVENT] End of file reached"); } }; // 检查系统音频设备 void checkAudioDevices() { Logger::instance().info("\n=== 音频设备检查 ==="); // 获取默认输出设备 QAudioDeviceInfo defaultDevice = QAudioDeviceInfo::defaultOutputDevice(); Logger::instance().info("默认音频输出设备: " + defaultDevice.deviceName().toStdString()); // 列出所有可用的音频输出设备 QList devices = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); Logger::instance().info("可用音频输出设备数量: " + std::to_string(devices.size())); for (int i = 0; i < devices.size(); ++i) { const QAudioDeviceInfo& device = devices[i]; Logger::instance().info(" 设备 " + std::to_string(i + 1) + ": " + device.deviceName().toStdString()); // 检查支持的采样率 QList sampleRates = device.supportedSampleRates(); std::string ratesStr = " 支持的采样率: "; for (int rate : sampleRates) { ratesStr += std::to_string(rate) + " "; } Logger::instance().info(ratesStr); // 检查支持的通道数 QList channels = device.supportedChannelCounts(); std::string channelsStr = " 支持的通道数: "; for (int ch : channels) { channelsStr += std::to_string(ch) + " "; } Logger::instance().info(channelsStr); } } // 测试Qt音频输出 void testQtAudioOutput() { Logger::instance().info("\n=== Qt音频输出测试 ==="); // 设置音频格式 QAudioFormat format; format.setSampleRate(44100); format.setChannelCount(2); format.setSampleSize(16); format.setCodec("audio/pcm"); format.setByteOrder(QAudioFormat::LittleEndian); format.setSampleType(QAudioFormat::SignedInt); // 检查默认设备是否支持该格式 QAudioDeviceInfo deviceInfo = QAudioDeviceInfo::defaultOutputDevice(); if (!deviceInfo.isFormatSupported(format)) { Logger::instance().warningf("警告: 默认设备不支持指定的音频格式"); format = deviceInfo.nearestFormat(format); Logger::instance().info("使用最接近的格式: " + std::to_string(format.sampleRate()) + "Hz, " + std::to_string(format.channelCount()) + "ch, " + std::to_string(format.sampleSize()) + "bit"); } else { Logger::instance().info("默认设备支持指定的音频格式"); } // 创建音频输出 QAudioOutput* audioOutput = new QAudioOutput(format); if (!audioOutput) { Logger::instance().error("错误: 无法创建QAudioOutput"); return; } Logger::instance().info("QAudioOutput创建成功"); Logger::instance().info("缓冲区大小: " + std::to_string(audioOutput->bufferSize()) + " bytes"); Logger::instance().info("音量: " + std::to_string(audioOutput->volume())); // 尝试启动音频设备 QIODevice* device = audioOutput->start(); if (!device) { Logger::instance().error("错误: 无法启动音频设备"); delete audioOutput; return; } Logger::instance().info("音频设备启动成功"); // 生成并播放测试音调(440Hz正弦波) const int sampleRate = format.sampleRate(); const int channels = format.channelCount(); const double frequency = 440.0; // A4音符 const double duration = 2.0; // 2秒 const int totalSamples = static_cast(sampleRate * duration); QByteArray testData; testData.resize(totalSamples * channels * sizeof(int16_t)); int16_t* samples = reinterpret_cast(testData.data()); for (int i = 0; i < totalSamples; ++i) { double time = static_cast(i) / sampleRate; int16_t sample = static_cast(16383 * std::sin(2.0 * M_PI * frequency * time)); for (int ch = 0; ch < channels; ++ch) { samples[i * channels + ch] = sample; } } Logger::instance().info("播放测试音调 (440Hz, 2秒)..."); // 分块写入音频数据 const int chunkSize = 4096; int bytesWritten = 0; while (bytesWritten < testData.size()) { int remainingBytes = testData.size() - bytesWritten; int writeSize = std::min(chunkSize, remainingBytes); qint64 written = device->write(testData.data() + bytesWritten, writeSize); if (written > 0) { bytesWritten += written; } // 等待一小段时间 std::this_thread::sleep_for(std::chrono::milliseconds(50)); } Logger::instance().info("测试音调播放完成"); // 等待播放完成 std::this_thread::sleep_for(std::chrono::milliseconds(500)); audioOutput->stop(); delete audioOutput; } int main(int argc, char* argv[]) { // 创建QApplication实例(Qt音频需要) QApplication app(argc, argv); Logger::instance().initialize("test.log", LogLevel::DEBUG, false, true); // 初始化日志系统 Logger::instance().setLevel(LogLevel::DEBUG); Logger::instance().info("Enhanced Audio Debug Test Started"); try { // 检查音频设备 checkAudioDevices(); // 测试Qt音频输出 // testQtAudioOutput(); Logger::instance().info("\n=== PlayerCoreV2音频测试 ==="); // 创建同步配置 SyncConfigV2 syncConfig; syncConfig.syncStrategy = SyncStrategy::ADAPTIVE; syncConfig.audioSyncThreshold = 0.040; syncConfig.videoSyncThreshold = 0.020; syncConfig.maxSyncError = 0.200; syncConfig.clockUpdateInterval = 10; syncConfig.smoothingWindow = 10; syncConfig.enableAdaptiveSync = true; syncConfig.enableFrameDrop = true; syncConfig.enableFrameDuplicate = true; syncConfig.enablePrediction = true; syncConfig.enableErrorRecovery = true; // 创建播放器实例 auto player = std::make_unique(syncConfig); // 创建事件回调 auto callback = std::make_unique(); player->setEventCallback(callback.get()); // 测试音频文件路径 std::string audioFile = "C:\\Windows\\Media\\notify.wav"; Logger::instance().info("测试音频文件: " + audioFile); // 打开音频文件 auto result = player->openFile(audioFile); if (result != ErrorCode::SUCCESS) { Logger::instance().error("无法打开音频文件: " + std::to_string(static_cast(result))); // 尝试其他文件 audioFile = "C:\\Windows\\Media\\chimes.wav"; Logger::instance().info("尝试备用文件: " + audioFile); result = player->openFile(audioFile); if (result != ErrorCode::SUCCESS) { Logger::instance().error("无法打开备用音频文件: " + std::to_string(static_cast(result))); return 1; } } Logger::instance().info("音频文件打开成功!"); // 获取媒体信息 auto mediaInfo = player->getMediaInfo(); Logger::instance().info("媒体时长: " + std::to_string(mediaInfo.duration / 1000000.0) + " 秒"); Logger::instance().info("包含音频: " + std::string(mediaInfo.hasAudio ? "是" : "否")); if (!mediaInfo.hasAudio) { Logger::instance().error("文件中未找到音频流!"); return 1; } // 设置音量为最大 player->setVolume(1.0); Logger::instance().info("音量设置为: " + std::to_string(player->getVolume())); // 开始播放 result = player->play(); if (result != ErrorCode::SUCCESS) { Logger::instance().error("播放启动失败: " + std::to_string(static_cast(result))); return 1; } Logger::instance().info("播放已开始! 现在应该能听到声音了."); Logger::instance().info("当前音量: " + std::to_string(player->getVolume())); // 等待播放完成 double totalDuration = mediaInfo.duration / 1000000.0; Logger::instance().info("等待播放完成 (" + std::to_string(totalDuration) + " 秒)..."); // 监控播放状态 - 让播放器自然结束 auto startTime = std::chrono::steady_clock::now(); while (true) { auto currentTime = std::chrono::steady_clock::now(); auto elapsed = std::chrono::duration_cast(currentTime - startTime).count(); auto state = player->getState(); auto currentPos = player->getCurrentTime() / 1000000.0; Logger::instance().debug("状态: " + std::to_string(static_cast(state)) + ", 位置: " + std::to_string(currentPos) + "s"); // 如果播放完成或出错,退出 if (state == PlayerState::Stopped || state == PlayerState::Error) { Logger::instance().info("播放器自然停止,状态: " + std::to_string(static_cast(state))); break; } // 超时保护 - 增加更长的超时时间 if (elapsed > totalDuration + 10) { Logger::instance().warningf("超时保护触发,停止播放..."); player->stop(); break; } std::this_thread::sleep_for(std::chrono::milliseconds(500)); } Logger::instance().info("音频测试完成."); } catch (const std::exception& e) { Logger::instance().error("异常: " + std::string(e.what())); return 1; } catch (...) { Logger::instance().error("发生未知异常"); return 1; } return 0; }