main.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. // #include "AV/code/base/logger.h"
  2. // #include "AV/code/player/player_core_v2.h"
  3. // #include <chrono>
  4. // #include <iostream>
  5. // #include <string>
  6. // #include <thread>
  7. // using namespace av::player;
  8. // using namespace av::utils;
  9. // // 示例事件回调类
  10. // class ExamplePlayerCallback : public PlayerEventCallback
  11. // {
  12. // public:
  13. // void onStateChanged(PlayerState newState) override
  14. // {
  15. // std::string stateStr;
  16. // switch (newState) {
  17. // case PlayerState::Idle:
  18. // stateStr = "Idle";
  19. // break;
  20. // case PlayerState::Opening:
  21. // stateStr = "Opening";
  22. // break;
  23. // case PlayerState::Stopped:
  24. // stateStr = "Stopped";
  25. // break;
  26. // case PlayerState::Playing:
  27. // stateStr = "Playing";
  28. // break;
  29. // case PlayerState::Paused:
  30. // stateStr = "Paused";
  31. // break;
  32. // case PlayerState::Seeking:
  33. // stateStr = "Seeking";
  34. // break;
  35. // case PlayerState::Error:
  36. // stateStr = "Error";
  37. // break;
  38. // }
  39. // std::cout << "[EVENT] State changed to: " << stateStr << std::endl;
  40. // }
  41. // void onPositionChanged(int64_t position) override
  42. // {
  43. // // 每秒更新一次位置信息
  44. // static auto lastUpdate = std::chrono::steady_clock::now();
  45. // auto now = std::chrono::steady_clock::now();
  46. // if (std::chrono::duration_cast<std::chrono::seconds>(now - lastUpdate).count() >= 1) {
  47. // double seconds = position / 1000000.0;
  48. // std::cout << "[EVENT] Position: " << std::fixed << std::setprecision(2) << seconds
  49. // << "s" << std::endl;
  50. // lastUpdate = now;
  51. // }
  52. // }
  53. // void onMediaInfoChanged(const MediaInfo& info) override
  54. // {
  55. // std::cout << "[EVENT] Media info changed:" << std::endl;
  56. // std::cout << " File: " << info.filename << std::endl;
  57. // std::cout << " Duration: " << (info.duration / 1000000.0) << "s" << std::endl;
  58. // std::cout << " Has Video: " << (info.hasVideo ? "Yes" : "No") << std::endl;
  59. // std::cout << " Has Audio: " << (info.hasAudio ? "Yes" : "No") << std::endl;
  60. // if (info.hasVideo) {
  61. // std::cout << " Video: " << info.width << "x" << info.height << " @ " << info.fps
  62. // << " fps" << std::endl;
  63. // }
  64. // if (info.hasAudio) {
  65. // std::cout << " Audio: " << info.sampleRate << " Hz, " << info.channels << " channels"
  66. // << std::endl;
  67. // }
  68. // }
  69. // void onErrorOccurred(const std::string& error) override
  70. // {
  71. // std::cout << "[ERROR] " << error << std::endl;
  72. // }
  73. // void onFrameDropped(int64_t totalDropped) override
  74. // {
  75. // std::cout << "[WARNING] Frame dropped, total: " << totalDropped << std::endl;
  76. // }
  77. // void onSyncError(double error, const std::string& reason) override
  78. // {
  79. // std::cout << "[WARNING] Sync error: " << (error * 1000) << "ms, reason: " << reason
  80. // << std::endl;
  81. // }
  82. // void onEndOfFile() override { std::cout << "[EVENT] End of file reached" << std::endl; }
  83. // };
  84. // // 简单的命令行界面
  85. // class SimplePlayerUI
  86. // {
  87. // public:
  88. // SimplePlayerUI(PlayerCoreV2* player)
  89. // : m_player(player)
  90. // , m_running(true)
  91. // {}
  92. // void run()
  93. // {
  94. // std::cout << "\n=== PlayerCoreV2 Example ===" << std::endl;
  95. // std::cout << "Commands:" << std::endl;
  96. // std::cout << " open <filename> - Open media file" << std::endl;
  97. // std::cout << " play - Start playback" << std::endl;
  98. // std::cout << " pause - Pause playback" << std::endl;
  99. // std::cout << " stop - Stop playback" << std::endl;
  100. // std::cout << " seek <seconds> - Seek to position" << std::endl;
  101. // std::cout << " speed <rate> - Set playback speed (0.5-4.0)" << std::endl;
  102. // std::cout << " volume <level> - Set volume (0.0-1.0)" << std::endl;
  103. // std::cout << " stats - Show playback statistics" << std::endl;
  104. // std::cout << " debug - Show debug information" << std::endl;
  105. // std::cout << " config - Show sync configuration" << std::endl;
  106. // std::cout << " quit - Exit program" << std::endl;
  107. // std::cout << "============================\n" << std::endl;
  108. // std::string line;
  109. // while (m_running && std::getline(std::cin, line)) {
  110. // processCommand(line);
  111. // }
  112. // }
  113. // private:
  114. // void processCommand(const std::string& line)
  115. // {
  116. // std::istringstream iss(line);
  117. // std::string command;
  118. // iss >> command;
  119. // if (command == "open") {
  120. // std::string filename;
  121. // iss >> filename;
  122. // if (!filename.empty()) {
  123. // auto result = m_player->openFile(filename);
  124. // if (result == ErrorCode::SUCCESS) {
  125. // std::cout << "File opened successfully" << std::endl;
  126. // } else {
  127. // std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
  128. // }
  129. // } else {
  130. // std::cout << "Usage: open <filename>" << std::endl;
  131. // }
  132. // } else if (command == "play") {
  133. // auto result = m_player->play();
  134. // if (result == ErrorCode::SUCCESS) {
  135. // std::cout << "Playback started" << std::endl;
  136. // } else {
  137. // std::cout << "Failed to start playback: " << static_cast<int>(result) << std::endl;
  138. // }
  139. // } else if (command == "pause") {
  140. // auto result = m_player->pause();
  141. // if (result == ErrorCode::SUCCESS) {
  142. // std::cout << "Playback paused" << std::endl;
  143. // } else {
  144. // std::cout << "Failed to pause playback: " << static_cast<int>(result) << std::endl;
  145. // }
  146. // } else if (command == "stop") {
  147. // auto result = m_player->stop();
  148. // if (result == ErrorCode::SUCCESS) {
  149. // std::cout << "Playback stopped" << std::endl;
  150. // } else {
  151. // std::cout << "Failed to stop playback: " << static_cast<int>(result) << std::endl;
  152. // }
  153. // } else if (command == "seek") {
  154. // double seconds;
  155. // iss >> seconds;
  156. // if (iss) {
  157. // int64_t timestamp = static_cast<int64_t>(seconds * 1000000); // 转换为微秒
  158. // auto result = m_player->seek(timestamp);
  159. // if (result == ErrorCode::SUCCESS) {
  160. // std::cout << "Seeking to " << seconds << "s" << std::endl;
  161. // } else {
  162. // std::cout << "Failed to seek: " << static_cast<int>(result) << std::endl;
  163. // }
  164. // } else {
  165. // std::cout << "Usage: seek <seconds>" << std::endl;
  166. // }
  167. // } else if (command == "speed") {
  168. // double speed;
  169. // iss >> speed;
  170. // if (iss) {
  171. // auto result = m_player->setPlaybackSpeed(speed);
  172. // if (result == ErrorCode::SUCCESS) {
  173. // std::cout << "Playback speed set to " << speed << "x" << std::endl;
  174. // } else {
  175. // std::cout << "Failed to set playback speed: " << static_cast<int>(result)
  176. // << std::endl;
  177. // }
  178. // } else {
  179. // std::cout << "Usage: speed <rate>" << std::endl;
  180. // }
  181. // } else if (command == "volume") {
  182. // double volume;
  183. // iss >> volume;
  184. // if (iss) {
  185. // m_player->setVolume(volume);
  186. // std::cout << "Volume set to " << volume << std::endl;
  187. // } else {
  188. // std::cout << "Usage: volume <level>" << std::endl;
  189. // }
  190. // } else if (command == "stats") {
  191. // showStats();
  192. // } else if (command == "debug") {
  193. // std::cout << m_player->getDebugInfo() << std::endl;
  194. // } else if (command == "config") {
  195. // showSyncConfig();
  196. // } else if (command == "quit" || command == "exit") {
  197. // m_running = false;
  198. // std::cout << "Exiting..." << std::endl;
  199. // } else if (!command.empty()) {
  200. // std::cout << "Unknown command: " << command << std::endl;
  201. // }
  202. // }
  203. // void showStats()
  204. // {
  205. // auto stats = m_player->getStats();
  206. // std::cout << "\n=== Playback Statistics ===" << std::endl;
  207. // std::cout << "Current Time: " << std::fixed << std::setprecision(2)
  208. // << (stats.currentTime / 1000000.0) << "s" << std::endl;
  209. // std::cout << "Playback Speed: " << stats.playbackSpeed << "x" << std::endl;
  210. // std::cout << "Total Frames: " << stats.totalFrames << std::endl;
  211. // std::cout << "Dropped Frames: " << stats.droppedFrames << std::endl;
  212. // std::cout << "Duplicated Frames: " << stats.duplicatedFrames << std::endl;
  213. // std::cout << "Sync Error: " << std::fixed << std::setprecision(1)
  214. // << (stats.syncError * 1000) << "ms" << std::endl;
  215. // std::cout << "Avg Sync Error: " << std::fixed << std::setprecision(1)
  216. // << (stats.avgSyncError * 1000) << "ms" << std::endl;
  217. // std::cout << "Max Sync Error: " << std::fixed << std::setprecision(1)
  218. // << (stats.maxSyncError * 1000) << "ms" << std::endl;
  219. // std::cout << "CPU Usage: " << std::fixed << std::setprecision(1) << stats.cpuUsage << "%"
  220. // << std::endl;
  221. // std::cout << "Memory Usage: " << std::fixed << std::setprecision(1) << stats.memoryUsage
  222. // << "MB" << std::endl;
  223. // std::cout << "Queued Packets: " << stats.queuedPackets << std::endl;
  224. // std::cout << "Queued Video Frames: " << stats.queuedVideoFrames << std::endl;
  225. // std::cout << "Queued Audio Frames: " << stats.queuedAudioFrames << std::endl;
  226. // std::cout << "Bitrate: " << std::fixed << std::setprecision(1) << stats.bitrate << " kbps"
  227. // << std::endl;
  228. // std::cout << "===========================\n" << std::endl;
  229. // }
  230. // void showSyncConfig()
  231. // {
  232. // auto config = m_player->getSyncConfig();
  233. // std::cout << "\n=== Sync Configuration ===" << std::endl;
  234. // std::cout << "Sync Strategy: " << static_cast<int>(config.syncStrategy) << std::endl;
  235. // std::cout << "Audio Sync Threshold: " << (config.audioSyncThreshold * 1000) << "ms"
  236. // << std::endl;
  237. // std::cout << "Video Sync Threshold: " << (config.videoSyncThreshold * 1000) << "ms"
  238. // << std::endl;
  239. // std::cout << "Max Sync Error: " << (config.maxSyncError * 1000) << "ms" << std::endl;
  240. // std::cout << "Clock Update Interval: " << config.clockUpdateInterval << "ms" << std::endl;
  241. // std::cout << "Smoothing Window: " << config.smoothingWindow << std::endl;
  242. // std::cout << "Adaptive Sync: " << (config.enableAdaptiveSync ? "Enabled" : "Disabled")
  243. // << std::endl;
  244. // std::cout << "Frame Drop: " << (config.enableFrameDrop ? "Enabled" : "Disabled")
  245. // << std::endl;
  246. // std::cout << "Frame Duplicate: " << (config.enableFrameDuplicate ? "Enabled" : "Disabled")
  247. // << std::endl;
  248. // std::cout << "Prediction: " << (config.enablePrediction ? "Enabled" : "Disabled")
  249. // << std::endl;
  250. // std::cout << "==========================\n" << std::endl;
  251. // }
  252. // PlayerCoreV2* m_player;
  253. // bool m_running;
  254. // };
  255. // int main(int argc, char* argv[])
  256. // {
  257. // // 初始化日志系统
  258. // Logger::instance().initialize("test.log", LogLevel::DEBUG, false, true);
  259. // Logger::instance().setLevel(LogLevel::DEBUG);
  260. // Logger::instance().info("PlayerCoreV2 Example Started");
  261. // try {
  262. // // 创建同步配置
  263. // SyncConfigV2 syncConfig;
  264. // syncConfig.syncStrategy = SyncStrategy::ADAPTIVE; // 使用自适应同步策略
  265. // syncConfig.audioSyncThreshold = 0.040; // 40ms
  266. // syncConfig.videoSyncThreshold = 0.020; // 20ms
  267. // syncConfig.maxSyncError = 0.200; // 200ms
  268. // syncConfig.clockUpdateInterval = 10; // 10ms
  269. // syncConfig.smoothingWindow = 10; // 10个样本
  270. // syncConfig.enableAdaptiveSync = true;
  271. // syncConfig.enableFrameDrop = true;
  272. // syncConfig.enableFrameDuplicate = true;
  273. // syncConfig.enablePrediction = true;
  274. // syncConfig.enableErrorRecovery = true;
  275. // // 创建播放器实例
  276. // auto player = std::make_unique<PlayerCoreV2>(syncConfig);
  277. // // 创建事件回调
  278. // auto callback = std::make_unique<ExamplePlayerCallback>();
  279. // player->setEventCallback(callback.get());
  280. // // 如果命令行提供了文件名,自动打开
  281. // if (argc > 1) {
  282. // std::string filename = argv[1];
  283. // std::cout << "Opening file: " << filename << std::endl;
  284. // auto result = player->openFile(filename);
  285. // if (result == ErrorCode::SUCCESS) {
  286. // std::cout << "File opened successfully" << std::endl;
  287. // // 自动开始播放
  288. // result = player->play();
  289. // if (result == ErrorCode::SUCCESS) {
  290. // std::cout << "Playback started" << std::endl;
  291. // } else {
  292. // std::cout << "Failed to start playback: " << static_cast<int>(result)
  293. // << std::endl;
  294. // }
  295. // } else {
  296. // std::cout << "Failed to open file: " << static_cast<int>(result) << std::endl;
  297. // }
  298. // }
  299. // // 启动用户界面
  300. // SimplePlayerUI ui(player.get());
  301. // // 启动更新线程
  302. // std::atomic<bool> shouldStop(false);
  303. // std::thread updateThread([&player, &shouldStop]() {
  304. // while (!shouldStop) {
  305. // player->update();
  306. // std::this_thread::sleep_for(std::chrono::milliseconds(16)); // ~60 FPS
  307. // }
  308. // });
  309. // // 运行用户界面
  310. // ui.run();
  311. // // 停止更新线程
  312. // shouldStop = true;
  313. // if (updateThread.joinable()) {
  314. // updateThread.join();
  315. // }
  316. // // 等待播放完成后再停止播放器
  317. // if (player->getState() == PlayerState::Playing) {
  318. // auto mediaInfo = player->getMediaInfo();
  319. // if (mediaInfo.duration > 0) {
  320. // std::cout << "Waiting for playback to complete..." << std::endl;
  321. // // 等待播放完成
  322. // while (player->getState() == PlayerState::Playing) {
  323. // auto currentTime = player->getCurrentTime();
  324. // auto duration = mediaInfo.duration;
  325. // // 如果播放时间接近总时长(留100ms缓冲),认为播放完成
  326. // if (currentTime >= duration - 100000) { // 100ms = 100000微秒
  327. // std::cout << "Playback completed naturally" << std::endl;
  328. // break;
  329. // }
  330. // // 每100ms检查一次
  331. // std::this_thread::sleep_for(std::chrono::milliseconds(100));
  332. // }
  333. // }
  334. // }
  335. // // 停止播放器
  336. // player->stop();
  337. // std::cout << "PlayerCoreV2 Example finished" << std::endl;
  338. // } catch (const std::exception& e) {
  339. // std::cerr << "Exception: " << e.what() << std::endl;
  340. // return 1;
  341. // } catch (...) {
  342. // std::cerr << "Unknown exception occurred" << std::endl;
  343. // return 1;
  344. // }
  345. // return 0;
  346. // }