You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic 3 Native Camera插件选视频后无法上传至服务器咨询

Fixing Video Upload Issues with Ionic 3 Native Camera on Android

Hey there, let's work through this video upload problem you're facing. It's a super common quirk with the Ionic Camera plugin on Android, so let's break down why it's happening and how to fix it.

First, Why Isn't destinationType Behaving As Expected?

For video files, the Camera plugin on Android intentionally ignores the DATA_URL setting (and sometimes defaults to returning a file path even when FILE_URI is set) because video files are typically large. Returning a base64-encoded string via DATA_URL would eat up way too much memory, leading to performance issues or crashes. So the plugin defaults to a file path/URI instead—this is actually a good thing, we just need to handle it correctly for uploads.

Step-by-Step Solution to Upload the Video

Since you can preview the video using the path, we know the file exists. The key is converting that file path into a Blob or File object that you can send to your server via HTTP. Here's how to do it:

1. Install Required Plugins

You'll need the Camera plugin (which you already have) plus the File plugin to read the file from device storage:

ionic cordova plugin add cordova-plugin-file
npm install @ionic-native/file

Ensure you're using Angular's HttpClient module for uploads (it's included in Ionic 3 by default, just confirm it's imported in your app module).

2. Adjust Your Camera Call Code

Update your camera options to explicitly target video, and stick with FILE_URI (since DATA_URL won't work for videos anyway):

import { Camera, CameraOptions } from '@ionic-native/camera';
import { File } from '@ionic-native/file';
import { HttpClient, HttpHeaders } from '@angular/common/http';

constructor(
  private camera: Camera,
  private file: File,
  private http: HttpClient
) {}

selectVideo() {
  const cameraOptions: CameraOptions = {
    sourceType: this.camera.PictureSourceType.PHOTOLIBRARY, // Use CAMERA if recording directly
    mediaType: this.camera.MediaType.VIDEO,
    destinationType: this.camera.DestinationType.FILE_URI,
    allowEdit: false,
    quality: 80 // Lower quality = smaller file size, adjust as needed
  };

  this.camera.getPicture(cameraOptions).then(fileUri => {
    // Convert the file URI to a Blob for upload
    this.convertFileUriToBlob(fileUri).then(blob => {
      this.uploadVideoToServer(blob);
    }).catch(err => console.error('Error converting file:', err));
  }).catch(err => console.error('Camera error:', err));
}

3. Convert File URI to Blob

This function handles both file:// URIs and newer content:// URIs (common on Android 10+) to read the file into a Blob:

private convertFileUriToBlob(fileUri: string): Promise<Blob> {
  // Handle content:// URIs (Android 10+ storage access)
  if (fileUri.startsWith('content://')) {
    return this.file.resolveLocalFilesystemUrl(fileUri)
      .then(entry => (entry as FileEntry).file())
      .then(file => {
        return new Promise((resolve, reject) => {
          const reader = new FileReader();
          reader.onloadend = () => {
            const blob = new Blob([reader.result as ArrayBuffer], { type: file.type });
            resolve(blob);
          };
          reader.onerror = reject;
          reader.readAsArrayBuffer(file);
        });
      });
  }

  // Handle file:// URIs
  const filePath = fileUri.replace('file://', '');
  const folderPath = filePath.substring(0, filePath.lastIndexOf('/'));
  const fileName = filePath.substring(filePath.lastIndexOf('/') + 1);

  return this.file.readAsArrayBuffer(folderPath, fileName)
    .then(buffer => {
      // Use the correct MIME type (adjust if you support other video formats)
      const mimeType = 'video/mp4';
      return new Blob([buffer], { type: mimeType });
    });
}

4. Upload the Blob to Your Server

Use FormData to send the Blob to your server—this is the standard way to upload files via HTTP:

private uploadVideoToServer(videoBlob: Blob) {
  const formData = new FormData();
  // Append the video blob with a filename (use original name if you want to preserve it)
  formData.append('video', videoBlob, 'uploaded-video.mp4');

  // Set up headers (omit Content-Type—browsers set it automatically for FormData)
  const headers = new HttpHeaders({
    'Accept': 'application/json'
    // Add auth headers here if needed, e.g., 'Authorization': 'Bearer ' + yourAuthToken
  });

  this.http.post('https://your-server-endpoint.com/upload', formData, { headers })
    .subscribe(response => {
      console.log('Upload successful!', response);
      // Add your success logic here (e.g., show a toast message)
    }, error => {
      console.error('Upload failed:', error);
      // Handle errors (e.g., display an error alert)
    });
}

Critical Android Permissions & Config

Don't forget to set up necessary permissions in config.xml to access files and the camera:

<!-- Basic permissions -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<!-- For Android 10+ to access legacy storage -->
<platform name="android">
  <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
    <application android:requestLegacyExternalStorage="true" />
  </edit-config>
</platform>

Key Notes

  • Avoid DATA_URL for videos: It's not feasible for large files—stick with FILE_URI.
  • Test on real devices: Emulators can have file system quirks, so always test on a physical Android device.
  • Check server-side handling: Ensure your server accepts multipart/form-data uploads (most backend frameworks support this out of the box).

内容的提问来源于stack exchange,提问作者Junaid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:12:38