TCPMP源代码分析

TCPMP 0.81视频播放器_wince TCPMP 0.81视频播放器_wince 一款很好视频播放器, 已经在wince6.0测试通过 立即下载

播放器主要由核心框架模块(common工程)和解码器、分离器插件组成。TCPMP的插件非常多,其中主要的插件有:interface插件实现了TCPMP的界面,ffmpeg是系统主要的音视频解码模块,splitter是媒体文件分离器。

由于ffmpeg的解码效率不高,系统仅使用了ffmpeg的部分功能。并且未使用其中的libavformat模块,而使用splitter模块进行。其他插件暂时没有研究。本周主要分析的是common工程。

common工程是核心模块,是一个开放的集数据输入、转换、音/视频解码、信号输出等功能为一体的完整的多媒体播放框架。这个框架自身不包含任何的Decode和Split功能,这些功能由插件实现,核心模块以一个树状结构管理所有的功能模块和插件模块,实现数据Render功能,对输入、转换、输出流程的控制,接受播放过程中的操作和对事件进行处理,同时也实现系统运行中经常使用的一些共用函数,比如解码过程中经常使用的逆离散余弦变换,内存操作,界面中需要使用的多语言字符处理等。

common工程的主目录下主要有:blit、dyncode、overlay、pcm、softidct、win32、zlib等子目录。其中blit和overlay存放是视频信号渲染模块,pcm存放PCM音频信号转换模块,softidct存放逆离散余弦变换函数,win32存放内存操作等常用模块,dyncode这个目录的代码比较晦涩,存放的是程序运行时动态生成代码模块,针对不同的CPU指令集,PCM数据声道和采样率不同,视频渲染数据格式和色深等不同情况动态生成不同的优化代码,zlib则提供了内存中压缩和解压缩的函数,包括未压缩数据的完整性检查。

以下是common工程核心模块中几个重要的概念:
(1)上下文对象context
   该对象在初始化函数bool_t Context_Init中创建了一个该对象实例(context.h)。该对象实例记录管理各个功能模块,用户界面可以通过该对象和核心模块交互,管理控制播放过程。

(2)功能模块
    功能模块包括定义对象nodedef和数据对象node,定义对象描述功能模块相互间的逻辑结构,数据对象记录模块属性和方法。所有的功能模块结构按一个树状结构来组织,结构关系如下,NODE是整个结构的根结点,其下为子节点,节点按类型可分为实节点,全局节点,设置节点,抽象节点。

   抽象节点没有对应的对象实例,类似C++的抽象基类,为了按照逻辑关系组织系统结构而存在,例如NODE就是抽象节点。全局节点只有一个对象的实例,如播放控制模块PLAYER_ID。设置节点表示和系统播放设置相关,比如声音均衡器模块EQUALIZER_ID,颜色控制模块COLOR_ID。实节点与抽象节点不同,指可以生成对象实例的节点,实节点没有特殊标识,一般以数据对象占用内存大小表示是否是一个实节点,创建节点时要根据该信息分配内存单元,实节点也可以有子节点,例如:MMS_ID的父节点是HTTP_ID。全局节点,设置节点和实节点可以相互组合,比如播放控制节点同时是全局节点,设置节点和实节点。

下面是主要的节点树状分布图:

