Picture-in-Picture (PiP) é um modo de reprodução de vídeo que exibe conteúdo em uma janela flutuante sobre outros aplicativos, permitindo que o usuário continue assistindo ao minimizar o aplicativo ou alternar entre programas. A janela PiP é posicionada automaticamente no canto da tela e pode ser movida pelo usuário. De acordo com a documentação do Apple AVPictureInPictureController (2026), o modo PiP é suportado no iOS a partir da versão 14 e no Android a partir da versão 8.0.
Principais pontos
Picture-in-Picture (PiP) é um modo de exibição de vídeo que mostra conteúdo em uma pequena janela flutuante que permanece sobre todas as outras janelas e aplicativos. O usuário pode mover a janela PiP pela tela, redimensioná-la (em algumas plataformas) e continuar assistindo ao conteúdo enquanto trabalha em outros aplicativos.
O conceito de PiP veio da televisão: já na década de 1990, os televisores permitiam exibir um segundo canal no canto da tela. Em dispositivos móveis, o PiP apareceu pela primeira vez no iPad com iOS 9 (2015) para vídeos no Safari, enquanto o PiP sistêmico completo para aplicativos tornou-se disponível no iOS 14 (2020). O suporte a PiP no Android chegou antes — na versão 8.0 Oreo (2017), mas apenas para vídeo, e a partir do Android 12 para qualquer tipo de conteúdo.
O PiP difere da reprodução em segundo plano porque o vídeo continua sendo exibido na tela, não apenas sendo reproduzido no fluxo de áudio. A reprodução de áudio em segundo plano está disponível em ambas as plataformas, mas o PiP dá ao usuário controle visual sobre o conteúdo: ele pode ver os quadros, pausar, retroceder ou fechar a janela. Isso é especialmente importante para tutoriais em vídeo, streams e videochamadas, onde o conteúdo visual é tão importante quanto o áudio.
Arquiteturalmente, o PiP é implementado através de um gerenciador de janelas do sistema que cria uma janela separada com prioridade de exibição reduzida. O aplicativo delega a saída de vídeo a um serviço do sistema que continua renderizando o vídeo mesmo depois que o aplicativo entra em segundo plano ou é minimizado.
O processo começa quando o usuário minimiza o aplicativo com vídeo ativo ou pressiona o botão PiP (no iOS), ou o sistema automaticamente transiciona a Activity para o modo PiP (no Android). O gerenciador de janelas do sistema captura o fluxo de vídeo e cria uma janela flutuante com proporções fixas. O tamanho da janela depende da proporção do vídeo original e das restrições da plataforma: no iOS, a janela PiP ocupa aproximadamente 1/6–1/4 da largura da tela; no Android, não menos que 108 dp de largura e 240 dp de altura para dispositivos móveis.
Quando a janela PiP está ativa, o aplicativo pode estar em um de três estados: em segundo plano (minimizado), no estado ativo (o usuário voltou ao aplicativo) ou em estado de espera (o sistema pausou o PiP devido à falta de recursos). Ao fazer a transição para o PiP, o aplicativo deve pausar operações desnecessárias da interface (animações, renderização da interface) e liberar memória, pois os recursos do sistema são distribuídos de forma mais restrita no modo multitarefa. O iOS envia automaticamente ao aplicativo a notificação AVPictureInPictureControllerWillStartNotification, enquanto o Android envia o callback onPictureInPictureModeChanged.
A janela PiP tem limitações significativas: não pode exibir elementos de controle de interface padrão (botão de pausa, barra de progresso) — apenas uma sobreposição mínima do sistema com controles básicos: reproduzir/pausar, fechar, expandir para tela cheia. A interface PiP do sistema no iOS inclui botões de pausa e fechar, enquanto no Android inclui os mesmos elementos mais um botão adicional de configurações. A interação com o conteúdo dentro do PiP (retroceder, selecionar legendas) não é possível — para isso, o aplicativo deve ser expandido para tela cheia.
No iOS, o PiP é implementado através do framework AVKit e da classe AVPictureInPictureController. Esta API está disponível no iOS 14+ para iPhone e iPad, mas com requisitos diferentes: no iPad, o PiP funciona através de AVPlayerLayer; no iPhone, apenas através de AVPlayerViewController.
Para o PiP funcionar no iOS, várias condições devem ser atendidas: o aplicativo deve usar AVPlayer para reprodução de vídeo, a sessão de áudio deve ser configurada para a categoria .playback ou .playAndRecord, e o aplicativo deve ter entitlements para áudio em segundo plano (UIBackgroundModes = audio). Sem essas configurações, o PiP não iniciará — o sistema rejeitará a solicitação de sessão PiP porque não pode garantir a reprodução correta após a transição para segundo plano.
No iOS, a janela PiP aparece automaticamente ao minimizar o aplicativo se o vídeo estiver sendo reproduzido ativamente e o usuário não tiver desativado esse recurso nas configurações. O usuário também pode minimizar manualmente o vídeo no PiP através do botão no AVPlayerViewController. O tamanho da janela PiP no iOS é fixo e determinado pelo sistema — o desenvolvedor não pode alterá-lo. A proporção da janela PiP corresponde à proporção do vídeo original, mas o tamanho máximo é limitado a 1/4 da largura da tela no iPhone e 1/3 no iPad.
As principais limitações do PiP no iOS: impossibilidade de interface personalizada na janela PiP, um único fluxo PiP por vez e a necessidade de um AVPlayer ativo para o PiP funcionar. O multi-PiP — reprodução simultânea de várias janelas PiP — não é suportado no iOS. Ao tentar iniciar um segundo PiP, o primeiro é automaticamente fechado. Esta é uma limitação de hardware: o processador de vídeo não pode atender simultaneamente dois canais PiP independentes devido a limitações de DMA e memória de vídeo.
Outra limitação importante é a duração da reprodução em segundo plano. Se o usuário não interagir com a janela PiP, o sistema pode pausar a reprodução após algum tempo para economizar energia. A pausa automática do PiP no iOS ocorre após 10–15 minutos de inatividade se o aplicativo não tiver implementado um mecanismo keep-alive através de uma tarefa em segundo plano. Para videochamadas e streams, recomenda-se usar PushKit e certificados VoIP, que contornam essa limitação.
No Android, o PiP é implementado como um modo integrado de Activity que é ativado através do método enterPictureInPictureMode. Desde o Android 8.0 (API 26), qualquer Activity pode entrar no modo PiP, e desde o Android 12 (API 31), há suporte a PiP para SurfaceView e TextureView sem necessidade de usar MediaCodec.
Para suportar PiP no manifesto do Android, o atributo android:supportsPictureInPicture deve ser especificado para a Activity na seção
No Android, a janela PiP por padrão não possui elementos de controle. O desenvolvedor pode adicionar ações personalizadas através de RemoteAction no método setPictureInPictureParams. Até 3 ações estão disponíveis (por exemplo: pausar/reproduzir, retroceder/avançar, fechar). Cada ação aparece na sobreposição do sistema PiP como um ícone. Ao contrário do iOS, onde todos os elementos da interface são estritamente fixos, o Android oferece mais flexibilidade para os controles básicos.
O PiP no Android tem capacidades diferentes dependendo da versão do SO. No Android 8.0–8.1, o PiP está disponível apenas para vídeo reproduzido através de MediaPlayer ou MediaCodec com SurfaceView. A partir do Android 9, pode-se usar PictureInPictureArgs.Builder para configurar a proporção da janela PiP. O Android 12 adicionou suporte PiP para SurfaceView e TextureView personalizados, além de transições melhoradas entre o modo tela cheia e PiP. O Android 13+ permite exibir a janela PiP mesmo com a tela bloqueada, se o aplicativo tiver a permissão adequada.
| Versão do Android | Capacidades PiP | API |
|---|---|---|
| 8.0–8.1 | PiP básico para MediaPlayer/MediaCodec | 26–27 |
| 9–11 | Configuração de proporção, ações personalizadas | 28–30 |
| 12 | Suporte PiP para SurfaceView/TextureView | 31 |
| 13+ | PiP na tela de bloqueio, animações melhoradas | 33+ |
Uma diferença chave do PiP no Android em relação ao iOS é a capacidade multi-PiP. No Android 12+, o sistema pode exibir várias janelas PiP simultaneamente se os aplicativos suportarem e o desempenho do dispositivo permitir. No entanto, na prática, o multi-PiP é limitado pelas capacidades do SoC: a maioria dos dispositivos suporta apenas uma janela PiP devido a limitações de hardware do decodificador, pois cada janela PiP requer seu próprio fluxo de vídeo e uma sessão de decodificação separada.
Vejamos uma implementação prática do PiP em ambas as plataformas móveis, levando em conta as últimas mudanças de API.
import AVKit
import AVFoundation
class VideoPlayerViewController: UIViewController {
var player: AVPlayer!
var pipController: AVPictureInPictureController?
override func viewDidLoad() {
super.viewDidLoad()
let playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspect
view.layer.addSublayer(playerLayer)
guard AVPictureInPictureController.isPictureInPictureSupported()
else { return }
pipController = AVPictureInPictureController(playerLayer: playerLayer)
pipController?.delegate = self
}
@IBAction func startPiPTapped() {
pipController?.startPictureInPicture()
}
}
extension VideoPlayerViewController: AVPictureInPictureControllerDelegate {
func pictureInPictureControllerWillStart(
_ pictureInPictureController: AVPictureInPictureController
) {
// Ocultar elementos da interface, liberar memória
}
func pictureInPictureControllerDidStop(
_ pictureInPictureController: AVPictureInPictureController
) {
// Restaurar a interface, retomar renderização
}
}
Neste exemplo, AVPictureInPictureController é inicializado com playerLayer após verificar isPictureInPictureSupported (PiP não é suportado no iPhone SE 1ª geração e alguns iPad sem memória suficiente). O delegado notifica o aplicativo sobre o início e fim do PiP — nestes callbacks, os elementos da interface devem ser ocultados e restaurados, pois a interface do aplicativo não fica visível no modo PiP. Ao fazer a transição para PiP, recomenda-se parar todas as animações, ocultar os controles do player e liberar memória não utilizada para evitar que o sistema descarregue forçosamente o aplicativo.
class PipVideoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setupVideoPlayer()
}
private fun enterPipMode() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val aspectRatio = Rational(16, 9)
val pipParams = PictureInPictureParams.Builder()
.setAspectRatio(aspectRatio)
.setAutoEnterEnabled(true)
.build()
enterPictureInPictureMode(pipParams)
}
}
override fun onPictureInPictureModeChanged(
isInPictureInPictureMode: Boolean,
newConfig: Configuration
) {
if (isInPictureInPictureMode) {
// Ocultar a interface, focar apenas na mídia
binding.controlsGroup.visibility = View.GONE
} else {
// Restaurar a interface
binding.controlsGroup.visibility = View.VISIBLE
}
}
}
O exemplo em Kotlin usa PictureInPictureParams.Builder para configurar o PiP. O método setAspectRatio define a proporção da janela PiP (16:9 para vídeo típico). setAutoEnterEnabled(true) ativa a transição automática para PiP ao minimizar o aplicativo. O callback onPictureInPictureModeChanged é invocado ao entrar e sair do PiP — aqui os elementos da interface devem ser ocultados ou exibidos. Para vídeo em SurfaceView, é necessário tratamento adicional de configuração adicionando android:configChanges="screenSize|smallestScreenSize" ao manifesto para evitar a recriação da Activity durante a transição para o modo PiP.
O PiP é uma ferramenta poderosa para melhorar a experiência do usuário em aplicativos onde o conteúdo permanece relevante mesmo ao alternar para outras tarefas. No entanto, a implementação do PiP deve ser justificada e não distrair o usuário.
Videochamadas e conferências são um dos principais cenários do PiP. No Zoom, FaceTime, Google Meet, o PiP permite ver o interlocutor enquanto trabalha em outros aplicativos: lendo anotações, vendo uma apresentação ou verificando e-mails. O PiP para videochamadas requer suporte de câmera em segundo plano e configuração adequada da sessão de áudio para continuar capturando áudio em segundo plano. No iOS, isso é feito usando AVSampleBufferDisplayLayer em vez de AVPlayerLayer, já que videochamadas não usam AVPlayer.
Serviços de streaming (YouTube, Netflix, Twitch) usam ativamente o PiP para continuar a visualização enquanto pesquisam novo conteúdo. O YouTube Premium oferece PiP como um recurso pago, e a Netflix também restringe o PiP a certos planos de assinatura devido a restrições de licenciamento de conteúdo. Para implementar PiP em um aplicativo de streaming, é necessária integração com um sistema DRM (FairPlay, Widevine) que suporte um pipeline seguro no modo PiP.
O PiP não é adequado para aplicativos com conteúdo de vídeo interativo que exija interação do usuário: plataformas educacionais com testes dentro do player, streams de jogos com chat, aplicativos de compras com links para produtos no vídeo. Nestes casos, a janela PiP é muito pequena para exibir informações adicionais, e os elementos interativos não são suportados dentro do PiP. Recomenda-se usar PiP apenas para visualização passiva, quando não é necessária interação com o conteúdo.
Para aplicativos de música e podcasts, o PiP é excessivo — basta áudio em segundo plano sem janela visual. O PiP consome recursos adicionais de GPU para renderizar vídeo em uma janela flutuante, reduzindo a duração da bateria. Se o conteúdo for auditivo (música, podcasts, audiolivros) — use reprodução em segundo plano sem PiP. Se for visual — implemente PiP para melhorar a experiência do usuário.
Perguntas frequentes
O PiP no iOS requer iPhone 6s+, iOS 14+ e uma região compatível (EUA, Canadá, Austrália, UE, Rússia e outros). O aplicativo deve configurar a sessão de áudio na categoria .playback e adicionar UIBackgroundModes = audio. Verifique também as configurações: Ajustes > Geral > Picture in Picture.
No iOS, o tamanho da janela PiP é totalmente determinado pelo sistema e não pode ser configurado pelo desenvolvedor. No Android, apenas a proporção pode ser definida via setAspectRatio no PictureInPictureParams.Builder, mas o tamanho exato da janela é determinado pelo sistema. O usuário pode redimensionar a janela PiP no Android 12+ com o gesto de pinça para zoom.
Sim, o PiP funciona com conteúdo protegido por DRM (FairPlay no iOS, Widevine L1 no Android) desde que a sessão DRM suporte um pipeline seguro no modo PiP. O Widevine L3 pode não suportar PiP, pois não garante a segurança do conteúdo decodificado em uma janela flutuante. Verifique a compatibilidade do DRM com PiP durante a fase de testes.
No iOS — apenas uma janela PiP. No Android 12+, teoricamente o multi-PiP é suportado, mas na prática a maioria dos dispositivos está limitada a uma janela devido a restrições de hardware. Dispositivos topo de linha (Samsung Galaxy S24, Pixel 8) podem suportar 2 janelas PiP, mas com desempenho reduzido.
Sim, o tratamento do ciclo de vida é criticamente importante. No iOS, ao fazer a transição para PiP, o aplicativo recebe uma notificação willStart onde a interface deve ser ocultada e a memória liberada. No Android, onPictureInPictureModeChanged é chamado ao entrar/sair do PiP. Sem o tratamento adequado do ciclo de vida, o sistema pode descarregar o aplicativo da memória, interrompendo a reprodução.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também