MediaPlayer音频与视频的播放介绍

news2024/11/25 14:52:08

作者:向阳逐梦

Android多媒体中的——MediaPlayer,我们可以通过这个API来播放音频和视频该类是Androd多媒体框架中的一个重要组件,通过该类,我们可以以最小的步骤来获取,解码和播放音视频。

它支持三种不同的媒体来源:

  • 本地资源
  • 内部的URI,比如你可以通过ContentResolver来获取
  • 外部URL(流)对于Android所支持的的媒体格式列表

1.相关方法详解

1)获得MediaPlayer实例:

可以直接new或者调用create方法创建:

MediaPlayer mp = new MediaPlayer();
MediaPlayer mp = MediaPlayer.create(this, R.raw.test);  //无需再调用setDataSource` </pre>

另外create还有这样的形式:create(Context context, Uri uri, SurfaceHolder holder) 通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器。

2)设置播放文件:

//①raw下的资源:
MediaPlayer.create(this, R.raw.test);

//②本地文件路径:
mp.setDataSource("/sdcard/test.mp3");

//③网络URL文件:
mp.setDataSource("http://www.xxx.com/music/test.mp3");

另外setDataSource()方法有多个,里面有这样一个类型的参数:FileDescriptor,在使用这个API的时候,需要把文件放到res文件夹平级的assets文件夹里,然后使用下述代码设置DataSource:

AssetFileDescriptor fileDescriptor = getAssets().openFd("rain.mp3");
m_mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),fileDescriptor.getStartOffset(), fileDescriptor.getLength());

3)其他方法

  • getCurrentPosition( ):得到当前的播放位置
  • getDuration() :得到文件的时间
  • getVideoHeight() :得到视频高度
  • getVideoWidth() :得到视频宽度
  • isLooping():是否循环播放
  • isPlaying():是否正在播放
  • pause():暂停
  • prepare():准备(同步)
  • prepareAsync():准备(异步)
  • release() :释放MediaPlayer对象
  • reset():重置MediaPlayer对象
  • seekTo(int msec) :指定播放的位置(以毫秒为单位的时间)
  • setAudioStreamType(int streamtype) :指定流媒体的类型
  • setDisplay(SurfaceHolder sh) :设置用SurfaceHolder来显示多媒体
  • setLooping(boolean looping) :设置是否循环播放
  • setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) :网络流媒体的缓冲监听
  • setOnCompletionListener(MediaPlayer.OnCompletionListener listener) :网络流媒体播放结束监听
  • setOnErrorListener(MediaPlayer.OnErrorListener listener) :设置错误信息监听
  • setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener) :视频尺寸监听
  • setScreenOnWhilePlaying(boolean screenOn) :设置是否使用SurfaceHolder显示
  • setVolume(float leftVolume, float rightVolume) :设置音量
  • start():开始播放
  • stop():停止播放

2.使用代码示例

示例一:使用MediaPlayer播放音频:

运行效果图

关键代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_play;
    private Button btn_pause;
    private Button btn_stop;
    private MediaPlayer mPlayer = null;
    private boolean isRelease = true;   //判断是否MediaPlayer是否释放的标志

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        btn_play = (Button) findViewById(R.id.btn_play);
        btn_pause = (Button) findViewById(R.id.btn_pause);
        btn_stop = (Button) findViewById(R.id.btn_stop);

        btn_play.setOnClickListener(this);
        btn_pause.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_play:
                if(isRelease){
                    mPlayer = MediaPlayer.create(this,R.raw.fly);
                    isRelease = false;
                }
                mPlayer.start();   //开始播放
                btn_play.setEnabled(false);
                btn_pause.setEnabled(true);
                btn_stop.setEnabled(true);
                break;
            case R.id.btn_pause:
                mPlayer.pause();     //停止播放
                btn_play.setEnabled(true);
                btn_pause.setEnabled(false);
                btn_stop.setEnabled(false);
                break;
            case R.id.btn_stop:
                mPlayer.reset();     //重置MediaPlayer
                mPlayer.release();   //释放MediaPlayer
                isRelease = true;
                btn_play.setEnabled(true);
                btn_pause.setEnabled(false);
                btn_stop.setEnabled(false);
                break;
        }
    }
}

注意事项:

