当前位置: 首页 > news >正文

Android 视频开发

在 Android 平台上进行视频开发,您需要掌握以下关键知识点,以确保能够成功地开发和调试视频应用程序:

  1. Android视频架构: 了解 Android 的视频系统架构,包括视频捕获、编码、解码、渲染和显示等。

  2. 视频格式和编解码: 熟悉不同视频格式(如H.264、VP9、AV1)及其编解码方法,以便正确处理视频数据。

  3. Camera API: 学习使用 Camera API 进行摄像头的控制和捕获图像/视频帧,了解不同摄像头的功能和参数设置。

  4. MediaCodec: 学会使用 MediaCodec 类进行硬件加速的视频编解码,以提高性能和效率。

  5. SurfaceView和TextureView: 了解如何使用 SurfaceView 和 TextureView 来进行视频渲染,实现流畅的视频播放。

  6. MediaPlayer和ExoPlayer: 学会使用 MediaPlayer 和 ExoPlayer 来播放本地或网络视频,以及如何处理音频和视频的同步。

  7. 视频流处理和分析: 了解如何处理和分析实时视频流,包括视频特效、滤镜、实时变换等。

  8. 延迟和同步: 了解视频延迟、音视频同步和帧率同步等问题,确保实时视频播放的准确性和稳定性。

  9. 视频权限和适配性: 了解 Android 的摄像头和视频权限模型,以及在不同 Android 版本上进行视频开发的适配性问题。

  10. 视频录制和编辑: 学会使用 MediaRecorder 进行视频录制,以及如何进行视频编辑、剪辑和合成。

  11. 视频编解码性能优化: 学会进行视频编解码性能优化,包括如何选择合适的编解码器、码率控制、硬件加速等。

  12. 调试和性能优化: 学会使用调试工具和分析工具来诊断视频问题,以及如何进行性能优化,避免视频卡顿、画面失真等问题。

  13. 视频流传输和网络: 了解视频流传输的协议(如RTP、RTSP、HTTP)、网络传输的优化和视频质量控制。

  14. 视频测试: 学会编写视频测试用例,进行视频功能和质量的测试,确保应用程序在各种情况下正常工作。

综上所述,视频开发涉及多个领域,包括硬件、视频编解码、应用开发和性能优化等。深入了解这些关键知识点将有助于您在 Android 平台上成功地开发高质量的视频应用程序。

Android视频架构

Android 的视频系统架构涵盖了视频捕获、编码、解码、渲染和显示等多个方面。下面我将详细介绍每个方面的主要组件和流程:

  1. 视频捕获:

    • Camera API / CameraX: 用于控制设备的摄像头,捕获视频流并提供预览。
    • MediaRecorder: 用于录制视频并将其编码为文件格式。
  2. 视频编码:

    • MediaCodec: 提供硬件或软件编码器,将原始视频帧编码为压缩格式(如H.264)。
    • MediaFormat: 定义了编码参数,如视频分辨率、比特率等。
  3. 视频解码:

    • MediaCodec: 也用于解码器,将压缩格式的视频解码成原始帧数据。
    • MediaExtractor: 用于从容器文件中提取视频轨道的数据。
  4. 视频渲染和显示:

    • SurfaceView 和 TextureView: 用于在界面上绘制视频图像,通常与MediaPlayer或ExoPlayer结合使用。
    • OpenGL ES: 可以使用 OpenGL ES 进行更高级的视频渲染和特效处理。
  5. 视频播放:

    • MediaPlayer: 用于播放本地或网络上的音视频文件,支持常见的媒体格式。
    • ExoPlayer: 更强大和可定制的播放器框架,支持更多的媒体格式和功能,如流媒体。
  6. 视频流媒体:

    • MediaPlayer / ExoPlayer: 用于实时流媒体播放,支持 HTTP、HLS、RTSP 等协议。
    • MediaCodec: 可以与网络传输一起使用,以便在接收到压缩数据时进行解码和播放。
  7. 视频处理和特效:

    • SurfaceTexture: 用于将外部纹理绑定到 OpenGL 渲染器,实现图像处理和特效。
    • OpenGL ES: 可以在渲染视频帧之前进行图像处理,如滤镜、旋转、缩放等。
  8. 视频编辑:

    • MediaExtractor / MediaMuxer: 用于提取和混合媒体轨道,从而实现视频剪辑和合并。

