Introducción
Los clips son vídeos creados a partir de segmentos de otros vídeos generados por Brightcove Social y otras herramientas. Si los clips se crean para compartirlos a través de Brightcove Social, es posible que desee eliminar sus copias para reducir el almacenamiento administrado o deshabilitarlas para evitar que aparezcan en los flujos de trabajo de vídeo.
Búsqueda de clips
Hay términos de búsqueda especiales para ayudarle CMS API a localizar clips en su cuenta:
q=%2Bis_clip:true
- devuelve solo clipsq=%2Dis_clip:true
- devuelve sólo los que no son clipsq=%2Bis_clip:false
- devuelve sólo los que no son clips (funcionalmente idénticos al elemento anterior)q=%2Bclip_source_video_id: video_id
- devuelve clips generados a partir del vídeo especificado
Ejemplo
Solicitud
https://cms.api.brightcove.com/v1/accounts/57838016001/videos?q=%2Bis_clip:true
Respuesta
[
{
"id": "5235328819001",
"account_id": "57838016001",
"ad_keys": null,
"clip_source_video_id": "4752143002001",
"complete": true,
"created_at": "2016-12-04T17:06:20.562Z",
"cue_points": [],
"custom_fields": {
"subject": "Birds"
},
"delivery_type": "static_origin",
"description": null,
"digital_master_id": "5235339325001",
"duration": 24042,
"economics": "AD_SUPPORTED",
"folder_id": null,
"geo": null,
"has_digital_master": true,
"images": {
"thumbnail": {
"asset_id": "5235341448001",
"remote": false,
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/2025/57838016001_5235341448001_5235328819001-th.jpg?pubId=57838016001&videoId=5235328819001",
"sources": [
{
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/2025/57838016001_5235341448001_5235328819001-th.jpg?pubId=57838016001&videoId=5235328819001",
"height": 90,
"width": 160
},
{
"src": "https://brightcove.hs.llnwd.net/v2/unsecured/media/57838016001/201612/2025/57838016001_5235341448001_5235328819001-th.jpg?pubId=57838016001&videoId=5235328819001",
"height": 90,
"width": 160
}
]
},
"poster": {
"asset_id": "5235339121001",
"remote": false,
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/2025/57838016001_5235339121001_5235328819001-vs.jpg?pubId=57838016001&videoId=5235328819001",
"sources": [
{
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/2025/57838016001_5235339121001_5235328819001-vs.jpg?pubId=57838016001&videoId=5235328819001",
"height": 360,
"width": 640
},
{
"src": "https://brightcove.hs.llnwd.net/v2/unsecured/media/57838016001/201612/2025/57838016001_5235339121001_5235328819001-vs.jpg?pubId=57838016001&videoId=5235328819001",
"height": 360,
"width": 640
}
]
}
},
"link": null,
"long_description": null,
"name": "greatblueheron.mp4 - Clip-2016-12-04",
"original_filename": "2efadac9-8e36-423c-b988-afcf2cd23c49.mov",
"projection": null,
"published_at": "2016-12-04T17:06:20.562Z",
"reference_id": null,
"schedule": null,
"sharing": null,
"state": "ACTIVE",
"tags": [
"newtag"
],
"text_tracks": [],
"updated_at": "2016-12-04T17:08:41.944Z"
},
{
"id": "5235312567001",
"account_id": "57838016001",
"ad_keys": null,
"clip_source_video_id": "5220368996001",
"complete": true,
"created_at": "2016-12-04T17:07:58.450Z",
"cue_points": [],
"custom_fields": {
"subject": "Birds"
},
"delivery_type": "static_origin",
"description": "Mother and child owls...",
"digital_master_id": "5235341452001",
"duration": 39253,
"economics": "AD_SUPPORTED",
"folder_id": null,
"geo": null,
"has_digital_master": true,
"images": {
"thumbnail": {
"asset_id": "5235339124001",
"remote": false,
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/1897/57838016001_5235339124001_5235312567001-th.jpg?pubId=57838016001&videoId=5235312567001",
"sources": [
{
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/1897/57838016001_5235339124001_5235312567001-th.jpg?pubId=57838016001&videoId=5235312567001",
"height": 90,
"width": 160
},
{
"src": "https://brightcove.hs.llnwd.net/v2/unsecured/media/57838016001/201612/1897/57838016001_5235339124001_5235312567001-th.jpg?pubId=57838016001&videoId=5235312567001",
"height": 90,
"width": 160
}
]
},
"poster": {
"asset_id": "5235341824001",
"remote": false,
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/1897/57838016001_5235341824001_5235312567001-vs.jpg?pubId=57838016001&videoId=5235312567001",
"sources": [
{
"src": "http://brightcove.vo.llnwd.net/v1/unsecured/media/57838016001/201612/1897/57838016001_5235341824001_5235312567001-vs.jpg?pubId=57838016001&videoId=5235312567001",
"height": 540,
"width": 960
},
{
"src": "https://brightcove.hs.llnwd.net/v2/unsecured/media/57838016001/201612/1897/57838016001_5235341824001_5235312567001-vs.jpg?pubId=57838016001&videoId=5235312567001",
"height": 540,
"width": 960
}
]
}
},
"link": null,
"long_description": null,
"name": "Great Horned Owl - Clip-2016-12-04",
"original_filename": "c0640095-e696-41ea-8e7e-2ebf4d090d69.mov",
"projection": null,
"published_at": "2016-12-04T17:07:58.450Z",
"reference_id": null,
"schedule": null,
"sharing": null,
"state": "ACTIVE",
"tags": [
"bird",
"nature",
"air"
],
"text_tracks": [],
"updated_at": "2016-12-04T17:09:16.967Z"
}
]
Eliminación de Activos
Si no va a utilizar sus clips para otro propósito que no sea compartir los sitios en redes sociales, puede que desee reducir el almacenamiento administrado eliminando activos de ellos. En términos de almacenamiento, las representaciones marcan la mayor diferencia, pero también puede eliminar carteles y miniaturas, si lo desea (esto también ayudaría a identificar los clips de Studio como no son vídeos de uso general).
Para eliminar activos, utilizará los extremos de activos de la API de CMS. La lógica es simple: primero OBTENGA los activos para recuperar sus identificadores en el sistema de Video Cloud y, a continuación, ELIMINARLOS:
Por lo general, solo habrá un solo póster y miniatura para eliminar, pero generalmente habrá varias copias, por lo que si va a hacer esto mediante programación, tendrá que recorrer la matriz de objetos devueltos por la solicitud de copias GET y eliminar las copias una por una. A continuación se presentan los puntos finales de API relevantes y algunos códigos de muestra (JavaScript + un proxy escrito en PHP para hacer las solicitudes de API) para realizar las tareas de eliminación de los activos.
Endpoints de activos
Estos son los puntos finales de activos relevantes que necesitará para eliminar activos. Para todos estos extremos, la URL base es:
https://cms.api.brightcove.com/v1/accounts
Variantes de representación
OBTENER copias
/account_id/videos/video_id/assets/renditions
SUPRIMIR una copia
/account_id/videos/video_id/assets/renditions/rendition_id
Carteles
GET carteles
/account_id/videos/video_id/assets/poster
ELIMINAR un póster
/account_id/videos/video_id/assets/poster/poster_id
Miniaturas
OBTENER miniaturas
/account_id/videos/video_id/assets/thumbnail
ELIMINAR una miniatura
/account_id/videos/video_id/assets/thumbnail/thumbnail_id
Aplicación de muestra
A continuación se muestra el código de ejemplo de una aplicación que encuentra todos los clips de una cuenta y, a continuación, elimina todas las copias, así como el póster y la miniatura de cada clip.
HTML
<fieldset>
<legend>Inputs</legend>
<p>Account id: <input type="text" name="account_id" id="account_id" value=""></p>
<p>Client id: <input type="text" name="client_id" id="client_id" value=""></p>
<p>Client secret: <input type="text" name="client_secret" id="client_secret" value=""></p>
<p><button id="goBtn">Remove all clip assets</button></p>
</fieldset>
<h2>Results</h2>
<pre id="status"></pre>
JavaScript
var BCLS = (function (window, document) {
/**
* this scripts assumes that HTML elements with ids shown
* in the following assignments exist in the page that
* calls this script.
* Alternatively, store the client_id and client_secret
* in the proxy (NOT in a client-side script!)
* and the account_id value here
*/
var account_id = document.getElementById('account_id'),
client_id = document.getElementById('client_id'),
client_secret = document.getElementById('client_secret'),
status = document.getElementById('status'),
goBtn = document.getElementById('goBtn'),
videoCount = 0,
videoNumber = 0,
totalCalls = 0,
callNumber = 0,
renditionNumber = 0,
videoData = [],
renditionData = [],
posterData = {},
thumbnailData = {};
/**
* sets up all API requests and handles the responses
* @param {String} type the request type
*/
function setUpRequest(type) {
var baseURL = 'https://cms.api.brightcove.com/v1/accounts',
endpoint,
responseDecoded,
// recommended limit value for best performance with CMS API
limit = 25,
options = {};
options.client_id = (client_id.value) ? client_id.value : null;
options.client_secret = (client_secret.value) ? client_secret.value : null;
switch (type) {
// get a count of clips
case 'getCount':
endpoint = '/' + account_id.value + '/counts/videos?q=%2Bis_clip:true';
options.url = baseURL + endpoint;
options.requestType = 'GET';
makeRequest(options, function(response) {
if (response) {
responseDecoded = JSON.parse(response);
videoCount = parseInt(responseDecoded.count);
// calculate total calls needed to get the video clips
totalCalls = Math.ceil(videoCount / limit);
setUpRequest('getVideoClips');
}
});
break;
// retrieve the clips
case 'getVideoClips':
endpoint = '/' + account_id.value + '/videos?q=%2Bis_clip:true&limit=' + limit + '&offset=' + (limit * callNumber);
options.url = baseURL + endpoint;
options.requestType = 'GET';
makeRequest(options, function(response) {
if (response) {
responseDecoded = JSON.parse(response);
// add new clips to videoData array
videoData.push.apply(videoData, responseDecoded);
}
// increment the call number
callNumber++;
// are we done?
if (callNumber < totalCalls) {
// get the next batch
setUpRequest('getVideoClips');
} else {
// got all the clips
// update status
status.textContent =+ videoData.length + ' video clips found \n';
// reset the callNumber
callNumber = 0;
setUpRequest('getRenditions');
}
});
break;
case 'getRenditions':
endpoint = '/' + account_id.value + '/videos/' + videoData[videoNumber].id + '/assets/renditions';
options.url = baseURL + endpoint;
options.requestType = 'GET';
// update status
status.textContent =+ 'fetching renditions for clip ' + videoData[callNumber].name + ' \n';
makeRequest(options, function(response) {
if (response) {
responseDecoded = JSON.parse(response);
renditionData = responseDecoded;
// update status
status.textContent =+ renditionData.length + ' renditions found for clip ' + videoData[callNumber].name + ' \n';
if (renditionData.length > 0) {
setUpRequest('deleteRendition');
} else {
setUpRequest('getPoster');
}
} else {
// no renditions
status.textContent =+ 'no renditions found for clip number ' + videoData[callNumber].name + ' \n';
setUpRequest('getPoster');
}
});
break;
case 'deleteRendition':
endpoint = '/' + account_id.value + '/videos/' + videoData[videoNumber].id + '/assets/renditions/' + renditionData[renditionNumber].id;
options.url = baseURL + endpoint;
options.requestType = 'DELETE';
makeRequest(options, function(response) {
// there should be no response unless there was an error
if (response) {
status.textContent += 'Delete rendition response: ' + response + ' \n';
// keep going anyway
renditionNumber++;
if (renditionNumber < renditionData.length) {
setUpRequest('deleteRendition');
} else {
// done with renditions, do poster
setUpRequest('getPoster');
}
} else {
status.textContent += 'Rendition deleted for ' + videoData[callNumber].name + '\n';
renditionNumber++;
// check to see if there are more renditions
if (renditionNumber < renditionData.length) {
setUpRequest('deleteRendition');
} else {
// do the poster
setUpRequest('getPoster');
}
}
});
break;
case 'getPoster':
endpoint = '/' + account_id.value + '/videos/' + videoData[videoNumber].id + '/assets/poster';
options.url = baseURL + endpoint;
options.requestType = 'GET';
makeRequest(options, function(response) {
if (response) {
posterData = JSON.parse(response);
setUpRequest('deletePoster');
} else {
// no poster, do the thumbail
setUpRequest('getThumbnail');
}
});
break;
case 'deletePoster':
endpoint = '/' + account_id.value + '/videos/' + videoData[videoNumber].id + '/assets/poster/' + posterData.id;
options.url = baseURL + endpoint;
options.requestType = 'DELETE';
makeRequest(options, function(response) {
// no response unless something went wront
if (response) {
status.textContent += 'Delete poster response: ' + response + ' \n';
// try thumbnail anyway
setUpRequest('getThumbnail');
} else {
// success; do thumbnail
status.textContent += 'Poster deleted for ' + videoData[callNumber].name + ' \n';
setUpRequest('getThumbnail');
}
});
break;
case 'getThumbnail':
endpoint = '/' + account_id.value + '/videos/' + videoData[callNumber].id + '/assets/thumbnail';
options.url = baseURL + endpoint;
options.requestType = 'GET';
makeRequest('options', function(response) {
if (response) {
thumbnailData = JSON.parse(response);
setUpRequest('deleteThumbnail');
} else {
// if no thumbnail, go on
videoNumber++;
if (videoNumber < videoCount) {
setUpRequest('getRenditions');
} else {
// done
status.textContent += 'Finished!';
}
}
});
break;
case 'deleteThumbnail':
endpoint = '/' + account_id.value + '/videos/' + videoData[videoNumber].id + '/assets/thumbnail/' + thumbnailData.id;
options.url = baseURL + endpoint;
options.requestType = 'DELETE';
makeRequest(options, function(response) {
// no response unless something went wrong
if (response) {
status.textContent += 'Delete thumbnail response: ' + response + ' \n';
// do next video anyway if any
videoNumber++;
if (videoNumber < videoCount) {
setUpRequest('getRenditions');
} else {
// done
status.textContent += 'Finished!';
}
} else {
// success
status.textContent += 'Thumbnail deleted for ' + videoData[callNumber].name + ' \n';
// do next video if any
videoNumber++;
if (videoNumber < videoCount) {
setUpRequest('getRenditions');
} else {
// done
status.textContent += 'Finished!';
}
}
});
break;
default:
if (console) {
console.log('default case: we should not be here');
}
}
}
/**
* send API request to the proxy
* @param {Object} requestData options for the request
* @param {Function} [callback] callback function
*/
function makeRequest(options, callback) {
var httpRequest = new XMLHttpRequest(),
response,
requestParams,
dataString,
proxyURL = 'https://solutions.brightcove.com/bcls/bcls-proxy/clips-proxy.php',
// response handler
getResponse = function() {
try {
if (httpRequest.readyState === 4) {
if (httpRequest.status >= 200 && httpRequest.status < 300) {
response = httpRequest.responseText;
console.log('raw response', response);
// some API requests return '{null}' for empty responses - breaks JSON.parse
if (response === '{null}') {
response = null;
}
// return the response
callback(response);
} else {
alert('There was a problem with the request. Request returned ' + httpRequest.status);
}
}
} catch (e) {
alert('Caught Exception: ' + e);
}
};
/**
* set up request data
* the proxy used here takes the following request body:
* JSON.stringify(options)
*/
// set response handler
httpRequest.onreadystatechange = getResponse;
// open the request
httpRequest.open('POST', proxyURL);
// set headers if there is a set header line, remove it
// open and send request
httpRequest.send(JSON.stringify(options));
}