audiotoggle | #Mobile Application | Cordova plugin

 by   alongubkin Java Updated: 9 months ago - Current License: Apache-2.0

Download this library from

Build Applications

kandi X-RAY | audiotoggle REVIEW AND RATINGS

Cordova plugin for switching between speaker and earpiece when playing audio.

kandi-support
Support

  • audiotoggle has a low active ecosystem.
  • It has 47 star(s) with 71 fork(s).
  • It had no major release in the last 12 months.
  • On average issues are closed in 95 days.
  • It has a neutral sentiment in the developer community.

quality kandi
Quality

  • audiotoggle has 0 bugs and 0 code smells.

security
Security

  • audiotoggle has no vulnerabilities reported, and its dependent libraries have no vulnerabilities reported.
  • audiotoggle code analysis shows 0 unresolved vulnerabilities.
  • There are 0 security hotspots that need review.

license
License

  • audiotoggle is licensed under the Apache-2.0 License. This license is Permissive.
  • Permissive licenses have the least restrictions, and you can use them in most projects.

build
Reuse

  • audiotoggle releases are not available. You will need to build from source code and install.
  • audiotoggle has no build file. You will be need to create the build yourself to build the component from source.
  • audiotoggle saves you 30 person hours of effort in developing the same functionality from scratch.
  • It has 83 lines of code, 2 functions and 3 files with 0 % test coverage
  • It has medium code complexity. Code complexity directly impacts maintainability of the code.
Top functions reviewed by kandi - BETA

kandi has reviewed audiotoggle and discovered the below as its top functions. This is intended to give you an instant insight into audiotoggle implemented functionality, and help decide if they suit your requirements.

  • Sets the audio mode .
  • Sets the audio mode .

audiotoggle Key Features

Cordova plugin for switching between speaker and earpiece when playing audio

audiotoggle examples and code snippets

  • AudioToggle
  • Usage
  • Pop up doesn't disappear when I click "Stop Capture" button of screen recording functionality
  • Ionic Cordova Plugin AudioToggle Not Imported Correctly
  • Pan audio in cordova (play only out of left / right headphone)

AudioToggle

cordova plugin add com.dooble.audiotoggle

Usage

AudioToggle.setAudioMode(AudioToggle.SPEAKER);
// or
AudioToggle.setAudioMode(AudioToggle.EARPIECE);

Pop up doesn't disappear when I click "Stop Capture" button of screen recording functionality

new Vue({
  // ...
  data () {
    return {
      // ...
      individualAudioStreams: [],
      // ...
    }
  },
  methods: {
    startBtn() {
      // ...

      const mergeAudioStreams = (desktopStream, voiceStream) => {
        // ...
        if (desktopStream && desktopStream.getAudioTracks().length > 0) {
          // ...
          this.individualAudioStreams.push(desktopStream)
        }
        if (voiceStream && voiceStream.getAudioTracks().length > 0) {
          // ...
          this.individualAudioStreams.push(voiceStream)
        }
        // ...
      }

      // ...
    },

    stop() {
      // ...
      this.individualAudioStreams.forEach(s => s.getTracks().forEach(t => t.stop()))
      this.individualAudioStreams = []
      // ...
    }
  },
})

Ionic Cordova Plugin AudioToggle Not Imported Correctly

declare var AudioToggle;

startVideoCall(){
  AudioToggle.setAudioMode(AudioToggle.SPEAKER);

  //Do other code...
}

Pan audio in cordova (play only out of left / right headphone)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">

    <title>StereoPannerNode example</title>

    <link rel="stylesheet" href="">
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
  </head>

  <body>
    <h1>StereoPannerNode example</h1>
    <audio controls>  
      <source src="omg.mp3" type="audio/mp3">   
      <p>Browser too old to support HTML5 audio? How depressing!</p>
    </audio>
    <h2>Set stereo panning</h2>
    <input class="panning-control" type="range" min="-1" max="1" step="0.1" value="0">
    <span class="panning-value">0</span>

  </body>
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var myAudio = document.querySelector('audio');

var panControl = document.querySelector('.panning-control');
var panValue = document.querySelector('.panning-value');


// Create a MediaElementAudioSourceNode
// Feed the HTMLMediaElement into it
var source = audioCtx.createMediaElementSource(myAudio);

// Create a stereo panner
var panNode = audioCtx.createStereoPanner();

// Event handler function to increase panning to the right and left
// when the slider is moved