总体来说,Android 的视频系统架构涉及多个 API 和组件,开发者可以根据需求选择适合的工具来实现视频的捕获、编码、解码、渲染和显示。需要根据具体的应用场景和需求,灵活地组合这些组件来实现高质量的视频体验。在开发过程中,了解每个组件的功能和使用方法,以及相互之间的配合关系,是非常重要的。

视频格式和编解码

视频格式和编解码是实现视频播放和处理的关键部分。不同的视频格式(也称为编码格式)使用不同的编码方法来压缩和解压缩视频数据。以下是一些常见的视频格式以及它们的编解码方法:

  1. H.264(AVC):

    • H.264 是一种广泛使用的视频编码标准,也被称为高级视频编码(Advanced Video Coding,AVC)。
    • 它使用了先进的压缩技术,能够在保持较高视频质量的同时减小文件大小。
    • H.264 编码使用了预测编码和变换编码技术,以及运动补偿等方法。
    • 在 Android 中,可以使用 MediaCodec 来进行 H.264 编码和解码。
  2. VP9:

    • VP9 是由 Google 开发的开放式视频编码标准,旨在提供高效的视频压缩和更好的视频质量。
    • VP9 采用了类似于 H.264 的技术,但具有更好的性能和更高的压缩效率。
    • VP9 适用于网络流媒体和在线视频播放,如 YouTube 使用了 VP9 来提供高分辨率的视频流。
    • 在 Android 中,可以使用 ExoPlayer 来进行 VP9 视频的解码和播放。
  3. AV1:

    • AV1 是一个由 Alliance for Open Media 开发的开放式视频编码格式,旨在提供更高的压缩效率和更好的视频质量。
    • AV1 使用了先进的编码技术,如预测编码、变换编码和运动补偿等。
    • 尽管 AV1 在压缩效率和质量方面表现出色,但由于其计算复杂性较高,可能需要更强大的硬件支持。
    • 在 Android 中,也可以使用 ExoPlayer 来进行 AV1 视频的解码和播放。
  4. 其他格式:

    • 此外,还有许多其他视频编码格式,如 MPEG-2、MPEG-4、HEVC(H.265)等。
    • MPEG-2 通常用于广播和 DVD,MPEG-4 用于各种多媒体应用,HEVC 作为 H.265 在一些高分辨率和高帧率的场景中应用广泛。

在处理不同视频格式时,你需要了解它们的编解码方式、参数设置以及适用场景,以便正确地选择和配置相关的编解码器。在 Android 开发中,可以使用 MediaCodec 进行硬件加速的视频编解码,或者使用播放器框架(如 MediaPlayer、ExoPlayer)来处理不同格式的视频流。了解各种格式的特点和优劣势,可以帮助你在开发过程中做出更合适的选择。

编解码流程

编解码(Encoding and Decoding)是将原始数据进行压缩(编码)和解压缩(解码)的过程,以便在存储、传输和处理时减小数据量、提高效率并保持数据的完整性。在多媒体领域,特别是在视频和音频处理中,编解码是至关重要的环节,因为它决定了媒体数据的存储和传输效率,以及最终用户所能够观看或听到的内容质量。

以下是编解码的详细介绍:

编码(Encoding):
编码是将原始数据转换为更紧凑的格式,以减小数据量。在多媒体编码中,常见的步骤包括:

  1. 预处理: 对原始数据进行预处理,如对音频进行滤波去噪,对视频进行颜色空间转换等。
  2. 变换和量化: 对数据进行数学变换(如离散余弦变换),然后进行量化以减小数据范围。
  3. 熵编码: 使用熵编码方法(如霍夫曼编码、算术编码)将量化后的数据映射到紧凑的编码。

解码(Decoding):
解码是将编码后的数据恢复为原始格式的过程,以便进行播放、显示或后续处理。在多媒体解码中,常见的步骤包括:

  1. 解码和逆变换: 使用解码器对编码后的数据进行解码和逆变换,以还原原始数据。
  2. 去量化: 对解码后的数据进行去量化,恢复到原始的数值范围。
  3. 后处理: 对解码后的数据进行后处理,如恢复颜色信息、去除噪声等。
  4. 渲染或播放: 最终将解码后的数据渲染到屏幕或播放音频。