播放的是res/raw目录下的音频文件,创建MediaPlayer调用的是create方法,第一次启动播放前不需要再调用prepare(),如果是使用构造方法构造的话,则需要调用一次prepare()方法!另外贴下官方文档中,从其他两种途径播放音频的示例代码:

本地Uri

Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
mediaPlayer.start();

外部URL

String url = "http://........"; // your URL here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare(); // might take long! (for buffering, etc)
mediaPlayer.start();

Note:假如你通过一个URL以流的形式播放在线音频文件,该文件必须可以进行渐进式下载

示例二:使用MediaPlayer播放视频

MediaPlayer主要用于播放音频,没有提供图像输出界面,所以我们需要借助其他的组件来显示MediaPlayer播放的图像输出,我们可以使用用SurfaceView来显示,下面我们使用SurfaceView来写个视频播放的例子:

运行效果图

实现代码

布局文件:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    <SurfaceView
        android:id="@+id/sfv_show"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始" />

    <Button
        android:id="@+id/btn_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="暂停 " />

    <Button
        android:id="@+id/btn_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="终止" />
    
</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements View.OnClickListener, SurfaceHolder.Callback {

    private MediaPlayer mPlayer = null;
    private SurfaceView sfv_show;
    private SurfaceHolder surfaceHolder;
    private Button btn_start;
    private Button btn_pause;
    private Button btn_stop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        sfv_show = (SurfaceView) findViewById(R.id.sfv_show);
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_pause = (Button) findViewById(R.id.btn_pause);
        btn_stop = (Button) findViewById(R.id.btn_stop);

        btn_start.setOnClickListener(this);
        btn_pause.setOnClickListener(this);
        btn_stop.setOnClickListener(this);

        //初始化SurfaceHolder类,SurfaceView的控制器
        surfaceHolder = sfv_show.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setFixedSize(320, 220);   //显示的分辨率,不设置为视频默认

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                mPlayer.start();
                break;
            case R.id.btn_pause:
                mPlayer.pause();
                break;
            case R.id.btn_stop:
                mPlayer.stop();
                break;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        mPlayer = MediaPlayer.create(MainActivity.this, R.raw.lesson);
        mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mPlayer.setDisplay(surfaceHolder);    //设置显示视频显示在SurfaceView上
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {}

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPlayer.isPlaying()) {
            mPlayer.stop();
        }
        mPlayer.release();
    }
}

代码很简单,布局有个SurfaceView,然后调用getHolder获得一个SurfaceHolder对象,在这里完成SurfaceView相关的设置,设置了显示的分辨率以及一个Callback接口,重写了SurfaceView创建时,发生变化时,以及销毁时的三个方法!然后按钮控制播放以及暂停而已。

示例三:使用VideoView播放视频

除了使用MediaPlayer + SurfaceView播放视频的方式,我们还可以使用VideoView来直接播放视频,我们稍微改点东西就可以实现视频播放!运行效果和上面的一致,就不贴了,直接上代码!

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private VideoView videoView;
    private Button btn_start;
    private Button btn_pause;
    private Button btn_stop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }
    
    private void bindViews() {
        videoView = (VideoView) findViewById(R.id.videoView);
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_pause = (Button) findViewById(R.id.btn_pause);
        btn_stop = (Button) findViewById(R.id.btn_stop);

        btn_start.setOnClickListener(this);
        btn_pause.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
        
        //根据文件路径播放
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/lesson.mp4");
        }

        //读取放在raw目录下的文件
        //videoView.setVideoURI(Uri.parse("android.resource://com.jay.videoviewdemo/" + R.raw.lesson));
        videoView.setMediaController(new MediaController(this));
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                videoView.start();
                break;
            case R.id.btn_pause:
                videoView.pause();
                break;
            case R.id.btn_stop:
                videoView.stopPlayback();
                break;
        }
    }
}

这里给大家推荐一套相关《音视频开发核心知识点笔记》,相信可以给大家提供一些帮助,有需要的朋友们也可以下载下来随时查漏补缺:https://qr18.cn/Ei3VPD

音视频初级入门

音视频初级入门主要是接触Android多媒体展示相关的API,通过单独的列举和使用这些API,对Android音视频处理有一个基本的轮廓,虽然知识点相对来说是比较散的,但是点成线、线成面,基本的基础掌握了,通过学习Android音视频核心的API将音视频的流程串联起来,这样对于音视频的了解和控制就不仅仅局限于最外层的API了,而是能够通过相对底层的方式来加深对Android 音视频开发的认知。

  • Android 音视频开发(一):通过三种方式绘制图片
  • Android 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件
  • Android 音视频开发(三):使用 AudioTrack 播放PCM音频
  • Android 音视频开发(四):使用 Camera API 采集视频数据
  • Android 音视频开发(五):使用 MediaExtractor 和 MediaMuxer API 解析和封装 mp4 文件
  • Android 音视频开发(六):MediaCodec API 详解
  • Android 音视频开发(七):音视频录制流程总结 ……

音视频中级进阶:OpenSL ES 学习:https://qr18.cn/Ei3VPD

学习 Android 平台 OpenSL ES API,了解 OpenSL 开发的基本流程,使用OpenSL播放PCM数据,并了解相关API的简单使用

  • Android OpenSL ES 开发:Android OpenSL 介绍和开发流程说明
  • Android OpenSL ES 开发:使用 OpenSL 播放 PCM 数据
  • Android OpenSL ES 开发:Android OpenSL 录制 PCM 音频数据
  • Android OpenSL ES 开发:OpenSL ES利用SoundTouch实现PCM音频的变速和变调

这一部分主要是动手实践,积累实战经验,可以试试给自己定以下目标:

  • 使用 OpenGL 显示一张图片

  • GLSurfaceviw 绘制 Camera 预览画面及实现拍照 使用OpenGL ES

  • 完成视频的录制,并实现视频水印效果

  • Android OpenGL ES 开发(一): OpenGL ES 介绍

  • Android OpenGL ES 开发(二): OpenGL ES 环境搭建

  • Android OpenGL ES 开发(三): OpenGL ES 定义形状

  • Android OpenGL ES 开发(四): OpenGL ES 绘制形状

  • Android OpenGL ES 开发(五): OpenGL ES 使用投影和相机视图

  • Android OpenGL ES 开发(六): OpenGL ES 添加运动效果

  • Android OpenGL ES 开发(七): OpenGL ES 响应触摸事件

  • Android OpenGL ES 开发(八): OpenGL ES 着色器语言GLSL

  • Android OpenGL ES 开发(九): OpenGL ES 纹理贴图

  • Android OpenGL ES 开发(十):通过GLES20与着色器交互

  • ……

音视频高级探究

  • 深入学习音视频编码,如H.264,AAC,研究使用开源编解码库,如x.264,JM 等
  • 深入研究音视频相关的网络协议,如 rtmp,hls,以及封包格式,如:flv,mp4
  • 深入学习一些音视频领域的开源项目,如 webrtc,ffmpeg,ijkplayer,librtmp 等等
  • 将 ffmpeg 库移植到 Android 平台,结合上面积累的经验,编写一款简易的音视频播放器
  • 将 x264 库移植到 Android 平台,结合上面积累的经验,完成视频数据 H264 软编功能
  • 将 librtmp 库移植到 Android 平台,结合上面积累的经验,完成 Android RTMP 推流功能

音视频编解码技术:https://qr18.cn/Ei3VPD

  • 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准 音
  • 视频编解码技术(二):AAC 音频编码技术
  • ……

流媒体协议

  • 流媒体协议(一):HLS 协议
  • 流媒体协议(二):RTMP协议
  • ……

多媒体文件格式

  • 多媒体文件格式(一):MP4 格式
  • 多媒体文件格式(二):FLV 格式
  • 多媒体文件格式(三):M3U8 格式
  • 多媒体文件格式(四):TS 格式
  • 多媒体文件格式(五):PCM / WAV 格式 ……

