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

【C语言ffmpeg】打开第一个视频

文章目录

  • 前言
    • 须知
    • ffmpeg打开文件基本流程图
    • ffmpeg打开媒体文件
      • `AVFormatContext *avformat_alloc_context(void);`
      • AVFormatContext 成员变量及其作用
        • `AVInputFormat *iformat`
        • `AVOutputFormat *oformat`
        • `void *priv_data`
        • `AVIOContext *pb`
        • `unsigned int nb_streams`
        • `AVStream **streams`
        • `char filename[1024]`
        • `int64_t duration`
        • `int64_t bit_rate`
        • `unsigned int nb_programs`
        • `AVProgram **programs`
        • `AVChapter **chapters`
        • `unsigned int nb_chapters`
        • `AVDictionary *metadata`
        • `int flags`
        • `int64_t start_time`
        • `int64_t start_time_realtime`
        • `int probesize`
        • `int max_analyze_duration`
        • `AVPacketList *packet_buffer`
      • `int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);`
      • `int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);`
      • `void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);`
      • `AVCodec *avcodec_find_decoder(enum AVCodecID id);`
      • `const char *avcodec_get_name(enum AVCodecID id);`
      • `const char *av_get_media_type_string(enum AVMediaType media_type);`
      • `void avformat_close_input(AVFormatContext **s);`
    • 示例
  • 总结


前言

FFmpeg 是一个强大的多媒体处理库,广泛应用于音视频编解码、转换和流媒体处理等领域。C语言作为一种底层编程语言,与FFmpeg结合使用,可以高效地处理各种音视频任务。在本篇文章中,我们将探讨如何利用C语言和FFmpeg库打开一个音视频文件,并对其进行基本的处理操作。这不仅为深入学习FFmpeg的使用打下基础,也为从事多媒体处理工作的开发者提供实用的参考。


须知

本教程使用ffmpeg版本为7.0.1如有函数不同请下载和我一样的版本

ffmpeg打开文件基本流程图

开始↓
包含头文件和定义视频文件路径↓
分配格式上下文↓
打开输入文件↓
|----------------------|
| 打开失败             |
||
| 打印错误信息并返回   |
|----------------------|↓
检查文件中的流信息↓
|----------------------|
| 检查失败             |
||
| 打印错误信息并关闭文件 |
|----------------------|↓
打印文件格式信息↓
遍历所有流↓
获取流和编解码参数↓
查找解码器↓
打印流的基本信息↓
|----------------------|
| 没有找到解码器       |
||
| 打印不支持的编解码器 |
|----------------------|↓
关闭输入文件并释放格式上下文↓
结束

ffmpeg打开媒体文件

AVFormatContext *avformat_alloc_context(void);

  • 作用: 分配并初始化 AVFormatContext 结构体。
  • 参数: 无。
  • 返回值: 指向新分配的 AVFormatContext 的指针。

AVFormatContext 结构体是 FFmpeg 中非常重要的一个数据结构,它包含了与多媒体文件或流相关的所有信息。以下是一些常用且重要的成员及其作用:

AVFormatContext 成员变量及其作用

AVInputFormat *iformat
  • 作用: 指向输入格式的指针。当打开输入文件时,这个成员将指向描述文件格式的 AVInputFormat 结构。
AVOutputFormat *oformat
  • 作用: 指向输出格式的指针。当创建输出文件时,这个成员将指向描述文件格式的 AVOutputFormat 结构。
void *priv_data
  • 作用: 私有数据,存储特定于输入/输出格式的私有数据。
AVIOContext *pb
  • 作用: I/O 上下文,用于管理文件或流的输入/输出操作。
unsigned int nb_streams
  • 作用: 文件中的流数量。
AVStream **streams
  • 作用: 指向包含所有流(音频、视频、字幕等)的指针数组。
char filename[1024]
  • 作用: 文件名或 URL。
int64_t duration
  • 作用: 文件的总时长(以 AV_TIME_BASE 为单位)。
int64_t bit_rate
  • 作用: 文件的总比特率(以比特每秒为单位)。
unsigned int nb_programs
  • 作用: 文件中节目的数量。
