BOOL player_impl::open(const char *movie, int media_type, int render_type) { // 如果未关闭原来的媒体, 则先关闭. if (m_avplay || m_source) close(); // 未创建窗口, 无法播放, 返回失败. if (!IsWindow(m_hwnd)) return FALSE; char filename[MAX_PATH]; int len = strlen(movie) + 1; strcpy(filename, movie); int64_t file_lentgh = 0; if (media_type == MEDIA_TYPE_FILE || media_type == MEDIA_TYPE_BT) { file_lentgh = file_size(movie); if (file_lentgh < 0) { ::logger("get file size failed!\n"); return FALSE; } } do { // 创建avplay. m_avplay = alloc_avplay_context(); if (!m_avplay) { ::logger("allocate avplay context failed!\n"); break; } // 为avplay创建demux. demux_context *demux = alloc_demux_context(); configure(m_avplay, demux, MEDIA_DEMUX); // 目前只有除youku之外, 都使用generic_demux. if (media_type != MEDIA_TYPE_YK) { demux->init_demux = generic_init_demux; demux->read_packet = generic_read_packet; demux->seek_packet = generic_packet_seek; demux->read_pause = generic_read_pause; demux->read_play = generic_read_play; demux->stream_index = generic_stream_index; demux->query_avcodec_id = generic_query_avcodec_id; demux->destory = generic_destory; } else { // TODO: 实现youku相关的demux. break; } // 初始化avplay. if (initialize(m_avplay, filename, media_type, demux) != 0) { ::logger("initialize avplay failed!\n"); break; } // TODO: 如果是bt类型, 则在此得到视频文件列表, 并添加到m_media_list. // if (media_type == MEDIA_TYPE_BT) // { // bt_source_info *bt_info = &m_avplay->m_source_ctx->info.bt; // for (int i = 0; i < bt_info->info_size; i++) // { // std::string name = std::string(bt_info->info[i].file_name); // m_media_list.insert(std::make_pair(filename, name)); // } // } // 分配音频和视频的渲染器. m_audio = alloc_audio_render(); if (!m_audio) { ::logger("allocate audio render failed!\n"); break; } m_video = alloc_video_render(m_hwnd); if (!m_video) { ::logger("allocate video render failed!\n"); break; } // 初始化音频和视频渲染器. init_audio(m_audio); init_video(m_video, render_type); // 配置音频视频渲染器. configure(m_avplay, m_video, VIDEO_RENDER); configure(m_avplay, m_audio, AUDIO_RENDER); // 得到视频宽高. if (m_avplay->m_video_ctx) { m_video_width = m_avplay->m_video_ctx->width; m_video_height = m_avplay->m_video_ctx->height; } // 打开视频实时码率和帧率计算. enable_calc_frame_rate(m_avplay); enable_calc_bit_rate(m_avplay); return TRUE; } while (0); if (m_avplay) free_avplay_context(m_avplay); m_avplay = NULL; if (m_source) free_media_source(m_source); if (m_audio) free_audio_render(m_audio); if (m_video) free_video_render(m_video); ::logger("open avplay failed!\n"); return FALSE; }
BOOL player_impl::open(const char *movie, int media_type, int render_type) { // 如果未关闭原来的媒体, 则先关闭. if (m_avplay || m_source) close(); // 未创建窗口, 无法播放, 返回失败. if (!IsWindow(m_hwnd)) return FALSE; char filename[MAX_PATH]; int len = strlen(movie) + 1; strcpy(filename, movie); uint64_t file_lentgh = 0; if (media_type == MEDIA_TYPE_FILE || media_type == MEDIA_TYPE_BT) { file_lentgh = file_size(movie); if (file_lentgh < 0) { ::logger("get file size failed!\n"); return FALSE; } } do { // 创建avplay. m_avplay = alloc_avplay_context(); if (!m_avplay) { ::logger("allocate avplay context failed!\n"); break; } // 根据打开的文件类型, 创建不同媒体源. if (media_type == MEDIA_TYPE_FILE) { len = strlen(filename); m_source = alloc_media_source(MEDIA_TYPE_FILE, filename, len + 1, file_lentgh); if (!m_source) { ::logger("allocate media source failed, type is file.\n"); break; } // 插入到媒体列表. m_media_list.insert(std::make_pair(filename, filename)); // 初始化文件媒体源. init_file_source(m_source); } if (media_type == MEDIA_TYPE_BT) { // 先读取bt种子数据, 然后作为附加数据保存到媒体源. FILE *fp = fopen(filename, "r+b"); if (!fp) { ::logger("open torrent file \'%s\' failed!\n", filename); break; } char *torrent_data = (char*)malloc(file_lentgh); int readbytes = fread(torrent_data, 1, file_lentgh, fp); if (readbytes != file_lentgh) { ::logger("read torrent file \'%s\' failed!\n", filename); break; } m_source = alloc_media_source(MEDIA_TYPE_BT, torrent_data, file_lentgh, 0); if (!m_source) { ::logger("allocate media source failed, type is torrent.\n"); break; } free(torrent_data); // 初始化torrent媒体源. init_torrent_source(m_source); } if (media_type == MEDIA_TYPE_HTTP) { len = strlen(filename) + 1; m_source = alloc_media_source(MEDIA_TYPE_HTTP, filename, len, 0); if (!m_source) { ::logger("allocate media source failed, type is http.\n"); break; } // 插入到媒体列表. m_media_list.insert(std::make_pair(filename, filename)); } if (media_type == MEDIA_TYPE_RTSP) { len = strlen(filename) + 1; m_source = alloc_media_source(MEDIA_TYPE_RTSP, filename, len, 0); if (!m_source) { ::logger("allocate media source failed, type is rtsp.\n"); break; } // 插入到媒体列表. m_media_list.insert(std::make_pair(filename, filename)); } // 初始化avplay. if (initialize(m_avplay, m_source) != 0) { ::logger("initialize avplay failed!\n"); break; } // 如果是bt类型, 则在此得到视频文件列表, 并添加到m_media_list. if (media_type == MEDIA_TYPE_BT) { int i = 0; media_info *media = m_source->media; for (; i < m_source->media_size; i++) { std::string name; name = media->name; m_media_list.insert(std::make_pair(filename, name)); } } // 分配音频和视频的渲染器. m_audio = alloc_audio_render(); if (!m_audio) { ::logger("allocate audio render failed!\n"); break; } m_video = alloc_video_render(m_hwnd); if (!m_video) { ::logger("allocate video render failed!\n"); break; } // 初始化音频和视频渲染器. init_audio(m_audio); init_video(m_video); // 配置音频视频渲染器. configure(m_avplay, m_video, VIDEO_RENDER); configure(m_avplay, m_audio, AUDIO_RENDER); // 得到视频宽高. m_video_width = av_width(m_avplay); m_video_height = av_height(m_avplay); // 打开视频实时码率和帧率计算. enable_calc_frame_rate(m_avplay); enable_calc_bit_rate(m_avplay); return TRUE; } while (0); if (m_avplay) free_avplay_context(m_avplay); m_avplay = NULL; if (m_source) free_media_source(m_source); if (m_audio) free_audio_render(m_audio); if (m_video) free_video_render(m_video); ::logger("open avplay failed!\n"); return FALSE; }