panControl.oninput = function() {
  panNode.pan.value = panControl.value;
  panValue.innerHTML = panControl.value;
}

// connect the AudioBufferSourceNode to the gainNode
// and the gainNode to the destination, so we can play the
// music and adjust the panning using the controls
source.connect(panNode);
panNode.connect(audioCtx.destination);
  </script>
</html>

COMMUNITY DISCUSSIONS

Top Trending Discussions on audiotoggle
  • Pop up doesn't disappear when I click &quot;Stop Capture&quot; button of screen recording functionality
  • Ionic Cordova Plugin AudioToggle Not Imported Correctly
  • Passing variable to function within class method
  • Pan audio in cordova (play only out of left / right headphone)
Top Trending Discussions on audiotoggle

QUESTION

Pop up doesn't disappear when I click &quot;Stop Capture&quot; button of screen recording functionality

Asked 2021-Jun-01 at 08:28

I'm facing this trouble with popup. When I select "get audio from desktop" and click "Start Recording" , another popup of browser appears , asking me for another decision ( It is about selecting the screen and sharing audio .I realize if I select "Sharing Audio" and click the blue button "share" . It starts to record and a modal appears : "website is sharing the screen and audio " but If I stop the recording with clicking "Stop Capture" button , the modal of "Website is sharing ... " still appearing . Could someone help me or explaining me if that is possible to disappear that modal when I click "Stop Capture" . Thanks.

I leave the codepen link, the design is a bit disorder but It has the code about the functionality, thanks.

https://codepen.io/gian1599/pen/QWpabWK?editors=1011

Images: 1, 2, 3. I wrote carefully about the workflow, thanks.

