pageflow 0.11.4 → 12.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pageflow might be problematic. Click here for more details.

Files changed (416) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +224 -1207
  3. data/README.md +7 -3
  4. data/Rakefile +2 -0
  5. data/admins/pageflow/accounts.rb +27 -8
  6. data/admins/pageflow/entry.rb +130 -47
  7. data/admins/pageflow/folder.rb +28 -17
  8. data/admins/pageflow/membership.rb +58 -6
  9. data/admins/pageflow/user.rb +105 -98
  10. data/app/assets/fonts/pageflow/fontawesome-webfont.eot +0 -0
  11. data/app/assets/fonts/pageflow/fontawesome-webfont.svg +644 -463
  12. data/app/assets/fonts/pageflow/fontawesome-webfont.ttf +0 -0
  13. data/app/assets/fonts/pageflow/fontawesome-webfont.woff +0 -0
  14. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.eot +0 -0
  15. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.svg +2864 -696
  16. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.ttf +0 -0
  17. data/app/assets/fonts/pageflow/sourcesanspro-bold-webfont.woff +0 -0
  18. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.eot +0 -0
  19. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.svg +2572 -613
  20. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.ttf +0 -0
  21. data/app/assets/fonts/pageflow/sourcesanspro-light-webfont.woff +0 -0
  22. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.eot +0 -0
  23. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.svg +2977 -779
  24. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.ttf +0 -0
  25. data/app/assets/fonts/pageflow/sourcesanspro-regular-webfont.woff +0 -0
  26. data/app/assets/javascripts/pageflow/admin/entries.js +21 -3
  27. data/app/assets/javascripts/pageflow/audio.js +30 -15
  28. data/app/assets/javascripts/pageflow/audio/multi_player.js +12 -1
  29. data/app/assets/javascripts/pageflow/audio_player.js +15 -1
  30. data/app/assets/javascripts/pageflow/audio_player/rewind_method.js +3 -1
  31. data/app/assets/javascripts/pageflow/base.js +4 -1
  32. data/app/assets/javascripts/pageflow/browser.js +3 -0
  33. data/app/assets/javascripts/pageflow/browser/autoplay_support.js +3 -0
  34. data/app/assets/javascripts/pageflow/browser/facebook.js +1 -2
  35. data/app/assets/javascripts/pageflow/browser/ios_platform.js +5 -0
  36. data/app/assets/javascripts/pageflow/browser/video.js +4 -0
  37. data/app/assets/javascripts/pageflow/components.js +7 -0
  38. data/app/assets/javascripts/pageflow/cookies.js +1 -4
  39. data/app/assets/javascripts/pageflow/dist/react.js +4724 -5808
  40. data/app/assets/javascripts/pageflow/editor/api.js +201 -161
  41. data/app/assets/javascripts/pageflow/editor/api/errors.js +80 -0
  42. data/app/assets/javascripts/pageflow/editor/api/failure.js +9 -0
  43. data/app/assets/javascripts/pageflow/editor/api/failures.js +25 -2
  44. data/app/assets/javascripts/pageflow/editor/api/file_type.js +42 -3
  45. data/app/assets/javascripts/pageflow/editor/api/file_types.js +75 -46
  46. data/app/assets/javascripts/pageflow/editor/base.js +8 -0
  47. data/app/assets/javascripts/pageflow/editor/collections/file_types_collection.js +37 -0
  48. data/app/assets/javascripts/pageflow/editor/collections/files_collection.js +32 -1
  49. data/app/assets/javascripts/pageflow/editor/collections/mixins/ordered_collection.js +1 -1
  50. data/app/assets/javascripts/pageflow/editor/collections/multi_collection.js +4 -6
  51. data/app/assets/javascripts/pageflow/editor/collections/nested_files_collection.js +27 -0
  52. data/app/assets/javascripts/pageflow/editor/collections/pages_collection.js +21 -1
  53. data/app/assets/javascripts/pageflow/editor/collections/subset_collection.js +8 -2
  54. data/app/assets/javascripts/pageflow/editor/controllers/sidebar_controller.js +3 -2
  55. data/app/assets/javascripts/pageflow/editor/initializers/error_listener.js +10 -5
  56. data/app/assets/javascripts/pageflow/editor/initializers/routing.js +3 -1
  57. data/app/assets/javascripts/pageflow/editor/initializers/setup_collections.js +3 -0
  58. data/app/assets/javascripts/pageflow/editor/initializers/setup_file_types.js +136 -6
  59. data/app/assets/javascripts/pageflow/editor/initializers/setup_file_uploader.js +10 -0
  60. data/app/assets/javascripts/pageflow/editor/initializers/setup_hotkeys.js +5 -7
  61. data/app/assets/javascripts/pageflow/editor/initializers/stylesheet_reloading.js +1 -1
  62. data/app/assets/javascripts/pageflow/editor/models/configuration.js +1 -0
  63. data/app/assets/javascripts/pageflow/editor/models/entry.js +34 -26
  64. data/app/assets/javascripts/pageflow/editor/models/file_configuration.js +10 -0
  65. data/app/assets/javascripts/pageflow/editor/models/file_reuse.js +23 -0
  66. data/app/assets/javascripts/pageflow/editor/models/file_uploader.js +69 -0
  67. data/app/assets/javascripts/pageflow/editor/models/mixins/retryable.js +1 -1
  68. data/app/assets/javascripts/pageflow/editor/models/page.js +13 -0
  69. data/app/assets/javascripts/pageflow/editor/models/text_track_file.js +48 -0
  70. data/app/assets/javascripts/pageflow/editor/models/uploaded_file.js +62 -11
  71. data/app/assets/javascripts/pageflow/editor/routers/sidebar_router.js +1 -0
  72. data/app/assets/javascripts/pageflow/editor/templates/confirm_upload.jst.ejs +18 -0
  73. data/app/assets/javascripts/pageflow/editor/templates/delete_row_table_cell.jst.ejs +1 -0
  74. data/app/assets/javascripts/pageflow/editor/templates/drop_down_button.jst.ejs +0 -2
  75. data/app/assets/javascripts/pageflow/editor/templates/drop_down_button_item.jst.ejs +1 -0
  76. data/app/assets/javascripts/pageflow/editor/templates/edit_entry.jst.ejs +3 -1
  77. data/app/assets/javascripts/pageflow/editor/templates/edit_file.jst.ejs +0 -0
  78. data/app/assets/javascripts/pageflow/editor/templates/file_item.jst.ejs +1 -6
  79. data/app/assets/javascripts/pageflow/editor/templates/file_meta_data_item_value_view.jst.ejs +3 -0
  80. data/app/assets/javascripts/pageflow/editor/templates/file_settings_dialog.jst.ejs +10 -0
  81. data/app/assets/javascripts/pageflow/editor/templates/files_blank_slate.jst.ejs +1 -1
  82. data/app/assets/javascripts/pageflow/editor/templates/filtered_files.jst.ejs +10 -0
  83. data/app/assets/javascripts/pageflow/{ui → editor}/templates/inputs/file_input.jst.ejs +1 -1
  84. data/app/assets/javascripts/pageflow/editor/templates/inputs/reference.jst.ejs +2 -2
  85. data/app/assets/javascripts/pageflow/editor/templates/nested_files.jst.ejs +1 -0
  86. data/app/assets/javascripts/pageflow/editor/templates/table_cell.jst.ejs +0 -0
  87. data/app/assets/javascripts/pageflow/editor/templates/text_tracks.jst.ejs +13 -0
  88. data/app/assets/javascripts/pageflow/editor/templates/uploadable_files.jst.ejs +1 -0
  89. data/app/assets/javascripts/pageflow/editor/utils/form_data_utils.js +19 -0
  90. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/audio.js +5 -2
  91. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/background_image.js +3 -2
  92. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/background.js +35 -0
  93. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/groups/options.js +7 -9
  94. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/video.js +6 -5
  95. data/app/assets/javascripts/pageflow/editor/views/confirm_upload_view.js +69 -0
  96. data/app/assets/javascripts/pageflow/editor/views/confirmable_file_item_view.js +1 -1
  97. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_item_list_view.js +9 -0
  98. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_item_view.js +14 -1
  99. data/app/assets/javascripts/pageflow/editor/views/drop_down_button_view.js +51 -20
  100. data/app/assets/javascripts/pageflow/editor/views/edit_entry_view.js +21 -2
  101. data/app/assets/javascripts/pageflow/editor/views/edit_file_view.js +52 -0
  102. data/app/assets/javascripts/pageflow/editor/views/edit_storyline_view.js +1 -1
  103. data/app/assets/javascripts/pageflow/editor/views/entry_preview_view.js +15 -7
  104. data/app/assets/javascripts/pageflow/editor/views/file_item_view.js +33 -22
  105. data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_value_view.js +49 -0
  106. data/app/assets/javascripts/pageflow/editor/views/file_meta_data_item_view.js +16 -5
  107. data/app/assets/javascripts/pageflow/editor/views/file_settings_dialog_view.js +31 -0
  108. data/app/assets/javascripts/pageflow/editor/views/files_explorer_view.js +6 -7
  109. data/app/assets/javascripts/pageflow/editor/views/files_view.js +13 -14
  110. data/app/assets/javascripts/pageflow/editor/views/filtered_files_view.js +75 -0
  111. data/app/assets/javascripts/pageflow/editor/views/help_view.js +3 -0
  112. data/app/assets/javascripts/pageflow/editor/views/inputs/file_input_view.js +217 -0
  113. data/app/assets/javascripts/pageflow/editor/views/inputs/page_link_input_view.js +6 -0
  114. data/app/assets/javascripts/pageflow/editor/views/inputs/reference_input_view.js +13 -2
  115. data/app/assets/javascripts/pageflow/editor/views/list_view.js +24 -14
  116. data/app/assets/javascripts/pageflow/editor/views/model_thumbnail_view.js +4 -1
  117. data/app/assets/javascripts/pageflow/editor/views/nested_files_view.js +94 -0
  118. data/app/assets/javascripts/pageflow/editor/views/page_preview_view.js +7 -2
  119. data/app/assets/javascripts/pageflow/editor/views/text_file_meta_data_item_value_view.js +25 -0
  120. data/app/assets/javascripts/pageflow/editor/views/text_tracks_file_meta_data_item_value_view.js +12 -0
  121. data/app/assets/javascripts/pageflow/editor/views/text_tracks_view.js +65 -0
  122. data/app/assets/javascripts/pageflow/editor/views/uploadable_files_view.js +56 -0
  123. data/app/assets/javascripts/pageflow/editor/views/uploader_view.js +13 -10
  124. data/app/assets/javascripts/pageflow/features.js +8 -12
  125. data/app/assets/javascripts/pageflow/focus_outline.js +2 -0
  126. data/app/assets/javascripts/pageflow/media_player/volume_binding.js +2 -0
  127. data/app/assets/javascripts/pageflow/media_player/volume_fading.js +6 -0
  128. data/app/assets/javascripts/pageflow/page_type.js +0 -1
  129. data/app/assets/javascripts/pageflow/phone_landscape_fullscreen.js +34 -0
  130. data/app/assets/javascripts/pageflow/react.js +4 -0
  131. data/app/assets/javascripts/pageflow/ready.js +3 -0
  132. data/app/assets/javascripts/pageflow/seed_entry_data.js +4 -1
  133. data/app/assets/javascripts/pageflow/slideshow.js +1 -0
  134. data/app/assets/javascripts/pageflow/slideshow/adjacent_preparer.js +7 -5
  135. data/app/assets/javascripts/pageflow/slideshow/atmo.js +3 -3
  136. data/app/assets/javascripts/pageflow/slideshow/hidden_text_indicator_widget.js +4 -2
  137. data/app/assets/javascripts/pageflow/slideshow/hide_text.js +8 -4
  138. data/app/assets/javascripts/pageflow/slideshow/lazy_page_widget.js +5 -0
  139. data/app/assets/javascripts/pageflow/slideshow/scroller_widget.js +11 -18
  140. data/app/assets/javascripts/pageflow/ui.js +6 -0
  141. data/app/assets/javascripts/pageflow/ui/templates/inputs/url_display.jst.ejs +7 -0
  142. data/app/assets/javascripts/pageflow/ui/templates/table.jst.ejs +7 -0
  143. data/app/assets/javascripts/pageflow/ui/templates/table_blank_slate.jst.ejs +3 -0
  144. data/app/assets/javascripts/pageflow/ui/utils/i18n_utils.js +97 -2
  145. data/app/assets/javascripts/pageflow/ui/views/collection_view.js +8 -1
  146. data/app/assets/javascripts/pageflow/ui/views/inputs/check_box_input_view.js +12 -1
  147. data/app/assets/javascripts/pageflow/ui/views/inputs/proxy_url_input_view.js +51 -5
  148. data/app/assets/javascripts/pageflow/ui/views/inputs/select_input_view.js +80 -2
  149. data/app/assets/javascripts/pageflow/ui/views/inputs/slider_input_view.js +8 -1
  150. data/app/assets/javascripts/pageflow/ui/views/inputs/text_area_input_view.js +17 -1
  151. data/app/assets/javascripts/pageflow/ui/views/inputs/text_input_view.js +47 -4
  152. data/app/assets/javascripts/pageflow/ui/views/inputs/url_display_view.js +42 -0
  153. data/app/assets/javascripts/pageflow/ui/views/inputs/url_input_view.js +20 -2
  154. data/app/assets/javascripts/pageflow/ui/views/mixins/input_view.js +74 -46
  155. data/app/assets/javascripts/pageflow/ui/views/table_cells/delete_row_table_cell_view.js +63 -0
  156. data/app/assets/javascripts/pageflow/ui/views/table_cells/enum_table_cell_view.js +26 -0
  157. data/app/assets/javascripts/pageflow/ui/views/table_cells/icon_table_cell_view.js +40 -0
  158. data/app/assets/javascripts/pageflow/ui/views/table_cells/presence_table_cell_view.js +31 -0
  159. data/app/assets/javascripts/pageflow/ui/views/table_cells/table_cell_view.js +101 -0
  160. data/app/assets/javascripts/pageflow/ui/views/table_cells/table_header_cell_view.js +10 -0
  161. data/app/assets/javascripts/pageflow/ui/views/table_cells/text_table_cell_view.js +46 -0
  162. data/app/assets/javascripts/pageflow/ui/views/table_row_view.js +47 -0
  163. data/app/assets/javascripts/pageflow/ui/views/table_view.js +47 -0
  164. data/app/assets/javascripts/pageflow/video_player.js +9 -5
  165. data/app/assets/javascripts/pageflow/video_player/buffer_underrun_waiting.js +15 -13
  166. data/app/assets/javascripts/pageflow/video_player/cue_settings_methods.js +33 -0
  167. data/app/assets/javascripts/pageflow/video_player/dash.js +3 -0
  168. data/app/assets/javascripts/pageflow/video_player/filter_sources.js +1 -1
  169. data/app/assets/javascripts/pageflow/video_player/lazy.js +3 -9
  170. data/app/assets/javascripts/pageflow/video_player/prebuffering.js +11 -2
  171. data/app/assets/javascripts/pageflow/video_player/use_slim_controls_during_phone_playback.js +16 -0
  172. data/app/assets/javascripts/pageflow/videojs.js +6 -0
  173. data/app/assets/javascripts/pageflow/widgets.js +41 -7
  174. data/app/assets/stylesheets/pageflow/admin.scss +7 -4
  175. data/app/assets/stylesheets/pageflow/admin/{entries/user_badge_list.scss → badge_list.scss} +6 -9
  176. data/app/assets/stylesheets/pageflow/admin/embed_code.scss +13 -0
  177. data/app/assets/stylesheets/pageflow/admin/entries.scss +1 -2
  178. data/app/assets/stylesheets/pageflow/admin/hint.scss +20 -0
  179. data/app/assets/stylesheets/pageflow/admin/tooltip_bubble.scss +34 -0
  180. data/app/assets/stylesheets/pageflow/editor/base.scss +4 -4
  181. data/app/assets/stylesheets/pageflow/editor/confirm_upload.scss +66 -0
  182. data/app/assets/stylesheets/pageflow/editor/dialogs.scss +9 -1
  183. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +56 -20
  184. data/app/assets/stylesheets/pageflow/editor/file_meta_data.scss +26 -6
  185. data/app/assets/stylesheets/pageflow/editor/file_settings_dialog.scss +32 -0
  186. data/app/assets/stylesheets/pageflow/editor/files.scss +5 -0
  187. data/app/assets/stylesheets/pageflow/editor/filtered_files.scss +25 -0
  188. data/app/assets/stylesheets/pageflow/editor/inputs.scss +2 -1
  189. data/app/assets/stylesheets/pageflow/editor/inputs/file_input.scss +65 -0
  190. data/app/assets/stylesheets/pageflow/editor/inputs/reference.scss +2 -2
  191. data/app/assets/stylesheets/pageflow/editor/text_tracks.scss +39 -0
  192. data/app/assets/stylesheets/pageflow/entries.scss +1 -0
  193. data/app/assets/stylesheets/pageflow/mixins/buttons.scss +77 -5
  194. data/app/assets/stylesheets/pageflow/mixins/icons/fontawesome.scss +3 -1
  195. data/app/assets/stylesheets/pageflow/page_types.scss +0 -4
  196. data/app/assets/stylesheets/pageflow/page_types/video.scss +5 -1
  197. data/app/assets/stylesheets/pageflow/page_types/video/content_hiding.scss +1 -0
  198. data/app/assets/stylesheets/pageflow/themes/default/base.scss +1 -0
  199. data/app/assets/stylesheets/pageflow/themes/default/built_in_page_types.scss +0 -2
  200. data/app/assets/stylesheets/pageflow/themes/default/definitions.scss +1 -0
  201. data/app/assets/stylesheets/pageflow/themes/default/loading_spinner.scss +31 -12
  202. data/app/assets/stylesheets/pageflow/themes/default/logo.scss +9 -1
  203. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/background_image.scss +8 -2
  204. data/app/assets/stylesheets/pageflow/themes/default/logo/variant/watermark.scss +21 -0
  205. data/app/assets/stylesheets/pageflow/themes/default/mixins/cue_margins.scss +43 -0
  206. data/app/assets/stylesheets/pageflow/themes/default/mixins/indicator_typography.scss +7 -3
  207. data/app/assets/stylesheets/pageflow/themes/default/page.scss +20 -2
  208. data/app/assets/stylesheets/pageflow/themes/default/player_controls.scss +4 -0
  209. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic.scss +4 -0
  210. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/container.scss +8 -6
  211. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/control_bar.scss +18 -3
  212. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/cue_margins.scss +1 -0
  213. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/custom.scss +14 -0
  214. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/icon_font.scss +4 -0
  215. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/icons/sprite.scss +4 -0
  216. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/info_box.scss +2 -2
  217. data/app/assets/stylesheets/pageflow/themes/default/player_controls/classic/menu_bar.scss +5 -0
  218. data/app/assets/stylesheets/pageflow/themes/default/player_controls/shared/menu_bar.scss +121 -0
  219. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim.scss +2 -0
  220. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/container.scss +2 -0
  221. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/control_bar.scss +74 -12
  222. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/cue_margins.scss +3 -0
  223. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/info_box.scss +31 -5
  224. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/menu_bar.scss +13 -0
  225. data/app/assets/stylesheets/pageflow/themes/default/player_controls/slim/quality_menu.scss +116 -0
  226. data/app/assets/stylesheets/pageflow/themes/default/player_controls/vjs_mapping.scss +13 -3
  227. data/app/assets/stylesheets/pageflow/themes/default/player_controls/widget_margins.scss +8 -3
  228. data/app/assets/stylesheets/pageflow/themes/default/text_track_cues.scss +25 -0
  229. data/app/assets/stylesheets/pageflow/themes/default/variables/widgets.scss +2 -2
  230. data/app/assets/stylesheets/pageflow/themes/default/video_player/vjs_base.scss +122 -79
  231. data/app/assets/stylesheets/pageflow/themes/default/video_wrapper.scss +16 -7
  232. data/app/assets/stylesheets/pageflow/ui.scss +5 -1
  233. data/app/assets/stylesheets/pageflow/ui/forms.scss +5 -58
  234. data/app/assets/stylesheets/pageflow/ui/table_cells/delete_row_table_cell.scss +7 -0
  235. data/app/assets/stylesheets/pageflow/ui/table_cells/icon_table_cell.scss +16 -0
  236. data/app/assets/stylesheets/pageflow/ui/table_cells/presence_table_cell.scss +8 -0
  237. data/app/assets/stylesheets/pageflow/ui/table_view.scss +33 -0
  238. data/app/assets/stylesheets/pageflow/ui/tooltip.scss +1 -1
  239. data/app/controllers/pageflow/editor/encoding_confirmations_controller.rb +3 -3
  240. data/app/controllers/pageflow/editor/entry_publications_controller.rb +3 -3
  241. data/app/controllers/pageflow/editor/files_controller.rb +72 -14
  242. data/app/controllers/pageflow/editor/widgets_controller.rb +1 -1
  243. data/app/controllers/pageflow/entries_controller.rb +12 -2
  244. data/app/controllers/pageflow/files_controller.rb +1 -1
  245. data/app/helpers/pageflow/admin/entries_helper.rb +17 -0
  246. data/app/helpers/pageflow/admin/form_helper.rb +1 -1
  247. data/app/helpers/pageflow/admin/memberships_helper.rb +117 -13
  248. data/app/helpers/pageflow/common_entry_seed_helper.rb +36 -5
  249. data/app/helpers/pageflow/embed_code_helper.rb +32 -0
  250. data/app/helpers/pageflow/entries_helper.rb +1 -1
  251. data/app/helpers/pageflow/entry_json_seed_helper.rb +6 -16
  252. data/app/helpers/pageflow/files_helper.rb +5 -2
  253. data/app/helpers/pageflow/folders_helper.rb +26 -2
  254. data/app/helpers/pageflow/page_background_asset_helper.rb +8 -0
  255. data/app/helpers/pageflow/quota_helper.rb +1 -1
  256. data/app/helpers/pageflow/video_files_helper.rb +0 -5
  257. data/app/jobs/pageflow/poll_zencoder_job.rb +1 -1
  258. data/app/jobs/pageflow/process_file_job.rb +18 -0
  259. data/app/mailers/pageflow/user_mailer.rb +4 -2
  260. data/app/models/concerns/pageflow/hosted_file.rb +9 -0
  261. data/app/models/concerns/pageflow/output_source.rb +60 -0
  262. data/app/models/concerns/pageflow/uploaded_file.rb +33 -5
  263. data/app/models/pageflow/account.rb +3 -1
  264. data/app/models/pageflow/audio_file_url_templates.rb +21 -0
  265. data/app/models/pageflow/draft_entry.rb +19 -9
  266. data/app/models/pageflow/entry.rb +2 -1
  267. data/app/models/pageflow/entry_duplicate.rb +2 -2
  268. data/app/models/pageflow/entry_role_query.rb +81 -0
  269. data/app/models/pageflow/file_reuse.rb +25 -0
  270. data/app/models/pageflow/file_usage.rb +7 -1
  271. data/app/models/pageflow/image_file.rb +7 -1
  272. data/app/models/pageflow/image_file_url_templates.rb +19 -0
  273. data/app/models/pageflow/invited_user.rb +2 -0
  274. data/app/models/pageflow/membership.rb +46 -3
  275. data/app/models/pageflow/published_entry.rb +2 -2
  276. data/app/models/pageflow/revision.rb +16 -5
  277. data/app/models/pageflow/roles.rb +36 -0
  278. data/app/models/pageflow/text_track_file.rb +45 -0
  279. data/app/models/pageflow/text_track_file_url_templates.rb +16 -0
  280. data/app/models/pageflow/thumbnail_file_resolver.rb +22 -2
  281. data/app/models/pageflow/url_template.rb +13 -0
  282. data/app/models/pageflow/used_file.rb +21 -0
  283. data/app/models/pageflow/video_file.rb +72 -27
  284. data/app/models/pageflow/video_file_url_templates.rb +34 -0
  285. data/app/policies/pageflow/account_policy.rb +145 -0
  286. data/app/policies/pageflow/admin/admin_only_tab_policy.rb +16 -0
  287. data/app/policies/pageflow/admin/entry_tab_policy.rb +25 -0
  288. data/app/policies/pageflow/application_policy.rb +11 -0
  289. data/app/policies/pageflow/entry_policy.rb +138 -0
  290. data/app/policies/pageflow/file_policy.rb +42 -0
  291. data/app/policies/pageflow/folder_policy.rb +54 -0
  292. data/app/policies/pageflow/membership_policy.rb +105 -0
  293. data/app/policies/pageflow/theming_policy.rb +57 -0
  294. data/app/policies/pageflow/user_policy.rb +69 -0
  295. data/app/state_machines/pageflow/encoded_file_state_machine.rb +4 -0
  296. data/app/state_machines/pageflow/image_file_state_machine.rb +5 -1
  297. data/app/views/admin/entries/_attributes_table.html.arb +21 -2
  298. data/app/views/admin/entries/_links.html.arb +1 -1
  299. data/app/views/admin/memberships/_entity_account_input.html.erb +5 -0
  300. data/app/views/admin/memberships/_entity_entry_input.html.erb +5 -0
  301. data/app/views/admin/memberships/_form.html.erb +16 -5
  302. data/app/views/admin/memberships/_role_hint.html.arb +2 -0
  303. data/app/views/admin/users/_form.html.erb +29 -20
  304. data/app/views/components/pageflow/admin/add_membership_button_if_needed.rb +62 -0
  305. data/app/views/components/pageflow/admin/embed_code_field.rb +15 -0
  306. data/app/views/components/pageflow/admin/entry_user_badge_list.rb +15 -7
  307. data/app/views/components/pageflow/admin/grouped_folder_list.rb +20 -16
  308. data/app/views/components/pageflow/admin/members_tab.rb +22 -11
  309. data/app/views/components/pageflow/admin/membership_role_with_tooltip.rb +21 -0
  310. data/app/views/components/pageflow/admin/tabs_view.rb +13 -13
  311. data/app/views/components/pageflow/admin/user_account_badge_list.rb +43 -0
  312. data/app/views/components/pageflow/admin/user_accounts_tab.rb +46 -0
  313. data/app/views/components/pageflow/admin/user_entries_tab.rb +50 -0
  314. data/app/views/components/pageflow/admin/users_tab.rb +32 -4
  315. data/app/views/layouts/pageflow/application.html.erb +3 -2
  316. data/app/views/pageflow/config/_editor_seeds.json.jbuilder +15 -2
  317. data/app/views/pageflow/editor/entries/_entry.json.jbuilder +1 -0
  318. data/app/views/pageflow/editor/files/_file.json.jbuilder +10 -2
  319. data/app/views/pageflow/entries/show.css.erb +4 -11
  320. data/app/views/pageflow/entries/show.json.jbuilder +1 -1
  321. data/app/views/pageflow/entry_json_seed/_entry.json.jbuilder +19 -0
  322. data/app/views/pageflow/file_types/_thumbnails.css.erb +1 -1
  323. data/app/views/pageflow/files/_file.json.jbuilder +12 -0
  324. data/app/views/pageflow/page_background_asset/_element.html.erb +3 -0
  325. data/app/views/pageflow/page_types/_page_type.json.jbuilder +7 -0
  326. data/app/views/pageflow/react/_widget.html.erb +1 -0
  327. data/app/views/pageflow/react/page.html.erb +6 -0
  328. data/app/views/pageflow/video_files/_video_file.json.jbuilder +2 -0
  329. data/config/initializers/admin_resource_tabs.rb +8 -1
  330. data/config/initializers/features.rb +1 -4
  331. data/config/initializers/help_entries.rb +2 -1
  332. data/config/initializers/paperclip.rb +4 -0
  333. data/config/initializers/zencoder.rb +5 -2
  334. data/config/locales/de.yml +370 -108
  335. data/config/locales/en.yml +333 -83
  336. data/config/routes.rb +18 -10
  337. data/db/migrate/20150825133449_update_audio_loop_pages_to_use_atmo.rb +24 -0
  338. data/db/migrate/20160304072911_rename_membership_entry_and_make_polymorphic.rb +19 -0
  339. data/db/migrate/20160304151327_add_role_to_membership.rb +19 -0
  340. data/db/migrate/20160504093145_replace_role_and_account_on_user.rb +42 -0
  341. data/db/migrate/20160531152500_update_users_count.rb +27 -0
  342. data/db/migrate/20160707125400_add_output_presences_to_video_files.rb +5 -0
  343. data/db/migrate/20160824115000_add_parent_file_to_video_files.rb +8 -0
  344. data/db/migrate/20160824115100_add_parent_file_to_audio_files.rb +8 -0
  345. data/db/migrate/20160824115200_add_parent_file_to_image_files.rb +8 -0
  346. data/db/migrate/20160929102700_add_configuration_to_files.rb +7 -0
  347. data/db/migrate/20161007144500_add_text_track_files.rb +31 -0
  348. data/db/migrate/20161216175734_move_configuration_from_file_to_file_usage.rb +27 -0
  349. data/db/migrate/20161230144429_add_processed_attachment_to_text_track_files.rb +8 -0
  350. data/db/migrate/20170222124848_update_video_file_output_presences.rb +12 -0
  351. data/db/migrate/20170421112300_turn_background_video_pages_into_background_image_pages.rb +22 -0
  352. data/lib/generators/pageflow/assets/assets_generator.rb +2 -0
  353. data/lib/generators/pageflow/assets/templates/components.js +4 -0
  354. data/lib/generators/pageflow/initializer/templates/pageflow.rb +23 -20
  355. data/lib/generators/pageflow/seeds/templates/seeds.rb +81 -15
  356. data/lib/pageflow.rb +8 -0
  357. data/lib/pageflow/ability_mixin.rb +196 -62
  358. data/lib/pageflow/admin/tab.rb +21 -0
  359. data/lib/pageflow/admin/tabs.rb +31 -6
  360. data/lib/pageflow/built_in_file_type.rb +39 -0
  361. data/lib/pageflow/built_in_page_types_plugin.rb +80 -0
  362. data/lib/pageflow/configuration.rb +13 -1
  363. data/lib/pageflow/engine.rb +6 -1
  364. data/lib/pageflow/file_type.rb +60 -15
  365. data/lib/pageflow/file_types.rb +20 -2
  366. data/lib/pageflow/page_type.rb +53 -4
  367. data/lib/pageflow/page_types.rb +4 -0
  368. data/lib/pageflow/paperclip_processors/vtt.rb +35 -0
  369. data/lib/pageflow/react.rb +11 -0
  370. data/lib/pageflow/react/page_type.rb +26 -0
  371. data/lib/pageflow/react/widget_type.rb +20 -0
  372. data/lib/pageflow/seeds.rb +59 -15
  373. data/lib/pageflow/user_mixin.rb +18 -25
  374. data/lib/pageflow/version.rb +1 -1
  375. data/lib/pageflow/zencoder_api.rb +18 -4
  376. data/lib/pageflow/zencoder_video_output_definition.rb +375 -127
  377. data/lib/tasks/pageflow_tasks.rake +7 -0
  378. data/spec/factories/accounts.rb +36 -3
  379. data/spec/factories/entries.rb +22 -4
  380. data/spec/factories/invited_user.rb +3 -4
  381. data/spec/factories/memberships.rb +34 -2
  382. data/spec/factories/text_track_files.rb +40 -0
  383. data/spec/factories/users.rb +32 -7
  384. data/spec/factories/video_files.rb +7 -1
  385. data/spec/fixtures/sample.srt +12 -0
  386. data/spec/fixtures/sample.vtt +40 -0
  387. data/vendor/assets/javascripts/dash.all.min.js +14 -0
  388. data/vendor/assets/javascripts/polyfills/bind.js +17 -11
  389. data/vendor/assets/javascripts/videojs-dash.js +302 -0
  390. data/vendor/assets/javascripts/videojs.js +26804 -0
  391. metadata +187 -49
  392. data/app/assets/images/pageflow/themes/default/page_type_pictograms/audio_loop/sprite.png +0 -0
  393. data/app/assets/images/pageflow/themes/default/page_type_pictograms/audio_loop/wide.png +0 -0
  394. data/app/assets/javascripts/pageflow/editor/collections/file_usages_collection.js +0 -21
  395. data/app/assets/javascripts/pageflow/editor/models/file_usage.js +0 -8
  396. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/audio_loop.js +0 -20
  397. data/app/assets/javascripts/pageflow/editor/views/configuration_editors/background_video.js +0 -24
  398. data/app/assets/javascripts/pageflow/page_types/audio.js +0 -135
  399. data/app/assets/javascripts/pageflow/page_types/audio_loop.js +0 -102
  400. data/app/assets/javascripts/pageflow/page_types/background_image.js +0 -44
  401. data/app/assets/javascripts/pageflow/page_types/background_video.js +0 -137
  402. data/app/assets/javascripts/pageflow/page_types/video.js +0 -277
  403. data/app/assets/javascripts/pageflow/ui/views/inputs/file_input_view.js +0 -79
  404. data/app/assets/javascripts/pageflow/video_player/play_button_patch.js +0 -39
  405. data/app/assets/javascripts/pageflow/video_player/player_buffered_patch.js +0 -47
  406. data/app/assets/javascripts/pageflow/video_player/src_from_options_method.js +0 -31
  407. data/app/assets/stylesheets/pageflow/page_types/audio_loop.scss +0 -18
  408. data/app/assets/stylesheets/pageflow/page_types/background-video.scss +0 -50
  409. data/app/controllers/pageflow/editor/file_usages_controller.rb +0 -37
  410. data/app/jobs/pageflow/process_image_file_job.rb +0 -18
  411. data/app/views/pageflow/pages/templates/_audio.html.erb +0 -69
  412. data/app/views/pageflow/pages/templates/_audio_loop.html.erb +0 -34
  413. data/app/views/pageflow/pages/templates/_background_image.html.erb +0 -24
  414. data/app/views/pageflow/pages/templates/_background_video.html.erb +0 -32
  415. data/app/views/pageflow/pages/templates/_video.html.erb +0 -42
  416. data/lib/pageflow/built_in_page_type.rb +0 -79
@@ -3,42 +3,41 @@ module Pageflow
3
3
  module UserMixin
4
4
  extend ActiveSupport::Concern
5
5
 
6
- NON_ADMIN_ROLES = ['editor', 'account_manager']
7
- ROLES = NON_ADMIN_ROLES + ['admin']
8
-
9
6
  include Suspendable
10
7
 
11
8
  included do
12
- belongs_to :account, counter_cache: true, class_name: 'Pageflow::Account'
13
-
14
9
  has_many :memberships, dependent: :destroy, class_name: 'Pageflow::Membership'
15
- has_many :entries, through: :memberships, class_name: 'Pageflow::Entry'
10
+ has_many :account_memberships,
11
+ -> { where(entity_type: 'Pageflow::Account') },
12
+ class_name: 'Pageflow::Membership'
13
+ has_many :entries,
14
+ through: :memberships,
15
+ class_name: 'Pageflow::Entry',
16
+ source: :entity,
17
+ source_type: 'Pageflow::Entry'
18
+ has_many :accounts,
19
+ through: :memberships,
20
+ class_name: 'Pageflow::Account',
21
+ source: :entity,
22
+ source_type: 'Pageflow::Account'
16
23
 
17
24
  has_many :revisions, class_name: 'Pageflow::Revision', foreign_key: :creator_id
