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…

1 Like

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.

1 Like

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

1 Like

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>
1 Like

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...
                })
1 Like

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);