主頁 >  其他 > [FFmpeg萬能音頻播放器]解碼音頻資料(三)

[FFmpeg萬能音頻播放器]解碼音頻資料(三)

2020-10-21 11:41:32 其他

注意本文代碼是在https://blog.csdn.net/we1less/article/details/109096144的基礎上寫的,

mainxml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="run"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="開始"
        android:onClick="begin"/>
</LinearLayout>

mainactivity

package com.example.godvmusic;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;

import com.example.myplayer.Demo;
import com.example.myplayer.listener.GonPreparedListener;
import com.example.myplayer.log.GLog;
import com.example.myplayer.player.GPlayer;

public class MainActivity extends AppCompatActivity {

    private Demo mDemo;
    private GPlayer mGPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDemo = new Demo();
        mGPlayer = new GPlayer();
        mGPlayer.setmGonPreparedListener(new GonPreparedListener() {
            @Override
            public void onPrepared() {
                GLog.d("準備成功");
                mGPlayer.play();
            }
        });
    }

    public void run(View view) {
        mDemo.showDetial();
    }

    public void begin(View view) {
        GLog.d("開始準備");
        mGPlayer.setSource("http://sc1.111ttt.cn/2017/1/05/09/298092035545.mp3");
        mGPlayer.prepared();
    }
}

開兩條權限

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

interface GonPreparedListener

package com.example.myplayer.listener;

public interface GonPreparedListener {
    //回呼方法
    void onPrepared();
}

GLog.java log類

package com.example.myplayer.log;

import android.util.Log;

public class GLog {
    public static void d(String msg) {
        Log.d("godv", msg);
    }
}

GPlayer.java 準備/播放類

package com.example.myplayer.player;

import android.text.TextUtils;

import com.example.myplayer.listener.GonPreparedListener;
import com.example.myplayer.log.GLog;

public class GPlayer {
    static {
        System.loadLibrary("native-lib");
        System.loadLibrary("avutil");
        System.loadLibrary("swresample");
        System.loadLibrary("avcodec");
        System.loadLibrary("avformat");
        System.loadLibrary("swscale");
        System.loadLibrary("postproc");
        System.loadLibrary("avfilter");
        System.loadLibrary("avdevice");
    }

    private String source;

    private GonPreparedListener mGonPreparedListener;

    public void setmGonPreparedListener(GonPreparedListener mGonPreparedListener) {
        this.mGonPreparedListener = mGonPreparedListener;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public GPlayer() {
    }

    public void prepared() {
        if (TextUtils.isEmpty(source)) {
            GLog.d("source not be empty");
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                GLog.d("Thread start");
                //呼叫執行方法
                n_prepared(source);

            }
        }).start();
    }

    //回呼方法 c->java
    public void onCallPrepared() {
        if (mGonPreparedListener != null) {
            mGonPreparedListener.onPrepared();
        }
    }

    public void play() {
        if (TextUtils.isEmpty(source)) {
            GLog.d("source not be empty");
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                GLog.d("Thread start");
                //呼叫執行方法
                n_start();
            }
        }).start();
    }

    //呼叫執行方法java->c
    public native void n_prepared(String source);

    public native void n_start();
}

native-lib.cpp *****之下的是本篇新加的

#include <jni.h>
#include <string>
#include "GLog.h"

extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myplayer_Demo_stringFromJNI(JNIEnv *env, jobject thiz) {
    std::string hello = "Hello godv";

    return env->NewStringUTF(hello.c_str());
}

extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_myplayer_Demo_showDetial(JNIEnv *env, jobject thiz) {
    av_register_all();
    AVCodec *c_temp = av_codec_next(NULL);
    while (c_temp != NULL) {
        switch (c_temp->type) {
            case AVMEDIA_TYPE_VIDEO:
                LOGD("[Video]:%s", c_temp->name);
                break;
            case AVMEDIA_TYPE_AUDIO:
                LOGD("[Audio]:%s", c_temp->name);
                break;
            default:
                LOGD("[Other]:%s", c_temp->name);
                break;
        }
        c_temp = c_temp->next;
    }
    std::string hello = "Hello godv";
    return env->NewStringUTF(hello.c_str());
}

/******************************************************************************************/
#include "GCallJava.h"
#include "GFFmpeg.h"