18
25
 
19
26
  validates :first_name, :last_name, presence: true
20
- validates :role, inclusion: ROLES
21
- validates :account, presence: true
22
27
 
23
- scope :admins, -> { where(role: 'admin') }
24
- scope :account_managers, -> { where(role: 'account_manager') }
25
- scope :editors, -> { where(role: 'editor') }
28
+ scope :admins, -> { where(admin: true) }
26
29
  end
27
30
 
28
31
  def admin?
29
- role == 'admin'
30
- end
31
-
32
- def account_manager?
33
- role == 'account_manager'
32
+ admin
34
33
  end
35
34
 
36
35
  def full_name
37
- [first_name, last_name] * " "
36
+ [first_name, last_name] * ' '
38
37
  end
39
38
 
40
39
  def formal_name
41
- [last_name, first_name] * ", "
40
+ [last_name, first_name] * ', '
42
41
  end
43
42
 
44
43
  def locale
@@ -60,17 +59,11 @@ module Pageflow
60
59
  destroy
61
60
  true
62
61
  else
63
- self.errors.add(:current_password, password.blank? ? :blank : :invalid)
62
+ errors.add(:current_password, password.blank? ? :blank : :invalid)
64
63
  false
65
64
  end
66
65
  end
67
66
 
68
- module ClassMethods
69
- def roles_accessible_by(ability)
70
- ability.can?(:read, Account) ? ROLES : NON_ADMIN_ROLES
71
- end
72
- end
73
-
74
67
  private
