Android 录制音视频的完整代码

打开camera

private void openCamera(int position) {

if (mCamera == null) {

mCamera = Camera.open(position);

int degree = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 0 : 90;

mCamera.setDisplayOrientation(degree);

}

}

camera默认是横屏的,所以我们要使用竖屏录制要旋转90度

int degree = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 0 : 90;

mCamera.setDisplayOrientation(degree);

camera预览

我们要选择一个与我们要显示的SurfaceView大小比例最接近的一个camera预览大小,这里要特别注意camera支持的宽高都是宽大于高。

所以就有了下面这段选择代码

private Size getBestCameraResolution(Camera.Parameters parameters, Size screenResolution) {

float tmp = 0f;

float mindiff = 100f;

Log.e("yuanVideo", "screen width=" + screenResolution.getWidth() + " height=" + screenResolution.getHeight());

float width_d_height;

if (screenResolution.getWidth() > screenResolution.getHeight()) {

width_d_height = (float) screenResolution.getWidth() / (float) screenResolution.getHeight();

} else {

width_d_height = (float) screenResolution.getHeight() / (float) screenResolution.getWidth();

}

Log.e("yuanVideo", "width_d_height=" + width_d_height);

Camera.Size best = null;

List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();

for (Camera.Size s : supportedPreviewSizes) {

tmp = Math.abs(((float) s.width / (float) s.height) - width_d_height);

Log.e("yuanVideo", "support width=" + s.width + " height=" + s.height + " ratio=" + tmp);

if (tmp < mindiff) {

mindiff = tmp;

best = s;

}

}

Log.e("yuanVideo", "best width=" + best.width + " height=" + best.height);

return new Size(best.width, best.height);

}

初始化MediaRecorder

private boolean prepareMediaRecorder() {

// 创建MediaPlayer对象

mCamera.unlock();

mRecorder = new MediaRecorder();

mRecorder.reset();

mRecorder.setCamera(mCamera);

// 设置从麦克风采集声音(或来自录像机的声音AudioSource.CAMCORDER)

mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);

// 设置从摄像头采集图像

mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

