commit
8d965d673d
Binary file not shown.
@ -0,0 +1,199 @@ |
||||
<?php |
||||
/* For licensing terms, see /license.txt */ |
||||
|
||||
/** |
||||
* This file allows record wav files. |
||||
* |
||||
* @package chamilo.document |
||||
* |
||||
* @author Juan Carlos Raña Trabado herodoto@telefonica.net |
||||
* @since 5/april/2012 |
||||
*/ |
||||
/** |
||||
* Code |
||||
*/ |
||||
|
||||
/* INIT SECTION */ |
||||
|
||||
// Name of the language file that needs to be included |
||||
$language_file = array('document'); |
||||
|
||||
require_once '../inc/global.inc.php'; |
||||
|
||||
$_SESSION['whereami'] = 'document/voicerecord'; |
||||
$this_section = SECTION_COURSES; |
||||
|
||||
require_once api_get_path(SYS_CODE_PATH).'document/document.inc.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'groupmanager.lib.php'; |
||||
|
||||
$nameTools = get_lang('VoiceRecord'); |
||||
|
||||
api_protect_course_script(); |
||||
api_block_anonymous_users(); |
||||
|
||||
$document_data = DocumentManager::get_document_data_by_id($_GET['id'], api_get_course_id(), true); |
||||
if (empty($document_data)) { |
||||
if (api_is_in_group()) { |
||||
$group_properties = GroupManager::get_group_properties(api_get_group_id()); |
||||
$document_id = DocumentManager::get_document_id(api_get_course_info(), $group_properties['directory']); |
||||
$document_data = DocumentManager::get_document_data_by_id($document_id, api_get_course_id()); |
||||
} |
||||
} |
||||
|
||||
$document_id = $document_data['id']; |
||||
$dir = $document_data['path']; |
||||
|
||||
//make some vars |
||||
$wamidir=$dir; |
||||
if($wamidir=="/"){ |
||||
$wamidir=""; |
||||
} |
||||
$wamiurlplay=api_get_path(WEB_COURSE_PATH).api_get_course_path().'/document'.$wamidir."/"; |
||||
|
||||
|
||||
$is_allowed_to_edit = api_is_allowed_to_edit(null, true); |
||||
|
||||
// Please, do not modify this dirname formatting |
||||
|
||||
if (strstr($dir, '..')) { |
||||
$dir = '/'; |
||||
} |
||||
|
||||
if ($dir[0] == '.') { |
||||
$dir = substr($dir, 1); |
||||
} |
||||
|
||||
if ($dir[0] != '/') { |
||||
$dir = '/'.$dir; |
||||
} |
||||
|
||||
if ($dir[strlen($dir) - 1] != '/') { |
||||
$dir .= '/'; |
||||
} |
||||
|
||||
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'.$dir; |
||||
|
||||
if (!is_dir($filepath)) { |
||||
$filepath = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document/'; |
||||
$dir = '/'; |
||||
} |
||||
//make some vars |
||||
//$waminame="audiorecord.wav"; |
||||
$wamiuserid=api_get_user_id(); |
||||
$userinfo=Database::get_user_info_from_id($wamiuserid); |
||||
$waminame = api_get_person_name($userinfo['firstname'], $userinfo['lastname']).'.wav'; |
||||
$waminame = replace_dangerous_char($waminame, 'strict'); |
||||
|
||||
|
||||
$waminame_noex=basename($waminame, ".wav"); |
||||
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'; |
||||
$saveDir=$dirBaseDocuments.$wamidir; |
||||
if (file_exists($saveDir.'/'.$waminame)){ |
||||
$i = 1; |
||||
while (file_exists($saveDir.'/'.$waminame_noex.'_'.$i.'.wav')) $i++; |
||||
$waminame = $waminame_noex . '_' . $i . '.wav'; |
||||
} |
||||
|
||||
//groups //TODO: clean |
||||
if (isset ($_SESSION['_gid']) && $_SESSION['_gid'] != 0) { |
||||
$req_gid = '&gidReq='.$_SESSION['_gid']; |
||||
$interbreadcrumb[] = array ("url" => "../group/group_space.php?gidReq=".$_SESSION['_gid'], "name" => get_lang('GroupSpace')); |
||||
$noPHP_SELF = true; |
||||
$to_group_id = $_SESSION['_gid']; |
||||
$group = GroupManager :: get_group_properties($to_group_id); |
||||
$path = explode('/', $dir); |
||||
if ('/'.$path[1] != $group['directory']) { |
||||
api_not_allowed(true); |
||||
} |
||||
} |
||||
|
||||
$interbreadcrumb[] = array ("url" => "./document.php?id=".$document_id.$req_gid, "name" => get_lang('Documents')); |
||||
|
||||
if (!$is_allowed_in_course) { |
||||
api_not_allowed(true); |
||||
} |
||||
|
||||
if (!($is_allowed_to_edit || $_SESSION['group_member_with_upload_rights'] || is_my_shared_folder(api_get_user_id(), Security::remove_XSS($dir),api_get_session_id()))) { |
||||
api_not_allowed(true); |
||||
} |
||||
|
||||
|
||||
/* Header */ |
||||
event_access_tool(TOOL_DOCUMENT); |
||||
|
||||
$display_dir = $dir; |
||||
if (isset ($group)) { |
||||
$display_dir = explode('/', $dir); |
||||
unset ($display_dir[0]); |
||||
unset ($display_dir[1]); |
||||
$display_dir = implode('/', $display_dir); |
||||
} |
||||
|
||||
// Interbreadcrumb for the current directory root path |
||||
$counter = 0; |
||||
if (isset($document_data['parents'])) { |
||||
foreach($document_data['parents'] as $document_sub_data) { |
||||
//fixing double group folder in breadcrumb |
||||
if (api_get_group_id()) { |
||||
if ($counter == 0) { |
||||
$counter++; |
||||
continue; |
||||
} |
||||
} |
||||
$interbreadcrumb[] = array('url' => $document_sub_data['document_url'], 'name' => $document_sub_data['title']); |
||||
$counter++; |
||||
} |
||||
} |
||||
|
||||
Display :: display_header($nameTools, 'Doc'); |
||||
echo '<div class="actions">'; |
||||
echo '<a href="document.php?id='.$document_id.'">'.Display::return_icon('back.png',get_lang('BackTo').' '.get_lang('DocumentsOverview'),'',ICON_SIZE_MEDIUM).'</a>'; |
||||
echo '</div>'; |
||||
|
||||
|
||||
?> |
||||
<!-- swfobject is a commonly used library to embed Flash content https://ajax.googleapis.com/ajax/libs/swfobject/2.2/ --> |
||||
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>swfobject/swfobject.js"></script>
|
||||
|
||||
<!-- Setup the recorder interface --> |
||||
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/recorder.js"></script>
|
||||
|
||||
<!-- GUI code... take it or leave it --> |
||||
<script type="text/javascript" src="<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/gui.js"></script>
|
||||
|
||||
<script> |
||||
function setupRecorder() { |
||||
Wami.setup({ |
||||
id : "wami", |
||||
onReady : setupGUI |
||||
}); |
||||
} |
||||
|
||||
function setupGUI() { |
||||
var gui = new Wami.GUI({ |
||||
id : "wami", |
||||
recordUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/record_document.php?waminame=<?php echo $waminame; ?>&wamidir=<?php echo $wamidir; ?>&wamiuserid=<?php echo $wamiuserid; ?>",
|
||||
playUrl : "<?php echo $wamiurlplay.$waminame; ?>",
|
||||
buttonUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/buttons.png",
|
||||
swfUrl : "<?php echo api_get_path(WEB_LIBRARY_PATH) ?>wami-recorder/Wami.swf",
|
||||
}); |
||||
|
||||
gui.setPlayEnabled(false); |
||||
} |
||||
|
||||
</script> |
||||
|
||||
<div id="wami" style="margin-left: 460px; margin-top:50px;"></div> |
||||
<div align="center" style="margin-top:200px;"> |
||||
<?php |
||||
|
||||
Display::display_normal_message(get_lang('VoiceRecord'), false); |
||||
|
||||
?> |
||||
|
||||
</div> |
||||
<body onLoad="setupRecorder()"> |
||||
|
||||
<?php |
||||
|
||||
Display :: display_footer(); |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,349 @@ |
||||
var Wami = window.Wami || {}; |
||||
|
||||
// Upon a creation of a new Wami.GUI(options), we assume that a WAMI recorder
|
||||
// has been initialized.
|
||||
Wami.GUI = function(options) { |
||||
var RECORD_BUTTON = 1; |
||||
var PLAY_BUTTON = 2; |
||||
|
||||
setOptions(options); |
||||
setupDOM(); |
||||
|
||||
var recordButton, playButton; |
||||
var recordInterval, playInterval; |
||||
|
||||
function createDiv(id, style) { |
||||
var div = document.createElement("div"); |
||||
if (id) { |
||||
div.setAttribute('id', id); |
||||
} |
||||
if (style) { |
||||
div.style.cssText = style; |
||||
} |
||||
return div; |
||||
} |
||||
|
||||
function setOptions(options) { |
||||
if (!options.buttonUrl) { |
||||
options.buttonUrl = "buttons.png"; |
||||
} |
||||
|
||||
if (typeof options.listen == 'undefined' || options.listen) { |
||||
listen(); |
||||
} |
||||
} |
||||
|
||||
function setupDOM() { |
||||
var guidiv = createDiv(null, |
||||
"position: absolute; width: 214px; height: 137px;"); |
||||
document.getElementById(options.id).appendChild(guidiv); |
||||
|
||||
var rid = Wami.createID(); |
||||
var recordDiv = createDiv(rid, |
||||
"position: absolute; left: 40px; top: 25px"); |
||||
guidiv.appendChild(recordDiv); |
||||
|
||||
recordButton = new Button(rid, RECORD_BUTTON, options.buttonUrl); |
||||
recordButton.onstart = startRecording; |
||||
recordButton.onstop = stopRecording; |
||||
|
||||
recordButton.setEnabled(true); |
||||
|
||||
if (!options.singleButton) { |
||||
var pid = Wami.createID(); |
||||
var playDiv = createDiv(pid, |
||||
"position: absolute; right: 40px; top: 25px"); |
||||
guidiv.appendChild(playDiv); |
||||
|
||||
playButton = new Button(pid, PLAY_BUTTON, options.buttonUrl); |
||||
playButton.onstart = startPlaying; |
||||
playButton.onstop = stopPlaying; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* These methods are called on clicks from the GUI. |
||||
*/ |
||||
function startRecording() { |
||||
if (!options.recordUrl) { |
||||
alert("No record Url specified!"); |
||||
} |
||||
recordButton.setActivity(0); |
||||
playButton.setEnabled(false); |
||||
Wami.startRecording(options.recordUrl, |
||||
Wami.nameCallback(onRecordStart), Wami |
||||
.nameCallback(onRecordFinish), Wami |
||||
.nameCallback(onError)); |
||||
} |
||||
|
||||
function stopRecording() { |
||||
Wami.stopRecording(); |
||||
clearInterval(recordInterval); |
||||
recordButton.setEnabled(true); |
||||
} |
||||
|
||||
function startPlaying() { |
||||
if (!options.playUrl) { |
||||
alert('No play URL specified!'); |
||||
} |
||||
|
||||
playButton.setActivity(0); |
||||
recordButton.setEnabled(false); |
||||
|
||||
Wami.startPlaying(options.playUrl, Wami.nameCallback(onPlayStart), Wami |
||||
.nameCallback(onPlayFinish), Wami.nameCallback(onError)); |
||||
} |
||||
|
||||
function stopPlaying() { |
||||
Wami.stopPlaying(); |
||||
} |
||||
|
||||
this.setPlayUrl = function(url) { |
||||
options.playUrl = url; |
||||
} |
||||
|
||||
this.setRecordUrl = function(url) { |
||||
options.recordUrl = url; |
||||
} |
||||
|
||||
this.setPlayEnabled = function(val) { |
||||
playButton.setEnabled(val); |
||||
} |
||||
|
||||
this.setRecordEnabled = function(val) { |
||||
recordButton.setEnabled(val); |
||||
} |
||||
|
||||
/** |
||||
* Callbacks from the flash indicating certain events |
||||
*/ |
||||
|
||||
function onError(e) { |
||||
alert(e); |
||||
} |
||||
|
||||
function onRecordStart() { |
||||
recordInterval = setInterval(function() { |
||||
if (recordButton.isActive()) { |
||||
var level = Wami.getRecordingLevel(); |
||||
recordButton.setActivity(level); |
||||
} |
||||
}, 200); |
||||
if (options.onRecordStart) { |
||||
options.onRecordStart(); |
||||
} |
||||
} |
||||
|
||||
function onRecordFinish() { |
||||
playButton.setEnabled(true); |
||||
if (options.onRecordFinish) { |
||||
options.onRecordFinish(); |
||||
} |
||||
} |
||||
|
||||
function onPlayStart() { |
||||
playInterval = setInterval(function() { |
||||
if (playButton.isActive()) { |
||||
var level = Wami.getPlayingLevel(); |
||||
playButton.setActivity(level); |
||||
} |
||||
}, 200); |
||||
if (options.onPlayStart) { |
||||
options.onPlayStart(); |
||||
} |
||||
} |
||||
|
||||
function onPlayFinish() { |
||||
clearInterval(playInterval); |
||||
recordButton.setEnabled(true); |
||||
playButton.setEnabled(true); |
||||
if (options.onPlayFinish) { |
||||
options.onPlayFinish(); |
||||
} |
||||
} |
||||
|
||||
function listen() { |
||||
Wami.startListening(); |
||||
// Continually listening when the window is in focus allows us to
|
||||
// buffer a little audio before the users clicks, since sometimes
|
||||
// people talk too soon. Without "listening", the audio would record
|
||||
// exactly when startRecording() is called.
|
||||
window.onfocus = function() { |
||||
Wami.startListening(); |
||||
}; |
||||
|
||||
// Note that the use of onfocus and onblur should probably be replaced
|
||||
// with a more robust solution (e.g. jQuery's $(window).focus(...)
|
||||
window.onblur = function() { |
||||
Wami.stopListening(); |
||||
}; |
||||
} |
||||
|
||||
function Button(buttonid, type, url) { |
||||
var self = this; |
||||
self.active = false; |
||||
self.type = type; |
||||
|
||||
init(); |
||||
|
||||
// Get the background button image position
|
||||
// Index: 1) normal 2) pressed 3) mouse-over
|
||||
function background(index) { |
||||
if (index == 1) |
||||
return "-56px 0px"; |
||||
if (index == 2) |
||||
return "0px 0px"; |
||||
if (index == 3) |
||||
return "-112px 0"; |
||||
alert("Background not found: " + index); |
||||
} |
||||
|
||||
// Get the type of meter and its state
|
||||
// Index: 1) enabled 2) meter 3) disabled
|
||||
function meter(index, offset) { |
||||
var top = 5; |
||||
if (offset) |
||||
top += offset; |
||||
if (self.type == RECORD_BUTTON) { |
||||
if (index == 1) |
||||
return "-169px " + top + "px"; |
||||
if (index == 2) |
||||
return "-189px " + top + "px"; |
||||
if (index == 3) |
||||
return "-249px " + top + "px"; |
||||
} else { |
||||
if (index == 1) |
||||
return "-269px " + top + "px"; |
||||
if (index == 2) |
||||
return "-298px " + top + "px"; |
||||
if (index == 3) |
||||
return "-327px " + top + "px"; |
||||
} |
||||
alert("Meter not found: " + self.type + " " + index); |
||||
} |
||||
|
||||
function silhouetteWidth() { |
||||
if (self.type == RECORD_BUTTON) { |
||||
return "20px"; |
||||
} else { |
||||
return "29px"; |
||||
} |
||||
} |
||||
|
||||
function mouseHandler(e) { |
||||
var rightclick; |
||||
if (!e) |
||||
var e = window.event; |
||||
if (e.which) |
||||
rightclick = (e.which == 3); |
||||
else if (e.button) |
||||
rightclick = (e.button == 2); |
||||
|
||||
if (!rightclick) { |
||||
if (self.active && self.onstop) { |
||||
self.active = false; |
||||
self.onstop(); |
||||
} else if (!self.active && self.onstart) { |
||||
self.active = true; |
||||
self.onstart(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
function init() { |
||||
var div = document.createElement("div"); |
||||
var elem = document.getElementById(buttonid); |
||||
if (elem) { |
||||
elem.appendChild(div); |
||||
} else { |
||||
alert('Could not find element on page named ' + buttonid); |
||||
} |
||||
|
||||
self.guidiv = document.createElement("div"); |
||||
self.guidiv.style.width = '56px'; |
||||
self.guidiv.style.height = '63px'; |
||||
self.guidiv.style.cursor = 'pointer'; |
||||
self.guidiv.style.background = "url(" + url + ") no-repeat"; |
||||
self.guidiv.style.backgroundPosition = background(1); |
||||
div.appendChild(self.guidiv); |
||||
|
||||
// margin auto doesn't work in IE quirks mode
|
||||
// http://stackoverflow.com/questions/816343/why-will-this-div-img-not-center-in-ie8
|
||||
// text-align is a hack to force it to work even if you forget the
|
||||
// doctype.
|
||||
self.guidiv.style.textAlign = 'center'; |
||||
|
||||
self.meterDiv = document.createElement("div"); |
||||
self.meterDiv.style.width = silhouetteWidth(); |
||||
self.meterDiv.style.height = '63px'; |
||||
self.meterDiv.style.margin = 'auto'; |
||||
self.meterDiv.style.cursor = 'pointer'; |
||||
self.meterDiv.style.position = 'relative'; |
||||
self.meterDiv.style.background = "url(" + url + ") no-repeat"; |
||||
self.meterDiv.style.backgroundPosition = meter(2); |
||||
self.guidiv.appendChild(self.meterDiv); |
||||
|
||||
self.coverDiv = document.createElement("div"); |
||||
self.coverDiv.style.width = silhouetteWidth(); |
||||
self.coverDiv.style.height = '63px'; |
||||
self.coverDiv.style.margin = 'auto'; |
||||
self.coverDiv.style.cursor = 'pointer'; |
||||
self.coverDiv.style.position = 'relative'; |
||||
self.coverDiv.style.background = "url(" + url + ") no-repeat"; |
||||
self.coverDiv.style.backgroundPosition = meter(1); |
||||
self.meterDiv.appendChild(self.coverDiv); |
||||
|
||||
self.active = false; |
||||
self.guidiv.onmousedown = mouseHandler; |
||||
} |
||||
|
||||
self.isActive = function() { |
||||
return self.active; |
||||
} |
||||
|
||||
self.setActivity = function(level) { |
||||
self.guidiv.onmouseout = function() { |
||||
}; |
||||
self.guidiv.onmouseover = function() { |
||||
}; |
||||
self.guidiv.style.backgroundPosition = background(2); |
||||
self.coverDiv.style.backgroundPosition = meter(1, 5); |
||||
self.meterDiv.style.backgroundPosition = meter(2, 5); |
||||
|
||||
var totalHeight = 31; |
||||
var maxHeight = 9; |
||||
|
||||
// When volume goes up, the black image loses height,
|
||||
// creating the perception of the colored one increasing.
|
||||
var height = (maxHeight + totalHeight - Math.floor(level / 100 |
||||
* totalHeight)); |
||||
self.coverDiv.style.height = height + "px"; |
||||
} |
||||
|
||||
self.setEnabled = function(enable) { |
||||
var guidiv = self.guidiv; |
||||
self.active = false; |
||||
if (enable) { |
||||
self.coverDiv.style.backgroundPosition = meter(1); |
||||
self.meterDiv.style.backgroundPosition = meter(1); |
||||
guidiv.style.backgroundPosition = background(1); |
||||
guidiv.onmousedown = mouseHandler; |
||||
guidiv.onmouseover = function() { |
||||
guidiv.style.backgroundPosition = background(3); |
||||
}; |
||||
guidiv.onmouseout = function() { |
||||
guidiv.style.backgroundPosition = background(1); |
||||
}; |
||||
} else { |
||||
self.coverDiv.style.backgroundPosition = meter(3); |
||||
self.meterDiv.style.backgroundPosition = meter(3); |
||||
guidiv.style.backgroundPosition = background(1); |
||||
guidiv.onmousedown = null; |
||||
guidiv.onmouseout = function() { |
||||
}; |
||||
guidiv.onmouseover = function() { |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,6 @@ |
||||
<html> |
||||
<head> |
||||
</head> |
||||
<body> |
||||
</body> |
||||
</html> |
@ -0,0 +1,64 @@ |
||||
<?php |
||||
require_once '../../../inc/global.inc.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'fileUpload.lib.php'; |
||||
require_once api_get_path(LIBRARY_PATH).'document.lib.php'; |
||||
////Add security from Chamilo |
||||
api_protect_course_script(); |
||||
api_block_anonymous_users(); |
||||
// |
||||
# Save the audio to a URL-accessible directory for playback. |
||||
parse_str($_SERVER['QUERY_STRING'], $params); |
||||
|
||||
if(isset($params['waminame']) && isset($params['wamidir']) && isset($params['wamiuserid'])) { |
||||
$waminame = $params['waminame']; |
||||
$wamidir = $params['wamidir']; |
||||
$wamiuserid = $params['wamiuserid']; |
||||
} |
||||
else { |
||||
api_not_allowed(); |
||||
die(); |
||||
} |
||||
|
||||
if ($wamiuserid!= api_get_user_id() || api_get_user_id()==0 || $wamiuserid==0) { |
||||
api_not_allowed(); |
||||
die(); |
||||
} |
||||
|
||||
|
||||
//clean |
||||
$waminame = Security::remove_XSS($waminame); |
||||
$waminame = addslashes(trim($waminame)); |
||||
$waminame = replace_dangerous_char($waminame, 'strict'); |
||||
$waminame = disable_dangerous_file($waminame); |
||||
$wamidir = Security::remove_XSS($wamidir); |
||||
|
||||
|
||||
$content = file_get_contents('php://input'); |
||||
|
||||
//security extension |
||||
$ext = explode('.', $waminame); |
||||
$ext = strtolower($ext[sizeof($ext) - 1]); |
||||
|
||||
if($ext!= 'wav'){ |
||||
die(); |
||||
} |
||||
|
||||
//Do not use here check Fileinfo method because return: text/plain |
||||
|
||||
$dirBaseDocuments = api_get_path(SYS_COURSE_PATH).$_course['path'].'/document'; |
||||
$saveDir=$dirBaseDocuments.$wamidir; |
||||
$current_session_id = api_get_session_id(); |
||||
$groupId=$_SESSION['_gid']; |
||||
$documentPath = $saveDir.'/'.$waminame; |
||||
$title=str_replace('_',' ',$waminame); |
||||
//$title=basename($waminame, ".wav");//save title whitout extension |
||||
|
||||
//add to disk |
||||
$fh = fopen($documentPath, 'w') or die("can't open file"); |
||||
fwrite($fh, $content); |
||||
fclose($fh); |
||||
|
||||
//add document to database |
||||
$doc_id = add_document($_course, $wamidir.'/'.$waminame, 'file', filesize($documentPath), $title); |
||||
api_item_property_update($_course, TOOL_DOCUMENT, $doc_id, 'DocumentAdded', $_user['user_id'], $groupId, null, null, null, $current_session_id); |
||||
?> |
@ -0,0 +1,273 @@ |
||||
var Wami = window.Wami || {}; |
||||
|
||||
// Returns a (very likely) unique string with of random letters and numbers
|
||||
Wami.createID = function() { |
||||
return "wid" + ("" + 1e10).replace(/[018]/g, function(a) { |
||||
return (a ^ Math.random() * 16 >> a / 4).toString(16) |
||||
}); |
||||
} |
||||
|
||||
// Creates a named callback in WAMI and returns the name as a string.
|
||||
Wami.nameCallback = function(cb, cleanup) { |
||||
Wami._callbacks = Wami._callbacks || {}; |
||||
var id = Wami.createID(); |
||||
Wami._callbacks[id] = function() { |
||||
if (cleanup) { |
||||
Wami._callbacks[id] = null; |
||||
} |
||||
cb.apply(null, arguments); |
||||
}; |
||||
var named = "Wami._callbacks['" + id + "']"; |
||||
return named; |
||||
} |
||||
|
||||
// This method ensures that a WAMI recorder is operational, and that
|
||||
// the following API is available in the Wami namespace. All functions
|
||||
// must be named (i.e. cannot be anonymous).
|
||||
//
|
||||
// Wami.startPlaying(url, startfn = null, finishedfn = null, failedfn = null);
|
||||
// Wami.stopPlaying()
|
||||
//
|
||||
// Wami.startRecording(url, startfn = null, finishedfn = null, failedfn = null);
|
||||
// Wami.stopRecording()
|
||||
//
|
||||
// Wami.getRecordingLevel() // Returns a number between 0 and 100
|
||||
// Wami.getPlayingLevel() // Returns a number between 0 and 100
|
||||
//
|
||||
// Wami.hide()
|
||||
// Wami.show()
|
||||
//
|
||||
// Manipulate the WAMI recorder's settings. In Flash
|
||||
// we need to check if the microphone permission has been granted.
|
||||
// We might also set/return sample rate here, etc.
|
||||
//
|
||||
// Wami.getSettings();
|
||||
// Wami.setSettings(options);
|
||||
//
|
||||
// Optional way to set up browser so that it's constantly listening
|
||||
// This is to prepend audio in case the user starts talking before
|
||||
// they click-to-talk.
|
||||
//
|
||||
// Wami.startListening()
|
||||
//
|
||||
Wami.setup = function(options) { |
||||
if (Wami.startRecording) { |
||||
// Wami's already defined.
|
||||
if (options.onReady) { |
||||
options.onReady(); |
||||
} |
||||
return; |
||||
} |
||||
|
||||
// Assumes that swfobject.js is included if Wami.swfobject isn't
|
||||
// already defined.
|
||||
Wami.swfobject = Wami.swfobject || swfobject; |
||||
|
||||
if (!Wami.swfobject) { |
||||
alert("Unable to find swfobject to help embed the SWF."); |
||||
} |
||||
|
||||
var _options; |
||||
setOptions(options); |
||||
embedWamiSWF(_options.id, Wami.nameCallback(delegateWamiAPI)); |
||||
|
||||
function supportsTransparency() { |
||||
// Detecting the OS is a big no-no in Javascript programming, but
|
||||
// I can't think of a better way to know if wmode is supported or
|
||||
// not... since NOT supporting it (like Flash on Ubuntu) is a bug.
|
||||
return (navigator.platform.indexOf("Linux") == -1); |
||||
} |
||||
|
||||
function setOptions(options) { |
||||
// Start with default options
|
||||
_options = { |
||||
swfUrl : "Wami.swf", |
||||
onReady : function() { |
||||
Wami.hide(); |
||||
}, |
||||
onSecurity : checkSecurity, |
||||
onError : function(error) { |
||||
alert(error); |
||||
} |
||||
}; |
||||
|
||||
if (typeof options == 'undefined') { |
||||
alert('Need at least an element ID to place the Flash object.'); |
||||
} |
||||
|
||||
if (typeof options == 'string') { |
||||
_options.id = options; |
||||
} else { |
||||
_options.id = options.id; |
||||
} |
||||
|
||||
if (options.swfUrl) { |
||||
_options.swfUrl = options.swfUrl; |
||||
} |
||||
|
||||
if (options.onReady) { |
||||
_options.onReady = options.onReady; |
||||
} |
||||
|
||||
if (options.onLoaded) { |
||||
_options.onLoaded = options.onLoaded; |
||||
} |
||||
|
||||
if (options.onSecurity) { |
||||
_options.onSecurity = options.onSecurity; |
||||
} |
||||
|
||||
if (options.onError) { |
||||
_options.onError = options.onError; |
||||
} |
||||
|
||||
// Create a DIV for the SWF under _options.id
|
||||
|
||||
var container = document.createElement('div'); |
||||
container.style.position = 'absolute'; |
||||
_options.cid = Wami.createID(); |
||||
container.setAttribute('id', _options.cid); |
||||
|
||||
var swfdiv = document.createElement('div'); |
||||
var id = Wami.createID(); |
||||
swfdiv.setAttribute('id', id); |
||||
|
||||
container.appendChild(swfdiv); |
||||
document.getElementById(_options.id).appendChild(container); |
||||
|
||||
_options.id = id; |
||||
} |
||||
|
||||
function checkSecurity() { |
||||
var settings = Wami.getSettings(); |
||||
if (settings.microphone.granted) { |
||||
_options.onReady(); |
||||
} else { |
||||
// Show any Flash settings panel you want:
|
||||
// http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/SecurityPanel.html
|
||||
Wami.showSecurity("privacy", "Wami.show", Wami |
||||
.nameCallback(_options.onSecurity), Wami |
||||
.nameCallback(_options.onError)); |
||||
} |
||||
} |
||||
|
||||
// Embed the WAMI SWF and call the named callback function when loaded.
|
||||
function embedWamiSWF(id, initfn) { |
||||
var flashVars = { |
||||
visible : false, |
||||
loadedCallback : initfn |
||||
} |
||||
|
||||
var params = { |
||||
allowScriptAccess : "always" |
||||
} |
||||
|
||||
if (supportsTransparency()) { |
||||
params.wmode = "transparent"; |
||||
} |
||||
|
||||
if (typeof console !== 'undefined') { |
||||
flashVars.console = true; |
||||
} |
||||
|
||||
var version = '10.0.0'; |
||||
document.getElementById(id).innerHTML = "WAMI requires Flash " |
||||
+ version |
||||
+ " or greater<br />https://get.adobe.com/flashplayer/"; |
||||
|
||||
// This is the minimum size due to the microphone security panel
|
||||
Wami.swfobject.embedSWF(_options.swfUrl, id, 214, 137, version, null, |
||||
flashVars, params); |
||||
|
||||
// Without this line, Firefox has a dotted outline of the flash
|
||||
Wami.swfobject.createCSS("#" + id, "outline:none"); |
||||
} |
||||
|
||||
// To check if the microphone settings were 'remembered', we
|
||||
// must actually embed an entirely new Wami client and check
|
||||
// whether its microphone is granted. If it is, it was remembered.
|
||||
function checkRemembered(finishedfn) { |
||||
var id = Wami.createID(); |
||||
var div = document.createElement('div'); |
||||
div.style.top = '-999px'; |
||||
div.style.left = '-999px'; |
||||
div.setAttribute('id', id); |
||||
var body = document.getElementsByTagName('body').item(0); |
||||
body.appendChild(div); |
||||
|
||||
var fn = Wami.nameCallback(function() { |
||||
var swf = document.getElementById(id); |
||||
Wami._remembered = swf.getSettings().microphone.granted; |
||||
Wami.swfobject.removeSWF(id); |
||||
eval(finishedfn + "()"); |
||||
}); |
||||
|
||||
embedWamiSWF(id, fn); |
||||
} |
||||
|
||||
// Attach all the audio methods to the Wami namespace in the callback.
|
||||
function delegateWamiAPI() { |
||||
var recorder = document.getElementById(_options.id); |
||||
|
||||
function delegate(name) { |
||||
Wami[name] = function() { |
||||
return recorder[name].apply(recorder, arguments); |
||||
} |
||||
} |
||||
delegate('startPlaying'); |
||||
delegate('stopPlaying'); |
||||
delegate('startRecording'); |
||||
delegate('stopRecording'); |
||||
delegate('startListening'); |
||||
delegate('stopListening'); |
||||
delegate('getRecordingLevel'); |
||||
delegate('getPlayingLevel'); |
||||
delegate('setSettings'); |
||||
|
||||
// Append extra information about whether mic settings are sticky
|
||||
Wami.getSettings = function() { |
||||
var settings = recorder.getSettings(); |
||||
settings.microphone.remembered = Wami._remembered; |
||||
return settings; |
||||
} |
||||
|
||||
Wami.showSecurity = function(panel, startfn, finishedfn, failfn) { |
||||
// Flash must be on top for this.
|
||||
var container = document.getElementById(_options.cid); |
||||
|
||||
var augmentedfn = Wami.nameCallback(function() { |
||||
checkRemembered(finishedfn); |
||||
container.style.cssText = "position: absolute;"; |
||||
}); |
||||
|
||||
container.style.cssText = "position: absolute; z-index: 99999"; |
||||
|
||||
recorder.showSecurity(panel, startfn, augmentedfn, failfn); |
||||
} |
||||
|
||||
Wami.show = function() { |
||||
if (!supportsTransparency()) { |
||||
recorder.style.visibility = "visible"; |
||||
} |
||||
} |
||||
|
||||
Wami.hide = function() { |
||||
// Hiding flash in all the browsers is tricky. Please read:
|
||||
// https://code.google.com/p/wami-recorder/wiki/HidingFlash
|
||||
if (!supportsTransparency()) { |
||||
recorder.style.visibility = "hidden"; |
||||
} |
||||
} |
||||
|
||||
// If we already have permissions, they were previously 'remembered'
|
||||
Wami._remembered = recorder.getSettings().microphone.granted; |
||||
|
||||
if (_options.onLoaded) { |
||||
_options.onLoaded(); |
||||
} |
||||
|
||||
if (!_options.noSecurityCheck) { |
||||
checkSecurity(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue