【MediaPlayer】基于libvlc+awtk的媒体播放器

libvlc

下载地址

  1. 可以到https://download.videolan.org/pub/videolan/vlc/去下载一个vlc版本,下载后其实是vlc的windows客户端,里面包含sdk目录,用于windows程序链接libvlc
  2. 需要的文件为:sdk/include、sdk/lib、libvlc.dll、libvlc_core.dll

awtk

下载地址

  1. AWTK是一套基于C语言的国产UI框架,目前开源在https://github.com/zlgopen/awtk,可自行下载后,按照文档编译即可,编译方法也很简单

代码实现

以像素格式RGBA8888为例

libvlc相关逻辑接口

  1. 头文件
#ifndef __TASK_MEDIA_PLAYER_H__
#define __TASK_MEDIA_PLAYER_H__

#include <stdint.h>

typedef int(*VideoFrameCb)(const unsigned char* data, const char* format, int w, int h, void* ctx);

typedef int(*AudioFrameCb)(const unsigned char* data, const char* format, int sampleRate, void* ctx);


typedef enum {
	MEDIA_STATUS_NONE,
	MEDIA_STATUS_OPENING,
	MEDIA_STATUS_PLAYING,
	MEDIA_STATUS_PAUSE,
	MEDIA_STATUS_STOP,
	MEDIA_STATUS_END,
	MEDIA_STATUS_ERROR,
}mediaStateEnum;

/*
* @function: taskMediaPlayerCreateLocal
* @params:
*    filePath: 媒体文件路径
* @brief:
*    创建本地文件的媒体播放器
*    成功返回播放器句柄,失败返回NULL
*/
void* taskMediaPlayerCreateLocal(const char* filePath);

/*
* @function: taskMediaPlayerCreateLocation
* @params:
*    path: 网络串流媒体路径
* @brief:
*    创建网络串流的媒体播放器
*    成功返回播放器句柄,失败返回NULL
*/
void* taskMediaPlayerCreateLocation(const char* path);

/*
* @function: taskMediaPlayerStart
* @params:
*    handle: 播放器句柄
* @brief:
*    开启播放
*/
int taskMediaPlayerStart(void** handle);

/*
* @function: taskMediaPlayerIsPlaying
* @params:
*    handle: 播放器句柄
* @brief:
*    查询是否处于播放状态
*    1:处于播放状态,0:不处于播放状态
*/
int taskMediaPlayerIsPlaying(void** handle);

/*
* @function: taskMediaPlayerPause
* @params:
*    handle: 播放器句柄
* @brief:
*    暂停播放
*/
int taskMediaPlayerPause(void** handle);

/*
* @function: taskMediaPlayerResume
* @params:
*    handle: 播放器句柄
* @brief:
*    恢复播放
*/
int taskMediaPlayerResume(void** handle);

/*
* @function: taskMediaPlayerStop
* @params:
*    handle: 播放器句柄
* @brief:
*    停止播放
*/
int taskMediaPlayerStop(void** handle);

/*
* @function: taskMediaPlayerRelease
* @params:
*    handle: 播放器句柄
* @brief:
*    释放播放器资源
*/
int taskMediaPlayerRelease(void** handle);

/*
* @function: taskMediaPlayerTakeSnapshot
* @params:
*    handle: 播放器句柄
*    fileName: 需要保存的文件路径
* @brief:
*    截图,成功返回0,失败返回-1
*/
int taskMediaPlayerTakeSnapshot(void** handle, const char* fileName);

/*
* @function: taskMediaPlayerSetFormat
* @params:
*    handle: 播放器句柄
*    format: 编码格式("RGBA/RV32/RV16"等等)
*    w: 输出视频宽度
*    h: 输出视频高度
* @brief:
*    设置编码格式和输出宽高
*/
int taskMediaPlayerSetFormat(void** handle, const char* format, int w, int h);

/*
* @function: taskMediaPlayerSetCallback
* @params:
*    handle: 播放器句柄
*    videoCb: 视频输出回调
*    videoCtx: 视频回调参数
*    audioCb: 音频输出回调
*    audioCtx: 音频回调参数
* @brief:
*    设置音视频输出的回调,每一帧解码都会调用回调,供上层应用播放和显示
*/
int taskMediaPlayerSetCallback(void** handle, VideoFrameCb videoCb, void* videoCtx, AudioFrameCb audioCb, void* audioCtx);

/*
* @function: taskMediaPlayerGetMediaSize
* @params:
*    handle: 播放器句柄
*    num: 视频编号(通常是0)
*    width: 视频宽度[out]
*    height: 视频高度[out]
* @brief:
*    成功返回0,失败返回-1
*/
int taskMediaPlayerGetMediaSize(void** handle, unsigned int num, unsigned int *width, unsigned int* height);

