正如前面提到的,API化包含两方面含义:对物理世界的数据化,以及数据的物理化。前者指的就是通过各种各样的传感器,将物理世界的各种表相转换为可以被算法处理的数据信息,比如各种监控摄像头所存储的校园内的影像信息。后者指的是将以上数据处理以后的结果转换为实际的物理行为,比如荷兰设计师设计的可以跟随人的椅子,Take a seat。
另一方面,美剧《Person of interests》讲了一个大数据的另一面,一个令人很恐慌的黑暗面。政府建造了一个监控所有数据的机器,由此发展出了智能,反过头来干预现实人们的生活。就目前的技术发展来看,很有可能片中的情况已经发生,只是我们被机器“照顾”的很“正常”,并没有意识到另一个“大意识”的存在。
[code lang=text]
—Responds—
OAuth HTTP
path Scope Code Payload ◆ Make LB Cloud…
—- —– —- ——— —————-
/devices
GET read 200 [<devices>] return a list of the user’s devices
/{device_id}
GET read 200 <device> return device model
PUT admin 200 <device> update device model
POST admin 201 <device> activate device, is then associated to the user
DELETE admin 200 <device> deactivate device, is then associated to no body
/output
POST write 200 output some voltage on the given device
/subscriptions
GET read 200 [<subs>] return device's subscriptions
POST read 201 publish given device events to given endpoint
DELETE read 200 stop publishing given device events to a given endpoint
[/code]
- (void)viewDidLoad {
[super viewDidLoad];
// Data notifications are received through NSNotificationCenter.
// Posted whenever a TLMMyo connects
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didConnectDevice:)
name:TLMHubDidConnectDeviceNotification
object:nil];
// Posted whenever a TLMMyo disconnects.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didDisconnectDevice:)
name:TLMHubDidDisconnectDeviceNotification
object:nil];
...
// Posted when a new pose is available from a TLMMyo.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didReceivePoseChange:)
name:TLMMyoDidReceivePoseChangedNotification
object:nil];
}
- (void)didReceivePoseChange:(NSNotification *)notification {
// Retrieve the pose from the NSNotification's userInfo with the kTLMKeyPose key.
TLMPose *pose = notification.userInfo[kTLMKeyPose];
self.currentPose = pose;
// Handle the cases of the TLMPoseType enumeration, and change the color of helloLabel based on the pose we receive.
switch (pose.type) {
case TLMPoseTypeUnknown:
case TLMPoseTypeRest:
case TLMPoseTypeDoubleTap:
// Changes helloLabel's font to Helvetica Neue when the user is in a rest or unknown pose.
self.helloLabel.text = @"Hello Myo";
self.helloLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:50];
self.helloLabel.textColor = [UIColor blackColor];
break;
case TLMPoseTypeFist:
// Changes helloLabel's font to Noteworthy when the user is in a fist pose.
self.helloLabel.text = @"Fist";
self.helloLabel.font = [UIFont fontWithName:@"Noteworthy" size:50];
self.helloLabel.textColor = [UIColor greenColor];
break;
case TLMPoseTypeWaveIn:
// Changes helloLabel's font to Courier New when the user is in a wave in pose.
self.helloLabel.text = @"Wave In";
self.helloLabel.font = [UIFont fontWithName:@"Courier New" size:50];
self.helloLabel.textColor = [UIColor greenColor];
break;
case TLMPoseTypeWaveOut:
// Changes helloLabel's font to Snell Roundhand when the user is in a wave out pose.
self.helloLabel.text = @"Wave Out";
self.helloLabel.font = [UIFont fontWithName:@"Snell Roundhand" size:50];
self.helloLabel.textColor = [UIColor greenColor];
break;
case TLMPoseTypeFingersSpread:
// Changes helloLabel's font to Chalkduster when the user is in a fingers spread pose.
self.helloLabel.text = @"Fingers Spread";
self.helloLabel.font = [UIFont fontWithName:@"Chalkduster" size:50];
self.helloLabel.textColor = [UIColor greenColor];
break;
}
// Unlock the Myo whenever we receive a pose
if (pose.type == TLMPoseTypeUnknown || pose.type == TLMPoseTypeRest) {
// Causes the Myo to lock after a short period.
[pose.myo unlockWithType:TLMUnlockTypeTimed];
} else {
// Keeps the Myo unlocked until specified.
// This is required to keep Myo unlocked while holding a pose, but if a pose is not being held, use
// TLMUnlockTypeTimed to restart the timer.
[pose.myo unlockWithType:TLMUnlockTypeHold];
// Indicates that a user action has been performed.
[pose.myo indicateUserAction];
}
}
这是一个非官方的Google TTS库,但是文档里说到Playbackwill only work when running the script locally as Google's server only returns audio if you can prevent the browser from sending the Referrer HTTP Header to their server,看来是Google对referrer做了检查。不过这点后面看起来似乎没那么严格。
我们先用个简单的页面测试一下播音(注意科学上网),播放一小段中文听起来还不错。
var tts = new GoogleTTS('zh-CN');
tts.play('你好呀呀呀呀', 'zh-CN', function (err) {
console.log('complete');
});
拿小说
这就用到了之前介绍的技术Import.io。安装桌面应用,Create API from URL 2.0,找一个详情页,比如第一百五十三章 照片上的三口之家,选择文章内容的div改column名为text。就可以create啦。
看一下文章的url是连续的,好,那就用node写个循环,然后用AVOS把文章内容保存下来。
// ...省略初始化
var Chapter = AV.Object.extend('Chapter');
_.each(_.map(_.range(27888, 27996), function (num) {
return 'http://book.guidaye.com/daomu/85/' + num + '.html';
}), function (url) {
var q = new AV.Query(Chapter);
q.equalTo('url', url);
q.first()
.then(function (chapter) {
if (chapter) {
console.log('exists,%s',url);
} else {
unirest.get('https://api.import.io/store/data/c2f29086-18a8-4c7b-9d5d-6ea1d54a9bc5/_query')
.query({
'input/webpage/url': url,
'_user': '[UER]',
'_apikey': '[API KEY]'
})
.end(function (response) {
new Chapter({
url: response.body.pageUrl,
text: response.body.results[0].text
}).save().then(function () {
console.log('done,%s', response.body.pageUrl);
}, function (err) {
console.log(err);
})
})
}
})
})
跑一遍基本就ok啦,如果有发生错误的就再执行一遍验证下。
读小说
好,我们要一个前端页面来读小说。
<div id='playing'></div>
AV.initialize("[APPID]", "[APPKEY]");
function speakChapter(chapterNum) {
var url = 'http://book.guidaye.com/daomu/85/' + chapterNum + '.html';
var Chapter = AV.Object.extend('Chapter');
var query = new AV.Query(Chapter);
query.equalTo('url', url);
query.first()
.then(function (chapter) {
document.getElementById('playing').text = "playing:" + url;
console.log('playing,%s', chapter.get('url'));
var tts = new GoogleTTS('zh-CN');
tts.play(chapter.get('text'), "zh-CN", function (err) {
console.log('complete,%s', chapter.url);
});
}, function (err) {
console.log(err);
})
}
//speakChapter(27889);