//宣告指標
GCallJava *callJava = NULL;
GFFmpeg *gFFmpeg = NULL;
JavaVM *javaVm = NULL;

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myplayer_player_GPlayer_n_1prepared(JNIEnv *env, jobject thiz, jstring source_) {
    if (LOG_DEBUG) {
        LOGD("c++ Java_com_example_myplayer_player_GPlayer_n_1prepared");
    }
    //將jstring 轉成const char *
    const char *source = env->GetStringUTFChars(source_, 0);
    if (callJava == NULL) {
        callJava = new GCallJava(javaVm, env, thiz);
    }
    if (gFFmpeg == NULL) {
        gFFmpeg = new GFFmpeg(callJava, source);
        if (LOG_DEBUG) {
            LOGD("c++ gFFmpeg->prepared()");
        }
    }
    gFFmpeg->prepared();
    //釋放記憶體
    //env->ReleaseStringUTFChars(source_, source);
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *unused) {
    JNIEnv *env;
    javaVm = vm;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    return JNI_VERSION_1_4;
}

extern "C"
JNIEXPORT void JNICALL
Java_com_example_myplayer_player_GPlayer_n_1start(JNIEnv *env, jobject thiz) {
    if (gFFmpeg != NULL) {
        gFFmpeg->start();
    }
}

GLog.h

#include "android/log.h"

#ifndef GODVMUSIC_GLOG_H
#define GODVMUSIC_GLOG_H

#endif //GODVMUSIC_GLOG_H

#define LOG_TAG "godv"

#define LOG_DEBUG true

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)

#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

GCallJava.h

#ifndef GODVMUSIC_GCALLJAVA_H
#define GODVMUSIC_GCALLJAVA_H

#include <jni.h>
#include "GLog.h"

#define MAIN_THREAD 0
#define CHILD_THREAD 1

//全域呼叫java類中的方法
class GCallJava {

public:
    _JavaVM *javaVm = NULL;
    JNIEnv *jniEnv = NULL;
    jobject jobj;

    //回呼方法 c->java
    jmethodID jmid_onCallPrepared;

public:
    //構造器
    GCallJava(_JavaVM *jvm, JNIEnv *env, jobject obj);

    ~GCallJava();

    void onCallPrepare(int type);

};


#endif //GODVMUSIC_GCALLJAVA_H

GCallJava.cpp

#include "GCallJava.h"

GCallJava::GCallJava(_JavaVM *jvm, JNIEnv *env, jobject obj) {
    this->javaVm = jvm;
    this->jniEnv = env;
    //獲取全域的obj
    this->jobj = jniEnv->NewGlobalRef(obj);
    //根據全域obj獲取jclass
    jclass clz = jniEnv->GetObjectClass(jobj);
    if (!clz) {
        if (LOG_DEBUG) {
            LOGD("get jclass error");
        }
        return;
    }
    //通過class java方法名 方法簽名回傳jmethodID
    jmid_onCallPrepared = env->GetMethodID(clz, "onCallPrepared", "()V");
}

GCallJava::~GCallJava() {

}

void GCallJava::onCallPrepare(int type) {
    switch (type) {
        case MAIN_THREAD:
            //根據jobj 和methodid 呼叫java中方法
            jniEnv->CallVoidMethod(jobj, jmid_onCallPrepared);
            break;
        case CHILD_THREAD:
            //子執行緒需要獲取全域的jnienv
            JNIEnv *jniEnv;
            if (javaVm->AttachCurrentThread(&jniEnv, 0) != JNI_OK) {
                if (LOG_DEBUG) {
                    LOGD("get child thread jnienv error");
                }
            }
            if (LOG_DEBUG) {
                LOGD("child thread CallVoidMethod jmid_onCallPrepared");
            }
            jniEnv->CallVoidMethod(jobj, jmid_onCallPrepared);
            //當當前執行緒關閉
            javaVm->DetachCurrentThread();
            break;
    }

};

GFFmpeg.h

#ifndef GODVMUSIC_GFFMPEG_H
#define GODVMUSIC_GFFMPEG_H

#include "GCallJava.h"
#include "pthread.h"
#include "GAudio.h"

extern "C" {
#include <libavformat/avformat.h>
};


class GFFmpeg {
public:
    GCallJava *callJava = NULL;

    const char *url = NULL;

    pthread_t decodeThread;

    AVFormatContext *gFormatctx = NULL;

    GAudio *gAudio = NULL;

public:
    GFFmpeg(GCallJava *callJava, const char *url);

    ~GFFmpeg();

    //準備方法
    void prepared();

    //解碼執行緒
    void decodeFFmpegThread();

    //播放方法
    void start();
};


#endif //GODVMUSIC_GFFMPEG_H

GFFmpeg.cpp

#include "GFFmpeg.h"

GFFmpeg::GFFmpeg(GCallJava *callJava, const char *url) {
    this->callJava = callJava;
    this->url = url;
}

//回呼方法
void *decodeCallBack(void *data) {
    GFFmpeg *gfFmpeg = (GFFmpeg *) data;
    if (LOG_DEBUG) {
        LOGD("c++ gFFmpeg->decodeCallBack()");
    }
    gfFmpeg->decodeFFmpegThread();
    pthread_exit(&gfFmpeg->decodeThread);
}

void GFFmpeg::prepared() {
    pthread_create(&decodeThread, NULL, decodeCallBack, this);
}

void GFFmpeg::decodeFFmpegThread() {
    av_register_all();
    avformat_network_init();
    gFormatctx = avformat_alloc_context();
    if (avformat_open_input(&gFormatctx, url, NULL, NULL) != 0) {
        if (LOG_DEBUG) {
            LOGD("can not open url %s", url);
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("open url %s", url);
    }
    //獲取流
    if (avformat_find_stream_info(gFormatctx, NULL) < 0) {
        if (LOG_DEBUG) {
            LOGD("can not find stream");
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("open url stream");
    }
    //找AVMEDIA_TYPE_AUDIO流
    for (int i = 0; i < gFormatctx->nb_streams; i++) {
        if (gFormatctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            if (gAudio == NULL) {
                gAudio = new GAudio();
                gAudio->streamIndex = i;
                gAudio->codecpar = gFormatctx->streams[i]->codecpar;
            }
        }
    }
    if (LOG_DEBUG) {
        LOGD("already find stream");
    }
    //得到解碼器
    AVCodec *avCodec = avcodec_find_decoder(gAudio->codecpar->codec_id);
    if (!avCodec) {
        if (LOG_DEBUG) {
            LOGD("can not find codec");
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("already find codec");
    }
    //獲得解碼器背景關系
    gAudio->avCodecContext = avcodec_alloc_context3(avCodec);
    if (!gAudio->avCodecContext) {
        if (LOG_DEBUG) {
            LOGD("can not alloc avCodecContext");
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("already alloc avCodecContext");
    }
    //把屬性賦值到解碼器背景關系中
    if (avcodec_parameters_to_context(gAudio->avCodecContext, gAudio->codecpar) < 0) {
        if (LOG_DEBUG) {
            LOGD("can not parameters to avCodecContext");
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("already parameters to avCodecContext");
    }
    //打開解碼器
    if (avcodec_open2(gAudio->avCodecContext, avCodec, 0) != 0) {
        if (LOG_DEBUG) {
            LOGD("can not open audio");
        }
        return;
    }
    if (LOG_DEBUG) {
        LOGD("already onCallPrepare ...");
    }
    callJava->onCallPrepare(1);
}

void GFFmpeg::start() {
    if (gAudio == NULL) {
        if (LOG_DEBUG) {
            LOGE("gAudio is null");
        }
        return;
    }
    int count = 0;
    while (1) {
        AVPacket *avPacket = av_packet_alloc();
        if (av_read_frame(gFormatctx, avPacket) == 0) {
            if (avPacket->stream_index == gAudio->streamIndex) {
                count++;
                if (LOG_DEBUG) {
                    LOGE("解碼第%d幀", count);
                }
                av_packet_free(&avPacket);
                av_free(avPacket);
                avPacket = NULL;
            } else {
                av_packet_free(&avPacket);
                av_free(avPacket);
                avPacket = NULL;
            }
        } else {
            av_packet_free(&avPacket);
            av_free(avPacket);
            avPacket = NULL;
            break;
        }
    }
}

GAudio.h

#ifndef GODVMUSIC_GAUDIO_H
#define GODVMUSIC_GAUDIO_H

extern "C" {
#include "include/libavcodec/avcodec.h"
};

class GAudio {
public:
    int streamIndex = -1;

    AVCodecParameters *codecpar;

    AVCodecContext *avCodecContext = NULL;
public:
    GAudio();

    ~GAudio();
};


#endif //GODVMUSIC_GAUDIO_H

GAudio.cpp

#include "GAudio.h"

GAudio::GAudio() {
}

GAudio::~GAudio() {
}

CMakeLists.txt 注意要把檔案加進來

add_library(
             native-lib
             SHARED
             ${CMAKE_SOURCE_DIR}/src/main/cpp/native-lib.cpp
             ${CMAKE_SOURCE_DIR}/src/main/cpp/GCallJava.cpp
             ${CMAKE_SOURCE_DIR}/src/main/cpp/GFFmpeg.cpp
             ${CMAKE_SOURCE_DIR}/src/main/cpp/GAudio.cpp)

下面附上工程結構圖

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/183684.html

標籤:其他

上一篇:MySQL資料庫基礎——資料庫創建、查看、修改、洗掉

下一篇:更為常用的網路檔案模型:多路復用,再也不用創建一個執行緒去監聽!!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more