75
68
 
76
69
  def needs_password?(attributes)
@@ -1,3 +1,3 @@
1
1
  module Pageflow
2
- VERSION = '0.11.4'
2
+ VERSION = '12.0.0.rc1'.freeze
3
3
  end
@@ -36,18 +36,32 @@ module Pageflow
36
36
  end
37
37
  end
38
38
 
39
+ # @deprecated Use `get_details(job_id)` instead.
39
40
  def get_input_details(job_id)
41
+ get_details(job_id)
42
+ end
43
+
44
+ def get_details(job_id)
40
45
  with_exception_translation do
41
46
  response = Zencoder::Job.details(job_id)
42
47
 
43
48
  if response.success?
44
49
  input_details = response.body['job']['input_media_file']
50
+ outputs_details = response.body['job']['output_media_files']
51
+
52
+ output_presences = outputs_details.inject({}) do |presences, output|
53
+ if output['label'].present?
54
+ presences[output['label'].to_sym] = output['state']
55
+ end
56
+ presences
57
+ end
45
58
 
46
59
  {
47
- :format => input_details["format"],
48
- :duration_in_ms => input_details["duration_in_ms"],
49
- :width => input_details["width"],
50
- :height => input_details["height"]
60
+ format: input_details['format'],
61
+ duration_in_ms: input_details['duration_in_ms'],
62
+ width: input_details['width'],
63
+ height: input_details['height'],
64
+ output_presences: output_presences
51
65
  }
