AlexaClientSDK  3.0.0
A cross-platform, modular SDK for interacting with the Alexa Voice Service
MediaPlayer.h
Go to the documentation of this file.
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0/
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #ifndef ALEXA_CLIENT_SDK_MEDIAPLAYER_GSTREAMERMEDIAPLAYER_INCLUDE_MEDIAPLAYER_MEDIAPLAYER_H_
17 #define ALEXA_CLIENT_SDK_MEDIAPLAYER_GSTREAMERMEDIAPLAYER_INCLUDE_MEDIAPLAYER_MEDIAPLAYER_H_
18 
19 #include <atomic>
20 #include <chrono>
21 #include <cstdint>
22 #include <functional>
23 #include <future>
24 #include <memory>
25 #include <queue>
26 #include <string>
27 #include <thread>
28 #include <unordered_set>
29 #include <vector>
30 
31 #include <gst/gst.h>
32 #include <gst/app/gstappsrc.h>
33 #include <gst/base/gstbasesink.h>
34 #include <gst/controller/gsttimedvaluecontrolsource.h>
35 
44 
49 
50 namespace alexaClientSDK {
51 namespace mediaPlayer {
52 
53 typedef std::vector<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface::TagKeyValueType> VectorOfTags;
54 
62  , private PipelineInterface
67  , public std::enable_shared_from_this<MediaPlayer> {
68 public:
78  static std::shared_ptr<MediaPlayer> create(
79  std::shared_ptr<avsCommon::sdkInterfaces::HTTPContentFetcherInterfaceFactoryInterface> contentFetcherFactory =
80  nullptr,
81  bool enableEqualizer = false,
82  std::string name = "",
83  bool enableLiveMode = false);
87  ~MediaPlayer();
88 
92  std::shared_ptr<avsCommon::avs::attachment::AttachmentReader> attachmentReader,
93  const avsCommon::utils::AudioFormat* format = nullptr,
96 
98  std::shared_ptr<avsCommon::avs::attachment::AttachmentReader> attachmentReader,
99  std::chrono::milliseconds offsetAdjustment,
100  const avsCommon::utils::AudioFormat* format = nullptr,
103 
105  const std::string& url,
106  std::chrono::milliseconds offset = std::chrono::milliseconds::zero(),
108  bool repeat = false,
109  const avsCommon::utils::mediaPlayer::PlaybackContext& playbackContext =
111 
113  std::shared_ptr<std::istream> stream,
114  bool repeat = false,
117 
118  bool play(SourceId id) override;
119  bool stop(SourceId id) override;
120  bool pause(SourceId id) override;
125  bool resume(SourceId id) override;
126  uint64_t getNumBytesBuffered() override;
127  std::chrono::milliseconds getOffset(SourceId id) override;
129  SourceId id) override;
130  void addObserver(std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface> observer) override;
131  void removeObserver(std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface> observer) override;
133 
136  bool setVolume(int8_t volume) override;
137  bool setMute(bool mute) override;
140 
143  void setAppSrc(GstAppSrc* appSrc) override;
144  GstAppSrc* getAppSrc() const override;
145  void setDecoder(GstElement* decoder) override;
146  GstElement* getDecoder() const override;
147  GstElement* getPipeline() const override;
148  guint queueCallback(const std::function<gboolean()>* callback) override;
149  guint attachSource(GSource* source) override;
150  gboolean removeSource(guint tag) override;
152 
155  void onError() override;
156  void onWriteComplete() override;
158 
161  void onFirstByteRead() override;
163 
164  void doShutdown() override;
165 
166 private:
184  struct AudioPipeline {
186  GstAppSrc* appsrc;
187 
189  GstElement* decoder;
190 
192  GstElement* decodedQueue;
193 
195  GstElement* converter;
196 
198  GstElement* volume;
199 
201  GstElement* fadeIn;
202 
204  GstElement* resample;
205 
207  GstElement* caps;
208 
210  GstElement* equalizer;
211 
213  GstElement* audioSink;
214 
216  GstElement* pipeline;
217 
219  AudioPipeline() :
220  appsrc{nullptr},
221  decoder{nullptr},
222  decodedQueue{nullptr},
223  converter{nullptr},
224  volume{nullptr},
225  fadeIn{nullptr},
226  resample{nullptr},
227  caps{nullptr},
228  equalizer{nullptr},
229  audioSink{nullptr},
230  pipeline{nullptr} {};
231  };
232 
241  MediaPlayer(
242  std::shared_ptr<avsCommon::sdkInterfaces::HTTPContentFetcherInterfaceFactoryInterface> contentFetcherFactory,
243  bool enableEqualizer,
245  bool enableLiveMode);
246 
252  bool configureSource(const avsCommon::utils::mediaPlayer::SourceConfig& config);
253 
257  void workerLoop();
258 
264  bool init();
265 
272  static gboolean onCallback(const std::function<gboolean()>* callback);
273 
280  bool setupPipeline();
281 
288  void tearDownTransientPipelineElements(bool notifyStop);
289 
293  void resetPipeline();
294 
305  static void onPadAdded(GstElement* src, GstPad* pad, gpointer mediaPlayer);
306 
314  void handlePadAdded(std::promise<void>* promise, GstElement* src, GstPad* pad);
315 
326  static gboolean onBusMessage(GstBus* bus, GstMessage* msg, gpointer mediaPlayer);
327 
335  gboolean handleBusMessage(GstMessage* message);
336 
343  std::unique_ptr<const VectorOfTags> collectTags(GstMessage* message);
344 
350  void sendStreamTagsToObserver(std::unique_ptr<const VectorOfTags> vectorOfTags);
351 
361  void handleSetAttachmentReaderSource(
362  std::shared_ptr<avsCommon::avs::attachment::AttachmentReader> reader,
364  std::promise<SourceId>* promise,
365  const avsCommon::utils::AudioFormat* audioFormat = nullptr,
366  bool repeat = false);
367 
377  void handleSetUrlSource(
378  const std::string& url,
379  std::chrono::milliseconds offset,
381  std::promise<SourceId>* promise,
382  bool repeat);
383 
392  void handleSetIStreamSource(
393  std::shared_ptr<std::istream> stream,
394  bool repeat,
396  std::promise<SourceId>* promise);
397 
403  void handleSetVolumeInternal(gdouble gstVolume);
404 
411  void handleSetVolume(std::promise<bool>* promise, int8_t volume);
412 
419  void handleAdjustVolume(std::promise<bool>* promise, int8_t delta);
420 
427  void handleSetMute(std::promise<bool>* promise, bool mute);
428 
435  void handleGetSpeakerSettings(
436  std::promise<bool>* promise,
438 
446  void handlePlay(SourceId id, std::promise<bool>* promise);
447 
455  void handleStop(SourceId id, std::promise<bool>* promise);
456 
464  void handlePause(SourceId id, std::promise<bool>* promise);
465 
473  void handleResume(SourceId id, std::promise<bool>* promise);
474 
481  void handleGetOffset(SourceId id, std::promise<std::chrono::milliseconds>* promise);
482 
488  std::chrono::milliseconds handleGetOffsetImmediately(SourceId id);
489 
496  avsCommon::utils::mediaPlayer::MediaPlayerState getMediaPlayerStateInternal(SourceId id);
497 
504  void handleAddObserver(
505  std::promise<void>* promise,
506  std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface> observer);
507 
514  void handleRemoveObserver(
515  std::promise<void>* promise,
516  std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface> observer);
517 
521  void sendPlaybackStarted();
522 
526  void sendPlaybackFinished();
527 
531  void sendPlaybackPaused();
532 
536  void sendPlaybackResumed();
537 
541  void sendPlaybackStopped();
542 
549  void sendPlaybackError(
551  const std::string& error);
552 
556  void sendBufferingComplete();
557 
561  void sendBufferUnderrun();
562 
566  void sendBufferRefilled();
567 
574  bool queryIsSeekable(bool* isSeekable);
575 
582  bool queryBufferPercent(gint* percent);
583 
589  bool seek();
590 
597  bool validateSourceAndId(SourceId id);
598 
605  static gboolean onErrorCallback(gpointer pointer);
606 
613  static gboolean onWriteCompleteCallback(gpointer pointer);
614 
620  std::chrono::milliseconds getCurrentStreamOffset();
621 
625  void cleanUpSource();
626 
629  void setEqualizerBandLevels(acsdkEqualizerInterfaces::EqualizerBandLevelMap bandLevelMap) override;
630  int getMinimumBandLevel() override;
631  int getMaximumBandLevel() override;
633 
640  int clampEqualizerLevel(int level);
641 
643  std::mutex m_operationMutex;
644 
646  gdouble m_lastVolume;
647 
649  bool m_isMuted;
650 
652  std::shared_ptr<playlistParser::UrlContentToAttachmentConverter> m_urlConverter;
653 
656  std::shared_ptr<alexaClientSDK::avsCommon::avs::attachment::AttachmentReader> m_parkedReader;
657 
659  OffsetManager m_offsetManager;
660 
662  std::shared_ptr<avsCommon::sdkInterfaces::HTTPContentFetcherInterfaceFactoryInterface> m_contentFetcherFactory;
663 
665  bool m_equalizerEnabled;
666 
668  AudioPipeline m_pipeline;
669 
671  GMainLoop* m_mainLoop;
672 
673  // Main loop thread
674  std::thread m_mainLoopThread;
675 
677  guint m_busWatchId;
678 
680  GMainContext* m_workerContext;
681 
683  bool m_playbackStartedSent;
684 
686  bool m_playbackFinishedSent;
687 
689  bool m_isPaused;
690 
692  bool m_isBufferUnderrun;
693 
695  std::unordered_set<std::shared_ptr<avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface>> m_playerObservers;
696 
698  std::shared_ptr<SourceInterface> m_source;
699 
701  SourceId m_currentId;
702 
704  bool m_isFakeSink;
705 
707  bool m_playPending;
708 
710  bool m_pausePending;
711 
713  bool m_resumePending;
714 
716  bool m_pauseImmediately;
717 
719  std::chrono::milliseconds m_offsetBeforeTeardown;
720 
722  const bool m_isLiveMode;
723 
725  std::chrono::milliseconds m_offsetAdjustment;
726 };
727 
728 } // namespace mediaPlayer
729 } // namespace alexaClientSDK
730 
731 #endif // ALEXA_CLIENT_SDK_MEDIAPLAYER_GSTREAMERMEDIAPLAYER_INCLUDE_MEDIAPLAYER_MEDIAPLAYER_H_
std::unordered_map< EqualizerBand, int, avsCommon::utils::functional::EnumClassHash > EqualizerBandLevelMap
A collection of bands with their level values. This is an alias for EqualizerBand to band level (int)...
Definition: EqualizerTypes.h:77
GstElement * getPipeline() const override
bool stop(SourceId id) override
std::vector< avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface::TagKeyValueType > VectorOfTags
Definition: MediaPlayer.h:53
SourceConfig emptySourceConfig()
Definition: SourceConfig.h:98
bool getSpeakerSettings(avsCommon::sdkInterfaces::SpeakerInterface::SpeakerSettings *settings) override
void removeObserver(std::shared_ptr< avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface > observer) override
uint64_t SourceId
A type that identifies which source is currently being operated on. This must be unique across all in...
Definition: MediaPlayerInterface.h:69
::std::string string
Definition: gtest-port.h:1097
bool setVolume(int8_t volume) override
SourceId setSource(std::shared_ptr< avsCommon::avs::attachment::AttachmentReader > attachmentReader, const avsCommon::utils::AudioFormat *format=nullptr, const avsCommon::utils::mediaPlayer::SourceConfig &config=avsCommon::utils::mediaPlayer::emptySourceConfig()) override
GstElement * getDecoder() const override
void setAppSrc(GstAppSrc *appSrc) override
MediaType
Definition: MediaType.h:29
Definition: OffsetManager.h:27
GstAppSrc * getAppSrc() const override
guint attachSource(GSource *source) override
void addObserver(std::shared_ptr< avsCommon::utils::mediaPlayer::MediaPlayerObserverInterface > observer) override
bool pause(SourceId id) override
guint queueCallback(const std::function< gboolean()> *callback) override
bool resume(SourceId id) override
Definition: MediaPlayer.h:58
Class to observe errors that arise from converting a URL to to an Attachment.
Definition: UrlContentToAttachmentConverter.h:44
Whether or not curl logs should be emitted.
Definition: AVSConnectionManager.h:36
void setDecoder(GstElement *decoder) override
bool play(SourceId id) override
type
Definition: upload.py:443
static std::shared_ptr< MediaPlayer > create(std::shared_ptr< avsCommon::sdkInterfaces::HTTPContentFetcherInterfaceFactoryInterface > contentFetcherFactory=nullptr, bool enableEqualizer=false, std::string name="", bool enableLiveMode=false)
ErrorType
Identifies the specific type of error in a PlaybackFailed event.
Definition: ErrorTypes.h:28
Class to allow notification when writing to the attachment is complete.
Definition: UrlContentToAttachmentConverter.h:58
std::chrono::milliseconds getOffset(SourceId id) override
Definition: PipelineInterface.h:33
tuple message
Definition: gtest_output_test.py:331
Definition: SourceObserverInterface.h:25
avsCommon::utils::Optional< avsCommon::utils::mediaPlayer::MediaPlayerState > getMediaPlayerState(SourceId id) override
gboolean removeSource(guint tag) override

AlexaClientSDK 3.0.0 - Copyright 2016-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0