Log.e("yuanProfile", "QUALITY_LOW=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW));

Log.e("yuanProfile", "QUALITY_HIGH=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH));

Log.e("yuanProfile", "QUALITY_QCIF=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF));

Log.e("yuanProfile", "QUALITY_480P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P));

Log.e("yuanProfile", "QUALITY_720P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P));

Log.e("yuanProfile", "QUALITY_1080P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P));

Log.e("yuanProfile", "QUALITY_QVGA=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA));

Log.e("yuanProfile", "QUALITY_2160P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P));

Log.e("yuanProfile", "QUALITY_VGA=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_VGA));

Log.e("yuanProfile", "QUALITY_4KDCI=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_4KDCI));

Log.e("yuanProfile", "QUALITY_QHD=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QHD));

Log.e("yuanProfile", "QUALITY_2K=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2K));

if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {

mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {

mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_1080P));

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {

mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW)) {

mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));

} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)) {

mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));

} else {

return false;

}

// mTempList.add(mCurrentTempRecordData);

mRecorder.setOutputFile(mCurPath);

mRecorder.setPreviewDisplay(activtityVideoRecordBinding.sView.getHolder().getSurface()); // ①

int degree;

if(getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){

int degree ;

if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {

degree = 270;

} else {

degree = 90;

}

mRecorder.setOrientationHint(degree);

}

try {

mRecorder.prepare();

} catch (Exception e) {

e.printStackTrace();

return false;

}

return true;

}

这里也要设置视频的旋转参数

if(getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){

int degree ;

if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {

degree = 270;

} else {

degree = 90;

}

mRecorder.setOrientationHint(degree);

}

下面是完整的代码

package com.yuanxuzhen.ffmpeg;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Size;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

import com.yuanxuzhen.ffmpeg.databinding.ActivtityVideoRecordBinding;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class VideoRecordActivity extends Activity {
    ActivtityVideoRecordBinding activtityVideoRecordBinding;
    MediaRecorder mRecorder;
    private boolean isRecording = false;

    private int cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;//0代表前置摄像头,1代表后置摄像头
    private Camera mCamera;
    private Camera.Parameters mParameters;
    private String mCurPath = null;
    private VideoTempRecordData mCurrentTempRecordData = null;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        mCurPath = DirUtil.getCacheDir(this) + File.separator + "out.mp4";
        activtityVideoRecordBinding = ActivtityVideoRecordBinding.inflate(getLayoutInflater());
        setContentView(activtityVideoRecordBinding.getRoot());
        activtityVideoRecordBinding.sView.getHolder().setKeepScreenOn(true);
        activtityVideoRecordBinding.sView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                openPreView();
            }

            @Override
            public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
                Log.e("yuanVideo", "surfaceChanged width=" + width + " height=" + height);
            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

            }
        });

        activtityVideoRecordBinding.recordOrStop.setText("开始");
        activtityVideoRecordBinding.recordOrStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isRecording) {
                    Log.d("TAG", "停止录像");
                    stopRecord();
                } else {
                    startRecord();
                }
            }
        });
        activtityVideoRecordBinding.change.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onClick(View v) {
                if(isRecording){
                    return;
                }
                releaseCamera();
                cameraPosition = cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT ? Camera.CameraInfo.CAMERA_FACING_BACK : Camera.CameraInfo.CAMERA_FACING_FRONT;
                openCamera(cameraPosition);
                openPreView();
            }
        });
    }

    /**
     * 1.打开相机
     */
    private void openCamera(int position) {
        if (mCamera == null) {
            mCamera = Camera.open(position);
            int degree = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 0 : 90;
            mCamera.setDisplayOrientation(degree);
        }
    }

    /**
     * initCameraAndSurfaceViewHolder初始化hoder后
     * 2.设置预览功能
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private void openPreView() {
        try {
            if (mCamera != null) {
                mParameters = mCamera.getParameters();
                mCamera.setPreviewDisplay(activtityVideoRecordBinding.sView.getHolder());
                Size screenPoint = getScreenMetrics(VideoRecordActivity.this);
                Size bestPreviewSize = getBestCameraResolution(mCamera.getParameters(), screenPoint);
                mParameters.setPreviewSize(bestPreviewSize.getWidth(), bestPreviewSize.getHeight());
                mCamera.setParameters(mParameters);
                mCamera.startPreview();
                mCamera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        Log.e("yuanVideo", "autoFocus success=" + success);

                    }
                });

                mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
                        Log.i("TAG", "获取预览帧...");
                        Log.d("TAG", "预览帧大小:" + String.valueOf(data.length));
                    }
                });

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean prepareMediaRecorder() {
        // 创建MediaPlayer对象
        mCamera.unlock();
        mRecorder = new MediaRecorder();
        mRecorder.reset();
        mRecorder.setCamera(mCamera);

        // 设置从麦克风采集声音(或来自录像机的声音AudioSource.CAMCORDER)
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        // 设置从摄像头采集图像
        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        Log.e("yuanProfile", "QUALITY_LOW=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW));
        Log.e("yuanProfile", "QUALITY_HIGH=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH));
        Log.e("yuanProfile", "QUALITY_QCIF=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QCIF));
        Log.e("yuanProfile", "QUALITY_480P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P));
        Log.e("yuanProfile", "QUALITY_720P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P));
        Log.e("yuanProfile", "QUALITY_1080P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P));
        Log.e("yuanProfile", "QUALITY_QVGA=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QVGA));
        Log.e("yuanProfile", "QUALITY_2160P=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P));
        Log.e("yuanProfile", "QUALITY_VGA=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_VGA));
        Log.e("yuanProfile", "QUALITY_4KDCI=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_4KDCI));
        Log.e("yuanProfile", "QUALITY_QHD=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_QHD));
        Log.e("yuanProfile", "QUALITY_2K=" + CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2K));

        if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {
            mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_720P));
        } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {
            mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_1080P));
        } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {
            mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
        } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW)) {
            mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
        } else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)) {
            mRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
        } else {
            return false;
        }
//        mTempList.add(mCurrentTempRecordData);
        mRecorder.setOutputFile(mCurPath);
        mRecorder.setPreviewDisplay(activtityVideoRecordBinding.sView.getHolder().getSurface()); // ①

        if(getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
            int degree ;
            if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                degree = 270;
            } else {
                degree = 90;
            }
            mRecorder.setOrientationHint(degree);
        }

        try {
            mRecorder.prepare();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;

    }

    private void startRecord() {
        if (prepareMediaRecorder()) {
            mRecorder.start();
            isRecording = true;
            activtityVideoRecordBinding.recordOrStop.setText("停止");
        } else {
            releaseMediaRecorder();
            isRecording = false;
            activtityVideoRecordBinding.recordOrStop.setText("开始");
        }

    }

    private void stopRecord() {
        if (mRecorder == null) {
            return;
        }
        mRecorder.stop();
        releaseMediaRecorder();
        isRecording = false;
        activtityVideoRecordBinding.recordOrStop.setText("开始");
    }

    @Nullable
    @Override
    public CharSequence onCreateDescription() {
        return super.onCreateDescription();
    }

    @Override
    protected void onDestroy() {
        releaseCamera();
        releaseMediaRecorder();
        super.onDestroy();
    }

    /**
     * 释放相机资源
     */
    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    private void releaseMediaRecorder() {
        if (mRecorder != null) {
            mRecorder.reset();
            mRecorder.release();
            mRecorder = null;
            mCamera.lock();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        openCamera(cameraPosition);
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder();
        releaseCamera();
    }

    /**
     * 获取最佳预览大小
     *
     * @param parameters       相机参数
     * @param screenResolution 屏幕宽高
     * @return
     */

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    private Size getBestCameraResolution(Camera.Parameters parameters, Size screenResolution) {
        float tmp = 0f;

        float mindiff = 100f;
        Log.e("yuanVideo", "screen width=" + screenResolution.getWidth() + " height=" + screenResolution.getHeight());

        float width_d_height;
        if (screenResolution.getWidth() > screenResolution.getHeight()) {
            width_d_height = (float) screenResolution.getWidth() / (float) screenResolution.getHeight();
        } else {
            width_d_height = (float) screenResolution.getHeight() / (float) screenResolution.getWidth();
        }
        Log.e("yuanVideo", "width_d_height=" + width_d_height);

        Camera.Size best = null;

        List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
        for (Camera.Size s : supportedPreviewSizes) {
            tmp = Math.abs(((float) s.width / (float) s.height) - width_d_height);
            Log.e("yuanVideo", "support width=" + s.width + " height=" + s.height + " ratio=" + tmp);

            if (tmp < mindiff) {
                mindiff = tmp;

                best = s;
            }

        }
        Log.e("yuanVideo", "best width=" + best.width + " height=" + best.height);

        return new Size(best.width, best.height);
    }

    /**
     * 获取屏幕宽度和高度,单位为px
     *
     * @param context
     * @return
     */

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static Size getScreenMetrics(Context context) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics();

        int w_screen = dm.widthPixels;

        int h_screen = dm.heightPixels;

        return new Size(w_screen, h_screen);
    }

}

