| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- // #include "AV/code/base/logger.h"
- // #include "AV/code/player/player_core_v2.h"
- // #include <chrono>
- // #include <iostream>
- // #include <string>
- // #include <thread>
- // using namespace av::player;
- // using namespace av::utils;
- // // 示例事件回调类
- // class ExamplePlayerCallback : 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;
- // }
- // std::cout << "[EVENT] State changed to: " << stateStr << std::endl;
- // }
- // 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<std::chrono::seconds>(now - lastUpdate).count() >= 1) {
- // double seconds = position / 1000000.0;
- // std::cout << "[EVENT] Position: " << std::fixed << std::setprecision(2) << seconds
- // << "s" << std::endl;
- // lastUpdate = now;
- // }
- // }
- // void onMediaInfoChanged(const MediaInfo& info) override
- // {
- // std::cout << "[EVENT] Media info changed:" << std::endl;
- // std::cout << " File: " << info.filename << std::endl;
- // std::cout << " Duration: " << (info.duration / 1000000.0) << "s" << std::endl;
- // std::cout << " Has Video: " << (info.hasVideo ? "Yes" : "No") << std::endl;
- // std::cout << " Has Audio: " << (info.hasAudio ? "Yes" : "No") << std::endl;
- // if (info.hasVideo) {
- // std::cout << " Video: " << info.width << "x" << info.height << " @ " << info.fps
- // << " fps" << std::endl;
- // }
- // if (info.hasAudio) {
- // std::cout << " Audio: " << info.sampleRate << " Hz, " << info.channels << " channels"
- // << std::endl;
- // }
- // }
- // void onErrorOccurred(const std::string& error) override
- // {
- // std::cout << "[ERROR] " << error << std::endl;
- // }
- // void onFrameDropped(int64_t totalDropped) override
- // {
- // std::cout << "[WARNING] Frame dropped, total: " << totalDropped << std::endl;
- // }
- // void onSyncError(double error, const std::string& reason) override
- // {
- // std::cout << "[WARNING] Sync error: " << (error * 1000) << "ms, reason: " << reason
- // << std::endl;
- // }
- // void onEndOfFile() override { std::cout << "[EVENT] End of file reached" << std::endl; }
- // };
- // // 简单的命令行界面
- // class SimplePlayerUI
- // {
- // public:
- // SimplePlayerUI(PlayerCoreV2* player)
- // : m_player(player)
- // , m_running(true)
- // {}
- // void run()
- // {
- // std::cout << "\n=== PlayerCoreV2 Example ===" << std::endl;
- // std::cout << "Commands:" << std::endl;
- // std::cout << " open <filename> - Open media file" << std::endl;
- // std::cout << " play - Start playback" << std::endl;
- // std::cout << " pause - Pause playback" << std::endl;
- // std::cout << " stop - Stop playback" << std::endl;
- // std::cout << " seek <seconds> - Seek to position" << std::endl;
- // std::cout << " speed <rate> - Set playback speed (0.5-4.0)" << std::endl;
- // std::cout << " volume <level> - Set volume (0.0-1.0)" << std::endl;
- // std::cout << " stats - Show playback statistics" << std::endl;
- // std::cout << " debug - Show debug information" << std::endl;
- // std::cout << " config - Show sync configuration" << std::endl;
- // std::cout << " quit - Exit program" << std::endl;
- // std::cout << "============================\n" << std::endl;
- // std::string line;
- // while (m_running && std::getline(std::cin, line)) {
- // processCommand(line);
- // }
- // }
- // private:
- // void processCommand(const std::string& line)
- // {
- // std::istringstream iss(line);
- // std::string command;
- // iss >> command;
- // if (command == "open") {
- // std::string filename;
- // iss >> filename;
- // if (!filename.empty()) {
- // auto result = m_player->openFile(filename);
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "File opened successfully" << std::endl;
- // } else {
- // std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
- // }
- // } else {
- // std::cout << "Usage: open <filename>" << std::endl;
- // }
- // } else if (command == "play") {
- // auto result = m_player->play();
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Playback started" << std::endl;
- // } else {
- // std::cout << "Failed to start playback: " << static_cast<int>(result) << std::endl;
- // }
- // } else if (command == "pause") {
- // auto result = m_player->pause();
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Playback paused" << std::endl;
- // } else {
- // std::cout << "Failed to pause playback: " << static_cast<int>(result) << std::endl;
- // }
- // } else if (command == "stop") {
- // auto result = m_player->stop();
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Playback stopped" << std::endl;
- // } else {
- // std::cout << "Failed to stop playback: " << static_cast<int>(result) << std::endl;
- // }
- // } else if (command == "seek") {
- // double seconds;
- // iss >> seconds;
- // if (iss) {
- // int64_t timestamp = static_cast<int64_t>(seconds * 1000000); // 转换为微秒
- // auto result = m_player->seek(timestamp);
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Seeking to " << seconds << "s" << std::endl;
- // } else {
- // std::cout << "Failed to seek: " << static_cast<int>(result) << std::endl;
- // }
- // } else {
- // std::cout << "Usage: seek <seconds>" << std::endl;
- // }
- // } else if (command == "speed") {
- // double speed;
- // iss >> speed;
- // if (iss) {
- // auto result = m_player->setPlaybackSpeed(speed);
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Playback speed set to " << speed << "x" << std::endl;
- // } else {
- // std::cout << "Failed to set playback speed: " << static_cast<int>(result)
- // << std::endl;
- // }
- // } else {
- // std::cout << "Usage: speed <rate>" << std::endl;
- // }
- // } else if (command == "volume") {
- // double volume;
- // iss >> volume;
- // if (iss) {
- // m_player->setVolume(volume);
- // std::cout << "Volume set to " << volume << std::endl;
- // } else {
- // std::cout << "Usage: volume <level>" << std::endl;
- // }
- // } else if (command == "stats") {
- // showStats();
- // } else if (command == "debug") {
- // std::cout << m_player->getDebugInfo() << std::endl;
- // } else if (command == "config") {
- // showSyncConfig();
- // } else if (command == "quit" || command == "exit") {
- // m_running = false;
- // std::cout << "Exiting..." << std::endl;
- // } else if (!command.empty()) {
- // std::cout << "Unknown command: " << command << std::endl;
- // }
- // }
- // void showStats()
- // {
- // auto stats = m_player->getStats();
- // std::cout << "\n=== Playback Statistics ===" << std::endl;
- // std::cout << "Current Time: " << std::fixed << std::setprecision(2)
- // << (stats.currentTime / 1000000.0) << "s" << std::endl;
- // std::cout << "Playback Speed: " << stats.playbackSpeed << "x" << std::endl;
- // std::cout << "Total Frames: " << stats.totalFrames << std::endl;
- // std::cout << "Dropped Frames: " << stats.droppedFrames << std::endl;
- // std::cout << "Duplicated Frames: " << stats.duplicatedFrames << std::endl;
- // std::cout << "Sync Error: " << std::fixed << std::setprecision(1)
- // << (stats.syncError * 1000) << "ms" << std::endl;
- // std::cout << "Avg Sync Error: " << std::fixed << std::setprecision(1)
- // << (stats.avgSyncError * 1000) << "ms" << std::endl;
- // std::cout << "Max Sync Error: " << std::fixed << std::setprecision(1)
- // << (stats.maxSyncError * 1000) << "ms" << std::endl;
- // std::cout << "CPU Usage: " << std::fixed << std::setprecision(1) << stats.cpuUsage << "%"
- // << std::endl;
- // std::cout << "Memory Usage: " << std::fixed << std::setprecision(1) << stats.memoryUsage
- // << "MB" << std::endl;
- // std::cout << "Queued Packets: " << stats.queuedPackets << std::endl;
- // std::cout << "Queued Video Frames: " << stats.queuedVideoFrames << std::endl;
- // std::cout << "Queued Audio Frames: " << stats.queuedAudioFrames << std::endl;
- // std::cout << "Bitrate: " << std::fixed << std::setprecision(1) << stats.bitrate << " kbps"
- // << std::endl;
- // std::cout << "===========================\n" << std::endl;
- // }
- // void showSyncConfig()
- // {
- // auto config = m_player->getSyncConfig();
- // std::cout << "\n=== Sync Configuration ===" << std::endl;
- // std::cout << "Sync Strategy: " << static_cast<int>(config.syncStrategy) << std::endl;
- // std::cout << "Audio Sync Threshold: " << (config.audioSyncThreshold * 1000) << "ms"
- // << std::endl;
- // std::cout << "Video Sync Threshold: " << (config.videoSyncThreshold * 1000) << "ms"
- // << std::endl;
- // std::cout << "Max Sync Error: " << (config.maxSyncError * 1000) << "ms" << std::endl;
- // std::cout << "Clock Update Interval: " << config.clockUpdateInterval << "ms" << std::endl;
- // std::cout << "Smoothing Window: " << config.smoothingWindow << std::endl;
- // std::cout << "Adaptive Sync: " << (config.enableAdaptiveSync ? "Enabled" : "Disabled")
- // << std::endl;
- // std::cout << "Frame Drop: " << (config.enableFrameDrop ? "Enabled" : "Disabled")
- // << std::endl;
- // std::cout << "Frame Duplicate: " << (config.enableFrameDuplicate ? "Enabled" : "Disabled")
- // << std::endl;
- // std::cout << "Prediction: " << (config.enablePrediction ? "Enabled" : "Disabled")
- // << std::endl;
- // std::cout << "==========================\n" << std::endl;
- // }
- // PlayerCoreV2* m_player;
- // bool m_running;
- // };
- // int main(int argc, char* argv[])
- // {
- // // 初始化日志系统
- // Logger::instance().initialize("test.log", LogLevel::DEBUG, false, true);
- // Logger::instance().setLevel(LogLevel::DEBUG);
- // Logger::instance().info("PlayerCoreV2 Example Started");
- // try {
- // // 创建同步配置
- // SyncConfigV2 syncConfig;
- // syncConfig.syncStrategy = SyncStrategy::ADAPTIVE; // 使用自适应同步策略
- // syncConfig.audioSyncThreshold = 0.040; // 40ms
- // syncConfig.videoSyncThreshold = 0.020; // 20ms
- // syncConfig.maxSyncError = 0.200; // 200ms
- // syncConfig.clockUpdateInterval = 10; // 10ms
- // syncConfig.smoothingWindow = 10; // 10个样本
- // syncConfig.enableAdaptiveSync = true;
- // syncConfig.enableFrameDrop = true;
- // syncConfig.enableFrameDuplicate = true;
- // syncConfig.enablePrediction = true;
- // syncConfig.enableErrorRecovery = true;
- // // 创建播放器实例
- // auto player = std::make_unique<PlayerCoreV2>(syncConfig);
- // // 创建事件回调
- // auto callback = std::make_unique<ExamplePlayerCallback>();
- // player->setEventCallback(callback.get());
- // // 如果命令行提供了文件名,自动打开
- // if (argc > 1) {
- // std::string filename = argv[1];
- // std::cout << "Opening file: " << filename << std::endl;
- // auto result = player->openFile(filename);
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "File opened successfully" << std::endl;
- // // 自动开始播放
- // result = player->play();
- // if (result == ErrorCode::SUCCESS) {
- // std::cout << "Playback started" << std::endl;
- // } else {
- // std::cout << "Failed to start playback: " << static_cast<int>(result)
- // << std::endl;
- // }
- // } else {
- // std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
- // }
- // }
- // // 启动用户界面
- // SimplePlayerUI ui(player.get());
- // // 启动更新线程
- // std::atomic<bool> shouldStop(false);
- // std::thread updateThread([&player, &shouldStop]() {
- // while (!shouldStop) {
- // player->update();
- // std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS
- // }
- // });
- // // 运行用户界面
- // ui.run();
- // // 停止更新线程
- // shouldStop = true;
- // if (updateThread.joinable()) {
- // updateThread.join();
- // }
- // // 等待播放完成后再停止播放器
- // if (player->getState() == PlayerState::Playing) {
- // auto mediaInfo = player->getMediaInfo();
- // if (mediaInfo.duration > 0) {
- // std::cout << "Waiting for playback to complete..." << std::endl;
- // // 等待播放完成
- // while (player->getState() == PlayerState::Playing) {
- // auto currentTime = player->getCurrentTime();
- // auto duration = mediaInfo.duration;
- // // 如果播放时间接近总时长(留100ms缓冲),认为播放完成
- // if (currentTime >= duration - 100000) { // 100ms = 100000微秒
- // std::cout << "Playback completed naturally" << std::endl;
- // break;
- // }
- // // 每100ms检查一次
- // std::this_thread::sleep_for(std::chrono::milliseconds(100));
- // }
- // }
- // }
- // // 停止播放器
- // player->stop();
- // std::cout << "PlayerCoreV2 Example finished" << std::endl;
- // } catch (const std::exception& e) {
- // std::cerr << "Exception: " << e.what() << std::endl;
- // return 1;
- // } catch (...) {
- // std::cerr << "Unknown exception occurred" << std::endl;
- // return 1;
- // }
- // return 0;
- // }
|