NODE (根节点)
    ├─FLOW (流控制模块)
    │  ├─CODEC (解码模块)
    │  │  ├─EQUALIZER_ID (声音均衡器模块)
    │  │  ├─VBUFFER_ID (视频缓冲模块)
    │  │  ├─DMO (DirectX Media Object)
    │  │  │  ├─WMV_ID
    │  │  │  ├─WMS_ID
    │  │  │  ├─WMVA_ID
    │  │  │  ├─WMA_ID
    │  │  │  └─WMAV_ID
    │  │  ├─FFMPEG VIDEO (FFMpeg 解码模块)
    │  │  └─LIBMAD_ID (Libmad Mp3解码模块)
    │  ├─OUT (信号渲染模块)
    │  │  ├─AOUT (音频信号渲染)
    │  │  │  ├─NULLAUDIO_ID
    │  │  │  └─WAVEOUT_ID
    │  │  └─VOUT (视频信号渲染)
    │  │      ├─NULLVIDEO_ID
    │  │      └─OVERLAY
    │  ├─IDCT (离散余弦解码模块)
    │  │  └─SOFTIDCT_ID
    │  └─CODECIDCT(离散余弦解码模块,函数比IDCT要少)
    │      └─MPEG1_ID
    ├─MEDIA (媒体文件格式编码解析模块)
    │  ├─FORMAT (格式解析模块)
    │  │  └─FORMATBASE
    │  │      ├─RAWAUDIO
    │  │      │  └─MP3_ID
    │  │      ├─RAWIMAGE
    │  │      ├─ASF_ID
    │  │      ├─AVI_ID
    │  │      ├─MP4_ID
    │  │      ├─MPG_ID
    │  │      ├─NSV_ID
    │  │      └─WAV_ID
    │  ├─PLAYLIST (播放列表模块)
    │  │  ├─ASX_ID
    │  │  ├─M3U_ID
    │  │  └─PLS_ID
    │  └─STREAMPROCESS (数据流处理模块)
    ├─STREAM (数据输入模块)
    │  ├─MEMSTREAM_ID (内存数据流模块)
    │  ├─FILE_ID (文件IO模块)
    │  └─HTTP_ID (网络数据获取模块)
    ├─TIMER (定时器模块)
    │  └─SYSTIMER_ID
    ├─ASSOCIATION_ID (文件扩展名自动关联模块)
    ├─ADVANCED_ID (高级设置模块)
    ├─COLOR_ID (颜色控制模块)
    ├─PLATFORM_ID (平台信息模块)
    ├─XSCALEDRIVER_ID
    ├─PLAYER_ID (播放控制模块)
    └─PLAYER_BUFFER_ID (播放缓冲模块)

以下是common工程核心模块的几个重要数据结构:
(1)context 上下文对象
typedef struct context

{

   int Version;//版本信息

   uint32_t ProgramId;//应用程序句柄

   const tchar_t* ProgramName;//应用程序名称

   const tchar_t* ProgramVersion;//程序版本号,字符串

   const tchar_t* CmdLine;//程序命令行信息

   void* Wnd;//视频渲染窗口句柄

   void* NodeLock;//功能模块访问临界区互斥变量

   array Node; //功能模块数据对象数组

   array NodeClass; // ordered by id功能模块定义对象数组,按照系统逻辑关系组织

   array NodeClassPri; // ordered by priority|id功能模块定义对象数组,按照系统逻辑关系和优先级排列

   array NodeModule;//外部插件模块数组

   int LoadModuleNo;//当前正在加载的外部插件序号

   void* LoadModule;//当前正在加载的外部插件

   array StrTable[2];//字符串资源数组,字符串分为:给底层使用的标准字符串资源、给界面使用的显示字符串资源,两个资源用两个数组表示

   array StrBuffer;

   array StrModule;//未使用

   void* StrLock;//字符串数组访问临界区互斥变量

   uint32_t Lang;//当前使用语言标志

   int CodePage;//当前使用代码页标志

   struct pcm_soft* PCM;//PCM音频信号转换模块

   struct blitpack* Blit;//视频信号渲染模块

   struct node* Platform;//得到平台相关信息

   struct node* Advanced;//得到播放模块高级信息

   struct node* Player;//播放控制模块

   notify Error;//信息错误回调函数

   int (*HwOrientation)(void*);

   void *HwOrientationContext;

   bool_t TryDynamic;//未使用

   int SettingsPage;//未使用

   size_t StartUpMemory;//可以使用的有效内存数

   bool_t InHibernate;//是否进入休眠状态

   bool_t WaitDisable;//未使用

   int FtrId;//未使用

   bool_t LowMemory;//可以使用的有效内存数是否小于系统要求的最低要求

   //动态代码生成中间状态及数据

   bool_t CodeFailed;

   bool_t CodeMoveBack;

   bool_t CodeDelaySlot;

   void* CodeLock;

   void* CodeInstBegin;

   void* CodeInstEnd;

   int NextCond;

   bool_t NextSet;

   bool_t NextByte;

   bool_t NextHalf;

   bool_t NextSign;

   uint32_t* FlushCache;//未使用

   void* CharConvertUTF8;//未使用

   void* CharConvertCustom;//未使用

   int CustomCodePage;//未使用

   void* CharConvertAscii;//未使用

   void* Application;

   void* Logger;//未使用

   bool_t KeepDisplay;//是否保持背光长亮

   int DisableOutOfMemory;//未使用

 

} context;

