国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制

這篇具有很好參考價(jià)值的文章主要介紹了十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. 前言

因?yàn)楣ぷ髦幸褂?code>Android Camera2 API,但因?yàn)?code>Camera2比較復(fù)雜,網(wǎng)上資料也比較亂,有一定入門門檻,所以花了幾天時(shí)間系統(tǒng)研究了下,并在CSDN上記錄了下,希望能幫助到更多的小伙伴。
上兩篇文章使用Camera2實(shí)現(xiàn)了相機(jī)預(yù)覽和拍照的功能,這篇文章我們接著上文,來實(shí)現(xiàn)Camera2視頻錄制的功能。

2. 前置操作

2.1 聲明相機(jī)參數(shù)和成員變量

首先還是聲明相機(jī)參數(shù)和成員變量,比起前文增加了這些

private var mediaRecorder: MediaRecorder? = null
private var isRecordingVideo: Boolean = false
private val SENSOR_ORIENTATION_DEFAULT_DEGREES = 90
private val SENSOR_ORIENTATION_INVERSE_DEGREES = 270
private val DEFAULT_ORIENTATIONS = SparseIntArray().apply {
    append(Surface.ROTATION_0, 90)
    append(Surface.ROTATION_90, 0)
    append(Surface.ROTATION_180, 270)
    append(Surface.ROTATION_270, 180)
}
private val INVERSE_ORIENTATIONS = SparseIntArray().apply {
    append(Surface.ROTATION_0, 270)
    append(Surface.ROTATION_90, 180)
    append(Surface.ROTATION_180, 90)
    append(Surface.ROTATION_270, 0)
}

完整的需要聲明的相機(jī)參數(shù)和成員變量如下

//后攝 : 0 ,前攝 : 1
private val cameraId = "0"
private val TAG = CameraActivity3::class.java.simpleName
private lateinit var cameraDevice: CameraDevice
private val cameraThread = HandlerThread("CameraThread").apply { start() }
private val cameraHandler = Handler(cameraThread.looper)
private val cameraManager: CameraManager by lazy {
    getSystemService(Context.CAMERA_SERVICE) as CameraManager
}
private val characteristics: CameraCharacteristics by lazy {
    cameraManager.getCameraCharacteristics(cameraId)
}
private lateinit var session: CameraCaptureSession

private lateinit var imageReader: ImageReader

//JPEG格式,所有相機(jī)必須支持JPEG輸出,因此不需要檢查
private val pixelFormat = ImageFormat.JPEG

//imageReader最大的圖片緩存數(shù)
private val IMAGE_BUFFER_SIZE: Int = 3

//線程池
private val threadPool = Executors.newCachedThreadPool()
private val imageReaderThread = HandlerThread("imageReaderThread").apply { start() }
private val imageReaderHandler = Handler(imageReaderThread.looper)
/** Live data listener for changes in the device orientation relative to the camera */
private lateinit var relativeOrientation: OrientationLiveData

private var mediaRecorder: MediaRecorder? = null
private var isRecordingVideo: Boolean = false
private val SENSOR_ORIENTATION_DEFAULT_DEGREES = 90
private val SENSOR_ORIENTATION_INVERSE_DEGREES = 270
private val DEFAULT_ORIENTATIONS = SparseIntArray().apply {
    append(Surface.ROTATION_0, 90)
    append(Surface.ROTATION_90, 0)
    append(Surface.ROTATION_180, 270)
    append(Surface.ROTATION_270, 180)
}
private val INVERSE_ORIENTATIONS = SparseIntArray().apply {
    append(Surface.ROTATION_0, 270)
    append(Surface.ROTATION_90, 180)
    append(Surface.ROTATION_180, 90)
    append(Surface.ROTATION_270, 0)
}

2.2 添加布局

首先我們需要在XML中添加兩個(gè)按鈕,分別是錄制按鈕和停止錄制按鈕