FFmpeg 学习:https://qr18.cn/Ei3VPD

  • FFmpeg命令行工具学习(一):查看媒体文件头信息工具ffprobe
  • FFmpeg命令行工具学习(二):播放媒体文件的工具ffplay
  • FFmpeg命令行工具学习(三):媒体文件转换工具ffmpeg
  • FFmpeg命令行工具学习(四):FFmpeg 采集设备
  • FFmpeg命令行工具学习(五):FFmpeg 调整音视频播放速度
  • ……

  • FFmpeg 学习(一):FFmpeg 简介
  • FFmpeg 学习(二):Mac下安装FFmpeg
  • FFmpeg 学习(三):将 FFmpeg 移植到 Android平台
  • FFmpeg 学习(四):FFmpeg API 介绍与通用 API 分析
  • FFmpeg 学习(五):FFmpeg 编解码 API 分析
  • FFmpeg 学习(六):FFmpeg 核心模块 libavformat 与 libavcodec 分析
  • ……

  • FFmpeg 结构体学习(一):AVFormatContext 分析
  • FFmpeg 结构体学习(二):AVStream 分析
  • FFmpeg 结构体学习(三):AVPacket 分析
  • FFmpeg 结构体学习(四):AVFrame 分析
  • FFmpeg 结构体学习(五):AVCodec 分析
  • FFmpeg 结构体学习(六):AVCodecContext 分析
  • FFmpeg 结构体学习(七):AVIOContext 分析
  • FFmpeg 结构体学习(八):FFMPEG中重要结构体之间的关系
  • ……

  • FFmpeg 开发之 AVFilter 使用流程总结
  • FFmpeg 过时 Api 汇总整理
  • ……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/922803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Binder通信的核心思想

Binder到底是什么&#xff1f;Binder通信到底是怎么实现的&#xff1f;脱离复杂的Android Framework代码&#xff0c;用最简单的方式来理解下什么是Binder通信。 关于IPC通信 在Linux系统中&#xff0c;正常运行的两个进程A和B&#xff0c;它们之间如果要进行数据的通信&#x…

iview时间控件 动态不可选日期 可选择24小时范围内 时间往后退24小时

演示 html 设定 起始时间 触发on-change 方法结束时间 options 动态设置不可选择的日期。 <!-- 起始时间 --> <FormItem :label"$t(startTime)" prop"startTime"><DatePickertransfertype"datetime":placeholder"$t(pleas…

文件和IO的核心API

