diff --git a/examples/PlayRecordingOnAC.js b/examples/PlayRecordingOnAC.js index a68e60a6fa..5a283a2557 100644 --- a/examples/PlayRecordingOnAC.js +++ b/examples/PlayRecordingOnAC.js @@ -12,12 +12,15 @@ 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"; // 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; @@ -30,7 +33,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..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/"; @@ -139,8 +141,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(); @@ -154,19 +154,23 @@ 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)) { if (!MyAvatar.isRecording()) { recordingFile = Window.save("Save recording to file", ".", "*.rec"); - MyAvatar.saveRecording(recordingFile); + if (recordingFile != null) { + 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 != "null") { + MyAvatar.loadRecording(recordingFile); + } } } else { diff --git a/libraries/avatars/src/Recorder.cpp b/libraries/avatars/src/Recorder.cpp index 69cde6560e..70568a3487 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,40 @@ void writeRecordingToFile(RecordingPointer recording, QString filename) { } RecordingPointer readRecordingFromFile(RecordingPointer recording, QString filename) { - qDebug() << "Reading recording from " << filename << "."; + QElapsedTimer timer; + timer.start(); + + 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(); + } + if (!recording) { recording.reset(new Recording()); } - QElapsedTimer timer; - QFile file(filename); - if (!file.open(QIODevice::ReadOnly)){ - return recording; - } - timer.start(); - QDataStream fileStream(&file); + QDataStream fileStream(byteArray); fileStream >> recording->_timestamps; RecordingFrame baseFrame; @@ -603,7 +646,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;