Using media transforms

Sometimes there is a need to alter a media item before beginning playback. Some example of this could be:

  • Request an authorization token to append to the stream url
  • A server side ad service which accepts some parameters then returns a dynamically generated stream url
  • A feed is provided by a third party service which does not match AMP's Media interface akamai.amp.Media

A media transform can be any function that excepts a media object, and returns a media object:

// synchronous transform
amp.addTransform(akamai.amp.TransformType.MEDIA, function (media) {
  media.src += "&testing=1234";
  return media;
});

A Promise can also be returned if the transform performs any asynchronous operations: returns a media object:

// asynchronous transform
amp.addTransform(akamai.amp.TransformType.MEDIA, function (media) {
  return new Promise(function (resolve, reject) {
    media.src += "&hello=world";
    resolve(media);
  });
});

For advanced use cases a formal transform object can be provided, based on the akamai.amp.Transform interface. This can be any object that contains a property called transform which is a function:

// asynchronous transform
amp.addTransform(akamai.amp.TransformType.MEDIA, {
  priority: 100,
  transform: function (media) {
    return new Promise(function (resolve, reject) {
      media.src += "&hello=world";
      resolve(media);
    });
  }
});

Using a transform object allows for a priority to be set. Transforms with higher priorities are executed first. Additionally, transforms cascade allowing transformations to occur on both the downstream and upstream:

// cascading transform
amp.addTransform(akamai.amp.TransformType.MEDIA, function (media, next) {
  return new Promise(function (resolve, reject) {
    var start = Date.now()
    // allow other transforms to be executed before completing this function
    next(media)
      .then(function (result) {
        result.src += "&elapsed=" + (Date.now() - start);
        resolve(result);
      })
  });
});

Calling the next() function suspends the transform and passes control to the next function in the list. When the other transforms have completed, the function resumes.