在视频编解码中,常见的编码标准包括 H.264(AVC),VP9,AV1,H.265(HEVC)等。每种标准都使用不同的技术来实现高效的压缩和解压缩,以满足不同的应用需求。对于音频编解码,常见的标准包括 MP3,AAC,Opus 等。

在 Android 开发中,你可以使用硬件加速的编解码器(如 MediaCodec)来进行视频和音频的编解码。了解不同编解码标准的特点、适用场景以及编解码方法,可以帮助你在开发中做出正确的选择,以实现高效的媒体处理和播放。

视频编解码方法

视频编解码是将原始视频数据进行压缩(编码)和解压缩(解码)的过程,以便在存储和传输时减小文件大小并提高传输效率。以下是视频编解码的一般流程以及涉及的主要方法:

  1. 预测编码(Predictive Coding):

    • 预测编码是一种通过预测当前图像帧的像素值,然后仅编码预测误差来实现压缩的方法。
    • 在编码端,使用预测器对当前帧进行预测,然后计算预测误差(残差)。
    • 预测误差通常会比原始帧数据小得多,因此只需编码残差来达到压缩的效果。
    • 常见的预测编码方法包括运动补偿和帧内预测。
  2. 变换编码(Transform Coding):

    • 变换编码通过对图像块应用数学变换,将数据转换成频域表示,然后在频域进行编码。
    • 最常见的变换是离散余弦变换(Discrete Cosine Transform,DCT),用于将图像从空域转换为频域。
    • 变换编码可通过去除高频部分来减少数据量,因为人眼对高频细节不太敏感。
  3. 熵编码(Entropy Coding):

    • 熵编码用于进一步减小数据量,通过为经常出现的数据分配短编码,为不常出现的数据分配长编码。
    • 常见的熵编码方法有霍夫曼编码和算术编码。
  4. 运动补偿(Motion Compensation):

    • 运动补偿是一种用于预测编码的技术,通过比较当前帧和之前帧之间的运动来减小残差。
    • 在编码端,计算当前帧与参考帧之间的运动矢量,并将残差编码。
    • 在解码端,使用运动矢量和参考帧重建当前帧。
  5. 量化(Quantization):

    • 量化是将图像或频域系数映射到较小的离散值的过程,以减小数据量。
    • 量化导致了信息的丢失,因此适当的量化级别需要平衡压缩率和图像质量。

这些方法通常结合在一起使用,构成了现代视频编解码的基础。不同的视频编码标准(如H.264、VP9、AV1)使用这些方法的不同变体和优化策略,以达到高压缩效率和良好的图像质量。在视频编解码器中,编码端和解码端需要共同遵循相同的算法和参数设置,以确保正确的数据传输和重建。

在 Android 开发中,可以使用 MediaCodec 来进行硬件加速的视频编解码。开发者需要了解各种编解码方法的工作原理和优缺点,以便在实际应用中进行合适的选择和调整。

Camera API

Camera2 API 是 Android 5.0 引入的摄像头 API,它提供了更强大和灵活的功能,适用于高级的摄像头应用开发。相对于传统的 Camera API,Camera2 API 允许更精细的控制,支持多摄像头设备,提供更高的性能和更好的用户体验。以下是 Camera2 API 的详细介绍和代码示例:

1. 获取摄像头实例:

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
String cameraId = null;
try {String[] cameraIds = manager.getCameraIdList();cameraId = cameraIds[0]; // 获取第一个摄像头
} catch (CameraAccessException e) {e.printStackTrace();
}

2. 配置摄像头参数:

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
Size[] sizes = map.getOutputSizes(SurfaceTexture.class); // 获取支持的预览尺寸