new Vue({
  el: "#app",
  vuetify: new Vuetify(),
  data() {
    return {
      valueMicAudioToggle: false,
      valueAudioToggle: false,
      valuestopBtn: true,
      valueCaptureBtn: false,
      valueStart: false,
      stream: "",
      rec: ""
    };
  },
  methods: {
    startBtn() {
      let blobs;
      let blob;

      const videoElement = document.getElementById("videoElement");
      const startBtn = document.getElementById("startBtn");

      const mergeAudioStreams = (desktopStream, voiceStream) => {
        const context = new AudioContext();
        const destination = context.createMediaStreamDestination();
        let hasDesktop = false;
        let hasVoice = false;
        if (desktopStream && desktopStream.getAudioTracks().length > 0) {
          // If you don't want to share Audio from the desktop it should still work with just the voice.
          const source1 = context.createMediaStreamSource(desktopStream);
          const desktopGain = context.createGain();
          desktopGain.gain.value = 0.7;
          source1.connect(desktopGain).connect(destination);
          hasDesktop = true;
        }

        if (voiceStream && voiceStream.getAudioTracks().length > 0) {
          const source2 = context.createMediaStreamSource(voiceStream);
          const voiceGain = context.createGain();
          voiceGain.gain.value = 0.7;
          source2.connect(voiceGain).connect(destination);
          hasVoice = true;
        }

        return hasDesktop || hasVoice
          ? destination.stream.getAudioTracks()
          : [];
      };

      let voiceStream;
      let desktopStream;
      // const captureBtn = document.getElementById("captureBtn");
      const download = document.getElementById("download");
      const audioToggle = document.getElementById("audioToggle");
      const micAudioToggle = document.getElementById("micAudioToggle");
      const self = this;
      const captureBtn = async () => {
        download.style.display = "none";
        const audio = audioToggle.checked || false;
        const mic = micAudioToggle.checked || false;

        desktopStream = await navigator.mediaDevices.getDisplayMedia({
          video: true,
          audio: audio
        });

        if (mic === true) {
          voiceStream = await navigator.mediaDevices.getUserMedia({
            video: false,
            audio: mic
          });
        }

        const tracks = [
          ...desktopStream.getVideoTracks(),
          ...mergeAudioStreams(desktopStream, voiceStream)
        ];

        console.log("Tracks to add to stream", tracks);
        self.stream = new MediaStream(tracks);
        console.log("Stream", self.stream);
        videoElement.srcObject = self.stream;
        videoElement.muted = true;

        blobs = [];

        self.rec = new MediaRecorder(self.stream, {
          mimeType: "video/webm; codecs=vp8,opus"
        });
        self.rec.ondataavailable = (e) => blobs.push(e.data);
        self.rec.onstop = async () => {
          // blobs.push(MediaRecorder.requestData());
          blob = new Blob(blobs, { type: "video/webm" });
          const url = window.URL.createObjectURL(blob);
          download.href = url;
          download.download = "test.webm";
          download.style.display = "block";
        };
        this.valuestopBtn = false;
        this.valueStart = true;
        this.valueCaptureBtn = true;
        this.valueAudioToggle = true;
        this.valueMicAudioToggle = true;
        // this.stopBtn = true
        this.rec.start();
      };
      captureBtn();
    },

    // const startBtn = document.getElementById('startBtn')
    // const stopBtn = document.getElementById('stopBtn')
    stop() {
      const videoElement = document.getElementById("videoElement");

      // this.startBtn = true
      // this.stopBtn = false

      this.valueAudioToggle = false;
      this.valueMicAudioToggle = false;
      this.valueStart = false;
      // this.stopBtn = true
      this.valuestopBtn = true;
      // const self = this

      this.rec.stop();

      this.stream.getTracks().forEach((s) => s.stop());
      videoElement.srcObject = null;
      this.stream = null;
    }
  }
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">

<div id="app">
  <div class="pointer video-list__container">

    <video id="videoElement" autoplay controls loop muted />
  </div>
  <div>
    <v-row>
      <v-col class="d-flex justify-center" cols="6">
        <v-checkbox id="audioToggle" :disabled="valueAudioToggle" label="Get Audio from Desktop" />


        <!-- <input
                        id="audioToggle"
                        :disabled="valueAudioToggle"
                        type="checkbox"
                      >

                      <label for="audioToggle">Capture Audio from Desktop</label> -->
      </v-col>
      <v-col class="d-flex justify-center" cols="6">
        <v-checkbox id="micAudioToggle" :disabled="valueMicAudioToggle" label="Get Audio from Microphone" />


        <!-- <input
                        id="micAudioToggle"
                        :disabled="valueMicAudioToggle"
                        type="checkbox"
                      >
                      <label for="micAudioToggle">Capture Audio from Microphone</label> -->
      </v-col>
    </v-row>

    <v-container>
      <v-row>
        <v-col class="d-flex justify-center" cols="12" />
        <v-btn id="download" class="accent-3 blue px-10" :disabled="buttonStateDownload">
          <a id="download1" align="center">Download</a>
        </v-btn>
        </v-col>
      </v-row>
    </v-container>
    <v-container>
      <v-row>
        <v-col class="d-flex justify-center" cols="12" />
        <v-col class="d-flex justify-center ml-0" cols="12">
          <p id="message" />
        </v-col>
      </v-row>
    </v-container>
  </div>

  <v-row>
    <v-col class="d-flex justify-center" cols="6">
      <v-btn id="startBtn" class="accent-3 blue" :disabled="valueStart" @click="startBtn">
        Start Recording
      </v-btn>
    </v-col>
    <v-col class="d-flex justify-center" cols="6">
      <v-btn id="stopBtn" class="accent-3 blue" :disabled="valuestopBtn" @click="stop">
        Stop Capture
      </v-btn>
    </v-col>
  </v-row>
</div>
</div>

ANSWER

Answered 2021-May-31 at 17:09

In your stop function, you stop all the tracks on this.stream. That includes the video tracks from the desktop stream, but only the audio tracks from the merged audio stream. The original, individual audio tracks from the desktop and the mic are not stopped, so as far as the browser knows they are still active.

Here is one way to stop the original streams:

new Vue({
  // ...
  data () {
    return {
      // ...
      individualAudioStreams: [],
      // ...
    }
  },
  methods: {
    startBtn() {
      // ...

      const mergeAudioStreams = (desktopStream, voiceStream) => {
        // ...
        if (desktopStream && desktopStream.getAudioTracks().length > 0) {
          // ...
          this.individualAudioStreams.push(desktopStream)
        }
        if (voiceStream && voiceStream.getAudioTracks().length > 0) {
          // ...
          this.individualAudioStreams.push(voiceStream)
        }
        // ...
      }

      // ...
    },

    stop() {
      // ...
      this.individualAudioStreams.forEach(s => s.getTracks().forEach(t => t.stop()))
      this.individualAudioStreams = []
      // ...
    }
  },
})

Source https://stackoverflow.com/questions/67777042

QUESTION

Ionic Cordova Plugin AudioToggle Not Imported Correctly

Asked 2019-Jul-01 at 14:02

I am developing an Ionic app with the ApiRTC library for video chat functionality. However, the video audio comes out the headset speaker on phones, where I want it to come out the main speaker. The ApiTRC Cordova FAQ suggests using the AudioToggle plugin, so that is what I am attempting to import into my project.

To import I did ionic cordova plugin add cordova-plugin-audiotoggle --save in the root of my project directory. Then I attempted to call the plugin in my code like this:

declare var AudioToggle;

constructor(public navCtrl: NavController, public navParams: NavParams...) {
    AudioToggle.setAudioMode(AudioToggle.EarPiece);
}

However, it says AudioToggle is undefined and a function "setAudoMode" does not exist for "undefined."

Am I importing a Cordova plugin the wrong way, or is something else wrong?

ANSWER

Answered 2019-Jul-01 at 14:02

I got it working by declaring the plugin, and then only setting the audio mode when I started an audio event (video call in my case).

declare var AudioToggle;

startVideoCall(){
  AudioToggle.setAudioMode(AudioToggle.SPEAKER);

  //Do other code...
}

Source https://stackoverflow.com/questions/54200205

QUESTION

Passing variable to function within class method

Asked 2018-Jul-15 at 16:47

I have a class I am attempting to write that looks like the below.

When I run the class, I get an error:

Audio.js:53 Uncaught ReferenceError: bufferLength is not defined

I believe this is because bufferLength is not available in the drawCanvas function.

I have tried adding the this keyword, however this did not work.

How can I make these variables available to functions within a method of this class?

export const LINE_COLORS = ['rgba(255, 23, 204, 0.5)', 'rgba(130, 23, 255, 0.5)'];

// The dimensions of the current viewport
// - Used to set canvas width & height
export const PAGE_DIMENSIONS = {
  width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
  height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight,
};

class AudioEngine {
  constructor(params) {
    this.params = params;
    this.audio = new Audio();
    this.ctx = new (window.AudioContext || window.webkitAudioContext)();
    this.analyser = this.ctx.createAnalyser();
    this.source = this.ctx.createMediaElementSource(this.audio);
    this.dataArray = new Uint8Array(this.analyser.frequencyBinCount);
    this.bufferLength = this.analyser.frequencyBinCount;

    this.canvas = document.getElementById(params.waveform);

    this.onInit();
  }

  onInit() {
    this.ConfigAudio();
    this.DrawAudioWave();
  }

  ConfigAudio = () => {
    this.audio.src = this.params.stream;
    this.audio.controls = false;
    this.audio.autoplay = false;
    this.audio.crossOrigin = 'anonymous';
    this.analyser.smoothingTimeConstant = 0.6;
    this.source.connect(this.ctx.destination);
    this.source.connect(this.analyser);
    this.analyser.fftSize = 2048;
    this.analyser.getByteFrequencyData(this.dataArray);

    document.body.appendChild(this.audio);
  };

  DrawAudioWave = () => {
    // Bind to the context
    const canvasCtx = this.canvas.getContext('2d');

    function drawCanvas() {
      // We always start the drawing function by clearing the canvas. Otherwise
      // we will be drawing over the previous frames, which gets messy real quick
      canvasCtx.clearRect(0, 0, PAGE_DIMENSIONS.width, PAGE_DIMENSIONS.height);
      requestAnimationFrame(drawCanvas);
      const sliceWidth = (PAGE_DIMENSIONS.width * 1.0) / bufferLength;
      // Create a new bounding rectangle to act as our backdrop, and set the
      // fill color to black.
      canvasCtx.fillStyle = '#000';
      canvasCtx.fillRect(0, 0, PAGE_DIMENSIONS.width, PAGE_DIMENSIONS.height);

      // Loop over our line colors. This allows us to draw two lines with
      // different colors.
      LINE_COLORS.forEach((color, index) => {
        let x = 0;
        // Some basic line width/color config
        canvasCtx.lineWidth = 2;
        canvasCtx.strokeStyle = color;

        // Start drawing the path
        canvasCtx.beginPath();
        for (let i = 0; i < bufferLength; i++) {
          // We offset using the loops index (stops both colored lines
          // from overlapping one another)
          const v = dataArray[i] / 120 + index / 20;
          // Set the Y point to be half of the screen size (the middle)
          const y = (v * PAGE_DIMENSIONS.height) / 2;

          if (i === 0) {
            canvasCtx.moveTo(x, y);
          } else {
            canvasCtx.lineTo(x, y);
          }

          x += sliceWidth;
        }
        canvasCtx.lineTo(canvas.width, canvas.height / 2);
        canvasCtx.stroke();
      });
    }
    drawCanvas();
  };

  audioToggle = () => (this.audio.paused ? this.audio.play() : this.audio.pause());
}

export default AudioEngine;

ANSWER

Answered 2018-Jul-15 at 16:47

requestAnimationFrame will call drawCanvas with the global context bound, so this.bufferLength will not be defined. Easiest solution is to take advantage of lexical scoping, which arrow functions make easy.

If you look at how you're defining your class's methods, they're using arrow functions. This is precisely to avoid the issue with rebinding this that you're currently having. You should read up on this and scoping in JavaScript to better understand why your code isn't working as you'd expect.

Couple solutions, both require drawCanvas -> this.drawCanvas:

(A) Bind the context of drawCanvas before passing it to requestAnimationFrame:

requestAnimationFrame(drawCanvas.bind(this))

Or (B) take advantange of lexical scoping:

requestAnimationFrame(() => drawCanvas())

"Lexical" scope is scope derived from the "text", i.e. where your arrow function is defined relative to other scopes. Non-lexical scoping uses the caller function to determine bound context.

You can also change the drawCanvas function itself to be bound to the appropriate scope using .bind or changing it to an arrow function.

Further Reading:

Source https://stackoverflow.com/questions/51350193

QUESTION

Pan audio in cordova (play only out of left / right headphone)

Asked 2017-Mar-23 at 02:23

Are there any libraries for panning audio left or right in Cordova/Phonegap/Ionic? Ideally, I would like to have a sound file and play it out of either the left or right headphone channel but not both.

I have looked at the cordova-media-plugin, cordova-native-audio, cordovoa-audioToggle, and soundJS/createJS. Of these, only soundJS & createJS seems to be able to control the headphone output and panning, but it doesn't seem like it works with Cordova. Also there are no examples for angular / cordova.

ANSWER

Answered 2017-Mar-23 at 02:23

On Android 6.0, the following script works. It makes use of the Web Audio API. I have not yet tested it on iOS, but I have a good feeling it will work there (please comment if it does not).

You need an "omg.mp3" file in your root directory to test with. You also should build using Cordova and not worry about the CORS or Same-domain error you might get in your browser

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">

    <title>StereoPannerNode example</title>

    <link rel="stylesheet" href="">
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
  </head>

  <body>
    <h1>StereoPannerNode example</h1>
    <audio controls>  
      <source src="omg.mp3" type="audio/mp3">   
      <p>Browser too old to support HTML5 audio? How depressing!</p>
    </audio>
    <h2>Set stereo panning</h2>
    <input class="panning-control" type="range" min="-1" max="1" step="0.1" value="0">
    <span class="panning-value">0</span>

  </body>
<script>
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var myAudio = document.querySelector('audio');

var panControl = document.querySelector('.panning-control');
var panValue = document.querySelector('.panning-value');


// Create a MediaElementAudioSourceNode
// Feed the HTMLMediaElement into it
var source = audioCtx.createMediaElementSource(myAudio);

// Create a stereo panner
var panNode = audioCtx.createStereoPanner();

// Event handler function to increase panning to the right and left
// when the slider is moved

panControl.oninput = function() {
  panNode.pan.value = panControl.value;
  panValue.innerHTML = panControl.value;
}

// connect the AudioBufferSourceNode to the gainNode
// and the gainNode to the destination, so we can play the
// music and adjust the panning using the controls
source.connect(panNode);
panNode.connect(audioCtx.destination);
  </script>
</html>

Source https://stackoverflow.com/questions/42941960

Community Discussions, Code Snippets contain sources that include Stack Exchange Network

VULNERABILITIES

No vulnerabilities reported

INSTALL audiotoggle

You can use audiotoggle like any standard Java library. Please include the the jar files in your classpath. You can also use any IDE and you can run and debug the audiotoggle component as you would do with any other Java program. Best practice is to use a build tool that supports dependency management such as Maven or Gradle. For Maven installation, please refer maven.apache.org. For Gradle installation, please refer gradle.org .

SUPPORT

AndroidiOS

Implement audiotoggle faster with kandi.

  • Use the support, quality, security, license, reuse scores and reviewed functions to confirm the fit for your project.
  • Use the, Q & A, Installation and Support guides to implement faster.

Discover Millions of Libraries and
Pre-built Use Cases on kandi

EXPLORE RELATED TOPICS