FFmpeg编译4(1)

news2025/2/8 20:51:02
  • ffmpeg.c
  • ffmpeg.h

修改ffmpeg文件

  • 修改刚刚拷贝的ffmpeg.c文件,找到int main(int argc, char **argv)函数,将其替换为int run(int argc, char **argv)
  • 在修改后的run(int argc, char **argv) 末尾(retrun 之前)加上如上如下代码:

nb_filtergraphs = 0;
progress_avio = NULL;

input_streams = NULL;
nb_input_streams = 0;
input_files = NULL;
nb_input_files = 0;

output_streams = NULL;
nb_output_streams = 0;
output_files = NULL;
nb_output_files = 0;

  • 并在ffmpeg.h文件末尾加上

int run(int argc, char **argv);

  • 再次打开ffmpeg.c文件,注释掉run(int argc, char **argv)下的所有exit_program函数,大致代码如下:

int run(int argc, char **argv)
{
int i, ret;
BenchmarkTimeStamps ti;

init_dynload();

register_exit(ffmpeg_cleanup);

setvbuf(stderr,NULL,_IONBF,0); /* win32 runtime needs this */

av_log_set_flags(AV_LOG_SKIP_REPEATED);
parse_loglevel(argc, argv, options);

if(argc>1 && !strcmp(argv[1], “-d”)){
run_as_daemon=1;
av_log_set_callback(log_callback_null);
argc–;
argv++;
}

#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
avformat_network_init();

show_banner(argc, argv, options);

/* parse options and open all input/output files */
ret = ffmpeg_parse_options(argc, argv);
if (ret < 0);
// exit_program(1);

if (nb_output_files <= 0 && nb_input_files == 0) {
show_usage();
av_log(NULL, AV_LOG_WARNING, “Use -h to get full help or, even better, run ‘man %s’\n”, program_name);
// exit_program(1);
}

/* file converter / grab */
if (nb_output_files <= 0) {
av_log(NULL, AV_LOG_FATAL, “At least one output file must be specified\n”);
// exit_program(1);
}

// if (nb_input_files == 0) {
// av_log(NULL, AV_LOG_FATAL, “At least one input file must be specified\n”);
// exit_program(1);
// }

for (i = 0; i < nb_output_files; i++) {
if (strcmp(output_files[i]->ctx->oformat->name, “rtp”))
want_sdp = 0;
}

current_time = ti = get_benchmark_time_stamps();
if (transcode() < 0);
// exit_program(1);
if (do_benchmark) {
int64_t utime, stime, rtime;
current_time = get_benchmark_time_stamps();
utime = current_time.user_usec - ti.user_usec;
stime = current_time.sys_usec - ti.sys_usec;
rtime = current_time.real_usec - ti.real_usec;
av_log(NULL, AV_LOG_INFO,
“bench: utime=%0.3fs stime=%0.3fs rtime=%0.3fs\n”,
utime / 1000000.0, stime / 1000000.0, rtime / 1000000.0);
}
av_log(NULL, AV_LOG_DEBUG, “%“PRIu64” frames successfully decoded, %“PRIu64” decoding errors\n”,
decode_error_stat[0], decode_error_stat[1]);
if ((decode_error_stat[0] + decode_error_stat[1]) * max_error_rate < decode_error_stat[1]);
// exit_program(69);

// exit_program(received_nb_signals ? 255 : main_return_code);

nb_filtergraphs = 0;
progress_avio = NULL;

input_streams = NULL;
nb_input_streams = 0;
input_files = NULL;
nb_input_files = 0;

output_streams = NULL;
nb_output_streams = 0;
output_files = NULL;
nb_output_files = 0;

return main_return_code;
}

新建ffmpeg-invoke

jni文件下新建一个ffmpeg-invoke.cpp的c++文件,将如下代码写入

#include <jni.h>
#include <string.h>
#include “android/log.h”

#define LOGD(…) __android_log_print(ANDROID_LOG_DEBUG, “ffmpeg-invoke”, VA_ARGS)

extern “C”{
#include “ffmpeg.h”
#include “libavcodec/jni.h”
}

