用戶端操作
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,所以,如果不想使用臨時token,請將其設定為NULL。
- 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