简单播放视频,使用摄像头拍照

1.要使用MediaPlayer播放视频,需要编写一个可以用于视频显示的空间,而这块空间要求可以快速进行GUI更新,而且可以在渲染代码时对GUI进行无阻塞的渲染,要实现该功能需要android.view.SurfaceView组件。SurfaceView组件封装了一个Surface对象,使用Surface可以完成对后台线程的控制,对于视频、3D图形等需要快速更新或者高帧率的对象有很大用处。
在SurfaceView类中,getHolder()方法最常用,该方法返回一个android.view.SurfaceHolder接口的实例化对象,使用SurfaceHolder接口可以控制显示的大小、像素等。
2.播放sdcard中的视频文件:

public class MyVideoPlayerDemo extends Activity {
    private ImageButton play = null ;
    private ImageButton stop = null ;
    private MediaPlayer media = null ;
    private SurfaceView surfaceView = null ;
    private SurfaceHolder surfaceHolder = null ;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.main);
        this.play = (ImageButton) super.findViewById(R.id.play) ;
        this.stop = (ImageButton) super.findViewById(R.id.stop) ;
        this.surfaceView = (SurfaceView) super.findViewById(R.id.surfaceView) ;
        this.surfaceHolder = this.surfaceView.getHolder() ;//取得SurfaceHolder
//设置SurfaceView的类型
        this.surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        this.media = new MediaPlayer() ;//创建MediaPlayer对象
        try {
            this.media.setDataSource("/sdcard/mldn.3gp") ;  //设置播放文件的路径
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.play.setOnClickListener(new PlayOnClickListenerImpl()) ;
        this.stop.setOnClickListener(new StopOnClickListenerImpl()) ;
    }
    private class PlayOnClickListenerImpl implements OnClickListener {
        @Override
        public void onClick(View v) {
        //设置音频类型
    MyVideoPlayerDemo.this.media.setAudioStreamType(AudioManager.STREAM_MUSIC) ;
        //设置显示区域
    MyVideoPlayerDemo.this.media.setDisplay(MyVideoPlayerDemo.this.surfaceHolder) ;
            try {
                MyVideoPlayerDemo.this.media.prepare() ;//预备状态
            } catch (Exception e) {
            }
            MyVideoPlayerDemo.this.media.start() ;//播放视频
        }

    }
    private class StopOnClickListenerImpl implements OnClickListener {
        @Override
        public void onClick(View v) {
            MyVideoPlayerDemo.this.media.stop() ;//停止播放
        }

    }
}

使用摄像头拍照
1.想实现拍照功能,需要手工实现android.view.SurfaceHolder.Callback操作接口。调用摄像头的操作类android.hardware.Camera,此类主要负责完成拍照的参数设置及保存。
2.捕获图像:

public class MyCameraDemo extends Activity {
    private SurfaceView surface = null ;
    private Button but = null ;
    private SurfaceHolder holder = null ;
    private Camera cam = null ;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.main);
        this.but = (Button) super.findViewById(R.id.but) ;
        this.surface = (SurfaceView) super.findViewById(R.id.surface) ;

        this.holder = this.surface.getHolder() ;
        this.holder.addCallback(new MySurfaceViewCallback()) ;
        this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) ;
        this.holder.setFixedSize(800, 480);

        this.but.setOnClickListener(new OnClickListenerImpl()) ;
    }
    private class OnClickListenerImpl implements OnClickListener {

        @Override
        public void onClick(View v) {

        }

    }

    private class MySurfaceViewCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            MyCameraDemo.this.cam = Camera.open(0) ;    // 取得第一个摄像头
            WindowManager manager = (WindowManager) MyCameraDemo.this
                    .getSystemService(Context.WINDOW_SERVICE);
            Display display = manager.getDefaultDisplay() ;
            Parameters param = MyCameraDemo.this.cam.getParameters() ;
            param.setPreviewSize(display.getWidth(), display.getHeight()) ;
            param.setPreviewFrameRate(5) ;  // 一秒5帧
            param.setPictureFormat(PixelFormat.JPEG) ;  // 图片形式
            param.set("jpen-quality", 85) ;
            MyCameraDemo.this.cam.setParameters(param) ;
            try {
                MyCameraDemo.this.cam.setPreviewDisplay(MyCameraDemo.this.holder) ;
            } catch (IOException e) {
            }
            MyCameraDemo.this.cam.startPreview() ;  // 进行预览
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

    }
}

3.实现拍照

