Hello.

I am Paul Kinlan.

A Developer Advocate for Chrome and the Open Web at Google.

testing-file-share-target

Paul Kinlan

यह एंड्रॉइड पर शेयर लक्ष्य एपीआई की एक परीक्षा है और यह फाइलों को साझा करने की क्षमता है। अगर आप यहाँ कुछ देखते हैं, तो सब अच्छा है :)

Read More

Paul Kinlan

Trying to make the web and developers better.

RSS Github Medium

Ricky Mondello: Adoption of Well-Known URL for Changing Passwords

Paul Kinlan

सफारी टीम पर रिकी मोंडेलो ने हाल ही में एक नोट साझा किया था कि ट्विटर कैसे ./well-ogn/change-password कल्पना का उपयोग कर रहा है।

I just noticed that Twitter has adopted the Well-Known URL for Changing Passwords! Is anyone aware of other sites that have adopted it?

Twitter’s implementation: https://twitter.com/.well-known/change-password; Github’s: https://github.com/.well-known/change-password; Specification :https://github.com/WICG/change-password-url

Read full post

फीचर ने मुझे पूरी तरह से पास कर दिया, लेकिन यह एक अच्छा विचार है: एक प्रसिद्ध स्थान पर एक फ़ाइल दी गई है, क्या ब्राउज़र उपयोगकर्ता को एक यूआई प्रदान कर सकता है जो उन्हें साइटों को जटिल यूआई नेविगेट करने के लिए बिना अपना पासवर्ड रीसेट करने की अनुमति देता है।

कल्पना भ्रामक रूप से सरल है: अच्छी तरह से ज्ञात फ़ाइल में उपयोगकर्ता को निर्देश देने के लिए URL होता है जब वे कार्रवाई करना चाहते हैं। यह मुझे सोच में ले जाता है, क्या हम इनमें से अधिक सुविधाएँ प्रदान कर सकते हैं:

  • GDPR- आधारित सहमति मॉडल (कुकी सहमति) के लिए एक प्रसिद्ध स्थान - साइट के मालिक उस पृष्ठ के लिए एक लिंक प्रदान कर सकते हैं जहाँ उपयोगकर्ता सभी कुकीज़ और अन्य डेटा सहमति आइटम को प्रबंधित और संभावित रूप से रद्द कर सकता है।
  • ब्राउज़र अनुमति प्रबंधन के लिए एक प्रसिद्ध स्थान - साइट के मालिक उपयोगकर्ताओं को जियो-लोकेशन, नोटिफिकेशन और अन्य प्राइमेटिक्स जैसी चीजों के लिए अनुमति देने में सक्षम होने के लिए एक त्वरित स्थान दे सकते हैं।
  • खाता हटाने और परिवर्तनों के लिए एक प्रसिद्ध मार्ग
  • मेल सदस्यता सूची प्रबंधन के लिए एक प्रसिद्ध मार्ग

सूची आगे बढ़ती है …. मुझे वास्तव में उपयोगकर्ताओं को सामान्य उपयोगकर्ता कार्यों की खोज करने में मदद करने के लिए सरल पुनर्निर्देशित फ़ाइलों के लिए विचार पसंद है, और ब्राउज़र के लिए एक तरह से इसे सतह के लिए।

pinch-zoom-element

Paul Kinlan

जेक और टीम ने ब्राउजर के खुद के पिंच-ज़ूम डायनामिक्स (मोबाइल व्यूपोर्ट जूमिंग के बारे में सोचें) के बाहर HTML के किसी भी सेट पर चुटकी जूमिंग को प्रबंधित करने के लिए यह बल्कि भयानक कस्टम तत्व बनाया। तत्व उन केंद्रीय घटकों में से एक था, जिन्हें हमें Chrome देव शिखर सम्मेलन में बनाए गए और जारी किए गए squoosh ऐप के लिए आवश्यक था … (मैं कहता हूं कि 'क्रोम देव शिखर सम्मेलन में रिलीज़' - जेक चीन के Google डेवलपर दिवस पर सभी को दिखा रहा था भले ही टीम के बाकी सदस्य शर्मिंदा थे;) …)

install: npm install --save-dev pinch-zoom-element

<pinch-zoom>
  <h1>Hello!</h1>
</pinch-zoom>

Read full post

मैंने अभी इसे अपने ब्लॉग में जोड़ा है (बस कुछ ही मिनटों में), आप इसे मेरे ' life ' अनुभाग पर देख सकते हैं, जहाँ मैंने अपने द्वारा लिए गए फ़ोटो साझा किए हैं। यदि आप एक टच-सक्षम डिवाइस पर हैं, तो आप जल्दी से तत्व पर चुटकी-ज़ूम कर सकते हैं, यदि आप एक ट्रैक-पैड का उपयोग कर रहे हैं जो कई उंगली इनपुट को संभाल सकता है जो काम भी करता है।

