OSS Media-C SDK分为客户端、服务端和HLS三部分。本文主要介绍客户端的相关操作。
接口
客户端相关的操作接口都位于oss_media_file.h中,目前提供以下接口:
- oss_media_file_open
- oss_media_file_stat
- oss_media_file_tell
- oss_media_file_seek
- oss_media_file_read
- oss_media_file_write
- oss_media_file_close
下面会详细介绍各个接口的功能和注意事项。
基础结构体介绍
/** * OSS MEDIA FILE的元数据,包括文件长度,位置和类型 */ typedef struct { int64_t length; int64_t pos; char *type; } oss_media_file_stat_t; /** * OSS MEDIA FILE的属性信息 */ typedef struct oss_media_file_s { void *ipc; char *endpoint; int8_t is_cname; char *bucket_name; char *object_key; char *access_key_id; char *access_key_secret; char *token; char *mode; oss_media_file_stat_t _stat; time_t expiration; auth_fn_t auth_func; } oss_media_file_t;
说明
- type:文件类型,Normal或者Appendable。
- ipc:用于设置设备的唯一标识,根据用户的需要可以在auth func中使用,如果用不到则可以忽略。
- endpoint:比如oss-cn-hangzhou.aliyuncs.com。
- is_cname:是否使用了CNAME。
- bucket_name:OSS上存储空间的名称。
- object_key:OSS上文件的名称。
- access_key_id:阿里云提供的访问控制的access key id,有以下两种使用方式。
- 使用主账号或者子账号的永久access key id,此时后面的token需要设置为NULL。
- 使用通过get_token获取的临时access key id。
- access_key_secret:阿里云提供的访问控制的access key secret,有以下两种使用方式。
- 使用主账号或者子账号的永久access key secret,此时后面的token需要设置为NULL。
- 使用通过get_token获取到的临时access key secret。access_key_id和access_key_secret必须同时使用同种方式。
- token:
- 如果使用了主账号或子账号的永久access key id和access key secret,这里需要设置为NULL。
- 如果是终端设备上传、下载资源,可以通过服务端的get_token获取临时的access_key_id、access_key_secret和token。
- 如果设置token不为NULL,则用户使用的是临时access key id、临时access key secrety和临时token。
- expiration:授权失效的时间,超出失效时间后才会再次授权。
- auth:授权函数,用户需要实现的一个函数,且在这个函数内为host、bucket、token等赋值。
- mode:读写模式。
初始化
/** * @brief 初始化oss media * @note 在程序开始的时候应该首先调用此接口,初始化OSS MEDIA C SDK * @return: * 返回0时表示成功 * 否则, 表示出现了错误,可能导致失败的原因包括:内存不足,apr、curl版本太低等 */ int oss_media_init(aos_log_level_e log_level);
说明 示例代码请参考
GitHub 。
销毁
/** * @brief 销毁oss meida * @note 在程序结束的时候应该最后调用此接口,销毁OSS MEDIA C SDK */ void oss_media_destroy();
说明 示例代码请参考
GitHub。
打开文件
/** * @brief 打开一个oss文件 * @param[in] bucket_name oss上存储文件的存储空间名称 * @param[in] object_key oss上的文件名称 * @param[in] mode: * 'r': 读模式 * 'w': 覆盖写模式 * 'a': 追加写模式 * notes: 不允许组合使用 * @param[in] auth_func 授权函数,设置access_key_id/access_key_secret等 * @return: * 返回非NULL时成功,否则失败 */ oss_media_file_t* oss_media_file_open(char *bucket_name, char *object_key, char *mode, auth_fn_t auth_func);
说明
- mode支持只读、覆盖写、追加写三种模式,不支持组合模式。
- 只读模式:打开文件后,一次读取部分文件内容,完整内容一般需要多次读取。
- 覆盖写:打开文件后,一次写入完整的文件内容,可以多次写入,且最后一次写入的内容会覆盖前面写入的内容。
- 追加写:打开文件后,可以多次追加写文件。
- 示例代码请参考GitHub
关闭文件
/** * @brief 关闭oss文件 */ void oss_media_file_close(oss_media_file_t *file);
说明 示例代码请参考
GitHub。
写文件
/** * @brief 写文件到oss上 * @return: * 成功时返回写入的数据大小,返回-1表示写失败 */ int64_t oss_media_file_write(oss_media_file_t *file, const void *buf, int64_t nbyte);
示例程序:
/* 授权函数 */ static void auth_func(oss_media_file_t *file) { file->endpoint = "your endpoint"; file->is_cname = 0; file->access_key_id = "阿里云提供的access key id或者临时access key id"; file->access_key_secret = "阿里云提供的access key secret或者临时access key secret"; file->token = "通过get_token接口获取到得临时token"; /* 本次授权的有效时间 */ file->expiration = time(NULL) + 300; } static void write_file() { oss_clean(g_filename); int64_t write_size; oss_media_file_t *file; char *bucket_name = "<your bucket name>"; char *key = "<your object key>"; char *content = "aliyun oss media c sdk"; /* 打开一个文件 */ file = oss_media_file_open(bucket_name, key, "w", auth_func); if (!file) { printf("open media file failed\n"); return; } /* 写文件 */ write_size = oss_media_file_write(file, content, strlen(content)); if (-1 != write_size) { printf("write %" PRId64 " bytes succeeded\n", write_size); } else { oss_media_file_close(file); printf("write failed\n"); return; } /* 关闭文件,释放资源 */ oss_media_file_close(file); }
说明
- 上述示例中,打开文件的模式为
覆盖写("w")
,如果多次写入,后一次写入的内容会覆盖前一次写入的内容。如果需要追加写,则指定打开文件的模式为追加写("a")
。 - 示例代码请参考GitHub。
读文件
/** * @brief 读取固定数目nbyte的数据 * @note buf的大小应该大于等于nbyte + 1 * @return: * 返回0时表示成功 * 否则, 返回-1时表示出现了错误,可能导致失败的原因包括:不是以读模式打开的文件,无法连接OSS,无权限读OSS等 */ int64_t oss_media_file_read(oss_media_file_t *file, void *buf, int64_t nbyte);
示例程序:
int ntotal, nread, nbuf = 16; char buf[nbuf]; char *content; char *bucket_name = "<your bucket name>"; char *key = "<your object key>"; oss_media_file_t *file; /* 打开文件 */ file = oss_media_file_open(bucket_name, key, "r", auth_func); if (!file) { printf("open media file failed\n"); return; } /* 读文件 */ content = malloc(stat.length + 1); ntotal = 0; while ((nread = oss_media_file_read(file, buf, nbuf)) > 0) { memcpy(content + ntotal, buf, nread); ntotal += nread; } content[ntotal] = '\0'; /* 关闭文件 */ oss_media_file_close(file); free(content); printf("oss media c sdk read object succeeded\n"); }
说明 示例代码请参考
GitHub。
管理文件
OSS Media File也支持tell、seek和stat操作。
/** * @brief 获取当前OSS MEDIA FILE的位置 * @return: * 返回0时表示成功 * 否则, 返回-1时表示出现了错误,可能导致失败的原因包括:不是以读模式打开的文件,无法连接OSS,无权限读OSS等 */ int64_t oss_media_file_tell(oss_media_file_t *file); /** * @brief 设置OSS MEDIA FILE的指针到指定位置 * @return: * 返回0时表示成功 * 否则, 返回-1时表示出现了错误,可能导致失败的原因包括:不是以读模式打开的文件,无法连接OSS,无权限读OSS等 */ int64_t oss_media_file_seek(oss_media_file_t *file, int64_t offset); /** * @brief 获取OSS MEDIA FILE的元数据 * @return: * 返回0时表示成功 * 否则, 返回-1时表示出现了错误,可能导致失败的原因包括:无法连接OSS,无权限读OSS等 */ int oss_media_file_stat(oss_media_file_t *file, oss_media_file_stat_t *stat);
示例程序:
static void seek_tell_stat_file() { int ntotal, nread, nbuf = 16; char buf[nbuf]; char *bucket_name = "<your bucket name>"; char *key = "<your object key>"; oss_media_file_t *file; /* 打开文件 */ file = oss_media_file_open(bucket_name, key, "r", auth_func); if (!file) { printf("open media file failed\n"); return; } /* 获取文件meta信息 */ oss_media_file_stat_t stat; if (0 != oss_media_file_stat(file, &stat)) { oss_media_file_close(file); oss_media_file_free(file); printf("stat media file[%s] failed\n", file->object_key); return; } printf("file [name=%s, length=%ld, type=%s]", file->object_key, stat.length, stat.type); /* tell */ printf("file [position=%" PRId64 "]", oss_media_file_tell(file)); /* seek */ oss_media_file_seek(file, stat.length / 2); /* 关闭文件 */ oss_media_file_close(file); printf("oss media c sdk seek object succeeded\n"); }
说明 示例代码请参考
GitHub。