AVProgram **programs
  • 作用: 指向包含所有节目的指针数组。
AVChapter **chapters
  • 作用: 指向包含所有章节的指针数组。
unsigned int nb_chapters
  • 作用: 文件中的章节数量。
AVDictionary *metadata
  • 作用: 文件的元数据(如标题、作者、版权等)。
int flags
  • 作用: 标志位,用于控制各种操作行为。
int64_t start_time
  • 作用: 文件的开始时间(以 AV_TIME_BASE 为单位)。
int64_t start_time_realtime
  • 作用: 以实时起始时间的时间戳表示的开始时间。
int probesize
  • 作用: 探测的大小,用于确定文件的格式。
int max_analyze_duration
  • 作用: 分析的最大时长,用于确定文件的格式。
AVPacketList *packet_buffer
  • 作用: 包含读取的数据包的缓冲区。

以下示例展示如何访问 AVFormatContext 的一些成员变量:

AVFormatContext *formatContext = avformat_alloc_context();
if (avformat_open_input(&formatContext, "example.mp4", NULL, NULL) == 0) {printf("Format: %s\n", formatContext->iformat->name);printf("Number of streams: %u\n", formatContext->nb_streams);printf("Duration: %" PRId64 "\n", formatContext->duration);printf("Bit rate: %" PRId64 "\n", formatContext->bit_rate);for (unsigned int i = 0; i < formatContext->nb_streams; i++) {AVStream *stream = formatContext->streams[i];printf("Stream #%u\n", i);printf("  Codec ID: %d\n", stream->codecpar->codec_id);printf("  Codec type: %s\n", av_get_media_type_string(stream->codecpar->codec_type));}avformat_close_input(&formatContext);
}

int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);

  • 作用: 打开输入文件并读取头部信息。
  • 参数:
    • ps: 指向 AVFormatContext 指针的指针。
    • filename: 文件名。
    • fmt: 指定输入格式,可以为 NULL。
    • options: 一些额外的选项,可以为 NULL。
  • 返回值: 成功返回 0,失败返回负值。

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);

  • 作用: 检查文件中的流信息。
  • 参数:
    • ic: AVFormatContext 指针。
    • options: 一些额外的选项,可以为 NULL。
  • 返回值: 成功返回非负值,失败返回负值。

void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);

  • 作用: 打印文件格式信息。
  • 参数:
    • ic: AVFormatContext 指针。
    • index: 要打印的流的索引,为 0 表示打印全部流信息。
    • url: 文件的 URL。
    • is_output: 指示是输入还是输出格式,0 表示输入,1 表示输出。
  • 返回值: 无。

AVCodec *avcodec_find_decoder(enum AVCodecID id);

  • 作用: 查找给定 codec id 的解码器。
  • 参数:
    • id: codec 的 ID。
  • 返回值: 指向 AVCodec 的指针,如果未找到返回 NULL。

const char *avcodec_get_name(enum AVCodecID id);

  • 作用: 获取 codec id 对应的 codec 名称。
  • 参数:
    • id: codec 的 ID。
  • 返回值: codec 名称的字符串指针。

const char *av_get_media_type_string(enum AVMediaType media_type);

  • 作用: 获取媒体类型的字符串表示。
  • 参数:
    • media_type: 媒体类型。
  • 返回值: 媒体类型名称的字符串指针。

void avformat_close_input(AVFormatContext **s);

  • 作用: 关闭输入文件并释放格式上下文。
  • 参数:
    • s: 指向 AVFormatContext 指针的指针。
  • 返回值: 无。

示例