52
66
  else
53
67
  raise translate_zencoder_errors(response.errors)
@@ -1,9 +1,12 @@
1
1
  module Pageflow
2
2
  class ZencoderVideoOutputDefinition < ZencoderOutputDefinition
3
- cattr_accessor :skip_hls
3
+ cattr_accessor :skip_hls, :skip_smil
4
4
 
5
5
  attr_reader :video_file
6
6
 
7
+ MIN_SIZE_FOR_4K = '1921x1080'.freeze
8
+ MIN_SIZE_FOR_FULLHD = '1281x720'.freeze
9
+
7
10
  def initialize(video_file, options = {})
8
11
  super(options)
9
12
  @video_file = video_file
@@ -15,14 +18,14 @@ module Pageflow
15
18
 
16
19
  def outputs
17
20
  [
18
- transferable(webm_high_definition),
19
- transferable(webm_medium_definition),
21
+ mp4_highdef_definitions,
20
22
  transferable(mp4_high_definition),
21
23
  transferable(mp4_medium_definition),
22
24
  transferable(mp4_low_definition),
23
25
 
26
+ dash_definitions,
24
27
  hls_definitions,
25
- non_transferable(smil_definition),
28
+ smil_definitions,
26
29
 
27
30
  thumbnails_definitions
28
31
  ].flatten