/*
* @function: taskMediaPlayerSetMediaScale
* @params:
*    handle: 播放器句柄
*    scale: 视频缩放倍数
* @brief:
*    成功返回0,失败返回-1
*/
int taskMediaPlayerSetMediaScale(void** handle, float scale);

/*
* @function: taskMediaPlayerGetMediaScale
* @params:
*    handle: 播放器句柄
* @brief:
*    成功返回视频播放倍数,失败返回0.0
*/
float taskMediaPlayerGetMediaScale(void** handle);

/*
* @function: taskMediaPlayerGetMediaLength
* @params:
*    handle: 播放器句柄
* @brief:
*    成功返回媒体总时长(ms),失败返回-1
*/
int64_t taskMediaPlayerGetMediaLength(void** handle);

/*
* @function: taskMediaPlayerGetMediaTime
* @params:
*    handle: 播放器句柄
* @brief:
*    成功返回媒体当前播放时长(ms),失败返回-1
*/
int64_t taskMediaPlayerGetMediaTime(void** handle);

/*
* @function: taskMediaPlayerSetMediaTime
* @params:
*    handle: 播放器句柄
*    timeMs: 设置媒体当前播放时间偏移(ms)
* @brief:
*    成功返回0,失败返回-1
*/
int taskMediaPlayerSetMediaTime(void** handle, int64_t timeMs);

/*
* @function: taskMediaPlayerSetMediaVolume
* @params:
*    handle: 播放器句柄
*    volume: 音量值[0, 100]
* @brief:
*    成功返回0,失败返回-1
*/
int taskMediaPlayerSetMediaVolume(void** handle, int volume);

/*
* @function: taskMediaPlayerGetMediaVolume
* @params:
*    handle: 播放器句柄
* @brief:
*    成功返回音量值,失败返回-1
*/
int taskMediaPlayerGetMediaVolume(void** handle);

/*
* @function: taskMediaPlayerGetMediaPosition
* @params:
*    handle: 播放器句柄
* @brief:
*    获取当前媒体播放进度位置,[0.0, 1.0]
*/
float taskMediaPlayerGetMediaPosition(void** handle);

/*
* @function: taskMediaPlayerSetMediaPosition
* @params:
*    handle: 播放器句柄
*    pos: 进度
* @brief:
*    设置当前媒体播放进度位置,[0.0, 1.0]
*/
int taskMediaPlayerSetMediaPosition(void** handle, float pos);

/*
* @function: taskMediaPlayerGetMediaRate
* @params:
*    handle: 播放器句柄
*    pos: 进度
* @brief:
*    返回当前媒体播放速率
*/
float taskMediaPlayerGetMediaRate(void** handle);

/*
* @function: taskMediaPlayerGetMediaRate
* @params:
*    handle: 播放器句柄
*    rate: 播放速率
* @brief:
*    设置当前媒体播放速率
*/
int taskMediaPlayerSetMediaRate(void** handle, float rate);

/*
* @function: taskMediaPlayerGetMediaState
* @params:
*    handle: 播放器句柄
* @brief:
*    获取媒体播放状态
*/
mediaStateEnum taskMediaPlayerGetMediaState(void** handle);

/*
* @function: taskMediaPlayerGetUrlIsValid
* @params:
*    url: 播放的url
* @brief:
*    获取url是否是有效的
*    1: 有效, 0: 无效
*/
int taskMediaPlayerGetUrlIsValid(const char* url);


#endif // !__TASK_TOOLS_MEDIA_PLAYER_H__

  1. c 文件
#include <string.h>
#include "task_media_player.h"
#include "tools/log.h"
#include "tools/tools_typedef.h"
#include "tools/libc_str.h"

#ifdef _WIN32  
#include <stddef.h> // 包含 ptrdiff_t 的定义  
typedef ptrdiff_t ssize_t;
#endif

#include "vlc/vlc.h"



#define TASK_MEDIA_PLAYER_TAG	"media_player"


typedef struct {
	libvlc_instance_t * instance;
	libvlc_media_player_t *mediaPlayer;
	libvlc_media_t *media;
	unsigned char* pixel;
	char format[16];
	int w;
	int h;
	int frameSize;
	VideoFrameCb videoCb;
	void* videoCtx;
	AudioFrameCb audioCb;
	void* audioCtx;
}vlcMediaPlayer_t;

static unsigned mediaVideoFormatSetup(void **opaque, char *chroma, unsigned *width, unsigned *height,
	unsigned *pitches, unsigned *lines) {
	vlcMediaPlayer_t** mediaPlayer = (vlcMediaPlayer_t**)opaque;
	if (mediaPlayer != NULL && *mediaPlayer != NULL) {
		strcpy(chroma, (*mediaPlayer)->format);
		*width = (*mediaPlayer)->w;
		*height = (*mediaPlayer)->h;
		if (strcmp(chroma, "RGBA") == 0) {
			*pitches = 4 * (*mediaPlayer)->w;
			*lines = (*mediaPlayer)->h;
		}
		return 1;
	}
	return 0;
}

