Describe the bug
I have tested the livestreaming with the example code and it worked on mux.com
But, the biggest problem is the video quality is very poor and can see blurred view on mux playback and Can you please help me to understand what I am missing? What is causing this poor video quality?
import 'dart:async';
import 'package:audio_session/audio_session.dart';
import 'package:flutter/material.dart';
import 'package:haishin_kit/audio_settings.dart';
import 'package:haishin_kit/audio_source.dart';
import 'package:haishin_kit/capture_settings.dart';
import 'package:haishin_kit/net_stream_drawable_texture.dart';
import 'package:haishin_kit/rtmp_connection.dart';
import 'package:haishin_kit/rtmp_stream.dart';
import 'package:haishin_kit/video_settings.dart';
import 'package:haishin_kit/video_source.dart';
import 'package:permission_handler/permission_handler.dart';
void main() {
runApp(const MyApp());
}
const streamKey = "***********************";
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
RtmpConnection? _connection;
RtmpStream? _stream;
bool _recording = false;
String _mode = "publish";
CameraPosition currentPosition = CameraPosition.front;
@override
void initState() {
super.initState();
initPlatformState();
}
@override
void dispose() {
_stream?.dispose();
_connection?.dispose();
super.dispose();
}
Future<void> initPlatformState() async {
await Permission.camera.request();
await Permission.microphone.request();
// Set up AVAudioSession for iOS.
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration(
avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
avAudioSessionCategoryOptions:
AVAudioSessionCategoryOptions.allowBluetooth,
));
RtmpConnection connection = await RtmpConnection.create();
connection.eventChannel.receiveBroadcastStream().listen((event) {
switch (event["data"]["code"]) {
case 'NetConnection.Connect.Success':
if (_mode == "publish") {
_stream?.publish(streamKey);
} else {
_stream?.play("live");
}
setState(() {
_recording = true;
});
break;
}
});
RtmpStream stream = await RtmpStream.create(connection);
stream.audioSettings = AudioSettings(muted: false, bitrate: 64 * 1000);
stream.videoSettings = VideoSettings(
width: 1080,
height: 1920,
bitrate: 12 * 1000,
frameInterval: 2
);
stream.attachAudio(AudioSource());
stream.attachVideo(VideoSource(position: currentPosition));
if (!mounted) return;
setState(() {
_connection = connection;
_stream = stream;
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('HaishinKit'), actions: [
// IconButton(
// icon: const Icon(Icons.play_arrow),
// onPressed: () {
// if (_mode == "publish") {
// _mode = "playback";
// _stream?.attachVideo(null);
// _stream?.attachAudio(null);
// } else {
// _mode = "publish";
// _stream?.attachAudio(AudioSource());
// _stream?.attachVideo(VideoSource(position: currentPosition));
// }
// },
// ),
IconButton(
icon: const Icon(Icons.flip_camera_android_sharp),
onPressed: () {
currentPosition = currentPosition == CameraPosition.front
? CameraPosition.back
: CameraPosition.front;
_stream?.attachVideo(VideoSource(position: currentPosition));
},
)
]),
body: Center(
child: _stream == null
? const CircularProgressIndicator()
: Stack(
children: [
NetStreamDrawableTexture(_stream),
Positioned(
bottom: 20,
right: 20,
left: 20,
child: SizedBox(
width: double.infinity,
height: 100,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Icon(Icons.shopping_bag, color: Colors.white,),
Icon(Icons.thumb_up, color: Colors.white,),
Icon(Icons.report, color: Colors.white,),
],
),
),
)
]
),
),
floatingActionButton: FloatingActionButton(
child: _recording
? const Icon(Icons.fiber_smart_record)
: const Icon(Icons.not_started),
onPressed: () {
if (_recording) {
_connection?.close();
setState(() {
_recording = false;
});
} else {
_connection?.connect("rtmps://global-live.mux.com:443/app");
}
},
),
),
);
}
}
To Reproduce
Run the above code as mentioned in the bug.
Expected behavior
The 720p should show HD and so on.
Version
0.9.2
Smartphone info.
Additional context
No response
Screenshots
No response
Relevant log output
Launching lib/main.dart on Redmi Note 8 Pro in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Debug service listening on ws://127.0.0.1:64958/HisNmM4CRNs=/ws
Syncing files to device Redmi Note 8 Pro...
E/ion ( 1410): ioctl c0044901 failed with code -1: Invalid argument
I/estream_haishi( 1410): ProcessProfilingInfo new_methods=1122 is saved saved_to_disk=1 resolve_classes_delay=8000
D/libMEOW ( 1410): applied 1 plugins for [com.example.livestream_haishin]:
D/libMEOW ( 1410): plugin 1: [libMEOW_gift.so]:
I/GED ( 1410): [GT]_get_procNameprocess pid(1410)
I/GED ( 1410): [GT]_getprocess name(com.example.livestream_haishin)
I/estream_haishi( 1410): [GT] ret(1) gt_status(00000000) aniso_debug_level(0) gt_aniso_max_level(16) ani so mask(00000001) tri mask(00000002)
I/libMEOW_gift( 1410): ctx:0xb4000071be46ff70, ARC not Enabled.
I/BufferQueueConsumer( 1410): [](id:58200000000,api:0,p:-1,c:1410) connect(): controlledByApp=true
I/CameraManagerGlobal( 1410): Connecting to camera service
D/libMEOW ( 1410): applied 1 plugins for [com.example.livestream_haishin]:
D/libMEOW ( 1410): plugin 1: [libMEOW_gift.so]:
I/GED ( 1410): [GT]_get_procNameprocess pid(1410)
I/GED ( 1410): [GT]_getprocess name(com.example.livestream_haishin)
I/estream_haishi( 1410): [GT] ret(1) gt_status(00000000) aniso_debug_level(0) gt_aniso_max_level(16) ani so mask(00000001) tri mask(00000002)
I/libMEOW_gift( 1410): ctx:0xb4000071b765bf68, ARC not Enabled.
W/CameraManagerGlobal( 1410): [soar.cts] ignore the status update of camera: 20
W/CameraManagerGlobal( 1410): [soar.cts] ignore the status update of camera: 21
W/CameraManagerGlobal( 1410): [soar.cts] ignore the status update of camera: 22
W/CameraManagerGlobal( 1410): [soar.cts] ignore the status update of camera: 61
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 21
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 22
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 61
I/BufferQueueProducer( 1410): [SurfaceTexture-0-1410-0](id:58200000000,api:1,p:1410,c:1410) connect(): api=1 producerControlledByApp=true
E/libc ( 1410): Access denied finding property "persist.vendor.camera.privapp.list"
E/CameraManagerGlobal( 1410): Camera 61 is not available. Ignore physical camera status change
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 21
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 22
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 61
I/BufferQueueConsumer( 1410): [](id:58200000001,api:0,p:-1,c:1410) connect(): controlledByApp=true
I/BufferQueueConsumer( 1410): [](id:58200000002,api:0,p:-1,c:1410) connect(): controlledByApp=true
I/BufferQueueProducer( 1410): [SurfaceTexture-1-1410-1](id:58200000001,api:4,p:825,c:1410) connect(): api=4 producerControlledByApp=true
I/BufferQueueProducer( 1410): [SurfaceTexture-1-1410-2](id:58200000002,api:4,p:825,c:1410) connect(): api=4 producerControlledByApp=true
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
I/mali_config( 1410): @get_buffer_dataspace_setting: update dataspace (0x10010000 -> 0x08020000)
V/PhoneWindow( 1410): DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@f58e519, this = DecorView@8fd59de[MainActivity]
I/GED ( 1410): ged_boost_gpu_freq, level 100, eOrigin 2, final_idx 27, oppidx_max 27, oppidx_min 0
E/CameraCaptureSession( 1410): Session 0: Exception while stopping repeating:
E/CameraCaptureSession( 1410): android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): The camera device has encountered a serious error
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.CameraDeviceImpl.checkIfCameraClosedOrInError(CameraDeviceImpl.java:2305)
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.CameraDeviceImpl.stopRepeating(CameraDeviceImpl.java:1263)
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.CameraCaptureSessionImpl.close(CameraCaptureSessionImpl.java:578)
E/CameraCaptureSession( 1410): at com.haishinkit.media.Camera2Source.setSession(Camera2Source.kt:79)
E/CameraCaptureSession( 1410): at com.haishinkit.media.Camera2Source.setDevice(Camera2Source.kt:52)
E/CameraCaptureSession( 1410): at com.haishinkit.media.Camera2Source.onError(Camera2Source.kt:199)
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.CameraDeviceImpl.notifyError(CameraDeviceImpl.java:1703)
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.CameraDeviceImpl.lambda$oDs27OTfKFfK18rUW2nQxxkPdV0(Unknown Source:0)
E/CameraCaptureSession( 1410): at android.hardware.camera2.impl.-$$Lambda$CameraDeviceImpl$oDs27OTfKFfK18rUW2nQxxkPdV0.accept(Unknown Source:8)
E/CameraCaptureSession( 1410): at com.android.internal.util.function.pooled.PooledLambdaImpl.doInvoke(PooledLambdaImpl.java:278)
E/CameraCaptureSession( 1410): at com.android.internal.util.function.pooled.PooledLambdaImpl.invoke(PooledLambdaImpl.java:201)
E/CameraCaptureSession( 1410): at com.android.internal.util.function.pooled.OmniFunction.run(OmniFunction.java:97)
E/CameraCaptureSession( 1410): at android.os.Handler.handleCallback(Handler.java:938)
E/CameraCaptureSession( 1410): at android.os.Handler.dispatchMessage(Handler.java:99)
E/CameraCaptureSession( 1410): at android.os.Looper.loop(Looper.java:236)
E/CameraCaptureSession( 1410): at android.os.HandlerThread.run(HandlerThread.java:67)
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 21
I/BufferQueueProducer( 1410): [SurfaceTexture-1-1410-1](id:58200000001,api:4,p:825,c:1410) disconnect(): api=4
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 22
D/libMEOW ( 1410): applied 1 plugins for [com.example.livestream_haishin]:
D/libMEOW ( 1410): plugin 1: [libMEOW_gift.so]:
W/CameraManagerGlobal( 1410): ignore the torch status update of camera: 61
I/BufferQueueProducer( 1410): [SurfaceTexture-1-1410-2](id:58200000002,api:4,p:825,c:1410) disconnect(): api=4
E/CameraManagerGlobal( 1410): Camera 61 is not available. Ignore physical camera status change