(2)nodedef  功能模块定义对象
功能模块树状结构通常由若干个静态定义对象(nodedef)实例实现,
typedef struct nodedef

{

        int     Flags;//功能模块节点的类型:抽象、实节点、全局、设置。

        int     Class;//功能模块节点的标识,如MEDIA_CLASS或ASF_ID等等。

        int     ParentClass;//功能模块父节点的标识,如SYSTIMER_ID对象的父节点是TIMER_CLASS。

        int     Priority;//表示功能模块节点优先级。

        nodecreate Create;//创建功能模块定义对象的函数指针

        nodedelete Delete;//销毁功能模块定义对象的函数指针

 

} nodedef;//功能模块定义对象

 

如解码器功能模块静态定义对象:

static const nodedef Codec =

{

        sizeof(codec)|CF_ABSTRACT,

        CODEC_CLASS,

        FLOW_CLASS,

        PRI_DEFAULT,

        (nodecreate)Create,

        (nodedelete)Delete,

};

(3)nodeclass  功能模块定义对象链表结构
用链表的方式实现了功能模块树状结构,每个链表代表树状结构的一个分支。

typedef struct nodeclass

{

        nodedef Def;//功能模块定义对象

        bool_t Registered;//是否注册

        int ModuleNo;//模块标识

        struct nodeclass* Parent;//功能模块定义对象的父对象

 

} nodeclass;//功能模块定义节点对象链表结构

(4)node  功能模块数据对象
typedef struct node

{

        int                     Class;//功能模块节点的类型,如MEDIA_CLASS等等,与nodedef相同。

        nodeenum  Enum;//枚举节点属性函数指针

        nodeget             Get;//获取节点属性的函数指针

        nodeset             Set;//设置节点属性的函数指针

 

} node;//功能模块数据对象

 

上述几个数据对象的相互关系:

        在系统上下文对象context中有两个元素记录功能模块信息array Node和array NodeClass,array是数组数据类型(在buffer.h/c中定义和实现),Node是功能模块数据对象的数组,NodeClass功能模块定义对象的数组,按照系统逻辑关系组织。

        创建功能模块时传入nodedef对象到功能模块创建函数,函数会根据nodedef信息生成对应nodeclass对象添加到NodeClass数组,同时根据nodedef信息分配数据对象的内存空间。在该节点的Create函数里面再初始化该功能模块的数据对象node。

 

(5)datadef 功能模块属性
typedef struct datadef

{

        int     No;//属性的标识,如播放控制模块的#define PLAYER_PLAY 0x32 就表示控制播放器播放或暂停。

        int     Type;//属性的数据类型,在node.h中定义,如TYPE_BOOL             

        int Flags;//属性数据的标志,是属性数据的标志,表示该数据是不是只读数据,是否有最大最小值等等,node.h中定义,如DF_RDONLY

        int Format1;

        int     Format2;

        const tchar_t* Name;

        int Class;                   

        int Size;                    

 

} datadef;//属性对象定义

