All Products
Search
Document Center

ApsaraVideo VOD:Migrate resources to ApsaraVideo VOD

Last Updated:Aug 05, 2026

ApsaraVideo VOD provides multiple methods to migrate video resources from third-party platforms, Object Storage Service (OSS), or across Alibaba Cloud accounts.

Migration methods

Choose a migration method based on your source resource location and requirements:

Source

Migration method

When to use

Tool

Third-party platform (AWS S3, Azure Blob, etc.)

URL-based batch upload (Recommended)

Resources are publicly accessible via URLs

ApsaraVideo VOD console or API

Third-party platform

SDK/API upload

Require real-time upload feedback

Upload SDK or API

OSS within same Alibaba Cloud account

OSS bucket registration (Recommended)

No need to move data physically

RegisterMedia API

OSS within same Alibaba Cloud account

URL-based batch upload

Need VOD-specific processing

ApsaraVideo VOD API

OSS across Alibaba Cloud accounts

URL-based batch upload

Resources in different accounts

Upload SDK or API

VOD across Alibaba Cloud accounts

URL-based batch upload

Migrate between VOD instances

Upload SDK or API

Key differences:

  • URL-based upload: Best for batch migration of publicly accessible resources. Async process, may take hours to days.

  • SDK upload: Best for real-time uploads requiring immediate feedback. Sync process, faster execution.

  • OSS bucket registration: Best for OSS-to-VOD migration within the same account. No data transfer needed.

Prerequisites

Before you begin, ensure that you have:

  • An active ApsaraVideo VOD service account

  • An AccessKey pair (AccessKey ID and AccessKey Secret) for API authentication

  • (For RAM users) A RAM user with the required VOD permissions (Create a RAM user)

  • Source resource URLs (if using URL-based upload) that remain valid during migration

  • (For OSS migration) Source OSS buckets and objects

Method 1: URL-based batch upload (Recommended)

When to use

Use URL-based batch upload when:

  • Resources are stored remotely (not on local devices) and publicly accessible

  • You need to migrate a large number of files efficiently

  • Resources are in supported regions: China (Shanghai), China (Beijing), China (Shenzhen), Singapore, or US (Silicon Valley)

For other regions, use Method 2 (SDK upload) instead.

