<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>FastAPI on Nguyen Ngoc Tin</title><link>https://ngoctin.me/tags/fastapi/</link><description>Recent content in FastAPI on Nguyen Ngoc Tin</description><generator>Hugo</generator><language>en</language><managingEditor>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</managingEditor><webMaster>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</webMaster><lastBuildDate>Fri, 20 Mar 2026 10:00:00 +0700</lastBuildDate><atom:link href="https://ngoctin.me/tags/fastapi/index.xml" rel="self" type="application/rss+xml"/><item><title>Bilingual Movie Learn: Nền tảng học tiếng Anh qua phim với Google Gemini API</title><link>https://ngoctin.me/posts/bilingual-movie-learning-platform/</link><pubDate>Fri, 20 Mar 2026 10:00:00 +0700</pubDate><author>ngoctin.work@gmail.com (Nguyen Ngoc Tin)</author><guid>https://ngoctin.me/posts/bilingual-movie-learning-platform/</guid><description>&lt;div class="youtube-embed-wrapper" data-video-id="USj7dpTuOZI" data-speed="1.5"&gt;&#10; &lt;div class="youtube-lite-player" onclick="playYoutubeInstant(this)" role="button" tabindex="0" aria-label="Phát video YouTube Video (tốc độ 1.5x)" onkeydown="if(event.key==='Enter'||event.key===' '){event.preventDefault();playYoutubeInstant(this);}"&gt;&#10; &lt;picture&gt;&#10; &lt;source srcset="https://i.ytimg.com/vi_webp/USj7dpTuOZI/maxresdefault.webp" type="image/webp"&gt;&#10; &lt;img src="https://i.ytimg.com/vi/USj7dpTuOZI/hqdefault.jpg" alt="YouTube Video" loading="lazy" class="youtube-poster-img" onerror="this.onerror=null;this.src='https://i.ytimg.com/vi/USj7dpTuOZI/hqdefault.jpg';"&gt;&#10; &lt;/picture&gt;&#10; &lt;button class="youtube-play-btn" type="button" aria-hidden="true" tabindex="-1"&gt;&#10; &lt;svg viewBox="0 0 68 48" width="64" height="45" class="youtube-play-svg"&gt;&#10; &lt;path class="youtube-btn-bg" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f43f5e"&gt;&lt;/path&gt;&#10; &lt;path d="M 45,24 27,14 27,34" fill="#ffffff"&gt;&lt;/path&gt;&#10; &lt;/svg&gt;&#10; &lt;/button&gt;&#10; &lt;div class="youtube-badge-speed"&gt;1.5x Speed&lt;/div&gt;&#10; &lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;script&gt;&#10;if (!window.playYoutubeInstant) {&#10; window._ytApiCallbacks = [];&#10; window._ytApiLoading = false;&#10;&#10; window.ensureYTAPILoaded = function(cb) {&#10; if (window.YT &amp;&amp; window.YT.Player) {&#10; cb();&#10; return;&#10; }&#10; window._ytApiCallbacks.push(cb);&#10; if (!window._ytApiLoading) {&#10; window._ytApiLoading = true;&#10; var tag = document.createElement('script');&#10; tag.id = 'yt-iframe-api';&#10; tag.src = 'https://www.youtube.com/iframe_api';&#10; var first = document.getElementsByTagName('script')[0];&#10; first.parentNode.insertBefore(tag, first);&#10;&#10; var prev = window.onYouTubeIframeAPIReady;&#10; window.onYouTubeIframeAPIReady = function() {&#10; if (typeof prev === 'function') prev();&#10; while (window._ytApiCallbacks.length) {&#10; var fn = window._ytApiCallbacks.shift();&#10; try { fn(); } catch (e) { console.error(e); }&#10; }&#10; };&#10; }&#10; };&#10;&#10; window.playYoutubeInstant = function(el) {&#10; var wrapper = el.closest('.youtube-embed-wrapper');&#10; if (!wrapper) return;&#10; var id = wrapper.getAttribute('data-video-id');&#10; var start = parseInt(wrapper.getAttribute('data-start'), 10) || 0;&#10; var speed = parseFloat(wrapper.getAttribute('data-speed')) || 1.5;&#10;&#10; var playerId = 'yt-player-' + Math.random().toString(36).substr(2, 9);&#10; var playerDiv = document.createElement('div');&#10; playerDiv.id = playerId;&#10; playerDiv.className = 'youtube-iframe-active';&#10;&#10; wrapper.innerHTML = '';&#10; wrapper.appendChild(playerDiv);&#10;&#10; window.ensureYTAPILoaded(function() {&#10; var speedApplied = false;&#10; new YT.Player(playerId, {&#10; videoId: id,&#10; playerVars: {&#10; autoplay: 1,&#10; playsinline: 1,&#10; rel: 0,&#10; modestbranding: 1,&#10; start: start&#10; },&#10; events: {&#10; onReady: function(event) {&#10; try {&#10; event.target.setPlaybackRate(speed);&#10; event.target.playVideo();&#10; } catch (err) {}&#10; },&#10; onStateChange: function(event) {&#10; if (!speedApplied &amp;&amp; event.data === YT.PlayerState.PLAYING) {&#10; try {&#10; event.target.setPlaybackRate(speed);&#10; speedApplied = true;&#10; } catch (err) {}&#10; }&#10; }&#10; }&#10; });&#10; });&#10; };&#10;}&#10;&lt;/script&gt;&#10;&lt;div class="admonition abstract open"&gt;&#10; &lt;div class="admonition-title"&gt;&#10; &lt;i class="icon ti ti-list-details" aria-hidden="true"&gt;&lt;/i&gt;Abstract&#10; &lt;/div&gt;&#10; &lt;div class="admonition-content"&gt;&lt;p&gt;Bilingual Movie Learn là nền tảng học tiếng Anh tương tác qua phim ảnh, giúp người học tra cứu từ vựng theo ngữ cảnh và giải thích ngữ pháp tức thì từ câu thoại video thông qua Google Gemini API.&lt;/p&gt;</description></item></channel></rss>