其中Format1和Format2是可选标志与Flags配合使用,比如如果Flags表示该属性存在最大最小值,Format1就是最大值,Format2则是最小值;

另外,如果(!(Flags & DF_NOSAVE) && !(Flags & DF_RDONLY))即属性标识为保存且可读写,则会被记录到注册表中,下次启动时用注册表的数据初始化该属性表。

 

(6)datatable  功能模块属性列表
typedef struct datatable

{

        int     No;

        int     Type;

        int Flags;   

        int Format1;

        int     Format2;

} datatable;//功能模块属性列表

各功能模块的属性通常以数组的形式定义和存储,如格式解析模块属性列表

static const datatable Params[] =

{

        { FORMAT_INPUT,                       TYPE_NODE, DF_INPUT|DF_HIDDEN, STREAM_CLASS },

        { FORMAT_OUTPUT,             TYPE_NODE, DF_HIDDEN, STREAM_CLASS },

        { FORMAT_DURATION,         TYPE_TICK },

        { FORMAT_FILEPOS,            TYPE_INT, DF_HIDDEN },

        { FORMAT_FILESIZE,           TYPE_INT, DF_KBYTE },

        { FORMAT_AUTO_READSIZE, TYPE_BOOL, DF_HIDDEN },

        { FORMAT_GLOBAL_COMMENT,TYPE_COMMENT, DF_OUTPUT },

        { FORMAT_FIND_SUBTITLES,TYPE_BOOL, DF_HIDDEN },

        { FORMAT_STREAM_COUNT, TYPE_INT, DF_HIDDEN },

 

        DATATABLE_END(FORMAT_CLASS)

};

(7)nodemodule  外部插件功能模块
typedef struct nodemodule

{

        int Id;//插件标识

        int ObjectCount;//该插件的实例个数(引用计数)

        bool_t Tmp;//是否是临时节点

        int64_t Date;//设置时间

        int KeepAlive;//保持时间

        void* Module;//外部插件模块

        void* Db;

        void* Func;

        uint8_t* Min;

        uint8_t* Max;

 

} nodemodule;//外部插件模块节点

核心模块的初始化流程及相应代码对应关系(参考context.c中的Context_Init函数)
            Mem_Init();

//内存等资源初始化(Win32/mem_win32.c)

            DynCode_Init();

//程序运行动态生成代码模块,优化PCM,视频渲染模块等(DynCode/DynCode.c)

            String_Init();

//系统使用字符串初始化(str.c,Win32/str_win32.c)

            PCM_Init();

//音频信号转换模块初始化(PCM/pcm_soft.c)

            Blit_Init();

//视频信号渲染模块初始化(Blit/blit_soft.c)

            Node_Init();

//根节点模块初始化(node.c,Win32/node_win32.c)

            Platform_Init();

//平台信息模块初始化(platform.c,Win32/platform_win32.c)

            Stream_Init();

//输入数据流模块初始化(streams.c)

            Advanced_Init();

//高级设置模块初始化(advance.c)

            Flow_Init();

//流控制模块初始化(flow.c)

            Codec_Init();

//解码模块初始化(codec.c)

            Audio_Init();

//音频信号处理模块初始化(audio.c)

            Video_Init();

//视频信号处理模块初始化(video.c)

            Format_Init();

//格式解析模块初始化(format.c)

            Playlist_Init();

//播放列表模块初始化(playlist.c)

            FormatBase_Init();

//基本格式解析模块初始化(format_base.c,format_subtitle.c)

            NullOutput_Init();

//无输出设备模块初始化(nulloutput.c)

            RawAudio_Init();

//RawAudio模块初始化(rawaudio.c)

            RawImage_Init();

//RawImage模块初始化(rawimage.c)

            Timer_Init();

//定时器模块初始化(timer.c)

            IDCT_Init();

//离散余弦解码模块初始化(idct.c)

            Overlay_Init();

//视频叠加模块初始化(overlay.c)

            M3U_Init();