Usage notes

  • Asynchronous processing: Batch upload jobs run asynchronously. Large migrations may take hours or days to complete.

  • New media IDs: Each upload creates a new media ID in VOD. UploadMediaByURL does not support specifying a target video ID, so you cannot overwrite an existing or deleted video ID, and the source file of a deleted video cannot be restored through migration. Track the mapping between source file addresses and media IDs for reference.

  • Deleted videos: If a video has been deleted from VOD, migration cannot restore it. Source files removed by calling DeleteMezzanines cannot be recovered either. Before migrating, confirm the status of the source file. To manage or remove videos that were uploaded by mistake, see Delete media files.

  • URL requirements: URLs must include file names with extensions (e.g., https://example.com/video.mp4)

  • URL signing: If your source enables URL signing, ensure URLs remain valid throughout the migration period.

  • Original file stream visibility: If you don't set the TemplateGroupId parameter (the default VOD_NO_TRANSCODE mode), the migrated video's playback addresses show only the "Original quality" stream. To also expose an "Original file" stream, specify a TemplateGroupId for a transcoding template group other than VOD_NO_TRANSCODE.

Procedure

Step 1: Install the VOD SDK

This example uses the ApsaraVideo VOD SDK for Java. For other languages, see VOD SDK overview.

Requirements:

  • JDK 8 or later

  • Maven 3.x or Gradle

Add the dependency to your pom.xml:

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-vod</artifactId>
    <version>2.16.11</version>
</dependency>

Step 2: Prepare source resource URLs

Create a list of all resources to migrate:

  1. Collect download URLs for all files

  2. Ensure URLs include file names and extensions:

    • Correct: https://example.com/videos/intro.mp4

    • Incorrect: https://example.com/download?id=12345 (no file extension)

  3. For signed URLs, verify they remain valid during migration

  4. Test a few URLs to confirm they're accessible

Step 3: Submit batch upload jobs

Call the UploadMediaByURL operation to submit upload jobs. You can test this API using OpenAPI Explorer.

Java example:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.UploadMediaByURLRequest;
import com.aliyuncs.vod.model.v20170321.UploadMediaByURLResponse;

public class UploadByURL {
    public static void main(String[] args) {
        // Read credentials from environment variables
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        String regionId = "cn-shanghai";  // Region where VOD service is activated

        // Initialize VOD client
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        // Create upload request
        UploadMediaByURLRequest request = new UploadMediaByURLRequest();

        // Specify source URLs (comma-separated for multiple files)
        request.setUploadURLs("https://example.com/video1.mp4,https://example.com/video2.mp4");

        // Optional: Specify a transcoding template group. If you don't set this parameter,
        // VOD transcodes the uploaded file using the destination account's default
        // transcoding template group, which may replace the mezzanine file with a
        // transcoded output instead of preserving the original file.
        request.setTemplateGroupId("");

        // Optional: Set metadata for uploaded videos
        request.setUploadMetadatas("[{\"Title\":\"Video 1\"},{\"Title\":\"Video 2\"}]");

        try {
            UploadMediaByURLResponse response = client.getAcsResponse(request);
            System.out.println("Request ID: " + response.getRequestId());
            System.out.println("Upload jobs created:");
            for (UploadMediaByURLResponse.UploadJob job : response.getUploadJobs()) {
                System.out.println("- Job ID: " + job.getJobId());
                System.out.println("  Source URL: " + job.getSourceURL());
            }
        } catch (Exception e) {
            System.err.println("Upload failed: " + e.getMessage());
        }
    }
}
Note

You can use the TemplateGroupId parameter to specify the transcoding template group that controls how the uploaded file is processed after the upload. By default, VOD_NO_TRANSCODE (no transcoding) is used, and the file is displayed as the mezzanine (OD) quality.

Before running the code:

  1. Set environment variables:

    export ALIBABA_CLOUD_ACCESS_KEY_ID="<your-access-key-id>"
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET="<your-access-key-secret>"
    
  2. Replace placeholders:

    • <your-access-key-id>: Your AccessKey ID

    • <your-access-key-secret>: Your AccessKey Secret

    • Update regionId to your VOD service region

    • Replace example URLs with your actual source URLs

  3. Compile and run:

    mvn compile exec:java -Dexec.mainClass="UploadByURL"
    

Step 4: Monitor upload progress

Choose one of the following methods to track upload job status:

Method 1: Event notifications (Recommended)

Configure event notifications to receive callbacks when uploads complete:

  1. Set up HTTP or MNS callbacks in the VOD console (see Event notification overview)

  2. Listen for UploadByURLComplete events

  3. Parse the callback payload to check upload status

Success callback example:

{
  "Status": "success",
  "EventTime": "2026-03-10T09:15:00Z",
  "EventType": "UploadByURLComplete",
  "VideoId": "43q9fjdun3f2a5b",
  "JobId": "4c815bjs83j1d8f",
  "SourceURL": "https://example.com/video.mp4",
  "Size": "123456789"
}

Failure callback example:

{
  "Status": "fail",
  "EventTime": "2026-03-10T09:15:00Z",
  "EventType": "UploadByURLComplete",
  "ErrorCode": "URLInvalidError",
  "ErrorMessage": "Download video failed by the URL, please check it",
  "JobId": "4c815bjsued1f9a",
  "SourceURL": "https://example.com/invalid-video.mp4"
}

Method 2: API polling

Call the GetURLUploadInfos operation periodically to query job status:

GetURLUploadInfosRequest request = new GetURLUploadInfosRequest();
request.setJobIds("job-id-1,job-id-2");  // Comma-separated job IDs

GetURLUploadInfosResponse response = client.getAcsResponse(request);
for (GetURLUploadInfosResponse.UrlUploadJobInfo job : response.getURLUploadInfoList()) {
    System.out.println("Job ID: " + job.getJobId());
    System.out.println("Status: " + job.getStatus());  // NotStarted/Uploading/Success/Failed
    if ("Success".equals(job.getStatus())) {
        System.out.println("Video ID: " + job.getVideoId());
    }
}

For more information, see GetURLUploadInfos.

Verify

After uploads complete:

  1. Check upload job status: Verify all jobs show "Success" status

  2. Confirm video IDs: Ensure each uploaded resource has a corresponding video ID

  3. Test playback: Play sample videos to confirm successful migration

  4. Map source to destination: Record the mapping between source URLs and VOD video IDs for reference


Method 2: SDK upload with self-built service

Use this method when:

  • URL-based upload is not supported in your region

  • You require real-time upload feedback

  • You need to download resources locally before uploading

Scenario A: Upload over internal network

When to use: Your ECS instance and source OSS bucket are in the same region.

Benefits: Faster upload speed, no public network traffic costs.

Prerequisites

  • An ECS instance deployed in the same region as the source OSS bucket

  • Network connectivity between ECS and OSS/VOD services

Procedure

Step 1: Obtain internal network addresses

For OSS resources:

  1. List objects in your OSS bucket (see List objects)

  2. Get the OSS address for each object

  3. Convert to internal network address by adding -internal after the region:

    • OSS address: outin-xxx.oss-cn-shanghai.aliyuncs.com/video.mp4

    • Internal address: outin-xxx.oss-cn-shanghai-internal.aliyuncs.com/video.mp4

For VOD resources:

  1. Call GetMezzanineInfo with OutputType=oss to get OSS addresses (see GetMezzanineInfo)

  2. Convert to internal network addresses using the same method above

Internal network address conversion:

OSS Address

Internal Network Address

bucket.oss-cn-shanghai.aliyuncs.com/file.mp4

bucket.oss-cn-shanghai-internal.aliyuncs.com/file.mp4

bucket.oss-us-west-1.aliyuncs.com/file.mp4

bucket.oss-us-west-1-internal.aliyuncs.com/file.mp4

For more information about internal endpoints, see Access OSS resources from ECS instances by using the internal endpoint of OSS.

Step 2: Deploy upload service on ECS

Deploy your upload service on an ECS instance in the same region as your source resources. Set the regionId parameter to match the ECS region. The upload SDK automatically uses internal network endpoints when the regions match.

Example upload code (Java):

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import java.io.InputStream;
import java.net.URL;

public class InternalNetworkUpload {
    public static void main(String[] args) throws Exception {
        // Read credentials from environment variables
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

        // Internal network URL (obtained in Step 1)
        String internalUrl = "https://bucket.oss-cn-shanghai-internal.aliyuncs.com/video.mp4";

        // Download from internal network URL
        InputStream inputStream = new URL(internalUrl).openStream();

        // Create upload request
        UploadStreamRequest request = new UploadStreamRequest(
            accessKeyId,
            accessKeySecret,
            "Video Title",    // Video title
            "video.mp4",      // File name with extension
            inputStream
        );

        // Set region (must match ECS region for internal network)
        request.setApiRegionId("cn-shanghai");
        request.setEcsRegionId("cn-shanghai");

        // Optional: Specify a transcoding template group. If you don't set this parameter,
        // VOD transcodes the uploaded file using the destination account's default
        // transcoding template group, which may replace the mezzanine file with a
        // transcoded output instead of preserving the original file.
        request.setTemplateGroupId("");

        // Upload
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadStreamResponse response = uploader.uploadStream(request);

        if (response.isSuccess()) {
            System.out.println("Upload successful");
            System.out.println("Video ID: " + response.getVideoId());
        } else {
            System.err.println("Upload failed: " + response.getMessage());
        }
    }
}

For more upload SDK examples, see Upload SDK for Java.

Step 3: Execute batch upload

Run your upload service to migrate all resources using internal network addresses.

Scenario B: Upload over Internet

When to use:

  • You don't have an ECS instance, or your ECS instance is in a different region from source resources

  • Source resources are on third-party platforms (AWS S3, Azure Blob, personal websites, etc.)

Procedure

Step 1: Prepare source file addresses

For VOD resources:

  1. Call SearchMedia to query video IDs (see SearchMedia)

  2. Call GetMezzanineInfo to get source file addresses (see GetMezzanineInfo)

For OSS resources:

  1. List objects in your OSS bucket (see List objects)

  2. Get public URLs for each object

For third-party resources:

  • Collect download URLs from your source platform

Step 2: Deploy upload service

Set up your upload service using the upload SDK. Example code:

import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import java.io.InputStream;
import java.net.URL;

public class InternetUpload {
    public static void main(String[] args) throws Exception {
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

        // Public URL
        String sourceUrl = "https://example.com/video.mp4";

        // Download from source
        InputStream inputStream = new URL(sourceUrl).openStream();

        // Create upload request
        UploadStreamRequest request = new UploadStreamRequest(
            accessKeyId,
            accessKeySecret,
            "Video Title",
            "video.mp4",
            inputStream
        );

        request.setApiRegionId("cn-shanghai");  // VOD service region

        // Upload
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadStreamResponse response = uploader.uploadStream(request);

        if (response.isSuccess()) {
            System.out.println("Video ID: " + response.getVideoId());
        }
    }
}

Step 3: Track source-to-destination mappings (Recommended)

To manage videos after migration, record mappings between source URLs and VOD video IDs. You can:

  • Write mappings to a database

  • Store mappings in logs

  • Include source URLs in video metadata using the UserData parameter during upload

Step 4: Organize migrated resources (Optional)

After migration, organize your videos based on the mappings. Use VOD APIs to:

  • Update video titles and descriptions

  • Add tags and categories

  • Set thumbnails and cover images

For more information, see UpdateVideoInfo.


Method 3: Register OSS buckets (Same account only)

When to use

Use this method to migrate OSS resources to VOD within the same Alibaba Cloud account without physically moving data. This is the fastest and most cost-effective method for same-account migration.

Limitations

  • Storage class: Only Standard OSS buckets are supported

  • Bucket quota: Maximum 10 OSS buckets per region can be added to VOD

  • Account restriction: Source OSS and destination VOD must belong to the same Alibaba Cloud account

Procedure

Step 1: Add OSS bucket to VOD

Add the source OSS bucket to your VOD service:

  1. Log on to the ApsaraVideo VOD console

  2. In the left-side navigation pane, choose Configuration Management > Media Management > Storage

  3. Click Add Storage

  4. Select your OSS bucket and configure permissions

  5. Click OK

For detailed steps, see Manage VOD storage.

Step 2: Register media resources

Register OSS objects as VOD media assets using the RegisterMedia API:

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.RegisterMediaRequest;
import com.aliyuncs.vod.model.v20170321.RegisterMediaResponse;

public class RegisterOSSMedia {
    public static void main(String[] args) throws Exception {
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

        DefaultProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        RegisterMediaRequest request = new RegisterMediaRequest();

        // Specify OSS file URL (must include OSS domain name)
        request.setRegisterMetadatas(
            "[{\"FileURL\":\"https://bucket-name.oss-cn-hangzhou.aliyuncs.com/video/example.mp4\"," +
            "\"Title\":\"Example Video\"}]"
        );

        RegisterMediaResponse response = client.getAcsResponse(request);
        System.out.println("Registered video IDs:");
        for (RegisterMediaResponse.RegisteredMedia media : response.getRegisteredMediaList()) {
            System.out.println("- " + media.getMediaId());
        }
    }
}

Key parameters:

  • FileURL: Full OSS path including domain name (e.g., https://bucket.oss-cn-hangzhou.aliyuncs.com/path/to/video.mp4)

  • Title: Video title in VOD

For more information, see RegisterMedia.

Verify

After registration:

  1. Check media library: Verify registered videos appear in the VOD console

  2. Test playback: Play registered videos to confirm they're accessible

  3. Verify metadata: Check video titles and attributes match your expectations


Best practices

Migration planning

  • Estimate migration time: URL-based batch upload is asynchronous. Large migrations (1000+ files) may take hours to days.

  • Batch size: Split large migrations into batches of 100-500 files for better tracking and error recovery.

  • Network bandwidth: Consider your network bandwidth when choosing between internal network and Internet upload.

Cost optimization

  • Use internal network: When migrating OSS resources in the same region, use internal network addresses to avoid public network traffic costs.

  • Register instead of upload: For same-account OSS-to-VOD migration, use bucket registration (Method 3) to avoid upload costs and time.

Resource management

  • Track mappings: Always record the mapping between source URLs and VOD video IDs for future reference.

  • Metadata migration: Include video metadata (title, tags, description) during upload to avoid manual updates later.

  • Cleanup: After verifying successful migration, delete source resources to reduce storage costs (if no longer needed).

Error handling

  • URL validity: Ensure signed URLs remain valid throughout the migration period.

  • Retry failed jobs: Monitor upload job status and retry failed uploads with corrected URLs.

  • Validation: Test upload with a small sample before migrating large volumes.


Troubleshooting

URL-based upload fails

Symptom: Upload job status shows "Failed" in the callback or API response.

Common causes:

  • URL not accessible: Source URL returns 403/404 error

    • Solution: Verify the URL is publicly accessible. If using signed URLs, check the signature hasn't expired.

  • Invalid URL format: URL doesn't include file name or extension

    • Solution: Ensure URLs follow the format https://domain.com/path/file.mp4

  • Region not supported: Source region doesn't support URL-based upload

    • Solution: Use Method 2 (SDK upload) instead

SDK upload performance is slow

Symptom: Upload takes longer than expected.

Common causes:

  • Network bandwidth limitation: Limited upload bandwidth

    • Solution: Use internal network upload (Scenario A) if ECS and source are in the same region

  • File size: Large video files take longer to upload

    • Solution: Consider compressing videos before upload, or use multipart upload for files over 100 MB

RegisterMedia fails

Symptom: API returns error when registering OSS objects.

Common causes:

  • OSS bucket not added: Bucket hasn't been added to VOD

    • Solution: Complete Step 1 to add the OSS bucket to VOD first

  • Invalid FileURL: URL format is incorrect

    • Solution: Ensure FileURL includes the full OSS domain name (e.g., https://bucket.oss-cn-hangzhou.aliyuncs.com/video.mp4)

  • Permission denied: VOD doesn't have permission to access the OSS bucket

    • Solution: Grant VOD read permission to your OSS bucket in the VOD console


Next steps