├── .npmignore
├── .gitignore
├── example
├── .gitignore
├── .babelrc
├── style.css
├── src
│ ├── main.js
│ └── App.vue
├── README.md
├── index.html
├── package.json
└── webpack.config.js
├── README.md
├── package.json
├── LICENSE
└── VueWebcam.js
/.npmignore:
--------------------------------------------------------------------------------
1 | example/
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["es2015", { "modules": false }]
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/example/style.css:
--------------------------------------------------------------------------------
1 | #app {
2 | position: absolute;
3 | top: 50%;
4 | left: 50%;
5 | transform: translate(-50%, -50%);
6 | }
7 |
--------------------------------------------------------------------------------
/example/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 |
4 | new Vue({
5 | el: '#app',
6 | render: h => h(App)
7 | });
8 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # vue-webcam-example
2 |
3 | > Example project for vue-webcam package
4 |
5 | ## Build Setup
6 |
7 | ``` bash
8 | # install dependencies
9 | npm install
10 |
11 | # serve with hot reload at localhost:8080
12 | npm start
13 | ```
14 |
--------------------------------------------------------------------------------
/example/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vue Webcam Example
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # If you found any issues please make PR as I'm not maintaining this anymore!
2 |
3 | # vue-webcam
4 | A Vue component for capturing image from webcam.
5 |
6 | ## Installation
7 | ```shell
8 | npm install --save vue-webcam
9 | ```
10 |
11 | ## Usage
12 | See the [example](https://github.com/smronju/vue-webcam/tree/master/example) files
13 |
14 | ## Options
15 |
16 | ### width
17 | * Type: `Number`
18 | * Required: `false`
19 |
20 | ### height
21 | * Type: `Number`
22 | * Required: `false`
23 |
24 | ### Resources
25 |
26 | See more about taking photos from webcam [documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos)
27 |
28 | ## License
29 | MIT
30 |
--------------------------------------------------------------------------------
/example/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
![]()
6 |
7 |
8 |
9 |
10 |
11 |
29 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-webcam-example",
3 | "description": "Example project for vue-webcam package",
4 | "author": {
5 | "name": "Mohammad Shoriful Islam Ronju",
6 | "email": "smronju@gmail.com",
7 | "url": "https://github.com/smronju"
8 | },
9 | "scripts": {
10 | "start": "webpack-dev-server --open --inline --hot"
11 | },
12 | "dependencies": {
13 | "vue": "^2.0.1",
14 | "vue-webcam": "^2.0.2"
15 | },
16 | "devDependencies": {
17 | "babel-core": "^6.0.0",
18 | "babel-loader": "^6.0.0",
19 | "babel-preset-es2015": "^6.0.0",
20 | "cross-env": "^3.0.0",
21 | "css-loader": "^0.25.0",
22 | "file-loader": "^0.9.0",
23 | "style-loader": "^0.13.1",
24 | "vue-loader": "^9.4.0",
25 | "webpack": "2.1.0-beta.22",
26 | "webpack-dev-server": "^2.1.0-beta.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-webcam",
3 | "version": "2.0.6",
4 | "description": "A Vue component for capturing image from webcam.",
5 | "main": "VueWebcam.js",
6 | "keywords": [
7 | "vue",
8 | "vuejs",
9 | "webcam",
10 | "stream",
11 | "component"
12 | ],
13 | "script": {
14 | "build": "./node_modules/.bin/microbundle -i ./VueWebcam.js"
15 | },
16 | "author": {
17 | "name": "Mohammad Shoriful Islam Ronju",
18 | "email": "smronju@gmail.com",
19 | "url": "https://github.com/smronju"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "https://github.com/smronju/vue-webcam"
24 | },
25 | "license": "MIT",
26 | "peerDependencies": {
27 | "vue": ">=2.0.0"
28 | },
29 | "devDependencies": {
30 | "microbundle": "^0.2.4"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Mohammad Shoriful Islam Ronju
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in
12 | all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
20 | OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/example/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 |
4 | module.exports = {
5 | entry: './src/main.js',
6 | output: {
7 | path: path.resolve(__dirname, './dist'),
8 | publicPath: '/dist/',
9 | filename: 'build.js'
10 | },
11 | resolveLoader: {
12 | root: path.join(__dirname, 'node_modules'),
13 | },
14 | module: {
15 | loaders: [
16 | {
17 | test: /\.vue$/,
18 | loader: 'vue'
19 | },
20 | {
21 | test: /\.js$/,
22 | loader: 'babel',
23 | exclude: /node_modules/
24 | },
25 | {
26 | test: /\.css$/,
27 | loader: 'style-loader!css-loader'
28 | },
29 | {
30 | test: /\.(png|jpg|gif|svg)$/,
31 | loader: 'file',
32 | query: {
33 | limit: 10000,
34 | name: '[name].[ext]?[hash]'
35 | }
36 | }
37 | ]
38 | },
39 | devServer: {
40 | historyApiFallback: true,
41 | noInfo: true
42 | },
43 | devtool: '#eval-source-map'
44 | }
45 |
46 | if (process.env.NODE_ENV === 'production') {
47 | module.exports.devtool = '#source-map'
48 | // http://vue-loader.vuejs.org/en/workflow/production.html
49 | module.exports.plugins = (module.exports.plugins || []).concat([
50 | new webpack.DefinePlugin({
51 | 'process.env': {
52 | NODE_ENV: '"production"'
53 | }
54 | }),
55 | new webpack.optimize.UglifyJsPlugin({
56 | compress: {
57 | warnings: false
58 | }
59 | }),
60 | new webpack.optimize.OccurenceOrderPlugin()
61 | ])
62 | }
63 |
--------------------------------------------------------------------------------
/VueWebcam.js:
--------------------------------------------------------------------------------
1 | // TODO:
2 | // 1. Enable mirror option
3 | // 2. Improve options handling
4 | // 3. Error handling
5 |
6 | const Vue = require('vue').default;
7 |
8 | const WebcamComponent = Vue.extend({
9 | props: {
10 | autoplay: {
11 | type: Boolean,
12 | default: true
13 | },
14 | width: {
15 | type: Number,
16 | default: 400
17 | },
18 | height: {
19 | type: Number,
20 | default: 300
21 | },
22 | mirror: {
23 | type: Boolean,
24 | default: true
25 | },
26 | screenshotFormat: {
27 | type: String,
28 | default: 'image/jpeg'
29 | }
30 | },
31 | data() {
32 | return {
33 | video: '',
34 | src: '',
35 | stream: '',
36 | hasUserMedia: false,
37 | styleObject: {
38 | transform: 'scale(-1, 1)',
39 | filter: 'FlipH'
40 | }
41 | };
42 | },
43 |
44 | mounted() {
45 | this.video = this.$refs.video;
46 | navigator.getUserMedia =
47 | navigator.getUserMedia ||
48 | navigator.webkitGetUserMedia ||
49 | navigator.mozGetUserMedia ||
50 | navigator.msGetUserMedia ||
51 | navigator.oGetUserMedia;
52 |
53 | // new api for video and audio called navigator.mediadevices
54 | // for new browsers video can directly consume MediaStream using srcObject
55 | //
56 | if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
57 | navigator.mediaDevices
58 | .getUserMedia({ video: true })
59 | .then(stream => {
60 | this.video = this.$refs.video; // reInitializing as it doesn't work sometime.
61 | this.video.srcObject = stream;
62 | this.stream = stream;
63 | this.hasUserMedia = true;
64 | })
65 | .catch(error => {
66 | console.log(error);
67 | });
68 | } else if (navigator.getUserMedia) {
69 | // if new api not there, use the old one
70 | navigator.getUserMedia(
71 | { video: true },
72 | stream => {
73 | this.video = this.$refs.video;
74 | // below line won't work on new browser because of this
75 | // https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL#Using_object_URLs_for_media_streams
76 | // this.src = window.URL.createObjectURL(stream);
77 | this.video.srcObject = stream;
78 | this.stream = stream;
79 | this.hasUserMedia = true;
80 | },
81 | error => {
82 | console.log(error);
83 | }
84 | );
85 | }
86 | },
87 | methods: {
88 | getPhoto() {
89 | if (!this.hasUserMedia) return null;
90 |
91 | const canvas = this.getCanvas();
92 | return canvas.toDataURL(this.screenshotFormat);
93 | },
94 | getCanvas() {
95 | if (!this.hasUserMedia) return null;
96 |
97 | const video = this.$refs.video;
98 | if (!this.ctx) {
99 | const canvas = document.createElement('canvas');
100 | canvas.height = video.clientHeight;
101 | canvas.width = video.clientWidth;
102 | this.canvas = canvas;
103 |
104 | this.ctx = canvas.getContext('2d');
105 |
106 | /*if (this.mirror) {
107 | const context = canvas.getContext('2d');
108 | context.translate(canvas.width, 0);
109 | context.scale(-1, 1);
110 | this.ctx = context;
111 | } else {
112 | this.ctx = canvas.getContext('2d');
113 | }*/
114 | }
115 |
116 | const { ctx, canvas } = this;
117 | ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
118 |
119 | return canvas;
120 | }
121 | },
122 |
123 | beforeDestroy: function() {
124 | this.video.pause();
125 | this.src = '';
126 | this.stream &&
127 | this.stream.getTracks()[0] &&
128 | this.stream.getTracks()[0].stop();
129 | },
130 |
131 | destroyed: function() {
132 | console.log('Destroyed');
133 | },
134 | render: function(h) {
135 | return h('video', {
136 | ref: 'video',
137 | attrs: {
138 | width: this.width,
139 | height: this.height,
140 | src: this.src,
141 | autoplay: this.autoplay
142 | }
143 | });
144 | }
145 | });
146 |
147 | const VueWebcam = Vue.component('vue-webcam', WebcamComponent);
148 | export default VueWebcam;
149 |
--------------------------------------------------------------------------------