Youtube video with hyphen not working in IOS - ios

I am using Cordova YoutubeVideoPlayer Plugin in my ionic project. It works well in android.But in IOS, it is not working with video id having a hyphen(-) in it(eg: "6L-ZHjUhcQY"). It works fine with all other urls. How can I solve this.
.controller('menuController', function () {
var id = "6L-ZHjUhcQY";
YoutubeVideoPlayer.openVideo(id);
});

In the debugger, are the video ids with hyphens correctly saved in the variable? It might be a character encoding issue, or an issue with the plug-in itself.

Fixed the ios issue by updating some files
https://github.com/fingentffts/CordovaYoutubeVideoPlayer
Now I found some issue in android tabs.
Videos are playing even if the screen is locked. And also hyphen video are not playing in samsung tab.

android issue also fixed by editing code in YoutubeVideoPlayer.java file in plugin
private Intent createYoutubeIntent(String videoId) {
// if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP){
Intent intent;
Context cordovaContext = cordova.getActivity();
String version = YouTubeIntents.getInstalledYouTubeVersionName(cordovaContext);
if(version != null && version.startsWith("11.16") && YouTubeIntents.canResolvePlayVideoIntent(cordovaContext)) {
intent = YouTubeIntents.createPlayVideoIntent(cordovaContext, videoId);
} else {
if(YouTubeIntents.canResolvePlayVideoIntentWithOptions(cordovaContext)){
intent = YouTubeIntents.createPlayVideoIntentWithOptions(cordovaContext, videoId, true, true);
} else {
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.youtube.com/watch?v=" + videoId), cordovaContext, YouTubeActivity.class);
intent.putExtra("videoId", videoId);
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(cordovaContext);
CordovaPreferences prefs = parser.getPreferences();
intent.putExtra("YouTubeApiId", prefs.getString("YouTubeDataApiKey","YOUTUBE_API_KEY"));
}
}
return intent;
// }
//return new Intent(null, Uri.parse("ytv://" + videoId), cordova.getActivity(), OpenYouTubePlayerActivity.class);
}

Related

Xamarin ios ZXING scanner not analyzing QR

i'm using an Iphone 10 with ios 15.3.1,Zxing version = 2.4.1, compiling the xamarin project in windows. I been trying to make a qr scanner with zxing for ios android, but when i run my app in ios, it won't go to the onResult event. I've tried with a lot of methods of doing this, but nothing seems to work. The camera shows, but the result never comes truh. ¿Does someone have any idea why this is happening? I also tried apps from other devs that are using zxing and it also dosen't work. but when i scan with the camera app it works.
async void OnButtonClickedAsync(object sender, System.EventArgs e)
{
var options = new ZXing.Mobile.MobileBarcodeScanningOptions
{
CameraResolutionSelector = HandleCameraResolutionSelectorDelegate
};
MobileBarcodeScanner scanner = new MobileBarcodeScanner();
//scanner.TopText = "Hold camera up to barcode to scan";
//scanner.BottomText = "Barcode will automatically scan";
//scanner.UseCustomOverlay = false;
scanner.FlashButtonText = "Flash";
scanner.CancelButtonText = "Cancel";
scanner.Torch(true);
scanner.AutoFocus();
var result = await scanner.Scan(options);
HandleScanResult(result);
}
void HandleScanResult(ZXing.Result result)
{
if (result != null && !string.IsNullOrEmpty(result.Text))
scanResultText.Text = result.Text;
}
CameraResolution HandleCameraResolutionSelectorDelegate(List<CameraResolution> availableResolutions)
{
//Don't know if this will ever be null or empty
if (availableResolutions == null || availableResolutions.Count < 1)
return new CameraResolution() { Width = 800, Height = 600 };
//Debugging revealed that the last element in the list
//expresses the highest resolution. This could probably be more thorough.
return availableResolutions[availableResolutions.Count - 1];
}
I compiled using a mac and it worked fine, must be a bug of visual studio on windows.

Printing using ngx-extended-pdf-viewer on iOS and Mobile Safari or Chrome