//M3U格式播放列表模块初始化(PlayList/m3u.c)

            PLS_Init();

//PLS格式播放列表模块初始化(PlayList/pls.c)

            ASX_Init();

//ASX格式播放列表模块初始化(PlayList/asx.c)

            WaveOut_Init();

//波形输出模块初始化(waveout.c,Win32/waveout_win32.c)

            SoftIDCT_Init();

//soft离散余弦解码模块初始化(SoftIDCT/softidct.c)

            Plugins_Init();

//外部插件模块初始化(Win32/node_win32.c)

另外还有文件扩展名自动关联模块Association_Init (参考文件Win32/ association_win32.c);颜色控制模块Color_Init(参考color.c);声音均衡器模块Equalizer_Init(参考equalizer.c);播放控制模块初始化(参考player.c )。

向系统中载入外部插件模块(参考node.c以及node_win32.c)
node.c中的LoadModule函数,可以在系统中载入外部插件模块,

static NOINLINE nodemodule* LoadModule(context* p,int No),

第一个参数是上下文对象,

第二个参数是外部插件模块标识

 

node_win32.c定义了dll的载入与卸载函数以及相应的注册表操作,如

在功能模块节点载入外部插件模块

void* NodeLoadModule(const tchar_t* Path,int* Id,void** AnyFunc,void** Db)

 

 

与界面相交互的播放控制模块(player.c)
        在所有功能模块中和界面加交互的主要就是播放控制模块struct node* Player;使用方法如下:

context* p = Context();

player* myplayer = NULL;

if(p) myplayer = (player*)(p->Player);

 

          控制播放使用

        Set(void* This,int No,const void* Data,int Size)

        第一个参数是播放模块指针,

        第二个参数是控制代码,即要进行什么操作,

        第三个参数是需要赋值给控制代码的数值,

        最后一个参数是所赋数值的占用内存的大小。

        myplayer->Set(myplayer,PLAYER_PLAY,1,sizeof(int));

        PLAYER_PLAY为控制代码,表示当前控制的是播放暂停功能,数值为1表       示播放为0表示暂停。

        得到某一控制属性使用Get(void* This,int No,void* Data,int Size);函数,参数含义和Set函数相同。

        控制代码是一组宏,定义在player.h文件中。比较重要的控制参数有播放控制模块所有可用参数见static const datatable PlayerParams[]结构。

        添加一个媒体文件到播放模块使用

int PlayerAdd(player* Player,int Index, const tchar_t* Path, const tchar_t* Title);
        第一个参数为播放模块指针,

        第二个参数是添加到播放模块文件队列的序号,如果是使文件成为第一个文                件该参数设为0,

        第三个参数是媒体文件的目录和名称,

        第四个参数为媒体文件标题,该参数可以忽略。

 

本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/ceFighter/archive/2009/04/17/4086231.aspx

TCPMP完整版(支持APE) 在CE上运行一次后关闭,打开注册表,导入注册文件。完成 立即下载

相关推荐

TCPMP中文完美版.rar

TCPMP中文完美版,解压之后就可以直接使用。这个是完美版,几乎可以播放所以的视频音乐。

TCPM/TCPC/TCPCI

TCPCI英文全称为USB Type-C Port Controller Interface ,即USB Type-C 端口控制器接口。TCPC英文全称为USB Type-C Port Controller,即USB Type-C 端口控制器。TCPC是一个功能控制模块,包括VBUS和VCONN电源控制、USB Type-C CC逻辑以及USB PD通信 BMC物理层和部分协议层等。TCPC是一个功能管理模块,包括VBUS和VCONN电源管理以及USB PD通信的设备策略管理层、策略引擎层和部分协议层等。

uunubt的专栏 4975

TCPMP.2011-0.6.9.0120.rar_Mobile 9_aacDECdrop_aacDECdrop下载

window mobile手机的tcpmp源代码

typec tcpm状态机工作原理