#include <stdio.h>
#include "include/libavcodec/avcodec.h"
#include "include/libavformat/avformat.h"
#include "include/libavutil/avutil.h"int main() {const char *videoname = "/home/ubuntu/MyFFMPEG/template_c_first/test2.mp4";//打开输入文件并读取头部信息AVFormatContext *formatContext = avformat_alloc_context();if(avformat_open_input(&formatContext,videoname,NULL,NULL) != 0){printf("open err:%s\n",videoname);return -1;}// 检查文件中的流信息if (avformat_find_stream_info(formatContext, NULL) < 0) {printf("Could not find stream information in file %s\n", videoname);avformat_close_input(&formatContext);return -1;}// 打印文件格式信息av_dump_format(formatContext, 0, videoname, 0);// 遍历所有流并打印流信息for (unsigned int i = 0; i < formatContext->nb_streams; i++) {AVStream *stream = formatContext->streams[i];AVCodecParameters *codecParams = stream->codecpar;AVCodec *codec = avcodec_find_decoder(codecParams->codec_id);if (codec == NULL) {printf("Unsupported codec!\n");continue;}printf("Stream #%u:\n", i);printf("  Codec: %s (%s)\n", codec->name, avcodec_get_name(codecParams->codec_id));printf("  Type: %s\n", av_get_media_type_string(codecParams->codec_type));printf("  Duration: %ld\n", stream->duration);printf("  Time base: %d/%d\n", stream->time_base.num, stream->time_base.den);}// 关闭输入文件并释放格式上下文avformat_close_input(&formatContext);return 0;
}

输出:

ubuntu@ubuntu-virtual-machine:~/MyFFMPEG/template_c_first/build$ ./ffmpeg_test 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/ubuntu/MyFFMPEG/template_c_first/test2.mp4':Metadata:major_brand     : isomminor_version   : 512compatible_brands: isomiso2avc1mp41encoder         : Lavf61.1.100description     : Packed by Bilibili XCoder v2.0.2Duration: 00:00:30.07, start: 0.000000, bitrate: 3275 kb/sStream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 3124 kb/s, 60 fps, 60 tbr, 16k tbn (default)Metadata:handler_name    : Bento4 Video Handlervendor_id       : [0][0][0][0]Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 135 kb/s (default)Metadata:handler_name    : Bento4 Sound Handlervendor_id       : [0][0][0][0]
Stream #0:Codec: h264 (h264)Type: videoDuration: 481066Time base: 1/16000
Stream #1:Codec: aac (aac)Type: audioDuration: 1323000Time base: 1/44100

总结

通过本文的介绍,我们了解了如何使用C语言结合FFmpeg库来打开一个音视频文件,并对其进行基本处理。FFmpeg提供了丰富的功能和灵活的接口,能够满足各种多媒体处理需求。掌握FFmpeg的使用方法,不仅能够提升我们在多媒体领域的开发效率,还能拓宽我们的技术视野。希望本篇文章能为读者提供有益的帮助,激发进一步探索FFmpeg和多媒体处理技术的兴趣。

相关文章:

【C语言ffmpeg】打开第一个视频

文章目录 前言须知ffmpeg打开文件基本流程图ffmpeg打开媒体文件AVFormatContext *avformat_alloc_context(void);AVFormatContext 成员变量及其作用AVInputFormat *iformatAVOutputFormat *oformatvoid *priv_dataAVIOContext *pbunsigned int nb_streamsAVStream **streamscha…...

【Langchain大语言模型开发教程】模型、提示和解析

&#x1f517; LangChain for LLM Application Development - DeepLearning.AI 学习目标 1、使用Langchain实例化一个LLM的接口 2、 使用Langchain的模板功能&#xff0c;将需要改动的部分抽象成变量&#xff0c;在具体的情况下替换成需要的内容&#xff0c;来达到模板复用效…...

Flutter 中的基本数据类型:num、int 和 double

在 Dart 编程语言中&#xff0c;数值类型的基础是 num&#xff0c;而 int 和 double 则是 num 的子类型。在开发 Flutter 应用时&#xff0c;理解这三者的区别和使用场景是非常重要的。本文将详细介绍 num、int 和 double 的定义及其使用区别。 num num 是 Dart 中的数值类型…...

基于Python+Django,开发的一个在线教育系统

一、项目简介 使用Python的web框架Django进行开发的一个在线教育系统&#xff01; 二、所需要的环境与组件 Python3.6 Django1.11.7 Pymysql Mysql pure_pagination DjangoUeditor captcha xadmin crispy_forms 三、安装 1. 下载项目后进入项目目录cd Online-educ…...

密码学原理精解【9】