static void *mediaVideoLock(void *opaque, void **planes) {
	vlcMediaPlayer_t* mediaPlayer = (vlcMediaPlayer_t*)opaque;
	*planes = mediaPlayer->pixel;
	return NULL;
}

static void mediaVideoUnlock(void *opaque, void *picture, void *const *planes) {
	vlcMediaPlayer_t* mediaPlayer = (vlcMediaPlayer_t*)opaque;
	if (mediaPlayer->videoCb != NULL) {
		mediaPlayer->videoCb((const unsigned char*)(*planes), mediaPlayer->format, mediaPlayer->w, mediaPlayer->h, mediaPlayer->videoCtx);
	}
}

static void mediaVideoDisplay(void *opaque, void *picture) {

}

void* taskMediaPlayerCreateLocal(const char* filePath) {
	return_val_if_fail(filePath != NULL, NULL);

	vlcMediaPlayer_t* vlcMediaPlayer = calloc(1, sizeof(vlcMediaPlayer_t));
	if (vlcMediaPlayer != NULL) {
		vlcMediaPlayer->instance = libvlc_new(0, NULL);
		vlcMediaPlayer->media = libvlc_media_new_path(vlcMediaPlayer->instance, filePath);
		if (vlcMediaPlayer->media != NULL) {
			vlcMediaPlayer->mediaPlayer = libvlc_media_player_new_from_media(vlcMediaPlayer->media);
		}
		else {
			libvlc_release(vlcMediaPlayer->instance);
			free(vlcMediaPlayer);
			return NULL;
		}
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p successfully!\n", __func__, vlcMediaPlayer);
		return vlcMediaPlayer;
	}
	log_Debug(TASK_MEDIA_PLAYER_TAG, "%s failed!\n", __func__);
	return NULL;
}

void* taskMediaPlayerCreateLocation(const char* path) {
	return_val_if_fail(path != NULL, NULL);

	vlcMediaPlayer_t* vlcMediaPlayer = calloc(1, sizeof(vlcMediaPlayer_t));
	if (vlcMediaPlayer != NULL) {
		vlcMediaPlayer->instance = libvlc_new(0, NULL);
		vlcMediaPlayer->media = libvlc_media_new_location(vlcMediaPlayer->instance, path);
		if (vlcMediaPlayer->media != NULL) {
			vlcMediaPlayer->mediaPlayer = libvlc_media_player_new_from_media(vlcMediaPlayer->media);
		}
		else {
			libvlc_release(vlcMediaPlayer->instance);
			free(vlcMediaPlayer);
			return NULL;
		}
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p, path:%s successfully!\n", __func__, vlcMediaPlayer, path);
		return vlcMediaPlayer;
	}
	log_Debug(TASK_MEDIA_PLAYER_TAG, "%s failed!\n", __func__);
	return NULL;
}

int taskMediaPlayerStart(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p!\n", __func__, *vlcMediaPlayer);
		return libvlc_media_player_play((*vlcMediaPlayer)->mediaPlayer);
	}
	return -1;
}

int taskMediaPlayerIsPlaying(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_is_playing((*vlcMediaPlayer)->mediaPlayer);
	}
	return 0;
}

int taskMediaPlayerPause(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_media_player_set_pause((*vlcMediaPlayer)->mediaPlayer, 1);
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p!\n", __func__, *vlcMediaPlayer);
		return 0;
	}
	return -1;
}

int taskMediaPlayerResume(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_media_player_set_pause((*vlcMediaPlayer)->mediaPlayer, 0);
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p!\n", __func__, *vlcMediaPlayer);
		return 0;
	}
	return -1;
}

int taskMediaPlayerStop(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_media_player_stop((*vlcMediaPlayer)->mediaPlayer);
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p!\n", __func__, *vlcMediaPlayer);
		return 0;
	}
	return -1;
}

int taskMediaPlayerRelease(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		if (taskMediaPlayerIsPlaying(handle)) {
			libvlc_media_player_stop((*vlcMediaPlayer)->mediaPlayer);
		}
		libvlc_media_player_release((*vlcMediaPlayer)->mediaPlayer);
		libvlc_media_release((*vlcMediaPlayer)->media);
		libvlc_release((*vlcMediaPlayer)->instance);
		log_Debug(TASK_MEDIA_PLAYER_TAG, "%s:%p successfully!\n", __func__, *vlcMediaPlayer);
		if ((*vlcMediaPlayer)->pixel != NULL) {
			free((*vlcMediaPlayer)->pixel);
		}
		free(*vlcMediaPlayer);
		*vlcMediaPlayer = NULL;
		return 0;
	}
	return -1;
}