什么是TCPM?TCPM英文全称为USB Type-C Port Manager,即USB Type-C 端口管理器。TCPC是一个功能管理模块,包括VBUS和VCONN电源管理以及USB PD通信的设备策略管理层、策略引擎层和部分协议层等。什么是TCPC?TCPC英文全称为USB Type-C Port Controller,即USB Type-C 端口控制器。

changcheng00的博客 4168

如何在Proteus中模拟Arduino

进一步的Proteus可用于设计任何与Arduino相关的项目,它将在进入硬件级别之前提供更好的理解。由于其广泛的库集合,它是Arduino社区中最受欢迎的工具之一,不仅如此,Proteus还可以为Arduino项目设计定制的PCB。就像上一步一样,现在搜索Arduino UNO板,选择Arduino板并单击“确定”以添加到项目中,或者双击以在Proteus项目中添加Arduino。一旦在Proteus中成功创建了一个新项目,现在我们将设计一个用于Proteus中闪烁LED的Arduino电路。

acktomas的博客 1万+

两张 300I Duo 部署 Qwen3.5‑32B

开发者成功使用两张华为300IDuo(共4颗Ascend310P3芯片)部署Qwen3/Qwen3.5的30B/32B模型,并公开详细步骤。关键点包括:硬件需两张300IDuo(每芯片44GB显存),软件需CANN≥24.1和MindIE2.3.0专用镜像。部署流程涵盖驱动安装、模型下载(需修改为FP16格式)、容器启动、张量并行配置(TP=4)等环节。实测显示每芯片显存占用20-35GB,系统稳定运行。该方案已在知乎等平台验证可行,适用于Qwen3.5-32B等同类模型。

evering的博客 2255

Unix系统tcp和tcpm命令的实现——第一次Unix实验总结

1.题目 DESCRIPTION The tcp utility copies the contents of the source to target. If target is a directory, tcp will copy source into this directory. EXAMPLES tcp file1 file2 tcp file1 dir tcp file1 dir/f...

qq_42614839的博客 700

拆开一个烧坏的IGBT模块,手把手教你识别过压、过流、过温的“案发现场”

本文详细解析了IGBT模块失效分析的实战技巧,通过观察铝层熔化纹路、焊锡溢出形态等物理痕迹,手把手教你识别过压、过流、过温的典型失效模式。文章提供了从基础工具包到现场快速诊断的完整流程,帮助工程师精准定位IGBT模块失效的根本原因。

weixin_30655569的博客 426

【无标题】

功率配置完成后,主机的嵌入式控制器(TCPM)控制LDR6280进行VDM信息的协商,包括DP Alt Mode的配置等,LDR6280如果收到Attention信息,报告给TCPM。由于USB-C端口、USB PD等快充协议是近几年才推出的,所以在之前推出的SOC或MCU必然没有集成USB PD、QC等协议,也不支持USB Type-C的逻辑识别功能,也就无法实现USB Type-C端口快充和高清音视频传输的功能,因为快充和高清音视频传输的实现都需要依靠USB Type-C的识别和相关协议的沟通。

sjjwbz的博客 298

从DIY到实战:手把手教你搭建一个媲美吉时利2450的nA级电流源表(附原理图与避坑指南)

本文详细解析如何从零打造nA级精密电流源,涵盖核心设计原理、PCB布局技巧、热电偶效应应对及校准验证体系。通过低成本替代方案和优化设计,实现媲美商用源表的性能,特别适合硬件爱好者和独立开发者。文章还提供原理图与避坑指南,助你轻松搭建高精度电流源系统。

weixin_42656416的博客 292

原形网络(Prototypical Networks)基于PyTorch的实现

我在Jay2coomzz的基础上修改了数据处理方式和evaluation_model()方法,作为初学者若有不当之处恳请大家批评指正,原文链接如下: https://blog.youkuaiyun.com/weixin_38471579/article/details/102631018 数据集和源码链接将放到评论区 文章目录1 数据集一个简单的数据集介绍数据集处理2 搭建网络CNNProtonets 1 数据集 一个简单的数据集介绍 Omniglot数据集一共包含1623 类手写体,每一类中包含20 个样本。其中.