I have an Angular 7 app that is using ngx-extended-pdf-viewer to render a PDF that I get as a byte array from the web.api. I have no issues rendering the PDF or even printing it from any desktop application. ngx-extended-pdf-viewer as a print button built right in. However, when trying to print from Safari on an iPhone (iOS 12) it only prints a blank page with the url at the bottom. The actual PDF does not print. With Chrome on iOS it doesn't do anything that I can see. I am pretty new to Angular and actually to mobile web development, so perhaps lack of knowledge is getting me. The PDF viewer is in a mat-tab, so not sure if maybe that is causing some issues??
I have tried other packages, but they all seem to be based on the same pdf.js code from Mozilla. Also this is the only one I've found so far that has a print. I was thinking about perhaps trying pdf.js outside of an npm package, but so far have not found solid directions on getting this to work in Angular. I'm sure it will, but all directions I have found seem to omit details. Such as, put this code in your app. They just fail to say where in the app.
From the web.api:
[HttpPost("GetPdfBytes/{PdfId}")]
public ActionResult<byte[]> GetPdfBytesId([FromBody]int id)
{
string exactPath = string.Empty;
if (id == 1)
{
exactPath = Path.GetFullPath("pdf-test.pdf");
}
else if (id == 2)
{
exactPath = Path.GetFullPath("DPP.pdf");
}
else if (id == 3)
{
exactPath = Path.GetFullPath("Request.pdf");
}
else
{
exactPath = Path.GetFullPath("Emergency Issue.pdf");
}
byte[] bytes = System.IO.File.ReadAllBytes(exactPath);
return Ok(bytes);
}
The HTML:
<mat-tab label="PDF">
<ng-template matTabContent>
<ngx-extended-pdf-viewer *ngIf="visible[2]" id="pdf3" [src]="pdfSrc3" useBrowserLocale="true" delayFirstView="1000" showSidebarButton="false"
showOpenFileButton="false" >
</ngx-extended-pdf-viewer>
</ng-template>
</mat-tab>
TypeScript:
getPDFBytesId(id: string) {
this.getPDFFromServicePdfBytesId(Number(id)).subscribe(
(data: any) => {
this.pdfSrc3 = this.convertDataURIToBinary(data);
},
error => {
console.log(error);
}
);
}
// hits the web.api
getPDFFromServicePdfBytesId(id: number): Observable<any> {
const body = id;
return this.http.post<any>('http://localhost:5000/api/values/GetPdfBytes/' + id, body);
}
// converts what we got back to a Uint8Array which is used by the viewer
convertDataURIToBinary(dataURI: string) {
const raw = window.atob(dataURI);
const rawLength = raw.length;
const array = new Uint8Array(new ArrayBuffer(rawLength));
for (let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}

onaudioprocess not called on ios11

I am trying to get audio capture from the microphone working on Safari on iOS11 after support was recently added
However, the onaudioprocess callback is never called. Here's an example page:
<html>
<body>
<button onclick="doIt()">DoIt</button>
<ul id="logMessages">
</ul>
<script>
function debug(msg) {
if (typeof msg !== 'undefined') {
var logList = document.getElementById('logMessages');
var newLogItem = document.createElement('li');
if (typeof msg === 'function') {
msg = Function.prototype.toString(msg);
} else if (typeof msg !== 'string') {
msg = JSON.stringify(msg);
}
var newLogText = document.createTextNode(msg);
newLogItem.appendChild(newLogText);
logList.appendChild(newLogItem);
}
}
function doIt() {
var handleSuccess = function (stream) {
var context = new AudioContext();
var input = context.createMediaStreamSource(stream)
var processor = context.createScriptProcessor(1024, 1, 1);
input.connect(processor);
processor.connect(context.destination);
processor.onaudioprocess = function (e) {
// Do something with the data, i.e Convert this to WAV
debug(e.inputBuffer);
};
};
navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then(handleSuccess);
}
</script>
</body>
</html>
On most platforms, you will see items being added to the messages list as the onaudioprocess callback is called. However, on iOS, this callback is never called.
Is there something else that I should do to try and get it called on iOS 11 with Safari?
There are two problems. The main one is that Safari on iOS 11 seems to automatically suspend new AudioContext's that aren't created in response to a tap. You can resume() them, but only in response to a tap.
(Update: Chrome mobile also does this, and Chrome desktop will have the same limitation starting in version 70 / December 2018.)
So, you have to either create it before you get the MediaStream, or else get the user to tap again later.
The other issue with your code is that AudioContext is prefixed as webkitAudioContext in Safari.
Here's a working version:
<html>
<body>
<button onclick="beginAudioCapture()">Begin Audio Capture</button>
<script>
function beginAudioCapture() {
var AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
var processor = context.createScriptProcessor(1024, 1, 1);
processor.connect(context.destination);
var handleSuccess = function (stream) {
var input = context.createMediaStreamSource(stream);
input.connect(processor);
var recievedAudio = false;
processor.onaudioprocess = function (e) {
// This will be called multiple times per second.
// The audio data will be in e.inputBuffer
if (!recievedAudio) {
recievedAudio = true;
console.log('got audio', e);
}
};
};
navigator.mediaDevices.getUserMedia({audio: true, video: false})
.then(handleSuccess);
}
</script>
</body>
</html>
(You can set the onaudioprocess callback sooner, but then you get empty buffers until the user approves of microphone access.)
Oh, and one other iOS bug to watch out for: the Safari on iPod touch (as of iOS 12.1.1) reports that it does not have a microphone (it does). So, getUserMedia will incorrectly reject with an Error: Invalid constraint if you ask for audio there.
FYI: I maintain the microphone-stream package on npm that does this for you and provides the audio in a Node.js-style ReadableStream. It includes this fix, if you or anyone else would prefer to use that over the raw code.
Tried it on iOS 11.0.1, and unfortunately this problem still isn't fixed.
As a workaround, I wonder if it makes sense to replace the ScriptProcessor with a function that takes the steam data from a buffet and then processes it every x milliseconds. But that's a big change to the functionality.
Just wondering... do you have the setting enabled in Safari settings? It comes enabled by default in iOS11, but maybe you just disabled it without noticing.

Distorted audio in iOS 7.1 with WebAudio API

On iOS 7.1, I keep getting a buzzing / noisy / distorted sound when playing back audio using the Web Audio API. It sounds distorted like this, in place of normal like this.
The same files are fine when using HTML5 audio. It all works fine on desktop (Firefox, Chrome, Safari.)
EDIT:
The audio is distorted in the iOS Simulator versions iOS 7.1, 8.1, 8.2. The buzzing sound often starts before I even playback anything.
The audio is distorted on a physical iPhone running iOS 7.1, in both Chrome and Safari.
The audio is fine on a physical iPhone running iOS 8.1, in both Chrome and Safari.
i.e.: the buzzing audio is on iOS 7.1. only.
Howler.js is not the issue. The problem is still there using pure JS like so:
var context;
var sound;
var extension = '.' + ( new Audio().canPlayType( 'audio/ogg' ) !== '' ? 'ogg' : 'mp3');
/** Test for WebAudio API support **/
try {
// still needed for Safari
window.AudioContext = window.AudioContext || window.webkitAudioContext;
// create an AudioContext
context = new AudioContext();
} catch(e) {
// API not supported
throw new Error( 'Web Audio API not supported.' );
}
function loadSound( url ) {
var request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.responseType = 'arraybuffer';
request.onload = function() {
// request.response is encoded... so decode it now
context.decodeAudioData( request.response, function( buffer ) {
sound = buffer;
}, function( err ) {
throw new Error( err );
});
}
request.send();
}
function playSound(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
}
loadSound( '/tests/Assets/Audio/En-us-hello' + extension );
$(document).ready(function(){
$( '#clickme' ).click( function( event ) {
playSound(sound);
});
}); /* END .ready() */
A live version of this code is available here: Web Audio API - Hello world
Google did not bring up any result about such a distorted sound issue on iOS 7.1.
Has anyone else run into it? Should I file a bug report to Apple?
I believe the issue is caused due to resetting the audioContext.sampleRate prop, which seem to happen after the browser/OS plays something recorded in a different sampling rate.
I've devised the following workaround, which basically silently plays a short wav file recorded in the sampling rate that the device currently does playback on:
"use strict";
var getData = function( context, filePath, callback ) {
var source = context.createBufferSource(),
request = new XMLHttpRequest();
request.open( "GET", filePath, true );
request.responseType = "arraybuffer";
request.onload = function() {
var audioData = request.response;
context.decodeAudioData(
audioData,
function( buffer ) {
source.buffer = buffer;
callback( source );
},
function( e ) {
console.log( "Error with decoding audio data" + e.err );
}
);
};
request.send();
};
module.exports = function() {
var AudioContext = window.AudioContext || window.webkitAudioContext,
context = new AudioContext();
getData(
context,
"path/to/short/file.wav",
function( bufferSource ) {
var gain = context.createGain();
gain.gain.value = 0;
bufferSource.connect( gain );
gain.connect( context.destination );
bufferSource.start( 0 );
}
);
};
Obviously, if some of the devices have different sampling rates, you would need to detect and use a specific file for every rate.
it looks like iOS6+ Safari defaults to a sample rate of 48000. If you type this into the developer console when you first open mobile safari, you'll get 48000:
var ctx = new window.webkitAudioContext();
console.log(ctx.sampleRate);
Further Reference: https://forums.developer.apple.com/thread/20677
Then if you close the initial context on load: ctx.close(), the next created context will use the sample rate most other browsers use (44100) and sound will play without distortion.
Credit to this for pointing me in the right direction (and in case the above no longer works in the future): https://github.com/Jam3/ios-safe-audio-context/blob/master/index.js
function as of post date:
function createAudioContext (desiredSampleRate) {
var AudioCtor = window.AudioContext || window.webkitAudioContext
desiredSampleRate = typeof desiredSampleRate === 'number'
? desiredSampleRate
: 44100
var context = new AudioCtor()
// Check if hack is necessary. Only occurs in iOS6+ devices
// and only when you first boot the iPhone, or play a audio/video
// with a different sample rate
if (/(iPhone|iPad)/i.test(navigator.userAgent) &&
context.sampleRate !== desiredSampleRate) {
var buffer = context.createBuffer(1, 1, desiredSampleRate)
var dummy = context.createBufferSource()
dummy.buffer = buffer
dummy.connect(context.destination)
dummy.start(0)
dummy.disconnect()
context.close() // dispose old context
context = new AudioCtor()
}
return context
}

Media is not playing in iOS phonegap 1.5 app

I am developing iOS app using phonegap 1.5. In this app I am using phonegap's Media API to play mp3 files. But it's not working on iOS. Same codebase works on Android without any issue.
Code:
Audio.js
//
var my_media = null;
var mediaTimer = null;
function playAudio(src) {
//alert("inside");
//if (my_media == null) {
// Create Media object from src
my_media = new Media(src, onSuccess, onError);
//alert(my_media);
//} // else play current audio
// Play audio
my_media.play();
//alert("Played");
}
function onSuccess() {
console.log("playAudio():Audio Success");
}
// onError Callback
//
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
I am including Audio.js in my html file and then calling function
playAudio("audio/welcome.mp3");
All of my mp3 files reside in www/audio folder.
I debugged using alert statements, call comes till this line of code
my_media = new Media(src, onSuccess, onError);
No error callback or no errors in console of xcode.
Am I missing something here? What could be the issue?
Phonegap is pretty difficult with having stuff behaving differently that it should, especially when it comes to media and plugins. You need to have something that changes the file path based off of the device (using the Cordova Device Plugin):
//Gets Device Platform
document.addEventListener("deviceready", getDevicePlatform, false);
function getDevicePlatform() {
$scope.devicePlatform = device.platform;
console.log(device.platform);
}
Then to set the media player file path correctly:
if ($scope.devicePlatform == "Android") {
var songFilePath = '/android_asset/www/res/' + song.name + '.mp3';
}
else {
var songFilePath = 'res/' + song.name + '.mp3';
}
$scope.song = new Media(songFilePath);
The song .name is something special I had to dynamically get the path, but the main thing is that for Android devices you need the /android_asset/, but for other devices like iOS and PhoneGap you can use normal file paths to media inside the /www folder.

Resources