布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 显示视频预览的SurfaceView -->
    <com.yuanxuzhen.ffmpeg.ResizeAbleSurfaceView
        android:id="@+id/sView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        >
        <TextView
            android:id="@+id/tv_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0秒"
            android:layout_centerInParent="true"
            android:textColor="@color/white"
            />
        <Button
            android:id="@+id/change"
            android:layout_width="wrap_content"
            android:layout_height="66dp"
            android:text="切换摄像头"
            android:layout_alignParentEnd="true"
            />
    </RelativeLayout>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true">
        <Button
            android:id="@+id/record_or_stop"
            android:layout_width="66dp"
            android:layout_height="66dp"
            android:text="录制"
            />
        <Button
            android:id="@+id/save"
            android:layout_width="66dp"
            android:layout_height="66dp"
            android:text="保存"
            />
    </LinearLayout>
</RelativeLayout>
package com.yuanxuzhen.ffmpeg;

import android.content.Context;
import android.util.AttributeSet;
import android.view.SurfaceView;

public class ResizeAbleSurfaceView extends SurfaceView {

    private int mWidth = -1;
    private int mHeight = -1;

    public ResizeAbleSurfaceView(Context context) {
        super(context);
    }

    public ResizeAbleSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ResizeAbleSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (-1 == mWidth || -1 == mHeight) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
        else {
            setMeasuredDimension(mWidth, mHeight);
        }
    }

    public void resize(int width, int height) {
        mWidth = width;
        mHeight = height;
        getHolder().setFixedSize(width, height);
        requestLayout();
        invalidate();
    }

}
package com.yuanxuzhen.ffmpeg;

import android.content.Context;
import android.os.Environment;

import java.io.File;

public class DirUtil {
    public static final String WEBVIEW_CACHE = ".webviewCache";
    public static final String IMAGE_PATH = "image";
    public static final String DOWNLOAD_PATH = "download";
    public static final String VIDEO_PATH = ".video";
    public static final String NET_PATH = ".net";

    //image
    public static String getImageDir(Context context) {
        return getCacheDir(context) + File.separator + IMAGE_PATH;
    }

