Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}