int taskMediaPlayerTakeSnapshot(void** handle, const char* fileName) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_video_take_snapshot((*vlcMediaPlayer)->mediaPlayer, 0, fileName, 0, 0);
	}
	return -1;
}

int taskMediaPlayerSetFormat(void** handle, const char* format, int w, int h) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		int size = 0;
		if (strcmp(format, "RGBA") == 0) {
			size = sizeof(char) * w * h * 4;
		}
		(*vlcMediaPlayer)->w = w;
		(*vlcMediaPlayer)->h = h;
		strlcpy((*vlcMediaPlayer)->format, format, sizeof((*vlcMediaPlayer)->format));
		if (size != (*vlcMediaPlayer)->frameSize) {
			(*vlcMediaPlayer)->frameSize = size;
			if ((*vlcMediaPlayer)->pixel != NULL) {
				free((*vlcMediaPlayer)->pixel);
			}
			if ((*vlcMediaPlayer)->pixel == NULL) {
				(*vlcMediaPlayer)->pixel = calloc(1, (*vlcMediaPlayer)->frameSize + 1);
			}
		}
		//libvlc_video_set_format((*vlcMediaPlayer)->mediaPlayer, format, w, h, w*4);
		return 0;
	}
	return -1;
}

int taskMediaPlayerSetCallback(void** handle, VideoFrameCb videoCb, void* videoCtx, 
	AudioFrameCb audioCb, void* audioCtx) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		(*vlcMediaPlayer)->videoCb = videoCb;
		(*vlcMediaPlayer)->videoCtx = videoCtx;
		(*vlcMediaPlayer)->audioCb = audioCb;
		(*vlcMediaPlayer)->audioCtx = audioCtx;
		libvlc_video_set_format_callbacks((*vlcMediaPlayer)->mediaPlayer, mediaVideoFormatSetup, NULL);
		libvlc_video_set_callbacks((*vlcMediaPlayer)->mediaPlayer, mediaVideoLock, mediaVideoUnlock, mediaVideoDisplay, *vlcMediaPlayer);
		return 0;
	}
	return -1;
}

int taskMediaPlayerGetMediaSize(void** handle, unsigned int num, unsigned int *width, unsigned int* height) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL && width != NULL && height != NULL) {
		return ((libvlc_video_get_size((*vlcMediaPlayer)->mediaPlayer, num, width, height) == 0) && *width > 0 && *height > 0) ? 0 : -1;
	}
	return -1;
}

int taskMediaPlayerSetMediaScale(void** handle, float scale) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_video_set_scale((*vlcMediaPlayer)->mediaPlayer, scale);
		return 0;
	}
	return -1;
}

float taskMediaPlayerGetMediaScale(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_video_get_scale((*vlcMediaPlayer)->mediaPlayer);
	}
	return 0.0;
}

int64_t taskMediaPlayerGetMediaLength(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_get_length((*vlcMediaPlayer)->mediaPlayer);
	}
	return -1;
}

int64_t taskMediaPlayerGetMediaTime(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_get_time((*vlcMediaPlayer)->mediaPlayer);
	}
	return -1;
}

int taskMediaPlayerSetMediaTime(void** handle, int64_t timeMs) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_media_player_set_time((*vlcMediaPlayer)->mediaPlayer, timeMs);
		return 0;
	}
	return -1;
}

int taskMediaPlayerSetMediaVolume(void** handle, int volume) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_audio_set_volume((*vlcMediaPlayer)->mediaPlayer, volume);
	}
	return -1;
}

int taskMediaPlayerGetMediaVolume(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_audio_get_volume((*vlcMediaPlayer)->mediaPlayer);
	}
	return -1;
}

float taskMediaPlayerGetMediaPosition(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_get_position((*vlcMediaPlayer)->mediaPlayer);
	}
	return 0.0;
}

int taskMediaPlayerSetMediaPosition(void** handle, float pos) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		libvlc_media_player_set_position((*vlcMediaPlayer)->mediaPlayer, pos);
		return 0;
	}
	return -1;
}

float taskMediaPlayerGetMediaRate(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_get_rate((*vlcMediaPlayer)->mediaPlayer);
	}
	return 0.0;
}

int taskMediaPlayerSetMediaRate(void** handle, float rate) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		return libvlc_media_player_set_rate((*vlcMediaPlayer)->mediaPlayer, rate);
	}
	return -1;
}