यह तत्व उपयोगकर्ता-इंटरफ़ेस घटकों को बनाने के लिए एक मॉडल के रूप में वेब घटकों से प्यार क्यों करता है, इसका एक बड़ा उदाहरण है। pinch-zoom तत्व तार पर 3kb (असम्पीडित) और निर्माण के लिए न्यूनतम निर्भरता के अंतर्गत है और यह सिर्फ एक काम करता है असाधारण रूप से अच्छी तरह से, किसी भी कस्टम अनुप्रयोग-स्तरीय तर्क को बांधने के बिना जो इसे उपयोग करना कठिन बना देगा (मुझे यूआई तर्क पर कुछ विचार हैं बनाम ऐप लॉजिक घटक जिन्हें मैं अपने सीखने के आधार पर स्क्वॉश ऐप से साझा करूंगा)।

मैं ऐसे तत्वों को देखना पसंद करूंगा, जिन्हें अधिक जागरूकता और उपयोग मिलता है, उदाहरण के लिए मैं सोच सकता था कि यह तत्व उस छवि ज़ूम कार्यक्षमता को प्रतिस्थापित या मानकीकृत कर सकता है जिसे आप कई वाणिज्य साइटों पर देखते हैं और हमेशा डेवलपर्स से उस दर्द को दूर करते हैं।

Registering as a Share Target with the Web Share Target API

Paul Kinlan

पीट LePage ने वेब शेयर लक्ष्य एपीआई और एक मूल परीक्षण के माध्यम से क्रोम में उपलब्धता का परिचय दिया

Until now, only native apps could register as a share target. The Web Share Target API allows installed web apps to register with the underlying OS as a share target to receive shared content from either the Web Share API or system events, like the OS-level share button.

Read full post

यह एपीआई वेब पर एक गेम चेंजर है, यह वेब को उस चीज़ तक खोलता है जो केवल एक बार देशी ऐप्स के लिए उपलब्ध था: नेटिव शेयरिंग। ऐप्स सिलोस हैं, वे सभी डेटा में चूसते हैं और प्लेटफार्मों भर में सुलभ होना मुश्किल बनाते हैं। शेयर टारगेट खेल के मैदान को समतल करने के लिए शुरू होता है ताकि वेब उसी गेम में खेल सके।

Twitter मोबाइल अनुभव में Share Target already enabled । यह पोस्ट मैंने अपनी साइट 'व्यवस्थापक पैनल' में परिभाषित किए गए शेयर लक्ष्य का उपयोग करके बनाया था - यह बहुत अच्छी तरह से काम करता है, और जिस मिनट वे फ़ाइल समर्थन का समर्थन करते हैं, मैं किसी भी छवि को पोस्ट करने या अपने डिवाइस पर अपने ब्लॉग पर ब्लॉब करने में सक्षम manifest.json

बहुत ही रोमांचक समय।

यह एपीआई कब जाना चाहिए और एपीआई का उपयोग कैसे करना चाहिए, इसके बारे में जानने के लिए समय-रेखाओं के बारे में जानने के लिए लिंक पर पढ़ें।

Why Build Progressive Web Apps: Push, but Don't be Pushy! Video Write-Up

Paul Kinlan

वेब पर अच्छे पुश सूचनाओं पर थॉमस स्टेनर द्वारा एक शानदार लेख और वीडियो और नमूना।

A particularly bad practice is to pop up the permission dialog on page load, without any context at all. Several high traffic sites have been caught doing this. To subscribe people to push notifications, you use the the PushManager interface. Now to be fair, this does not allow the developer to specify the context or the to-be-expected frequency of notifications. So where does this leave us?

Read full post

वेब पुश एक अद्भुत शक्तिशाली एपीआई है, लेकिन आपके उपयोगकर्ताओं को दुरुपयोग और परेशान करना आसान है। आपकी साइट के लिए बुरी बात यह है कि अगर कोई उपयोगकर्ता बिना किसी चेतावनी के सूचनाओं को रोकता है, तो आपको दोबारा पूछने का मौका नहीं मिलता है।

अपने उपयोगकर्ताओं के साथ सम्मान के साथ व्यवहार करें, वेब पुश सूचनाओं के लिए संदर्भ राजा है।

Maybe Our Documentation "Best Practices" Aren''t Really Best Practices

Paul Kinlan

Kayce Basques, हमारी टीम के एक भयानक तकनीकी लेखक ने अपने अनुभवों के बारे में एक बहुत ही अद्भुत लेख लिखा है, जो यह मापता है कि तकनीकी सामग्री की व्याख्या करने के लिए मौजूदा प्रलेखन सर्वोत्तम-व्यवहार कैसे काम करते हैं। इस अर्थ में सर्वोत्तम अभ्यास तकनीकी लेखन के लिए प्रसिद्ध उद्योग मानक हो सकते हैं, या यह आपकी अपनी कंपनी हो सकती है जो शैली गाइड लिख रही है। इसकी जांच - पड़ताल करें!

Recently I discovered that a supposed documentation “best practice” may not actually stand up to scrutiny when measured in the wild. I’m now on a mission to get a “was this page helpful?” feedback widget on every documentation page on the web. It’s not the end-all be-all solution, but it’s a start towards a more rigorous understanding of what actually makes our docs more helpful.