这里写目录标题 迭代密码概述SPN具体算法过程SPN算法基本步骤举例说明注意 轮换-置换网络一、定义与概述二、核心组件三、加密过程四、应用实例五、总结 轮函数理论定义与作用特点与性质应用实例总结 迭代密码理论定义与原理特点与优势应用场景示例发展趋势 AES特点概述一、算法…...

【Nacos】Nacos服务注册与发现 心跳检测机制源码解析

在前两篇文章&#xff0c;介绍了springboot的自动配置原理&#xff0c;而nacos的服务注册就依赖自动配置原理。 Nacos Nacos核心功能点 服务注册 :Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务&#xff0c;提供自身的元数据&#xff0c;比如ip地址、端…...

python 66 个冷知识 0720

66个有趣的Python冷知识 一行反转列表 使用切片一行反转列表&#xff1a;reversed_list my_list[::-1] 统计文件单词数量 使用 collections.Counter 统计文件中每个单词的数量&#xff1a;from collections import Counter; with open(file.txt) as f: word_count Counter(f…...

利用PyTorch进行模型量化

利用PyTorch进行模型量化 目录 利用PyTorch进行模型量化 一、模型量化概述 1.为什么需要模型量化&#xff1f; 2.模型量化的挑战 二、使用PyTorch进行模型量化 1.PyTorch的量化优势 2.准备工作 3.选择要量化的模型 4.量化前的准备工作 三、PyTorch的量化工具包 1.介…...

Android 小白菜鸟从入门到精通教程

前言 Android一词最早出现于法国作家利尔亚当&#xff08;Auguste Villiers de l’Isle-Adam&#xff09;在1886年发表的科幻小说《未来的夏娃》&#xff08;L’ve future&#xff09;中。他将外表像人的机器起名为Android。从初学者的角度出发&#xff0c;通过通俗易懂的语言…...

php相关

php相关 ​ 借鉴了小迪安全以及各位大佬的博客&#xff0c;如果一切顺利&#xff0c;会不定期更新。 如果感觉不妥&#xff0c;可以私信删除。 默认有php基础。 文章目录 php相关1. php 缺陷函数1. 与2. MD53. intval()4. preg_match() 2. php特性1. php字符串解析特性2. 杂…...

uniapp上传功能用uni-file-picker实现

文章目录 html代码功能实现css样式代码 html代码 <uni-file-pickerselect"onFileSelected"cancel"onFilePickerCancel"limit"1"class"weightPage-upload-but"file-mediatype"image"></uni-file-picker><imag…...

【PPT笔记】1-3节 | 默认设置/快捷键/合并形状

文章目录 说明笔记1 默认设置1.1 OFFICE版本选择1.1.1 Office某某数字专属系列1.1.2 Office3651.1.3 产品信息怎么看 1.2 默认设置1.2.1 暗夜模式1.2.2 无限撤回1.2.3 自动保存&#xff08;Office2013版本及以上&#xff09;1.2.4 图片压缩1.2.5 字体嵌入1.2.6 多格式导出1.2.7…...

Qt中的高分辨率及缩放处理

写在前面 使用Qt开发界面客户端&#xff0c;需要考虑不同分辨率及缩放对UI界面的影响&#xff0c;否则会影响整体的交互使用。 问题 高分辨率/缩放设备上图片/图标模糊 若不考虑高分辨及缩放处理&#xff0c;在高分辨率/缩放设备上&#xff0c;软件中的图片、图标可能会出现…...

电机泵盖机器人打磨去毛刺,选德国进口高精度主轴

机器人打磨去毛刺该如何选择主轴呢&#xff1f;首先我们需要考虑的是工件的材质&#xff0c;电机泵盖通常使用铸铁、不锈钢、合金钢等金属材质&#xff0c;因此这类保持的硬度较高&#xff0c;一般会选择功率、扭矩较大的德国进口高精度主轴Kasite 4060 ER-S。 Kasite 4060 ER-…...

Android init.rc各阶段的定义和功能

Android开机优化系列文档-CSDN博客 Android 14 开机时间优化措施汇总-CSDN博客Android 14 开机时间优化措施-CSDN博客根据systrace报告优化系统时需要关注的指标和优化策略-CSDN博客Android系统上常见的性能优化工具-CSDN博客Android上如何使用perfetto分析systrace-CSDN博客A…...

.net dataexcel 脚本公式 函数源码

示例如: ScriptExec(""sum(1, 2, 3, 4)"") 结果等于10 using Feng.Excel.Builder; using Feng.Excel.Collections; using Feng.Excel.Interfaces; using Feng.Script.CBEexpress; using Feng.Script.Method; using System; using System.Collections.Gen…...

HarmonyOS ArkUi @CustomDialog 和promptAction.openCustomDialog踩坑以及如何选择

CustomDialog 内使用Link&#xff0c;如何正常使用 错误使用方式&#xff1a; 定义一个函数&#xff0c;在函数内使用弹窗&#xff0c;如下面代码showDialog&#xff1a; 这种使用方式&#xff0c;无法在自定义的CustomDialog内使用 Link&#xff0c;进行父子双向绑定&#x…...

Python面试题:详细讲解Python的多线程与多进程编程问题

在 Python 中&#xff0c;多线程和多进程编程是并发编程的两种主要方式&#xff0c;用于提高程序的执行效率和响应性。虽然它们都可以实现并发执行&#xff0c;但它们的工作原理和适用场景有所不同。以下是对 Python 多线程和多进程编程的详细讲解&#xff0c;包括它们的工作原…...

前端Canvas入门——用canvas写五子棋?

前言 五子棋的实现其实不难&#xff0c;因为本身就是一个很小的游戏。 至于画线什么的&#xff0c;其实很简单&#xff0c;都是lineTo()&#xff0c;moveTo()就行了。 难的在于——怎么让棋子落入到指定的格子上&#xff0c;怎么判断连子胜利。 当然啦&#xff0c;这部分是…...

[PaddlePaddle飞桨] PaddleDetection-通用目标检测-小模型部署

PaddleDetection的GitHub项目地址 推荐环境&#xff1a; PaddlePaddle > 2.3.2 OS 64位操作系统 Python 3(3.5.1/3.6/3.7/3.8/3.9/3.10)&#xff0c;64位版本 pip/pip3(9.0.1)&#xff0c;64位版本 CUDA > 10.2 cuDNN > 7.6pip下载指令&#xff1a; python -m pip i…...

Golang | Leetcode Golang题解之第239题滑动窗口最大值

题目&#xff1a; 题解&#xff1a; func maxSlidingWindow(nums []int, k int) []int {n : len(nums)prefixMax : make([]int, n)suffixMax : make([]int, n)for i, v : range nums {if i%k 0 {prefixMax[i] v} else {prefixMax[i] max(prefixMax[i-1], v)}}for i : n - 1…...

深度解析:在 React 中实现类似 Vue 的 KeepAlive 组件

在前端开发中&#xff0c;Vue 的 keep-alive 组件是一个非常强大的工具&#xff0c;它可以在组件切换时缓存组件的状态&#xff0c;避免重新渲染&#xff0c;从而提升性能。那么&#xff0c;如何在 React 中实现类似的功能呢&#xff1f;本文将带你深入探讨&#xff0c;并通过代…...

2024-7-20 IT新闻

目录 微软全球IT系统故障 中国量子计算产业峰会召开 其他IT相关动态 微软全球IT系统故障 后续处理&#xff1a; 微软和CrowdStrike均迅速响应&#xff0c;发布了相关声明并部署了修复程序。CrowdStrike撤销了有问题的软件更新&#xff0c;以帮助用户恢复系统正常运作。微软也…...

前端组件化开发:以Vue自定义底部操作栏组件为例

摘要 随着前端技术的不断演进&#xff0c;组件化开发逐渐成为提升前端开发效率和代码可维护性的关键手段。本文将通过介绍一款Vue自定义的底部操作栏组件&#xff0c;探讨前端组件化开发的重要性、实践过程及其带来的优势。 一、引言 随着Web应用的日益复杂&#xff0c;传统的…...

11.斑马纹列表 为没有文本的链接设置样式

斑马纹列表 创建一个背景色交替的条纹列表。 使用 :nth-child(odd) 或 :nth-child(even) 伪类选择器,根据元素在一组兄弟元素中的位置,对匹配的元素应用不同的 background-color。 💡 提示:你可以用它对其他 HTML 元素应用不同的样式,如 <div>、<tr>、<p&g…...

