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

allow consumers to specify a mime type for particular URLs #10

Merged
merged 5 commits into from
Sep 25, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions addon/hifi-connections/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,16 @@ let ClassMethods = Ember.Mixin.create({
},

canPlay(url) {
let urlExtension = url.split('.').pop().split('?').shift().split('#').shift();
return this.canUseConnection(url) && this.canPlayExtension(urlExtension);
if (typeof url === 'string') {
let urlExtension = url.split('.').pop().split('?').shift().split('#').shift();
return this.canUseConnection(url) && this.canPlayExtension(urlExtension);
}
else if (url.mimeType) {
return this.canPlayMimeType(url.mimeType);
}
else {
throw new Error('URL must be a string or object with a mimeType property');
}
},

canUseConnection() {
Expand All @@ -32,6 +40,21 @@ let ClassMethods = Ember.Mixin.create({
else {
return true; // assume true
}
},

canPlayMimeType(mimeType) {
let mimeTypeWhiteList = this.mimeTypeWhiteList;
let mimeTypeBlackList = this.mimeTypeBlackList;

if (mimeTypeWhiteList) {
return Ember.A(mimeTypeWhiteList).contains(mimeType);
}
else if (mimeTypeBlackList){
return !Ember.A(mimeTypeBlackList).contains(mimeType);
}
else {
return true; // assume true
}
}
});

Expand Down
1 change: 1 addition & 0 deletions addon/hifi-connections/hls.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import HLS from 'hls';

let ClassMethods = Ember.Mixin.create({
extensionWhiteList: ['m3u8'],
mimeTypeWhiteList: ['application/vnd.apple.mpegurl'],

canUseConnection(/* audioUrl */) {
// We basically never want to use this on a mobile device
Expand Down
1 change: 1 addition & 0 deletions addon/hifi-connections/howler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Howl } from 'howler';

let ClassMethods = Ember.Mixin.create({
extensionBlackList: ['m3u8'],
mimeTypeBlackList: ['application/vnd.apple.mpegurl'],

toString() {
return 'Howler';
Expand Down
13 changes: 8 additions & 5 deletions addon/hifi-connections/native-audio.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@ import BaseSound from './base';

let ClassMethods = Ember.Mixin.create({
canPlayExtension(extension) {
let audio = new Audio();

if (Ember.A(['m3u8', 'm3u']).contains(extension)) {
return audio.canPlayType(`audio/mpeg`) !== "";
return this.canPlayMimeType('audio/mpeg');
}
else {
// it returns "probably" and "maybe". Both are worth trying. Empty is bad.
return (audio.canPlayType(`audio/${extension}`) !== "");
return this.canPlayMimeType(`audio/${extension}`);
}
},

canPlayMimeType(mimeType) {
let audio = new Audio();
// it returns "probably" and "maybe". Both are worth trying. Empty is bad.
return (audio.canPlayType(mimeType) !== "");
},

toString() {
return 'Native Audio';
}
Expand Down
2 changes: 1 addition & 1 deletion addon/services/hifi.js
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ export default Service.extend(Ember.Evented, {
strategies.push({
connectionName: name,
connection: connection,
url: url
url: url.url || url
});
}
});
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/hifi-connections/hls-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,28 @@ test("HLS connection should say it can play files with m3u8 extension", function
});
});

test("HLS connection should report playability of file objects", function(assert) {
let goodFiles = Ember.A([
{url: "http://example.org/test.m3u8", mimeType: "application/vnd.apple.mpegurl"},
]);

let badFiles = Ember.A([
{url: "http://example.org/test.mp3", mimeType: "audio/mpeg"},
{url: "http://example.org/test.aac", mimeType: "audio/aac"},
{url: "http://example.org/test.wav", mimeType: "audio/wav"}
]);

assert.expect(badFiles.length + goodFiles.length);

badFiles.forEach(url => {
assert.equal(HLSConnection.canPlay(url), false, `Should not play file with mime type ${url.mimeType}`);
});

goodFiles.forEach(url => {
assert.equal(HLSConnection.canPlay(url), true, `Should be able to play file with ${url.mimeType}`);
});
});

test("On first media error stream will attempt a retry", function(assert) {
let sound = this.subject({url: goodUrl});

Expand Down
22 changes: 22 additions & 0 deletions tests/unit/hifi-connections/howler-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ test("Howler should say it cannot play hls streams", function(assert) {
});
});

test("Howler should report playability of file objects", function(assert) {
let badFiles = Ember.A([
{url: "http://example.org/test.m3u8", mimeType: "application/vnd.apple.mpegurl"},
]);

let goodFiles = Ember.A([
{url: "http://example.org/test.mp3", mimeType: "audio/mpeg"},
{url: "http://example.org/test.aac", mimeType: "audio/aac"},
{url: "http://example.org/test.wav", mimeType: "audio/wav"}
]);

assert.expect(badFiles.length + goodFiles.length);

badFiles.forEach(url => {
assert.equal(HowlerConnection.canPlay(url), false, `Should not play file with mime type ${url.mimeType}`);
});

goodFiles.forEach(url => {
assert.equal(HowlerConnection.canPlay(url), true, `Should be able to play file with ${url.mimeType}`);
});
});

test("If we 404, we give up", function(assert) {
assert.expect(1);
let done = assert.async();
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/services/hifi-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,31 @@ test("consumer can specify the order of connections to be used with a some urls"
});
});

test("consumer can specify a mime type for a url", function(assert) {
const service = this.subject({ options: chooseActiveConnections('LocalDummyConnection') });

let done = assert.async();
let fileObject = {url: "/test/sound-without-extension", mimeType: "audio/mpeg"};

let LocalDummyConnection = get(service, `_connections.LocalDummyConnection`);

let mimeTypeSpy = sinon.stub(LocalDummyConnection, 'canPlayMimeType').returns(true);
let createSpy = sinon.stub(LocalDummyConnection, 'create', function() {
let sound = DummyConnection.create(...arguments);
Ember.run.next(() => sound.trigger('audio-ready'));
return sound;
});

let promise = service.load(fileObject);

promise.then(() => {
assert.ok(mimeTypeSpy.calledOnce, "local canPlayMimeType should have been called");
assert.ok(createSpy.calledOnce, "Local connection should have been used");

done();
});
});

test("for desktop devices, try each url on each connection", function(assert) {
let done = assert.async();
let urls = ["first-test-url.mp3", "second-test-url.mp3", "third-test-url.mp3"];
Expand Down