{"id":1592,"date":"2025-08-28T08:07:53","date_gmt":"2025-08-28T08:07:53","guid":{"rendered":"https:\/\/zahiralam.com\/blog\/?p=1592"},"modified":"2025-11-12T11:33:47","modified_gmt":"2025-11-12T11:33:47","slug":"gemini-2-5-flash-live-preview-on-macos-apple-silicon-end-to-end-tutorial","status":"publish","type":"post","link":"https:\/\/zahiralam.com\/blog\/gemini-2-5-flash-live-preview-on-macos-apple-silicon-end-to-end-tutorial\/","title":{"rendered":"Gemini 2.5 Flash\u00a0Live Preview\u00a0on macOS (Apple Silicon) : End-to-End Tutorial"},"content":{"rendered":"\n<p>This is a complete, guide for setting up&nbsp;<strong>Gemini 2.5 Flash Live Preview<\/strong>&nbsp;(real-time audio + optional camera\/screen frames) on a Mac with&nbsp;<strong>Miniconda<\/strong>.\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What you\u2019ll build<\/h2>\n\n\n\n<p>A Python script (<code><a href=\"https:\/\/github.com\/google-gemini\/cookbook\/blob\/main\/quickstarts\/Get_started_LiveAPI.py\" target=\"_blank\" rel=\"noreferrer noopener\">live_preview_stream.py<\/a><\/code>) that:\n\n\n\n<ul class=\"wp-block-list\">\n<li>streams&nbsp;<strong>your mic audio<\/strong>&nbsp;to Gemini and&nbsp;<strong>plays back<\/strong>&nbsp;the model\u2019s voice in real time,<\/li>\n\n\n\n<li>optionally streams&nbsp;<strong>webcam frames<\/strong>&nbsp;(<code>--mode camera<\/code>) or&nbsp;<strong>screen captures<\/strong>&nbsp;(<code>--mode screen<\/code>),<\/li>\n\n\n\n<li>lets you also send&nbsp;<strong>typed text<\/strong>&nbsp;in the terminal.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>macOS on Apple Silicon<\/strong>&nbsp;(M1\/M2\/M3\/M4).<\/li>\n\n\n\n<li><strong>Miniconda<\/strong>&nbsp;(or Anaconda).<\/li>\n\n\n\n<li>(Optional)&nbsp;<strong>Homebrew<\/strong>&nbsp;\u2014 only needed if you prefer to install PortAudio via brew.<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If you don\u2019t have Miniconda:&nbsp;https:\/\/zahiralam.com\/blog\/conda-installation-on-apple-silicon-mac-simplified-step-by-step-instructions\/\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">1) Create a clean conda environment<\/h1>\n\n\n\n<p>We\u2019ll use&nbsp;<strong>Python 3.11<\/strong>&nbsp;because the script uses&nbsp;<code>asyncio.TaskGroup<\/code>&nbsp;and&nbsp;<code>ExceptionGroup<\/code>&nbsp;(which are 3.11 features).\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-1\">conda create -n gemini-live python=3.11 -y\nconda activate gemini-live<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#conda%20create%20-n%20gemini-live%20python%3D3.11%20-y%0Aconda%20activate%20gemini-live\">\n                            <button class=\"copy-button\" data-label=\"conda create -n gemini-live python=3.11 -y\nconda activate gemini-live\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">2) Install PortAudio and PyAudio (audio I\/O)<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">Option A (keeps everything inside the conda env) \u2705<\/h3>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-2\"># install PortAudio into the env\nconda install -c conda-forge portaudio -y\n\n# tell the compiler to look inside this env for headers\/libs\nexport CFLAGS=&quot;-I$CONDA_PREFIX\/include&quot;\nexport LDFLAGS=&quot;-L$CONDA_PREFIX\/lib&quot;\nexport PKG_CONFIG_PATH=&quot;$CONDA_PREFIX\/lib\/pkgconfig&quot;\n\n# build PyAudio against that PortAudio\npython -m pip install --no-binary :all: pyaudio<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#%23%20install%20PortAudio%20into%20the%20env%0Aconda%20install%20-c%20conda-forge%20portaudio%20-y%0A%0A%23%20tell%20the%20compiler%20to%20look%20inside%20this%20env%20for%20headers%2Flibs%0Aexport%20CFLAGS%3D%22-I%24CONDA_PREFIX%2Finclude%22%0Aexport%20LDFLAGS%3D%22-L%24CONDA_PREFIX%2Flib%22%0Aexport%20PKG_CONFIG_PATH%3D%22%24CONDA_PREFIX%2Flib%2Fpkgconfig%22%0A%0A%23%20build%20PyAudio%20against%20that%20PortAudio%0Apython%20-m%20pip%20install%20--no-binary%20%3Aall%3A%20pyaudio\">\n                            <button class=\"copy-button\" data-label=\"# install PortAudio into the env\nconda install -c conda-forge portaudio -y\n\n# tell the compiler to look inside this env for headers\/libs\nexport CFLAGS=&quot;-I$CONDA_PREFIX\/include&quot;\nexport LDFLAGS=&quot;-L$CONDA_PREFIX\/lib&quot;\nexport PKG_CONFIG_PATH=&quot;$CONDA_PREFIX\/lib\/pkgconfig&quot;\n\n# build PyAudio against that PortAudio\npython -m pip install --no-binary :all: pyaudio\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Verify audio devices<\/h3>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-3\">python - &lt;&lt; &#039;PY&#039;\nimport pyaudio\np = pyaudio.PyAudio()\nprint(&quot;OK. Devices:&quot;)\nfor i in range(p.get_device_count()):\n    d = p.get_device_info_by_index(i)\n    print(i, d[&quot;name&quot;], int(d[&quot;maxInputChannels&quot;]), int(d[&quot;maxOutputChannels&quot;]))\np.terminate()\nPY<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#python%20-%20%3C%3C%20%27PY%27%0Aimport%20pyaudio%0Ap%20%3D%20pyaudio.PyAudio%28%29%0Aprint%28%22OK.%20Devices%3A%22%29%0Afor%20i%20in%20range%28p.get_device_count%28%29%29%3A%0A%20%20%20%20d%20%3D%20p.get_device_info_by_index%28i%29%0A%20%20%20%20print%28i%2C%20d%5B%22name%22%5D%2C%20int%28d%5B%22maxInputChannels%22%5D%29%2C%20int%28d%5B%22maxOutputChannels%22%5D%29%29%0Ap.terminate%28%29%0APY\">\n                            <button class=\"copy-button\" data-label=\"python - &lt;&lt; &#039;PY&#039;\nimport pyaudio\np = pyaudio.PyAudio()\nprint(&quot;OK. Devices:&quot;)\nfor i in range(p.get_device_count()):\n    d = p.get_device_info_by_index(i)\n    print(i, d[&quot;name&quot;], int(d[&quot;maxInputChannels&quot;]), int(d[&quot;maxOutputChannels&quot;]))\np.terminate()\nPY\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<p>You should see your&nbsp;<strong>iPhone Microphone<\/strong>,&nbsp;<strong>MacBook Pro Microphone<\/strong>,&nbsp;<strong>Speakers<\/strong>, etc.\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>If you see mic errors:<\/strong>&nbsp;On macOS, go to&nbsp;<strong>System Settings \u2192 Privacy &amp; Security \u2192 Microphone<\/strong>&nbsp;and allow your Terminal\/iTerm\/VS Code. For camera mode, also allow&nbsp;<strong>Camera<\/strong>.\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">3) Install the SDK and vision\/screen dependencies<\/h1>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-4\">python -m pip install -U google-genai opencv-python pillow mss<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#python%20-m%20pip%20install%20-U%20google-genai%20opencv-python%20pillow%20mss\">\n                            <button class=\"copy-button\" data-label=\"python -m pip install -U google-genai opencv-python pillow mss\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>google-genai<\/code>&nbsp;\u2014 the new official SDK (<code>from google import genai<\/code>)<\/li>\n\n\n\n<li><code>opencv-python<\/code>&nbsp;(<code>cv2<\/code>) \u2014 webcam capture + color conversions<\/li>\n\n\n\n<li><code>pillow<\/code>&nbsp;\u2014 image re-encoding (JPEG)<\/li>\n\n\n\n<li><code>mss<\/code>&nbsp;\u2014 screen capture<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">4) Provide your API key<\/h1>\n\n\n\n<p>You have three safe choices; pick one.\n\n\n\n<h3 class=\"wp-block-heading\">Option 1 \u2014 Environment variable (recommended for servers\/CI)<\/h3>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-5\">export GOOGLE_API_KEY=&quot;YOUR_REAL_KEY&quot;<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#export%20GOOGLE_API_KEY%3D%22YOUR_REAL_KEY%22\">\n                            <button class=\"copy-button\" data-label=\"export GOOGLE_API_KEY=&quot;YOUR_REAL_KEY&quot;\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Option 2 \u2014&nbsp;<code>.env<\/code>&nbsp;file (nice for local dev)<\/h3>\n\n\n\n<p>Create&nbsp;<code>.env<\/code>&nbsp;in your project:\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-6\">GOOGLE_API_KEY=YOUR_REAL_KEY<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#GOOGLE_API_KEY%3DYOUR_REAL_KEY\">\n                            <button class=\"copy-button\" data-label=\"GOOGLE_API_KEY=YOUR_REAL_KEY\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<p>Load it early in your script:\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-7\">from dotenv import load_dotenv\nload_dotenv()  # pip install python-dotenv<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#from%20dotenv%20import%20load_dotenv%0Aload_dotenv%28%29%20%20%23%20pip%20install%20python-dotenv\">\n                            <button class=\"copy-button\" data-label=\"from dotenv import load_dotenv\nload_dotenv()  # pip install python-dotenv\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<h3 class=\"wp-block-heading\">Option 3 \u2014 Inline (quick demo only)<\/h3>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-8\">client = genai.Client(api_key=&quot;YOUR_REAL_KEY&quot;)<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#client%20%3D%20genai.Client%28api_key%3D%22YOUR_REAL_KEY%22%29\">\n                            <button class=\"copy-button\" data-label=\"client = genai.Client(api_key=&quot;YOUR_REAL_KEY&quot;)\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">5) The working script (key parts)<\/h1>\n\n\n\n<p>Your&nbsp;<code>live_preview_stream.py<\/code>&nbsp;already has all the right plumbing. Keep your logic and queues; ensure the following details match:\n\n\n\n<ul class=\"wp-block-list\">\n<li>Audio settings (good already):<code>FORMAT = pyaudio.paInt16 CHANNELS = 1 SEND_SAMPLE_RATE = 16000 # mic \u2192 model RECEIVE_SAMPLE_RATE = 24000 # model \u2192 speakers CHUNK_SIZE = 1024<\/code><\/li>\n\n\n\n<li>Live connect (already good):<code>async with client.aio.live.connect(model=MODEL, config=CONFIG) as session: self.session = session ...<\/code><\/li>\n\n\n\n<li>Camera frames (you already fixed BGR\u2192RGB):<code>frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img = PIL.Image.fromarray(frame_rgb) # re-encode to JPEG, base64, send with mime \"image\/jpeg\"<\/code><\/li>\n\n\n\n<li>Screen frames (via&nbsp;<code>mss<\/code>) \u2014 you re-encode to JPEG before sending.<\/li>\n\n\n\n<li>Messages to model:<br>Your code uses&nbsp;<code>await self.session.send(...)<\/code>. That\u2019s fine today. The SDK prints a&nbsp;<strong>DeprecationWarning<\/strong>(future change, not urgent). You can ignore it, silence it, or later migrate:\n<ul class=\"wp-block-list\">\n<li>Text \/ images \/ screen \u2192&nbsp;<code>send_client_content(...)<\/code><\/li>\n\n\n\n<li>Realtime audio chunks \u2192&nbsp;<code>send_realtime_input(...)<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>To&nbsp;<strong>silence the warning<\/strong>&nbsp;for now:\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-9\">import warnings\nwarnings.filterwarnings(\n    &quot;ignore&quot;,\n    message=&quot;The `session.send` method is deprecated&quot;,\n    category=DeprecationWarning,\n)<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#import%20warnings%0Awarnings.filterwarnings%28%0A%20%20%20%20%22ignore%22%2C%0A%20%20%20%20message%3D%22The%20%60session.send%60%20method%20is%20deprecated%22%2C%0A%20%20%20%20category%3DDeprecationWarning%2C%0A%29\">\n                            <button class=\"copy-button\" data-label=\"import warnings\nwarnings.filterwarnings(\n    &quot;ignore&quot;,\n    message=&quot;The `session.send` method is deprecated&quot;,\n    category=DeprecationWarning,\n)\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">6) Run it<\/h1>\n\n\n\n<p>From your project folder:\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-10\">conda activate gemini-live\n\n# voice only\npython live_preview_stream.py --mode none\n\n# webcam + mic\npython live_preview_stream.py --mode camera\n\n# screen + mic\npython live_preview_stream.py --mode screen<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#conda%20activate%20gemini-live%0A%0A%23%20voice%20only%0Apython%20live_preview_stream.py%20--mode%20none%0A%0A%23%20webcam%20%2B%20mic%0Apython%20live_preview_stream.py%20--mode%20camera%0A%0A%23%20screen%20%2B%20mic%0Apython%20live_preview_stream.py%20--mode%20screen\">\n                            <button class=\"copy-button\" data-label=\"conda activate gemini-live\n\n# voice only\npython live_preview_stream.py --mode none\n\n# webcam + mic\npython live_preview_stream.py --mode camera\n\n# screen + mic\npython live_preview_stream.py --mode screen\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<p>When it starts you\u2019ll see&nbsp;<code>message &gt;<\/code>. Type to send text; speak to send audio. Press&nbsp;<strong><code>q<\/code>&nbsp;+ Enter<\/strong>&nbsp;to exit.\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Quality checks &amp; tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>List audio devices<\/strong>&nbsp;(we did this) to ensure mic\/speaker are visible to PyAudio.<\/li>\n\n\n\n<li><strong>macOS permissions:<\/strong>&nbsp;the Terminal\/iTerm\/VS Code app must be allowed to use&nbsp;<strong>Microphone<\/strong>&nbsp;(and&nbsp;<strong>Camera<\/strong>&nbsp;for camera mode).<\/li>\n\n\n\n<li><strong>Frame rate:<\/strong>&nbsp;you already throttle to ~1 FPS with&nbsp;<code>await asyncio.sleep(1.0)<\/code>&nbsp;which is perfect for \u201cpreview\u201d without blowing the context.<\/li>\n\n\n\n<li><strong>.env for local dev:<\/strong>&nbsp;add&nbsp;<code>python-dotenv<\/code>&nbsp;to avoid exporting every time:<code>python -m pip install python-dotenv <\/code>and put this near the top of your script:<code>from dotenv import load_dotenv load_dotenv()<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Copy-paste install block (Apple Silicon)<\/h2>\n\n\n\n<div class=\"code-block-container\">\n                        <pre class=\"wp-block-code\"><code id=\"code-11\"># 1) env\nconda create -n gemini-live python=3.11 -y\nconda activate gemini-live\n\n# 2) audio stack\nconda install -c conda-forge portaudio -y\nexport CFLAGS=&quot;-I$CONDA_PREFIX\/include&quot;\nexport LDFLAGS=&quot;-L$CONDA_PREFIX\/lib&quot;\nexport PKG_CONFIG_PATH=&quot;$CONDA_PREFIX\/lib\/pkgconfig&quot;\npython -m pip install --no-binary :all: pyaudio\n\n# 3) sdk + vision\/screen\npython -m pip install -U google-genai opencv-python pillow mss\n\n# 4) api key (pick one method)\nexport GOOGLE_API_KEY=&quot;YOUR_REAL_KEY&quot;\n\n# 5) run\npython live_preview_stream.py --mode none\n# or\npython live_preview_stream.py --mode camera\n# or\npython live_preview_stream.py --mode screen<\/code><\/pre>\n                        <amp-iframe sandbox=\"allow-scripts\" width=\"94\" height=\"72\" frameborder=\"0\" \n                                    src=\"https:\/\/zahiralam.com\/blog\/wp-content\/plugins\/amp-copy-code-button\/copier.html#%23%201%29%20env%0Aconda%20create%20-n%20gemini-live%20python%3D3.11%20-y%0Aconda%20activate%20gemini-live%0A%0A%23%202%29%20audio%20stack%0Aconda%20install%20-c%20conda-forge%20portaudio%20-y%0Aexport%20CFLAGS%3D%22-I%24CONDA_PREFIX%2Finclude%22%0Aexport%20LDFLAGS%3D%22-L%24CONDA_PREFIX%2Flib%22%0Aexport%20PKG_CONFIG_PATH%3D%22%24CONDA_PREFIX%2Flib%2Fpkgconfig%22%0Apython%20-m%20pip%20install%20--no-binary%20%3Aall%3A%20pyaudio%0A%0A%23%203%29%20sdk%20%2B%20vision%2Fscreen%0Apython%20-m%20pip%20install%20-U%20google-genai%20opencv-python%20pillow%20mss%0A%0A%23%204%29%20api%20key%20%28pick%20one%20method%29%0Aexport%20GOOGLE_API_KEY%3D%22YOUR_REAL_KEY%22%0A%0A%23%205%29%20run%0Apython%20live_preview_stream.py%20--mode%20none%0A%23%20or%0Apython%20live_preview_stream.py%20--mode%20camera%0A%23%20or%0Apython%20live_preview_stream.py%20--mode%20screen\">\n                            <button class=\"copy-button\" data-label=\"# 1) env\nconda create -n gemini-live python=3.11 -y\nconda activate gemini-live\n\n# 2) audio stack\nconda install -c conda-forge portaudio -y\nexport CFLAGS=&quot;-I$CONDA_PREFIX\/include&quot;\nexport LDFLAGS=&quot;-L$CONDA_PREFIX\/lib&quot;\nexport PKG_CONFIG_PATH=&quot;$CONDA_PREFIX\/lib\/pkgconfig&quot;\npython -m pip install --no-binary :all: pyaudio\n\n# 3) sdk + vision\/screen\npython -m pip install -U google-genai opencv-python pillow mss\n\n# 4) api key (pick one method)\nexport GOOGLE_API_KEY=&quot;YOUR_REAL_KEY&quot;\n\n# 5) run\npython live_preview_stream.py --mode none\n# or\npython live_preview_stream.py --mode camera\n# or\npython live_preview_stream.py --mode screen\"  placeholder disabled>Copy<\/button>\n                        <\/amp-iframe>\n                    <\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n","protected":false},"excerpt":{"rendered":"<p>This is a complete, guide for setting up&nbsp;Gemini 2.5 Flash Live Preview&nbsp;(real-time audio + optional camera\/screen frames) on a Mac with&nbsp;Miniconda. What you\u2019ll build A [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":1628,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24],"tags":[277,278,256],"class_list":["post-1592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-artificial-intelligence","tag-gemini-2-5-flash-live-preview","tag-google-tts","tag-mac-m1-m2-m3-m4"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/posts\/1592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/comments?post=1592"}],"version-history":[{"count":3,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/posts\/1592\/revisions"}],"predecessor-version":[{"id":1629,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/posts\/1592\/revisions\/1629"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/media\/1628"}],"wp:attachment":[{"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/media?parent=1592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/categories?post=1592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zahiralam.com\/blog\/wp-json\/wp\/v2\/tags?post=1592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}