    //webview
    public static String getWebviewCache(Context context) {
        return getCacheDir(context) + File.separator + WEBVIEW_CACHE;
    }

    //download
    public static String getDownloadDir(Context context) {
        return getCacheDir(context) + File.separator + DOWNLOAD_PATH;
    }

    //video
    public static String getVideoPath(Context context) {
        return getCacheDir(context) + File.separator + VIDEO_PATH;
    }

    //net
    public static String getNetPath(Context context) {
        return getCacheDir(context) + File.separator + NET_PATH;
    }

    public static String getCacheDir(Context context) {

        if (context == null) {
            return "";
        }
        String path = null;
        if (context.getExternalCacheDir() != null
                && (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
                || !Environment.isExternalStorageRemovable())) {
            //外部存储可用
            path = context.getExternalCacheDir().getPath();
        } else {
            //内部存储不可用
            path = context.getCacheDir().getPath();
        }
        return path;
    }

}

以上就是Android 录制音视频的详细内容,更多关于Android 录制音视频的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android中音视频合成的几种方案详析

    前言 最近工作中遇到了音视频处理的需求,Android下音视频合成,在当前调研方案中主要有三大类方法:MediaMux硬解码,mp4parser,FFmepg.三种方法均可实现,但是也有不同的局限和问题,先将实现和问题记录于此,便于之后的总结学习.下面话不多说了,来一起看看详细的介绍吧. 方法一(Fail) 利用MediaMux实现音视频的合成. 效果:可以实现音视频的合并,利用Android原生的VideoView和SurfaceView播放正常,大部分的播放器也播放正常,但是,但是,在上传Y

  • Android音视频之视频采集(系统API预览)

    我们了解了视频相关的基础知识,后面的文章我们要能够和音频一样可以采集我们的视频,视频是一帧一帧的图片来的,我们首先要学习预览视频,然后采集一帧图片,采集视频从简到难的来了解这个问题.首先第一个反应打开Google搜索和Android视频采集相关的东西,我们要知道如何通过API来采集,不由自主地到了Android官网的Camera API.Android有两个视频采集的API,Camera是Android 5.0以前使用的,现在已经废弃了,我们还是得学一下他的使用,Camera2是最新的视频采集A

  • Android仿微信多人音视频通话界面

    工作中需要实现一个类似微信多人视频通话功能的界面,分别使用自定义viewgroup和自定义layoutManager的方式进行了实现.最终工作中采用了layoutManager,因为可以使用payload更新单个布局控件,效率更好.下面放出两种具体的实现效果代码. 1.使用自定义ViewGroup方式实现 下面是三个人通话时候的效果,其他的可以参考微信多人音视频通话界面. package com.dnaer.android.telephone.widgets; import android.co

  • Android提高之MediaPlayer音视频播放

    前面文章已经详细介绍了Android界面的入门技术,相信大家在看完和跟着练习之后,会对于常用的Layout和View都会有一定的了解了,接下来就不再强调介绍界面了,而是针对具体的常见功能而展开. 本文将介绍MediaPlayer的使用.MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoView比MediaPlayer简单易用,但定制性不如用MediaPlayer,这需要视情况选择.MediaPlayer播放音频比较简单,但是要播放视频就需要Sur

  • Android基于腾讯云实时音视频仿微信视频通话最小化悬浮

    最近项目中有需要语音.视频通话需求,看到这个像环信.融云等SDK都有具体Demo实现,但咋的领导对腾讯情有独钟啊,IM要用腾讯云IM,不妙的是腾讯云IM并不包含有音视频通话都要自己实现,没办法深入了解腾讯云产品后,决定自己基于腾讯云实时音视频做去语音.视频通话功能.在这里把实现过程记录下为以后用到便于查阅,另一方面也给有需要的人提供一个思路,让大家少走弯路,有可能我的实现的方法不是最好,但是这或许是一个可行的方案,大家不喜勿喷.基于腾讯云实时音视频SDK 6.5.7272版本,腾讯DEMO下载地

  • android采用FFmpeg实现音视频合成与分离

    上一篇文章谈到音频剪切.混音.拼接与转码,也详细介绍cMake配置与涉及FFmpeg文件的导入: android端采用FFmpeg进行音频混合与拼接剪切.现在接着探讨音视频的合成与分离. 1.音频提取 从多媒体文件中提取音频,关键命令为"-acodec copy -vn",其中"-acodec copy"是采用音频编码器拷贝音频流,"-vn"是去掉video视频流: /** * 使用ffmpeg命令行进行抽取音频 * @param srcFile

  • Android 录制音视频的完整代码

    打开camera private void openCamera(int position) { if (mCamera == null) { mCamera = Camera.open(position); int degree = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 0 : 90; mCamera.setDisplayOrientation(degree)

  • python3下载抖音视频的完整代码

    python3下载抖音视频的代码如下所示: # -*- coding:utf-8 -*- from contextlib import closing import requests, json, re, os, sys, random from ipaddress import ip_address from subprocess import Popen, PIPE import urllib class DouYin(object): def __init__(self, width =

  • Android仿微信录制小视频

    本文实例为大家分享了Android仿微信录制小视频的具体代码,供大家参考,具体内容如下 先上张图片看看效果 简单叙述下 首先通过Camera类调用系统相机 通过surfaceview绘制出来 通过MediaRecorder来录制视频 闪光灯 和 切换摄像头 需要重新配置Camera的参数 Camera预览界面画面拉升的原因是因为Surfaceview的大小与设定的比例不一致的 **本次版本更新了 切换前置摄像头录制视频问题 Android部分手机录制视频适配IOS手机问题 (OPPO手机部分不适

  • Java 使用 FFmpeg 处理视频文件示例代码详解

    目前在公司做一个小东西,里面用到了 FFmpeg 简单处理音视频,感觉功能特别强大,在做之前我写了一个小例子,现在记录一下分享给大家,希望大家遇到这个问题知道解决方案. FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视频的完整解决方案.它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的. FFmpeg在Linux平

  • C# 调用FFmpeg处理音视频的示例

    FFmpeg 开源.跨平台.体积小.功能强大,提供了录制.转换以及流化音视频的完整解决方案. 官网:https://www.ffmpeg.org/ 百科:https://baike.baidu.com/item/ffmpeg/2665727?fr=aladdin FFmpeg 应用非常广泛,可以用来播放本地视频甚至网络视频,查看音视频信息,还可以用于从视频中提取音频,转换音视频文件格式等等,本文主要介绍如何调用 FFmpeg 来查看音视频信息.从视频中提取音频.转换音视频格式等. 1. 调用FF

  • C#调用FFmpeg操作音视频的实现示例

    目录 项目背景 FFmpeg介绍 FFmpeg相关教程 博客示例源码 下载FFmpeg.exe安装包 C#进程调用FFmpeg操作音视频 项目背景 因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作.本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并,音频合并,音频与视频合并成视频这几个简单的音视频操作,还有些

  • Android录制声音文件(音频)并播放

    本文实例为大家分享了Android录制音频文件的具体代码,供大家参考,具体内容如下 1.这个demo中没有对多次点击同一个声音文件做详细处理,偶尔会有崩溃,用的时候需要注意. 2.按住录音按钮录音过程中,只对竖直方向处理了一下,水平方向没写: 3.没有做删除某个声音文件的操作,但是测试的时候实现了功能,需要用到的话,在MainActivity->onItemClick中的TODO中有详细说明: 4.这只是个demo,如果要在项目中使用,先写出demo,没问题了,再引入项目,在写成demo后,在真

  • python批量爬取下载抖音视频

    本文实例为大家分享了python批量爬取下载抖音视频的具体代码,供大家参考,具体内容如下 import os import requests import re import sys import asyncio import aiohttp headers = { 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) ' 'Ve

  • python批量下载抖音视频

    本文实例为大家分享了python批量下载抖音视频的具体代码,供大家参考,具体内容如下 知识储备:博主是在Pycharm下进行的 文件夹:dou_ying 1:在文件夹doy_ying下新建第一个文件:dou_ying_video_download.py 代码: # coding=utf-8 """ @author: jiajiknag 程序功能:批量下载抖音视频 """ import requests import bs4 import os i

  • Android 微信小视频录制功能实现详细介绍

    Android 微信小视频录制功能 开发之前 这几天接触了一下和视频相关的控件, 所以, 继之前的微信摇一摇, 我想到了来实现一下微信小视频录制的功能, 它的功能点比较多, 我每天都抽出点时间来写写, 说实话, 有些东西还是比较费劲, 希望大家认真看看, 说得不对的地方还请大家在评论中指正. 废话不多说, 进入正题. 开发环境 最近刚更新的, 没更新的小伙伴们抓紧了 Android Studio 2.2.2 JDK1.7 API 24 Gradle 2.2.2 相关知识点 视频录制界面 Surf

随机推荐