<Button
    android:id="@+id/btn_capture_video"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"
    android:layout_marginRight="16dp"
    android:text="錄屏"
    android:visibility="visible"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent" />

<Button
    android:id="@+id/btn_stop_capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|left"
    android:text="停止錄屏"
    android:visibility="visible"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent" />

2.3 初始化MediaPlayer

我們需要在打開相機(jī)的時(shí)候,去初始化mediaRecorder

mediaRecorder = MediaRecorder()

完整代碼如下

@SuppressLint("MissingPermission")
private fun openCamera(cameraId: String) {
    cameraManager.openCamera(cameraId, object : CameraDevice.StateCallback() {
        override fun onOpened(camera: CameraDevice) {
            cameraDevice = camera
            mediaRecorder = MediaRecorder()
            startPreview()
        }

        override fun onDisconnected(camera: CameraDevice) {
            this@CameraActivity3.finish()
        }

        override fun onError(camera: CameraDevice, error: Int) {
            Toast.makeText(application, "openCamera Failed:$error", Toast.LENGTH_SHORT).show()
        }
    }, cameraHandler)
}

3. 實(shí)現(xiàn)視頻錄制功能

3.1 關(guān)閉原本的Session

因?yàn)榕恼蘸弯浿埔曨l功能不好一起使用,所以需要先調(diào)用closePreviewSession,來關(guān)閉原來的session

private fun closePreviewSession() {
    session?.close()
}

3.2 給MediaRecorder設(shè)置參數(shù)

接著,需要調(diào)用setUpMediaRecorder()來初始化MediaRecorder
setUpMediaRecorder中,會(huì)給mediaRecorder設(shè)置很多預(yù)置參數(shù)

首先獲取目標(biāo)路徑

 val nextVideoAbsolutePath = getVideoFilePath(cameraActivity)
 
fun getVideoFilePath(context: Context?): String {
    val filename = "VIDEO_${System.currentTimeMillis()}.mp4"
    val dir = context?.getExternalFilesDir("video")

    return if (dir == null) {
        filename
    } else {
        "${dir.absolutePath}/$filename"
    }
}

然后設(shè)置mediaRecorder方向

val sensorOrientation = characteristics?.get(SENSOR_ORIENTATION)
val rotation = cameraActivity.windowManager.defaultDisplay.rotation
when (sensorOrientation) {
    SENSOR_ORIENTATION_DEFAULT_DEGREES ->
        mediaRecorder?.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation))
    SENSOR_ORIENTATION_INVERSE_DEGREES ->
        mediaRecorder?.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation))
}

最后給meidaRecorder設(shè)置若干參數(shù)項(xiàng),這里我們默認(rèn)給視頻尺寸設(shè)置成了1920*1080,如果你的設(shè)備相機(jī)不支持這個(gè)分辨率,需要修改一下。

mediaRecorder?.apply {
    setAudioSource(MediaRecorder.AudioSource.MIC)
    setVideoSource(MediaRecorder.VideoSource.SURFACE)
    setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    setOutputFile(nextVideoAbsolutePath)
    setVideoEncodingBitRate(10000000)
    setVideoFrameRate(30)
    setVideoSize(1920,1080)
    setVideoEncoder(MediaRecorder.VideoEncoder.H264)
    setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    prepare()
}

再來看下完整的代碼

private fun setUpMediaRecorder() {
    val cameraActivity = this

    val nextVideoAbsolutePath = getVideoFilePath(cameraActivity)

    val sensorOrientation = characteristics?.get(SENSOR_ORIENTATION)
    val rotation = cameraActivity.windowManager.defaultDisplay.rotation
    when (sensorOrientation) {
        SENSOR_ORIENTATION_DEFAULT_DEGREES ->
            mediaRecorder?.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation))
        SENSOR_ORIENTATION_INVERSE_DEGREES ->
            mediaRecorder?.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation))
    }

    mediaRecorder?.apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setVideoSource(MediaRecorder.VideoSource.SURFACE)
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setOutputFile(nextVideoAbsolutePath)
        setVideoEncodingBitRate(10000000)
        setVideoFrameRate(30)
        setVideoSize(1920,1080) //FIXME 如果你的設(shè)備相機(jī)不支持這個(gè)分辨率,需要修改一下
        setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        prepare()
    }
}

