test_player.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /**
  2. * @file test_player.cpp
  3. * @brief 播放器模块测试程序
  4. * @author AI Assistant
  5. * @date 2024
  6. */
  7. #include "code/player/player_core.h"
  8. #include "code/base/media_common.h"
  9. #include <iostream>
  10. #include <thread>
  11. #include <chrono>
  12. #include <string>
  13. using namespace av;
  14. using namespace av::player;
  15. /**
  16. * @brief 播放器事件回调实现
  17. */
  18. class TestPlayerCallback : public PlayerEventCallback {
  19. public:
  20. void onStateChanged(PlayerState state) override {
  21. std::cout << "[EVENT] State changed to: " << static_cast<int>(state) << std::endl;
  22. }
  23. void onMediaInfoChanged(const MediaInfo& info) override {
  24. std::cout << "[EVENT] Media info changed:" << std::endl;
  25. std::cout << " File: " << info.filename << std::endl;
  26. std::cout << " Duration: " << info.duration << std::endl;
  27. std::cout << " Has Video: " << (info.hasVideo ? "Yes" : "No") << std::endl;
  28. std::cout << " Has Audio: " << (info.hasAudio ? "Yes" : "No") << std::endl;
  29. if (info.hasVideo) {
  30. std::cout << " Video: " << info.width << "x" << info.height
  31. << " @ " << info.fps << " fps" << std::endl;
  32. }
  33. if (info.hasAudio) {
  34. std::cout << " Audio: " << info.audioSampleRate << " Hz, "
  35. << info.audioChannels << " channels" << std::endl;
  36. }
  37. }
  38. void onErrorOccurred(const std::string& error) override {
  39. std::cout << "[ERROR] " << error << std::endl;
  40. }
  41. void onPlaybackFinished() override {
  42. std::cout << "[EVENT] Playback finished" << std::endl;
  43. }
  44. };
  45. /**
  46. * @brief 测试播放器基本功能
  47. */
  48. bool testPlayerBasicFunctions() {
  49. std::cout << "\n=== Testing Player Basic Functions ===" << std::endl;
  50. // 创建播放器
  51. PlayerCore player;
  52. TestPlayerCallback callback;
  53. player.setEventCallback(&callback);
  54. // 测试初始状态
  55. if (player.getState() != PlayerState::Idle) {
  56. std::cout << "[FAIL] Initial state should be Idle" << std::endl;
  57. return false;
  58. }
  59. // 测试音量设置
  60. player.setVolume(0.5);
  61. if (std::abs(player.getVolume() - 0.5) > 0.001) {
  62. std::cout << "[FAIL] Volume setting failed" << std::endl;
  63. return false;
  64. }
  65. // 测试播放速度设置
  66. ErrorCode result = player.setPlaybackSpeed(1.5);
  67. if (result != ErrorCode::SUCCESS) {
  68. std::cout << "[FAIL] Playback speed setting failed" << std::endl;
  69. return false;
  70. }
  71. // 测试无效播放速度
  72. result = player.setPlaybackSpeed(-1.0);
  73. if (result == ErrorCode::SUCCESS) {
  74. std::cout << "[FAIL] Should reject invalid playback speed" << std::endl;
  75. return false;
  76. }
  77. std::cout << "[PASS] Player basic functions test passed" << std::endl;
  78. return true;
  79. }
  80. /**
  81. * @brief 测试播放器状态转换
  82. */
  83. bool testPlayerStateTransitions() {
  84. std::cout << "\n=== Testing Player State Transitions ===" << std::endl;
  85. PlayerCore player;
  86. TestPlayerCallback callback;
  87. player.setEventCallback(&callback);
  88. // 测试在Idle状态下播放(应该失败)
  89. ErrorCode result = player.play();
  90. if (result == ErrorCode::SUCCESS) {
  91. std::cout << "[FAIL] Should not be able to play in Idle state" << std::endl;
  92. return false;
  93. }
  94. // 测试在Idle状态下暂停(应该失败)
  95. result = player.pause();
  96. if (result == ErrorCode::SUCCESS) {
  97. std::cout << "[FAIL] Should not be able to pause in Idle state" << std::endl;
  98. return false;
  99. }
  100. // 测试停止(应该成功,因为已经是停止状态)
  101. result = player.stop();
  102. if (result != ErrorCode::SUCCESS) {
  103. std::cout << "[FAIL] Stop should always succeed" << std::endl;
  104. return false;
  105. }
  106. std::cout << "[PASS] Player state transitions test passed" << std::endl;
  107. return true;
  108. }
  109. /**
  110. * @brief 测试媒体文件打开(使用不存在的文件)
  111. */
  112. bool testMediaFileHandling() {
  113. std::cout << "\n=== Testing Media File Handling ===" << std::endl;
  114. PlayerCore player;
  115. TestPlayerCallback callback;
  116. player.setEventCallback(&callback);
  117. // 测试打开不存在的文件
  118. ErrorCode result = player.openFile("nonexistent_file.mp4");
  119. if (result == ErrorCode::SUCCESS) {
  120. std::cout << "[FAIL] Should fail to open nonexistent file" << std::endl;
  121. return false;
  122. }
  123. // 测试打开空文件名
  124. result = player.openFile("");
  125. if (result == ErrorCode::SUCCESS) {
  126. std::cout << "[FAIL] Should fail to open empty filename" << std::endl;
  127. return false;
  128. }
  129. std::cout << "[PASS] Media file handling test passed" << std::endl;
  130. return true;
  131. }
  132. /**
  133. * @brief 测试播放器统计信息
  134. */
  135. bool testPlayerStats() {
  136. std::cout << "\n=== Testing Player Stats ===" << std::endl;
  137. PlayerCore player;
  138. // 获取初始统计信息
  139. PlaybackStats stats = player.getStats();
  140. // 验证初始值
  141. if (stats.currentTime != 0 || stats.playbackSpeed != 1.0) {
  142. std::cout << "[FAIL] Initial stats values incorrect" << std::endl;
  143. return false;
  144. }
  145. // 设置播放速度并验证统计信息
  146. player.setPlaybackSpeed(2.0);
  147. stats = player.getStats();
  148. if (std::abs(stats.playbackSpeed - 2.0) > 0.001) {
  149. std::cout << "[FAIL] Stats playback speed not updated" << std::endl;
  150. return false;
  151. }
  152. std::cout << "[PASS] Player stats test passed" << std::endl;
  153. return true;
  154. }
  155. /**
  156. * @brief 测试帧获取接口
  157. */
  158. bool testFrameInterface() {
  159. std::cout << "\n=== Testing Frame Interface ===" << std::endl;
  160. PlayerCore player;
  161. // 测试在没有媒体的情况下获取帧
  162. AVFrame* videoFrame = player.getNextVideoFrame();
  163. if (videoFrame != nullptr) {
  164. std::cout << "[FAIL] Should return null when no media loaded" << std::endl;
  165. return false;
  166. }
  167. AVFrame* audioFrame = player.getNextAudioFrame();
  168. if (audioFrame != nullptr) {
  169. std::cout << "[FAIL] Should return null when no media loaded" << std::endl;
  170. return false;
  171. }
  172. // 测试释放空帧(应该安全)
  173. player.releaseVideoFrame(nullptr);
  174. player.releaseAudioFrame(nullptr);
  175. std::cout << "[PASS] Frame interface test passed" << std::endl;
  176. return true;
  177. }
  178. /**
  179. * @brief 测试播放器更新循环
  180. */
  181. bool testPlayerUpdate() {
  182. std::cout << "\n=== Testing Player Update ===" << std::endl;
  183. PlayerCore player;
  184. // 调用更新函数(应该安全)
  185. player.update();
  186. // 多次调用更新
  187. for (int i = 0; i < 10; ++i) {
  188. player.update();
  189. std::this_thread::sleep_for(std::chrono::milliseconds(1));
  190. }
  191. std::cout << "[PASS] Player update test passed" << std::endl;
  192. return true;
  193. }
  194. /**
  195. * @brief 测试播放器多实例
  196. */
  197. bool testMultiplePlayerInstances() {
  198. std::cout << "\n=== Testing Multiple Player Instances ===" << std::endl;
  199. // 创建多个播放器实例
  200. std::vector<std::unique_ptr<PlayerCore>> players;
  201. std::vector<std::unique_ptr<TestPlayerCallback>> callbacks;
  202. for (int i = 0; i < 3; ++i) {
  203. auto player = std::make_unique<PlayerCore>();
  204. auto callback = std::make_unique<TestPlayerCallback>();
  205. player->setEventCallback(callback.get());
  206. player->setVolume(0.1 * (i + 1));
  207. players.push_back(std::move(player));
  208. callbacks.push_back(std::move(callback));
  209. }
  210. // 验证每个播放器的状态
  211. for (size_t i = 0; i < players.size(); ++i) {
  212. if (players[i]->getState() != PlayerState::Idle) {
  213. std::cout << "[FAIL] Player " << i << " state incorrect" << std::endl;
  214. return false;
  215. }
  216. double expectedVolume = 0.1 * (i + 1);
  217. if (std::abs(players[i]->getVolume() - expectedVolume) > 0.001) {
  218. std::cout << "[FAIL] Player " << i << " volume incorrect" << std::endl;
  219. return false;
  220. }
  221. }
  222. std::cout << "[PASS] Multiple player instances test passed" << std::endl;
  223. return true;
  224. }
  225. /**
  226. * @brief 运行所有测试
  227. */
  228. int main() {
  229. std::cout << "Starting Player Module Tests..." << std::endl;
  230. int passedTests = 0;
  231. int totalTests = 0;
  232. // 运行所有测试
  233. struct TestCase {
  234. const char* name;
  235. bool (*func)();
  236. };
  237. TestCase tests[] = {
  238. {"Player Basic Functions", testPlayerBasicFunctions},
  239. {"Player State Transitions", testPlayerStateTransitions},
  240. {"Media File Handling", testMediaFileHandling},
  241. {"Player Stats", testPlayerStats},
  242. {"Frame Interface", testFrameInterface},
  243. {"Player Update", testPlayerUpdate},
  244. {"Multiple Player Instances", testMultiplePlayerInstances}
  245. };
  246. for (const auto& test : tests) {
  247. totalTests++;
  248. try {
  249. if (test.func()) {
  250. passedTests++;
  251. }
  252. }
  253. catch (const std::exception& e) {
  254. std::cout << "[EXCEPTION] Test " << test.name << " threw: " << e.what() << std::endl;
  255. }
  256. catch (...) {
  257. std::cout << "[EXCEPTION] Test " << test.name << " threw unknown exception" << std::endl;
  258. }
  259. }
  260. // 输出测试结果
  261. std::cout << "\n=== Test Results ===" << std::endl;
  262. std::cout << "Passed: " << passedTests << "/" << totalTests << std::endl;
  263. std::cout << "Success Rate: " << (100.0 * passedTests / totalTests) << "%" << std::endl;
  264. if (passedTests == totalTests) {
  265. std::cout << "\n🎉 All tests passed!" << std::endl;
  266. return 0;
  267. } else {
  268. std::cout << "\n❌ Some tests failed!" << std::endl;
  269. return 1;
  270. }
  271. }