3. 创建预览会话:

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
CameraDevice cameraDevice = null;
try {manager.openCamera(cameraId, new CameraDevice.StateCallback() {@Overridepublic void onOpened(CameraDevice camera) {cameraDevice = camera;// 创建预览会话List<Surface> surfaces = new ArrayList<>();SurfaceTexture texture = textureView.getSurfaceTexture();Surface surface = new Surface(texture);surfaces.add(surface);try {camera.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(CameraCaptureSession session) {// 配置成功,可以进行预览等操作}}, null);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onDisconnected(CameraDevice camera) {// 摄像头断开连接}@Overridepublic void onError(CameraDevice camera, int error) {// 打开摄像头发生错误}}, null);
} catch (CameraAccessException e) {e.printStackTrace();
}

4. 拍照:

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
try {CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);Size[] jpegSizes = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputSizes(ImageFormat.JPEG);ImageReader reader = ImageReader.newInstance(jpegSizes[0].getWidth(), jpegSizes[0].getHeight(),ImageFormat.JPEG, 1);List<Surface> outputSurfaces = new ArrayList<>(2);outputSurfaces.add(reader.getSurface());outputSurfaces.add(new Surface(textureView.getSurfaceTexture()));final CaptureRequest.Builder captureBuilder =cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);captureBuilder.addTarget(reader.getSurface());captureBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);// 拍照reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {@Overridepublic void onImageAvailable(ImageReader reader) {Image image = null;try {image = reader.acquireLatestImage();ByteBuffer buffer = image.getPlanes()[0].getBuffer();byte[] data = new byte[buffer.remaining()];buffer.get(data);// 处理拍照得到的图像数据} finally {if (image != null) {image.close();}}}}, null);final CameraCaptureSession.CaptureCallback captureCallback =new CameraCaptureSession.CaptureCallback() {@Overridepublic void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,TotalCaptureResult result) {// 拍照完成}};cameraDevice.createCaptureSession(outputSurfaces,new CameraCaptureSession.StateCallback() {@Overridepublic void onConfigured(CameraCaptureSession session) {try {session.capture(captureBuilder.build(), captureCallback, null);} catch (CameraAccessException e) {e.printStackTrace();}}@Overridepublic void onConfigureFailed(CameraCaptureSession session) {// 配置会话失败}}, null);
} catch (CameraAccessException e) {e.printStackTrace();
}

以上示例演示了 Camera2 API 的一些基本用法,包括打开摄像头、配置摄像头参数、创建预览会话和拍照等操作。Camera2 API 提供了更多的功能,如手动对焦、自动曝光控制、预览回调等,可以根据需求进一步扩展和优化应用。

请注意,Camera2 API 的使用相对复杂,需要处理许多回调和状态变化。确保在开发过程中仔细阅读官方文档并进行适当的测试,以确保正确地使用摄像头功能。

SurfaceView和TextureView

SurfaceView 和 TextureView 都是 Android 中用于在界面上绘制图像的视图组件,它们在不同的场景下有不同的用途和特点。下面我会详细介绍这两个视图,并提供示例代码以说明它们的使用方法。

SurfaceView:

SurfaceView 是一个特殊的视图,它允许你在一个独立的线程(SurfaceHolder.Callback 中的回调线程)中绘制图像,从而避免了主 UI 线程阻塞的问题。SurfaceView 适用于需要在绘图线程中执行耗时的绘制操作的情况,如视频播放、游戏等。

示例代码:

public class SurfaceViewActivity extends AppCompatActivity implements SurfaceHolder.Callback {private SurfaceView surfaceView;private MediaPlayer mediaPlayer;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_surface_view);surfaceView = findViewById(R.id.surfaceView);surfaceView.getHolder().addCallback(this);}@Overridepublic void surfaceCreated(SurfaceHolder holder) {try {mediaPlayer = new MediaPlayer();mediaPlayer.setDataSource("path_to_your_video");mediaPlayer.setDisplay(holder);mediaPlayer.prepare();mediaPlayer.start();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {// SurfaceView 的尺寸发生改变}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {if (mediaPlayer != null) {mediaPlayer.release();mediaPlayer = null;}}
}

TextureView:

TextureView 是一个用于在布局层次中显示视频、图像等纹理的视图。与 SurfaceView 不同,TextureView 可以在 UI 线程中绘制,适用于需要在 UI 线程中进行图像绘制的场景,如相机预览、图像处理等。

示例代码:

public class TextureViewActivity extends AppCompatActivity {private TextureView textureView;private Camera camera;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_texture_view);textureView = findViewById(R.id.textureView);textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {@Overridepublic void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {// 打开摄像头并设置预览camera = Camera.open();Camera.Parameters parameters = camera.getParameters();List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();Camera.Size selectedSize = sizes.get(0); // 选择合适的预览尺寸parameters.setPreviewSize(selectedSize.width, selectedSize.height);camera.setParameters(parameters);try {camera.setPreviewTexture(surfaceTexture);camera.startPreview();} catch (IOException e) {e.printStackTrace();}}@Overridepublic void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width, int height) {// TextureView 的尺寸发生改变}@Overridepublic boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {if (camera != null) {camera.stopPreview();camera.release();camera = null;}return true;}@Overridepublic void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {// 纹理更新时的回调}});}
}

总结起来,SurfaceView 和 TextureView 都是用于在 Android 应用中绘制图像的视图组件,但在使用场景和特点上有所不同。SurfaceView 适合在独立线程中进行绘制操作,TextureView 则适合在 UI 线程中绘制。根据你的需求,选择合适的视图组件可以帮助你实现更流畅的界面和更好的用户体验。

相关文章:

Android 视频开发

在 Android 平台上进行视频开发&#xff0c;您需要掌握以下关键知识点&#xff0c;以确保能够成功地开发和调试视频应用程序&#xff1a; Android视频架构&#xff1a; 了解 Android 的视频系统架构&#xff0c;包括视频捕获、编码、解码、渲染和显示等。 视频格式和编解码&am…...

【计算机网络篇】UDP协议

✅作者简介&#xff1a;大家好&#xff0c;我是小杨 &#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; UDP协议 1&#xff0c;UDP 简介 UDP&#xff08;User Datagram Protocol&#xff09;是一种无连…...

LeetCode 2682. 找出转圈游戏输家

【LetMeFly】2682.找出转圈游戏输家 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-the-losers-of-the-circular-game/ n 个朋友在玩游戏。这些朋友坐成一个圈&#xff0c;按 顺时针方向 从 1 到 n 编号。从第 i 个朋友的位置开始顺时针移动 1 步会到达第 (i …...

数据结构单链表

单链表 1 链表的概念及结构 概念&#xff1a;链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链 接次序实现的 。 在我们开始讲链表之前&#xff0c;我们是写了顺序表&#xff0c;顺序表就是类似一个数组的东西&#xff0…...

自定义WEB框架结合Jenkins实现全自动测试

自定义WEB框架结合Jenkins实现全自动测试 allure生成 allure生成 1.allure–纯命令运行 -固定的–稍微记住对应的单词即可。2 安装&#xff0c;2个步骤: 1.下载allure包&#xff0c;然后配置环境变量。 https://github.com/allure-framework/allure2/releases/tag/2.22.4 2.在…...

PHP加密与安全的最佳实践

PHP加密与安全的最佳实践 概述 在当今信息时代&#xff0c;数据安全是非常重要的。对于开发人员而言&#xff0c;掌握加密和安全的最佳实践是必不可少的。PHP作为一种常用的后端开发语言&#xff0c;提供了许多功能强大且易于使用的加密和安全性相关函数和类。本文将介绍一些P…...

SQL Server数据库无法连接

问题如下&#xff1a; 原因&#xff1a;sql server服务器未开启 解决方法&#xff1a;以管理员身份打开cmd&#xff0c;输入&#xff1a;net start mssqlserver。...

videojs 播放视频

背景&#xff1a;在项目中使用第三方插件videojs进行播放视频&#xff0c;点击事件更改播放的数据源。 一、视频相关理论 (一)、背景 网络流媒体的呈现形式分为两种&#xff1a;直播点播 (二)、流媒体的3种协议 分类&#xff1a;HTTPHLSRTMP定义&#xff1a;基于HTTP的流媒体…...

vue强制刷新变量

在前端开发中&#xff0c;我们经常需要变量的值实时响应到界面上。Vue就是一个非常强大的前端框架&#xff0c;它的数据绑定能够非常好地实现变量与界面的同步更新。但是有时候&#xff0c;我们需要强制刷新某个变量的值&#xff0c;以便界面能及时地反映出它的变化。本文将介绍…...

[QCA6174]QCA6174 5G WiFi DFS处理逻辑分析及雷达误检率高优化规避

DFS认证信息 WIFI DFS测试要求 Master设备需要测试的项目 4.6.2.1 Channel Availability Check 信道可用性检查 定义其作为雷达脉冲检测机制,当雷达脉冲出现时所占用的信道需要能被设备检测到已经被占用。当相关信道未被占用时,这些信道被称为Avaliable Channel可用信道 …...

预防SQL漏洞注入和规避网络攻击

前言: 虽然近些年SQL注入已经被各类的安全开发框架规避了绝大部分&#xff0c;但SQL注入作为一种最原始的攻击手段之一&#xff0c;破坏力仍然十分强大&#xff0c;因为它直捣黄龙数据中心。所以未雨绸缪&#xff0c;各位不可不重视。 预防SQL注入方法措施&#xff1a; 服务器…...

《Go 语言第一课》课程学习笔记(一)

配好环境&#xff1a;选择一种最适合你的 Go 安装方法 选择 Go 版本 一般情况下&#xff0c;建议采用最新版本。因为 Go 团队发布的 Go 语言稳定版本的平均质量一直是很高的&#xff0c;少有影响使用的重大 bug。可以根据不同实际项目需要或开源社区的情况使用不同的版本。 有…...

网络安全 Day29-运维安全项目-iptables防火墙

iptables防火墙 1. 防火墙概述2. 防火墙2.1 防火墙种类及使用说明2.2 必须熟悉的名词2.3 iptables 执行过程※※※※※2.4 表与链※※※※※2.4.1 简介2.4.2 每个表说明2.4.2.1 filter表 :star::star::star::star::star:2.4.2.2 nat表 2.5 环境准备及命令2.6 案例01&#xff1a…...

SQL 复习 03

函数与关键字 用法说明round(x, n)四舍五入&#xff0c;x为浮点数&#xff0c;n为保留的位数ceil(x)向上取整floor(x)向下取整truncate(x, n)截断x&#xff0c;n为保留的位&#xff0c;该位之后的数值置零&#xff0c;位数表示示例&#xff1a;321.123&#xff0c;其中小数点前…...

出现 sudo: docker: command not found 的解决方法

目录 1. 问题所示2. 原理分析3. 解决方法3.1 未成功安装引起3.2 环境变量引起1. 问题所示 安装了docker,但是执行docker命令的时候,提示该问题: ubuntu@10-41-104-1:~$ sudo docker ps -a sudo: docker: command not foundubuntu@10-41-104-1:~$ sudo apt-get install doc…...

FastApi-1-结合sql 增/查demo

目录 FastAPI学习记录项目结构部分接口/代码展示感受全部代码 FastAPI学习记录 fastapi已经学习有一段时间&#xff0c;今天抽时间简单整理下。 官网介绍&#xff1a; FastAPI 是一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的 web 框架&#xff0c;使用 Py…...

Spring学习笔记3

使用注解开发&#xff1a; Component 组件开发相当于 Value(“xxx”)可以对属性进行赋值 package pojo;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; //等价于<bean id"user" class"po…...

springboot艰难版本升级之路!! springboot 2.3.x版本升级到2.7.x版本

文章目录 1.缘起1.1 升级到版本2.7.12启动失败,而且没有报错信息1.2 application-dev.yml 配置加载问题1.3 openfeign依赖问题汇总1.4 datasource报错1.5 MySQL驱动升级1.6 循环依赖报错1.7 跨域错误临时总结1.缘起 由于服务需要搭建链路追踪, 需要把springboot版本升级到2.7.1…...

Codeforces 1856E2 复杂度分析 + DP

题意 传送门 Codeforces 1856E2 PermuTree (hard version) 题解 可以独立考虑每一个固定的 p l c a ( u , v ) plca(u,v) plca(u,v) 对答案的贡献。可以观察到&#xff0c;对于 p p p 的每一棵子树&#xff0c;其所有节点在最优情况下仅有 a p < a v a_p < a_v ap…...

Windows - UWP - 为UWP应用创建桌面快捷方式

Windows - UWP - 为UWP应用创建桌面快捷方式 前言 这是一个较为简单的方式&#xff0c;不需要过多的命令行。 How 首先Win R -> shell:AppsFolder -> 回车&#xff0c; 这将显示电脑上的已安装应用&#xff08;Win32 & UWP&#xff09;&#xff1a; 找到想要创建…...

了解Web DDoS海啸攻击的4个维度

我们都知道近年来网络攻击的数量和频率急剧上升&#xff0c;针对Web应用程序的DDoS海啸攻击就是其中增长非常迅速的一个种类。过去常见的HTTP/S洪水攻击正在大范围的转变为更难对付的Web DDoS海啸攻击&#xff0c;每个人都应该提前做好被攻击的准备并采取适当的保护措施。 哪些…...

【数学建模】逻辑回归算法(Logistic Resgression)

逻辑回归算法 简介逻辑回归与条件概率绘制sigmoid函数 简介 逻辑回归算法是一种简单但功能强大的二元线性分类算法。需要注意的是&#xff0c;尽管"逻辑回归"名字带有“回归”二字&#xff0c;但逻辑回归是一个分类算法&#xff0c;而不是回归算法。 我认为&#xff…...

Hadoop HA集群两个NameNode都是standby或者主NameNode是standby,从NameNode是active的情况集锦

文章目录 背景架构HDFS HA配置错误原因解决方案方案一方案二方案三&#xff08;首先查看自己各参数文件是否配置出错&#xff09; 后记补充failovertransitionToActive 常用端口号及配置文件常用端口号hadoop3.xhadoop2.x 常用配置文件 这里说一下配置Hadoop HA集群可能出现的两…...

[Go版]算法通关村第十一关白银——位运算的高频算法题

目录 专题1&#xff1a;位移的妙用题目&#xff1a;位1的个数&#xff08;也被称为汉明重量&#xff09;解法1&#xff1a;遍历所有位&#xff0c;判断每个位的数字是否是1Go代码 解法2&#xff1a;依次消除每个1的位 numnum&(num-1)Go代码 题目&#xff1a;比特位计数思路…...

Swift 基础

工程目录 请点击下面工程名称&#xff0c;跳转到代码的仓库页面&#xff0c;将工程 下载下来 Demo Code 里有详细的注释 点击下载代码&#xff1a;swift-01...

IDEA的常用设置,让你更快速的编程

一、前言 在使用JetBrains的IntelliJ IDEA进行软件开发时&#xff0c;了解和正确配置一些常用设置是非常重要的。IDEA的强大功能和定制性使得开发过程更加高效和舒适。 在本文中&#xff0c;我们将介绍一些常用的IDEA设置&#xff0c;帮助您更好地利用IDEA进行开发。这些设置包…...

docker 镜像的导出与导入 save 与 load

一、镜像导出 docker save 导出 将系统中的镜像保存为压缩包&#xff0c;进行文件传输。使用 docker save --help 查看命令各参数&#xff0c;或者去docker官网查看.以 hello-world镜像为例。 A&#xff1a;将镜像保存为tar包 docker save image > package.tar docker sa…...

WPF显示初始界面--SplashScreen

WPF显示初始界面–SplashScreen 前言 WPF应用程序的运行速度快&#xff0c;但并不能在瞬间启动。当第一次启动应用程序时&#xff0c;会有一些延迟&#xff0c;因为公共语言运行时&#xff08;CLR&#xff09;首先需要初始化.NET环境&#xff0c;然后启动应用程序。 对于WPF中…...

08- AD/DA模/数转换

AD/DA模/数转换 8、AD/DA模/数转换8.1 AD转换注意 示例8.2 DA转换DAC转换原理&#xff1a; 8.3 PWM的DAC 8、AD/DA模/数转换 8.1 AD转换 通道引脚对照表&#xff1a; ADC的引脚&#xff1a; 规则通道和注入通道&#xff1a; 各个通道可以在单次、连续、扫描或者间断模式里…...

DTC服务(0x14 0x19 0x85)

DTC相关的服务有ReadDTCInformation (19) service&#xff0c;ControlDTCSetting (85) service和ReadDTCInformation (19) service ReadDTCInformation (19) service 该服务允许客户端从车辆内任意一台服务器或一组服务器中读取驻留在服务器中的诊断故障代码( DTC )信息的状态…...