fun getVideoFilePath(context: Context?): String {
    val filename = "VIDEO_${System.currentTimeMillis()}.mp4"
    val dir = context?.getExternalFilesDir("video")

    return if (dir == null) {
        filename
    } else {
        "${dir.absolutePath}/$filename"
    }
}

3.3 重新創(chuàng)建Session

接著就將binding.surfaceViewrecorderSurface添加到surfaces

val recorderSurface = mediaRecorder!!.surface
val surfaces = ArrayList<Surface>().apply {
    add(binding.surfaceView.holder.surface)
    add(recorderSurface)
}

重新調(diào)用cameraDevice?.createCaptureSession,將surfaces傳入

cameraDevice?.createCaptureSession(surfaces,
    object : CameraCaptureSession.StateCallback() {

        override fun onConfigured(cameraCaptureSession: CameraCaptureSession) {
            //待實(shí)現(xiàn)
        }

        override fun onConfigureFailed(cameraCaptureSession: CameraCaptureSession) {
            Toast.makeText(application, "onConfigureFailed", Toast.LENGTH_SHORT).show()
        }
    }, cameraHandler)

3.4 開始錄制

當(dāng)onConfigured調(diào)用后,我們執(zhí)行下面這些代碼,主要執(zhí)行了這些操作

  • cameraCaptureSession賦值給session
  • session?.setRepeatingRequest,這將不斷地實(shí)時(shí)發(fā)送視頻流,直到會(huì)話斷開或調(diào)用session.stoprepeat()
  • 調(diào)用mediaRecorder?.start錄制視頻
session = cameraCaptureSession

val previewRequestBuilder = cameraDevice!!.createCaptureRequest(TEMPLATE_RECORD).apply {
    addTarget(binding.surfaceView.holder.surface)
    addTarget(recorderSurface)
}
session?.setRepeatingRequest(previewRequestBuilder!!.build(), null, cameraHandler)

isRecordingVideo = true
mediaRecorder?.start()

3.5 錄制視頻完整代碼

binding.btnCaptureVideo.setOnClickListener {
    startRecordingVideo()
}

private fun startRecordingVideo() {
closePreviewSession()
setUpMediaRecorder()

val recorderSurface = mediaRecorder!!.surface
val surfaces = ArrayList<Surface>().apply {
    add(binding.surfaceView.holder.surface)
    add(recorderSurface)
}

cameraDevice?.createCaptureSession(
	    surfaces,
	    object : CameraCaptureSession.StateCallback() {
	
	        override fun onConfigured(cameraCaptureSession: CameraCaptureSession) {
	            session = cameraCaptureSession
	
	            val previewRequestBuilder =
	                cameraDevice!!.createCaptureRequest(TEMPLATE_RECORD).apply {
	                    addTarget(binding.surfaceView.holder.surface)
	                    addTarget(recorderSurface)
	                }
	            session?.setRepeatingRequest(
	                previewRequestBuilder!!.build(),
	                null,
	                cameraHandler
	            )
	
	            isRecordingVideo = true
	            mediaRecorder?.start()
	        }
	
	        override fun onConfigureFailed(cameraCaptureSession: CameraCaptureSession) {
	            Toast.makeText(application, "onConfigureFailed", Toast.LENGTH_SHORT).show()
	        }
	    }, cameraHandler
	)
}

private fun closePreviewSession() {
    session?.close()
}