Read full post

जबकि मैं एक तकनीकी लेखक नहीं हूं, मेरी भूमिका में हमारी तकनीक लेखन टीम के साथ-साथ सगाई की एक बड़ी मात्रा शामिल है और साथ ही साथ स्वयं डेवलपर्स के लिए बहुत सारी 'सर्वोत्तम प्रथाओं' का प्रकाशन भी है। मैं चकित था कि कायेस ने हमारी टीमों की सामग्री के लेंस के माध्यम से आधुनिक डॉक्स लिखने की कला पर कितनी गहराई और शोध किया है। मैं आपको कायस के लेख को गहराई से पढ़ने के लिए प्रोत्साहित करता हूं - मैंने बहुत कुछ सीखा। धन्यवाद Kayce!

Grep your git commit log

Paul Kinlan

Finding code that was changed in a commit

Read More

Performance and Resilience: Stress-Testing Third Parties by CSS Wizardry

Paul Kinlan

मैं Google डेवलपर दिवस के लिए कुछ हफ्ते पहले चीन में था और मैं अपने सभी क्यूआरकोड स्कैनर को दिखा रहा था, जब तक मैं ऑफ़लाइन नहीं जाता तब तक यह बहुत अच्छा काम कर रहा था। जब उपयोगकर्ता ऑफलाइन था (या आंशिक रूप से कनेक्ट) कैमरा शुरू नहीं होगा, जिसका मतलब था कि आप क्यूआर कोड को स्नैप नहीं कर सके। यह हुआ कि काम करने के लिए मुझे उम्र बढ़ गई, और यह पता चला कि मैं गलती से कैमरे को अपने ‘ऑनलोड’ ईवेंट में शुरू कर रहा था और Google Analytics अनुरोध समय-समय पर हल होगा और हल नहीं होगा। यह यह प्रतिबद्धता है जो इसे ठीक करता है

Because these types of assets block rendering, the browser will not paint anything to the screen until they have been downloaded (and executed/parsed). If the service that provides the file is offline, then that’s a lot of time that the browser has to spend trying to access the file, and during that period the user is left potentially looking at a blank screen. After a certain period has elapsed, the browser will eventually timeout and display the page without the asset(s) in question. How long is that certain period of time?

It’s 1 minute and 20 seconds.

If you have any render-blocking, critical, third party assets hosted on an external domain, you run the risk of showing users a blank page for 1.3 minutes.

Below, you’ll see the DOMContentLoaded and Load events on a site that has a render-blocking script hosted elsewhere. The browser was completely held up for 78 seconds, showing nothing at all until it ended up timing out.

पूर्ण पोस्ट पढ़ें

मैं आपको पद पढ़ने के लिए प्रोत्साहित करता हूं क्योंकि बहुत सारी अंतर्दृष्टि है।

Chrome Bug 897727 - MediaRecorder using Canvas.captureStream() fails for large canvas elements on Android

Paul Kinlan

सप्ताहांत में मैं बुमेरांग प्रभाव वीडियो एन्कोडर के साथ खेल रहा था, आप इसे वास्तविक समय में काम कर सकते हैं (मैं बाद में समझाऊंगा)। मुझे यह डेस्कटॉप पर क्रोम पर काम कर रहा है, लेकिन यह एंड्रॉइड पर क्रोम पर ठीक से काम नहीं करेगा। [यहां कोड] देखें (0)।

ऐसा लगता है कि आप 'कैप्चरस्ट्रीम () `का उपयोग करते हैं 'जिसमें अपेक्षाकृत बड़ा संकल्प है (मेरे मामले में 1280x720) MediaRecorder API वीडियो को एन्कोड करने में सक्षम नहीं होगा और यह त्रुटि नहीं होगी और आप यह नहीं पता लगा सकते कि यह समय से पहले वीडियो को एन्कोड नहीं कर सकता है।

(1) Capture a large res video (from getUM 1280x720) to a buffer for later processing. (2) Create a MediaRecorder with a stream from a canvas element (via captureStream) sized to 1280x720 (3) For each frame captured putImageData on the canvas (4) For each frame call canvasTrack.requestFrame() at 60fps

context.putImageData(frame, 0, 0); canvasStreamTrack.requestFrame();

Demo: https://boomerang-video-chrome-on-android-bug.glitch.me/ Code: https://glitch.com/edit/#!/boomerang-video-chrome-on-android-bug?path=script.js:21:42

What is the expected result?

For the exact demo, I buffer the frames and then reverse them so you would see the video play forwards and backwards (it works on desktop). In generall I would expect all frames sent to the canvas to be processed by the MediaRecorder API - yet they are not.

What happens instead?

It only captures the stream from the canvas for a partial part of the video and then stops. It’s not predicatable where it will stop.

I suspect there is a limit with the MediaRecorder API and what resolution it can encode depending on the device, and there is no way to know about these limits ahead of time.

As far as I can tell this has never worked on Android. If you use https://boomerang-video-chrome-on-android-bug.glitch.me which has a 640x480 video frame it records just fine. The demo works at higher-resolution just fine on desktop.

पूर्ण पोस्ट पढ़ें

यदि आप डेमो के साथ खेलना चाहते हैं जो दोनों पर काम करता है यहां क्लिक करें

Why Microsoft and Google love progressive web apps | Computerworld

Paul Kinlan

माइक एलगन से पीडब्लूए के बारे में एक अच्छी पोस्ट। मुझे पीडब्लूए के साथ माइक्रोसॉफ्ट के लक्ष्य के बारे में निश्चित नहीं है, लेकिन मुझे लगता है कि हमारा बहुत आसान है: हम चाहते हैं कि उपयोगकर्ता तुरंत सामग्री और कार्यक्षमता तक पहुंच सकें और एक तरह से वे अपने उपकरणों पर इसके साथ बातचीत करने में सक्षम होने की उम्मीद करते हैं। वेब को प्रत्येक कनेक्टेड डिवाइस पर सभी तक पहुंचा जाना चाहिए और उपयोगकर्ता को अपनी पसंदीदा मोडैलिटी में ऐप के रूप में पहुंचने में सक्षम होना चाहिए, अगर ऐसा है कि वे इसकी अपेक्षा करते हैं (मोबाइल, शायद), या सहायक आदि पर आवाज।

हम अभी भी एक [हेडलेस वेब से लंबा रास्ता] हैं (0), हालांकि, एक चीज ने वास्तव में लेख में मुझे मारा:

Another downside is that PWAs are highly isolated. So it’s hard and unlikely for different PWAs to share resources or data directly.

पूर्ण पोस्ट पढ़ें

वेब पर साइट्स और ऐप्स को अलग नहीं किया जाना चाहिए, वेब लिंक करने योग्य, अनुक्रमणीय, क्षणिक है, लेकिन हम जो भी साइट बनाते हैं, उसके साथ हम अधिक चुप हो रहे हैं। हम अनियंत्रित सिलो बना रहे हैं क्योंकि प्लेटफॉर्म उपयोगकर्ताओं को आसानी से साइटों को * इन * डेटा को आसानी से प्राप्त करने की अनुमति नहीं देता है। मैं आरडीएफ या उसके बारे में कुछ भी नहीं बोल रहा हूं, कॉपी और पेस्ट, ड्रैग और ड्रॉप जैसे मूल संचालन, साइट पर साझा करें और साइट से साझा करें आज के वेब पर टूटा हुआ है, और इससे पहले कि हम फ्रेम, श्रमिकों के बीच आईपीसी प्राप्त करें और खिड़कियां।

Building a video editor on the web. Part 0.1 - Screencast

Paul Kinlan

आप ब्राउज़र में बस वेब का उपयोग करके वीडियो बनाने और संपादित करने में सक्षम होना चाहिए। स्क्रीनफ्लो के समान उपयोगकर्ता-इंटरफ़ेस प्रदान करना संभव होना चाहिए जो आपको एक आउटपुट वीडियो बनाने देता है जो एकाधिक वीडियो, छवियों और ऑडियो को एक वीडियो में जोड़ता है जिसे YouTube जैसी सेवाओं पर अपलोड किया जा सकता है। मेरे पिछली पोस्ट के बाद से जो वीडियो संपादक की आवश्यकताओं का संक्षेप में वर्णन करता है, इस पोस्ट में मैं बस एक स्क्रीनकास्ट में दिखाना चाहता था कि मैंने वेब कैम रिकॉर्डर कैसे बनाया, और स्क्रीनकास्ट कैसे बनाया जाए रिकॉर्डर :)

Read More

894556 - Multiple video tracks in a MediaStream are not reflected on the videoTracks object on the video element

Paul Kinlan

पहला मुद्दा जो मैंने पाया है वेब पर एक वीडियो संपादक बनाना