extern “C”
JNIEXPORT jint JNICALL
Java_com_coder_ffmpeg_jni_FFmpegCmd_run(JNIEnv *env, jclass type, jint cmdLen,
jobjectArray cmd) {
//set java vm
JavaVM *jvm = NULL;
env->GetJavaVM(&jvm);
av_jni_set_java_vm(jvm, NULL);

char *argCmd[cmdLen] ;
jstring buf[cmdLen];

for (int i = 0; i < cmdLen; ++i) {
buf[i] = static_cast(env->GetObjectArrayElement(cmd, i));
char *string = const_cast<char *>(env->GetStringUTFChars(buf[i], JNI_FALSE));
argCmd[i] = string;
LOGD(“argCmd=%s”,argCmd[i]);
}

int retCode = run(cmdLen, argCmd);
LOGD(“ffmpeg-invoke: retCode=%d”,retCode);

return retCode;

}

需注意的是 Java_com_coder_ffmpeg_jni_FFmpegCmd_runcom_coder_ffmpeg_jni表示FFmpegCmd所在你Android项目的位置。

新建Android.mk

jni文件夹下,新建Android.mk的文件,将如下代码拷贝,但是需要注意的是将 LOCAL_C_INCLUDES路径替换成你源码所在位置。

// 将此处的路径改为你ffmepg源码所在位置
LOCAL_C_INCLUDES := /home/anjoiner/Documents/AnJoiner/ffmpeg

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := libavdevice
LOCAL_SRC_FILES := prebuilt/libavdevice.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavutil
LOCAL_SRC_FILES := prebuilt/libavutil.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libswresample
LOCAL_SRC_FILES := prebuilt/libswresample.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libswscale
LOCAL_SRC_FILES := prebuilt/libswscale.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavcodec
LOCAL_SRC_FILES := prebuilt/libavcodec.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavformat
LOCAL_SRC_FILES := prebuilt/libavformat.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libavfilter
LOCAL_SRC_FILES := prebuilt/libavfilter.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := libpostproc
LOCAL_SRC_FILES := prebuilt/libpostproc.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := ffmpeg-invoke

LOCAL_SRC_FILES :=ffmpeg-invoke.cpp
cmdutils.c
ffmpeg_filter.c
ffmpeg_opt.c
ffmpeg_hw.c
ffmpeg.c

// 将此处的路径改为你ffmepg源码所在位置
LOCAL_C_INCLUDES := /home/anjoiner/Documents/AnJoiner/ffmpeg

LOCAL_LDLIBS := -llog -ljnigraphics -lz -landroid -lm -pthread -L$(SYSROOT)/usr/lib
LOCAL_SHARED_LIBRARIES := libavdevice libavcodec libavfilter libavformat libavutil libswresample libswscale libpostproc

include $(BUILD_SHARED_LIBRARY)

新建Application.mk

jni文件夹下,新建Application.mk并将如下代码拷贝进入

APP_ABI := armeabi-v7a
APP_PLATFORM := android-21
APP_OPTIM := release
APP_STL := stlport_static

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

到此基本上的配置已经完成,然后在jni文件下运行ndk-build

/home/anjoiner/Documents/AnJoiner/build/jni# /home/anjoiner/Documents/AnJoiner/ffmpeg/ndk/ndk-build

当出现如下代码就表示成功了

[armeabi-v7a] SharedLibrary : libffmpeg-invoke.so
[armeabi-v7a] Install : libffmpeg-invoke.so => libs/armeabi-v7a/libffmpeg-invoke.so
[armeabi-v7a] Install : libpostproc.so => libs/armeabi-v7a/libpostproc.so
[armeabi-v7a] Install : libswresample.so => libs/armeabi-v7a/libswresample.so
[armeabi-v7a] Install : libswscale.so => libs/armeabi-v7a/libswscale.so

测试

  • 新建一个支持C++项目,注意包名需是上述ava_com_coder_ffmpeg_jni_FFmpegCmd_run中的com.coder.ffmpeg
  • jni的同级目录下,会生成一个libs的目录,将这个目录下的armeabi-v7a文件拷贝到你所在的Android项目中的app/src/main/jniLibs
  • 新建一个jni的文件目录,在此目录下新建一个FFmpegCmd

