hls.js supports this, as do many other clients. IME it works nicely for providing some client-side switching in case one of your hosts/CDNs goes down.
As a silly limiting example, imagine that you host Netflix on your dial-up connection as url A.
Oh, okay, right, let's set a timeout then, if it takes more than 1 second to load, we try url B.
That works, but now we've got a 1 second delay on everything. Okay, we'll update the default to be url B.
Conditions are changing all the time as a result of bottlenecks in the infrastructure moving about.
What I think you'd actually need to do is something like this - initially, fetch from multiple endpoints simultaneously with an early-cancel (so you don't waste bandwidth on the slower ones).
For N seconds you just use the fastest one (perhaps with an 'if it doesn't work' mechanism, sure).
Every N seconds you re-evaluate the fastest endpoint using the multi-fetch.
And so on and so forth.
There are better algorithms, this is back of the envelope stuff.
Firstly, I'm not solving anything. I'm explaining why fallback URLs are not equivalent to CDNs.
You don't use a CDN because your site doesn't work, you use it because it's faster.
Secondly, no, doing an occasional speed test, using data you'd be downloading anyway, then selecting an endpoint between speedtests does not increase bandwidth usage by 3x.
That extra bandwidth is a rounding error in the grand scheme of things.
It could be important, though, for the client to signal the server to close the connection. Theoretically the connection would drop after several seconds and the server would stop transmitting, but I could imagine some middleware cheerfully downloading the whole stream and throwing it away.
Then the instruction to stop the download is not instantaneous, so by the time you realize you have downloaded 1kB on the client side, the server might already have sent the whole video segment on the other side, so this is not the way to go in order to optimize congestion
If you want to do it on a sub-asset (video segment, or image or JS file) level, it's possible by doing byte-range requests (ask bytes 0-100 from CDN A and 101-200 from CDN B), but in that case you still add some overhead for establishing the TCP connection, and in the end as you need the whole asset to use it, you'll just limit the download speed to the minimum of the two.
Perhaps it could be done in a flexible, extensible way as well. Create a limited language (no loops or dangerous stuff) to express policy, search order, etc. And design it so the client side doesn't necessarily have carte blanche and the server side can maintain some control if necessary.
Basically, we're already doing this for fault tolerance and load balancing within a single CDN. Except that currently we randomize the IPs. To enforce priorities, you'd want the IPs in the A record at least partially ordered by provider.
But you can't actually expect any ordering to make it through to the client. Your authoritative server may reorder the records, their recursive server may reorder the records, and the client resolution library may also reorder the records. There's actually an RFC advocating reordering records in client libraries; it's fairly misguided, but it exists in the wild. Reordering is also likely to happen in OS dns caches where those are used.
That's not sufficient for something like CDN selection though, you want a fallback in case of failure but you first want to select based on various criteria.
Then providers would need to combat this by dropping the most expensive CDNs, causing a race to the bottom in which everyone loses: users have worse streaming experience, providers lose customers, good CDNs make less money, margins for bad CDNs are squeezed.