weixin_43872532的博客 6636

TCPMP之旅(一) TCPMP整体软体框架

本 人转载自: http://blog.youkuaiyun.com/navi_dx/article/details/1885780 一. 引言 去年年底帮别人做一个项目,了解了一下TCPMP,觉得这个软件的结构写得很好就做了些记录,今天偶然翻出来看看觉得可能对正在研究这个软件的人有点帮助就贴出来。如果转载请注明出处,谢谢。 二. TCPMP简介 TCPMP是一个功能强大开放式的开源多媒体播放器,...

mmdev 266

YOLOv8 模型进化全解析:百种创新模块集成方法与实战部署指南(附资料链接)

动态网络 | DeformableConv/DynamicHead| +2.8% || 轻量化卷积 | GhostConv/MobileConv | +1.2% || 多尺度融合 | AFPN/ASFF | +3.5% || 注意力机制 | CA/EMA/SimAM | +1.8-4.2% |

FJN110的博客 111

TCPMP源代码分析---窥豹一斑

由于项目需要,最近看了下TCPMP(.72.sc1)源代码。网上深入分析TCPMP源代码的文章很少。《TCPMP播放器到WINDOWSCE平台的移植编译过程》一文对在EVC下编译TCPMP的介绍甚是详尽,非常适合入手。《WINCE TCPMP应用》与《水煮TCPMP》两篇文章简要介绍了下TCPMP的结构和各部分的功能,个人认为远远没有达到水煮的境界,但还是很值得一看。    TCPMP作为一个

alien75的专栏 2641

Python爬虫:抓取外卖平台餐厅菜单、价格与评价数据

美团外卖:国内领先的外卖平台之一,提供餐饮外卖、超市配送等服务。饿了么:另一大主流外卖平台,覆盖广泛的餐饮品类。等:国际性的外卖平台。在本文中,我们将以美团外卖为例,展示如何抓取餐厅的菜单、价格和评价等数据。我们会使用Python的爬虫库,如Scrapy和Selenium,来解决抓取任务。本文详细介绍了如何使用Python爬虫抓取外卖平台上的餐厅菜单、价格、评价等信息。我们展示了如何使用Scrapy和Selenium抓取静态与动态网页数据,如何清洗和存储数据,并讨论了如何应对外卖平台的反爬虫机制。

2201_76125261的博客 1499

超十万字解读Spring AI实战:开篇

大模型技术正以惊人的速度改变世界,2025年的人工智能已不再是科幻,而是现实。大模型如ChatGPT等,正在重塑各行各业,降低技术门槛,使专业能力普及化。SpringAI的出现为Java开发者提供了桥梁,使其能在企业级系统中稳定运行AI,同时保持工程化思维。尽管SpringAI在生态、学习成本和性能上存在不足,但其企业级基因和国产化适配能力使其成为Java开发者的重要工具。本系列文章旨在介绍SpringAI的功能与特性,鼓励更多Java开发者参与AI实践,共同探索AI时代的无限可能。

liaokailin的专栏 1577

tcpmp 编译 源代码分析

TCPMP源代码分析 TCPMP源代码分析      播放器主要由核心框架模块(common工程)和解码器、分离器插件组成。TCPMP的插件非常多,其中主要的插件有:interface插件实现了TCPMP的界面,ffmpeg是系统主要的音视频解码模块,splitter是媒体文件分离器。      由于ffmpeg的解码效率不高,系统仅使用了ffmpeg的部分功能。并且未使用其中的liba

szu030606的专栏 1397

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: 嵌入式linux学习计划第二阶段总结
下一篇: TCPMP源代码分析---窥豹一斑
alien75
博客等级 码龄25年 195粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值