@@ -30,186 +33,435 @@ module Pageflow
30
33
 
31
34
  private
32
35
 
33
- def webm_high_definition
36
+ def mp4_highdef_definitions
37
+ return [] unless video_file.entry.feature_state('highdef_video_encoding')
38
+ [transferable(mp4_4k_definition), transferable(mp4_fullhd_definition)]
39
+ end
40
+
41
+ def mp4_4k_definition
34
42
  {
35
- :label => 'webm_high',
36
- :format => 'webm',
37
- :path => video_file.webm_high.path,
38
- :size => '1280x720',
39
- :quality => 4,
40
- :max_video_bitrate => 3500,
41
- :public => 1,
42
- :sharpen => true
43
+ label: '4k',
44
+ prepare_for_segmenting: ['hls', 'dash'],
45
+ path: video_file.mp4_4k.path,
46
+ video_bitrate: 22000,
47
+ decoder_bitrate_cap: 24420,
48
+ decoder_buffer_size: 36631,
49
+ audio_bitrate: 320,
50
+ size: '3839x2160',
51
+ skip: {
52
+ min_size: MIN_SIZE_FOR_4K
53
+ },
54
+ public: 1,
43
55
  }
44
56
  end
45
57
 
46
- def webm_medium_definition
58
+ def mp4_fullhd_definition
47
59
  {
48
- :label => 'webm_medium',
49
- :format => 'webm',
50
- :path => video_file.webm_medium.path,
51
- :size => '1280x720',
52
- :quality => 3,
53
- :max_video_bitrate => 2000,
54
- :public => 1,
55
- :sharpen => true
60
+ label: 'fullhd',
61
+ prepare_for_segmenting: ['hls', 'dash'],
62
+ path: video_file.mp4_fullhd.path,
63
+ video_bitrate: 6000,
64
+ decoder_bitrate_cap: 6660,
65
+ decoder_buffer_size: 9990,
66
+ audio_bitrate: 192,
67
+ size: '1919x1080',
68
+ skip: {
69
+ min_size: MIN_SIZE_FOR_FULLHD
70
+ },
71
+ public: 1,
56
72
  }
57
73
  end
58
74
 
59
-
60
75
  def mp4_high_definition
61
76
  {
62
- :label => 'high',
63
- :format => 'mp4',
64
- :path => video_file.mp4_high.path,
65
- :h264_level => 3.1,
66
- :max_frame_rate => 30,
67
- :max_video_bitrate => 3500,
68
- :audio_bitrate => 192,
69
- :h264_profile => 'main',
70
- :size => '1280x720',
71
- :public => 1,
72
- :forced_keyframe_rate => '0.5',
73
- :tuning => "film",
74
- :sharpen => true
77
+ label: 'high',
78
+ prepare_for_segmenting: ['hls', 'dash'],
79
+ path: video_file.mp4_high.path,
80
+ video_bitrate: 3072,
81
+ decoder_bitrate_cap: 3410,
82
+ decoder_buffer_size: 7326,
83
+ audio_bitrate: 128,
84
+ size: '1280x720',
85
+ public: 1,
75
86
  }
76
87
  end
77
88
 
78
89
  def mp4_medium_definition
79
90
  {
80
- :label => 'medium',
81
- :format => 'mp4',
82
- :path => video_file.mp4_medium.path,
83
- :h264_level => 3.1,
84
- :max_frame_rate => 30,
85
- :max_video_bitrate => 2000,
86
- :audio_bitrate => 128,
87
- :h264_profile => 'main',
88
- :size => '1280x720',
89
- :forced_keyframe_rate => '0.5',
90
- :public => 1,
91
- :sharpen => true
91
+ label: 'medium',
92
+ prepare_for_segmenting: ['hls', 'dash'],
93
+ path: video_file.mp4_medium.path,
94
+ video_bitrate: 1536,
95
+ decoder_bitrate_cap: 1705,
96
+ decoder_buffer_size: 2557,
97
+ audio_bitrate: 64,
98
+ audio_channels: 1,
99
+ size: '853x480',
100
+ public: 1
92
101
  }
93
102
  end
94
103
 
95
104
  def mp4_low_definition
96
105
  {
97
- :label => 'low',
98
- :format => 'mp4',
99
- :path => video_file.mp4_low.path,
100
- :device_profile => 'mobile/legacy',
101
- :audio_bitrate => 56,
102
- :forced_keyframe_rate => '0.5',
103
- :public => 1,
104
- :sharpen => true
106
+ label: 'low',
107
+ prepare_for_segmenting: ['hls', 'dash'],
108
+ path: video_file.mp4_low.path,
109
+ video_bitrate: 500,
110
+ decoder_bitrate_cap: 555,
111
+ decoder_buffer_size: 924,
112
+ audio_bitrate: 64,
113
+ audio_channels: 1,
114
+ size: '640x360',
115
+ public: 1,
116
+ h264_profile: 'baseline'
105
117
  }
106
118
  end
107
119
 
