Line data Source code
1 : /* 2 : * Copyright (C) 2004-2024 Savoir-faire Linux Inc. 3 : * 4 : * Author: Hugo Lefeuvre <hugo.lefeuvre@savoirfairelinux.com> 5 : * Author: Philippe Gorley <philippe.gorley@savoirfairelinux.com> 6 : * 7 : * This program is free software; you can redistribute it and/or modify 8 : * it under the terms of the GNU General Public License as published by 9 : * the Free Software Foundation; either version 3 of the License, or 10 : * (at your option) any later version. 11 : * 12 : * This program is distributed in the hope that it will be useful, 13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 : * GNU General Public License for more details. 16 : * 17 : * You should have received a copy of the GNU General Public License 18 : * along with this program; if not, write to the Free Software 19 : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 : */ 21 : 22 : #include "localrecorder.h" 23 : #include "audio/ringbufferpool.h" 24 : #include "audio/ringbuffer.h" 25 : #include "client/videomanager.h" 26 : #include "media_stream.h" 27 : #include "manager.h" 28 : #include "logger.h" 29 : #include "client/videomanager.h" 30 : 31 : namespace jami { 32 : 33 0 : LocalRecorder::LocalRecorder(const std::string& inputUri) 34 : { 35 0 : inputUri_ = inputUri; 36 0 : isAudioOnly_ = inputUri_.empty(); 37 0 : recorder_->audioOnly(isAudioOnly_); 38 0 : } 39 : 40 0 : LocalRecorder::~LocalRecorder() 41 : { 42 0 : if (isRecording()) 43 0 : stopRecording(); 44 0 : } 45 : 46 : void 47 0 : LocalRecorder::setPath(const std::string& path) 48 : { 49 0 : if (isRecording()) { 50 0 : JAMI_ERR("can't set path while recording"); 51 0 : return; 52 : } 53 : 54 0 : recorder_->setPath(path); 55 0 : path_ = path; 56 : } 57 : 58 : bool 59 0 : LocalRecorder::startRecording() 60 : { 61 0 : if (isRecording()) { 62 0 : JAMI_ERR("recording already started!"); 63 0 : return false; 64 : } 65 : 66 0 : if (path_.empty()) { 67 0 : JAMI_ERR("could not start recording (path not set)"); 68 0 : return false; 69 : } 70 : 71 0 : if (!recorder_) { 72 0 : JAMI_ERR("could not start recording (no recorder)"); 73 0 : return false; 74 : } 75 : 76 : // audio recording 77 : // create read offset in RingBuffer 78 0 : Manager::instance().getRingBufferPool().bindHalfDuplexOut(path_, RingBufferPool::DEFAULT_ID); 79 : 80 0 : audioInput_ = getAudioInput(path_); 81 0 : audioInput_->setFormat(AudioFormat::STEREO()); 82 0 : audioInput_->attach(recorder_->addStream(audioInput_->getInfo())); 83 0 : audioInput_->switchInput(""); 84 : 85 : #ifdef ENABLE_VIDEO 86 : // video recording 87 0 : if (!isAudioOnly_) { 88 0 : videoInput_ = std::static_pointer_cast<video::VideoInput>(getVideoInput(inputUri_)); 89 0 : if (videoInput_) { 90 0 : videoInput_->attach(recorder_->addStream(videoInput_->getInfo())); 91 : } else { 92 0 : JAMI_ERR() << "Unable to record video (no video input)"; 93 0 : return false; 94 : } 95 : } 96 : #endif 97 : 98 0 : return Recordable::startRecording(path_); 99 : } 100 : 101 : void 102 0 : LocalRecorder::stopRecording() 103 : { 104 0 : if (auto ob = recorder_->getStream(audioInput_->getInfo().name)) 105 0 : audioInput_->detach(ob); 106 : #ifdef ENABLE_VIDEO 107 0 : if (videoInput_) 108 0 : if (auto ob = recorder_->getStream(videoInput_->getInfo().name)) 109 0 : videoInput_->detach(ob); 110 : #endif 111 0 : Manager::instance().getRingBufferPool().unBindHalfDuplexOut(path_, RingBufferPool::DEFAULT_ID); 112 : // NOTE stopRecording should be last call to avoid data races 113 0 : Recordable::stopRecording(); 114 0 : } 115 : 116 : } // namespace jami