public class MyCameraDemo extends Activity {
    private SurfaceView surface = null ;//主要用于取得SurfaceHolder对象
    private Button but = null ;
    private SurfaceHolder holder = null ;//主要用来设置图片的类型、分辨率等参数以及//指定SurfaceHolder.Callback
    private Camera cam = null ;//负责具体的拍照操作
    private boolean previewRunning =  true ;//保存现在是否是预览状态
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.main);
super.requestWindowFeature(Window.FEATURE_NO_TITLE);//不显示标题
super.getWindow.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示
super.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//高亮显示
        this.but = (Button) super.findViewById(R.id.but) ;
        this.surface = (SurfaceView) super.findViewById(R.id.surface) ;

        this.holder = this.surface.getHolder() ;//调用Holder
        this.holder.addCallback(new MySurfaceViewCallback()) ;//加入回调
    this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS) ;//设置缓冲类型
        this.holder.setFixedSize(500, 350);//设置分辨率

        this.but.setOnClickListener(new OnClickListenerImpl()) ;
    }
    private class OnClickListenerImpl implements OnClickListener {

        @Override
        public void onClick(View v) {
            if(MyCameraDemo.this.cam != null) {//存在Camera对象
        MyCameraDemo.this.cam.autoFocus(new AutoFocusCallbackImpl()) ;//自动对焦
            }
        }

    }
    //接口SurfaceHolder.Callback被用来接收摄像头预览界面变化的信息
    private class MySurfaceViewCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {//当预览界面的格式和大小发生改变时,该方法被调用

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {//初次实例化预览界面调用
            MyCameraDemo.this.cam = Camera.open(0) ;    // 取得第一个摄像头
            WindowManager manager = (WindowManager) MyCameraDemo.this
                    .getSystemService(Context.WINDOW_SERVICE);//取得服务
            Display display = manager.getDefaultDisplay() ;//取得Display对象
        Parameters param = MyCameraDemo.this.cam.getParameters() ;//取得相机参数
    param.setPreviewSize(display.getWidth(), display.getHeight()) ;//设置预览大小
            param.setPreviewFrameRate(5) ;  // 一秒5帧
            param.setPictureFormat(PixelFormat.JPEG) ;  // 图片形式
            param.set("jpen-quality", 80) ;//设置图片质量,最高为100
            MyCameraDemo.this.cam.setParameters(param) ;//设置参数
            try {//通过SurfaceView显示
                MyCameraDemo.this.cam.setPreviewDisplay(MyCameraDemo.this.holder) ;
            } catch (IOException e) {
            }
            MyCameraDemo.this.cam.startPreview() ;  // 进行预览
            MyCameraDemo.this.previewRunning = true ;   // 修改预览标记,已经开始预览
        }

        @Override
public void surfaceDestroyed(SurfaceHolder holder) {//当预览界面被关闭时方法被调用
            if(MyCameraDemo.this.cam != null) {
                if(MyCameraDemo.this.previewRunning) {//如果正在预览
                    MyCameraDemo.this.cam.stopPreview() ;   // 停止预览
                    MyCameraDemo.this.previewRunning = false ;//修改标记
                }
//摄像头只能被一个Activity程序使用,所有要释放摄像头
                MyCameraDemo.this.cam.release() ;//释放摄像头
            }
        }

    }

    private class AutoFocusCallbackImpl implements AutoFocusCallback {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if(success) {   // 对焦成功
                MyCameraDemo.this.cam.takePicture(sc, pc, jpgcall) ;//获取图片
MyCameraDemo.this.cam.stopPreview();//停止预览
            }
        }

    }

    private PictureCallback jpgcall = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {    // 保存图片的操作
            Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
            String fileName = Environment.getExternalStorageDirectory()
                    .toString()
                    + File.separator
                    + "mldnphoto"
                    + File.separator
                    + "MLDN_" + System.currentTimeMillis() + ".jpg";//输出文件名称
            File file = new File(fileName) ;//定义File对象
            if (!file.getParentFile().exists()) {//父文件夹不存在
                file.getParentFile().mkdirs() ; // 创建文件夹
            }
            try {
                BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)) ;//使用字节缓存流
                bmp.compress(Bitmap.CompressFormat.JPEG, 80, bos) ; // 向缓冲区之中压缩图片
                bos.flush() ;//清空缓存
                bos.close() ;//关闭
                Toast.makeText(MyCameraDemo.this,
                        "拍照成功,照片已保存在" + fileName + "文件之中!", Toast.LENGTH_SHORT)
                        .show();//显示Toast
            } catch (Exception e) {
                Toast.makeText(MyCameraDemo.this,
                        "拍照失败!", Toast.LENGTH_SHORT)
                        .show();
            }
            MyCameraDemo.this.cam.stopPreview() ;//停止预览
            MyCameraDemo.this.cam.startPreview() ;//开始预览
        }

    } ;

    private ShutterCallback sc = new ShutterCallback(){
        @Override
        public void onShutter() {
            // 按下快门之后进行的操作
        }
    } ;
    private PictureCallback pc = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            //保存的源图片数据
        }

    } ;
}