120
+ def dash_definitions
121
+ dash_highdef_definitions +
122
+ [
123
+ non_transferable(dash_high_definition),
124
+ non_transferable(dash_medium_definition),
125
+ non_transferable(dash_low_definition),
126
+ non_transferable(dash_playlist_definition)
127
+ ]
128
+ end
129
+
130
+ def dash_highdef_definitions
131
+ return [] unless video_file.entry.feature_state('highdef_video_encoding')
132
+
133
+ [
134
+ non_transferable(dash_fullhd_definition),
135
+ non_transferable(dash_4k_definition)
136
+ ]
137
+ end
108
138
 
109
139
  def hls_definitions
110
140
  return [] if skip_hls
111
141
 
142
+ hls_highdef_definitions +
143
+ [
144
+ non_transferable(hls_high_definition),
145
+ non_transferable(hls_medium_definition),
146
+ non_transferable(hls_low_definition),
147
+ non_transferable(hls_playlist_definition)
148
+ ]
149
+ end
150
+
151
+ def hls_highdef_definitions
152
+ return [] unless video_file.entry.feature_state('highdef_video_encoding')
153
+
112
154
  [
113
- non_transferable(hls_high_definition),
114
- non_transferable(hls_medium_definition),
115
- non_transferable(hls_low_definition),
116
- non_transferable(hls_playlist_definition)
155
+ non_transferable(hls_fullhd_definition),
156
+ non_transferable(hls_4k_definition)
157
+ ]
158
+ end
159
+
160
+ def dash_low_definition
161
+ {
162
+ label: 'dash-low',
163
+ source: 'low',
164
+ copy_audio: 'true',
165
+ copy_video: 'true',
166
+ streaming_delivery_format: 'dash',
167
+ streaming_delivery_profile: 'on_demand',
168
+ path: video_file.dash_low.path,
169
+ type: 'segmented',
170
+ public: 1
171
+ }
172
+ end
173
+
174
+ def dash_medium_definition
175
+ {
176
+ label: 'dash-medium',
177
+ source: 'medium',
178
+ copy_audio: 'true',
179
+ copy_video: 'true',
180
+ streaming_delivery_format: 'dash',
181
+ streaming_delivery_profile: 'on_demand',
182
+ path: video_file.dash_medium.path,
183
+ type: 'segmented',
184
+ public: 1
185
+ }
186
+ end
187
+
188
+ def dash_high_definition
189
+ {
190
+ label: 'dash-high',
191
+ source: 'high',
192
+ copy_audio: 'true',
193
+ copy_video: 'true',
194
+ streaming_delivery_format: 'dash',
195
+ streaming_delivery_profile: 'on_demand',
196
+ path: video_file.dash_high.path,
197
+ type: 'segmented',
198
+ public: 1
199
+ }
200
+ end
201
+
202
+ def dash_fullhd_definition
203
+ {
204
+ label: 'dash-fullhd',
205
+ source: 'fullhd',
206
+ copy_audio: 'true',
207
+ copy_video: 'true',
208
+ streaming_delivery_format: 'dash',
209
+ streaming_delivery_profile: 'on_demand',
210
+ path: video_file.dash_fullhd.path,
211
+ type: 'segmented',
212
+ public: 1
213
+ }
214
+ end
215
+
216
+ def dash_4k_definition
217
+ {
218
+ label: 'dash-4k',
219
+ source: '4k',
220
+ copy_audio: 'true',
221
+ copy_video: 'true',
222
+ streaming_delivery_format: 'dash',
223
+ streaming_delivery_profile: 'on_demand',
224
+ path: video_file.dash_4k.path,
225
+ type: 'segmented',
226
+ public: 1
227
+ }
228
+ end
229
+
230
+ def dash_playlist_definition
231
+ {
232
+ label: 'dash-playlist',
233
+ streams: dash_stream_definitions,
234
+ allow_skipped_sources: true,
235
+ type: 'playlist',
236
+ streaming_delivery_format: 'dash',
237
+ path: video_file.dash_playlist.path,
238
+ public: 1
239
+ }
240
+ end
241
+
242
+ def dash_stream_definitions
243
+ [
244
+ {
245
+ source: 'dash-low',
246
+ path: video_file.dash_low.url
247
+ },
248
+ {
249
+ source: 'dash-medium',
250
+ path: video_file.dash_medium.url
251
+ },
252
+ {
253
+ source: 'dash-high',
254
+ path: video_file.dash_high.url
255
+ }
256
+ ] + dash_highdef_stream_definitions
257
+ end
258
+
259
+ def dash_highdef_stream_definitions
260
+ return [] unless video_file.entry.feature_state('highdef_video_encoding')
261
+ [
262
+ {
263
+ source: 'dash-fullhd',
264
+ path: video_file.dash_fullhd.url
265
+ },
266
+ {
267
+ source: 'dash-4k',
268
+ path: video_file.dash_4k.url
269
+ }
117
270
  ]
118
271
  end
119
272
 
120
273
  def hls_low_definition
121
274
  {
122
- :label => 'hls-low',
123
- :format => 'ts',
124
- :source => 'low',
125
- :copy_audio => 'true',
126
- :copy_video => 'true',
127
- :path => video_file.hls_low.path,
128
- :type => 'segmented',
129
- :public => 1
275
+ label: 'hls-low',
276
+ format: 'ts',
277
+ source: 'low',
278
+ copy_audio: 'true',
279
+ copy_video: 'true',
280
+ path: video_file.hls_low.path,
281
+ type: 'segmented',
282
+ public: 1
130
283
  }
131
284
  end
132
285
 
133
286
  def hls_medium_definition
134
287
  {
135
- :label => 'hls-medium',
136
- :format => 'ts',
137
- :source => 'medium',
138
- :copy_audio => 'true',
139
- :copy_video => 'true',
140
- :path => video_file.hls_medium.path,
141
- :type => 'segmented',
142
- :public => 1
288
+ label: 'hls-medium',
289
+ format: 'ts',
290
+ source: 'medium',
291
+ copy_audio: 'true',
292
+ copy_video: 'true',
293
+ path: video_file.hls_medium.path,
294
+ type: 'segmented',
295
+ public: 1
143
296
  }
144
297
  end
145
298
 
146
299
  def hls_high_definition
147
300
  {
148
- :label => 'hls-high',
149
- :format => 'ts',
150
- :source => 'high',
151
- :copy_audio => 'true',
152
- :copy_video => 'true',
153
- :path => video_file.hls_high.path,
154
- :type => 'segmented',
155
- :public => 1
301
+ label: 'hls-high',
302
+ format: 'ts',
303
+ source: 'high',
304
+ copy_audio: 'true',
305
+ copy_video: 'true',
306
+ path: video_file.hls_high.path,
307
+ type: 'segmented',
308
+ public: 1
309
+ }
310
+ end
311
+
312
+ def hls_fullhd_definition
313
+ {
314
+ label: 'hls-fullhd',
315
+ format: 'ts',
316
+ source: 'fullhd',
317
+ copy_audio: 'true',
318
+ copy_video: 'true',
319
+ path: video_file.hls_fullhd.path,
320
+ type: 'segmented',
321
+ public: 1
322
+ }
323
+ end
324
+
325
+ def hls_4k_definition
326
+ {
327
+ label: 'hls-4k',
328
+ format: 'ts',
329
+ source: '4k',
330
+ copy_audio: 'true',
331
+ copy_video: 'true',
332
+ path: video_file.hls_4k.path,
333
+ type: 'segmented',
334
+ public: 1
156
335
  }
157
336
  end
158
337
 
159
338
  def hls_playlist_definition