mediaStateEnum taskMediaPlayerGetMediaState(void** handle) {
	vlcMediaPlayer_t** vlcMediaPlayer = (vlcMediaPlayer_t**)handle;
	if (vlcMediaPlayer != NULL && *vlcMediaPlayer != NULL) {
		mediaStateEnum mediaState = MEDIA_STATUS_NONE;
		libvlc_state_t state = libvlc_media_player_get_state((*vlcMediaPlayer)->mediaPlayer);
		switch (state) {
		case libvlc_Opening:
			mediaState = MEDIA_STATUS_OPENING;
			break;
		case libvlc_Playing:
			mediaState = MEDIA_STATUS_PLAYING;
			break;
		case libvlc_Paused:
			mediaState = MEDIA_STATUS_PAUSE;
			break;
		case libvlc_Stopped:
			mediaState = MEDIA_STATUS_STOP;
			break;
		case libvlc_Ended:
			mediaState = MEDIA_STATUS_END;
			break;
		case libvlc_Error:
			mediaState = MEDIA_STATUS_ERROR;
			break;
		}
		return mediaState;
	}
	return MEDIA_STATUS_NONE;
}

int taskMediaPlayerGetUrlIsValid(const char* url) {
	if(url == NULL) return 0;

	if(strStartWith(url, "file:///")
		|| strStartWith(url, "rtsp://")
		|| strStartWith(url, "http://")
		|| strStartWith(url, "mms://")
		|| strStartWith(url, "screen://")
		|| strStartWith(url, "dvd://")
		|| strStartWith(url, "vcd://")
		|| strStartWith(url, "cdda://")
		|| strStartWith(url, "udp://")) {
		return 1;
	}
	return 0;
}

UI媒体接口

一、UI媒体播放接口,使用AWTK自带的mutable_image控件,AWTK控件的使用,可在AWTK控件的使用去查看官方文档,以及AWTK源码里doc/目录的各种文档

二、代码封装如下:

  1. 头文件
#ifndef __UI_MEDIA_PLAYER_LIST_H__
#define __UI_MEDIA_PLAYER_LIST_H__

#include <stdio.h>
#include "awtk.h"


typedef enum {
	MEDIA_START,
	MEDIA_PAUSE,
	MEDIA_STOP,
}MEDIA_PLAY_ACTION;

typedef enum {
	MEDIA_STATE_NONE,
	MEDIA_STATE_OPENING,
	MEDIA_STATE_PLAYING,
	MEDIA_STATE_PAUSE,
	MEDIA_STATE_STOP,
	MEDIA_STATE_END,
	MEDIA_STATE_ERROR,
}MEDIA_PLAY_STATE;

typedef struct mediaPlayerList {
	/* public */
	int (*getUrlIsValid)(const char* url);
	ret_t(*setDrawRectParam)(widget_t* mutableImage, void* handle);
	void* (*getMediaHandle)(void* handle);
	int(*getPlayVideoState)(void* handle);
	ret_t (*getPlayVideoSize)(void* handle, int num, int *w, int*h);
	ret_t (*createPlayVideoBitmap)(void* handle, bitmap_format_t format, int w, int h);
	ret_t (*getPlayVideoFrame)(void* handle, bitmap_t* image);
	ret_t(*takeSnapShot)(void* handle, const char* filePath);
	int64_t(*getMediaLenth)(void* handle);
	int64_t(*getMediaTime)(void* handle);
	ret_t(*setMediaPosition)(void* handle, float position);
	float(*getMediaPosition)(void* handle);
	ret_t(*setMediaVolume)(void* handle, int volume);
	int(*getMediaVolume)(void* handle);
	ret_t(*setPlayVideoFormat)(void* handle, const char* format, int w, int h);
	ret_t(*start)(void* handle, const char* url);
	ret_t(*pause)(void* handle);
	ret_t(*stop)(void* handle);

	widget_t* mutableImage;

	/* private */
	bitmap_t* image;
	int playState;
	void* mediaHandle;
	int needClearImge; /* 结束时清除一帧mutableImage */
}mediaPlayerList_t;

/*
* @function: uiMediaPlayerListCreate
* @params:
*    无
* @brief:
*    创建播放器
*/
mediaPlayerList_t* uiMediaPlayerListCreate(void);

/*
* @function: uiMediaPlayerListDestroy
* @params:
*    mediaPlayList: 播放器句柄
* @brief:
*    销毁播放器
*/
ret_t uiMediaPlayerListDestroy(mediaPlayerList_t** mediaPlayList);

#endif // !__UI_MEDIA_PLAYER_LIST_H__

  1. c 文件
#include <stdio.h>
#include "ui_media_player_list.h"
#include "task/media_player/task_media_player.h"
#include "tools/log.h"


#define UI_MEDIA_PLAYLIST_TAG	"ui_media_play_list.c"

static ret_t uiMediaPlayerListStop(void* handle);