配置权限文件:

<uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Electron 中调用摄像头拍照可以通过使用 `screen` 和 `camera` 模块来实现。下面是一个简单的示例代码,演示了如何使用 Electron 调用摄像头拍照: 1. 首先,确保你已经安装了 Electron。 2. 创建一个新的 Electron 项目,可以使用 `electron-app cd my-electron-app npm init -y npm install electron@latest --save-dev ``` 3. 在项目根目录下创建一个名为 `main.js` 的文件,并输入以下代码: ```javascript const { app, BrowserWindow } = require('electron') const fs = require('fs') function createWindow () { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false } }) win.loadFile('index.html') } app.whenReady().then(createWindow) ``` 4. 在 `package.json` 文件中添加一个名为 `index.html` 的入口文件,用于展示摄像头拍照的界面。可以使用以下代码创建 `index.html` 文件: ```html <!DOCTYPE html> <html> <body> <video id="video" width="640" height="480" autoplay></video> <button id="capture">拍照</button> <script src="main.js"></script> </body> </html> ``` 5. 在 `main.js` 文件中添加以下代码,用于调用摄像头拍照: ```javascript const { screen, camera } = require('electron') // 引入摄像头模块 const { ipcMain } = require('electron') // 引入 ipcMain 模块用于处理事件 const { dialog } = require('electron').remote // 使用远程模块中的对话框 API 弹出拍照界面 const fs = require('fs') // 使用 Node.js 的文件系统模块来保存照片文件 const htmlFile = './index.html' // 设置前端入口文件的路径,此处需要保证与前端页面路径一致 const videoElement = document.getElementById('video') // 获取视频元素对象,用于显示摄像头画面 const captureButton = document.getElementById('capture') // 获取拍照按钮对象,用于触发拍照事件 const videoStream = screen.getPrimaryDisplay().getDisplayMedia({ video: true }) // 获取主屏幕的摄像头流对象,返回一个 Promise 对象,等待 Promise 解析完成即可获取到摄像头流对象,并赋值给 videoStream 变量 const streamPromise = new Promise((resolve, reject) => { // 创建一个 Promise 对象,用于等待摄像头流对象解析完成,并在解析失败时抛出错误信息并终止程序执行 videoStream.on('error', (error) => { // 当摄像头流对象出现错误时触发此事件,并抛出错误信息并终止程序执行 reject(error) }) resolve(videoStream) // 当摄像头流对象解析成功时触发此事件,将摄像头流对象赋值给 resolve() 方法返回的参数值中,即 Promise 的 resolve() 方法返回的参数值中赋值给 videoStream 变量即可完成 Promise 的解析操作,此时可以正常使用摄像头流对象进行后续操作了。 }) camera.getMedia({ video: true }).then((stream) => { // 使用摄像头模块中的 getMedia 方法获取摄像头流对象,并返回一个 Promise 对象,等待 Promise 解析完成即可获取到摄像头流对象,并赋值给 stream 变量使用,此处需要使用 Promise 的 then() 方法来处理 Promise 的解析结果并使用 stream 变量进行后续操作。当获取到摄像头流对象后,可以使用 stream.on() 方法来监听视频播放的回调函数以触发相应的事件和功能实现。在 stream 上注册回调函数可以使用回调函数的 eventId() 方法获取到具体的回调事件和函数指针变量进行注册回调函数的操作。可以在具体实现时结合调用相机进行拍照、保存照片、传输等操作实现相关的功能实现需求。上述代码中使用 htmlElement.on() 方法监听视频播放事件触发相应的事件和功能实现需求。具体实现可以结合使用相关的 API 和库来实现相应的功能需求。当视频播放完毕时可以使用 stream.getVideoTracks().get(0).getTracks().stop() 方法来停止视频播放并释放资源。上述代码中使用了 WebRTC 技术来处理视频流的播放和传递。使用时需要根据具体的 API 和功能实现需求来进行调用和处理。以上就是使用 Electron 和相关模块实现调用摄像头拍照的基本步骤和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值