【算法】跳跃游戏II

难度&#xff1a;中等 题目&#xff1a; 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[…...

学习大数据DAY20 Linux环境配置与Linux基本指令

目录 Linux 介绍 Linux 发行版 Linux 和 Windows 比较 Linux 就业方向&#xff1a; 下载 CentOS Linux 目录树 Linux 目录结构 作业 1 常用命令分类 文件目录类 作业 2 vim 编辑文件 作业 3 你问我第 19 天去哪了&#xff1f;第 19 天在汇报第一阶段的知识总结&#xff0c;没什…...

达梦+flowable改造

原项目springbootflowablemysql模式现需改造springbootflowable达梦&#xff0c; 1.在项目中引入达梦jpa包 引入高版本包已兼容flowable&#xff08;6.4.2&#xff09;liquibase&#xff08;3.6.2&#xff09; 我没有像网上做覆盖及达梦配置 <dependency> …...

【乐吾乐2D可视化组态编辑器】消息

消息 乐吾乐2D可视化组态编辑器demo&#xff1a;https://2d.le5le.com/ 监听消息 const fn (event, data) > {}; meta2d.on(event, fn);// 监听全部消息 meta2d.on(*, fn);// 取消监听 meta2d.off(event, fn); meta2d.off(*, fn); Copy 系统消息 event&#xff08;…...

Qt创建列表,通过外部按钮控制列表的选中下移、上移以及左侧图标的显现

引言 项目中需要使用列表QListWidget,但是不能直接拿来使用。需要创建一个列表,通过向上和向下的按钮来向上或者向下移动选中列表项,当当前项背选中再去点击确认按钮,会在列表项的前面出现一个图标。 实现效果 本实例实现的效果如下: 实现思路 思路一 直接采用QLis…...

python做网站原理/网站有吗免费的

前言 在JVM专栏的第一篇&#xff1a;我们讲了什么是双亲委派模型&#xff0c;以及为什么需要双亲委派模型。还没看过的大佬&#xff0c;有钱没钱都捧个人场&#xff0c;点它&#xff1a; 你能说出jvm的类加载是什么吗 同时还了解到这样设计是为了保持JVM整个体系的稳定。但在…...

新势力网站建设/网站优化关键词排名

laravel-modules可以通过模块化的方式进行开发。 另外。我们开发可以不从app里面进行开发 因为app本身也携带了一些laravel的类。以后如果出来laravel 9 或者 laravel10的话 我们升级也好升级。因为我们已经新建了别的模块 效果如下 不需要手动 安装。 首先在 Laravel 项…...

企业网站响应式/semicircle

装饰者模式 概念 装饰者模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。这种类型的设计模式属于结构模式&#xff0c;它是作为现有类的一个包装。 这种模式创建了一个装饰类&#xff0c;用来包装原有的类&a…...

百度不收录网站/seo专业培训费用

为什么80%的码农都做不了架构师&#xff1f;>>> Question 345. Reverse Vowels of a String Solution 思路&#xff1a;交换元音&#xff0c;第一次遍历&#xff0c;先把出现元音的索引位置记录下来&#xff0c;第二遍遍历元音的索引并替换。 Java实现&#xff1a;…...

网站开发目的和意义/培训seo哪家学校好

Using mysqldump for Backups使用mysqldump工具可以以以下几种方式来生成dump文件:.作为备份在数据丢失的情况下来执行数据恢复.作为源数据用来配置复制从服务器.作为源数据用来进行实验:-为了复制数据库而不用改变源数据-为了测试潜在的升级后不兼容的问题mysqldump生成两种类…...

建设部网站官网 建造师 挂靠/seo优化好做吗

方法一&#xff1a;生成两个&#xff08;1,5&#xff09;的随机数&#xff0c;这样一共是25种情况&#xff0c;注意这两个数是有顺序的&#xff0c;从这25种情况中&#xff0c;取前21种&#xff0c;每三种代表&#xff08;1,7&#xff09;中的一个数字&#xff0c;如果取到的是…...