static bitmap_t* uiMediaPlayerListCreateImage(void* ctx, bitmap_format_t format, bitmap_t* old_image) {
	bitmap_t* image = old_image;
	mediaPlayerList_t* playList = (mediaPlayerList_t*)ctx;
	return_value_if_fail(playList != NULL && playList->mutableImage != NULL, NULL);

	if (playList->getPlayVideoState(playList) == MEDIA_STATE_PLAYING) {
		uint32_t ww = playList->mutableImage->w;
		uint32_t wh = playList->mutableImage->h;
		uint32_t vw = playList->mutableImage->w;
		uint32_t vh = playList->mutableImage->h;
		if (playList->getPlayVideoSize(playList, 0, &vw, &vh) == RET_OK) {
			double scale_w = (double)ww / (double)vw;
			double scale_h = (double)wh / (double)vh;
			double scale = tk_min(scale_w, scale_h);

			uint32_t iw = (uint32_t)(vw * scale) / 32 * 32;
			uint32_t ih = (uint32_t)(vh * scale) / 32 * 32;
			playList->setPlayVideoFormat(playList, "RGBA", iw, ih);
			if (old_image != NULL) {
				if (old_image->w != iw || old_image->h != ih) {
					bitmap_destroy(old_image);
					old_image = NULL;
				}
			}

			if (old_image == NULL && iw > 0 && ih > 0) {
				image = bitmap_create_ex(iw, ih, 0, format);
				playList->createPlayVideoBitmap(playList, format, iw, ih);
			}
		}
	}
	return image;
}

static ret_t uiMediaPlayerListPrepareImage(void* ctx, bitmap_t* image) {
	mediaPlayerList_t* playList = (mediaPlayerList_t*)ctx;
	if (playList != NULL && playList->needClearImge) {
		rect_t r = rect_init(0, 0, image->w, image->h);
		color_t color;
		color.rgba.r = 0;
		color.rgba.g = 0;
		color.rgba.b = 0;
		color.rgba.a = 0;
		playList->needClearImge = 0;
		return image_clear(image, &r, color);
	}
	else if (playList != NULL) {
		return playList->getPlayVideoFrame(playList, image);
	}
	return RET_FAIL;
}

static bool_t uiMediaPlayerListNeedRedrawImage(void* ctx) {
	mediaPlayerList_t *playList = (mediaPlayerList_t*)ctx;
	if (playList != NULL) {
		return (playList->getPlayVideoState(playList) == MEDIA_STATE_PLAYING) || (playList->needClearImge == 1);
	}
	return FALSE;
}

static ret_t uiMediaPlayerListSetDrawRectParam(widget_t* mutableImage, void* handle) {
	mediaPlayerList_t* playList = (mediaPlayerList_t*)handle;
	playList->mutableImage = mutableImage;
	mutable_image_set_create_image(mutableImage, uiMediaPlayerListCreateImage, handle);
	mutable_image_set_prepare_image(mutableImage, uiMediaPlayerListPrepareImage, handle);
	mutable_image_set_need_redraw(mutableImage, uiMediaPlayerListNeedRedrawImage, handle);
}

static int uiMediaVideoCb(const unsigned char* data, const char* format, int w, int h, void* ctx) {
	mediaPlayerList_t *mediaPlayList = (mediaPlayerList_t*)ctx;
	if (mediaPlayList != NULL && mediaPlayList->image != NULL) {
		if (tk_str_eq(format, "RGBA")) {
			uint32_t i = 0;
			uint32_t bpp = 0;
			uint32_t size = 0;
			uint8_t* image_data = NULL;
			bitmap_format_t bitmapFormat = mediaPlayList->image->format;
			bpp = bitmap_get_bpp(mediaPlayList->image);
			size = mediaPlayList->image->h * bitmap_get_line_length(mediaPlayList->image);
			image_data = bitmap_lock_buffer_for_write(mediaPlayList->image);
			for (; i < size && i < w * h * 4; i += bpp, image_data += bpp) {
				if(bitmapFormat == BITMAP_FMT_RGBA8888) {
					image_data[0] = data[i];
					image_data[1] = data[i + 1];
					image_data[2] = data[i + 2];
					image_data[3] = data[i + 3];
				} else {
					image_data[0] = data[i + 2];
					image_data[1] = data[i + 1];
					image_data[2] = data[i];
					image_data[3] = data[i + 3];
				}
			}
			bitmap_unlock_buffer(mediaPlayList->image);
		}
	}
	return 0;
}