private fun setUpMediaRecorder() {
    val cameraActivity = this

    val nextVideoAbsolutePath = getVideoFilePath(cameraActivity)

    val sensorOrientation = characteristics?.get(SENSOR_ORIENTATION)
    val rotation = cameraActivity.windowManager.defaultDisplay.rotation
    when (sensorOrientation) {
        SENSOR_ORIENTATION_DEFAULT_DEGREES ->
            mediaRecorder?.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation))

        SENSOR_ORIENTATION_INVERSE_DEGREES ->
            mediaRecorder?.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation))
    }

    mediaRecorder?.apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setVideoSource(MediaRecorder.VideoSource.SURFACE)
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setOutputFile(nextVideoAbsolutePath)
        setVideoEncodingBitRate(10000000)
        setVideoFrameRate(30)
        setVideoSize(1920, 1080) //FIXME 如果你的設(shè)備相機(jī)不支持這個(gè)分辨率,需要修改一下
        setVideoEncoder(MediaRecorder.VideoEncoder.H264)
        setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
        prepare()
    }
}

十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制

我們運(yùn)行程序,點(diǎn)擊錄制視頻,過幾秒點(diǎn)擊停止錄制,然后打開文件管理器,在/sdcard/Android/data/包名/files/video文件夾下,可以看到這個(gè)視頻了

十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制

4. 停止錄制視頻

停止錄制視頻比較簡單,只需要釋放mediaRecorder
然后再調(diào)用startPreview重新開始預(yù)覽就可以了

private fun stopRecordingVideo() {
    isRecordingVideo = false
    mediaRecorder?.apply {
        stop()
        reset()
    }
    //重新開始預(yù)覽
    startPreview()
}

5. 實(shí)現(xiàn)動(dòng)態(tài)設(shè)置分辨率

之前我們這是錄制分辨率是寫死的1920*1080,這樣是不夠動(dòng)態(tài)靈活的,接下來我們來實(shí)現(xiàn)下動(dòng)態(tài)設(shè)置分辨率

首先通過characteristics獲取到可用的分辨率列表

val characteristics = manager.getCameraCharacteristics(cameraId)
val map = characteristics.get(SCALER_STREAM_CONFIGURATION_MAP) ?:
        throw RuntimeException("Cannot get available preview/video sizes")

然后通過這個(gè)map來選擇出最適合的分辨率,這里的選擇規(guī)則是返回寬高比3:4的分辨率中最高的分辨率

 videoSize = chooseVideoSize(map.getOutputSizes(MediaRecorder::class.java))
 
fun chooseVideoSize(choices: Array<Size>) = choices.firstOrNull {
        it.width == it.height * 4 / 3 } ?: choices[choices.size - 1]

最后,將該分辨率設(shè)置到mediaRecorder中就行了

mediaRecorder?.apply {
    setAudioSource(MediaRecorder.AudioSource.MIC)
    setVideoSource(MediaRecorder.VideoSource.SURFACE)
    setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
    setOutputFile(nextVideoAbsolutePath)
    setVideoEncodingBitRate(10000000)
    setVideoFrameRate(30)
    //setVideoSize(1920, 1080)
    setVideoSize(videoSize.width,videoSize.height)
    setVideoEncoder(MediaRecorder.VideoEncoder.H264)
    setAudioEncoder(MediaRecorder.AudioEncoder.AAC)
    prepare()
}

6. 其他

6.1 本文源碼下載

下載地址 : Android Camera2 Demo - 實(shí)現(xiàn)相機(jī)預(yù)覽、拍照、錄制視頻功能

6.2 Android Camera2 系列

更多Camera2相關(guān)文章,請(qǐng)看
十分鐘實(shí)現(xiàn) Android Camera2 相機(jī)預(yù)覽_氦客的博客-CSDN博客
十分鐘實(shí)現(xiàn) Android Camera2 相機(jī)拍照_氦客的博客-CSDN博客
十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制_氦客的博客-CSDN博客

6.3 Android 相機(jī)相關(guān)文章

