media/docs/doc/reference/com/google/android/exoplayer2/audio/AudioSink.html
olly a038f875f6 Update Javadoc for 2.14.0
#minor-release

PiperOrigin-RevId: 373351935
2021-05-12 13:55:32 +01:00

962 lines
45 KiB
HTML

<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="en">
<head><!-- start favicons snippet, use https://realfavicongenerator.net/ --><link rel="apple-touch-icon" sizes="180x180" href="/assets/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicon-16x16.png"><link rel="manifest" href="/assets/site.webmanifest"><link rel="mask-icon" href="/assets/safari-pinned-tab.svg" color="#fc4d50"><link rel="shortcut icon" href="/assets/favicon.ico"><meta name="msapplication-TileColor" content="#ffc40d"><meta name="msapplication-config" content="/assets/browserconfig.xml"><meta name="theme-color" content="#ffffff"><!-- end favicons snippet -->
<title>AudioSink (ExoPlayer library)</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="../../../../../stylesheet.css" title="Style">
<link rel="stylesheet" type="text/css" href="../../../../../jquery/jquery-ui.css" title="Style">
<script type="text/javascript" src="../../../../../script.js"></script>
<script type="text/javascript" src="../../../../../jquery/jszip/dist/jszip.min.js"></script>
<script type="text/javascript" src="../../../../../jquery/jszip-utils/dist/jszip-utils.min.js"></script>
<!--[if IE]>
<script type="text/javascript" src="../../../../../jquery/jszip-utils/dist/jszip-utils-ie.min.js"></script>
<![endif]-->
<script type="text/javascript" src="../../../../../jquery/jquery-3.5.1.js"></script>
<script type="text/javascript" src="../../../../../jquery/jquery-ui.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="AudioSink (ExoPlayer library)";
}
}
catch(err) {
}
//-->
var data = {"i0":6,"i1":6,"i2":6,"i3":6,"i4":6,"i5":6,"i6":6,"i7":6,"i8":6,"i9":6,"i10":6,"i11":6,"i12":6,"i13":6,"i14":6,"i15":6,"i16":6,"i17":6,"i18":6,"i19":6,"i20":6,"i21":6,"i22":6,"i23":6,"i24":6};
var tabs = {65535:["t0","All Methods"],2:["t2","Instance Methods"],4:["t3","Abstract Methods"]};
var altColor = "altColor";
var rowColor = "rowColor";
var tableTab = "tableTab";
var activeTableTab = "activeTableTab";
var pathtoroot = "../../../../../";
var useModuleDirectories = false;
loadScripts(document, 'script');</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<header role="banner">
<nav role="navigation">
<div class="fixedNav">
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a id="navbar.top">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a id="navbar.top.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../../../../../allclasses.html">All&nbsp;Classes</a></li>
</ul>
<ul class="navListSearch">
<li><label for="search">SEARCH:</label>
<input type="text" id="search" value="search" disabled="disabled">
<input type="reset" id="reset" value="reset" disabled="disabled">
</li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_top");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a id="skip.navbar.top">
<!-- -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
</div>
<div class="navPadding">&nbsp;</div>
<script type="text/javascript"><!--
$('.navPadding').css('padding-top', $('.fixedNav').css("height"));
//-->
</script>
</nav>
</header>
<!-- ======== START OF CLASS DATA ======== -->
<main role="main">
<div class="header">
<div class="subTitle"><span class="packageLabelInType">Package</span>&nbsp;<a href="package-summary.html">com.google.android.exoplayer2.audio</a></div>
<h2 title="Interface AudioSink" class="title">Interface AudioSink</h2>
</div>
<div class="contentContainer">
<div class="description">
<ul class="blockList">
<li class="blockList">
<dl>
<dt>All Known Implementing Classes:</dt>
<dd><code><a href="../testutil/CapturingAudioSink.html" title="class in com.google.android.exoplayer2.testutil">CapturingAudioSink</a></code>, <code><a href="DefaultAudioSink.html" title="class in com.google.android.exoplayer2.audio">DefaultAudioSink</a></code>, <code><a href="ForwardingAudioSink.html" title="class in com.google.android.exoplayer2.audio">ForwardingAudioSink</a></code></dd>
</dl>
<hr>
<pre>public interface <span class="typeNameLabel">AudioSink</span></pre>
<div class="block">A sink that consumes audio data.
<p>Before starting playback, specify the input audio format by calling <a href="#configure(com.google.android.exoplayer2.Format,int,int%5B%5D)"><code>configure(Format,
int, int[])</code></a>.
<p>Call <a href="#handleBuffer(java.nio.ByteBuffer,long,int)"><code>handleBuffer(ByteBuffer, long, int)</code></a> to write data, and <a href="#handleDiscontinuity()"><code>handleDiscontinuity()</code></a> when the data being fed is discontinuous. Call <a href="#play()"><code>play()</code></a> to start
playing the written data.
<p>Call <a href="#configure(com.google.android.exoplayer2.Format,int,int%5B%5D)"><code>configure(Format, int, int[])</code></a> whenever the input format changes. The sink will
be reinitialized on the next call to <a href="#handleBuffer(java.nio.ByteBuffer,long,int)"><code>handleBuffer(ByteBuffer, long, int)</code></a>.
<p>Call <a href="#flush()"><code>flush()</code></a> to prepare the sink to receive audio data from a new playback position.
<p>Call <a href="#playToEndOfStream()"><code>playToEndOfStream()</code></a> repeatedly to play out all data when no more input buffers
will be provided via <a href="#handleBuffer(java.nio.ByteBuffer,long,int)"><code>handleBuffer(ByteBuffer, long, int)</code></a> until the next <a href="#flush()"><code>flush()</code></a>. Call <a href="#reset()"><code>reset()</code></a> when the instance is no longer required.
<p>The implementation may be backed by a platform <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink"><code>AudioTrack</code></a>. In this case, <a href="#setAudioSessionId(int)"><code>setAudioSessionId(int)</code></a>, <a href="#setAudioAttributes(com.google.android.exoplayer2.audio.AudioAttributes)"><code>setAudioAttributes(AudioAttributes)</code></a>, <a href="#enableTunnelingV21()"><code>enableTunnelingV21()</code></a> and <a href="#disableTunneling()" target="_top"><code>disableTunneling()</code></a> may be called before writing data to the
sink. These methods may also be called after writing data to the sink, in which case it will be
reinitialized as required. For implementations that are not based on platform <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioTrack</code></a>s, calling methods relating to audio sessions, audio attributes, and tunneling may
have no effect.</div>
</li>
</ul>
</div>
<div class="summary">
<ul class="blockList">
<li class="blockList">
<!-- ======== NESTED CLASS SUMMARY ======== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="nested.class.summary">
<!-- -->
</a>
<h3>Nested Class Summary</h3>
<table class="memberSummary">
<caption><span>Nested Classes</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Interface</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.ConfigurationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.ConfigurationException</a></span></code></th>
<td class="colLast">
<div class="block">Thrown when a failure occurs configuring the sink.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.InitializationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.InitializationException</a></span></code></th>
<td class="colLast">
<div class="block">Thrown when a failure occurs initializing the sink.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static interface&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.Listener.html" title="interface in com.google.android.exoplayer2.audio">AudioSink.Listener</a></span></code></th>
<td class="colLast">
<div class="block">Listener for audio sink events.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static interface&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.SinkFormatSupport.html" title="annotation in com.google.android.exoplayer2.audio">AudioSink.SinkFormatSupport</a></span></code></th>
<td class="colLast">
<div class="block">The level of support the sink provides for a format.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.UnexpectedDiscontinuityException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.UnexpectedDiscontinuityException</a></span></code></th>
<td class="colLast">
<div class="block">Thrown when the sink encounters an unexpected timestamp discontinuity.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static class&nbsp;</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="AudioSink.WriteException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.WriteException</a></span></code></th>
<td class="colLast">
<div class="block">Thrown when a failure occurs writing to the sink.</div>
</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- =========== FIELD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.summary">
<!-- -->
</a>
<h3>Field Summary</h3>
<table class="memberSummary">
<caption><span>Fields</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Field</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#CURRENT_POSITION_NOT_SET">CURRENT_POSITION_NOT_SET</a></span></code></th>
<td class="colLast">
<div class="block">Returned by <a href="#getCurrentPositionUs(boolean)"><code>getCurrentPositionUs(boolean)</code></a> when the position is not set.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#SINK_FORMAT_SUPPORTED_DIRECTLY">SINK_FORMAT_SUPPORTED_DIRECTLY</a></span></code></th>
<td class="colLast">
<div class="block">The sink supports the format directly, without the need for internal transcoding.</div>
</td>
</tr>
<tr class="altColor">
<td class="colFirst"><code>static int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#SINK_FORMAT_SUPPORTED_WITH_TRANSCODING">SINK_FORMAT_SUPPORTED_WITH_TRANSCODING</a></span></code></th>
<td class="colLast">
<div class="block">The sink supports the format, but needs to transcode it internally to do so.</div>
</td>
</tr>
<tr class="rowColor">
<td class="colFirst"><code>static int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#SINK_FORMAT_UNSUPPORTED">SINK_FORMAT_UNSUPPORTED</a></span></code></th>
<td class="colLast">
<div class="block">The sink does not support the format.</div>
</td>
</tr>
</table>
</li>
</ul>
</section>
<!-- ========== METHOD SUMMARY =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.summary">
<!-- -->
</a>
<h3>Method Summary</h3>
<table class="memberSummary">
<caption><span id="t0" class="activeTableTab"><span>All Methods</span><span class="tabEnd">&nbsp;</span></span><span id="t2" class="tableTab"><span><a href="javascript:show(2);">Instance Methods</a></span><span class="tabEnd">&nbsp;</span></span><span id="t3" class="tableTab"><span><a href="javascript:show(4);">Abstract Methods</a></span><span class="tabEnd">&nbsp;</span></span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Method</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tr id="i0" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#configure(com.google.android.exoplayer2.Format,int,int%5B%5D)">configure</a></span>&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;inputFormat,
int&nbsp;specifiedBufferSize,
int[]&nbsp;outputChannels)</code></th>
<td class="colLast">
<div class="block">Configures (or reconfigures) the sink.</div>
</td>
</tr>
<tr id="i1" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#disableTunneling()">disableTunneling</a></span>()</code></th>
<td class="colLast">
<div class="block">Disables tunneling.</div>
</td>
</tr>
<tr id="i2" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#enableTunnelingV21()">enableTunnelingV21</a></span>()</code></th>
<td class="colLast">
<div class="block">Enables tunneling, if possible.</div>
</td>
</tr>
<tr id="i3" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#experimentalFlushWithoutAudioTrackRelease()">experimentalFlushWithoutAudioTrackRelease</a></span>()</code></th>
<td class="colLast">
<div class="block">Flushes the sink, after which it is ready to receive buffers from a new playback position.</div>
</td>
</tr>
<tr id="i4" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#flush()">flush</a></span>()</code></th>
<td class="colLast">
<div class="block">Flushes the sink, after which it is ready to receive buffers from a new playback position.</div>
</td>
</tr>
<tr id="i5" class="rowColor">
<td class="colFirst"><code>long</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getCurrentPositionUs(boolean)">getCurrentPositionUs</a></span>&#8203;(boolean&nbsp;sourceEnded)</code></th>
<td class="colLast">
<div class="block">Returns the playback position in the stream starting at zero, in microseconds, or <a href="#CURRENT_POSITION_NOT_SET"><code>CURRENT_POSITION_NOT_SET</code></a> if it is not yet available.</div>
</td>
</tr>
<tr id="i6" class="altColor">
<td class="colFirst"><code>int</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getFormatSupport(com.google.android.exoplayer2.Format)">getFormatSupport</a></span>&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</code></th>
<td class="colLast">
<div class="block">Returns the level of support that the sink provides for a given <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</div>
</td>
</tr>
<tr id="i7" class="rowColor">
<td class="colFirst"><code><a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2">PlaybackParameters</a></code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getPlaybackParameters()">getPlaybackParameters</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns the active <a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2"><code>PlaybackParameters</code></a>.</div>
</td>
</tr>
<tr id="i8" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#getSkipSilenceEnabled()">getSkipSilenceEnabled</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns whether silences are skipped in the audio stream.</div>
</td>
</tr>
<tr id="i9" class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#handleBuffer(java.nio.ByteBuffer,long,int)">handleBuffer</a></span>&#8203;(<a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top">ByteBuffer</a>&nbsp;buffer,
long&nbsp;presentationTimeUs,
int&nbsp;encodedAccessUnitCount)</code></th>
<td class="colLast">
<div class="block">Attempts to process data from a <a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top"><code>ByteBuffer</code></a>, starting from its current position and
ending at its limit (exclusive).</div>
</td>
</tr>
<tr id="i10" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#handleDiscontinuity()">handleDiscontinuity</a></span>()</code></th>
<td class="colLast">
<div class="block">Signals to the sink that the next buffer may be discontinuous with the previous buffer.</div>
</td>
</tr>
<tr id="i11" class="rowColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#hasPendingData()">hasPendingData</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns whether the sink has data pending that has not been consumed yet.</div>
</td>
</tr>
<tr id="i12" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#isEnded()">isEnded</a></span>()</code></th>
<td class="colLast">
<div class="block">Returns whether <a href="#playToEndOfStream()"><code>playToEndOfStream()</code></a> has been called and all buffers have been processed.</div>
</td>
</tr>
<tr id="i13" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#pause()">pause</a></span>()</code></th>
<td class="colLast">
<div class="block">Pauses playback.</div>
</td>
</tr>
<tr id="i14" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#play()">play</a></span>()</code></th>
<td class="colLast">
<div class="block">Starts or resumes consuming audio if initialized.</div>
</td>
</tr>
<tr id="i15" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#playToEndOfStream()">playToEndOfStream</a></span>()</code></th>
<td class="colLast">
<div class="block">Processes any remaining data.</div>
</td>
</tr>
<tr id="i16" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#reset()">reset</a></span>()</code></th>
<td class="colLast">
<div class="block">Resets the renderer, releasing any resources that it currently holds.</div>
</td>
</tr>
<tr id="i17" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setAudioAttributes(com.google.android.exoplayer2.audio.AudioAttributes)">setAudioAttributes</a></span>&#8203;(<a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes</a>&nbsp;audioAttributes)</code></th>
<td class="colLast">
<div class="block">Sets attributes for audio playback.</div>
</td>
</tr>
<tr id="i18" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setAudioSessionId(int)">setAudioSessionId</a></span>&#8203;(int&nbsp;audioSessionId)</code></th>
<td class="colLast">
<div class="block">Sets the audio session id.</div>
</td>
</tr>
<tr id="i19" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setAuxEffectInfo(com.google.android.exoplayer2.audio.AuxEffectInfo)">setAuxEffectInfo</a></span>&#8203;(<a href="AuxEffectInfo.html" title="class in com.google.android.exoplayer2.audio">AuxEffectInfo</a>&nbsp;auxEffectInfo)</code></th>
<td class="colLast">
<div class="block">Sets the auxiliary effect.</div>
</td>
</tr>
<tr id="i20" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setListener(com.google.android.exoplayer2.audio.AudioSink.Listener)">setListener</a></span>&#8203;(<a href="AudioSink.Listener.html" title="interface in com.google.android.exoplayer2.audio">AudioSink.Listener</a>&nbsp;listener)</code></th>
<td class="colLast">
<div class="block">Sets the listener for sink events, which should be the audio renderer.</div>
</td>
</tr>
<tr id="i21" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setPlaybackParameters(com.google.android.exoplayer2.PlaybackParameters)">setPlaybackParameters</a></span>&#8203;(<a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2">PlaybackParameters</a>&nbsp;playbackParameters)</code></th>
<td class="colLast">
<div class="block">Attempts to set the playback parameters.</div>
</td>
</tr>
<tr id="i22" class="altColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setSkipSilenceEnabled(boolean)">setSkipSilenceEnabled</a></span>&#8203;(boolean&nbsp;skipSilenceEnabled)</code></th>
<td class="colLast">
<div class="block">Sets whether silences should be skipped in the audio stream.</div>
</td>
</tr>
<tr id="i23" class="rowColor">
<td class="colFirst"><code>void</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#setVolume(float)">setVolume</a></span>&#8203;(float&nbsp;volume)</code></th>
<td class="colLast">
<div class="block">Sets the playback volume.</div>
</td>
</tr>
<tr id="i24" class="altColor">
<td class="colFirst"><code>boolean</code></td>
<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="#supportsFormat(com.google.android.exoplayer2.Format)">supportsFormat</a></span>&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</code></th>
<td class="colLast">
<div class="block">Returns whether the sink supports a given <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</div>
</td>
</tr>
</table>
</li>
</ul>
</section>
</li>
</ul>
</div>
<div class="details">
<ul class="blockList">
<li class="blockList">
<!-- ============ FIELD DETAIL =========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="field.detail">
<!-- -->
</a>
<h3>Field Detail</h3>
<a id="SINK_FORMAT_SUPPORTED_DIRECTLY">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SINK_FORMAT_SUPPORTED_DIRECTLY</h4>
<pre>static final&nbsp;int SINK_FORMAT_SUPPORTED_DIRECTLY</pre>
<div class="block">The sink supports the format directly, without the need for internal transcoding.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../../constant-values.html#com.google.android.exoplayer2.audio.AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY">Constant Field Values</a></dd>
</dl>
</li>
</ul>
<a id="SINK_FORMAT_SUPPORTED_WITH_TRANSCODING">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SINK_FORMAT_SUPPORTED_WITH_TRANSCODING</h4>
<pre>static final&nbsp;int SINK_FORMAT_SUPPORTED_WITH_TRANSCODING</pre>
<div class="block">The sink supports the format, but needs to transcode it internally to do so. Internal
transcoding may result in lower quality and higher CPU load in some cases.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../../constant-values.html#com.google.android.exoplayer2.audio.AudioSink.SINK_FORMAT_SUPPORTED_WITH_TRANSCODING">Constant Field Values</a></dd>
</dl>
</li>
</ul>
<a id="SINK_FORMAT_UNSUPPORTED">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>SINK_FORMAT_UNSUPPORTED</h4>
<pre>static final&nbsp;int SINK_FORMAT_UNSUPPORTED</pre>
<div class="block">The sink does not support the format.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../../constant-values.html#com.google.android.exoplayer2.audio.AudioSink.SINK_FORMAT_UNSUPPORTED">Constant Field Values</a></dd>
</dl>
</li>
</ul>
<a id="CURRENT_POSITION_NOT_SET">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>CURRENT_POSITION_NOT_SET</h4>
<pre>static final&nbsp;long CURRENT_POSITION_NOT_SET</pre>
<div class="block">Returned by <a href="#getCurrentPositionUs(boolean)"><code>getCurrentPositionUs(boolean)</code></a> when the position is not set.</div>
<dl>
<dt><span class="seeLabel">See Also:</span></dt>
<dd><a href="../../../../../constant-values.html#com.google.android.exoplayer2.audio.AudioSink.CURRENT_POSITION_NOT_SET">Constant Field Values</a></dd>
</dl>
</li>
</ul>
</li>
</ul>
</section>
<!-- ============ METHOD DETAIL ========== -->
<section role="region">
<ul class="blockList">
<li class="blockList"><a id="method.detail">
<!-- -->
</a>
<h3>Method Detail</h3>
<a id="setListener(com.google.android.exoplayer2.audio.AudioSink.Listener)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setListener</h4>
<pre class="methodSignature">void&nbsp;setListener&#8203;(<a href="AudioSink.Listener.html" title="interface in com.google.android.exoplayer2.audio">AudioSink.Listener</a>&nbsp;listener)</pre>
<div class="block">Sets the listener for sink events, which should be the audio renderer.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>listener</code> - The listener for sink events, which should be the audio renderer.</dd>
</dl>
</li>
</ul>
<a id="supportsFormat(com.google.android.exoplayer2.Format)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>supportsFormat</h4>
<pre class="methodSignature">boolean&nbsp;supportsFormat&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</pre>
<div class="block">Returns whether the sink supports a given <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>format</code> - The format.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>Whether the sink supports the format.</dd>
</dl>
</li>
</ul>
<a id="getFormatSupport(com.google.android.exoplayer2.Format)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getFormatSupport</h4>
<pre class="methodSignature"><a href="AudioSink.SinkFormatSupport.html" title="annotation in com.google.android.exoplayer2.audio">@SinkFormatSupport</a>
int&nbsp;getFormatSupport&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;format)</pre>
<div class="block">Returns the level of support that the sink provides for a given <a href="../Format.html" title="class in com.google.android.exoplayer2"><code>Format</code></a>.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>format</code> - The format.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>The level of support provided.</dd>
</dl>
</li>
</ul>
<a id="getCurrentPositionUs(boolean)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getCurrentPositionUs</h4>
<pre class="methodSignature">long&nbsp;getCurrentPositionUs&#8203;(boolean&nbsp;sourceEnded)</pre>
<div class="block">Returns the playback position in the stream starting at zero, in microseconds, or <a href="#CURRENT_POSITION_NOT_SET"><code>CURRENT_POSITION_NOT_SET</code></a> if it is not yet available.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>sourceEnded</code> - Specify <code>true</code> if no more input buffers will be provided.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>The playback position relative to the start of playback, in microseconds.</dd>
</dl>
</li>
</ul>
<a id="configure(com.google.android.exoplayer2.Format,int,int[])">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>configure</h4>
<pre class="methodSignature">void&nbsp;configure&#8203;(<a href="../Format.html" title="class in com.google.android.exoplayer2">Format</a>&nbsp;inputFormat,
int&nbsp;specifiedBufferSize,
@Nullable
int[]&nbsp;outputChannels)
throws <a href="AudioSink.ConfigurationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.ConfigurationException</a></pre>
<div class="block">Configures (or reconfigures) the sink.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>inputFormat</code> - The format of audio data provided in the input buffers.</dd>
<dd><code>specifiedBufferSize</code> - A specific size for the playback buffer in bytes, or 0 to infer a
suitable buffer size.</dd>
<dd><code>outputChannels</code> - A mapping from input to output channels that is applied to this sink's
input as a preprocessing step, if handling PCM input. Specify <code>null</code> to leave the
input unchanged. Otherwise, the element at index <code>i</code> specifies index of the input
channel to map to output channel <code>i</code> when preprocessing input buffers. After the map
is applied the audio data will have <code>outputChannels.length</code> channels.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="AudioSink.ConfigurationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.ConfigurationException</a></code> - If an error occurs configuring the sink.</dd>
</dl>
</li>
</ul>
<a id="play()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>play</h4>
<pre class="methodSignature">void&nbsp;play()</pre>
<div class="block">Starts or resumes consuming audio if initialized.</div>
</li>
</ul>
<a id="handleDiscontinuity()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>handleDiscontinuity</h4>
<pre class="methodSignature">void&nbsp;handleDiscontinuity()</pre>
<div class="block">Signals to the sink that the next buffer may be discontinuous with the previous buffer.</div>
</li>
</ul>
<a id="handleBuffer(java.nio.ByteBuffer,long,int)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>handleBuffer</h4>
<pre class="methodSignature">boolean&nbsp;handleBuffer&#8203;(<a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top">ByteBuffer</a>&nbsp;buffer,
long&nbsp;presentationTimeUs,
int&nbsp;encodedAccessUnitCount)
throws <a href="AudioSink.InitializationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.InitializationException</a>,
<a href="AudioSink.WriteException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.WriteException</a></pre>
<div class="block">Attempts to process data from a <a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top"><code>ByteBuffer</code></a>, starting from its current position and
ending at its limit (exclusive). The position of the <a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top"><code>ByteBuffer</code></a> is advanced by the
number of bytes that were handled. <a href="AudioSink.Listener.html#onPositionDiscontinuity()"><code>AudioSink.Listener.onPositionDiscontinuity()</code></a> will be called if
<code>presentationTimeUs</code> is discontinuous with the last buffer handled since the last reset.
<p>Returns whether the data was handled in full. If the data was not handled in full then the
same <a href="https://developer.android.com/reference/java/nio/ByteBuffer.html" title="class or interface in java.nio" class="externalLink" target="_top"><code>ByteBuffer</code></a> must be provided to subsequent calls until it has been fully consumed,
except in the case of an intervening call to <a href="#flush()"><code>flush()</code></a> (or to <a href="#configure(com.google.android.exoplayer2.Format,int,int%5B%5D)"><code>configure(Format,
int, int[])</code></a> that causes the sink to be flushed).</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>buffer</code> - The buffer containing audio data.</dd>
<dd><code>presentationTimeUs</code> - The presentation timestamp of the buffer in microseconds.</dd>
<dd><code>encodedAccessUnitCount</code> - The number of encoded access units in the buffer, or 1 if the
buffer contains PCM audio. This allows batching multiple encoded access units in one
buffer.</dd>
<dt><span class="returnLabel">Returns:</span></dt>
<dd>Whether the buffer was handled fully.</dd>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="AudioSink.InitializationException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.InitializationException</a></code> - If an error occurs initializing the sink.</dd>
<dd><code><a href="AudioSink.WriteException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.WriteException</a></code> - If an error occurs writing the audio data.</dd>
</dl>
</li>
</ul>
<a id="playToEndOfStream()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>playToEndOfStream</h4>
<pre class="methodSignature">void&nbsp;playToEndOfStream()
throws <a href="AudioSink.WriteException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.WriteException</a></pre>
<div class="block">Processes any remaining data. <a href="#isEnded()"><code>isEnded()</code></a> will return <code>true</code> when no data remains.</div>
<dl>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="AudioSink.WriteException.html" title="class in com.google.android.exoplayer2.audio">AudioSink.WriteException</a></code> - If an error occurs draining data to the sink.</dd>
</dl>
</li>
</ul>
<a id="isEnded()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>isEnded</h4>
<pre class="methodSignature">boolean&nbsp;isEnded()</pre>
<div class="block">Returns whether <a href="#playToEndOfStream()"><code>playToEndOfStream()</code></a> has been called and all buffers have been processed.</div>
</li>
</ul>
<a id="hasPendingData()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>hasPendingData</h4>
<pre class="methodSignature">boolean&nbsp;hasPendingData()</pre>
<div class="block">Returns whether the sink has data pending that has not been consumed yet.</div>
</li>
</ul>
<a id="setPlaybackParameters(com.google.android.exoplayer2.PlaybackParameters)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setPlaybackParameters</h4>
<pre class="methodSignature">void&nbsp;setPlaybackParameters&#8203;(<a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2">PlaybackParameters</a>&nbsp;playbackParameters)</pre>
<div class="block">Attempts to set the playback parameters. The audio sink may override these parameters if they
are not supported.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>playbackParameters</code> - The new playback parameters to attempt to set.</dd>
</dl>
</li>
</ul>
<a id="getPlaybackParameters()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getPlaybackParameters</h4>
<pre class="methodSignature"><a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2">PlaybackParameters</a>&nbsp;getPlaybackParameters()</pre>
<div class="block">Returns the active <a href="../PlaybackParameters.html" title="class in com.google.android.exoplayer2"><code>PlaybackParameters</code></a>.</div>
</li>
</ul>
<a id="setSkipSilenceEnabled(boolean)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setSkipSilenceEnabled</h4>
<pre class="methodSignature">void&nbsp;setSkipSilenceEnabled&#8203;(boolean&nbsp;skipSilenceEnabled)</pre>
<div class="block">Sets whether silences should be skipped in the audio stream.</div>
</li>
</ul>
<a id="getSkipSilenceEnabled()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>getSkipSilenceEnabled</h4>
<pre class="methodSignature">boolean&nbsp;getSkipSilenceEnabled()</pre>
<div class="block">Returns whether silences are skipped in the audio stream.</div>
</li>
</ul>
<a id="setAudioAttributes(com.google.android.exoplayer2.audio.AudioAttributes)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setAudioAttributes</h4>
<pre class="methodSignature">void&nbsp;setAudioAttributes&#8203;(<a href="AudioAttributes.html" title="class in com.google.android.exoplayer2.audio">AudioAttributes</a>&nbsp;audioAttributes)</pre>
<div class="block">Sets attributes for audio playback. If the attributes have changed and if the sink is not
configured for use with tunneling, then it is reset and the audio session id is cleared.
<p>
If the sink is configured for use with tunneling then the audio attributes are ignored. The
sink is not reset and the audio session id is not cleared. The passed attributes will be used
if the sink is later re-configured into non-tunneled mode.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>audioAttributes</code> - The attributes for audio playback.</dd>
</dl>
</li>
</ul>
<a id="setAudioSessionId(int)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setAudioSessionId</h4>
<pre class="methodSignature">void&nbsp;setAudioSessionId&#8203;(int&nbsp;audioSessionId)</pre>
<div class="block">Sets the audio session id.</div>
</li>
</ul>
<a id="setAuxEffectInfo(com.google.android.exoplayer2.audio.AuxEffectInfo)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setAuxEffectInfo</h4>
<pre class="methodSignature">void&nbsp;setAuxEffectInfo&#8203;(<a href="AuxEffectInfo.html" title="class in com.google.android.exoplayer2.audio">AuxEffectInfo</a>&nbsp;auxEffectInfo)</pre>
<div class="block">Sets the auxiliary effect.</div>
</li>
</ul>
<a id="enableTunnelingV21()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>enableTunnelingV21</h4>
<pre class="methodSignature">void&nbsp;enableTunnelingV21()</pre>
<div class="block">Enables tunneling, if possible. The sink is reset if tunneling was previously disabled.
Enabling tunneling is only possible if the sink is based on a platform <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioTrack</code></a>, and
requires platform API version 21 onwards.</div>
<dl>
<dt><span class="throwsLabel">Throws:</span></dt>
<dd><code><a href="https://developer.android.com/reference/java/lang/IllegalStateException.html" title="class or interface in java.lang" class="externalLink" target="_top">IllegalStateException</a></code> - Thrown if enabling tunneling on platform API version &lt; 21.</dd>
</dl>
</li>
</ul>
<a id="disableTunneling()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>disableTunneling</h4>
<pre class="methodSignature">void&nbsp;disableTunneling()</pre>
<div class="block">Disables tunneling. If tunneling was previously enabled then the sink is reset and any audio
session id is cleared.</div>
</li>
</ul>
<a id="setVolume(float)">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>setVolume</h4>
<pre class="methodSignature">void&nbsp;setVolume&#8203;(float&nbsp;volume)</pre>
<div class="block">Sets the playback volume.</div>
<dl>
<dt><span class="paramLabel">Parameters:</span></dt>
<dd><code>volume</code> - Linear output gain to apply to all channels. Should be in the range [0.0, 1.0].</dd>
</dl>
</li>
</ul>
<a id="pause()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>pause</h4>
<pre class="methodSignature">void&nbsp;pause()</pre>
<div class="block">Pauses playback.</div>
</li>
</ul>
<a id="flush()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>flush</h4>
<pre class="methodSignature">void&nbsp;flush()</pre>
<div class="block">Flushes the sink, after which it is ready to receive buffers from a new playback position.
<p>The audio session may remain active until <a href="#reset()"><code>reset()</code></a> is called.</div>
</li>
</ul>
<a id="experimentalFlushWithoutAudioTrackRelease()">
<!-- -->
</a>
<ul class="blockList">
<li class="blockList">
<h4>experimentalFlushWithoutAudioTrackRelease</h4>
<pre class="methodSignature">void&nbsp;experimentalFlushWithoutAudioTrackRelease()</pre>
<div class="block">Flushes the sink, after which it is ready to receive buffers from a new playback position.
<p>Does not release the <a href="https://developer.android.com/reference/android/media/AudioTrack.html" title="class or interface in android.media" class="externalLink" target="_top"><code>AudioTrack</code></a> held by the sink.
<p>This method is experimental, and will be renamed or removed in a future release.
<p>Only for experimental use as part of <a href="MediaCodecAudioRenderer.html#experimentalSetEnableKeepAudioTrackOnSeek(boolean)"><code>MediaCodecAudioRenderer.experimentalSetEnableKeepAudioTrackOnSeek(boolean)</code></a>.</div>
</li>
</ul>
<a id="reset()">
<!-- -->
</a>
<ul class="blockListLast">
<li class="blockList">
<h4>reset</h4>
<pre class="methodSignature">void&nbsp;reset()</pre>
<div class="block">Resets the renderer, releasing any resources that it currently holds.</div>
</li>
</ul>
</li>
</ul>
</section>
</li>
</ul>
</div>
</div>
</main>
<!-- ========= END OF CLASS DATA ========= -->
<footer role="contentinfo">
<nav role="navigation">
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a id="navbar.bottom">
<!-- -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a id="navbar.bottom.firstrow">
<!-- -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../../../../../index.html">Overview</a></li>
<li><a href="package-summary.html">Package</a></li>
<li class="navBarCell1Rev">Class</li>
<li><a href="package-tree.html">Tree</a></li>
<li><a href="../../../../../deprecated-list.html">Deprecated</a></li>
<li><a href="../../../../../index-all.html">Index</a></li>
<li><a href="../../../../../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../../../../../allclasses.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
allClassesLink = document.getElementById("allclasses_navbar_bottom");
if(window==top) {
allClassesLink.style.display = "block";
}
else {
allClassesLink.style.display = "none";
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
</div>
<div>
<ul class="subNavList">
<li>Summary:&nbsp;</li>
<li><a href="#nested.class.summary">Nested</a>&nbsp;|&nbsp;</li>
<li><a href="#field.summary">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.summary">Method</a></li>
</ul>
<ul class="subNavList">
<li>Detail:&nbsp;</li>
<li><a href="#field.detail">Field</a>&nbsp;|&nbsp;</li>
<li>Constr&nbsp;|&nbsp;</li>
<li><a href="#method.detail">Method</a></li>
</ul>
</div>
<a id="skip.navbar.bottom">
<!-- -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</nav>
</footer>
</body>
</html>