static ret_t uiMediaPlayerListStart(void* handle, const char* url) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList == NULL) {
		log_Error(UI_MEDIA_PLAYLIST_TAG, "%s, error! playState=%d\n", __func__, mediaPlayList!=NULL?mediaPlayList->playState:-1);
		return RET_FAIL;
	}
	if (mediaPlayList->playState == MEDIA_STATE_PLAYING || mediaPlayList->playState == MEDIA_STATE_NONE) {
		uiMediaPlayerListStop(mediaPlayList);
		mediaPlayList->playState = MEDIA_STATE_NONE;
	}
	if (mediaPlayList->playState == MEDIA_STATE_PAUSE){
		mediaPlayList->playState = MEDIA_STATE_PLAYING;
		taskMediaPlayerResume(&mediaPlayList->mediaHandle);
	}
	else if(mediaPlayList->playState == MEDIA_STATE_NONE){ /* 播放 */
		mediaPlayList->mediaHandle = taskMediaPlayerCreateLocation(url);
		if (mediaPlayList->mediaHandle != NULL) {
			taskMediaPlayerSetCallback(&mediaPlayList->mediaHandle, uiMediaVideoCb, mediaPlayList, NULL, NULL);
			taskMediaPlayerStart(&mediaPlayList->mediaHandle);
			mediaPlayList->playState = MEDIA_STATE_PLAYING;
		}
		else {
			return RET_FAIL;
		}
	}
	return RET_OK;
}

static ret_t uiMediaPlayerListPause(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		mediaPlayList->playState = MEDIA_STATE_PAUSE;
		return taskMediaPlayerPause(&mediaPlayList->mediaHandle) == 0 ? RET_OK : RET_FAIL;
	}
	return RET_FAIL;
}

static ret_t uiMediaPlayerListStop(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	return_value_if_fail(mediaPlayList != NULL, RET_FAIL);
	if (mediaPlayList->mediaHandle != NULL) {
		taskMediaPlayerRelease(&mediaPlayList->mediaHandle);
		mediaPlayList->mediaHandle = NULL;
	}
	if (mediaPlayList->image != NULL) {
		rect_t r = rect_init(0, 0, mediaPlayList->image->w, mediaPlayList->image->h);
		color_t color;
		color.rgba.r = 0;
		color.rgba.g = 0;
		color.rgba.b = 0;
		color.rgba.a = 0;
		image_clear(mediaPlayList->image, &r, color);
	}
	mediaPlayList->playState = MEDIA_STATE_NONE;
	mediaPlayList->needClearImge = 1;
	return RET_OK;
}

static int uiMediaPlayerListGetState(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL) {
		return (MEDIA_PLAY_STATE)taskMediaPlayerGetMediaState(&mediaPlayList->mediaHandle);
	}
	return MEDIA_STATE_NONE;
}

static ret_t uiMediaPlayerListSetFormat(void* handle, const char* format, int w, int h) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL) {
		taskMediaPlayerSetFormat(&mediaPlayList->mediaHandle, format, w, h);
	}
	return RET_OK;
}

static ret_t uiMediaPlayerListCreateBitmap(void* handle, bitmap_format_t format, int w, int h) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList == NULL) {
		return RET_FAIL;
	}
	if (mediaPlayList->image != NULL) {
		bitmap_destroy(mediaPlayList->image);
		mediaPlayList->image = NULL;
	}

	if (mediaPlayList->image == NULL) {
		mediaPlayList->image = bitmap_create_ex(w, h, 0, format);
	}
	return RET_OK;
}

static ret_t uiMediaPlayerListGetVideoSize(void* handle, int num, int* w, int *h) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL) {
		return taskMediaPlayerGetMediaSize(&mediaPlayList->mediaHandle, 0, w, h) == 0 ? RET_OK : RET_FAIL;
	}
	return RET_FAIL;
}

static ret_t uiMediaPlayerListGetVideoFrame(void* handle, bitmap_t* image) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->playState == MEDIA_STATE_PLAYING && mediaPlayList->image != NULL) {
		rect_t r = rect_init(0, 0, image->w, image->h);
		return image_copy(image, mediaPlayList->image, &r, 0, 0);
	}
	return RET_FAIL;
}

static ret_t uiMediaPlayerListTakeSnapShot(void* handle, const char* filePath) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerTakeSnapshot(&mediaPlayList->mediaHandle, filePath) == 0 ? RET_OK : RET_FAIL;
	}
	return RET_FAIL;
}

static int64_t uiMediaPlayerListGetMediaLenth(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerGetMediaLength(&mediaPlayList->mediaHandle) ;
	}
	return 0;
}

static int64_t uiMediaPlayerListGetMediaTime(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerGetMediaTime(&mediaPlayList->mediaHandle);
	}
	return 0;
}

static float uiMediaPlayerListGetMediaPosition(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerGetMediaPosition(&mediaPlayList->mediaHandle);
	}
	return 0.0;
}

static ret_t uiMediaPlayerListSetMediaPosition(void* handle, float pos) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerSetMediaPosition(&mediaPlayList->mediaHandle, pos) == 0 ? RET_OK : RET_FAIL;
	}
	return RET_FAIL;
}