/**

  • @author: AnJoiner
  • @datetime: 19-7-30
    */
    public class FFmpegCmd {
    static {
    System.loadLibrary(“avdevice”);
    System.loadLibrary(“avutil”);
    System.loadLibrary(“avcodec”);
    System.loadLibrary(“swresample”);
    System.loadLibrary(“avformat”);
    System.loadLibrary(“swscale”);
    System.loadLibrary(“avfilter”);
    System.loadLibrary(“postproc”);
    System.loadLibrary(“ffmpeg-invoke”);
    }

private static native int run(int cmdLen, String[] cmd);

public static int runCmd(String[] cmd){
return run(cmd.length,cmd);
}
}

拷贝进来run方法名会出现红色,不用管他,

  • 在我们的MainActivity中进行调用,此方法是将音频进行剪切

public class MainActivity extends AppCompatActivity {

// Used to load the ‘native-lib’ library on application startup.
static {
System.loadLibrary(“native-lib”);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
100);
}

// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());

findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ffmpegTest();
}
});
}

/**

  • A native method that is implemented by the ‘native-lib’ native library,
  • which is packaged with this application.
    */
    public native String stringFromJNI();

private void ffmpegTest() {
new Thread() {
@Override
public void run() {
long startTime = System.currentTimeMillis();
String input =
Environment.getExternalStorageDirectory().getPath() + File.separator +
“DCIM” + File.separator + “test.mp3”;
String output =
Environment.getExternalStorageDirectory().getPath() + File.separator +
“DCIM” + File.separator + “output.mp3”;

String cmd = “ffmpeg -y -i %s -vn -acodec copy -ss %s -t %s %s”;
String result = String.format(cmd, input, “00:00:30”, “00:00:40”, output);
FFmpegCmd.runCmd(result.split(" "));
Log.d(“FFmpegTest”, “run: 耗时:” + (System.currentTimeMillis() - startTime));
}
}.start();

}

如果上述步骤不出错,基本没什么问题,在资料的参考下,我也弄了好几天,但幸好结果还是好的~

使用 NDK-r20 编译FFmpeg

前面使用过老版本NDK-r14b编译FFmpeg,其实质是通过gcc去进行编译,但是最新的NDK版本中已经不使用gcc去编译,而是使用clang去进行编译.这里贴上最新配置文件代码

  • 下载最新版本NDK-r20
  • 下载FFmpeg-4.2.1

#!/bin/bash

清空上次的编译

make clean
#你自己的NDK路径.
export NDK=/home/anjoiner/Android/Sdk/ndk-bundle
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/
API=29

function build_android
{
echo “Compiling FFmpeg for C P U " . / c o n f i g u r e   − − p r e f i x = CPU" ./configure \ --prefix= CPU"./configure prefix=PREFIX
–enable-neon
–enable-hwaccels
–enable-gpl
–enable-postproc
–enable-shared
–enable-jni
–enable-mediacodec
–enable-decoder=h264_mediacodec
–disable-static
–disable-doc
–enable-ffmpeg
–disable-ffplay
–disable-ffprobe
–enable-avdevice
–disable-doc
–disable-symver
–cross-prefix= C R O S S P R E F I X   − − t a r g e t − o s = a n d r o i d   − − a r c h = CROSS_PREFIX \ --target-os=android \ --arch= CROSSPREFIX targetos=android arch=ARCH
–cpu= C P U   − − c c = CPU \ --cc= CPU cc=CC
–cxx= C X X − − e n a b l e − c r o s s − c o m p i l e   − − s y s r o o t = CXX --enable-cross-compile \ --sysroot= CXXenablecrosscompile sysroot=SYSROOT
–extra-cflags=”-Os -fpic O P T I M I Z E C F L A G S "   − − e x t r a − l d f l a g s = " OPTIMIZE_CFLAGS" \ --extra-ldflags=" OPTIMIZECFLAGS" extraldflags="ADDI_LDFLAGS"
$ADDITIONAL_CONFIGURE_FLAG
make clean
make
make install
echo “The Compilation of FFmpeg for $CPU is completed”
}

