với tính năng Chèn quảng cáo động (DAI) để bắt đầu kiếm tiền từ các luồng video nội dung bằng quảng cáo.
Chọn giải pháp DAI mà bạn quan tâm
DAI phân phát nhóm
SDK IMA giúp đơn giản hoá việc tích hợp quảng cáo đa phương tiện vào trang web và ứng dụng của bạn.
SDK IMA có thể yêu cầu quảng cáo từ mọi máy chủ quảng cáo tuân thủ VAST và quản lý việc phát quảng cáo trong ứng dụng của bạn.
Với SDK DAI của IMA, các ứng dụng sẽ tạo yêu cầu phát trực tuyến cho quảng cáo và video nội dung cho VOD hoặc nội dung phát trực tiếp. Sau đó, SDK sẽ trả về một luồng video kết hợp, nhờ đó bạn không phải quản lý việc chuyển đổi giữa quảng cáo và video nội dung trong ứng dụng của mình.
Hướng dẫn này minh hoạ cách phát một luồng Phân phát nhóm DAI bằng cách sử dụng IMA DAI SDK cho CAF.
Trước khi sử dụng hướng dẫn này, hãy làm quen với giao thức Web Receiver của Khung ứng dụng Chromecast. Hướng dẫn này giả định rằng bạn hiểu rõ các khái niệm cơ bản về bộ nhận CAF, chẳng hạn như trình chặn thông báo và các đối tượng mediaInformation, cũng như quen thuộc với việc sử dụng Công cụ điều khiển và chỉ đạo truyền để mô phỏng một bộ gửi CAF.
Để sử dụng cơ chế Phân phát nhóm DAI của IMA, bạn phải hợp tác với một đối tác Phân phát nhóm và phải có tài khoản Ad Manager 360 Advanced. Nếu bạn có tài khoản Ad Manager, hãy liên hệ với người quản lý tài khoản để biết thêm thông tin chi tiết. Để biết thông tin về cách đăng ký Ad Manager, hãy truy cập vào Trung tâm trợ giúp của Ad Manager.
Để biết thông tin về cách tích hợp với các nền tảng khác hoặc cách sử dụng SDK phía máy khách IMA, hãy xem SDK quảng cáo trên phương tiện truyền thông tương tác.
Tổng quan về cơ chế Phân phát nhóm DAI của IMA
Việc triển khai tính năng Phân phát nhóm bằng IMA CAF DAI SDK bao gồm 2 thành phần chính, được minh hoạ trong hướng dẫn này:
StreamRequest
: Một đối tượng xác định yêu cầu phát trực tuyến đến các máy chủ quảng cáo của Google. Các yêu cầu chỉ định Mã mạng, Khoá tài sản tuỳ chỉnh và khoá API không bắt buộc, cũng như các tham số không bắt buộc khác.StreamManager
: Một đối tượng xử lý hoạt động giao tiếp giữa luồng video và IMA DAI SDK, chẳng hạn như kích hoạt ping theo dõi và chuyển tiếp các sự kiện luồng đến nhà xuất bản.
Điều kiện tiên quyết
- Tài khoản Cast Developer Console có các thiết bị kiểm thử đã đăng ký.
- Một ứng dụng web receiver được lưu trữ đã đăng ký với Cast Developer Console và có thể sửa đổi để lưu trữ mã do hướng dẫn này cung cấp.
- Một ứng dụng gửi được định cấu hình để sử dụng ứng dụng nhận web của bạn. Để phục vụ mục đích của ví dụ này, hãy sử dụng công cụ Lệnh truyền và điều khiển làm ứng dụng gửi.
Định cấu hình các đối tượng MediaInfo của người gửi
Trước tiên, hãy định cấu hình đối tượng MediaInfo
của ứng dụng người gửi để thêm các trường sau:
Trường | Nội dung | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
Giá trị nhận dạng duy nhất của mục nội dung nghe nhìn này.
CONTENT_ID |
||||||||||
contentUrl
|
Không bắt buộc. URL dự phòng của sự kiện phát trực tiếp để phát nếu sự kiện phát trực tiếp DAI không tải được.
BACKUP_STREAM_URL |
||||||||||
contentType
|
Không bắt buộc. Loại MIME của các luồng sao lưu nội dung. Chỉ cần cho luồng DASH.
CONTENT_STREAM_MIMETYPE |
||||||||||
streamType
|
Chuỗi ký tự hoặc hằng số được dùng cho giá trị này sẽ thay đổi tuỳ theo nền tảng của người gửi. | ||||||||||
customData
|
Trường customData chứa một khoá-giá trị của các trường bắt buộc bổ sung. Trong mẫu này, nó chứa các thông số luồng DAI của bạn. Trong ứng dụng phát hành chính thức, thay vào đó, bạn có thể truyền một giá trị nhận dạng mà ứng dụng nhận truyền sẽ dùng để truy xuất các tham số này bằng một yêu cầu phía máy chủ.
|
Sau đây là một số mẫu mã giúp bạn bắt đầu:
Web
Để định cấu hình các giá trị này trong một trình gửi web Cast, trước tiên, hãy tạo một đối tượng MediaInfo
có dữ liệu bắt buộc, sau đó đưa ra một yêu cầu tải cho trình nhận web.
// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "CONTENT_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
daiStreamType: "DAI_STREAM_TYPE",
networkCode: "NETWORK-CODE",
customAssetKey: "CUSTOM_ASSET_KEY",
apiKey: "API_KEY"
};
// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
() => { console.log('Load succeed'); },
(errorCode) => { console.log('Error code: ' + errorCode); });
Android
Để định cấu hình các giá trị này trong một trình gửi web Cast, trước tiên, hãy tạo một đối tượng MediaInfo bằng dữ liệu bắt buộc, sau đó thực hiện một yêu cầu tải đến trình nhận web.
JSONObject customData = new JSONObject()?
.put("daiStreamType", "DAI_STREAM_TYPE")
.put("networkCode", "NETWORK-CODE")
.put("customAssetKey", "CUSTOM_ASSET_KEY")
.put("apiKey", "API_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
.setContentUrl("BACKUP_STREAM_URL")
.setContentType("CONTENT_STREAM_MIMETYPE")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setCustomData(customData)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
iOS (Obj-C)
Để định cấu hình các giá trị này trong một trình gửi web Cast, trước tiên, hãy tạo một đối tượng GCKMediaInformation
có dữ liệu bắt buộc, sau đó đưa ra một yêu cầu tải cho trình nhận web.
NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
@"daiStreamType": @"DAI_STREAM_TYPE",
@"networkCode": @"NETWORK-CODE",
@"customAssetKey": @"CUSTOM_ASSET_KEY",
@"apiKey": @"API_KEY"};
mediaInfoBuilder.customData = customData;
GCKMediaInformationBuilder *mediaInfoBuilder =
[[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];
GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
request.delegate = self;
}
iOS (Swift)
Để định cấu hình các giá trị này trong một trình gửi web Cast, trước tiên, hãy tạo một đối tượng GCKMediaInformation
có dữ liệu bắt buộc, sau đó đưa ra một yêu cầu tải cho trình nhận web.
let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
print("invalid mediaURL")
return
}
let customData = [
"daiStreamType": "DAI_STREAM_TYPE",
"networkCode": "NETWORK-CODE",
"customAssetKey": "CUSTOM_ASSET_KEY",
"region": "API_KEY"
]
let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = @"CONTENT_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()
guard let mediaInfo = mediaInformation else {
print("invalid mediaInformation")
return
}
if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia
(mediaInfo) {
request.delegate = self
}
Công cụ CAC
Để định cấu hình các giá trị này trong công cụ Lệnh và quyền kiểm soát Cast, hãy nhấp vào thẻ Tải nội dung nghe nhìn rồi đặt loại yêu cầu tải tuỳ chỉnh thành LOAD. Sau đó, hãy thay thế dữ liệu JSON trong vùng văn bản bằng JSON này:
{
"media": {
"contentId": "CONTENT_ID",
"contentUrl": "BACKUP_STREAM_URL",
"contentType": ""CONTENT_STREAM_MIMETYPE"",
"streamType": "LIVE",
"customData": {
"daiStreamType": "DAI_STREAM_TYPE",
"networkCode": "NETWORK-CODE",
"customAssetKey": "CUSTOM_ASSET_KEY",
"oAuthToken": "API_KEY"
}
}
}
Bạn có thể gửi yêu cầu tải tuỳ chỉnh này đến máy thu để kiểm thử các bước còn lại.
Tạo một trình nhận CAF cơ bản
Tạo một trình nhận tuỳ chỉnh cho web, như trong Hướng dẫn về trình nhận tuỳ chỉnh cho web của CAF SDK.
Mã của bộ nhận sẽ có dạng như sau:
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
</script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
// ...
</script>
</body>
</html>
Nhập IMA DAI SDK và lấy Trình quản lý trình phát
Thêm một thẻ tập lệnh để nhập IMA DAI SDK cho CAF vào trình nhận web của bạn, ngay sau khi tập lệnh tải CAF. Trong thẻ tập lệnh, hãy lưu trữ ngữ cảnh của trình nhận và trình quản lý trình phát dưới dạng hằng số trước khi khởi động trình nhận.
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
castContext.start();
</script>
</body>
</html>
Khởi chạy Trình quản lý luồng phát IMA
Khởi chạy Trình quản lý luồng phát IMA.
<html>
<head>
<script type="text/javascript"
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
castContext.start();
</script>
</body>
</html>
Tạo Stream Manager Load Interceptor
Trước khi các mục nội dung nghe nhìn được truyền đến CAF, hãy tạo yêu cầu phát trực tuyến trong một trình chặn thông báo LOAD.
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
/**
* Creates a livestream request object for a Pod Serving stream.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => { /* ... */};
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithPodStreamData) => {
console.log('Successfully made DAI stream request.');
// ...
return castRequestWithPodStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, createDAICastRequest);
castContext.start();
Tạo yêu cầu phát trực tiếp
Hoàn tất hàm createStreamRequest
để tạo một luồng Phân phát nhóm dựa trên yêu cầu tải CAF.
/**
* Creates a livestream request object for a Pod Serving stream.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => {
const customData = castRequest.media.customData;
let streamRequest;
if (customData.daiStreamType == "LIVE") {
streamRequest = new google.ima.cast.dai.api.PodStreamRequest();
streamRequest.customAssetKey = customData.customAssetKey;
streamRequest.networkCode = customData.networkCode;
streamRequest.apiKey = customData.apiKey;
} else if (customData.daiStreamType == "VOD") {
streamRequest = new google.ima.cast.dai.api.PodVodStreamRequest();
streamRequest.networkCode = customData.networkCode;
streamRequest.apiKey = customData.apiKey;
}
return streamRequest;
};
Truy xuất tệp kê khai được ghép từ VTP
Nếu yêu cầu phát trực tiếp của bạn thành công, hãy sử dụng streamManager.getStreamId()
để truy xuất mã nhận dạng của luồng phát. Đối tác công nghệ video (VTP) hoặc trình thao tác tệp kê khai tuỳ chỉnh sẽ cung cấp hướng dẫn để truy xuất URL tệp kê khai bằng mã nhận dạng luồng phát này.
Sau khi bạn truy xuất URL của tệp kê khai, hãy thay thế contentUrl
hiện có bằng manifestUrl
mới.
Cuối cùng, trước khi trả về tệp kê khai luồng đã sửa đổi, hãy gọi phương thức loadStreamMetadata
trên streamManager
để thông báo cho SDK IMA rằng SDK này có thể yêu cầu siêu dữ liệu luồng một cách an toàn. Lệnh gọi này chỉ cần thiết cho luồng VOD.
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithPodStreamData) => {
console.log('Successfully made DAI stream request.');
// This is a sample VTP integration. Consult your VTP documentation
// for how to retrieve an ad-stitched stream manifest URL.
const manifestTemplate = "https://.../manifest.m3u8?gam_stream_id=[[STREAMID]]";
const streamId = streamManager.getStreamId();
const manifestUrl = manifestTemplate.replace('[[STREAMID]]', streamId)
// Assign your manifestUrl to the request's content URL.
castRequestWithPodStreamData.media.contentUrl = manifestUrl;
// After generating the manifest URL, VOD streams must notify the
// IMA SDK that it is safe to request ad pod metadata.
// This is only necessary for VOD streams. It is a no-op for
// livestreams, so no conditional is needed.
streamManager.loadStreamMetadata();
return castRequestWithPodStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
Dọn dẹp các thành phần DAI của IMA
Khi đã hoàn tất việc yêu cầu và hiển thị quảng cáo trong luồng Phân phát theo nhóm bằng SDK DAI của IMA, bạn nên dọn dẹp mọi tài nguyên sau khi phiên Phân phát theo nhóm hoàn tất. Gọi StreamManager.destroy()
để dừng phát nội dung phát trực tiếp, dừng tất cả hoạt động theo dõi quảng cáo và giải phóng tất cả các thành phần nội dung phát trực tiếp đã tải.