| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- /**
- * @file test_player.cpp
- * @brief 播放器模块测试程序
- * @author AI Assistant
- * @date 2024
- */
- #include "code/player/player_core.h"
- #include "code/base/media_common.h"
- #include <iostream>
- #include <thread>
- #include <chrono>
- #include <string>
- using namespace av;
- using namespace av::player;
- /**
- * @brief 播放器事件回调实现
- */
- class TestPlayerCallback : public PlayerEventCallback {
- public:
- void onStateChanged(PlayerState state) override {
- std::cout << "[EVENT] State changed to: " << static_cast<int>(state) << std::endl;
- }
-
- 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 << 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.audioSampleRate << " Hz, "
- << info.audioChannels << " channels" << std::endl;
- }
- }
-
- void onErrorOccurred(const std::string& error) override {
- std::cout << "[ERROR] " << error << std::endl;
- }
-
- void onPlaybackFinished() override {
- std::cout << "[EVENT] Playback finished" << std::endl;
- }
- };
- /**
- * @brief 测试播放器基本功能
- */
- bool testPlayerBasicFunctions() {
- std::cout << "\n=== Testing Player Basic Functions ===" << std::endl;
-
- // 创建播放器
- PlayerCore player;
- TestPlayerCallback callback;
- player.setEventCallback(&callback);
-
- // 测试初始状态
- if (player.getState() != PlayerState::Idle) {
- std::cout << "[FAIL] Initial state should be Idle" << std::endl;
- return false;
- }
-
- // 测试音量设置
- player.setVolume(0.5);
- if (std::abs(player.getVolume() - 0.5) > 0.001) {
- std::cout << "[FAIL] Volume setting failed" << std::endl;
- return false;
- }
-
- // 测试播放速度设置
- ErrorCode result = player.setPlaybackSpeed(1.5);
- if (result != ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Playback speed setting failed" << std::endl;
- return false;
- }
-
- // 测试无效播放速度
- result = player.setPlaybackSpeed(-1.0);
- if (result == ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Should reject invalid playback speed" << std::endl;
- return false;
- }
-
- std::cout << "[PASS] Player basic functions test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试播放器状态转换
- */
- bool testPlayerStateTransitions() {
- std::cout << "\n=== Testing Player State Transitions ===" << std::endl;
-
- PlayerCore player;
- TestPlayerCallback callback;
- player.setEventCallback(&callback);
-
- // 测试在Idle状态下播放(应该失败)
- ErrorCode result = player.play();
- if (result == ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Should not be able to play in Idle state" << std::endl;
- return false;
- }
-
- // 测试在Idle状态下暂停(应该失败)
- result = player.pause();
- if (result == ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Should not be able to pause in Idle state" << std::endl;
- return false;
- }
-
- // 测试停止(应该成功,因为已经是停止状态)
- result = player.stop();
- if (result != ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Stop should always succeed" << std::endl;
- return false;
- }
-
- std::cout << "[PASS] Player state transitions test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试媒体文件打开(使用不存在的文件)
- */
- bool testMediaFileHandling() {
- std::cout << "\n=== Testing Media File Handling ===" << std::endl;
-
- PlayerCore player;
- TestPlayerCallback callback;
- player.setEventCallback(&callback);
-
- // 测试打开不存在的文件
- ErrorCode result = player.openFile("nonexistent_file.mp4");
- if (result == ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Should fail to open nonexistent file" << std::endl;
- return false;
- }
-
- // 测试打开空文件名
- result = player.openFile("");
- if (result == ErrorCode::SUCCESS) {
- std::cout << "[FAIL] Should fail to open empty filename" << std::endl;
- return false;
- }
-
- std::cout << "[PASS] Media file handling test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试播放器统计信息
- */
- bool testPlayerStats() {
- std::cout << "\n=== Testing Player Stats ===" << std::endl;
-
- PlayerCore player;
-
- // 获取初始统计信息
- PlaybackStats stats = player.getStats();
-
- // 验证初始值
- if (stats.currentTime != 0 || stats.playbackSpeed != 1.0) {
- std::cout << "[FAIL] Initial stats values incorrect" << std::endl;
- return false;
- }
-
- // 设置播放速度并验证统计信息
- player.setPlaybackSpeed(2.0);
- stats = player.getStats();
-
- if (std::abs(stats.playbackSpeed - 2.0) > 0.001) {
- std::cout << "[FAIL] Stats playback speed not updated" << std::endl;
- return false;
- }
-
- std::cout << "[PASS] Player stats test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试帧获取接口
- */
- bool testFrameInterface() {
- std::cout << "\n=== Testing Frame Interface ===" << std::endl;
-
- PlayerCore player;
-
- // 测试在没有媒体的情况下获取帧
- AVFrame* videoFrame = player.getNextVideoFrame();
- if (videoFrame != nullptr) {
- std::cout << "[FAIL] Should return null when no media loaded" << std::endl;
- return false;
- }
-
- AVFrame* audioFrame = player.getNextAudioFrame();
- if (audioFrame != nullptr) {
- std::cout << "[FAIL] Should return null when no media loaded" << std::endl;
- return false;
- }
-
- // 测试释放空帧(应该安全)
- player.releaseVideoFrame(nullptr);
- player.releaseAudioFrame(nullptr);
-
- std::cout << "[PASS] Frame interface test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试播放器更新循环
- */
- bool testPlayerUpdate() {
- std::cout << "\n=== Testing Player Update ===" << std::endl;
-
- PlayerCore player;
-
- // 调用更新函数(应该安全)
- player.update();
-
- // 多次调用更新
- for (int i = 0; i < 10; ++i) {
- player.update();
- std::this_thread::sleep_for(std::chrono::milliseconds(1));
- }
-
- std::cout << "[PASS] Player update test passed" << std::endl;
- return true;
- }
- /**
- * @brief 测试播放器多实例
- */
- bool testMultiplePlayerInstances() {
- std::cout << "\n=== Testing Multiple Player Instances ===" << std::endl;
-
- // 创建多个播放器实例
- std::vector<std::unique_ptr<PlayerCore>> players;
- std::vector<std::unique_ptr<TestPlayerCallback>> callbacks;
-
- for (int i = 0; i < 3; ++i) {
- auto player = std::make_unique<PlayerCore>();
- auto callback = std::make_unique<TestPlayerCallback>();
-
- player->setEventCallback(callback.get());
- player->setVolume(0.1 * (i + 1));
-
- players.push_back(std::move(player));
- callbacks.push_back(std::move(callback));
- }
-
- // 验证每个播放器的状态
- for (size_t i = 0; i < players.size(); ++i) {
- if (players[i]->getState() != PlayerState::Idle) {
- std::cout << "[FAIL] Player " << i << " state incorrect" << std::endl;
- return false;
- }
-
- double expectedVolume = 0.1 * (i + 1);
- if (std::abs(players[i]->getVolume() - expectedVolume) > 0.001) {
- std::cout << "[FAIL] Player " << i << " volume incorrect" << std::endl;
- return false;
- }
- }
-
- std::cout << "[PASS] Multiple player instances test passed" << std::endl;
- return true;
- }
- /**
- * @brief 运行所有测试
- */
- int main() {
- std::cout << "Starting Player Module Tests..." << std::endl;
-
- int passedTests = 0;
- int totalTests = 0;
-
- // 运行所有测试
- struct TestCase {
- const char* name;
- bool (*func)();
- };
-
- TestCase tests[] = {
- {"Player Basic Functions", testPlayerBasicFunctions},
- {"Player State Transitions", testPlayerStateTransitions},
- {"Media File Handling", testMediaFileHandling},
- {"Player Stats", testPlayerStats},
- {"Frame Interface", testFrameInterface},
- {"Player Update", testPlayerUpdate},
- {"Multiple Player Instances", testMultiplePlayerInstances}
- };
-
- for (const auto& test : tests) {
- totalTests++;
- try {
- if (test.func()) {
- passedTests++;
- }
- }
- catch (const std::exception& e) {
- std::cout << "[EXCEPTION] Test " << test.name << " threw: " << e.what() << std::endl;
- }
- catch (...) {
- std::cout << "[EXCEPTION] Test " << test.name << " threw unknown exception" << std::endl;
- }
- }
-
- // 输出测试结果
- std::cout << "\n=== Test Results ===" << std::endl;
- std::cout << "Passed: " << passedTests << "/" << totalTests << std::endl;
- std::cout << "Success Rate: " << (100.0 * passedTests / totalTests) << "%" << std::endl;
-
- if (passedTests == totalTests) {
- std::cout << "\n🎉 All tests passed!" << std::endl;
- return 0;
- } else {
- std::cout << "\n❌ Some tests failed!" << std::endl;
- return 1;
- }
- }
|