160
339
  {
161
- :label => 'hls-playlist',
162
- :streams => hls_stream_definitions,
163
- :type => 'playlist',
164
- :path => video_file.hls_playlist.path,
165
- :public => 1
340
+ label: 'hls-playlist',
341
+ streams: hls_stream_definitions,
342
+ allow_skipped_sources: true,
343
+ type: 'playlist',
344
+ path: video_file.hls_playlist.path,
345
+ public: 1
166
346
  }
167
347
  end
168
348
 
169
349
  def hls_stream_definitions
170
350
  [
171
351
  {
172
- :path => video_file.hls_medium.url(host: :hls_origin, default_protocol: 'http'),
173
- :bandwidth => 2250
352
+ source: 'hls-medium',
353
+ path: video_file.hls_medium.url(host: :hls_origin, default_protocol: 'http'),
354
+ bandwidth: 1769
174
355
  },
175
356
  {
176
- :path => video_file.hls_low.url(host: :hls_origin, default_protocol: 'http'),
177
- :bandwidth => 256
357
+ source: 'hls-low',
358
+ path: video_file.hls_low.url(host: :hls_origin, default_protocol: 'http'),
359
+ bandwidth: 619
178
360
  },
179
361
  {
180
- :path => video_file.hls_high.url(host: :hls_origin, default_protocol: 'http'),
181
- :bandwidth => 3750
362
+ source: 'hls-high',
363
+ path: video_file.hls_high.url(host: :hls_origin, default_protocol: 'http'),
364
+ bandwidth: 3538
365
+ }
366
+ ] + hls_highdef_stream_definitions
367
+ end
368
+
369
+ def hls_highdef_stream_definitions
370
+ return [] unless video_file.entry.feature_state('highdef_video_encoding')
371
+ [
372
+ {
373
+ source: 'hls-fullhd',
374
+ path: video_file.hls_fullhd.url(host: :hls_origin, default_protocol: 'http'),
375
+ bandwidth: 8575
376
+ },
377
+ {
378
+ source: 'hls-4k',
379
+ path: video_file.hls_4k.url(host: :hls_origin, default_protocol: 'http'),
380
+ bandwidth: 32000
182
381
  }
183
382
  ]
184
383
  end
185
384
 
186
- def smil_definition
187
- {
188
- :streams => smil_stream_definitions,
189
- :type => 'playlist',
190
- :format => 'highwinds',
191
- :path => video_file.smil.path,
192
- :public => true
385
+ def smil_definitions
386
+ return [] if skip_smil
387
+
388
+ smil_definition = {
389
+ type: 'playlist',
390
+ format: 'highwinds',
391
+ path: video_file.smil.path,
392
+ public: true
193
393
  }
394
+
395
+ # EXPLANATION: Zencoder always includes all conditional outputs
396
+ # in SMIL files even if they were skipped. To prevent generating
397
+ # SMIL files which point to non existent files, we include three
398
+ # definitions for the same file and apply the same conditions
399
+ # that are used to decide whether outputs are skipped.
400
+ #
401
+ # Using the `min_size` values as `max_size` allows cases where
402
+ # only one of the three SMIL outputs is skipped (i.e. if the
403
+ # resolution is exactly equal to `MIN_SIZE_FULLHD`). Still, in
404
+ # these cases the input file is just a tiny bit larger than the
405
+ # next lower resolution, so we do not really care if the SMIL
406
+ # file which does not include the higher quality does not win.
407
+ if video_file.entry.feature_state('highdef_video_encoding')
408
+ [
409
+ non_transferable(smil_definition.merge(streams: smil_default_stream_definitions,
410
+ skip: {
411
+ max_size: MIN_SIZE_FOR_FULLHD
412
+ })),
413
+ non_transferable(smil_definition.merge(streams: smil_fullhd_stream_definitions,
414
+ skip: {
415
+ min_size: MIN_SIZE_FOR_FULLHD,
416
+ max_size: MIN_SIZE_FOR_4K
417
+ })),
418
+ non_transferable(smil_definition.merge(streams: smil_4k_stream_definitions,
419
+ skip: {
420
+ min_size: MIN_SIZE_FOR_4K
421
+ }))
422
+ ]
423
+ else
424
+ non_transferable(smil_definition.merge(streams: smil_default_stream_definitions))
425
+ end
194
426
  end
195
427
 
196
- def smil_stream_definitions
428
+ def smil_default_stream_definitions
197
429
  [
198
430
  {
199
- :path => video_file.mp4_medium.url(host: :hls_origin, default_protocol: 'http'),
200
- :bandwidth => 2250
431
+ path: video_file.mp4_medium.url(host: :hls_origin, default_protocol: 'http'),
432
+ bandwidth: 1769
201
433
  },
202
434
  {
203
- :path => video_file.mp4_low.url(host: :hls_origin, default_protocol: 'http'),
204
- :bandwidth => 256
435
+ path: video_file.mp4_low.url(host: :hls_origin, default_protocol: 'http'),
436
+ bandwidth: 619
205
437
  },
206
438
  {
207
- :path => video_file.mp4_high.url(host: :hls_origin, default_protocol: 'http'),
208
- :bandwidth => 3750
439
+ path: video_file.mp4_high.url(host: :hls_origin, default_protocol: 'http'),
440
+ bandwidth: 3538
209
441
  }
210
442
  ]
211
443
  end
212
444
 
445
+ def smil_fullhd_stream_definitions
446
+ [
447
+ smil_default_stream_definitions,
448
+ {
449
+ path: video_file.mp4_fullhd.url(host: :hls_origin, default_protocol: 'http'),
450
+ bandwidth: 8575
451
+ }
452
+ ].flatten
453
+ end
454
+
455
+ def smil_4k_stream_definitions
456
+ [
457
+ smil_fullhd_stream_definitions,
458
+ {
459
+ path: video_file.mp4_4k.url(host: :hls_origin, default_protocol: 'http'),
460
+ bandwidth: 32000
461
+ }
462
+ ].flatten
463
+ end
464
+
213
465
  def thumbnails_definitions
214
466
  if akamai_configured?
215
467
  result = [thumbnails_definition(method(:akamai_url))]
@@ -222,24 +474,20 @@ module Pageflow
222
474
 
223
475
  def thumbnails_definition(url_helper)
224
476
  {
225
- :thumbnails => [
226
- with_credentials({
227
- :label => 'poster',
228
- :format => video_file.zencoder_poster.format,
229
- :number => 1,
230
- :start_at_first_frame => true,
231
- :filename => video_file.zencoder_poster.base_name_pattern,
232
- :base_url => url_helper.call(video_file.zencoder_poster.dir_name),
233
- :public => 1
234
- }),
235
- with_credentials({
236
- :label => 'thumbnail',
237
- :format => video_file.zencoder_thumbnail.format,
238
- :number => 1,
239
- :filename => video_file.zencoder_thumbnail.base_name_pattern,
240
- :base_url => url_helper.call(video_file.zencoder_thumbnail.dir_name),
241
- :public => 1
242
- })
477
+ thumbnails: [
478
+ with_credentials(label: 'poster',
479
+ format: video_file.zencoder_poster.format,
480
+ number: 1,
481
+ start_at_first_frame: true,
482
+ filename: video_file.zencoder_poster.base_name_pattern,
483
+ base_url: url_helper.call(video_file.zencoder_poster.dir_name),
484
+ public: 1),
485
+ with_credentials(label: 'thumbnail',
486
+ format: video_file.zencoder_thumbnail.format,
487
+ number: 1,
488
+ filename: video_file.zencoder_thumbnail.base_name_pattern,
489
+ base_url: url_helper.call(video_file.zencoder_thumbnail.dir_name),
490
+ public: 1)
243
491
  ]
244
492
  }
245
493
  end