Android 使用CameraX實(shí)現(xiàn)預(yù)覽/拍照/錄制視頻/圖片分析/對(duì)焦/縮放/切換攝像頭等操作_氦客的博客-CSDN博客
Android 從零開發(fā)一個(gè)簡易的相機(jī)App_android開發(fā)簡易app_氦客的博客-CSDN博客
Android 使用Camera1實(shí)現(xiàn)相機(jī)預(yù)覽、拍照、錄像_android 相機(jī)預(yù)覽_氦客的博客-CSDN博客文章來源地址http://www.zghlxwxcb.cn/news/detail-509882.html

到了這里,關(guān)于十分鐘實(shí)現(xiàn) Android Camera2 視頻錄制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 還在苦惱如何開發(fā)一個(gè)Chrome插件嗎?十分鐘帶你實(shí)現(xiàn)一個(gè)實(shí)用小插件

    還在苦惱如何開發(fā)一個(gè)Chrome插件嗎?十分鐘帶你實(shí)現(xiàn)一個(gè)實(shí)用小插件

    你是否曾考慮過創(chuàng)建自己的 Chrome 插件,但又撓頭毫無思路?那么在接下來的幾分鐘里,我不僅會(huì)介紹 Chrome 瀏覽器擴(kuò)展的基本知識(shí),還會(huì)指導(dǎo)你通過五個(gè)簡單的步驟來制作自己的擴(kuò)展。 知道怎么做嗎?讓我們一探究竟! 今年我們見證了人工智能能力的爆炸式增長。雖然cha

    2024年02月10日
    瀏覽(91)
  • NDK Android平臺(tái)camera2采集視頻

    NDK Android平臺(tái)camera2采集視頻

    《Android平臺(tái)使用camera2采集視頻 代碼實(shí)現(xiàn) 》鏈接: https://edu.csdn.net/learn/38258/606148?spm=1003.2001.3001.4157 在Android平臺(tái)開發(fā)實(shí)時(shí)音視頻項(xiàng)目,攝像頭的采集是一個(gè)必不可少的流程;通常在Android平臺(tái)上采集攝像頭數(shù)據(jù)可以使用Camera1接口、Camera2接口或者CameraX接口。Camera1接口只支持

    2024年02月11日
    瀏覽(24)
  • 零編程經(jīng)驗(yàn),通過 GPT-4 十分鐘開發(fā)了一個(gè)瀏覽器插件,并成功運(yùn)行,實(shí)現(xiàn)了需求目標(biāo)!

    零編程經(jīng)驗(yàn),通過 GPT-4 十分鐘開發(fā)了一個(gè)瀏覽器插件,并成功運(yùn)行,實(shí)現(xiàn)了需求目標(biāo)!

    大佬藍(lán)鳥ID: sundyme 零編程經(jīng)驗(yàn),通過 GPT-4 十分鐘開發(fā)了一個(gè)瀏覽器插件,并成功運(yùn)行,實(shí)現(xiàn)了需求目標(biāo)!太不可思意了,真正體會(huì)到了自然語言編程的魅力! 下一步是利用Pinterest 的 API 接口實(shí)現(xiàn)自動(dòng)發(fā)圖,已經(jīng)生成好了代碼和步驟(看著挺靠譜),等明天開發(fā)者權(quán)限審核下

    2023年04月08日
    瀏覽(86)
  • 十分鐘入門Zigbee

    十分鐘入門Zigbee

    大部分教程通常都是已Zigbee原理開始講解和學(xué)習(xí),各種概念讓初學(xué)者難以理解。本教程從一個(gè)小白的角度出發(fā),入門無需任何Zigbee底層原理知識(shí),只需要基本的MCU研發(fā)經(jīng)驗(yàn)就可以掌握,讓您快速實(shí)現(xiàn)zigbee組網(wǎng)和節(jié)點(diǎn)之間通信。 本教程采用泰凌微TLSR8258芯片,芯片資料鏈接TLS

    2023年04月09日
    瀏覽(106)
  • 每天十分鐘學(xué)會(huì)Spark

    每天十分鐘學(xué)會(huì)Spark

    Spark是什么 Spark是一種基于內(nèi)存的快速、通用、可拓展的大數(shù)據(jù)分析計(jì)算引擎。 Spark官網(wǎng):http://spark.apache.org/ Spark的特點(diǎn) 1、快速 ??一般情況下,對(duì)于迭代次數(shù)較多的應(yīng)用程序,Spark程序在內(nèi)存中的運(yùn)行速度是Hadoop MapReduce運(yùn)行速度的100多倍,在磁盤上的運(yùn)行速度是Hadoop MapRedu

    2024年03月18日
    瀏覽(98)
  • 十分鐘掌握J(rèn)ava本地緩存

    —————————— Yesterday is history, tomorrow is a mystery, but today is a gift. That is why it’s called the present. —————————— 緩存是Java開發(fā)中經(jīng)常用到的組件,我們會(huì)使用緩存來存儲(chǔ)一些 不經(jīng)常改變 的 熱點(diǎn) 數(shù)據(jù),提高系統(tǒng)處理效率,其根本原因在于內(nèi)存和硬盤讀寫速度的

    2024年02月05日
    瀏覽(94)
  • 通俗易懂,十分鐘讀懂DES,詳解DES加密算法原理,DES攻擊手段以及3DES原理。Python DES實(shí)現(xiàn)源碼

    通俗易懂,十分鐘讀懂DES,詳解DES加密算法原理,DES攻擊手段以及3DES原理。Python DES實(shí)現(xiàn)源碼

    DES(Data Encryption Standard)是一種 對(duì)稱加密 算法。它是在20世紀(jì)70年代初期由IBM研發(fā)的。它的設(shè)計(jì)目標(biāo)是提供高度的數(shù)據(jù)安全性和性能,并且能夠在各種硬件和軟件平臺(tái)上實(shí)現(xiàn)。 DES使用56位的密鑰和64位的明文塊進(jìn)行加密。DES算法的分組大小是64位,因此,如果需要加密的明文長

    2024年02月03日
    瀏覽(28)
  • Django入門,十分鐘學(xué)會(huì)登錄網(wǎng)頁

    我們假定你已經(jīng)閱讀了?安裝 Django。你能知道 Django 已被安裝,且安裝的是哪個(gè)版本,通過在命令提示行輸入命令 cmd黑窗口運(yùn)行,不懂cmd百度一下 如果這是你第一次使用 Django 的話,你需要一些初始化設(shè)置。也就是說,你需要用一些自動(dòng)生成的代碼配置一個(gè) Django?project?——

    2024年01月24日
    瀏覽(104)
  • 十分鐘python入門 正則表達(dá)式

    正則常見的三種功能,它們分別是:校驗(yàn)數(shù)據(jù)的有效性、查找符合要求的文本以及對(duì)文本進(jìn)行切割和替換等操作。 所謂元字符就是指那些在正則表達(dá)式中具有特殊意義的專用字符 元字符大致分成這幾類:表示單個(gè)特殊字符的,表示空白符的,表示某個(gè)范圍的,表示次數(shù)的量

    2024年02月13日
    瀏覽(92)
  • 十分鐘理解回歸測(cè)試(Regression Testing)

    十分鐘理解回歸測(cè)試(Regression Testing)

    回歸測(cè)試是一個(gè)系統(tǒng)的質(zhì)量控制過程,用于驗(yàn)證最近對(duì)軟件的更改或更新是否無意中引入了新錯(cuò)誤或?qū)σ郧暗墓δ芊矫娈a(chǎn)生了負(fù)面影響(比如你在家中安裝了新的空調(diào)系統(tǒng),發(fā)現(xiàn)雖然新的空調(diào)系統(tǒng)可以按預(yù)期工作,但是本來亮的等卻不亮了)。其主要目標(biāo)是確保旨在改進(jìn)的修

    2024年02月05日
    瀏覽(92)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包