diff --git a/player/raw-file.coffee b/player/raw-file.coffee
index f16f9735..8cf63182 100644
--- a/player/raw-file.coffee
+++ b/player/raw-file.coffee
@@ -1,10 +1,12 @@
-guessMimeTypeBecauseBrowsersAreDumb = (link) ->
- m = /.*\.([a-zA-Z0-9]+)[^.]*$/.exec(link)
- if m
- return m[1]
- else
- # Couldn't guess mime type; give up and hope flash can play it
- return 'flv'
+codecToMimeType = (codec) ->
+ switch codec
+ when 'mov/h264' then 'video/mp4'
+ when 'flv/h264' then 'video/flv'
+ when 'matroska/vp8', 'matroska/vp9' then 'video/webm'
+ when 'ogg/theora' then 'video/ogg'
+ when 'mp3' then 'audio/mp3'
+ when 'vorbis' then 'audio/vorbis'
+ else 'video/flv'
window.FilePlayer = class FilePlayer extends VideoJSPlayer
constructor: (data) ->
@@ -13,7 +15,7 @@ window.FilePlayer = class FilePlayer extends VideoJSPlayer
data.meta.direct =
480: [{
- contentType: guessMimeTypeBecauseBrowsersAreDumb(data.id)
+ contentType: codecToMimeType(data.meta.codec)
link: data.id
}]
super(data)
@@ -21,7 +23,7 @@ window.FilePlayer = class FilePlayer extends VideoJSPlayer
load: (data) ->
data.meta.direct =
480: [{
- contentType: guessMimeTypeBecauseBrowsersAreDumb(data.id)
+ contentType: codecToMimeType(data.meta.codec)
link: data.id
}]
super(data)
diff --git a/player/videojs.coffee b/player/videojs.coffee
index 2fa32d55..5e18059d 100644
--- a/player/videojs.coffee
+++ b/player/videojs.coffee
@@ -1,3 +1,11 @@
+fixContentType = (contentType) ->
+ # TODO: In mediaquery, fix Google Drive/Google+ to return video/mp4,
+ # video/webm so this is unnecessary
+ if /^(video|audio)\//.test(contentType)
+ return contentType
+ else
+ return "video/#{contentType}"
+
sortSources = (sources) ->
if not sources
console.error('sortSources() called with null source list')
@@ -17,8 +25,9 @@ sortSources = (sources) ->
flv = []
nonflv = []
sources[quality].forEach((source) ->
+ source.contentType = fixContentType(source.contentType)
source.quality = quality
- if source.contentType == 'flv'
+ if source.contentType == 'video/flv'
flv.push(source)
else
nonflv.push(source)
@@ -27,7 +36,7 @@ sortSources = (sources) ->
flvOrder = flvOrder.concat(flv)
return sourceOrder.concat(flvOrder).map((source) ->
- type: "video/#{source.contentType}"
+ type: source.contentType
src: source.link
quality: source.quality
)
@@ -42,7 +51,9 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player
return new VideoJSPlayer(data)
@setMediaProperties(data)
+ @loadPlayer(data)
+ loadPlayer: (data) ->
waitUntilDefined(window, 'videojs', =>
video = $('')
.addClass('video-js vjs-default-skin embed-responsive-item')
@@ -93,10 +104,11 @@ window.VideoJSPlayer = class VideoJSPlayer extends Player
load: (data) ->
@setMediaProperties(data)
- if @player
- @player.src(sortSources(data.meta.direct))
- else
- console.log('VideoJSPlayer::load() called but @player is undefined')
+ # Note: VideoJS does have facilities for loading new videos into the
+ # existing player object, however it appears to be pretty glitchy when
+ # a video can't be played (either previous or next video). It's safer
+ # to just reset the entire thing.
+ @loadPlayer(data)
play: ->
@paused = false
diff --git a/www/js/player.js b/www/js/player.js
index 6b162b6a..bf173551 100644
--- a/www/js/player.js
+++ b/www/js/player.js
@@ -1,5 +1,5 @@
(function() {
- var CUSTOM_EMBED_WARNING, CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, EmbedPlayer, FilePlayer, HITBOX_ERROR, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, genParam, guessMimeTypeBecauseBrowsersAreDumb, sortSources,
+ var CUSTOM_EMBED_WARNING, CustomEmbedPlayer, DEFAULT_ERROR, DailymotionPlayer, EmbedPlayer, FilePlayer, HITBOX_ERROR, HitboxPlayer, ImgurPlayer, LivestreamPlayer, Player, RTMPPlayer, SoundCloudPlayer, TYPE_MAP, TwitchPlayer, UstreamPlayer, VideoJSPlayer, VimeoPlayer, YouTubePlayer, codecToMimeType, fixContentType, genParam, sortSources,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
@@ -444,6 +444,14 @@
})(Player);
+ fixContentType = function(contentType) {
+ if (/^(video|audio)\//.test(contentType)) {
+ return contentType;
+ } else {
+ return "video/" + contentType;
+ }
+ };
+
sortSources = function(sources) {
var flv, flvOrder, i, idx, len, nonflv, pref, qualities, quality, qualityOrder, sourceOrder;
if (!sources) {
@@ -465,8 +473,9 @@
flv = [];
nonflv = [];
sources[quality].forEach(function(source) {
+ source.contentType = fixContentType(source.contentType);
source.quality = quality;
- if (source.contentType === 'flv') {
+ if (source.contentType === 'video/flv') {
return flv.push(source);
} else {
return nonflv.push(source);
@@ -478,7 +487,7 @@
}
return sourceOrder.concat(flvOrder).map(function(source) {
return {
- type: "video/" + source.contentType,
+ type: source.contentType,
src: source.link,
quality: source.quality
};
@@ -499,7 +508,11 @@
return new VideoJSPlayer(data);
}
this.setMediaProperties(data);
- waitUntilDefined(window, 'videojs', (function(_this) {
+ this.loadPlayer(data);
+ }
+
+ VideoJSPlayer.prototype.loadPlayer = function(data) {
+ return waitUntilDefined(window, 'videojs', (function(_this) {
return function() {
var sources, video;
video = $('').addClass('video-js vjs-default-skin embed-responsive-item').attr({
@@ -548,15 +561,11 @@
});
};
})(this));
- }
+ };
VideoJSPlayer.prototype.load = function(data) {
this.setMediaProperties(data);
- if (this.player) {
- return this.player.src(sortSources(data.meta.direct));
- } else {
- return console.log('VideoJSPlayer::load() called but @player is undefined');
- }
+ return this.loadPlayer(data);
};
VideoJSPlayer.prototype.play = function() {
@@ -609,13 +618,23 @@
})(Player);
- guessMimeTypeBecauseBrowsersAreDumb = function(link) {
- var m;
- m = /.*\.([a-zA-Z0-9]+)[^.]*$/.exec(link);
- if (m) {
- return m[1];
- } else {
- return 'flv';
+ codecToMimeType = function(codec) {
+ switch (codec) {
+ case 'mov/h264':
+ return 'video/mp4';
+ case 'flv/h264':
+ return 'video/flv';
+ case 'matroska/vp8':
+ case 'matroska/vp9':
+ return 'video/webm';
+ case 'ogg/theora':
+ return 'video/ogg';
+ case 'mp3':
+ return 'audio/mp3';
+ case 'vorbis':
+ return 'audio/vorbis';
+ default:
+ return 'video/flv';
}
};
@@ -629,7 +648,7 @@
data.meta.direct = {
480: [
{
- contentType: guessMimeTypeBecauseBrowsersAreDumb(data.id),
+ contentType: codecToMimeType(data.meta.codec),
link: data.id
}
]
@@ -641,7 +660,7 @@
data.meta.direct = {
480: [
{
- contentType: guessMimeTypeBecauseBrowsersAreDumb(data.id),
+ contentType: codecToMimeType(data.meta.codec),
link: data.id
}
]