मेरे पास एकाधिक वीडियो स्ट्रीम (डेस्कटॉप और वेब कैमरा) हैं और मैं एक वीडियो तत्व पर वीडियो स्ट्रीम के बीच टॉगल करने में सक्षम होना चाहता था ताकि मैं जल्दी से वेब कैम और डेस्कटॉप के बीच स्विच कर सकूं और ‘MediaRecorder` को तोड़ न सकूं।

ऐसा लगता है कि आपको 'चयनित' संपत्ति को videoTracks &#39;ऑब्जेक्ट पर&#39; चयनित &#39;संपत्ति को टॉगल करने के माध्यम से ऐसा करने में सक्षम होना चाहिए। <video>तत्व, लेकिन आप नहीं कर सकते, ट्रैक की सरणी में केवल 1 तत्व होता है (मीडियास्ट्रीम पर पहला वीडियो ट्रैक)।

What steps will reproduce the problem? (1) Get two MediaStreams with video tracks (2) Add them to a new MediaStream and attach as srcObject on a videoElement (3) Check the videoElement.videoTracks object and see there is only one track

Demo at https://multiple-tracks-bug.glitch.me/

What is the expected result? I would expect videoElement.videoTracks to have two elements.

What happens instead? It only has the first videoTrack that was added to the MediaStream.

पूर्ण पोस्ट पढ़ें

रेपो केस

window.onload = () => {
  if('getDisplayMedia' in navigator) warning.style.display = 'none';

  let blobs;
  let blob;
  let rec;
  let stream;
  let webcamStream;
  let desktopStream;

  captureBtn.onclick = async () => {

       
    desktopStream = await navigator.getDisplayMedia({video:true});
    webcamStream = await navigator.mediaDevices.getUserMedia({video: { height: 1080, width: 1920 }, audio: true});
    
    // Always 
    let tracks = [...desktopStream.getTracks(), ... webcamStream.getTracks()]
    console.log('Tracks to add to stream', tracks);
    stream = new MediaStream(tracks);
    
    console.log('Tracks on stream', stream.getTracks());
    
    videoElement.srcObject = stream;
    
    console.log('Tracks on video element that has stream', videoElement.videoTracks)
    
    // I would expect the length to be 2 and not 1
  };

};

Building a video editor on the web. Part 0.

Paul Kinlan

आप ब्राउज़र में बस वेब का उपयोग करके वीडियो बनाने और संपादित करने में सक्षम होना चाहिए। स्क्रीनफ्लो के समान उपयोगकर्ता-इंटरफ़ेस प्रदान करना संभव होना चाहिए जो आपको एक आउटपुट वीडियो बनाने देता है जो एकाधिक वीडियो, छवियों और ऑडियो को एक वीडियो में जोड़ता है जिसे YouTube जैसी सेवाओं पर अपलोड किया जा सकता है। यह पोस्ट वास्तव में सिर्फ इरादे का बयान है। मैं प्लेटफार्म पर क्या उपलब्ध है और उपलब्ध नहीं है यह देखने की लंबी प्रक्रिया शुरू करने जा रहा हूं और देख रहा हूं कि आज हम कितना दूर कर सकते हैं।

Read More

Barcode detection in a Web Worker using Comlink

Paul Kinlan

मैं क्यूआरकोड्स का एक बड़ा प्रशंसक हूं, वे असली दुनिया और डिजिटल दुनिया के बीच डेटा का आदान-प्रदान करने के लिए बहुत ही सरल और साफ तरीके हैं। कुछ सालों से अब मेरे पास एक छोटी सा परियोजना है QRSnapper & mdash; ठीक है, इसमें कुछ नाम हैं, लेकिन यह वह है जिसे मैंने तय किया है & mdash; जो उपयोगकर्ता के कैमरे से लाइव डेटा लेने के लिए getUserMedia API का उपयोग करता है ताकि वह वास्तविक समय में क्यूआर कोडों के लिए स्कैन कर सके।

ऐप का लक्ष्य यूआई में 60 एफपीएस बनाए रखना और क्यूआर कोड के तत्काल पता लगाने के लिए था, इसका मतलब था कि मुझे एक वेब वर्कर (सुंदर मानक सामान) में पहचान कोड डालना पड़ा। इस पोस्ट में मैं बस वर्कर में तर्क को व्यापक रूप से सरल बनाने के लिए comlink का उपयोग कैसे करता हूं, इसे तुरंत साझा करना चाहता था।

qrclient.js

import * as Comlink from './comlink.js';

const proxy = Comlink.proxy(new Worker('/scripts/qrworker.js')); 

export const decode = async function (context) {
  try {
    let canvas = context.canvas;
    let width = canvas.width;
    let height = canvas.height;
    let imageData = context.getImageData(0, 0, width, height);
    return await proxy.detectUrl(width, height, imageData);
  } catch (err) {
    console.log(err);
  }
};

qrworker.js (वेब ​​वर्कर)

import * as Comlink from './comlink.js';
import {qrcode} from './qrcode.js';

// Use the native API's
let nativeDetector = async (width, height, imageData) => {
  try {
    let barcodeDetector = new BarcodeDetector();
    let barcodes = await barcodeDetector.detect(imageData);
    // return the first barcode.
    if (barcodes.length > 0) {
      return barcodes[0].rawValue;
    }
  } catch(err) {
    detector = workerDetector;
  }
};

// Use the polyfil
let workerDetector = async (width, height, imageData) => {
  try {
    return qrcode.decode(width, height, imageData);
  } catch (err) {
    // the library throws an excpetion when there are no qrcodes.
    return;
  }
}

let detectUrl = async (width, height, imageData) => {
  return detector(width, height, imageData);
};

let detector = ('BarcodeDetector' in self) ? nativeDetector : workerDetector;
// Expose the API to the client pages.
Comlink.expose({detectUrl}, self);

मुझे वास्तव में कॉमलिंक पसंद है, मुझे लगता है कि यह लाइब्रेरी का एक गेम चेंजर है, खासकर जब यह थियम्स पर काम करने वाली मूर्खतापूर्ण जावास्क्रिप्ट बनाने की बात आती है। अंततः यहां एक साफ चीज़ यह है कि मूल बारकोड पहचान एपीआई एक कार्यकर्ता के अंदर चलाया जा सकता है ताकि सभी तर्क यूआई से दूर हो जाएं।

पूर्ण पोस्ट पढ़ें

Running FFMPEG with WASM in a Web Worker

Paul Kinlan

मुझे FFMPEG.js पसंद है, यह एक साफ उपकरण है जिसे asm.js के साथ संकलित किया गया है और यह मुझे जेएस वेब ऐप्स बनाने देता है जो वीडियो को त्वरित रूप से संपादित कर सकता है। FFMPEG.js वेब श्रमिकों के साथ भी काम करता है ताकि आप मुख्य धागे को अवरुद्ध किए बिना वीडियो एन्कोड कर सकें।

मुझे भी पसंद है कॉमलिंक। कॉमलिंक चलो मैं जटिल ‘पोस्ट मैसेज’ राज्य मशीन से निपटने के बिना कार्यों और कक्षाओं को उजागर करके वेब श्रमिकों से आसानी से बातचीत कर सकता हूं।

मुझे हाल ही में दोनों को एक साथ जोड़ना है। मैं वेब असेंबली में निर्यात किए गए एफएफएमपीईजी का प्रयोग कर रहा था (यह काम करता है - याय) और मैं वर्तमान FFMPEG.js प्रोजेक्ट में सभी पोस्ट मैसेज काम को साफ़ करना चाहता था। नीचे कोड अब जैसा दिखता है - मुझे लगता है कि यह बहुत साफ है। हमारे पास एक कार्यकर्ता है जो ffmpeg.js और comlink आयात करता है और यह केवल ffmpeg इंटरफ़ेस का खुलासा करता है, और उसके बाद हमारे पास वेबपृष्ठ है जो कार्यकर्ता को लोड करता है और फिर ffmpeg API में प्रॉक्सी बनाने के लिए कॉमलिंक का उपयोग करता है।

साफ।

worker.js

importScripts('https://cdn.jsdelivr.net/npm/comlinkjs@3.0.2/umd/comlink.js');
importScripts('../ffmpeg-webm.js'); 
Comlink.expose(ffmpegjs, self);

client.html

let ffmpegjs = await Comlink.proxy(worker);
let result = await ffmpegjs({
   arguments: ['-y','-i', file.name, 'output.webm'],
   MEMFS: [{name: file.name, data: data}],
   stdin: Comlink.proxyValue(() => {}),
   onfilesready: Comlink.proxyValue((e) => {
     let data = e.MEMFS[0].data;
     output.src = URL.createObjectURL(new Blob([data]))
     console.log('ready', e)
   }),
   print: Comlink.proxyValue(function(data) { console.log(data); stdout += data + "\n"; }),
   printErr: Comlink.proxyValue(function(data) { console.log('error', data); stderr += data + "\n"; }),
   postRun: Comlink.proxyValue(function(result) { console.log('DONE', result); }),
   onExit: Comlink.proxyValue(function(code) {
     console.log("Process exited with code " + code);
     console.log(stdout);
   }),
});

मुझे वास्तव में पसंद है कि कॉमलिंक, वर्कर्स और डब्ल्यूएएसएम संकलित मॉड्यूल कैसे खेल सकते हैं। मुझे मूर्खतापूर्ण जावास्क्रिप्ट मिलता है जो सीधे WASM मॉड्यूल के साथ इंटरैक्ट करता है और यह मुख्य धागे को चलाता है।

पूर्ण पोस्ट पढ़ें

Translating a blog using Google Cloud Translate and Hugo

Paul Kinlan

मैं हाल ही में Google4 इंडिया ईवेंट (जल्द ही रिपोर्ट) में भाग लेने और कई व्यवसायों और डेवलपर्स से मिलने के लिए भारत की यात्रा से लौट आया। चर्चा में सबसे दिलचस्प परिवर्तनों में से एक देश में उपयोगकर्ताओं की भाषा में अधिक सामग्री के लिए धक्का था, और यह विशेष रूप से Google के सभी उत्पादों में स्पष्ट था जो उपयोगकर्ताओं की भाषा में खोजना आसान बनाने, सामग्री खोजने के लिए, और इसे टेक्स्ट या वॉइस फॉर्म में उपयोगकर्ताओं को वापस पढ़ने के लिए भी।

पूरी यात्रा ने मुझे सोच लिया। मेरा ब्लॉग ह्यूगो के साथ बनाया गया है। ह्यूगो अब कई भाषाओं में लिखित सामग्री का समर्थन करता है। ह्यूगो पूरी तरह स्थिर है, इसलिए नई सामग्री बनाना सिर्फ एक नई फाइल बनाने और बिल्ड सिस्टम को जादू करने की बात है। तो शायद मैं कुछ ऐसा निर्माण कर सकता हूं जो मेरी सामग्री को एक अनुवाद उपकरण के माध्यम से मेरी स्थिर सामग्री चलाकर अधिक लोगों के लिए अधिक उपलब्ध कराएगा क्योंकि सामग्री का मानव अनुवाद बहुत महंगा है।

यूके में वापस आने से कुछ घंटे पहले मैंने एक छोटी सी लिपि बनाई जो मेरी मार्कडाउन फाइलें ले लेगा और उन्हें त्वरित बनाने के लिए Google क्लाउड अनुवाद के माध्यम से चलाएगा उस पृष्ठ का अनुवाद जिसे मैं तुरंत होस्ट कर सकता हूं। पूरा समाधान नीचे प्रस्तुत किया गया है। यह एक अपेक्षाकृत बुनियादी प्रोसेसर है, यह हूगो प्रमोबल को अनदेखा करता है, यह ‘कोड’ को अनदेखा करता है और यह पुल उद्धरणों को अनदेखा करता है - मेरी धारणा यह थी कि इन्हें हमेशा लिखे जाने के तरीके के रूप में छोड़ा जाना चाहिए।

नोट: यह अनुवादों के उपयोग के लिए हमारे सीखने के सॉफ्टवेयर की तरह दिखता है, इसलिए यह महत्वपूर्ण है कि अपने पृष्ठ को चिह्नित करें ताकि सीखने के उपकरण Google अनुवादित सामग्री का उपयोग इसके एल्गोरिदम में इनपुट के रूप में न करें

// Imports the Google Cloud client library
const Translate = require('@google-cloud/translate');
const program = require('commander');
const fs = require('fs');
const path = require('path');

program
  .version('0.1.0')
  .option('-s, --source [path]', 'Add in the source file.')
  .option('-t, --target [lang]', 'Add target language.')
  .parse(process.argv);

// Creates a client
const translate = new Translate({
  projectId: 'html5rocks-hrd'
});

const options = {
  to:  program.target,
};

async function translateLines(text) {
  if(text === ' ') return ' ';
  const output = [];
  let results = await translate.translate(text, options);

  let translations = results[0];
  translations = Array.isArray(translations)
    ? translations
    : [translations];

  translations.forEach((translation, i) => {
    output.push(translation)
  });

  return output.join('\n');
};

// Translates the text into the target language. "text" can be a string for
// translating a single piece of text, or an array of strings for translating
// multiple texts.
(async function (filePath, target) {

  const text = fs.readFileSync(filePath, 'utf8');

  const lines = text.split('\n');
  let translateBlock = [];
  const output = [];

  let inHeader = false;
  let inCode = false;
  let inQuote = false;
  for (const line of lines) {
    // Don't translate preampble
    if (line.startsWith('---') && inHeader) { inHeader = false; output.push(line); continue; }
    if (line.startsWith('---')) { inHeader = true; output.push(line); continue; }
    if (inHeader) { output.push(line); continue; }

    // Don't translate code
    if (line.startsWith('```') && inCode) { inCode = false; output.push(line); continue; }
    if (line.startsWith('```')) { inCode = true; output.push(await translateLines(translateBlock.join(' '))); translateBlock = []; output.push(line); continue; }
    if (inCode) { output.push(line); continue; }

    // Dont translate quotes
    if (inQuote && line.startsWith('>') === false) { inQuote = false; }
    if (line.startsWith('>')) { inQuote = true; output.push(await translateLines(translateBlock.join(' '))); translateBlock = []; output.push(line); }
    if (inQuote) { output.push(line); continue; }

    if (line.charAt(0) === '\n' || line.length === 0) { output.push(await translateLines(translateBlock.join(' '))); output.push(line); translateBlock = []; continue;} 

    translateBlock.push(line);
  }

  if(translateBlock.length > 0) output.push(await translateLines(translateBlock.join(' ')))

  const result = output.join('\n');
  const newFileName = path.parse(filePath);
  fs.writeFileSync(`content/${newFileName.name}.${target}${newFileName.ext}`, result);

})(program.source, program.target);

