Video JS in Angular 9 - live video - 'Can't resolve videojs' problem?

感情迁移 提交于 2020-08-09 08:17:49

问题


I am struggling to get the videojs to work in my angular 9 app. I have viewed all the exisitng stackoverflow posts, applied their solution, looked at different blog posts and github for issues with video js but I still have the 'Can't resolve videojs' problem.

I would like it to work in that an individual viewing the page could start recording a video of themselves.

Can someone please advise? Please see my code below@

my package.json file:

{
  "name": "post-stroke-care-project",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~9.1.9",
    "@angular/common": "~9.1.9",
    "@angular/compiler": "~9.1.9",
    "@angular/core": "~9.1.9",
    "@angular/forms": "~9.1.9",
    "@angular/platform-browser": "~9.1.9",
    "@angular/platform-browser-dynamic": "~9.1.9",
    "@angular/router": "~9.1.9",
    "@fortawesome/angular-fontawesome": "^0.6.1",
    "@fortawesome/fontawesome-svg-core": "^1.2.29",
    "@fortawesome/free-brands-svg-icons": "^5.13.1",
    "@fortawesome/free-regular-svg-icons": "^5.13.1",
    "@fortawesome/free-solid-svg-icons": "^5.13.1",
    "@fullcalendar/angular": "^5.1.0",
    "@fullcalendar/daygrid": "^5.1.0",
    "@fullcalendar/interaction": "^5.1.0",
    "@types/video.js": "^7.3.10",
    "angular-google-charts": "^1.1.4",
    "bootstrap": "^4.5.0",
    "core-js": "^3.6.5",
    "fullcalendar": "^5.1.0",
    "html-webpack-plugin": "^4.3.0",
    "jquery": "^3.5.1",
    "moment": "^2.27.0",
    "ngx-build-plus": "^10.1.1",
    "popper.js": "^1.16.1",
    "raw-loader": "^4.0.1",
    "rxjs": "~6.5.4",
    "rxjs-compat": "^6.6.0",
    "ts-loader": "^8.0.1",
    "tslib": "^1.10.0",
    "video.js": "^7.8.4",
    "videojs-record": "^4.0.0",
    "webpack": "^4.44.0",
    "webpack-cli": "^3.3.12",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.901.7",
    "@angular/cli": "~9.1.7",
    "@angular/compiler-cli": "~9.1.9",
    "@types/jasmine": "~3.5.0",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.12.53",
    "codelyzer": "^5.1.2",
    "jasmine": "^3.6.1",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~5.0.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~2.1.0",
    "karma-jasmine": "~3.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.8.3",
    "webpack-dev-server": "^3.11.0"
  }
}

webpack.config.js file:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');

module.exports = {
    entry: './src/main.ts',
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            videojs: 'video.js',
            WaveSurfer: 'wavesurfer.js',
            RecordRTC: 'recordrtc'
        }
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: ['ts-loader']
            },
            {
                test: /\.(html|css)$/,
                use: 'raw-loader'
            }
        ]
    },
    plugins: [
        new ProvidePlugin({
            videojs: 'video.js/dist/video.cjs.js',
            RecordRTC: 'recordrtc'
        }),
        new HtmlWebpackPlugin({ template: './src/index.html' })
    ]
}

video component.ts file:

