* added missing message "mwe-no_text_tracks_found"
[lhc/web/wiklou.git] / js2 / mwEmbed / libAddMedia / mvAdvFirefogg.js
1 /*
2 * Adds advanced firefogg support (let you control and structure advanced controls over many aspects of video encoding)
3 */
4
5 //@@todo put all msg text into loadGM json
6
7 loadGM({
8 "fogg-help-sticky" : "Help (click to stick)",
9 "fogg-cg-preset" : "Preset : <strong>$1<\/strong>",
10 "fogg-cg-quality" : "Basic quality and resolution control",
11 "fogg-cg-meta" : "Metadata for the clip",
12 "fogg-cg-range" : "Encoding range",
13 "fogg-cg-advVideo" : "Advanced video encoding controls",
14 "fogg-cg-advAudio" : "Advanced audio encoding controls",
15 "fogg-preset-custom" : "Custom settings"
16 });
17
18 var mvAdvFirefogg = function( iObj ){
19 return this.init( iObj );
20 }
21 var default_mvAdvFirefogg_config = {
22 //which config groups to include
23 'config_groups' : ['preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
24
25 //if you want to load any custom presets must follow the mvAdvFirefogg.presetConf json outline below
26 'custom_presets' : {},
27
28 //any firefog config properties that may need to be excluded from options
29 'exclude_settings' : [],
30
31 //the control container (where we put all the controls)
32 'target_control_container':false
33 }
34
35 mvAdvFirefogg.prototype = {
36 //the global groupings and titles for for configuration options :
37 config_groups : [ 'preset', 'range', 'quality', 'meta', 'advVideo', 'advAudio'],
38 //list of pre-sets:
39 //local instance encoder config:
40 default_local_settings:{
41 'd' : 'webvideo',
42 'type' : 'select',
43 'selectVal': ['webvideo'],
44 'group' : "preset",
45 'pSet' : {
46 'custom':{
47 'descKey': 'fogg-preset-custom',
48 'conf': {}
49 },
50 'webvideo': {
51 'desc': "Web Video Theora, Vorbis 400kbs & 400px max width",
52 'conf': {
53 'maxSize' : 400,
54 'videoBitrate' : 544,
55 'audioBitrate' : 96,
56 'noUpscaling' : true,
57 }
58 },
59 'savebandwith': {
60 'desc': "Low Bandwith Theora, Vorbis 164kbs & 200px max size",
61 'conf': {
62 'maxSize' : 200,
63 'videoBitrate' : 164,
64 'audioBitrate' : 32,
65 'samplerate' : 22050,
66 'framerate' : 15,
67 'channels' : 1,
68 'noUpscaling' : true
69 }
70 },
71 'hqstream':{
72 'desc': "High Quality Theora, Vorbis 1080px max width",
73 'conf': {
74 'maxSize' : 1080,
75 'videoQuality' : 6,
76 'audioQuality' : 3,
77 'noUpscaling' : true,
78 }
79 },
80 }
81 },
82 local_settings: {},
83
84 //core firefogg default encoder configuration
85 //see encoder options here: http://www.firefogg.org/dev/index.html
86 default_encoder_config : {
87 //base quality settings:
88 'videoQuality': {
89 'd' : 5,
90 't' : 'Video Quality',
91 'range' : {'min':0,'max':10},
92 'type' : 'slider',
93 'group' : 'quality',
94 'help' : "Used to set the <i>Visual Quality</i> of the encoded video. (not used if you set bitrate in advanced controls below)"
95 },
96 'twopass':{
97 't' : "Two Pass Encoding",
98 'type' : "boolean",
99 'group' : "quality",
100 'help' : "Two Pass Encoding enables more consitant quality by making two passes over the video file"
101 },
102 'starttime':{
103 't' : "Start Second",
104 'type' : "float",
105 'group' : "range",
106 'help' : "Only encode from time in seconds"
107 },
108 'endtime':{
109 't' : "End Second",
110 'type' : "float",
111 'group' : "range",
112 'help' : "only encode to time in seconds"
113 },
114 'audioQuality': {
115 'd' : 1,
116 't' : 'Audio Quality',
117 'range' : {'min':-1,'max':10},
118 'type' : 'slider',
119 'group' : 'quality',
120 'help' : "Used to set the <i>Acoustic Quality</i> of the encoded audio. (not used if you set bitrate in advanced controls below)"
121 },
122 'videoCodec':{
123 'd' : "theora",
124 't' : 'Video Codec',
125 'selectVal' : ['theora'],
126 'type' : "select",
127 'group' : "quality",
128 'help' : "Used to select the clip video codec. Presently only Theora is supported. More about the <a href=\"http://www.theora.org/\">theora codec</a> "
129 },
130 'audioCodec':{
131 'd' : "vorbis",
132 't' : 'Audio Codec',
133 'selectVal' : ['vorbis'],
134 'type' : "select",
135 'group' : "quality",
136 'help' : "Used to set the clip audio codec. Presently only Vorbis is supported. More about the <a href=\"http://www.vorbis.com//\">vorbis codec</a> "
137 },
138 'width': {
139 't' : 'Video Width',
140 'range' : {'min':0,'max':1080},
141 'step' : 4,
142 'type' : 'slider',
143 'group' : "quality",
144 'help' : "Resize to given width."
145 },
146 'height': {
147 't' : 'Video Height',
148 'range' : {'min':0,'max':1080},
149 'step' : 4,
150 'type' : "slider",
151 'group' : "quality",
152 'help' : "Resize to given height"
153 },
154 //advanced Video control configs:
155 'videoBitrate':{
156 't' : 'Video Bitrate',
157 'range' : {'min':1, 'max':16778},
158 'type' : "slider",
159 'group' : "advVideo",
160 'help' : "Video Bitrate sets the encoding bitrate for video in (kb/s)"
161 } ,
162 'framerate':{
163 't' : 'Framerate',
164 'd' : '24',
165 'selectVal' : ['12', '16', {'24000:1001':'23.97'}, '24', '25', {'30000:1001':'29.97'}, '30'],
166 'type' : "select",
167 'group' : "advVideo",
168 'help' : "The video Framerate. More about <a target=\"_new\" href=\"http://en.wikipedia.org/wiki/Frame_rate\">Framerate</a>"
169 },
170 'aspect':{
171 't' : 'Aspect Ratio',
172 'd' : '4:3',
173 'type' : "select",
174 'selectVal' : ['4:3', '16:9'],
175 'group' : "advVideo",
176 'help' : "The video aspect ratio can be fraction 4:3 or 16:9. More about <a target=\"_new\" href=\"http://en.wikipedia.org/wiki/Aspect_ratio_%28image%29\">aspect ratios</a>"
177 },
178 'keyframeInterval':{
179 'd' : '64',
180 't' : 'Key Frame Interval',
181 'range' : {'min':0,'max':65536},
182 'numberType': 'force keyframe every $1 frames',
183 'type' : 'int',
184 'group' : 'advVideo',
185 'help' : "The keyframe interval in frames. Note: Most codecs force keyframes if the difference between frames is greater than keyframe encode size. More about <a href=\"http://en.wikipedia.org/wiki/I-frame\">keyframes</a>"
186 },
187 'denoise':{
188 'type' : "boolean",
189 't' : "Denoise Filter",
190 'group' : 'advVideo',
191 'help' : "Denoise input video. More about <a target=\"_new\" href=\"http://en.wikipedia.org/wiki/Video_denoising\">denoise</a>"
192 },
193 'novideo':{
194 't' : "No Video",
195 'type' : "boolean",
196 'group' : 'advVideo',
197 'help' : "disable video in the output"
198 },
199
200 //advanced Audio control Config:
201 'audioBitrate':{
202 't' : "Audio Bitrate",
203 'range' : {'min':32,'max':500},
204 'numberType': '$1 kbs',
205 'type' : 'slider',
206 'group' : 'advAudio'
207 },
208 'samplerate':{
209 't' : "Audio Sample Rate",
210 'type' : 'select',
211 'selectVal' : [{'22050':'22 kHz'}, {'44100':'44 khz'}, {'48000':'48 khz'}],
212 'formatSelect' : function(val){
213 return (Math.round(val/100)*10) + ' Hz';
214 },
215 'help' : "set output samplerate (in Hz)."
216 },
217 'noaudio':{
218 't' : "No Audio",
219 'type' : 'boolean',
220 'group' : 'advAudio',
221 'help' : "disable audio in the output"
222 },
223
224 //meta tags:
225 'title':{
226 't' : "Title",
227 'type' : 'string',
228 'group' : 'meta',
229 'help' : "A title for your clip"
230 },
231 'artist':{
232 't' : "Artist Name",
233 'type' : 'string',
234 'group' : 'meta',
235 'help' : "The artist that created this clip"
236 },
237 'date':{
238 't' : "Date",
239 'group' : 'meta',
240 'type' : 'date',
241 'help' : "The date the footage was created or released"
242 },
243 'location':{
244 't' : "Location",
245 'type' : 'string',
246 'group' : 'meta',
247 'help' : "The location of the footage"
248 },
249 'organization':{
250 't' : "Organization",
251 'type' : 'string',
252 'group' : 'meta',
253 'help' : "Name of organization (studio)"
254 },
255 'copyright':{
256 't' : "Copyright",
257 'type' : 'string',
258 'group' : 'meta',
259 'help' : "The Copyright of the clip"
260 },
261 'license':{
262 't' : "License",
263 'type' : 'string',
264 'group' : 'meta',
265 'help' : "The license of the clip (preferably a creative commons url)"
266 },
267 'contact':{
268 't' : "Contact",
269 'type' : 'string',
270 'group' : 'meta',
271 'help' : "Contact link"
272 }
273 },
274 init:function( iObj ){
275 //setup a "supported" iObj:
276 for(var i in iObj){
277 if( typeof default_mvAdvFirefogg_config [i] != 'undefined' ){
278 this[i] = iObj[i];
279 }
280 }
281 //inherit the base mvFirefogg class:
282 var myFogg = new mvFirefogg( iObj );
283 for(var i in myFogg){
284 if( typeof this[i] != 'undefined'){
285 this[ 'basefogg_' + i ] = myFogg[i];
286 }else{
287 this[ i ] = myFogg[i];
288 }
289 }
290 },
291 setupForm:function(){
292 //call base firefogg form setup
293 basefogg_setupForm();
294
295 //gennerate the control html
296 this.doControlHTML();
297
298 //setup control bindings:
299 this.doControlBindings();
300
301 },
302 doControlHTML: function(){
303 js_log("adv doControlHTML");
304 var _this = this;
305 //load presets from cookie:
306 this.loadEncSettings();
307
308 //add base control buttons:
309 this.basefogg_doControlHTML();
310
311 //build the config group outpouts
312 var gdout ='';
313 $j.each(this.config_groups, function(inx, group_key){
314 gdout+= '<div> '+
315 '<h3><a href="#" class="gd_'+group_key+'" >' + gM('fogg-cg-'+group_key) + '</a></h3>'+
316 '<div>';
317 //output that group control options:
318 gdout+='<table width="' + ($j(_this.selector).width()-60) + '" ><tr><td width="35%"></td><td width="65%"></td></tr>';
319 //output the special prset output
320 if(group_key=='preset'){
321 gdout += _this.proccessPresetControl();
322 }
323 for(var cK in _this.default_encoder_config){
324 var cConf = _this.default_encoder_config[cK];
325 if(cConf.group == group_key){
326 gdout+= _this.proccessCkControlHTML( cK );
327 }
328 }
329 gdout+='</table>';
330 gdout+= '</div>' +
331 '</div>';
332
333 });
334 //add the control container:
335 if(!this.target_control_container){
336 this.target_control_container = this.selector + ' .control_container';
337 //set the target contorl container to height
338 $j(this.selector).append( '<p><div class="control_container"></div>' );
339 }
340 //hide the container and add the output
341 $j(this.target_control_container).hide();
342 $j(this.target_control_container).html( gdout );
343
344 },
345 //custom advanced target rewrites:
346 getTargetHtml:function(target){
347 if( target=='target_btn_select_file' ||
348 target=='target_btn_select_new_file'||
349 target=='target_btn_save_local_file'){
350 var icon = (target=='target_btn_save_local_file')?'ui-icon-video':'ui-icon-folder-open';
351 return '<a class="ui-state-default ui-corner-all ui-icon_link '+
352 target +'" href="#"><span class="ui-icon ' + icon + '"/>' +
353 gM( 'fogg-' + target.substring(11) ) +
354 '</a>';
355 }else if( target=='target_btn_select_url'){
356 //return the btnHtml:
357 return $j.btnHtml( gM( 'fogg-' + target.substring(11) ), target, 'link');
358
359 }else if( target=='target_use_latest_fox' ||
360 target=='target_please_install' ||
361 target == 'target_passthrough_mode'){
362 return '<div style="margin-top:1em;padding: 0pt 0.7em;" class="ui-state-error ui-corner-all ' +
363 target + '">' +
364 '<p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-alert"/>'+
365 gM( 'fogg-' + target.substring(7)) +'</p>'+
366 '</div>';
367 }else if( target == 'target_input_file_name'){
368 return '<br><br><input style="" class="text ui-widget-content ui-corner-all ' + target + '" '+
369 'type="text" value="' + gM( 'fogg-' + target.substring(11)) + '" size="60" /> ';
370 }else{
371 js_log('call : basefogg_getTargetHtml');
372 return this.basefogg_getTargetHtml(target);
373 }
374 },
375 proccessPresetControl:function(){
376 var out='';
377 var _this = this;
378 js_log('proccessPresetControl::');
379 if(typeof this.local_settings.pSet!= 'undefined' ){
380 out+= '<select class="_preset_select">';
381 $j.each(this.local_settings.pSet, function(pKey, pSet){
382 var pDesc = (pSet.descKey) ? gM(pSet.descKey) : pSet.desc;
383 var sel = (_this.local_settings.d == pKey)?' selected':'';
384 out+='<option value="'+pKey+'" '+sel+'>'+ pDesc+'</option>';
385 });
386 out+='</select>';
387 }
388 return out;
389 },
390 proccessCkControlHTML:function( cK ){
391 var cConf = this.default_encoder_config[cK];
392 var out ='';
393 out+='<tr><td valign="top">'+
394 '<label for="_' + cK + '">' +
395 cConf.t + ':' +
396 '<span title="' + gM('fogg-help-sticky') + '" class="help_'+ cK + ' ui-icon ui-icon-info" style="float:left"></span>'+
397 '</label></td><td valign="top">';
398 //if we don't value for this:
399 var dv = ( this.default_encoder_config[cK].d ) ? this.default_encoder_config[cK].d : '';
400 //switch on the config type
401 switch( cConf.type ){
402 case 'string':
403 case 'date':
404 case 'int':
405 case 'float':
406 var size = ( cConf.type =='string' ||cConf.type == 'date' )?'14':'4';
407 out+= '<input size="' + size + '" type="text" class="_' + cK + ' text ui-widget-content ui-corner-all" value="' + dv + '" >' ;
408 break;
409 case 'boolean':
410 var checked_attr = (dv===true)?' checked="true"':'';
411 out+='<input type="checkbox" class="_'+cK+ ' ui-widget-content ui-corner-all" ' + checked_attr + '>';
412 break;
413 case 'slider':
414 var strMax = this.default_encoder_config[ cK ].range.max + '';
415 maxdigits = strMax.length +1;
416 out+= '<input type="text" maxlength="'+maxdigits+'" size="' +maxdigits + '" '+
417 'class="_'+cK+ ' text ui-widget-content ui-corner-all" style="display:inline;border:0; color:#f6931f; font-weight:bold;" ' +
418 'value="' + dv + '" >' +
419 '<div class="slider_' + cK + '"></div>';
420 break;
421 case 'select':
422 out+= '<select class="_' + cK + '">'+
423 '<option value=""> </option>';
424 for(var i in cConf.selectVal){
425 var val = cConf.selectVal[i];
426 if(typeof val == 'string'){
427 var sel = ( cConf.selectVal[i] == val)?' selected':'';
428 out+= '<option value="'+val+'"'+sel+'>'+val+'</option>';
429 }else if(typeof val == 'object'){
430 for(var key in val){
431 hr_val = val[key];
432 }
433 var sel = ( cConf.selectVal[i] == key )?' selected':'';
434
435 out+= '<option value="'+key+'"'+sel+'>'+hr_val+'</option>';
436 }
437 }
438 out+='</select>';
439 break;
440 }
441 //output the help row:
442 if(cConf.help){
443 out+='<div class="helpRow_' + cK + '">'+
444 '<span class="helpClose_' + cK + ' ui-icon ui-icon-circle-close" '+
445 'title="Close Help"'+
446 'style="float:left"/>'+
447 cConf.help +
448 '</div>';
449 }
450 out+='</td></tr><tr><td colspan="2" height="10"></td></tr>';
451 return out;
452 },
453 selectByUrl:function(){
454 var urlValue = prompt("Please enter the source media url you would like to transcode from.","http://");
455 if( urlValue ){
456 //update the mode:
457 this.sourceMode = 'url';
458 this.sourceUrl = urlValue;
459 this.selectFoggActions();
460 this.autoEncoderSettings();
461 //update the input target
462 $j(this.target_input_file_name).unbind().val( urlValue ).removeAttr('readonly');
463 }
464 },
465 doControlBindings:function(){
466 var _this = this;
467 _this.basefogg_doControlBindings();
468 //show the select by url if present:
469 /*$j( this.target_btn_select_url ).unbind(
470 ).attr('disabled', false
471 ).css({'display':'inline'}
472 ).click(function(){
473 _this.selectByUrl();
474 });
475 */
476
477
478 //hide the base advanced controls untill a file is selected:
479 $j(this.target_control_container).hide();
480
481 var helpState = {};
482 //do some display tweeks:
483 js_log('tw:' + $j(this.selector).width() +
484 'ssf:' + $j(this.target_btn_select_new_file).width() +
485 'sf:' + $j(this.target_btn_save_local_file).width() );
486
487 //set width to 250
488 $j(this.target_input_file_name).width( 250 );
489
490 //special preset action:
491 $j(this.selector + ' ._preset_select').change(function(){
492 _this.updatePresetSelection( $j(this).val() );
493 });
494
495 //bind control actions
496 for(var cK in this.default_encoder_config){
497 var cConf = this.default_encoder_config[cK];
498 //set up the help for all types:
499 if(cConf.help){
500 //initial state is hidden:
501 $j( this.selector + ' .helpRow_' + cK).hide();
502 $j(this.selector + ' .help_' + cK).click(function(){
503 //get the ckId (assume its the last class)
504 var cK = _this.getClassId(this, 'help_');
505
506 if(helpState[cK]){
507 $j(_this.selector + ' .helpRow_' + cK).hide('slow');
508 helpState[cK] = false;
509 }else{
510 $j(_this.selector + ' .helpRow_' + cK).show('slow');
511 helpState[cK] = true;
512 }
513 return false;
514 }).hover(
515 function(){
516 //get the ckId (assume its the last class)
517 var cK = _this.getClassId(this, 'help_');
518 $j( _this.selector + ' .helpRow_' + cK).show('slow');
519 },function(){
520 var cK = _this.getClassId(this, 'help_');
521 if(!helpState[cK])
522 $j( _this.selector + ' .helpRow_' + cK).hide('slow')
523 }
524 );
525 $j( _this.selector + ' .helpClose_' + cK).click(function(){
526 js_log("close help: " +cK);
527 //get the ckId (assume its the last class)
528 var cK = _this.getClassId(this, 'helpClose_');
529 $j(_this.selector + ' .helpRow_' + cK).hide('slow');
530 helpState[cK] = false;
531 return false;
532 }).css('cursor', 'pointer');
533 }else{
534 $j(this.selector + ' .help_' + cK).hide();
535 }
536
537 //setup bindings for change values: (validate input)
538
539 switch( cConf.type ){
540 case 'boolean':
541 $j(_this.selector + ' ._'+cK).click(function(){
542 _this.updateLocalValue( _this.getClassId(this), $j(this).is(":checked") );
543 _this.updatePresetSelection('custom');
544 })
545 break;
546 case 'select':
547 case 'string':
548 case 'int':
549 case 'float':
550 //@@check if we have a validate function on the string
551 $j(_this.selector + ' ._'+cK).change(function(){
552 $j(this).val( _this.updateLocalValue(
553 _this.getClassId(this),
554 $j(this).val() ));
555 _this.updatePresetSelection('custom');
556 })
557 break;
558 case 'date':
559 $j(_this.selector + ' ._'+cK).datepicker({
560 changeMonth: true,
561 changeYear: true,
562 dateFormat: 'd MM, yy',
563 onSelect: function(dateText) {
564 _this.updateInterfaceValue(_this.getClassId(this), dateText);
565 }
566 });
567 break;
568 case 'slider':
569 $j(this.selector + ' .slider_' + cK ).slider({
570 range: "min",
571 animate: true,
572 step: (cConf.step)?cConf.step:1,
573 value: $j( this.selector +' ._' + cK ).val(),
574 min: this.default_encoder_config[ cK ].range.min,
575 max: this.default_encoder_config[ cK ].range.max,
576 slide: function(event, ui) {
577 $j( _this.selector + ' ._' + _this.getClassId(this, 'slider_') ).val( ui.value );
578
579 //maintain source video aspect ratio:
580 if(_this.getClassId(this, 'slider_') == 'width'){
581 var hv = parseInt((_this.sourceFileInfo.video[0]['height']/_this.sourceFileInfo.video[0]['width'])* ui.value );
582 //update the height value: the new hight value is > that orginal the slider:
583 if(hv > _this.updateInterfaceValue('height', hv))
584 return false;
585 }
586 if(_this.getClassId(this, 'slider_') == 'height'){
587 var wv = parseInt((_this.sourceFileInfo.video[0]['width']/_this.sourceFileInfo.video[0]['height'])* ui.value );
588 //update the height value: the new hight value is > that orginal the slider:
589 if(wv > _this.updateInterfaceValue('width', wv))
590 return false;
591 }
592 },
593 change: function(event, ui){
594 //update the local settings
595 _this.updateLocalValue( _this.getClassId(this, 'slider_'), ui.value);
596 _this.updatePresetSelection('custom');
597 }
598 })
599 $j( this.selector +' ._' + cK).change(function(){
600 var scid = _this.getClassId(this);
601 var valdVal = _this.updateLocalValue(scid.substr(1),$j(this).val() );
602 _this.updatePresetSelection('custom');
603 //(validate user form input)
604 $j(this).val(valdVal);
605 //update the slider
606 js_log("update: " + _this.selector + ' .slider' + scid);
607 $j(_this.selector + ' .slider'+ scid).slider('option', 'value', valdVal );
608 });
609 break
610 }
611 }
612 $j(this.target_control_container).accordion({
613 header: "h3",
614 collapsible: true,
615 active: false,
616 fillSpace: true
617 });
618
619 //do config value updates if any
620 this.updateValuesInHtml();
621 },
622 updatePresetSelection:function( pKey ){
623 //update the local key:
624 this.local_settings.d = pKey;
625 //js_log('update preset desc: '+ pKey);
626 var pset_desc = '';
627 if(this.local_settings.pSet[ pKey ].desc){
628 pset_desc = this.local_settings.pSet[ pKey ].desc;
629 }else{
630 pset_desc = gM('fogg-preset-'+ pKey);
631 }
632 //update the preset title:
633 $j( this.selector + ' .gd_preset' ).html(
634 gM('fogg-cg-preset', pset_desc)
635 );
636 //update the selector
637 $j(this.selector + ' ._preset_select').val(pKey);
638 },
639 /*
640 * updates the interface
641 */
642 updateInterfaceValue:function(confKey, val){
643 var _this = this;
644 if(!val){
645 return ;
646 }
647 //js_log('updateInterfaceValue:: ' + confKey + ' v:' + val + ' cv:'+ _this.selector + '._'+ confKey+' len:' + $j(_this.selector + ' ._'+confKey).length );
648 //lookup the type
649 if(typeof this.default_encoder_config[confKey] == 'undefined'){
650 js_error('error: missing default key: '+ confKey);
651 return false;
652 }
653
654 //update the local value (if not already up-to-date
655 if( this.local_settings.pSet['custom']['conf'][confKey] != val ){
656 val = this.updateLocalValue(confKey, val);
657 }
658 //update the text filed:
659 $j(_this.selector + ' ._'+confKey).val( val );
660 //update the interaface widget:
661 switch(this.default_encoder_config[confKey].type){
662 case 'slider':
663 $j(_this.selector + ' .slider_' + confKey).slider('option',
664 'value', $j(_this.selector + ' ._'+ confKey).val() );
665 break;
666 }
667 return val;
668 },
669 updateLocalValue:function(confKey, value){
670 //update the local value (return the value we acutally set)
671 if(typeof this.default_encoder_config[confKey] == 'undefined'){
672 js_log("Error:could not update conf key:" + confKey)
673 return value;
674 }
675 dec = this.default_encoder_config[confKey];
676 if(dec.range){
677 value = parseInt(value);
678 var min = ( dec.range.local_min) ? dec.range.local_min :dec.range.min;
679 if(value < min)
680 value = min;
681 var max = ( dec.range.local_max) ? dec.range.local_max : dec.range.max
682 if(value > max)
683 value = max;
684 }
685 if(dec.type=='int')
686 value = parseInt(value);
687
688 //step value:
689 /*if(dec.step){
690 if((value % dec.step)!=0){
691 value = value - (value % dec.step);
692 }
693 }*/
694
695 js_log('update:local_settings:custom:conf:'+ confKey + ' = ' + value);
696 this.local_settings.pSet['custom']['conf'][confKey] = value;
697
698 return value;
699 },
700 getLocalValue:function(confKey){
701 return this.local_settings.pSet['custom']['conf'][confKey];
702 },
703 getClassId:function(elm, rmstr){
704 var elmclass = $j(elm).attr("class").split(' ').slice(0,1).toString();
705 if(rmstr){
706 return elmclass.replace( rmstr, '' );
707 }else{
708 //strip leading underscore:
709 return (elmclass[0]=='_')?elmclass.substr(1):elmclass;
710 }
711 },
712 /*
713 * sets up the autoEncoder settings
714 */
715 autoEncoderSettings:function(){
716 var _this = this;
717 //do the base encoder settings setup:
718 this.basefogg_autoEncoderSettings();
719 //make sure we are "encoding" if not display not a video file eror:
720 if( this.encoder_settings['passthrough'] ){
721 js_log("in passthrough mode (hide control)");
722 //hide all controls
723 //dispaly not encodable video
724 $j(this.target_control_container).hide('slow');
725 $j(this.target_passthrough_mode).show('slow');
726 return ;
727 }
728 //restore display:
729 $j(this.target_control_container).show('slow');
730 $j(this.target_passthrough_mode).hide('slow');
731
732 //do setup settings based on local_settings /default_encoder_config with sourceFileInfo
733 //see: http://firefogg.org/dev/sourceInfo_example.html
734 var setValues = function(k, val, maxVal) {
735 if( k !== false){
736 //update the value if unset:
737 _this.updateLocalValue(k, val);
738 }
739 if( maxVal ){
740 //update the local range:
741 if(_this.default_encoder_config[k].range){
742 _this.default_encoder_config[k].range.local_max = maxVal;
743 }
744 }
745 }
746 //container level settings
747 for(var i in this.sourceFileInfo){
748 var val = this.sourceFileInfo[i];
749 var k = false;
750 var maxVal= false;
751 switch(i){
752 //do nothing with these:
753 case 'bitrate':
754 k = 'videoBitrate';
755 maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
756 break;
757 }
758 setValues(k, val, maxVal);
759 }
760 //video stream settings
761 for(var i in this.sourceFileInfo.video[0]){
762 var val = this.sourceFileInfo.video[0][i];
763 var k = false;
764 var maxVal= false;
765 switch(i){
766 case 'width':
767 case 'height':
768 k = i;
769 maxVal = val;
770 break;
771 }
772 setValues(k, val, maxVal);
773 }
774 //audio stream settings, assumes for now thare is only one stream
775 for(var i in this.sourceFileInfo.audio[0]){
776 var val = this.sourceFileInfo.audio[0][i];
777 var k = false;
778 var maxVal= false;
779 switch(i){
780 case 'bitrate':
781 k = 'audioBitrate';
782 maxVal = (val*2 > this.default_encoder_config[k])?this.default_encoder_config[k]:val*2;
783 break;
784 }
785 setValues(k, val, maxVal);
786 }
787
788 //set all values to new default ranges & update slider:
789 $j.each(this.default_encoder_config, function(inx, val){
790 if($j(_this.selector + ' ._'+inx).length!=0){
791 if(typeof val.range != 'undefined'){
792 //udate slider range
793 var new_max = (val.range.local_max)?val.range.local_max: val.range.max
794 $j( _this.selector + ' .slider_'+inx).slider('option', 'max', new_max);
795
796 //update slider/input value:
797 _this.updateInterfaceValue(inx, _this.local_settings.pSet['custom']['conf'][inx]);
798 }
799 }
800 });
801 //update values
802 this.updateValuesInHtml();
803 },
804 doEncode:function(){
805 //update the encoder settings (from local settings)
806 pKey = this.local_settings.d;
807 this.encoder_settings = this.local_settings.pSet[ pKey ].conf;
808 this.basefogg_doEncode();
809 },
810 updateValuesInHtml:function(){
811 js_log('updateValuesInHtml::');
812 var _this = this;
813 var pKey = this.local_settings.d;
814 this.updatePresetSelection( pKey );
815
816 //set the actual HTML & widgets based on any local settings values:
817 $j.each(_this.local_settings.pSet['custom']['conf'], function(inx, val){
818 if($j(_this.selector + ' ._'+inx).length !=0){
819 $j(_this.selector + ' ._'+inx).val( val );
820 }
821 });
822 },
823 //restors settings from a cookie if you have them)
824 loadEncSettings:function( force ){
825 if($j.cookie('fogg_encoder_config')){
826 js_log("load:fogg_encoder_config from cookie ");
827 this.local_settings = JSON.parse( $j.cookie('fogg_settings') );
828 }
829 //set to default if not loaded yet:
830 if( this.local_settings && this.local_settings.pSet && this.local_settings.pSet['custom']['conf']){
831 js_log('local settings already populated');
832 }else{
833 this.local_settings = this.default_local_settings;
834 }
835
836 },
837 //clear preset settings:
838 clearSettings:function(force){
839
840 },
841 //save settings to the cookie
842 saveEncSettings:function(){
843 $j.cookie('fogg_settings', JSON.stringify( this.local_settings ) );
844 }
845 };