Use o SDK de upload para Android do ApsaraVideo VOD para enviar arquivos de mídia de um dispositivo local para o armazenamento do ApsaraVideo VOD. Este tópico descreve como integrar o SDK, configure uploads e tratar erros.
Pré-requisitos
|
Item |
Requisito |
|
Versão mínima do Android |
API 14 (Android 4.0) |
|
Versão de compilação |
|
|
Conta Alibaba Cloud |
Obtida Ative ApsaraVideo VOD |
|
Service de autorização |
Service de backend capaz de emitir credenciais de upload ( |
Limites de uso
O SDK para Android permite o upload de áudio, vídeo e imagens. Não há suporte para upload de recursos de mídia auxiliares.
Integrar o SDK
Adicionar a dependência do SDK
Adicione o repositório Maven do Alibaba Cloud ao arquivo build.gradle no nível do projeto:
allprojects {
repositories {
maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
}
}
Adicione a dependência do SDK ao arquivo build.gradle no nível do módulo:
dependencies {
implementation 'com.aliyun.video.android:upload:2.0.1'
}
O SDK subjacente do OSS para Android é incluído transitivamente pela dependência api do VODUpload. Não é necessário declará-lo novamente.
Configuração do projeto
Declare as permissões necessárias no arquivo AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Android 13+ granular media permissions, declare as needed -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
Se você ativar a ofuscação de código, adicione as seguintes regras ao arquivo proguard-rules.pro:
-keep class com.alibaba.sdk.android.vod.upload.v2.** { *; }
-keep interface com.alibaba.sdk.android.vod.upload.v2.** { *; }
O SDK subjacente do OSS para Android já inclui regras ProGuard integradas. Não é necessário declará-las novamente.
Uso básico
Tratamento de callbacks
O SDK de upload (v2) usa um callback assíncrono unificado VODGetAuthCallback para solicitar credenciais de upload à camada de negócios. O SDK invoca getAuth nos cenários abaixo e usa VODAuthContext.getKind() para indicar o tipo de credencial necessária:
|
Tipo |
Gatilho |
Operação OpenAPI a ser chamada |
|
|
Primeiro upload de um arquivo de vídeo |
|
|
|
Upload retomável / atualização de credencial |
|
|
|
Upload de imagem |
A camada de negócios precisa apenas passar a resposta JSON bruta da OpenAPI do backend diretamente para o SDK, sem modificações. O SDK lê as chaves pelos nomes exatos dos campos da OpenAPI (diferencia maiúsculas de minúsculas):
|
Tipo |
Campos obrigatórios |
|
|
|
|
|
|
Não renomeie os campos. Renomear campos para videoId, imageUrl ou image_url faz com que o SDK os interprete como null.
O exemplo a seguir mostra uma implementação de getAuth que trata cada tipo:
VODGetAuthCallback getAuth = (ctx, completion) -> {
switch (ctx.getKind()) {
case CREATE_VIDEO:
yourBackend.createUploadVideo(ctx.getFileName(), ctx.getFileSize(),
json -> completion.onSuccess(json),
err -> completion.onFailure("BIZ.CREATE_VIDEO", err.getMessage()));
break;
case REFRESH_VIDEO:
yourBackend.refreshUploadVideo(ctx.getVideoId(),
json -> completion.onSuccess(json),
err -> completion.onFailure("BIZ.REFRESH_VIDEO", err.getMessage()));
break;
case CREATE_IMAGE:
yourBackend.createUploadImage(ctx.getFileName(),
json -> completion.onSuccess(json),
err -> completion.onFailure("BIZ.CREATE_IMAGE", err.getMessage()));
break;
}
};
Inicializar a instância de upload
Use VODUploadConfig.Builder para construir a configuração e chame VODUploadClient.create(...) para crie uma instância de upload:
import com.alibaba.sdk.android.vod.upload.v2.*;
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth) // Required: authentication callback. For more information, see "Callback handling".
.build();
VODUploadClient uploader = VODUploadClient.create(context, config);
A instância uploader é reutilizável. Use a mesma instância para enviar vários arquivos simultaneamente. Chame uploader.dispose() para liberar recursos quando o ciclo de vida terminar.
Controle de upload
Chame upload(...) para iniciar um upload. O método retorna um identificador VODUploadTask que permite cancele o upload:
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setTags("demo")
.setCateId(1000)
.build();
VODUploadOptions options = new VODUploadOptions.Builder()
.setVideoMeta(meta)
.setOnProgress((percent, uploaded, total) ->
Log.d("Upload", String.format("%.1f%%", percent * 100)))
.build();
VODUploadTask task = uploader.upload(filePath, options, new VODUploadResultCallback() {
@Override public void onSuccess(VODUploadResult r) {
Log.i("Upload",
"videoId=" + r.getVideoId()
+ " uploadTaskId=" + r.getUploadTaskId()
+ " etag=" + r.getEtag()
+ " requestId=" + r.getRequestId()
+ " durationMs=" + r.getDurationMs());
}
@Override public void onFailure(VODUploadError e) {
Log.e("Upload", e.getErrorCode() + " : " + e.getErrorMessage(), e.getCause());
}
});
// Cancel the upload midway. Resumable upload is enabled by default. The next upload(...) call for the same file automatically resumes the upload.
task.cancel();
// task.getUploadTaskId() can be used to correlate logs or integrate with analytics.
upload(...) oferece duas sobrecargas que aceitam caminhos de arquivo e URIs content:// (compatíveis com o Scoped Storage do Android 10+):
uploader.upload(String filePath, VODUploadOptions options, VODUploadResultCallback callback);
uploader.upload(Uri fileUri, VODUploadOptions options, VODUploadResultCallback callback);
Upload de imagem: O SDK usa automaticamente o caminho de upload de imagem com base na extensão do nome do arquivo (jpg / jpeg / png / gif / bmp / webp / heic) ou quando options.imageMeta != null. No callback de sucesso, result.getImageId() e result.getImageUrl() contêm valores válidos:
VODImageMeta imgMeta = new VODImageMeta.Builder()
.setImageType("cover")
.setTitle("Cover")
.build();
uploader.upload("/sdcard/cover.jpg",
new VODUploadOptions.Builder().setImageMeta(imgMeta).build(),
callback);
Configurações avançadas
Aceleração de upload
Defina VODVideoMeta.userData com o JSON a seguir. O servidor VOD retorna automaticamente o endpoint de aceleração de transferência global do OSS (oss-accelerate.aliyuncs.com) ao emitir o UploadAddress. O SDK envia diretamente para o endpoint de aceleração:
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setUserData("{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}")
.build();
A aceleração de upload depende da aceleração de transferência global do OSS. Ative a aceleração de transferência para o bucket no console do OSS. Para mais informações, consulte Access OSS using transfer acceleration.
Upload e transcodificação
Especifique um grupo de modelos de transcodificação ou fluxo de trabalho por meio de VODVideoMeta:
VODVideoMeta meta = new VODVideoMeta.Builder()
.setTitle("My Video")
.setDescription("Video description")
.setCoverUrl("https://example.com/cover.jpg")
.setCateId(1000)
.setTags("tag1,tag2")
.setStorageLocation("<Optional: custom storage region>")
.setTemplateGroupId("<Your template group ID>") // transcoding template group
.setWorkflowId("<Your workflow ID>") // Workflow (optional)
.setAppId("<Optional: application ID>")
.build();
VODVideoMeta aceita os seguintes campos: title / description / coverUrl / cateId / tags / userData / storageLocation / templateGroupId / workflowId / appId. Todos os campos são opcionais e repassados para CreateUploadVideo.
Após a conclusão do upload, o servidor VOD transcodifica o vídeo source com base no grupo de modelos de transcodificação. Se não desejar acionar a transcodificação, passe um grupo de modelos "sem transcodificação" na chamada CreateUploadVideo do seu backend.
Timeout e nova tentativa
Configure o timeout e o número de novas tentativas para requisições ao OSS:
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setTimeout(60 * 1000) // Unit: milliseconds. Default: 60s
.setMaxRetryCount(2) // Default: 2
.build();
timeout controla o timeout de conexão e leitura/escrita para uma única requisição ao OSS (em milissegundos). maxRetryCount defina o número de novas tentativas para uma requisição ao OSS em caso de exceções de rede.
Versão da assinatura
Especifique a versão da assinatura do OSS:
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setSignature("v4") // Default: "v4". Options: "v1"
.build();
A assinatura V4 do OSS é a versão recomendada. A partir de 1º de setembro de 2025, buckets recém-criados devem usar a assinatura V4. Recomenda-se também que clientes existentes migrem o quanto antes. Defina "v1" explicitamente apenas se o seu bucket ainda suportar exclusivamente a assinatura V1.
Upload retomável
Por padrão, o upload retomável está ativado. O SDK usa a tríade (lastModified, fileName, fileSize) como chave de upload retomável e a persiste automaticamente no SharedPreferences.
|
Cenário |
Comportamento do SDK |
|
Chamada de |
O registro de upload retomável é mantido. A próxima chamada |
|
Falha do aplicativo / encerramento do processo |
O registro de upload retomável é mantido. A próxima chamada |
|
Alteração na impressão digital do arquivo |
O arquivo é tratado como novo e enviado do zero. |
|
Expiração do uploadId do OSS |
O SDK limpa automaticamente o registro antigo e inicia um novo upload via |
Para desativar o upload retomável:
new VODUploadConfig.Builder().setGetAuth(getAuth).setCheckpoint(false).build();
Upload multipart
Use partSize para controlar o tamanho das partes e parallel para defina o número de partes simultâneas:
// Global configuration
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setPartSize(1024 * 1024) // Default: 1 MB
.setParallel(4) // Default: 4
.build();
// Override for a single task
VODUploadOptions options = new VODUploadOptions.Builder()
.setVideoMeta(meta)
.setPartSize(2 * 1024 * 1024)
.setParallel(6)
.build();
Definir a região do service VOD
Especifique a região do service ApsaraVideo VOD:
new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setRegion("cn-shanghai") // Default: cn-shanghai
.build();
Para obter a lista de regiões suportadas, consulte ApsaraVideo VOD region IDs.
Relatório de dados
Por padrão, o SDK ativa a instrumentação do caminho de upload para monitoramento da qualidade do product. Apenas métricas de tempo de execução do processo de upload são coletadas. O conteúdo do arquivo não é coletado. Para desativar o relatório de dados:
VODUploadConfig config = new VODUploadConfig.Builder()
.setGetAuth(getAuth)
.setReportEnabled(false) // Default: true
.build();
Tratamento de erros
VODUploadError estende java.lang.Exception. Os códigos de erro seguem o formato de três segmentos UPLOAD.{LAYER}.{TYPE}:
|
CAMADA |
Código de erro |
Descrição |
|
AUTH |
|
Falha no callback |
|
AUTH |
|
Falha ao decodificar |
|
AUTH |
|
A credencial expirou. |
|
OSS |
|
Acesso negado ao OSS (problema de permissão/assinatura). |
|
OSS |
|
O bucket não existe. |
|
OSS |
|
O uploadId expirou. O SDK reverte automaticamente para um novo upload. |
|
OSS |
|
Falha no upload do OSS. |
|
OSS |
|
Falha na mesclagem multipart do OSS. |
|
NETWORK |
|
Timeout de rede. |
|
NETWORK |
|
Rede inacessível. |
|
FILE |
|
O arquivo não existe. |
|
FILE |
|
O arquivo está vazio. |
|
CANCEL |
|
O usuário cancelou o upload. |
|
INTERNAL |
|
A instância foi descartada. |
|
INTERNAL |
|
Configuração inválida. |
Métodos públicos de VODUploadError:
String getErrorCode()— Retorna o código de erro.String getErrorMessage()— Retorna a mensagem de erro.String getUploadTaskId()— Retorna o ID da tarefa de upload.String getSuggestion()— Retorna a sugestão de correção integrada do SDK.Throwable getCause()— Retorna a exceção subjacente do OSS (herdada deException).
O exemplo a seguir trata erros com base no código de erro:
@Override public void onFailure(VODUploadError e) {
if (e.getErrorCode().startsWith("UPLOAD.AUTH.")) {
// Prompt the user to check backend authentication
} else if (VODUploadError.OSS_UPLOAD_FAILED.equals(e.getErrorCode())) {
// Retry or prompt the user to check the network
}
Log.e(TAG, e.getErrorCode() + ": " + e.getErrorMessage()
+ " (suggestion=" + e.getSuggestion() + ")", e.getCause());
}
Perguntas frequentes
Posso iniciar vários uploads simultaneamente?
Sim. Cada task é independente. Como prática recomendada, controle o número de uploads simultâneos conforme as condições da rede para evitar amplificar a pressão sobre a largura de banda de upstream quando combinado com parallel.
O upload retomável não funciona após cancelar e reenviar
Verifique os seguintes pontos:
Confirme se o caminho do arquivo é o mesmo.
Verifique se os valores
lastModifiedesizedo arquivo não foram alterados.Certifique-se de que
config.checkpointesteja definido comotrue.Verifique se o uploadId expirou. Quando a resposta for
NoSuchUpload, o SDK reverte automaticamente para um novo upload. Esse comportamento é esperado.
Quais são os valores de fileName e fileSize ao enviar uma URI content://?
O SDK lê OpenableColumns.DISPLAY_NAME e OpenableColumns.SIZE por meio de ContentResolver.query(...). Se não for possível ler o tamanho, UPLOAD.FILE.EMPTY será retornado.
O que getCause() retorna?
O valor retornado herda de Exception e preserva a exceção subjacente do OSS, seja ServerException, ClientException ou IOException, o que facilita a solução detalhada de problemas.