import {
    Component,
    OnInit,
    OnDestroy,
    ElementRef
  } from '@angular/core';
  
  import videojs from 'video.js';
  import * as adapter from 'webrtc-adapter/out/adapter_no_global.js';
  import * as RecordRTC from 'recordrtc';
  
  
  import * as Record from 'videojs-record/dist/videojs.record.js';
  
  @Component({
    selector: 'videojs-record',
    template: `
      <style>
      /* change player background color */
      .video-js video {
           background-color: #42f489;
      }
      </style>
      <video id="video_{{idx}}" class="video-js vjs-default-skin" playsinline></video>
      `
  })
  
  export class VideorComponent implements OnInit, OnDestroy {
  
    // reference to the element itself: used to access events and methods
    private _elementRef: ElementRef
  
    // index to create unique ID for component
    idx = 'clip1';
  
    private config: any;
    private player: any; 
    private plugin: any;
  
    // constructor initializes our declared vars
    constructor(elementRef: ElementRef) {
      this.player = false;
  
      // save reference to plugin (so it initializes)
      this.plugin = Record;
  
      // video.js configuration
      this.config = {
        controls: true,
        autoplay: false,
        fluid: false,
        loop: false,
        width: 320,
        height: 240,
        bigPlayButton: false,
        controlBar: {
          volumePanel: false
        },
        plugins: {
          /*
          // wavesurfer section is only needed when recording audio-only
          wavesurfer: {
              backend: 'WebAudio',
              waveColor: '#36393b',
              progressColor: 'black',
              debug: true,
              cursorWidth: 1,
              displayMilliseconds: true,
              hideScrollbar: true,
              plugins: [
                  // enable microphone plugin
                  WaveSurfer.microphone.create({
                      bufferSize: 4096,
                      numberOfInputChannels: 1,
                      numberOfOutputChannels: 1,
                      constraints: {
                          video: false,
                          audio: true
                      }
                  })
              ]
          },
          */
          // configure videojs-record plugin
          record: {
            audio: false,
            video: true,
            debug: true
          }
        }
      };
    }
  
    ngOnInit() {}
  
    // use ngAfterViewInit to make sure we initialize the videojs element
    // after the component template itself has been rendered
    ngAfterViewInit() {
      // ID with which to access the template's video element
      let el = 'video_' + this.idx;
  
      // setup the player via the unique element ID
      this.player = videojs(document.getElementById(el), this.config, () => {
        console.log('player ready! id:', el);
  
        // print version information at startup
        var msg = 'Using video.js ' + videojs.VERSION +
          ' with videojs-record ' + videojs.getPluginVersion('record') +
          ' and recordrtc ' + RecordRTC.version;
        videojs.log(msg);
      });
  
      // device is ready
      this.player.on('deviceReady', () => {
        console.log('device is ready!');
      });
  
      // user clicked the record button and started recording
      this.player.on('startRecord', () => {
        console.log('started recording!');
      });
  
      // user completed recording and stream is available
      this.player.on('finishRecord', () => {
        // recordedData is a blob object containing the recorded data that
        // can be downloaded by the user, stored on server etc.
        console.log('finished recording: ', this.player.recordedData);
      });
  
      // error handling
      this.player.on('error', (element, error) => {
        console.warn(error);
      });
  
      this.player.on('deviceError', () => {
        console.error('device error:', this.player.deviceErrorCode);
      });
    }
  
    // use ngOnDestroy to detach event handlers and remove the player
    ngOnDestroy() {
      if (this.player) {
        this.player.dispose();
        this.player = false;
      }
    }
  
  }

video component.html file:

<!DOCTYPE html>
<html>
<head>
    <base href="/" />
    <title>Angular videojs-record example</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <!-- styles -->
    <link href="node_modules/video.js/dist/video-js.css" rel="stylesheet">
    <!-- videojs.wavesurfer.css is only required when recording audio-only
    <link href="node_modules/videojs-wavesurfer/dist/css/videojs.wavesurfer.css" rel="stylesheet">
    -->
    <link href="node_modules/videojs-record/dist/css/videojs.record.css" rel="stylesheet">
</head>
<body>
    <videojs-record></videojs-record>
</body>
</html>

webpack.externals.js:

const webpack = require('webpack');
module.exports = {
    "externals": {
        "rxjs": "rxjs",
        "@angular/core": "ng.core",
        "@angular/common": "ng.common",
        "@angular/common/http": "ng.common.http",
        "@angular/platform-browser": "ng.platformBrowser",
        "@angular/platform-browser-dynamic": "ng.platformBrowserDynamic",
        "@angular/compiler": "ng.compiler",
        "@angular/elements": "ng.elements",

        // Uncomment and add to scripts in angular.json if needed
        // "@angular/router": "ng.router",
        // "@angular/forms": "ng.forms"
    }
}

Error message:Error: Can't resolve 'videojs' in 'C:\Users\learnerA\stroke-care-project\node_modules\videojs-record\dist'


回答1:


I think the problem is your webpack.alias doesn't get affected. On the other hand, your webpack.config.js is not applied yet. Here is the solution for you:

  • Install the following packages which give you capability to custom webpack:
npm i -D @angular-builders/custom-webpack @angular-builders/dev-server
  • In angular.json file, then change the builder from @angular-devkit/build-angular:browser to @angular-builders/custom-webpack:browser and add the customWebpackConfig:
"build": {
  "builder": "@angular-builders/custom-webpack:browser",
  "options": {
    "customWebpackConfig": {
      // path to your webpack config
      "path": "./webpack.config.js"
    }
  }
}
  • Also in angular.json, replace value of build property from @angular-devkit/build-angular:dev-server to @angular-builders/custom-webpack:dev-server under serve block.
"serve": {
  "builder": "@angular-builders/custom-webpack:dev-server",
}

Regarding to your webpack.config.js, the minimal code to resolve problem is to set alias from video.js -> videojs since videojs-record requires module videojs:

module.exports = {
  resolve: {
    alias: {
      videojs: 'video.js'
    }
  },
}

That's it! Hopefully it would help to resolve your problem.



来源:https://stackoverflow.com/questions/63278288/video-js-in-angular-9-live-video-cant-resolve-videojs-problem

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!