How to capture video and play it back?

I’m using the ionic native MediaCapture to record a video, and then display it. However, I can not figure out how to play back the video just recorded.

In my page:

takeVideo() {
    let options: CaptureVideoOptions = { limit: 1 };
    MediaCapture.captureVideo(options)
      .then((data: MediaFile[]) => {
        console.log(data);
        var i, path, len;
        for (i = 0, len = data.length; i < len; i += 1) {
          console.log(path);
          // data[i].fullPath = "file:/storage/extSdCard/DCIM/Camera/20160827_225041.mp4"
          // data[i].localURL = "cdvfile://localhost/root/storage/extSdCard/DCIM/Camera/20160827_225041.mp4"
          // How do I display this video to the user?
          this.videoFilePath = data[i].fullPath;
        }
      },
      (err: CaptureError) => {
        console.error(err);
      }
      );
  }

I’m trying to display it with this tag, but I see only an empty player control. It can not access the file.

<video id="resource-video" controls="controls" autoplay="false" [src]="videoFilePath">
  Your browser does not support the video tag.
</video>

I’ve tried both the “fullPath” which uses the file:/ protocol, as well as the localURL which uses the cdvfile:// protocol. Do I need to modify the path string, or is there a content policy I need to enable, or is there a different approach altogether I need to be using?

Thanks!

To answer my own question…

The problem was that I was using live reload to test on my device, and apparently the local file:/ references will not work (I presume because the index.html is being served from a remote host, i.e. my dev machine).
Second problem is that on ios I had to prefix the fullPath as returned from the capture with “file://” in order to get it to load the video.
So without live reload (running ionic without the -l switch) and by prefixing the fullPath with “file://” if not already in the string, I am able to capture and playback local video files.

I would still appreciate any advice on how to get it working with live reload.

Hi Randbrown,

Do you know now how to use “controls” to control the video ? For example, make a function to make it playing, make it pausing etc…

I’m using the integrated controls of the <video> tag.

@randbrown, have you had any solution about the inability to display captured video inside the video tag for typescript? Pls. I need help with that. I am stucked with the problem for days now.

I got it to work by not using ionic’s live reload feature, and by adjusting the file paths. See my previous post from Aug 30

Pls. thanks for your prompt reply. What you are implying is that I should run it on a physical device with the same code. Secondly what do you mean by adjusting the file paths? I count on your assistance already. Thanks.

It appears my previously working code no longer works on Android 6.0. Now I get access denied errors when trying to access the local files in a video tag. Any suggestions? Is it just me or is it supposed to be this difficult to capture and display a video on the local device? Shouldn’t this be the easy case?

were you able to find a solution to the access denied issue?

@nylex yes I got it working. Perhaps there is a better way, but here is what I did for displaying a local video file:

In the controller typescript, import the sanitizer:

import { DomSanitizer } from '@angular/platform-browser'

Inject the sanitizer:
constructor(private sanitizer: DomSanitizer) { ... }

Sanitize the native file URL:
this.safeUrl = this.sanitizer.bypassSecurityTrustUrl(this.fileEntry.nativeURL);

In the html:

  <video id="resource-video" controls="controls" [src]="safeUrl">
    Your browser does not support the video tag.
  </video>

Hi Nylex

Check the Diagnostics native plugin and the part about requesting run time access to the external storage.

@abaadmin: The solution you provided with the DomSanitizer, is it for displaying video while in reload, or when it runs normally as installed application?

Because also when I record video in Android (6.0) the file is there, I have not access-issue, but still the component will not play my video. Although it loads it and displays to me its duration, etc.

Has anyone made a recorded video work with HTML video player?

Thank you
Costas

I’m struggling with this issue as well (ERR_ACCESS_DENIED) although I’ve already used the DomSanitizer. Did you guys managed to solved this now? many thanks

This how I do it:

Because the Native Diagnostic plugin does not provide request for External storage access, you have to directly access the cordova.plugins in Windows object.

public requestExternalStorageAuthorization(){
    window.cordova.plugins.diagnostic.requestRuntimePermission(
          (status:string)=>{           /*on success do... */            }, 
          ()=>{           /*on error do ... */            },
          window.cordova.plugins.diagnostic.permission.READ_EXTERNAL_STORAGE
        );
}

Before that you might also want to request Camera authorization. This time you may use Ionic’s native wrapper for Diagnostic.

           import { Diagnostic } from 'ionic-native';

            Diagnostic.requestCameraAuthorization()
                .then((data:any)=>{
                    //on success do...
                })
                .catch((err:any)=>{
                    //on error do...
                })

Hi @killerchip,

Thanks for your reply. I have no issue on capturing video, only on the playback. Also, in my AndroidManifest.xml, there’s already the permission to read and write to external storage:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

Do i still need the Diagnostic plugin for this?

I think I get it now. My application actually captures photo and video. If I capture only video using the MediaCapture plugin, the video playback fails with Access Denied. However, if I capture/upload photo first (which then request for permission for Camera and READ_EXTERNAL_STORAGE) then capture video, the video now plays.

Hi @dcrow

To my understanding (and tests) you need to call the .requestRuntimePermission, because it requests at run-time the access to external storage (to access the video). This is something that is needed for Android 6.0 and above.

Hi @killerchip,

Yep, I’ve followed your advice on calling requestCameraAuthorization when capturing video only. Many thanks man :slight_smile:

Hi @dcrow,

I’m struggling on playing a video from the storage location on Android. I was able to get granted permissions to READ_EXTERNAL_STORAGE. But my video still doesn’t load. I must miss something. Could you share some code that plays a video ?

Here is my html (I’ve tried a lot of combinations with/without source, mimetype, extension…):
> < video width=“400px” height=“300px” autoplay controls>

        < source src="file:///storage/emulated/0/Android/data/com.ionicframework.playground458460/files/video.mp4" type="video/webm"></video>

My file has the right path (I use FileTransfer to download the video to the storage)

Thank you for your help

Maybe you can try this one

html

<video controls="controls" preload="metadata" autoplay="autoplay" webkit-playsinline="webkit-playsinline" width="300" height="300" class="videoPlayer">
    <source [src]="safeUrl" type="video/mp4"/>
</video>

ts file

import { DomSanitizer, SafeUrl } from ‘@angular/platform-browser’

sanitizer: DomSanitizer;
safeUrl: SafeUrl;

then
this.videoUrl = //your video file path here
this.safeUrl = this.sanitizer.bypassSecurityTrustUrl(this.videoUrl);