static ret_t uiMediaPlayerListSetMediaVolume(void* handle, int volume) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerSetMediaVolume(&mediaPlayList->mediaHandle, volume) == 0 ? RET_OK : RET_FAIL;
	}
	return RET_FAIL;
}

static int uiMediaPlayerListGetMediaVolume(void* handle) {
	mediaPlayerList_t* mediaPlayList = (mediaPlayerList_t*)handle;
	if (mediaPlayList != NULL && mediaPlayList->mediaHandle != NULL) {
		return taskMediaPlayerGetMediaVolume(&mediaPlayList->mediaHandle);
	}
	return -1;
}

static int uiMediaPlayerListGetUrlIsValid(const char* url) {
	return_value_if_fail(url != NULL, 0);
	return taskMediaPlayerGetUrlIsValid(url);
}

mediaPlayerList_t* uiMediaPlayerListCreate(void) {
	mediaPlayerList_t* mediaPlayList = calloc(1, sizeof(mediaPlayerList_t));
	if (mediaPlayList != NULL) {
		mediaPlayList->start = uiMediaPlayerListStart;
		mediaPlayList->pause = uiMediaPlayerListPause;
		mediaPlayList->stop = uiMediaPlayerListStop;
		mediaPlayList->createPlayVideoBitmap = uiMediaPlayerListCreateBitmap;
		mediaPlayList->getPlayVideoFrame = uiMediaPlayerListGetVideoFrame;
		mediaPlayList->getPlayVideoSize = uiMediaPlayerListGetVideoSize;
		mediaPlayList->getPlayVideoState = uiMediaPlayerListGetState;
		mediaPlayList->setPlayVideoFormat = uiMediaPlayerListSetFormat;
		mediaPlayList->takeSnapShot = uiMediaPlayerListTakeSnapShot;
		mediaPlayList->getMediaLenth = uiMediaPlayerListGetMediaLenth;
		mediaPlayList->getMediaTime = uiMediaPlayerListGetMediaTime;
		mediaPlayList->setMediaPosition = uiMediaPlayerListSetMediaPosition;
		mediaPlayList->getMediaPosition = uiMediaPlayerListGetMediaPosition;
		mediaPlayList->setMediaVolume = uiMediaPlayerListSetMediaVolume;
		mediaPlayList->getMediaVolume = uiMediaPlayerListGetMediaVolume;
		mediaPlayList->setDrawRectParam = uiMediaPlayerListSetDrawRectParam;
		mediaPlayList->getUrlIsValid = uiMediaPlayerListGetUrlIsValid;
	}
	return mediaPlayList;
}

ret_t uiMediaPlayerListDestroy(mediaPlayerList_t** mediaPlayList) {
	if (mediaPlayList != NULL && *mediaPlayList != NULL) {
		if ((*mediaPlayList)->mediaHandle != NULL) {
			uiMediaPlayerListStop(mediaPlayList);
		}
		if ((*mediaPlayList)->image != NULL) {
			bitmap_destroy((*mediaPlayList)->image);
			(*mediaPlayList)->image = NULL;
		}
		free(*mediaPlayList);
		*mediaPlayList = NULL;
	}
	return RET_OK;
}

实例化媒体播放器

  1. main.c:
#include "awtk.h"
#include "assets.inc"


ret_t application_init(void) {
	window_manager_set_max_fps(window_manager(), 120);
	widget_t* win = window_open("media_play_win");
	mediaPlayerList_t* playList = uiMediaPlayerListCreate();
	widget_t* mutable_image = widget_lookup(win, "video_mutable", TRUE);
	playList->setDrawRectParam(mutable_image, playList);
	playList->start(playList, "E:\\test.avi");
	return RET_OK;
}

ret_t application_exit() {
	log_debug("application_exit\n");
	window_close(widget_child(window_manager(), "media_play_win"));
	return RET_OK;
}

#define LCD_WIDTH 1024
#define LCD_HEIGHT 600
#define APP_TYPE APP_DESKTOP
#define APP_NAME "vlc_awtk_media_player"
#define APP_ENABLE_CONSOLE FALSE /*关闭命令行窗口*/

#ifdef WITH_FS_RES
#define APP_DEFAULT_FONT "default_full"
#endif /*WITH_FS_RES*/

#ifndef APP_RES_ROOT
#define APP_RES_ROOT "./res"
#endif /*APP_RES_ROOT*/

#include "awtk_main.inc"

注意事项

  1. 目前只处理了video视频帧,audio帧没有处理,libvlc会自动调用windows接口,将视频里面的声音播放出来。
  2. 本文适用于已经对AWTK有所熟悉的人,如果有不熟悉AWTK的,需要自行了解一下。

No pains, no gains.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值