कुल मिलाकर, मैं प्रक्रिया से बहुत खुश हूं। मैं समझता हूं कि मशीन अनुवाद सही नहीं है लेकिन मेरी सोच यह है कि मैं अपनी सामग्री की पहुंच को उन लोगों तक बढ़ा सकता हूं जो अपनी भाषा में खोज रहे हों, न कि अंग्रेजी में, मैं अपनी सामग्री की खोज सतह क्षेत्र को बढ़ा सकता हूं और उम्मीद करता हूं कि और अधिक मदद करें लोग।

यह देखने में कुछ समय लगेगा कि यह वास्तव में लोगों की मदद करता है, इसलिए जब मैं अधिक डेटा प्राप्त करता हूं तो मैं वापस रिपोर्ट करूंगा …. अब मेरी स्क्रिप्ट को मेरी साइट पर चलाने के लिए :)

Apple - Web apps - All Categories

Paul Kinlan

याद रखें जब वेब एप्स * आई * पर ऐप का उपयोग करने के लिए अनुशंसित तरीका थे?

What are web apps? Learn what they are and how to use them.

पूर्ण पोस्ट पढ़ें

लगभग 2013 में ऐप्पल ने / webapps / top-level निर्देशिका को / iphone /

बात यह है कि निर्देशिका वास्तव में बहुत अच्छी थी, आज भी बहुत से ऐप्स आज काम करते हैं। हालांकि ऐपस्टोर को देखते हुए डेवलपर्स के पास बहुत अधिक समस्याएं हल हुईं: बेहतर खोज और विशेष रूप से खोज क्योंकि ऐपस्टोर सीधे डिवाइस पर था। ऐपस्टोर भी उपयोगकर्ताओं और डेवलपर्स से विशेष रूप से भुगतान के संबंध में हटाए गए घर्षण को पेश करना शुरू कर रहा था।

