Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Renderer method used on all mediaType #3231

Closed
jdelhommeau opened this issue Oct 25, 2018 · 22 comments
Closed

Renderer method used on all mediaType #3231

jdelhommeau opened this issue Oct 25, 2018 · 22 comments

Comments

@jdelhommeau
Copy link
Collaborator

Type of issue

Bug

Description

When running multiple mediaType on a single adUnit (for example: outstream + banner) and you need to use client side renderer for the video outstream, the renderer will also try to render banner ad, not just outstream ad. Ideally, there is a way to either have a way in renderer to fallback on default renderer, OR the renderer is only called for video ad returned.

Steps to reproduce

1 - Build an adUnit for video and banner mediaType that delivers both video and banner creative
2 - define manual renderer
3 - run. When a banner ad is returned, the rendering fails because of missing information (bid.adResponse is missing on banner)

Test page

http://jdelhommeau.devnxs.net/POC/VIDEO/prebid_outstream_banner_plct.html

Expected results

Way to fallback on default renderer when in renderer method OR renderer is only used when video mediatype is returned

Actual results

Renderer is called all the time for all mediaType and fails when not video

Platform details

Other information

@benjaminclot
Copy link
Contributor

benjaminclot commented Oct 27, 2018

@jdelhommeau
You could do something like this:

pbjs.onEvent("bidWon", function(bid) {
  if (/* condition */) {
    bid.renderer = {
      url: rendererUrl,
      render: rendererFn
    };
  }
});

@pkayfire
Copy link

pkayfire commented Mar 4, 2019

Any updates here? This is a pretty big issue with anyone that wants to run a multi-format placement with banner + outstream video.

@benjaminclot not sure the workaround works 100% of the time. In my case the renderer URL did not load.

@benjaminclot
Copy link
Contributor

@pkayfire I use a fake URL as rendererUrl because my rendererFn is already available. It's just that renderer requires a URL parameter.

@jaiminpanchal27
Copy link
Collaborator

Here is possible solution to this bug:
Renderer module is not tied to any particular format, even though it is only used for outstream by Prebid adapters as of now.

Prebid core installs renderer on bid response if renderer is present on adUnit. See here

We can add renderer property inside mediaTypes.<format> object in case of multi-format. By doing this Prebid core will be able to find out for which format it needs to install renderer.

This will not be a breaking change, as we will support existing feature as well where renderer is directly added at the topmost level in adUnit. Maybe we can remove that in 3.0

@mkendall07 @bretg Your thoughts.

@mkendall07
Copy link
Member

what if we just associated a renderer with every bid, and for banner the renderer is simply the "renderAd" function that is standard for banner?

@jdelhommeau
Copy link
Collaborator Author

I really like @jaiminpanchal27 idea of having ability to assign renderer per mediaType.
That would also allow people to add renderer for native (when not using an adserver for example) or to add renderer for specific banner case (skin).
We would also need to have a way in the custom renderer function to passback to default renderer from prebid. That way, you could have stuff like:

renderer for display: function(bid){

if (bid.width == 1800 and bid.height == 1000) { // skin case
// apply css / js code for correct rendering of skin creative
}
defaultRendererFunction();
}

That would be a huge improvement over current way of implementing such format.

@pkayfire
Copy link

pkayfire commented Mar 6, 2019

For the sake of speed it could make sense to go with the solution by @mkendall07 and have the renderer per mediaType be a follow-up feature.

@Hamper
Copy link
Contributor

Hamper commented Jan 27, 2020

Multiformat auctions still can't be used with custom renderer?

@jdelhommeau
Copy link
Collaborator Author

@pkayfire and @mkendall07 was there any updates on this ticket? Has support for different renderer per mediaType been improved?

@patmmccann
Copy link
Collaborator

patmmccann commented Aug 20, 2020

So if a publisher were to define types in the ad unit renderer like this

