【MediaPlayer】基于libvlc+awtk的媒体播放器
基于libvlc+awtk的媒体播放器
- libvlc
- 下载地址
- awtk
- 下载地址
- 代码实现
- libvlc相关逻辑接口
- UI媒体接口
- 实例化媒体播放器
- 注意事项
libvlc
下载地址
- 可以到https://download.videolan.org/pub/videolan/vlc/去下载一个vlc版本,下载后其实是vlc的windows客户端,里面包含sdk目录,用于windows程序链接libvlc
- 需要的文件为:sdk/include、sdk/lib、libvlc.dll、libvlc_core.dll
awtk
下载地址
- AWTK是一套基于C语言的国产UI框架,目前开源在https://github.com/zlgopen/awtk,可自行下载后,按照文档编译即可,编译方法也很简单
代码实现
以像素格式RGBA8888为例
libvlc相关逻辑接口
- 头文件
#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__
- 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/目录的各种文档
二、代码封装如下:
- 头文件
#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__
- 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;
}
实例化媒体播放器
- 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"
注意事项
- 目前只处理了video视频帧,audio帧没有处理,libvlc会自动调用windows接口,将视频里面的声音播放出来。
- 本文适用于已经对AWTK有所熟悉的人,如果有不熟悉AWTK的,需要自行了解一下。
No pains, no gains.
相关文章:
【MediaPlayer】基于libvlc+awtk的媒体播放器
基于libvlcawtk的媒体播放器 libvlc下载地址 awtk下载地址 代码实现libvlc相关逻辑接口UI媒体接口实例化媒体播放器注意事项 libvlc 下载地址 可以到https://download.videolan.org/pub/videolan/vlc/去下载一个vlc版本,下载后其实是vlc的windows客户端࿰…...
复古未来主义屏幕辉光像素化显示器反乌托邦效果PS(PSD)设计模板样机 Analog Retro-Futuristic Monitor Effect
这款模拟复古未来主义显示器效果直接取材于 90 年代赛博朋克电影中的黑客巢穴,将粗糙的屏幕辉光和像素化的魅力强势回归。它精准地模仿了老式阴极射线管显示器,能将任何图像变成故障频出的监控画面或高风险的指挥中心用户界面。和……在一起 2 个完全可编…...
Kafka 如何保证消息有序性?
Kafka 保证消息顺序性,是基于 Partition(分区)级别的顺序 来实现的。下面我们详细拆解一下: ✅ 同一个 Partition 内,消息是严格有序的 Kafka 在 同一个分区(Partition)内,消息是按…...
【积木画】——第十三届蓝桥杯(2022)T7思路解析
题目描述 关键词 递推、dp 思路 显然这是一道递推题。 但是为什么我还要写在这呢?因为我虽然看了题解但是还是没想明白,综合了下面两篇 参考文献我才初步理解这题的精髓。所以还是自己写一遍为好。 我们把最终结果记为F(n)。 情况1 直接以一个竖着…...
Android studio xml布局预览中 Automotive和Autotive Distant Display的区别
在 Android Studio 中,Configure Hardware Profile 设置中的 Device Type 选项有两个不同的设置:Android Automotive 和 Android Automotive Distant Display,它们的含义和用途如下: 1. Android Automotive 含义:这个…...
第十三章:持久化存储_《凤凰架构:构建可靠的大型分布式系统》
第十三章 持久化存储 一、Kubernetes存储设计核心概念 (1)存储抽象模型 PersistentVolume (PV):集群级别的存储资源抽象(如NFS卷/云存储盘)PersistentVolumeClaim (PVC):用户对存储资源的声明请求&#…...
Nginx 基础使用(2025)
一、Nginx目录结构 [rootlocalhost ~]# tree /usr/local/nginx /usr/local/nginx ├── client_body_temp # POST 大文件暂存目录 ├── conf # Nginx所有配置文件的目录 │ ├── fastcgi.conf # fastcgi相…...
Docker基础1
本篇文章我将从系统的知识体系讲解docker的由来和在linux中的安装下载 随后的文章会介绍下载镜像、启动新容器、登录新容器 如需转载,标记出处 docker的出现就是为了节省资本和服务器资源 当企业需要一个新的应用程序时,需要为它买台全新的服务器。这样…...
【奇点时刻】GPT4o新图像生成模型底层原理深度洞察报告
个人最近一直在关注openai的新图像生成特性,以下内容基于现阶段社区及研究者们对 GPT-4O 图像生成功能的公开测试、逆向分析与技术推测综合而成,OpenAI 并未正式发布完整的技术报告,因此本文为非官方推断总结。但从多方信息与技术背景出发&am…...
Java的Selenium的特殊元素操作与定位之模态框
Modal Dialogue Box,又叫做模式对话框,是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。 alert(警告) //访问本地的HTML文件 chromeDr…...
回归预测 | Matlab实现NRBO-Transformer-LSTM多输入单输出回归预测
回归预测 | Matlab实现NRBO-Transformer-LSTM多输入单输出回归预测 目录 回归预测 | Matlab实现NRBO-Transformer-LSTM多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.【JCR一区级】Matlab实现NRBO-Transformer-LSTM多输入单输出回归预测…...
Python菜鸟教程(小程序)
目录 一.简易计算器 二.学生成绩分级 三.密码设置 四.作业选择 点赞收藏,评论支持 一.简易计算器 print(-------使用的运算符-------\n) print(1.加号) print(2.减号) print(3.乘号) print(4.除号) Aint(input(请输入第一个数: )) Bint(input(请输入第二个数: )) Fi…...
类的(多态性、虚函数)基础练习
练习1:(简单) #include <iostream> using namespace std; class Vehicle { public: virtual void run() const0; }; class Car: public Vehicle { public: void run() const { cout << "run a car. "<<…...
特殊的质数肋骨--dfs+isp
1.dfs全排列组数,an记得还原 2.如果范围确定且只比较质数,isp比线性筛快,主要这个范围太大了 https://www.luogu.com.cn/problem/P1218 #include<bits/stdc.h> using namespace std; #define N 100011 typedef long long ll; typed…...
智能体开发实战指南:提示词设计、开发框架与工作流详解
在大语言模型(LLM)驱动的智能体(Agent)快速发展的今天,构建一个实用、智能的Agent已不再遥不可及。无论你是开发法律助手、租房合同分析器,还是通用办公自动化助手,理解提示词工程(P…...
jetson orin nano学习(torch+OpenCV+yolov5+)
一:入门第一件事:跟着商家教程配置哈哈 指令:nvidia-smi -h 帮助命令 sudo jtop --查看nvidia的gpu状态 Tip:教程下载的pytorth,cuda,cudnn版本不一定是你项目符合的,要提前想好 1.2 安装虚拟环境包(要安…...
client-go如何监听自定义资源
如何使用 client-go 监听自定义资源 在 Kubernetes 中使用 client-go 监听自定义资源(Custom Resource,简称 CR)需要借助 Dynamic Client 或 Custom Informer,因为 client-go 的标准 Clientset 只支持内置资源(如 Pod…...
【51单片机】3-3【定时器/计数器/中断】超声波测距模块测距
1.硬件 51最小系统超声波测距模块 2.软件 #include "reg52.h"//距离小于10cm,D5亮,D6灭,反之相反现象sbit D5 P3^7;//根据原理图(电路图),设备变量led1指向P3组IO口的第7口 sbit D6 P3^6;//根据原理图&…...
C语言求3到100之间的素数
一、代码展示 二、运行结果 三、感悟思考 注意: 这个题思路他是一个试除法的一个思路 先进入一个for循环 遍历3到100之间的数字 第二个for循环则是 判断他不是素数 那么就直接退出 这里用break 是素数就打印出来 在第一个for循环内 第二个for循环外...
金仓数据库KCM认证考试介绍【2025年4月更新】
KCM(金仓认证大师)认证是金仓KES数据库的顶级认证,学员需通过前置KCA、KCP认证才能考KCM认证。 KCM培训考试一般1-2个月一次,KCM报名费原价为1.8万,当前优惠价格是1万(趋势是:费用越来越高&…...
leetcode每日一题:替换子串得到平衡字符串
引言 今天的每日一题原题是1863. 找出所有子集的异或总和再求和,比较水,直接对于集合中的每一个元素,都有取或者不取2种情况,直接递归进去求和即可。更换成前几天遇到的更有意思的一题来写这个每日一题。 题目 有一个只含有 Q,…...
2025年数字化社会与智能计算国际学术会议 (ICDSIC 2025)
基本信息 官网:www.icdsic.net 时间:2025年4月18-20日 地点:中国-深圳 主题 数字化社会 智能计算 数字化制造、经济 数字化政务、转型 数字化农业、水利、管理 数字化医疗、学习、社区 数字基建、通信、交通 数字…...
BN测试和训练时有什么不同, 在测试时怎么使用?
我们来彻底搞懂 Batch Normalization(BN) 在训练和测试阶段的区别,以及 测试时怎么用。 🧠 一句话总结: 训练时:使用 当前 mini-batch 的均值和方差 测试时:使用 整个训练集估计的“滑动平均均值…...
为什么卷积神经网络适用于图像和视频?
我们常听说“卷积神经网络(CNN)擅长图像和视频”,但其实 CNN 的核心本质远不止图像领域。我们先搞懂它为啥适合图像/视频。 🧠CNN 为什么适用于图像和视频? 主要因为 图像/视频具有空间局部性和结构平移性,…...
python爬虫:DrissionPage实战教程
如果本文章看不懂可以看看上一篇文章,加强自己的基础:爬虫自动化工具:DrissionPage-CSDN博客 案例解析: 前提:我们以ChromiumPage为主,写代码工具使用Pycharm(python环境3.9-3.10) …...
【Python爬虫高级技巧】BeautifulSoup高级教程:数据抓取、性能调优、反爬策略,全方位提升爬虫技能!
大家好,我是唐叔!上期我们聊了 BeautifulSoup的基础用法 ,今天带来进阶篇。我将分享爬虫老司机总结的BeautifulSoup高阶技巧,以及那些官方文档里不会告诉你的实战经验! 文章目录 一、BeautifulSoup性能优化技巧1. 解析…...
【动手学深度学习】卷积神经网络(CNN)入门
【动手学深度学习】卷积神经网络(CNN)入门 1,卷积神经网络简介2,卷积层2.1,互相关运算原理2.2,互相关运算实现2.3,实现卷积层 3,卷积层的简单应用:边缘检测3.1࿰…...
IPSG 功能协议
IPSG(IP Source Guard)即 IP 源保护,是一种基于 IP 地址和 MAC 地址绑定的安全功能,用于防止 IP 地址欺骗和非法的 IP 地址访问。以下是配置 IPSG 功能的一般步骤: 基于端口的 IPSG 配置 进入接口配置模式࿱…...
19.go日志包log
核心功能与接口 基础日志输出 Print 系列:支持 Print()、Println()、Printf(),输出日志不中断程序。 log.Print("常规日志") // 输出: 2025/03/18 14:47:13 常规日志 log.Printf("格式化: %s", "数据") Fatal…...
横扫SQL面试——TopN问题
横扫SQL面试 电商平台的"销量Top10商品"🛍️,内容社区的"热度Top5文章“”🔥,还是金融领域的"交易额Top3客户"💰——TopN问题无处不在! 无论是日常业务分析📊&#x…...
高级:微服务架构面试题全攻略
一、引言 在现代软件开发中,微服务架构被广泛应用于构建复杂、可扩展的应用程序。面试官通过相关问题,考察候选人对微服务架构的理解、拆分原则的掌握、服务治理的能力以及API网关的运用等。本文将深入剖析微服务架构相关的面试题,结合实际开…...
使用MATIO库读取Matlab数据文件中的cell结构数据
使用MATIO库读取Matlab数据文件中的cell结构数据 MATIO是一个用于读写Matlab数据文件(.mat)的C/C库。下面我将展示如何使用MATIO库来读取Matlab文件中的cell结构数据。 示例程序 #include <stdio.h> #include <stdlib.h> #include <matio.h>int main(int …...
pyTorch框架使用CNN进行手写数字识别
目录 1.导包 2.torchvision数据处理的方法 3.下载加载手写数字的训练数据集 4.下载加载手写数字的测试数据集 5. 将训练数据与测试数据 转换成dataloader 6.转成迭代器取数据 7.创建模型 8. 把model拷到GPU上面去 9. 定义损失函数 10. 定义优化器 11. 定义训练…...
新能源汽车电子电气架构设计中的功能安全
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…...
使用binance-connector库获取Binance全市场的币种价格,然后选择一个币种进行下单
一个完整的示例,展示如何使用 api 获取Binance全市场的币种价格,然后选择一个最便宜的币种进行下单操作 代码经过修改,亲测可用,目前只可用于现货,合约的待开发 获取市场价格:使用client.ticker_price()获取所有交易对的当前价格 账户检查:获取账户余额,确保有足够的资…...
HikariCP 源码核心设计解析与 ZKmall开源商城场景调优实践
HikariCP 作为 Spring Boot 默认数据库连接池,其高性能源于独特的无锁设计、轻量级数据结构和精细化生命周期管理。以下从源码解析与 ZKmall开源商城性能调优两个维度展开: 一、HikariCP 源码核心设计解析 无锁并发控制与 ConcurrentBag 容器 Concur…...
P1036 [NOIP 2002 普及组] 选数(DFS)
题目描述 已知 n 个整数 x1,x2,⋯,xn,以及 1 个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n4,k3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它…...
自然语言处理
自然语言处理基础 什么是自然语言处理:让计算机来理解人类所说的一种语言。自然语言处理实际就是让计算机理解人类说的话,然后像人一样进行交互,去进行对话,去生成自然语言。 自然语言处理的基本任务 词性标注:把给…...
LeetCode刷题常见的Java排序
1. 字符串排序(字母排序) 首先,你的代码实现了根据字母表顺序对字符串中的字母进行排序,忽略了大小写并且保留了非字母字符的位置。关键点是: 提取和排序字母:通过 Character.isLetter() 判断是否为字母,并利用 Character.toLowerCase() 来忽略大小写进行排序。保留非字…...
# 利用OpenCV和Dlib实现疲劳检测:守护安全与专注
利用OpenCV和Dlib实现疲劳检测:守护安全与专注 在当今快节奏的生活中,疲劳和注意力不集中是许多人面临的常见问题,尤其是在驾驶、学习等需要高度集中精力的场景中。疲劳不仅影响个人的健康和安全,还可能导致严重的事故。为了应对…...
python基础-16-处理csv文件和json数据
文章目录 【README】【16】处理csv文件和json数据【16.1】csv模块【16.1.1】reader对象【16.1.2】在for循环中, 从reader对象读取数据【16.1.3】writer对象【16.1.5】DictReader与DictWriter对象 【16.4】json模块【16.4.1】使用loads()函数读取json字符串并转为jso…...
Mysql 数据库编程技术01
一、数据库基础 1.1 认识数据库 为什么学习数据库 瞬时数据:比如内存中的数据,是不能永久保存的。持久化数据:比如持久化至数据库中或者文档中,能够长久保存。 数据库是“按照数据结构来组织、存储和管理数据的仓库”。是一个长…...
基于SSM的车辆管理系统的设计与实现(代码+数据库+LW)
摘要 当下,正处于信息化的时代,许多行业顺应时代的变化,结合使用计算机技术向数字化、信息化建设迈进。以前企业对于车辆信息的管理和控制,采用人工登记的方式保存相关数据,这种以人力为主的管理模式已然落后。本人结…...
BugKu Simple_SSTI_2
这个题很简单,主要是记录一下,做题的原理: 打开环境,提示我们用flag传参,然后我们需要判断是什么模板: 这里有一张图片,可以帮助我们轻松判断是什么模板类型:这个图片找不到出处了&…...
浙考!【触发器逻辑方程推导(电位运算)】
RS触发器是浙江高考通用技术一大考点。“对角线原则”、“置1置0”、“保持”、“不使用”、“记忆功能”…经常让考生云里雾里,非常反直觉。 这篇文章,我想以高中生的视角诠释一下触发器。 1、触发器逻辑方程推导(以或非门触发器为例&…...
二叉树的前序中序后序遍历
一、前序遍历 144. Binary Tree Preorder Traversal 递归代码实现: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* …...
es中节点类型有哪些
Elasticsearch 节点类型有哪些 在 Elasticsearch 中,节点类型(或角色)定义了每个节点在集群中的职责。不同版本的 Elasticsearch 对节点角色的定义和管理方式有所不同,尤其在 7.9.0 版本引入 node.roles 后,配置方式更…...
【学习笔记】深度学习环境部署相关
文章目录 [AI硬件科普] 内存/显存带宽,从 NVIDIA 到苹果 M4[工具使用] tmux 会话管理及会话持久性[A100 02] GPU 服务器压力测试,gpu burn,cpu burn,cuda samples[A100 01] A100 服务器开箱,超微平台,gpu、…...
游戏引擎学习第206天
回顾并为当天的工作定下目标 接着回顾了前一天的进展。之前我们做了一些调试功能,并且已经完成了一些基础的工作,但是还有一些功能需要继续完善。其中一个目标是能够展示实体数据,以便在开发游戏逻辑系统时,可以清晰地查看和检查…...
Rust所有权详解
文章目录 Rust所有权所有权规则作用域 内存和分配移动与克隆栈空间堆空间 关于函数的所有权机制作为参数作为返回值 引用与租借垂悬引用 Rust所有权 C/C中我们对于堆内存通常需要自己手动管理,手动申请和释放,即便有了智能指针,对于效率的影…...