Gears API

Paul Kinlan

मैं शुरुआती मोबाइल वेब एपीआई के बारे में एक ब्लॉग पोस्ट लिख रहा हूं और एलेक्स रसेल ने मुझे Google गियर्स की याद दिला दी

Gears modules include:

  • LocalServer Cache and serve application resources (HTML, JavaScript, images, etc.) locally
  • Database Store data locally in a fully-searchable relational database
  • WorkerPool Make your web applications more responsive by performing resource-intensive operations asynchronously

पूर्ण पोस्ट पढ़ें

मुझे लगता है कि यह देखना दिलचस्प है कि ऐप कैश और वेबस्क्लुएल, जिओलोकेशन और वेबवर्कर्स Google गियर्स में विचारों से बाहर आए और यह केवल बाद वाले दो हैं जो वास्तव में जीवित रहे। WebSQL कभी व्यापक रूप से समर्थित नहीं था, और indexedDB द्वारा प्रतिस्थापित किया गया था; और AppCache ServiceWorker द्वारा प्रतिस्थापित किया गया

RSS Feed to Google Chat Webhook using Cloud Functions for Firebase and Superfeedr

Paul Kinlan

हम अपनी टीम में संवाद करने के लिए आंतरिक रूप से Google चैट का उपयोग करते हैं - यह हमारे ढीले की तरह है; हम आरएसएस फ़ीड के माध्यम से बहुत सी सामग्री भी उपलब्ध कराते हैं, हमारे पास एक टीम फीड भी है जिसे आप सभी देख सकते हैं। यह हाल ही में तब तक नहीं था जब मुझे पता चला कि [वेबहूक के माध्यम से एक साधारण पोस्ट-केवल बॉट] बनाना आसान था (https://developers.google.com/hangouts/chat/how-tos/webhooks) और वह मुझे यह विचार दिया, मैं एक साधारण सेवा बना सकता हूं जो आरएसएस फ़ीड को खिलाती है और फिर उन्हें हमारे वेबकूक पर भेजती है जो सीधे हमारी टीम चैट में पोस्ट कर सकती है।

अंत में यह बहुत आसान था, और मैंने नीचे दिए गए सभी कोड शामिल किए हैं। मैंने फायरबेस फ़ंक्शन का उपयोग किया - मुझे संदेह है कि यह अन्य फ़ंक्शन-ए-ए-सर्विस साइट्स और सुपरफेडर ​​पर जितना आसान है। सुपरफेडर एक ऐसी सेवा है जो Pubsubhubbub पिंग्स (अब वेबसब) सुन सकती है और यह आरएसएस फ़ीड को भी मतदान करेगी जिसमें पब्सब सेट नहीं है। फिर जब यह एक फीड पाता है तो यह एक कॉन्फ़िगर किए गए यूआरएल (मेरे मामले में फायरबेस में मेरे क्लाउड फ़ंक्शन) को एक्सएमएल या जेएसओएन के नए पाए गए फ़ीड डेटा के प्रतिनिधित्व के साथ पिंग करेगा - आपको बस डेटा को पार्स करना होगा और इसके साथ कुछ करना होगा।

const functions = require('firebase-functions');
const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const app = express();

// Automatically allow cross-origin requests
app.use(cors({ origin: true }));

app.post('/', (req, res) => {
  const { webhook_url } = req.query;
  const { body } = req;
  if (body.items === undefined || body.items.length === 0) {
    res.send('');
    return;
  }

  const item = body.items[0];
  const actor = (item.actor && item.actor.displayName) ? item.actor.displayName : body.title;

  fetch(webhook_url, {
    method: 'POST',
    headers: {
      "Content-Type": "application/json; charset=utf-8",
    },
    body: JSON.stringify({
      "text": `*${actor}* published <${item.permalinkUrl}|${item.title}>. Please consider <https://twitter.com/intent/tweet?url=${encodeURIComponent(body.items[0].permalinkUrl)}&text=${encodeURIComponent(body.items[0].title)}|Sharing it>.`
    })  
  }).then(() => {
    return res.send('ok');
  }).catch(() => {
    return res.send('error')
  });
})
// Expose Express API as a single Cloud Function:
exports.publish = functions.https.onRequest(app);

पूर्ण पोस्ट पढ़ें

मैं आश्चर्यचकित और प्रसन्न था कि इसे स्थापित करना कितना आसान था।

Using HTTPArchive and Chrome UX report to get Lighthouse score for top visited sites in India.

Paul Kinlan

A quick dive in to how to use Lighthouse,HTTPArchive and Chrome UX report to try and understand how users in a country might experience the web.

Read More