pbjs.addAdUnit({ code: 'video1', mediaTypes: { video: { context: 'outstream', playerSize: [640, 480] } }, renderer: { url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', types: ['video'], render: function (bid) { ANOutstreamVideo.renderAd({ targetId: bid.adUnitCode, adResponse: bid.adResponse, }); } }, ... });

and https://github.com/prebid/Prebid.js/blob/master/src/auction.js#L515 was modified from if (adUnitRenderer && adUnitRenderer.url) { bidObject.renderer = Renderer.install({ url: adUnitRenderer.url }); bidObject.renderer.setRender(adUnitRenderer.render); } to

if (adUnitRenderer && adUnitRenderer.url && !(adUnitRenderer.types && adUnitRenderer.types.indexOf(bidObject.mediaType) !== -1)) { bidObject.renderer = Renderer.install({ url: adUnitRenderer.url }); bidObject.renderer.setRender(adUnitRenderer.render); }

would that work?

@patmmccann
Copy link
Collaborator

plan is to implement the types check after #5638 gets merged so as to not introduce a merge conflict

@MikeSperone
Copy link
Contributor

MikeSperone commented Sep 10, 2020

Not sure if there's a use case for this - but what if you also needed a separate renderer for display or native (or both)?
@patmmccann would your solution allow for both separate 'banner' renderer and a 'video' renderer?

I was thinking the publisher could define it like this, and it could potentially cover additional use cases:

pbjs.addAdUnit({
    code: 'video1',
      // This renderer would work the same as it does now...
    renderer: {
        url: 'example.com/publishersCustomRenderer.js',
        render: function(bid) { renderAdUnit(...) }
    },
    mediaTypes: {
        video: {
            context: 'outstream',
            playerSize: [640, 480],
              // but a renderer passed in here would apply only to this mediaType.
              // It would override the above renderer if that was defined. ...
            renderer: {
                url: 'example.com/videoRenderer.js',
                render: function (bid) { renderVideo(...) }
            }
        },
        display: {
            ...,
              // and you'd be able to do the same for each mediaType
            renderer: {
                url: 'example.com/displayRenderer.js',
                render: function(bid) { renderDisplay(...) }
            }
        }
    },
    ...
});

In which case, I think you could do something like this:

var renderer = null;

var mediaTypeRenderer = !!bidReq[bidObject.mediaType] && bidReq[bidObject.mediaType].renderer;
if (!!mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.renderer) {
    renderer = mediaTypeRenderer;
} else if (adUnitRenderer && adUnitRenderer.url && !(adUnitRenderer.backupOnly && isBoolean(adUnitRenderer.backupOnly) && bid.renderer)) {
    renderer = adUnitRenderer;
}

if (renderer) {
    bidObject.renderer = Renderer.install({ url: renderer.url });
    bidObject.renderer.setRender(renderer.render);
}

Also, I do actually need this feature (either your proposed solution or this one would work for me)... so if you're not already working on this, I'd be happy to create a PR for this

@patmmccann
Copy link
Collaborator

having up to three different renderers on a given ad unit, one for each mediatype, is a much better solution than the type check i am proposing, but we don't want the perfect to be the enemy of the good and that solution is much harder.

@hnkhandev
Copy link
Contributor

Could a temporary fix (until the type check is implemented and merged) be something like just passing the bid through and checking if the mediaType is video in isRendererRequired?

export function isRendererRequired(renderer) {

@MikeSperone
Copy link
Contributor

@patmmccann I actually think I got something that might work - it seems to be working so far. I can create a PR, or first paste a link to it in my fork when it's ready.

@patmmccann
Copy link
Collaborator

patmmccann commented Sep 13, 2020 via email

@MikeSperone
Copy link
Contributor

MikeSperone commented Sep 14, 2020

@patmmccann I want to add a test case still, but this is working for me - and the existing tests still pass

MikeSperone@7b7dad6
(edit: had to make another small change)
https://github.com/prebid/Prebid.js/compare/master...MikeSperone:mediaType-renderers?expand=1

@MikeSperone
Copy link
Contributor

I'm not sure if I should make a new issue or ask this here, but I am trying to write a test for my above change, and placing my test after the 2 tests here: https://github.com/prebid/Prebid.js/blob/master/test/spec/auctionmanager_spec.js#L721-L764

I'm confused about the video-outstream media type, which I can only find reference to in the tests and not anywhere in the code or documentation.
If I use "video-outstream" as the mediaType, as in L757 then I can get a value for addedBid. But the type needs to be video since I am testing adding a renderer to the "video" mediaType. I don't understand why a mediaType of video-outstream seems to be required to receive bids in this test if in the real-world it seems this value should be video for a multiFormat video

@bretg
Copy link
Collaborator

bretg commented Sep 15, 2020

@MikeSperone - there's not really such a thing as a mediatype called video-outstream. The mediatype is video and the context is outstream. Unit tests can use test strings that are different than production use.

The one place the video-outstream string exists is in the mediatypepricegranularity config, and that's a hack shortcut.

@MikeSperone
Copy link
Contributor

Thanks @bretg! That was very helpful! I found out that my test was actually working, it was my code that had the error

@patmmccann
Copy link
Collaborator

I think this was solved by 5760 and can be closed

@ChrisHuie
Copy link
Collaborator

Solved with #5760

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests