From a6bf9d7b9070c3995756a8f3ec3b4043b735147c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 28 Aug 2014 11:42:39 -0700 Subject: [PATCH 1/3] Handle URL recordings + some safety checks --- examples/PlayRecordingOnAC.js | 5 ++- examples/Recorder.js | 8 +++-- libraries/avatars/src/Recorder.cpp | 57 +++++++++++++++++++++++++----- libraries/avatars/src/Recorder.h | 7 ++-- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/examples/PlayRecordingOnAC.js b/examples/PlayRecordingOnAC.js index a68e60a6fa..9af5dd6f95 100644 --- a/examples/PlayRecordingOnAC.js +++ b/examples/PlayRecordingOnAC.js @@ -12,6 +12,7 @@ var filename = "http://your.recording.url"; var playFromCurrentLocation = true; +var loop = true; Avatar.faceModelURL = "http://public.highfidelity.io/models/heads/EvilPhilip_v7.fst"; Avatar.skeletonModelURL = "http://public.highfidelity.io/models/skeletons/Philip_Carl_Body_A-Pose.fst"; @@ -30,7 +31,9 @@ function update(event) { return; } if (count == 0) { - Avatar.startPlaying(playFromCurrentLocation); + Avatar.setPlayFromCurrentLocation(playFromCurrentLocation); + Avatar.setLoop(loop); + Avatar.startPlaying(); Avatar.play(); Vec3.print("Playing from ", Avatar.position); diff --git a/examples/Recorder.js b/examples/Recorder.js index cf4b422926..dad8db8cb4 100644 --- a/examples/Recorder.js +++ b/examples/Recorder.js @@ -161,12 +161,16 @@ function mousePressEvent(event) { } else if (saveIcon === toolBar.clicked(clickedOverlay)) { if (!MyAvatar.isRecording()) { recordingFile = Window.save("Save recording to file", ".", "*.rec"); - MyAvatar.saveRecording(recordingFile); + if (recordingFile != "") { + MyAvatar.saveRecording(recordingFile); + } } } else if (loadIcon === toolBar.clicked(clickedOverlay)) { if (!MyAvatar.isRecording()) { recordingFile = Window.browse("Load recorcding from file", ".", "*.rec"); - MyAvatar.loadRecording(recordingFile); + if (recordingFile != "") { + MyAvatar.loadRecording("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/bartender.rec"); + } } } else { diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp index 69cde6560e..15ac6ede6c 100644 --- a/libraries/avatars/src/Recorder.cpp +++ b/libraries/avatars/src/Recorder.cpp @@ -10,7 +10,9 @@ // #include +#include +#include #include #include #include @@ -57,6 +59,25 @@ Recording::~Recording() { delete _audio; } +int Recording::getLength() const { + if (_timestamps.isEmpty()) { + return 0; + } + return _timestamps.last(); +} + +qint32 Recording::getFrameTimestamp(int i) const { + if (i >= _timestamps.size()) { + return getLength(); + } + return _timestamps[i]; +} + +const RecordingFrame& Recording::getFrame(int i) const { + assert(i < _timestamps.size()); + return _frames[i]; +} + void Recording::addFrame(int timestamp, RecordingFrame &frame) { _timestamps << timestamp; _frames << frame; @@ -492,18 +513,38 @@ void writeRecordingToFile(RecordingPointer recording, QString filename) { } RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filename) { - qDebug() << "Reading recording from " << filename << "."; + QElapsedTimer timer; + timer.start(); if (!recording) { recording.reset(new Recording()); } - QElapsedTimer timer; - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)){ - return recording; + QByteArray byteArray; + QUrl url(filename); + if (url.scheme() == "http" || url.scheme() == "https" || url.scheme() == "ftp") { + qDebug() << "Downloading recording at" << url; + NetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkReply* reply = networkAccessManager.get(QNetworkRequest(url)); + QEventLoop loop; + QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit())); + loop.exec(); + if (reply->error() != QNetworkReply::NoError) { + qDebug() << "Error while downloading recording: " << reply->error(); + reply->deleteLater(); + return recording; + } + byteArray = reply->readAll(); + reply->deleteLater(); + } else { + qDebug() << "Reading recording from " << filename << "."; + QFile file(filename); + if (!file.open(QIODevice::ReadOnly)){ + return recording; + } + byteArray = file.readAll(); + file.close(); } - timer.start(); - QDataStream fileStream(&file); + QDataStream fileStream(byteArray); fileStream >> recording->_timestamps; RecordingFrame baseFrame; @@ -603,7 +644,7 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filen recording->addAudioPacket(audioArray); - qDebug() << "Read " << file.size() << " bytes in " << timer.elapsed() << " ms."; + qDebug() << "Read " << byteArray.size() << " bytes in " << timer.elapsed() << " ms."; return recording; } diff --git a/libraries/avatars/src/Recorder.h b/libraries/avatars/src/Recorder.h index 1f41672749..447c3eabe8 100644 --- a/libraries/avatars/src/Recorder.h +++ b/libraries/avatars/src/Recorder.h @@ -81,11 +81,11 @@ public: ~Recording(); bool isEmpty() const { return _timestamps.isEmpty(); } - int getLength() const { return _timestamps.last(); } // in ms + int getLength() const; // in ms int getFrameNumber() const { return _frames.size(); } - qint32 getFrameTimestamp(int i) const { return _timestamps[i]; } - const RecordingFrame& getFrame(int i) const { return _frames[i]; } + qint32 getFrameTimestamp(int i) const; + const RecordingFrame& getFrame(int i) const; Sound* getAudio() const { return _audio; } protected: @@ -97,7 +97,6 @@ private: QVector _timestamps; QVector _frames; - bool _stereo; Sound* _audio; friend class Recorder; From 1a131b0e29584cd5ce5db2703fc2bb627e353cef Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 28 Aug 2014 11:50:18 -0700 Subject: [PATCH 2/3] Removed some debug + fixed some checks --- examples/Recorder.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/examples/Recorder.js b/examples/Recorder.js index dad8db8cb4..12d72fae3b 100644 --- a/examples/Recorder.js +++ b/examples/Recorder.js @@ -139,8 +139,6 @@ function moveUI() { function mousePressEvent(event) { clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); - print("Status: isPlaying=" + MyAvatar.isPlaying() + ", isRecording=" + MyAvatar.isRecording()); - if (recordIcon === toolBar.clicked(clickedOverlay) && !MyAvatar.isPlaying()) { if (!MyAvatar.isRecording()) { MyAvatar.startRecording(); @@ -161,15 +159,16 @@ function mousePressEvent(event) { } else if (saveIcon === toolBar.clicked(clickedOverlay)) { if (!MyAvatar.isRecording()) { recordingFile = Window.save("Save recording to file", ".", "*.rec"); - if (recordingFile != "") { + if (recordingFile != null) { MyAvatar.saveRecording(recordingFile); } } } else if (loadIcon === toolBar.clicked(clickedOverlay)) { if (!MyAvatar.isRecording()) { recordingFile = Window.browse("Load recorcding from file", ".", "*.rec"); - if (recordingFile != "") { - MyAvatar.loadRecording("https://s3-us-west-1.amazonaws.com/highfidelity-public/ozan/bartender.rec"); + if (recordingFile != "null") { + } else { + MyAvatar.loadRecording(recordingFile); } } } else { From 9b5b83117f4ba0617bc3cb77f03983f31ed70600 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 29 Aug 2014 14:25:05 -0700 Subject: [PATCH 3/3] CR --- examples/PlayRecordingOnAC.js | 2 ++ examples/Recorder.js | 9 +++++---- libraries/avatars/src/Recorder.cpp | 8 +++++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/examples/PlayRecordingOnAC.js b/examples/PlayRecordingOnAC.js index 9af5dd6f95..5a283a2557 100644 --- a/examples/PlayRecordingOnAC.js +++ b/examples/PlayRecordingOnAC.js @@ -19,6 +19,8 @@ Avatar.skeletonModelURL = "http://public.highfidelity.io/models/skeletons/Philip // Set position here if playFromCurrentLocation is true Avatar.position = { x:1, y: 1, z: 1 }; +Avatar.orientation = Quat.fromPitchYawRollDegrees(0, 0, 0); +Avatar.scale = 1.0; Agent.isAvatar = true; diff --git a/examples/Recorder.js b/examples/Recorder.js index 12d72fae3b..7ecf0e2640 100644 --- a/examples/Recorder.js +++ b/examples/Recorder.js @@ -12,6 +12,8 @@ Script.include("toolBars.js"); var recordingFile = "recording.rec"; +var playFromCurrentLocation = true; +var loop = true; var windowDimensions = Controller.getViewportDimensions(); var TOOL_ICON_URL = "http://s3-us-west-1.amazonaws.com/highfidelity-public/images/tools/"; @@ -152,8 +154,8 @@ function mousePressEvent(event) { if (MyAvatar.isPlaying()) { MyAvatar.stopPlaying(); } else { - MyAvatar.setPlayFromCurrentLocation(true); - MyAvatar.setPlayerLoop(true); + MyAvatar.setPlayFromCurrentLocation(playFromCurrentLocation); + MyAvatar.setPlayerLoop(loop); MyAvatar.startPlaying(true); } } else if (saveIcon === toolBar.clicked(clickedOverlay)) { @@ -167,8 +169,7 @@ function mousePressEvent(event) { if (!MyAvatar.isRecording()) { recordingFile = Window.browse("Load recorcding from file", ".", "*.rec"); if (recordingFile != "null") { - } else { - MyAvatar.loadRecording(recordingFile); + MyAvatar.loadRecording(recordingFile); } } } else { diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp index 15ac6ede6c..70568a3487 100644 --- a/libraries/avatars/src/Recorder.cpp +++ b/libraries/avatars/src/Recorder.cpp @@ -515,9 +515,6 @@ void writeRecordingToFile(RecordingPointer recording, QString filename) { RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filename) { QElapsedTimer timer; timer.start(); - if (!recording) { - recording.reset(new Recording()); - } QByteArray byteArray; QUrl url(filename); @@ -544,6 +541,11 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filen byteArray = file.readAll(); file.close(); } + + if (!recording) { + recording.reset(new Recording()); + } + QDataStream fileStream(byteArray); fileStream >> recording->_timestamps;