#armv8-a
ARCH=arm64
CPU=armv8-a
CC= T O O L C H A I N / b i n / a a r c h 64 − l i n u x − a n d r o i d TOOLCHAIN/bin/aarch64-linux-android TOOLCHAIN/bin/aarch64linuxandroidAPI-clang
CXX= T O O L C H A I N / b i n / a a r c h 64 − l i n u x − a n d r o i d TOOLCHAIN/bin/aarch64-linux-android TOOLCHAIN/bin/aarch64linuxandroidAPI-clang++
SYSROOT= N D K / t o o l c h a i n s / l l v m / p r e b u i l t / l i n u x − x 8 6 6 4 / s y s r o o t C R O S S P R E F I X = NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot CROSS_PREFIX= NDK/toolchains/llvm/prebuilt/linuxx8664/sysrootCROSSPREFIX=TOOLCHAIN/bin/aarch64-linux-android-
PREFIX= ( p w d ) / a n d r o i d / (pwd)/android/ (pwd)/android/CPU
OPTIMIZE_CFLAGS=“-march=$CPU”
build_android

#armv7-a
ARCH=arm
CPU=armv7-a
CC= T O O L C H A I N / b i n / a r m v 7 a − l i n u x − a n d r o i d e a b i TOOLCHAIN/bin/armv7a-linux-androideabi TOOLCHAIN/bin/armv7alinuxandroideabiAPI-clang
CXX= T O O L C H A I N / b i n / a r m v 7 a − l i n u x − a n d r o i d e a b i TOOLCHAIN/bin/armv7a-linux-androideabi TOOLCHAIN/bin/armv7alinuxandroideabiAPI-clang++
SYSROOT= N D K / t o o l c h a i n s / l l v m / p r e b u i l t / l i n u x − x 8 6 6 4 / s y s r o o t C R O S S P R E F I X = NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot CROSS_PREFIX= NDK/toolchains/llvm/prebuilt/linuxx8664/sysrootCROSSPREFIX=TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX= ( p w d ) / a n d r o i d / (pwd)/android/ (pwd)/android/CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
build_android

#x86
ARCH=x86
CPU=x86
CC= T O O L C H A I N / b i n / i 686 − l i n u x − a n d r o i d TOOLCHAIN/bin/i686-linux-android TOOLCHAIN/bin/i686linuxandroidAPI-clang
CXX= T O O L C H A I N / b i n / i 686 − l i n u x − a n d r o i d TOOLCHAIN/bin/i686-linux-android TOOLCHAIN/bin/i686linuxandroidAPI-clang++
SYSROOT= N D K / t o o l c h a i n s / l l v m / p r e b u i l t / l i n u x − x 8 6 6 4 / s y s r o o t C R O S S P R E F I X = NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot CROSS_PREFIX= NDK/toolchains/llvm/prebuilt/linuxx8664/sysrootCROSSPREFIX=TOOLCHAIN/bin/i686-linux-android-
PREFIX= ( p w d ) / a n d r o i d / (pwd)/android/ (pwd)/android/CPU
OPTIMIZE_CFLAGS=“-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32”
build_android
#x86_64
ARCH=x86_64
CPU=x86-64
CC= T O O L C H A I N / b i n / x 8 6 6 4 − l i n u x − a n d r o i d TOOLCHAIN/bin/x86_64-linux-android TOOLCHAIN/bin/x8664linuxandroidAPI-clang
CXX= T O O L C H A I N / b i n / x 8 6 6 4 − l i n u x − a n d r o i d TOOLCHAIN/bin/x86_64-linux-android TOOLCHAIN/bin/x8664linuxandroidAPI-clang++
SYSROOT= N D K / t o o l c h a i n s / l l v m / p r e b u i l t / l i n u x − x 8 6 6 4 / s y s r o o t C R O S S P R E F I X = NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot CROSS_PREFIX= NDK/toolchains/llvm/prebuilt/linuxx8664/sysrootCROSSPREFIX=TOOLCHAIN/bin/x86_64-linux-android-
PREFIX= ( p w d ) / a n d r o i d / (pwd)/android/ (pwd)/android/CPU
OPTIMIZE_CFLAGS=“-march=$CPU -m
sse4.2 -mpopcnt -m64 -mtune=intel”
build_android
参考资料

编译FFmpeg4.1.3并移植到Android app中使用(最详细的FFmpeg-Android编译教程)

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取
m
sse4.2 -mpopcnt -m64 -mtune=intel"
build_android
参考资料

编译FFmpeg4.1.3并移植到Android app中使用(最详细的FFmpeg-Android编译教程)

最后

小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。

[外链图片转存中…(img-GNYfv5yl-1719052615500)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

资料⬅专栏获取

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

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

相关文章

跟TED演讲学英文:How language shapes the way we think by Lera Boroditsky

How language shapes the way we think Link: https://www.ted.com/talks/lera_boroditsky_how_language_shapes_the_way_we_think? Speaker: Lera Boroditsky Date: November 2017 文章目录 How language shapes the way we thinkIntroductionVocabularySummaryTranscriptA…

【完全复现】基于改进粒子群算法的微电网多目标优化调度(含matlab代码)

目录 主要内容 部分代码 结果一览 下载链接 主要内容 程序完全复现文献模型《基于改进粒子群算法的微电网多目标优化调度》&#xff0c;以微电网系统运行成本和环境保护成本为目标函数&#xff0c;建立了并网方式下的微网多目标优化调度模型&#xff0c;通过改进…

数组和链表的区别是什么?

引言&#xff1a;本文旨在深入探讨数组和链表之间的区别&#xff0c;分析它们在不同情境下的优缺点&#xff0c;并探讨如何根据应用需求选择合适的数据结构。通过深入理解数组和链表的内部工作原理和应用场景&#xff0c;读者将能够更好地应用这些知识解决实际问题&#xff0c;…

【Gradio】从 BigQuery 数据创建实时仪表板

Google BigQuery 是一个基于云的服务&#xff0c;用于处理非常大的数据集。它是一个无服务器且高度可扩展的数据仓库解决方案&#xff0c;使用户能够使用类 SQL 查询分析数据。 在本教程中&#xff0c;我们将向您展示如何在 Python 中查询 BigQuery 数据集&#xff0c;并使用 g…

【论文阅读】-- 评估叠加时间序列和时间事件序列可视化中的对齐方法

中文标题 摘要1 引言2 相关工作2.1 时间事件序列可视化2.2 理解时间事件序列的任务 3个假设4 对比评价4.1 刺激和任务4.2 程序4.3 参与者4.4 测量与分析 5 结果与讨论5.1 前兆和后果事件5.2 中间事件 6 反思和设计意义7 结论致谢参考文献 期刊: IEEE VIS &#xff08;发表日期:…

2024年【T电梯修理】免费试题及T电梯修理考试总结

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 T电梯修理免费试题参考答案及T电梯修理考试试题解析是安全生产模拟考试一点通题库老师及T电梯修理操作证已考过的学员汇总&#xff0c;相对有效帮助T电梯修理考试总结学员顺利通过考试。 1、【多选题】TSGT7005-2012《…

企业该如何防查盗版?如何防软件后台泄密数据?

随着信息化的发展&#xff0c;企业日常办公越来越依赖互联网。终端以及普通PC终端在访问互联网过程中&#xff0c;会遇到各种各样不容忽视的风险&#xff0c;例如员工主动故意的数据泄漏&#xff0c;后台应用程序偷偷向外部发信息&#xff0c;木马间谍软件的外联&#xff0c;以…

Android图片圆角转换 RoundedImageView开源项目 小记(1)

android:background“#7f000000” android:paddingLeft“8dp” android:paddingRight“8dp” android:textAppearance“?android:attr/textAppearanceMediumInverse” /> <TextView android:id“id/textView1” android:layout_width“wrap_content” android:la…

c++ 内存分析模型、引用

一、内存模型分区 内存四区的意义&#xff1a; 不同区域存放的数据&#xff0c;赋予不同的生命周期&#xff0c;给我们更大的灵活编程 &#xff08;一&#xff09;程序运行前 在程序编译后&#xff0c;生成了exe可执行程序&#xff0c;未执行程序前分为两个区域 代码区&…

Linux常用命令(14)—查看文件内容(有相关截图)

写在前面&#xff1a; 最近在学习Linux命令&#xff0c;记录一下学习Linux常用命令的过程&#xff0c;方便以后复习。仅供参考&#xff0c;若有不当的地方&#xff0c;恳请指正。如果对你有帮助&#xff0c;欢迎点赞&#xff0c;关注&#xff0c;收藏&#xff0c;评论&#xf…

基于Java技术的摄影跟拍预定管理系统

你好&#xff0c;我是热衷于计算机科学与技术研究的码农小野。如果你对摄影跟拍预定管理系统感兴趣或有相关开发需求&#xff0c;欢迎私信交流。 开发语言 Java 数据库 MySQL 技术 B/S模式&#xff0c;SpringBoot 工具 Eclipse&#xff0c;Navicat&#xff0c;Tomcat …

Nuxt3 [Vue warn]: Hydration node mismatch:【解决方案】

[Vue warn]: Hydration node mismatch: 水合节点不匹配 Server rendered element contains more child nodes than client vdom. 服务器呈现的元素包含的子节点多于客户端vdom。 这个问题解决起来也很好解决&#xff0c;看这个问题是怎么出来的&#xff0c;看代码&#xff1a;…

Unity 天空盒制作使用教程

文章目录 1.概念2.制作天空盒3.使用天空盒3.1 为场景添加3.2 为相机添加 1.概念 天空盒是包裹整个场景的环境效果。 2.制作天空盒 1、创建材质球。 2、设置材质球Shader为SkyBox/6 Sided&#xff0c;将六张贴图放到对应位置。 3.使用天空盒 3.1 为场景添加 方法一、直接…

Vue3 - 在项目中使用vue-i18n不生效的问题

检查和配置 Vue I18n 确保你已经正确安装了Vue I18n并且配置了组合API模式。 安装 Vue I18n npm install vue-i18nnext配置 i18n.js import { createI18n } from vue-i18n; import messages from ./messages;const i18n createI18n({legacy: false, // 使用组合 API 模式l…

【Mysql】DQL操作单表、创建数据库、排序、聚合函数、分组、limit关键字

DQL操作单表 1.1 创建数据库 •创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8;•将db1数据库中的 emp表 复制到当前 db2数据库 ** 1.2 排序** 通过 ORDER BY 子句,可以将查询出的结果进行排序 (排序只是显示效果,不会影响真实数据) 语法结构&#xff1a;…

计算机系统基础实训八—ProxyLab实验

实验目的与要求 1、让学生应用套接字接口实现网络编程&#xff1b; 2、让学生理解Web服务器开发的相关知识&#xff1b; 3、让学生应用并发编程技术进行并发服务器的开发&#xff1b; 实验原理与内容 Web代理是一种在Web浏览器和终端服务器之间充当中介角色的程序。在Web代…

可灵王炸更新,图生视频、视频续写,最长可达3分钟!Runway 不香了 ...

现在视频大模型有多卷&#xff1f; Runway 刚在6月17号 发布Gen3 &#xff0c;坐上王座没几天&#xff1b; 可灵就在6月21日中午&#xff0c;重新夺回了王座&#xff01;发布了图生视频功能&#xff0c;视频续写功能&#xff01; 一张图概括&#xff1a; 二师兄和团队老师第一…

链表中环的入口节点

链表中环的入口节点 描述 链表中环的入口节点 给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。 数据范围&#xff1a; n≤10000&#xff0c; 1<结点值<10000 要求&#xff1a;空间复杂度 O(1)…

剪画音频提取:周杰伦音乐自由听,谁还付费听歌呀!

​作为周杰伦的狂热粉丝&#xff0c;你是否常常为各大音乐软件的会员限制而感到烦恼&#xff1f;每当想听一首心仪的周杰伦歌曲&#xff0c;却被“会员专享”这几个字挡住去路&#xff0c;实在是令人扫兴。但是别担心&#xff0c;今天我将为你揭示一个神奇的方法——把视频提取…

嵌入式通信协议----Wi-Fi协议详解(二)(基于STM32+有人物联网WIFI模块)

四、有人WIFI模块 1.模块介绍 Wi-Fi 模块用于实现串口到 Wi-Fi 数据包的双向透明转发&#xff0c;模块内部完成协议转换&#xff0c;通 过该模块&#xff0c;客户可以将物理设备连接到 Wi-Fi 网络上&#xff0c;从而实现物联网的控制与管理。 2.模块参数 Wi-Fi 模块的…