Hallo,
Dieses schöne Tool
https://github.com/lajos/iFrameExtractor lässt verschiedene Videoformate auf dem iPhone/iPad abspielen, allerdings ohne Ton.
Ich habe jetzt mal folgendes zusammen gebracht, um auch Ton zu unterstützen:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
{
AVCodecContext *c;
AVStream *st;
st = av_new_stream(oc, 1);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
}
c = st->codec;
c->codec_id = codec_id;
c->codec_type = CODEC_TYPE_AUDIO;
c->sample_fmt = SAMPLE_FMT_S16;
/* put sample parameters */
c->bit_rate = 64000;
c->sample_rate = 44100;
c->channels = 2;
return st;
}
static void open_audio(AVFormatContext *oc, AVStream *st)
{
AVCodecContext *c;
AVCodec *codec;
c = st->codec;
/* find the audio encoder */
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
/* open it */
if (avcodec_open(c, codec) < 0) {
fprintf(stderr, "could not open codec\n");
exit(1);
}
/* init signal generator */
t = 0;
tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
audio_outbuf_size = 10000;
audio_outbuf = av_malloc(audio_outbuf_size);
/* ugly hack for PCM codecs (will be removed ASAP with new PCM
support to compute the input frame size in samples */
if (c->frame_size <= 1) {
audio_input_frame_size = audio_outbuf_size / c->channels;
switch(st->codec->codec_id) {
case CODEC_ID_PCM_S16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_U16BE:
audio_input_frame_size >>= 1;
break;
default:
break;
}
} else {
audio_input_frame_size = c->frame_size;
}
samples = av_malloc(audio_input_frame_size * 2 * c->channels);
}
/* prepare a 16 bit dummy audio frame of 'frame_size' samples and
'nb_channels' channels */
static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
{
int j, i, v;
int16_t *q;
q = samples;
for(j=0;j<frame_size;j++) {
v = (int)(sin(t) * 10000);
for(i = 0; i < nb_channels; i++)
*q++ = v;
t += tincr;
tincr += tincr2;
}
}
static void write_audio_frame(AVFormatContext *oc, AVStream *st)
{
AVCodecContext *c;
AVPacket pkt;
av_init_packet(&pkt);
c = st->codec;
get_audio_frame(samples, audio_input_frame_size, c->channels);
pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, samples);
if (c->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
pkt.flags |= PKT_FLAG_KEY;
pkt.stream_index= st->index;
pkt.data= audio_outbuf;
/* write the compressed frame in the media file */
if (av_interleaved_write_frame(oc, &pkt) != 0) {
fprintf(stderr, "Error while writing audio frame\n");
exit(1);
}
}
static void close_audio(AVFormatContext *oc, AVStream *st)
{
avcodec_close(st->codec);
av_free(samples);
av_free(audio_outbuf);
}
|
und mit dem Code initialisiere ich den Stream:
|
Quellcode
|
1
2
3
4
5
6
7
|
AVStream *audioStream = add_audio_stream(pFormatCtxVideo, CODEC_ID_PCM_U16BE);
open_audio(pFormatCtxVideo, audioStream);
get_audio_frame(samples, audio_input_frame_size, 2);
write_audio_frame(pFormatCtxVideo, audioStream);
|
allerdings funktioniert das ganze nicht so wie ich es mir gedacht habe...
Ich bekomme einen EXC_BAD_ACCESS im #0 0x00360ed0 in "av_interleaved_write_frame at /Users/USER/iFrameExtractor/ffmpeg/libavformat/utils.c:2766" bei folgender Zeile:
|
Quellcode
|
1
|
0x00360ed0 <+0192> ldr r4, [r3, #48]
|
vl. haben wir ja den ein oder anderen Spezialisten unter uns der genau weiß was hier zu tun ist
Liebe Grüße,
Lukas