操作文件 public static void main(String[] args) throws IOException {//创建一个文件对象&#xff0c;并且指向某个路径File file new File("C:\\Users\\1162\\Desktop\\1.trx");//创建文件System.out.println(file.exists());boolean newFile file.createNewFi…

Mysql-InnoDB数据页结构

一、页结构说明 大致分7部分 二、记录在页中的存储 2.1 页面记录内存结构 行格式 存储到 User Records 部分&#xff0c;每当我们插入一条记录&#xff0c;都会从 Free Space 部分申请一个记录大小的空间划分到 User Records 部分 &#xff0c;用完则申请新的页&#xff1b; …

Vue中使用element-plus中的el-dialog定义弹窗-内部样式修改-v-model实现-demo

效果图 实现代码 <template><el-dialog class"no-code-dialog" v-model"isShow" title"没有收到验证码&#xff1f;"><div class"nocode-body"><div class"tips">请尝试一下操作</div><d…

用香港服务器域名需要备案吗?

​  在选择服务器的时候&#xff0c;很多人会考虑使用香港服务器。香港服务器的一个优势就是不需要备案。不管是虚拟主机还是云主机&#xff0c;无论是个人网站还是商业网站&#xff0c;都不需要进行备案手续。 域名实名认证 虽然不需要备案&#xff0c;但使用香港服务器搭建…

Doris安装及使用

Doris简介 Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库&#xff0c;以极速易用的特点被人们所熟知&#xff0c;仅需亚秒级响应时间即可返回海量数据下的查询结果&#xff0c;不仅可以支持高并发的点查询场景&#xff0c;也能支持高吞吐的复杂分析场景。基于…

怎么做出老板看得懂的财务数据分析报表?

财务数据分析报表的主要作用就是为决策提供必不可少的数据信息&#xff0c;让老板以及管理层在充分了解企业现金流情况、债务能力、还债能力、进账情况等财务信息后&#xff0c;更科学地做出运营管理决策。因此&#xff0c;财务数据分析报表必须做得直观易懂&#xff0c;毕竟不…

Linux监控基础命令

Linux资源监控 一.资源监控常用命令汇总 内存&#xff1a;top、free、vmstat、pmap I/O&#xff1a;vmstat、sar CPU&#xff1a;top、vmstat、mpstat、iostat 二.监控命令 日常检测使用top和free就足够了&#xff0c;如果要对系统进行日常监控可以使用zabbix或者prometh…

微软宣布在 Excel 中使用 Python:结合了 Python 的强大功能和 Excel 的灵活性。

自诞生以来&#xff0c;Microsoft Excel 改变了人们组织、分析和可视化数据的方式&#xff0c;为每天使用它的数百万人提供了决策基础。今天&#xff0c;我们宣布发布 Excel 中的 Python 公共预览版&#xff0c;从而使 Excel 中的分析功能取得重大进展。 Excel 中的 Python 可…

网易2023年Q2财报:营收240亿元,游戏技术跨产业创造数字就业

8月24日&#xff0c;网易发布2023年Q2财报。二季度&#xff0c;网易继续聚焦主营业务&#xff0c;业绩表现稳健&#xff1b;净收入240亿元&#xff0c;非公认会计准则下归属于公司股东的持续经营净利润90亿元&#xff0c;研发投入39亿元&#xff0c;相当于拿出近一半利润投入研…

同城分类信息便民公众号抖音百度支付宝小程序开发

同城分类信息便民公众号抖音百度支付宝小程序开发 用户注册和登录功能&#xff1a;允许用户通过手机号或第三方账号登录&#xff0c;并进行个人信息补充和修改。发布信息功能&#xff1a;用户可以发布需要出售或者需要购买的商品、服务或者其他资源信息&#xff0c;并填写详细…

专访 Hyper Oracle:可编程的 zkOracle 打造未来世界的超算

许多 Web3 应用在实现的过程中&#xff0c;常常会遇到基础设施方面的限制&#xff0c;包括去中心化自动化、预言机、链上信息搜索等问题。绝大部分区块链的中间件网络都是依赖于节点质押来保证节点执行的诚实性&#xff0c;这样的模式会产生诸多衍生问题&#xff0c;例如安全性…

linux centos7 sort命令的学习与训练

sort命令的功能是对文件中的各行进行排序。sort命令有许多非常实用的选项&#xff0c;这些选项最初是用来对数据库格式的文件内容进行各种排序操作的。实际上&#xff0c;sort命令可以被认为是一个非常强大的数据管理工具&#xff0c;用来管理内容类似数据库记录的文件。 sort…

Centos7防火墙启动失败问题

下面记录一下防火墙启动失败问题排查和解决的过程。防火墙启动失败的错误信息如下&#xff1a; ERROR: Exception DBusException: org.freedesktop.DBus.Error.AccessDenied: Conn...n file 比较郁闷的地方是之前防火墙是正常启动的&#xff0c;后面不知道服务器修改了什么配置…

[MyBatis系列②]Dao层开发的两种方式

目录 1、传统开发 1.1、代码 1.2、存在的问题 2、代理开发 2.1、开发规范 2.2、代码 ⭐mybatis系列①&#xff1a;增删改查 1、传统开发 传统的mybatis开发中&#xff0c;是在数据访问层实现相应的接口&#xff0c;在实现类中用"命名空间.id"的形式找到对应的映…

ARM汇编【5】:STACK AND FUNCTIONS

在这一部分中&#xff0c;我们将研究称为堆栈的进程的一个特殊内存区域。本章介绍了Stack的用途和相关操作。此外&#xff0c;我们还将介绍ARM中函数的实现、类型和差异。 STACK 一般来说&#xff0c;堆栈是程序/进程中的一个内存区域。这部分内存是在创建进程时分配的。…

《信息安全技术 数据安全风险评估方法》(征求意见稿)解读

8月21日&#xff0c;全国信息安全标准化技术委员会秘书处发布关于征求国家标准《信息安全技术 数据安全风险评估方法》&#xff08;征求意见稿&#xff09;意见的通知&#xff0c;面向社会广泛征求意见。 一、数据安全相关政策法规 此前&#xff0c;国家也发布了多部数据安全相…

dockerfile镜像及Harbor私有仓库搭建的应用

目录 搭建私有仓库harbordockerfile构建镜像1&#xff0c;先创建一个目录2&#xff0c;编写dockerfile3&#xff0c;构建4&#xff0c; 验证镜像5&#xff0c;标记镜像6&#xff0c;上传镜像 搭建私有仓库harbor 首先安装容器编排工具&#xff1a;docker compose 我使用的是离…

企业如何做好实施数字工厂管理系统前的需求分析

随着工业4.0的到来&#xff0c;数字工厂系统解决方案已经成为企业提高生产效率、优化资源配置和提升产品质量的重要工具。在考虑实施数字工厂管理系统之前&#xff0c;企业需要进行详细的需求分析&#xff0c;以确保系统的实施能够真正满足企业的业务需求。本文将探讨企业如何做…